The Pedigree Project  0.1
ops.c
1 /*
2  * Copyright (c) 2008-2014, Pedigree Developers
3  *
4  * Please see the CONTRIB file in the root of the source tree for a full
5  * list of contributors.
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #include "x86emu/x86emui.h"
21 
22 /*----------------------------- Implementation ----------------------------*/
23 
24 /****************************************************************************
25 PARAMETERS:
26 op1 - Instruction op code
27 
28 REMARKS:
29 Handles illegal opcodes.
30 ****************************************************************************/
31 static void x86emuOp_illegal_op(u8 op1)
32 {
33  START_OF_INSTR();
34  if (M.x86.R_SP != 0)
35  {
36  DECODE_PRINTF("ILLEGAL X86 OPCODE\n");
37  TRACE_REGS();
38  printk(
39  "%04x:%04x: %02X ILLEGAL X86 OPCODE!\n", M.x86.R_CS, M.x86.R_IP - 1,
40  op1);
41  HALT_SYS();
42  }
43  else
44  {
45  /* If we get here, it means the stack pointer is back to zero
46  * so we are just returning from an emulator service call
47  * so therte is no need to display an error message. We trap
48  * the emulator with an 0xF1 opcode to finish the service
49  * call.
50  */
51  X86EMU_halt_sys();
52  }
53  END_OF_INSTR();
54 }
55 
56 /****************************************************************************
57 REMARKS:
58 Handles opcode 0x00
59 ****************************************************************************/
60 static void x86emuOp_add_byte_RM_R(u8 X86EMU_UNUSED(op1))
61 {
62  int mod, rl, rh;
63  uint destoffset;
64  u8 *destreg, *srcreg;
65  u8 destval;
66 
67  START_OF_INSTR();
68  DECODE_PRINTF("ADD\t");
69  FETCH_DECODE_MODRM(mod, rh, rl);
70  switch (mod)
71  {
72  case 0:
73  destoffset = decode_rm00_address(rl);
74  DECODE_PRINTF(",");
75  destval = fetch_data_byte(destoffset);
76  srcreg = DECODE_RM_BYTE_REGISTER(rh);
77  DECODE_PRINTF("\n");
78  TRACE_AND_STEP();
79  destval = add_byte(destval, *srcreg);
80  store_data_byte(destoffset, destval);
81  break;
82  case 1:
83  destoffset = decode_rm01_address(rl);
84  DECODE_PRINTF(",");
85  destval = fetch_data_byte(destoffset);
86  srcreg = DECODE_RM_BYTE_REGISTER(rh);
87  DECODE_PRINTF("\n");
88  TRACE_AND_STEP();
89  destval = add_byte(destval, *srcreg);
90  store_data_byte(destoffset, destval);
91  break;
92  case 2:
93  destoffset = decode_rm10_address(rl);
94  DECODE_PRINTF(",");
95  destval = fetch_data_byte(destoffset);
96  srcreg = DECODE_RM_BYTE_REGISTER(rh);
97  DECODE_PRINTF("\n");
98  TRACE_AND_STEP();
99  destval = add_byte(destval, *srcreg);
100  store_data_byte(destoffset, destval);
101  break;
102  case 3: /* register to register */
103  destreg = DECODE_RM_BYTE_REGISTER(rl);
104  DECODE_PRINTF(",");
105  srcreg = DECODE_RM_BYTE_REGISTER(rh);
106  DECODE_PRINTF("\n");
107  TRACE_AND_STEP();
108  *destreg = add_byte(*destreg, *srcreg);
109  break;
110  }
111  DECODE_CLEAR_SEGOVR();
112  END_OF_INSTR();
113 }
114 
115 /****************************************************************************
116 REMARKS:
117 Handles opcode 0x01
118 ****************************************************************************/
119 static void x86emuOp_add_word_RM_R(u8 X86EMU_UNUSED(op1))
120 {
121  int mod, rl, rh;
122  uint destoffset;
123 
124  START_OF_INSTR();
125  DECODE_PRINTF("ADD\t");
126  FETCH_DECODE_MODRM(mod, rh, rl);
127  switch (mod)
128  {
129  case 0:
130  if (M.x86.mode & SYSMODE_PREFIX_DATA)
131  {
132  u32 destval;
133  u32 *srcreg;
134 
135  destoffset = decode_rm00_address(rl);
136  DECODE_PRINTF(",");
137  destval = fetch_data_long(destoffset);
138  srcreg = DECODE_RM_LONG_REGISTER(rh);
139  DECODE_PRINTF("\n");
140  TRACE_AND_STEP();
141  destval = add_long(destval, *srcreg);
142  store_data_long(destoffset, destval);
143  }
144  else
145  {
146  u16 destval;
147  u16 *srcreg;
148 
149  destoffset = decode_rm00_address(rl);
150  DECODE_PRINTF(",");
151  destval = fetch_data_word(destoffset);
152  srcreg = DECODE_RM_WORD_REGISTER(rh);
153  DECODE_PRINTF("\n");
154  TRACE_AND_STEP();
155  destval = add_word(destval, *srcreg);
156  store_data_word(destoffset, destval);
157  }
158  break;
159  case 1:
160  if (M.x86.mode & SYSMODE_PREFIX_DATA)
161  {
162  u32 destval;
163  u32 *srcreg;
164 
165  destoffset = decode_rm01_address(rl);
166  DECODE_PRINTF(",");
167  destval = fetch_data_long(destoffset);
168  srcreg = DECODE_RM_LONG_REGISTER(rh);
169  DECODE_PRINTF("\n");
170  TRACE_AND_STEP();
171  destval = add_long(destval, *srcreg);
172  store_data_long(destoffset, destval);
173  }
174  else
175  {
176  u16 destval;
177  u16 *srcreg;
178 
179  destoffset = decode_rm01_address(rl);
180  DECODE_PRINTF(",");
181  destval = fetch_data_word(destoffset);
182  srcreg = DECODE_RM_WORD_REGISTER(rh);
183  DECODE_PRINTF("\n");
184  TRACE_AND_STEP();
185  destval = add_word(destval, *srcreg);
186  store_data_word(destoffset, destval);
187  }
188  break;
189  case 2:
190  if (M.x86.mode & SYSMODE_PREFIX_DATA)
191  {
192  u32 destval;
193  u32 *srcreg;
194 
195  destoffset = decode_rm10_address(rl);
196  DECODE_PRINTF(",");
197  destval = fetch_data_long(destoffset);
198  srcreg = DECODE_RM_LONG_REGISTER(rh);
199  DECODE_PRINTF("\n");
200  TRACE_AND_STEP();
201  destval = add_long(destval, *srcreg);
202  store_data_long(destoffset, destval);
203  }
204  else
205  {
206  u16 destval;
207  u16 *srcreg;
208 
209  destoffset = decode_rm10_address(rl);
210  DECODE_PRINTF(",");
211  destval = fetch_data_word(destoffset);
212  srcreg = DECODE_RM_WORD_REGISTER(rh);
213  DECODE_PRINTF("\n");
214  TRACE_AND_STEP();
215  destval = add_word(destval, *srcreg);
216  store_data_word(destoffset, destval);
217  }
218  break;
219  case 3: /* register to register */
220  if (M.x86.mode & SYSMODE_PREFIX_DATA)
221  {
222  u32 *destreg, *srcreg;
223 
224  destreg = DECODE_RM_LONG_REGISTER(rl);
225  DECODE_PRINTF(",");
226  srcreg = DECODE_RM_LONG_REGISTER(rh);
227  DECODE_PRINTF("\n");
228  TRACE_AND_STEP();
229  *destreg = add_long(*destreg, *srcreg);
230  }
231  else
232  {
233  u16 *destreg, *srcreg;
234 
235  destreg = DECODE_RM_WORD_REGISTER(rl);
236  DECODE_PRINTF(",");
237  srcreg = DECODE_RM_WORD_REGISTER(rh);
238  DECODE_PRINTF("\n");
239  TRACE_AND_STEP();
240  *destreg = add_word(*destreg, *srcreg);
241  }
242  break;
243  }
244  DECODE_CLEAR_SEGOVR();
245  END_OF_INSTR();
246 }
247 
248 /****************************************************************************
249 REMARKS:
250 Handles opcode 0x02
251 ****************************************************************************/
252 static void x86emuOp_add_byte_R_RM(u8 X86EMU_UNUSED(op1))
253 {
254  int mod, rl, rh;
255  u8 *destreg, *srcreg;
256  uint srcoffset;
257  u8 srcval;
258 
259  START_OF_INSTR();
260  DECODE_PRINTF("ADD\t");
261  FETCH_DECODE_MODRM(mod, rh, rl);
262  switch (mod)
263  {
264  case 0:
265  destreg = DECODE_RM_BYTE_REGISTER(rh);
266  DECODE_PRINTF(",");
267  srcoffset = decode_rm00_address(rl);
268  srcval = fetch_data_byte(srcoffset);
269  DECODE_PRINTF("\n");
270  TRACE_AND_STEP();
271  *destreg = add_byte(*destreg, srcval);
272  break;
273  case 1:
274  destreg = DECODE_RM_BYTE_REGISTER(rh);
275  DECODE_PRINTF(",");
276  srcoffset = decode_rm01_address(rl);
277  srcval = fetch_data_byte(srcoffset);
278  DECODE_PRINTF("\n");
279  TRACE_AND_STEP();
280  *destreg = add_byte(*destreg, srcval);
281  break;
282  case 2:
283  destreg = DECODE_RM_BYTE_REGISTER(rh);
284  DECODE_PRINTF(",");
285  srcoffset = decode_rm10_address(rl);
286  srcval = fetch_data_byte(srcoffset);
287  DECODE_PRINTF("\n");
288  TRACE_AND_STEP();
289  *destreg = add_byte(*destreg, srcval);
290  break;
291  case 3: /* register to register */
292  destreg = DECODE_RM_BYTE_REGISTER(rh);
293  DECODE_PRINTF(",");
294  srcreg = DECODE_RM_BYTE_REGISTER(rl);
295  DECODE_PRINTF("\n");
296  TRACE_AND_STEP();
297  *destreg = add_byte(*destreg, *srcreg);
298  break;
299  }
300  DECODE_CLEAR_SEGOVR();
301  END_OF_INSTR();
302 }
303 
304 /****************************************************************************
305 REMARKS:
306 Handles opcode 0x03
307 ****************************************************************************/
308 static void x86emuOp_add_word_R_RM(u8 X86EMU_UNUSED(op1))
309 {
310  int mod, rl, rh;
311  uint srcoffset;
312 
313  START_OF_INSTR();
314  DECODE_PRINTF("ADD\t");
315  FETCH_DECODE_MODRM(mod, rh, rl);
316  switch (mod)
317  {
318  case 0:
319  if (M.x86.mode & SYSMODE_PREFIX_DATA)
320  {
321  u32 *destreg;
322  u32 srcval;
323 
324  destreg = DECODE_RM_LONG_REGISTER(rh);
325  DECODE_PRINTF(",");
326  srcoffset = decode_rm00_address(rl);
327  srcval = fetch_data_long(srcoffset);
328  DECODE_PRINTF("\n");
329  TRACE_AND_STEP();
330  *destreg = add_long(*destreg, srcval);
331  }
332  else
333  {
334  u16 *destreg;
335  u16 srcval;
336 
337  destreg = DECODE_RM_WORD_REGISTER(rh);
338  DECODE_PRINTF(",");
339  srcoffset = decode_rm00_address(rl);
340  srcval = fetch_data_word(srcoffset);
341  DECODE_PRINTF("\n");
342  TRACE_AND_STEP();
343  *destreg = add_word(*destreg, srcval);
344  }
345  break;
346  case 1:
347  if (M.x86.mode & SYSMODE_PREFIX_DATA)
348  {
349  u32 *destreg;
350  u32 srcval;
351 
352  destreg = DECODE_RM_LONG_REGISTER(rh);
353  DECODE_PRINTF(",");
354  srcoffset = decode_rm01_address(rl);
355  srcval = fetch_data_long(srcoffset);
356  DECODE_PRINTF("\n");
357  TRACE_AND_STEP();
358  *destreg = add_long(*destreg, srcval);
359  }
360  else
361  {
362  u16 *destreg;
363  u16 srcval;
364 
365  destreg = DECODE_RM_WORD_REGISTER(rh);
366  DECODE_PRINTF(",");
367  srcoffset = decode_rm01_address(rl);
368  srcval = fetch_data_word(srcoffset);
369  DECODE_PRINTF("\n");
370  TRACE_AND_STEP();
371  *destreg = add_word(*destreg, srcval);
372  }
373  break;
374  case 2:
375  if (M.x86.mode & SYSMODE_PREFIX_DATA)
376  {
377  u32 *destreg;
378  u32 srcval;
379 
380  destreg = DECODE_RM_LONG_REGISTER(rh);
381  DECODE_PRINTF(",");
382  srcoffset = decode_rm10_address(rl);
383  srcval = fetch_data_long(srcoffset);
384  DECODE_PRINTF("\n");
385  TRACE_AND_STEP();
386  *destreg = add_long(*destreg, srcval);
387  }
388  else
389  {
390  u16 *destreg;
391  u16 srcval;
392 
393  destreg = DECODE_RM_WORD_REGISTER(rh);
394  DECODE_PRINTF(",");
395  srcoffset = decode_rm10_address(rl);
396  srcval = fetch_data_word(srcoffset);
397  DECODE_PRINTF("\n");
398  TRACE_AND_STEP();
399  *destreg = add_word(*destreg, srcval);
400  }
401  break;
402  case 3: /* register to register */
403  if (M.x86.mode & SYSMODE_PREFIX_DATA)
404  {
405  u32 *destreg, *srcreg;
406 
407  destreg = DECODE_RM_LONG_REGISTER(rh);
408  DECODE_PRINTF(",");
409  srcreg = DECODE_RM_LONG_REGISTER(rl);
410  DECODE_PRINTF("\n");
411  TRACE_AND_STEP();
412  *destreg = add_long(*destreg, *srcreg);
413  }
414  else
415  {
416  u16 *destreg, *srcreg;
417 
418  destreg = DECODE_RM_WORD_REGISTER(rh);
419  DECODE_PRINTF(",");
420  srcreg = DECODE_RM_WORD_REGISTER(rl);
421  DECODE_PRINTF("\n");
422  TRACE_AND_STEP();
423  *destreg = add_word(*destreg, *srcreg);
424  }
425  break;
426  }
427  DECODE_CLEAR_SEGOVR();
428  END_OF_INSTR();
429 }
430 
431 /****************************************************************************
432 REMARKS:
433 Handles opcode 0x04
434 ****************************************************************************/
435 static void x86emuOp_add_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
436 {
437  u8 srcval;
438 
439  START_OF_INSTR();
440  DECODE_PRINTF("ADD\tAL,");
441  srcval = fetch_byte_imm();
442  DECODE_PRINTF2("%x\n", srcval);
443  TRACE_AND_STEP();
444  M.x86.R_AL = add_byte(M.x86.R_AL, srcval);
445  DECODE_CLEAR_SEGOVR();
446  END_OF_INSTR();
447 }
448 
449 /****************************************************************************
450 REMARKS:
451 Handles opcode 0x05
452 ****************************************************************************/
453 static void x86emuOp_add_word_AX_IMM(u8 X86EMU_UNUSED(op1))
454 {
455  u32 srcval;
456 
457  START_OF_INSTR();
458  if (M.x86.mode & SYSMODE_PREFIX_DATA)
459  {
460  DECODE_PRINTF("ADD\tEAX,");
461  srcval = fetch_long_imm();
462  }
463  else
464  {
465  DECODE_PRINTF("ADD\tAX,");
466  srcval = fetch_word_imm();
467  }
468  DECODE_PRINTF2("%x\n", srcval);
469  TRACE_AND_STEP();
470  if (M.x86.mode & SYSMODE_PREFIX_DATA)
471  {
472  M.x86.R_EAX = add_long(M.x86.R_EAX, srcval);
473  }
474  else
475  {
476  M.x86.R_AX = add_word(M.x86.R_AX, (u16) srcval);
477  }
478  DECODE_CLEAR_SEGOVR();
479  END_OF_INSTR();
480 }
481 
482 /****************************************************************************
483 REMARKS:
484 Handles opcode 0x06
485 ****************************************************************************/
486 static void x86emuOp_push_ES(u8 X86EMU_UNUSED(op1))
487 {
488  START_OF_INSTR();
489  DECODE_PRINTF("PUSH\tES\n");
490  TRACE_AND_STEP();
491  push_word(M.x86.R_ES);
492  DECODE_CLEAR_SEGOVR();
493  END_OF_INSTR();
494 }
495 
496 /****************************************************************************
497 REMARKS:
498 Handles opcode 0x07
499 ****************************************************************************/
500 static void x86emuOp_pop_ES(u8 X86EMU_UNUSED(op1))
501 {
502  START_OF_INSTR();
503  DECODE_PRINTF("POP\tES\n");
504  TRACE_AND_STEP();
505  M.x86.R_ES = pop_word();
506  DECODE_CLEAR_SEGOVR();
507  END_OF_INSTR();
508 }
509 
510 /****************************************************************************
511 REMARKS:
512 Handles opcode 0x08
513 ****************************************************************************/
514 static void x86emuOp_or_byte_RM_R(u8 X86EMU_UNUSED(op1))
515 {
516  int mod, rl, rh;
517  u8 *destreg, *srcreg;
518  uint destoffset;
519  u8 destval;
520 
521  START_OF_INSTR();
522  DECODE_PRINTF("OR\t");
523  FETCH_DECODE_MODRM(mod, rh, rl);
524  switch (mod)
525  {
526  case 0:
527  destoffset = decode_rm00_address(rl);
528  DECODE_PRINTF(",");
529  destval = fetch_data_byte(destoffset);
530  srcreg = DECODE_RM_BYTE_REGISTER(rh);
531  DECODE_PRINTF("\n");
532  TRACE_AND_STEP();
533  destval = or_byte(destval, *srcreg);
534  store_data_byte(destoffset, destval);
535  break;
536  case 1:
537  destoffset = decode_rm01_address(rl);
538  DECODE_PRINTF(",");
539  destval = fetch_data_byte(destoffset);
540  srcreg = DECODE_RM_BYTE_REGISTER(rh);
541  DECODE_PRINTF("\n");
542  TRACE_AND_STEP();
543  destval = or_byte(destval, *srcreg);
544  store_data_byte(destoffset, destval);
545  break;
546  case 2:
547  destoffset = decode_rm10_address(rl);
548  DECODE_PRINTF(",");
549  destval = fetch_data_byte(destoffset);
550  srcreg = DECODE_RM_BYTE_REGISTER(rh);
551  DECODE_PRINTF("\n");
552  TRACE_AND_STEP();
553  destval = or_byte(destval, *srcreg);
554  store_data_byte(destoffset, destval);
555  break;
556  case 3: /* register to register */
557  destreg = DECODE_RM_BYTE_REGISTER(rl);
558  DECODE_PRINTF(",");
559  srcreg = DECODE_RM_BYTE_REGISTER(rh);
560  DECODE_PRINTF("\n");
561  TRACE_AND_STEP();
562  *destreg = or_byte(*destreg, *srcreg);
563  break;
564  }
565  DECODE_CLEAR_SEGOVR();
566  END_OF_INSTR();
567 }
568 
569 /****************************************************************************
570 REMARKS:
571 Handles opcode 0x09
572 ****************************************************************************/
573 static void x86emuOp_or_word_RM_R(u8 X86EMU_UNUSED(op1))
574 {
575  int mod, rl, rh;
576  uint destoffset;
577 
578  START_OF_INSTR();
579  DECODE_PRINTF("OR\t");
580  FETCH_DECODE_MODRM(mod, rh, rl);
581  switch (mod)
582  {
583  case 0:
584  if (M.x86.mode & SYSMODE_PREFIX_DATA)
585  {
586  u32 destval;
587  u32 *srcreg;
588 
589  destoffset = decode_rm00_address(rl);
590  DECODE_PRINTF(",");
591  destval = fetch_data_long(destoffset);
592  srcreg = DECODE_RM_LONG_REGISTER(rh);
593  DECODE_PRINTF("\n");
594  TRACE_AND_STEP();
595  destval = or_long(destval, *srcreg);
596  store_data_long(destoffset, destval);
597  }
598  else
599  {
600  u16 destval;
601  u16 *srcreg;
602 
603  destoffset = decode_rm00_address(rl);
604  DECODE_PRINTF(",");
605  destval = fetch_data_word(destoffset);
606  srcreg = DECODE_RM_WORD_REGISTER(rh);
607  DECODE_PRINTF("\n");
608  TRACE_AND_STEP();
609  destval = or_word(destval, *srcreg);
610  store_data_word(destoffset, destval);
611  }
612  break;
613  case 1:
614  if (M.x86.mode & SYSMODE_PREFIX_DATA)
615  {
616  u32 destval;
617  u32 *srcreg;
618 
619  destoffset = decode_rm01_address(rl);
620  DECODE_PRINTF(",");
621  destval = fetch_data_long(destoffset);
622  srcreg = DECODE_RM_LONG_REGISTER(rh);
623  DECODE_PRINTF("\n");
624  TRACE_AND_STEP();
625  destval = or_long(destval, *srcreg);
626  store_data_long(destoffset, destval);
627  }
628  else
629  {
630  u16 destval;
631  u16 *srcreg;
632 
633  destoffset = decode_rm01_address(rl);
634  DECODE_PRINTF(",");
635  destval = fetch_data_word(destoffset);
636  srcreg = DECODE_RM_WORD_REGISTER(rh);
637  DECODE_PRINTF("\n");
638  TRACE_AND_STEP();
639  destval = or_word(destval, *srcreg);
640  store_data_word(destoffset, destval);
641  }
642  break;
643  case 2:
644  if (M.x86.mode & SYSMODE_PREFIX_DATA)
645  {
646  u32 destval;
647  u32 *srcreg;
648 
649  destoffset = decode_rm10_address(rl);
650  DECODE_PRINTF(",");
651  destval = fetch_data_long(destoffset);
652  srcreg = DECODE_RM_LONG_REGISTER(rh);
653  DECODE_PRINTF("\n");
654  TRACE_AND_STEP();
655  destval = or_long(destval, *srcreg);
656  store_data_long(destoffset, destval);
657  }
658  else
659  {
660  u16 destval;
661  u16 *srcreg;
662 
663  destoffset = decode_rm10_address(rl);
664  DECODE_PRINTF(",");
665  destval = fetch_data_word(destoffset);
666  srcreg = DECODE_RM_WORD_REGISTER(rh);
667  DECODE_PRINTF("\n");
668  TRACE_AND_STEP();
669  destval = or_word(destval, *srcreg);
670  store_data_word(destoffset, destval);
671  }
672  break;
673  case 3: /* register to register */
674  if (M.x86.mode & SYSMODE_PREFIX_DATA)
675  {
676  u32 *destreg, *srcreg;
677 
678  destreg = DECODE_RM_LONG_REGISTER(rl);
679  DECODE_PRINTF(",");
680  srcreg = DECODE_RM_LONG_REGISTER(rh);
681  DECODE_PRINTF("\n");
682  TRACE_AND_STEP();
683  *destreg = or_long(*destreg, *srcreg);
684  }
685  else
686  {
687  u16 *destreg, *srcreg;
688 
689  destreg = DECODE_RM_WORD_REGISTER(rl);
690  DECODE_PRINTF(",");
691  srcreg = DECODE_RM_WORD_REGISTER(rh);
692  DECODE_PRINTF("\n");
693  TRACE_AND_STEP();
694  *destreg = or_word(*destreg, *srcreg);
695  }
696  break;
697  }
698  DECODE_CLEAR_SEGOVR();
699  END_OF_INSTR();
700 }
701 
702 /****************************************************************************
703 REMARKS:
704 Handles opcode 0x0a
705 ****************************************************************************/
706 static void x86emuOp_or_byte_R_RM(u8 X86EMU_UNUSED(op1))
707 {
708  int mod, rl, rh;
709  u8 *destreg, *srcreg;
710  uint srcoffset;
711  u8 srcval;
712 
713  START_OF_INSTR();
714  DECODE_PRINTF("OR\t");
715  FETCH_DECODE_MODRM(mod, rh, rl);
716  switch (mod)
717  {
718  case 0:
719  destreg = DECODE_RM_BYTE_REGISTER(rh);
720  DECODE_PRINTF(",");
721  srcoffset = decode_rm00_address(rl);
722  srcval = fetch_data_byte(srcoffset);
723  DECODE_PRINTF("\n");
724  TRACE_AND_STEP();
725  *destreg = or_byte(*destreg, srcval);
726  break;
727  case 1:
728  destreg = DECODE_RM_BYTE_REGISTER(rh);
729  DECODE_PRINTF(",");
730  srcoffset = decode_rm01_address(rl);
731  srcval = fetch_data_byte(srcoffset);
732  DECODE_PRINTF("\n");
733  TRACE_AND_STEP();
734  *destreg = or_byte(*destreg, srcval);
735  break;
736  case 2:
737  destreg = DECODE_RM_BYTE_REGISTER(rh);
738  DECODE_PRINTF(",");
739  srcoffset = decode_rm10_address(rl);
740  srcval = fetch_data_byte(srcoffset);
741  DECODE_PRINTF("\n");
742  TRACE_AND_STEP();
743  *destreg = or_byte(*destreg, srcval);
744  break;
745  case 3: /* register to register */
746  destreg = DECODE_RM_BYTE_REGISTER(rh);
747  DECODE_PRINTF(",");
748  srcreg = DECODE_RM_BYTE_REGISTER(rl);
749  DECODE_PRINTF("\n");
750  TRACE_AND_STEP();
751  *destreg = or_byte(*destreg, *srcreg);
752  break;
753  }
754  DECODE_CLEAR_SEGOVR();
755  END_OF_INSTR();
756 }
757 
758 /****************************************************************************
759 REMARKS:
760 Handles opcode 0x0b
761 ****************************************************************************/
762 static void x86emuOp_or_word_R_RM(u8 X86EMU_UNUSED(op1))
763 {
764  int mod, rl, rh;
765  uint srcoffset;
766 
767  START_OF_INSTR();
768  DECODE_PRINTF("OR\t");
769  FETCH_DECODE_MODRM(mod, rh, rl);
770  switch (mod)
771  {
772  case 0:
773  if (M.x86.mode & SYSMODE_PREFIX_DATA)
774  {
775  u32 *destreg;
776  u32 srcval;
777 
778  destreg = DECODE_RM_LONG_REGISTER(rh);
779  DECODE_PRINTF(",");
780  srcoffset = decode_rm00_address(rl);
781  srcval = fetch_data_long(srcoffset);
782  DECODE_PRINTF("\n");
783  TRACE_AND_STEP();
784  *destreg = or_long(*destreg, srcval);
785  }
786  else
787  {
788  u16 *destreg;
789  u16 srcval;
790 
791  destreg = DECODE_RM_WORD_REGISTER(rh);
792  DECODE_PRINTF(",");
793  srcoffset = decode_rm00_address(rl);
794  srcval = fetch_data_word(srcoffset);
795  DECODE_PRINTF("\n");
796  TRACE_AND_STEP();
797  *destreg = or_word(*destreg, srcval);
798  }
799  break;
800  case 1:
801  if (M.x86.mode & SYSMODE_PREFIX_DATA)
802  {
803  u32 *destreg;
804  u32 srcval;
805 
806  destreg = DECODE_RM_LONG_REGISTER(rh);
807  DECODE_PRINTF(",");
808  srcoffset = decode_rm01_address(rl);
809  srcval = fetch_data_long(srcoffset);
810  DECODE_PRINTF("\n");
811  TRACE_AND_STEP();
812  *destreg = or_long(*destreg, srcval);
813  }
814  else
815  {
816  u16 *destreg;
817  u16 srcval;
818 
819  destreg = DECODE_RM_WORD_REGISTER(rh);
820  DECODE_PRINTF(",");
821  srcoffset = decode_rm01_address(rl);
822  srcval = fetch_data_word(srcoffset);
823  DECODE_PRINTF("\n");
824  TRACE_AND_STEP();
825  *destreg = or_word(*destreg, srcval);
826  }
827  break;
828  case 2:
829  if (M.x86.mode & SYSMODE_PREFIX_DATA)
830  {
831  u32 *destreg;
832  u32 srcval;
833 
834  destreg = DECODE_RM_LONG_REGISTER(rh);
835  DECODE_PRINTF(",");
836  srcoffset = decode_rm10_address(rl);
837  srcval = fetch_data_long(srcoffset);
838  DECODE_PRINTF("\n");
839  TRACE_AND_STEP();
840  *destreg = or_long(*destreg, srcval);
841  }
842  else
843  {
844  u16 *destreg;
845  u16 srcval;
846 
847  destreg = DECODE_RM_WORD_REGISTER(rh);
848  DECODE_PRINTF(",");
849  srcoffset = decode_rm10_address(rl);
850  srcval = fetch_data_word(srcoffset);
851  DECODE_PRINTF("\n");
852  TRACE_AND_STEP();
853  *destreg = or_word(*destreg, srcval);
854  }
855  break;
856  case 3: /* register to register */
857  if (M.x86.mode & SYSMODE_PREFIX_DATA)
858  {
859  u32 *destreg, *srcreg;
860 
861  destreg = DECODE_RM_LONG_REGISTER(rh);
862  DECODE_PRINTF(",");
863  srcreg = DECODE_RM_LONG_REGISTER(rl);
864  DECODE_PRINTF("\n");
865  TRACE_AND_STEP();
866  *destreg = or_long(*destreg, *srcreg);
867  }
868  else
869  {
870  u16 *destreg, *srcreg;
871 
872  destreg = DECODE_RM_WORD_REGISTER(rh);
873  DECODE_PRINTF(",");
874  srcreg = DECODE_RM_WORD_REGISTER(rl);
875  DECODE_PRINTF("\n");
876  TRACE_AND_STEP();
877  *destreg = or_word(*destreg, *srcreg);
878  }
879  break;
880  }
881  DECODE_CLEAR_SEGOVR();
882  END_OF_INSTR();
883 }
884 
885 /****************************************************************************
886 REMARKS:
887 Handles opcode 0x0c
888 ****************************************************************************/
889 static void x86emuOp_or_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
890 {
891  u8 srcval;
892 
893  START_OF_INSTR();
894  DECODE_PRINTF("OR\tAL,");
895  srcval = fetch_byte_imm();
896  DECODE_PRINTF2("%x\n", srcval);
897  TRACE_AND_STEP();
898  M.x86.R_AL = or_byte(M.x86.R_AL, srcval);
899  DECODE_CLEAR_SEGOVR();
900  END_OF_INSTR();
901 }
902 
903 /****************************************************************************
904 REMARKS:
905 Handles opcode 0x0d
906 ****************************************************************************/
907 static void x86emuOp_or_word_AX_IMM(u8 X86EMU_UNUSED(op1))
908 {
909  u32 srcval;
910 
911  START_OF_INSTR();
912  if (M.x86.mode & SYSMODE_PREFIX_DATA)
913  {
914  DECODE_PRINTF("OR\tEAX,");
915  srcval = fetch_long_imm();
916  }
917  else
918  {
919  DECODE_PRINTF("OR\tAX,");
920  srcval = fetch_word_imm();
921  }
922  DECODE_PRINTF2("%x\n", srcval);
923  TRACE_AND_STEP();
924  if (M.x86.mode & SYSMODE_PREFIX_DATA)
925  {
926  M.x86.R_EAX = or_long(M.x86.R_EAX, srcval);
927  }
928  else
929  {
930  M.x86.R_AX = or_word(M.x86.R_AX, (u16) srcval);
931  }
932  DECODE_CLEAR_SEGOVR();
933  END_OF_INSTR();
934 }
935 
936 /****************************************************************************
937 REMARKS:
938 Handles opcode 0x0e
939 ****************************************************************************/
940 static void x86emuOp_push_CS(u8 X86EMU_UNUSED(op1))
941 {
942  START_OF_INSTR();
943  DECODE_PRINTF("PUSH\tCS\n");
944  TRACE_AND_STEP();
945  push_word(M.x86.R_CS);
946  DECODE_CLEAR_SEGOVR();
947  END_OF_INSTR();
948 }
949 
950 /****************************************************************************
951 REMARKS:
952 Handles opcode 0x0f. Escape for two-byte opcode (286 or better)
953 ****************************************************************************/
954 static void x86emuOp_two_byte(u8 X86EMU_UNUSED(op1))
955 {
956  u8 op2 = (*sys_rdb)(((u32) M.x86.R_CS << 4) + (M.x86.R_IP++));
957  INC_DECODED_INST_LEN(1);
958  (*x86emu_optab2[op2])(op2);
959 }
960 
961 /****************************************************************************
962 REMARKS:
963 Handles opcode 0x10
964 ****************************************************************************/
965 static void x86emuOp_adc_byte_RM_R(u8 X86EMU_UNUSED(op1))
966 {
967  int mod, rl, rh;
968  u8 *destreg, *srcreg;
969  uint destoffset;
970  u8 destval;
971 
972  START_OF_INSTR();
973  DECODE_PRINTF("ADC\t");
974  FETCH_DECODE_MODRM(mod, rh, rl);
975  switch (mod)
976  {
977  case 0:
978  destoffset = decode_rm00_address(rl);
979  DECODE_PRINTF(",");
980  destval = fetch_data_byte(destoffset);
981  srcreg = DECODE_RM_BYTE_REGISTER(rh);
982  DECODE_PRINTF("\n");
983  TRACE_AND_STEP();
984  destval = adc_byte(destval, *srcreg);
985  store_data_byte(destoffset, destval);
986  break;
987  case 1:
988  destoffset = decode_rm01_address(rl);
989  DECODE_PRINTF(",");
990  destval = fetch_data_byte(destoffset);
991  srcreg = DECODE_RM_BYTE_REGISTER(rh);
992  DECODE_PRINTF("\n");
993  TRACE_AND_STEP();
994  destval = adc_byte(destval, *srcreg);
995  store_data_byte(destoffset, destval);
996  break;
997  case 2:
998  destoffset = decode_rm10_address(rl);
999  DECODE_PRINTF(",");
1000  destval = fetch_data_byte(destoffset);
1001  srcreg = DECODE_RM_BYTE_REGISTER(rh);
1002  DECODE_PRINTF("\n");
1003  TRACE_AND_STEP();
1004  destval = adc_byte(destval, *srcreg);
1005  store_data_byte(destoffset, destval);
1006  break;
1007  case 3: /* register to register */
1008  destreg = DECODE_RM_BYTE_REGISTER(rl);
1009  DECODE_PRINTF(",");
1010  srcreg = DECODE_RM_BYTE_REGISTER(rh);
1011  DECODE_PRINTF("\n");
1012  TRACE_AND_STEP();
1013  *destreg = adc_byte(*destreg, *srcreg);
1014  break;
1015  }
1016  DECODE_CLEAR_SEGOVR();
1017  END_OF_INSTR();
1018 }
1019 
1020 /****************************************************************************
1021 REMARKS:
1022 Handles opcode 0x11
1023 ****************************************************************************/
1024 static void x86emuOp_adc_word_RM_R(u8 X86EMU_UNUSED(op1))
1025 {
1026  int mod, rl, rh;
1027  uint destoffset;
1028 
1029  START_OF_INSTR();
1030  DECODE_PRINTF("ADC\t");
1031  FETCH_DECODE_MODRM(mod, rh, rl);
1032  switch (mod)
1033  {
1034  case 0:
1035  if (M.x86.mode & SYSMODE_PREFIX_DATA)
1036  {
1037  u32 destval;
1038  u32 *srcreg;
1039 
1040  destoffset = decode_rm00_address(rl);
1041  DECODE_PRINTF(",");
1042  destval = fetch_data_long(destoffset);
1043  srcreg = DECODE_RM_LONG_REGISTER(rh);
1044  DECODE_PRINTF("\n");
1045  TRACE_AND_STEP();
1046  destval = adc_long(destval, *srcreg);
1047  store_data_long(destoffset, destval);
1048  }
1049  else
1050  {
1051  u16 destval;
1052  u16 *srcreg;
1053 
1054  destoffset = decode_rm00_address(rl);
1055  DECODE_PRINTF(",");
1056  destval = fetch_data_word(destoffset);
1057  srcreg = DECODE_RM_WORD_REGISTER(rh);
1058  DECODE_PRINTF("\n");
1059  TRACE_AND_STEP();
1060  destval = adc_word(destval, *srcreg);
1061  store_data_word(destoffset, destval);
1062  }
1063  break;
1064  case 1:
1065  if (M.x86.mode & SYSMODE_PREFIX_DATA)
1066  {
1067  u32 destval;
1068  u32 *srcreg;
1069 
1070  destoffset = decode_rm01_address(rl);
1071  DECODE_PRINTF(",");
1072  destval = fetch_data_long(destoffset);
1073  srcreg = DECODE_RM_LONG_REGISTER(rh);
1074  DECODE_PRINTF("\n");
1075  TRACE_AND_STEP();
1076  destval = adc_long(destval, *srcreg);
1077  store_data_long(destoffset, destval);
1078  }
1079  else
1080  {
1081  u16 destval;
1082  u16 *srcreg;
1083 
1084  destoffset = decode_rm01_address(rl);
1085  DECODE_PRINTF(",");
1086  destval = fetch_data_word(destoffset);
1087  srcreg = DECODE_RM_WORD_REGISTER(rh);
1088  DECODE_PRINTF("\n");
1089  TRACE_AND_STEP();
1090  destval = adc_word(destval, *srcreg);
1091  store_data_word(destoffset, destval);
1092  }
1093  break;
1094  case 2:
1095  if (M.x86.mode & SYSMODE_PREFIX_DATA)
1096  {
1097  u32 destval;
1098  u32 *srcreg;
1099 
1100  destoffset = decode_rm10_address(rl);
1101  DECODE_PRINTF(",");
1102  destval = fetch_data_long(destoffset);
1103  srcreg = DECODE_RM_LONG_REGISTER(rh);
1104  DECODE_PRINTF("\n");
1105  TRACE_AND_STEP();
1106  destval = adc_long(destval, *srcreg);
1107  store_data_long(destoffset, destval);
1108  }
1109  else
1110  {
1111  u16 destval;
1112  u16 *srcreg;
1113 
1114  destoffset = decode_rm10_address(rl);
1115  DECODE_PRINTF(",");
1116  destval = fetch_data_word(destoffset);
1117  srcreg = DECODE_RM_WORD_REGISTER(rh);
1118  DECODE_PRINTF("\n");
1119  TRACE_AND_STEP();
1120  destval = adc_word(destval, *srcreg);
1121  store_data_word(destoffset, destval);
1122  }
1123  break;
1124  case 3: /* register to register */
1125  if (M.x86.mode & SYSMODE_PREFIX_DATA)
1126  {
1127  u32 *destreg, *srcreg;
1128 
1129  destreg = DECODE_RM_LONG_REGISTER(rl);
1130  DECODE_PRINTF(",");
1131  srcreg = DECODE_RM_LONG_REGISTER(rh);
1132  DECODE_PRINTF("\n");
1133  TRACE_AND_STEP();
1134  *destreg = adc_long(*destreg, *srcreg);
1135  }
1136  else
1137  {
1138  u16 *destreg, *srcreg;
1139 
1140  destreg = DECODE_RM_WORD_REGISTER(rl);
1141  DECODE_PRINTF(",");
1142  srcreg = DECODE_RM_WORD_REGISTER(rh);
1143  DECODE_PRINTF("\n");
1144  TRACE_AND_STEP();
1145  *destreg = adc_word(*destreg, *srcreg);
1146  }
1147  break;
1148  }
1149  DECODE_CLEAR_SEGOVR();
1150  END_OF_INSTR();
1151 }
1152 
1153 /****************************************************************************
1154 REMARKS:
1155 Handles opcode 0x12
1156 ****************************************************************************/
1157 static void x86emuOp_adc_byte_R_RM(u8 X86EMU_UNUSED(op1))
1158 {
1159  int mod, rl, rh;
1160  u8 *destreg, *srcreg;
1161  uint srcoffset;
1162  u8 srcval;
1163 
1164  START_OF_INSTR();
1165  DECODE_PRINTF("ADC\t");
1166  FETCH_DECODE_MODRM(mod, rh, rl);
1167  switch (mod)
1168  {
1169  case 0:
1170  destreg = DECODE_RM_BYTE_REGISTER(rh);
1171  DECODE_PRINTF(",");
1172  srcoffset = decode_rm00_address(rl);
1173  srcval = fetch_data_byte(srcoffset);
1174  DECODE_PRINTF("\n");
1175  TRACE_AND_STEP();
1176  *destreg = adc_byte(*destreg, srcval);
1177  break;
1178  case 1:
1179  destreg = DECODE_RM_BYTE_REGISTER(rh);
1180  DECODE_PRINTF(",");
1181  srcoffset = decode_rm01_address(rl);
1182  srcval = fetch_data_byte(srcoffset);
1183  DECODE_PRINTF("\n");
1184  TRACE_AND_STEP();
1185  *destreg = adc_byte(*destreg, srcval);
1186  break;
1187  case 2:
1188  destreg = DECODE_RM_BYTE_REGISTER(rh);
1189  DECODE_PRINTF(",");
1190  srcoffset = decode_rm10_address(rl);
1191  srcval = fetch_data_byte(srcoffset);
1192  DECODE_PRINTF("\n");
1193  TRACE_AND_STEP();
1194  *destreg = adc_byte(*destreg, srcval);
1195  break;
1196  case 3: /* register to register */
1197  destreg = DECODE_RM_BYTE_REGISTER(rh);
1198  DECODE_PRINTF(",");
1199  srcreg = DECODE_RM_BYTE_REGISTER(rl);
1200  DECODE_PRINTF("\n");
1201  TRACE_AND_STEP();
1202  *destreg = adc_byte(*destreg, *srcreg);
1203  break;
1204  }
1205  DECODE_CLEAR_SEGOVR();
1206  END_OF_INSTR();
1207 }
1208 
1209 /****************************************************************************
1210 REMARKS:
1211 Handles opcode 0x13
1212 ****************************************************************************/
1213 static void x86emuOp_adc_word_R_RM(u8 X86EMU_UNUSED(op1))
1214 {
1215  int mod, rl, rh;
1216  uint srcoffset;
1217 
1218  START_OF_INSTR();
1219  DECODE_PRINTF("ADC\t");
1220  FETCH_DECODE_MODRM(mod, rh, rl);
1221  switch (mod)
1222  {
1223  case 0:
1224  if (M.x86.mode & SYSMODE_PREFIX_DATA)
1225  {
1226  u32 *destreg;
1227  u32 srcval;
1228 
1229  destreg = DECODE_RM_LONG_REGISTER(rh);
1230  DECODE_PRINTF(",");
1231  srcoffset = decode_rm00_address(rl);
1232  srcval = fetch_data_long(srcoffset);
1233  DECODE_PRINTF("\n");
1234  TRACE_AND_STEP();
1235  *destreg = adc_long(*destreg, srcval);
1236  }
1237  else
1238  {
1239  u16 *destreg;
1240  u16 srcval;
1241 
1242  destreg = DECODE_RM_WORD_REGISTER(rh);
1243  DECODE_PRINTF(",");
1244  srcoffset = decode_rm00_address(rl);
1245  srcval = fetch_data_word(srcoffset);
1246  DECODE_PRINTF("\n");
1247  TRACE_AND_STEP();
1248  *destreg = adc_word(*destreg, srcval);
1249  }
1250  break;
1251  case 1:
1252  if (M.x86.mode & SYSMODE_PREFIX_DATA)
1253  {
1254  u32 *destreg;
1255  u32 srcval;
1256 
1257  destreg = DECODE_RM_LONG_REGISTER(rh);
1258  DECODE_PRINTF(",");
1259  srcoffset = decode_rm01_address(rl);
1260  srcval = fetch_data_long(srcoffset);
1261  DECODE_PRINTF("\n");
1262  TRACE_AND_STEP();
1263  *destreg = adc_long(*destreg, srcval);
1264  }
1265  else
1266  {
1267  u16 *destreg;
1268  u16 srcval;
1269 
1270  destreg = DECODE_RM_WORD_REGISTER(rh);
1271  DECODE_PRINTF(",");
1272  srcoffset = decode_rm01_address(rl);
1273  srcval = fetch_data_word(srcoffset);
1274  DECODE_PRINTF("\n");
1275  TRACE_AND_STEP();
1276  *destreg = adc_word(*destreg, srcval);
1277  }
1278  break;
1279  case 2:
1280  if (M.x86.mode & SYSMODE_PREFIX_DATA)
1281  {
1282  u32 *destreg;
1283  u32 srcval;
1284 
1285  destreg = DECODE_RM_LONG_REGISTER(rh);
1286  DECODE_PRINTF(",");
1287  srcoffset = decode_rm10_address(rl);
1288  srcval = fetch_data_long(srcoffset);
1289  DECODE_PRINTF("\n");
1290  TRACE_AND_STEP();
1291  *destreg = adc_long(*destreg, srcval);
1292  }
1293  else
1294  {
1295  u16 *destreg;
1296  u16 srcval;
1297 
1298  destreg = DECODE_RM_WORD_REGISTER(rh);
1299  DECODE_PRINTF(",");
1300  srcoffset = decode_rm10_address(rl);
1301  srcval = fetch_data_word(srcoffset);
1302  DECODE_PRINTF("\n");
1303  TRACE_AND_STEP();
1304  *destreg = adc_word(*destreg, srcval);
1305  }
1306  break;
1307  case 3: /* register to register */
1308  if (M.x86.mode & SYSMODE_PREFIX_DATA)
1309  {
1310  u32 *destreg, *srcreg;
1311 
1312  destreg = DECODE_RM_LONG_REGISTER(rh);
1313  DECODE_PRINTF(",");
1314  srcreg = DECODE_RM_LONG_REGISTER(rl);
1315  DECODE_PRINTF("\n");
1316  TRACE_AND_STEP();
1317  *destreg = adc_long(*destreg, *srcreg);
1318  }
1319  else
1320  {
1321  u16 *destreg, *srcreg;
1322 
1323  destreg = DECODE_RM_WORD_REGISTER(rh);
1324  DECODE_PRINTF(",");
1325  srcreg = DECODE_RM_WORD_REGISTER(rl);
1326  DECODE_PRINTF("\n");
1327  TRACE_AND_STEP();
1328  *destreg = adc_word(*destreg, *srcreg);
1329  }
1330  break;
1331  }
1332  DECODE_CLEAR_SEGOVR();
1333  END_OF_INSTR();
1334 }
1335 
1336 /****************************************************************************
1337 REMARKS:
1338 Handles opcode 0x14
1339 ****************************************************************************/
1340 static void x86emuOp_adc_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
1341 {
1342  u8 srcval;
1343 
1344  START_OF_INSTR();
1345  DECODE_PRINTF("ADC\tAL,");
1346  srcval = fetch_byte_imm();
1347  DECODE_PRINTF2("%x\n", srcval);
1348  TRACE_AND_STEP();
1349  M.x86.R_AL = adc_byte(M.x86.R_AL, srcval);
1350  DECODE_CLEAR_SEGOVR();
1351  END_OF_INSTR();
1352 }
1353 
1354 /****************************************************************************
1355 REMARKS:
1356 Handles opcode 0x15
1357 ****************************************************************************/
1358 static void x86emuOp_adc_word_AX_IMM(u8 X86EMU_UNUSED(op1))
1359 {
1360  u32 srcval;
1361 
1362  START_OF_INSTR();
1363  if (M.x86.mode & SYSMODE_PREFIX_DATA)
1364  {
1365  DECODE_PRINTF("ADC\tEAX,");
1366  srcval = fetch_long_imm();
1367  }
1368  else
1369  {
1370  DECODE_PRINTF("ADC\tAX,");
1371  srcval = fetch_word_imm();
1372  }
1373  DECODE_PRINTF2("%x\n", srcval);
1374  TRACE_AND_STEP();
1375  if (M.x86.mode & SYSMODE_PREFIX_DATA)
1376  {
1377  M.x86.R_EAX = adc_long(M.x86.R_EAX, srcval);
1378  }
1379  else
1380  {
1381  M.x86.R_AX = adc_word(M.x86.R_AX, (u16) srcval);
1382  }
1383  DECODE_CLEAR_SEGOVR();
1384  END_OF_INSTR();
1385 }
1386 
1387 /****************************************************************************
1388 REMARKS:
1389 Handles opcode 0x16
1390 ****************************************************************************/
1391 static void x86emuOp_push_SS(u8 X86EMU_UNUSED(op1))
1392 {
1393  START_OF_INSTR();
1394  DECODE_PRINTF("PUSH\tSS\n");
1395  TRACE_AND_STEP();
1396  push_word(M.x86.R_SS);
1397  DECODE_CLEAR_SEGOVR();
1398  END_OF_INSTR();
1399 }
1400 
1401 /****************************************************************************
1402 REMARKS:
1403 Handles opcode 0x17
1404 ****************************************************************************/
1405 static void x86emuOp_pop_SS(u8 X86EMU_UNUSED(op1))
1406 {
1407  START_OF_INSTR();
1408  DECODE_PRINTF("POP\tSS\n");
1409  TRACE_AND_STEP();
1410  M.x86.R_SS = pop_word();
1411  DECODE_CLEAR_SEGOVR();
1412  END_OF_INSTR();
1413 }
1414 
1415 /****************************************************************************
1416 REMARKS:
1417 Handles opcode 0x18
1418 ****************************************************************************/
1419 static void x86emuOp_sbb_byte_RM_R(u8 X86EMU_UNUSED(op1))
1420 {
1421  int mod, rl, rh;
1422  u8 *destreg, *srcreg;
1423  uint destoffset;
1424  u8 destval;
1425 
1426  START_OF_INSTR();
1427  DECODE_PRINTF("SBB\t");
1428  FETCH_DECODE_MODRM(mod, rh, rl);
1429  switch (mod)
1430  {
1431  case 0:
1432  destoffset = decode_rm00_address(rl);
1433  DECODE_PRINTF(",");
1434  destval = fetch_data_byte(destoffset);
1435  srcreg = DECODE_RM_BYTE_REGISTER(rh);
1436  DECODE_PRINTF("\n");
1437  TRACE_AND_STEP();
1438  destval = sbb_byte(destval, *srcreg);
1439  store_data_byte(destoffset, destval);
1440  break;
1441  case 1:
1442  destoffset = decode_rm01_address(rl);
1443  DECODE_PRINTF(",");
1444  destval = fetch_data_byte(destoffset);
1445  srcreg = DECODE_RM_BYTE_REGISTER(rh);
1446  DECODE_PRINTF("\n");
1447  TRACE_AND_STEP();
1448  destval = sbb_byte(destval, *srcreg);
1449  store_data_byte(destoffset, destval);
1450  break;
1451  case 2:
1452  destoffset = decode_rm10_address(rl);
1453  DECODE_PRINTF(",");
1454  destval = fetch_data_byte(destoffset);
1455  srcreg = DECODE_RM_BYTE_REGISTER(rh);
1456  DECODE_PRINTF("\n");
1457  TRACE_AND_STEP();
1458  destval = sbb_byte(destval, *srcreg);
1459  store_data_byte(destoffset, destval);
1460  break;
1461  case 3: /* register to register */
1462  destreg = DECODE_RM_BYTE_REGISTER(rl);
1463  DECODE_PRINTF(",");
1464  srcreg = DECODE_RM_BYTE_REGISTER(rh);
1465  DECODE_PRINTF("\n");
1466  TRACE_AND_STEP();
1467  *destreg = sbb_byte(*destreg, *srcreg);
1468  break;
1469  }
1470  DECODE_CLEAR_SEGOVR();
1471  END_OF_INSTR();
1472 }
1473 
1474 /****************************************************************************
1475 REMARKS:
1476 Handles opcode 0x19
1477 ****************************************************************************/
1478 static void x86emuOp_sbb_word_RM_R(u8 X86EMU_UNUSED(op1))
1479 {
1480  int mod, rl, rh;
1481  uint destoffset;
1482 
1483  START_OF_INSTR();
1484  DECODE_PRINTF("SBB\t");
1485  FETCH_DECODE_MODRM(mod, rh, rl);
1486  switch (mod)
1487  {
1488  case 0:
1489  if (M.x86.mode & SYSMODE_PREFIX_DATA)
1490  {
1491  u32 destval;
1492  u32 *srcreg;
1493 
1494  destoffset = decode_rm00_address(rl);
1495  DECODE_PRINTF(",");
1496  destval = fetch_data_long(destoffset);
1497  srcreg = DECODE_RM_LONG_REGISTER(rh);
1498  DECODE_PRINTF("\n");
1499  TRACE_AND_STEP();
1500  destval = sbb_long(destval, *srcreg);
1501  store_data_long(destoffset, destval);
1502  }
1503  else
1504  {
1505  u16 destval;
1506  u16 *srcreg;
1507 
1508  destoffset = decode_rm00_address(rl);
1509  DECODE_PRINTF(",");
1510  destval = fetch_data_word(destoffset);
1511  srcreg = DECODE_RM_WORD_REGISTER(rh);
1512  DECODE_PRINTF("\n");
1513  TRACE_AND_STEP();
1514  destval = sbb_word(destval, *srcreg);
1515  store_data_word(destoffset, destval);
1516  }
1517  break;
1518  case 1:
1519  if (M.x86.mode & SYSMODE_PREFIX_DATA)
1520  {
1521  u32 destval;
1522  u32 *srcreg;
1523 
1524  destoffset = decode_rm01_address(rl);
1525  DECODE_PRINTF(",");
1526  destval = fetch_data_long(destoffset);
1527  srcreg = DECODE_RM_LONG_REGISTER(rh);
1528  DECODE_PRINTF("\n");
1529  TRACE_AND_STEP();
1530  destval = sbb_long(destval, *srcreg);
1531  store_data_long(destoffset, destval);
1532  }
1533  else
1534  {
1535  u16 destval;
1536  u16 *srcreg;
1537 
1538  destoffset = decode_rm01_address(rl);
1539  DECODE_PRINTF(",");
1540  destval = fetch_data_word(destoffset);
1541  srcreg = DECODE_RM_WORD_REGISTER(rh);
1542  DECODE_PRINTF("\n");
1543  TRACE_AND_STEP();
1544  destval = sbb_word(destval, *srcreg);
1545  store_data_word(destoffset, destval);
1546  }
1547  break;
1548  case 2:
1549  if (M.x86.mode & SYSMODE_PREFIX_DATA)
1550  {
1551  u32 destval;
1552  u32 *srcreg;
1553 
1554  destoffset = decode_rm10_address(rl);
1555  DECODE_PRINTF(",");
1556  destval = fetch_data_long(destoffset);
1557  srcreg = DECODE_RM_LONG_REGISTER(rh);
1558  DECODE_PRINTF("\n");
1559  TRACE_AND_STEP();
1560  destval = sbb_long(destval, *srcreg);
1561  store_data_long(destoffset, destval);
1562  }
1563  else
1564  {
1565  u16 destval;
1566  u16 *srcreg;
1567 
1568  destoffset = decode_rm10_address(rl);
1569  DECODE_PRINTF(",");
1570  destval = fetch_data_word(destoffset);
1571  srcreg = DECODE_RM_WORD_REGISTER(rh);
1572  DECODE_PRINTF("\n");
1573  TRACE_AND_STEP();
1574  destval = sbb_word(destval, *srcreg);
1575  store_data_word(destoffset, destval);
1576  }
1577  break;
1578  case 3: /* register to register */
1579  if (M.x86.mode & SYSMODE_PREFIX_DATA)
1580  {
1581  u32 *destreg, *srcreg;
1582 
1583  destreg = DECODE_RM_LONG_REGISTER(rl);
1584  DECODE_PRINTF(",");
1585  srcreg = DECODE_RM_LONG_REGISTER(rh);
1586  DECODE_PRINTF("\n");
1587  TRACE_AND_STEP();
1588  *destreg = sbb_long(*destreg, *srcreg);
1589  }
1590  else
1591  {
1592  u16 *destreg, *srcreg;
1593 
1594  destreg = DECODE_RM_WORD_REGISTER(rl);
1595  DECODE_PRINTF(",");
1596  srcreg = DECODE_RM_WORD_REGISTER(rh);
1597  DECODE_PRINTF("\n");
1598  TRACE_AND_STEP();
1599  *destreg = sbb_word(*destreg, *srcreg);
1600  }
1601  break;
1602  }
1603  DECODE_CLEAR_SEGOVR();
1604  END_OF_INSTR();
1605 }
1606 
1607 /****************************************************************************
1608 REMARKS:
1609 Handles opcode 0x1a
1610 ****************************************************************************/
1611 static void x86emuOp_sbb_byte_R_RM(u8 X86EMU_UNUSED(op1))
1612 {
1613  int mod, rl, rh;
1614  u8 *destreg, *srcreg;
1615  uint srcoffset;
1616  u8 srcval;
1617 
1618  START_OF_INSTR();
1619  DECODE_PRINTF("SBB\t");
1620  FETCH_DECODE_MODRM(mod, rh, rl);
1621  switch (mod)
1622  {
1623  case 0:
1624  destreg = DECODE_RM_BYTE_REGISTER(rh);
1625  DECODE_PRINTF(",");
1626  srcoffset = decode_rm00_address(rl);
1627  srcval = fetch_data_byte(srcoffset);
1628  DECODE_PRINTF("\n");
1629  TRACE_AND_STEP();
1630  *destreg = sbb_byte(*destreg, srcval);
1631  break;
1632  case 1:
1633  destreg = DECODE_RM_BYTE_REGISTER(rh);
1634  DECODE_PRINTF(",");
1635  srcoffset = decode_rm01_address(rl);
1636  srcval = fetch_data_byte(srcoffset);
1637  DECODE_PRINTF("\n");
1638  TRACE_AND_STEP();
1639  *destreg = sbb_byte(*destreg, srcval);
1640  break;
1641  case 2:
1642  destreg = DECODE_RM_BYTE_REGISTER(rh);
1643  DECODE_PRINTF(",");
1644  srcoffset = decode_rm10_address(rl);
1645  srcval = fetch_data_byte(srcoffset);
1646  DECODE_PRINTF("\n");
1647  TRACE_AND_STEP();
1648  *destreg = sbb_byte(*destreg, srcval);
1649  break;
1650  case 3: /* register to register */
1651  destreg = DECODE_RM_BYTE_REGISTER(rh);
1652  DECODE_PRINTF(",");
1653  srcreg = DECODE_RM_BYTE_REGISTER(rl);
1654  DECODE_PRINTF("\n");
1655  TRACE_AND_STEP();
1656  *destreg = sbb_byte(*destreg, *srcreg);
1657  break;
1658  }
1659  DECODE_CLEAR_SEGOVR();
1660  END_OF_INSTR();
1661 }
1662 
1663 /****************************************************************************
1664 REMARKS:
1665 Handles opcode 0x1b
1666 ****************************************************************************/
1667 static void x86emuOp_sbb_word_R_RM(u8 X86EMU_UNUSED(op1))
1668 {
1669  int mod, rl, rh;
1670  uint srcoffset;
1671 
1672  START_OF_INSTR();
1673  DECODE_PRINTF("SBB\t");
1674  FETCH_DECODE_MODRM(mod, rh, rl);
1675  switch (mod)
1676  {
1677  case 0:
1678  if (M.x86.mode & SYSMODE_PREFIX_DATA)
1679  {
1680  u32 *destreg;
1681  u32 srcval;
1682 
1683  destreg = DECODE_RM_LONG_REGISTER(rh);
1684  DECODE_PRINTF(",");
1685  srcoffset = decode_rm00_address(rl);
1686  srcval = fetch_data_long(srcoffset);
1687  DECODE_PRINTF("\n");
1688  TRACE_AND_STEP();
1689  *destreg = sbb_long(*destreg, srcval);
1690  }
1691  else
1692  {
1693  u16 *destreg;
1694  u16 srcval;
1695 
1696  destreg = DECODE_RM_WORD_REGISTER(rh);
1697  DECODE_PRINTF(",");
1698  srcoffset = decode_rm00_address(rl);
1699  srcval = fetch_data_word(srcoffset);
1700  DECODE_PRINTF("\n");
1701  TRACE_AND_STEP();
1702  *destreg = sbb_word(*destreg, srcval);
1703  }
1704  break;
1705  case 1:
1706  if (M.x86.mode & SYSMODE_PREFIX_DATA)
1707  {
1708  u32 *destreg;
1709  u32 srcval;
1710 
1711  destreg = DECODE_RM_LONG_REGISTER(rh);
1712  DECODE_PRINTF(",");
1713  srcoffset = decode_rm01_address(rl);
1714  srcval = fetch_data_long(srcoffset);
1715  DECODE_PRINTF("\n");
1716  TRACE_AND_STEP();
1717  *destreg = sbb_long(*destreg, srcval);
1718  }
1719  else
1720  {
1721  u16 *destreg;
1722  u16 srcval;
1723 
1724  destreg = DECODE_RM_WORD_REGISTER(rh);
1725  DECODE_PRINTF(",");
1726  srcoffset = decode_rm01_address(rl);
1727  srcval = fetch_data_word(srcoffset);
1728  DECODE_PRINTF("\n");
1729  TRACE_AND_STEP();
1730  *destreg = sbb_word(*destreg, srcval);
1731  }
1732  break;
1733  case 2:
1734  if (M.x86.mode & SYSMODE_PREFIX_DATA)
1735  {
1736  u32 *destreg;
1737  u32 srcval;
1738 
1739  destreg = DECODE_RM_LONG_REGISTER(rh);
1740  DECODE_PRINTF(",");
1741  srcoffset = decode_rm10_address(rl);
1742  srcval = fetch_data_long(srcoffset);
1743  DECODE_PRINTF("\n");
1744  TRACE_AND_STEP();
1745  *destreg = sbb_long(*destreg, srcval);
1746  }
1747  else
1748  {
1749  u16 *destreg;
1750  u16 srcval;
1751 
1752  destreg = DECODE_RM_WORD_REGISTER(rh);
1753  DECODE_PRINTF(",");
1754  srcoffset = decode_rm10_address(rl);
1755  srcval = fetch_data_word(srcoffset);
1756  DECODE_PRINTF("\n");
1757  TRACE_AND_STEP();
1758  *destreg = sbb_word(*destreg, srcval);
1759  }
1760  break;
1761  case 3: /* register to register */
1762  if (M.x86.mode & SYSMODE_PREFIX_DATA)
1763  {
1764  u32 *destreg, *srcreg;
1765 
1766  destreg = DECODE_RM_LONG_REGISTER(rh);
1767  DECODE_PRINTF(",");
1768  srcreg = DECODE_RM_LONG_REGISTER(rl);
1769  DECODE_PRINTF("\n");
1770  TRACE_AND_STEP();
1771  *destreg = sbb_long(*destreg, *srcreg);
1772  }
1773  else
1774  {
1775  u16 *destreg, *srcreg;
1776 
1777  destreg = DECODE_RM_WORD_REGISTER(rh);
1778  DECODE_PRINTF(",");
1779  srcreg = DECODE_RM_WORD_REGISTER(rl);
1780  DECODE_PRINTF("\n");
1781  TRACE_AND_STEP();
1782  *destreg = sbb_word(*destreg, *srcreg);
1783  }
1784  break;
1785  }
1786  DECODE_CLEAR_SEGOVR();
1787  END_OF_INSTR();
1788 }
1789 
1790 /****************************************************************************
1791 REMARKS:
1792 Handles opcode 0x1c
1793 ****************************************************************************/
1794 static void x86emuOp_sbb_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
1795 {
1796  u8 srcval;
1797 
1798  START_OF_INSTR();
1799  DECODE_PRINTF("SBB\tAL,");
1800  srcval = fetch_byte_imm();
1801  DECODE_PRINTF2("%x\n", srcval);
1802  TRACE_AND_STEP();
1803  M.x86.R_AL = sbb_byte(M.x86.R_AL, srcval);
1804  DECODE_CLEAR_SEGOVR();
1805  END_OF_INSTR();
1806 }
1807 
1808 /****************************************************************************
1809 REMARKS:
1810 Handles opcode 0x1d
1811 ****************************************************************************/
1812 static void x86emuOp_sbb_word_AX_IMM(u8 X86EMU_UNUSED(op1))
1813 {
1814  u32 srcval;
1815 
1816  START_OF_INSTR();
1817  if (M.x86.mode & SYSMODE_PREFIX_DATA)
1818  {
1819  DECODE_PRINTF("SBB\tEAX,");
1820  srcval = fetch_long_imm();
1821  }
1822  else
1823  {
1824  DECODE_PRINTF("SBB\tAX,");
1825  srcval = fetch_word_imm();
1826  }
1827  DECODE_PRINTF2("%x\n", srcval);
1828  TRACE_AND_STEP();
1829  if (M.x86.mode & SYSMODE_PREFIX_DATA)
1830  {
1831  M.x86.R_EAX = sbb_long(M.x86.R_EAX, srcval);
1832  }
1833  else
1834  {
1835  M.x86.R_AX = sbb_word(M.x86.R_AX, (u16) srcval);
1836  }
1837  DECODE_CLEAR_SEGOVR();
1838  END_OF_INSTR();
1839 }
1840 
1841 /****************************************************************************
1842 REMARKS:
1843 Handles opcode 0x1e
1844 ****************************************************************************/
1845 static void x86emuOp_push_DS(u8 X86EMU_UNUSED(op1))
1846 {
1847  START_OF_INSTR();
1848  DECODE_PRINTF("PUSH\tDS\n");
1849  TRACE_AND_STEP();
1850  push_word(M.x86.R_DS);
1851  DECODE_CLEAR_SEGOVR();
1852  END_OF_INSTR();
1853 }
1854 
1855 /****************************************************************************
1856 REMARKS:
1857 Handles opcode 0x1f
1858 ****************************************************************************/
1859 static void x86emuOp_pop_DS(u8 X86EMU_UNUSED(op1))
1860 {
1861  START_OF_INSTR();
1862  DECODE_PRINTF("POP\tDS\n");
1863  TRACE_AND_STEP();
1864  M.x86.R_DS = pop_word();
1865  DECODE_CLEAR_SEGOVR();
1866  END_OF_INSTR();
1867 }
1868 
1869 /****************************************************************************
1870 REMARKS:
1871 Handles opcode 0x20
1872 ****************************************************************************/
1873 static void x86emuOp_and_byte_RM_R(u8 X86EMU_UNUSED(op1))
1874 {
1875  int mod, rl, rh;
1876  u8 *destreg, *srcreg;
1877  uint destoffset;
1878  u8 destval;
1879 
1880  START_OF_INSTR();
1881  DECODE_PRINTF("AND\t");
1882  FETCH_DECODE_MODRM(mod, rh, rl);
1883 
1884  switch (mod)
1885  {
1886  case 0:
1887  destoffset = decode_rm00_address(rl);
1888  DECODE_PRINTF(",");
1889  destval = fetch_data_byte(destoffset);
1890  srcreg = DECODE_RM_BYTE_REGISTER(rh);
1891  DECODE_PRINTF("\n");
1892  TRACE_AND_STEP();
1893  destval = and_byte(destval, *srcreg);
1894  store_data_byte(destoffset, destval);
1895  break;
1896 
1897  case 1:
1898  destoffset = decode_rm01_address(rl);
1899  DECODE_PRINTF(",");
1900  destval = fetch_data_byte(destoffset);
1901  srcreg = DECODE_RM_BYTE_REGISTER(rh);
1902  DECODE_PRINTF("\n");
1903  TRACE_AND_STEP();
1904  destval = and_byte(destval, *srcreg);
1905  store_data_byte(destoffset, destval);
1906  break;
1907 
1908  case 2:
1909  destoffset = decode_rm10_address(rl);
1910  DECODE_PRINTF(",");
1911  destval = fetch_data_byte(destoffset);
1912  srcreg = DECODE_RM_BYTE_REGISTER(rh);
1913  DECODE_PRINTF("\n");
1914  TRACE_AND_STEP();
1915  destval = and_byte(destval, *srcreg);
1916  store_data_byte(destoffset, destval);
1917  break;
1918 
1919  case 3: /* register to register */
1920  destreg = DECODE_RM_BYTE_REGISTER(rl);
1921  DECODE_PRINTF(",");
1922  srcreg = DECODE_RM_BYTE_REGISTER(rh);
1923  DECODE_PRINTF("\n");
1924  TRACE_AND_STEP();
1925  *destreg = and_byte(*destreg, *srcreg);
1926  break;
1927  }
1928  DECODE_CLEAR_SEGOVR();
1929  END_OF_INSTR();
1930 }
1931 
1932 /****************************************************************************
1933 REMARKS:
1934 Handles opcode 0x21
1935 ****************************************************************************/
1936 static void x86emuOp_and_word_RM_R(u8 X86EMU_UNUSED(op1))
1937 {
1938  int mod, rl, rh;
1939  uint destoffset;
1940 
1941  START_OF_INSTR();
1942  DECODE_PRINTF("AND\t");
1943  FETCH_DECODE_MODRM(mod, rh, rl);
1944  switch (mod)
1945  {
1946  case 0:
1947  if (M.x86.mode & SYSMODE_PREFIX_DATA)
1948  {
1949  u32 destval;
1950  u32 *srcreg;
1951 
1952  destoffset = decode_rm00_address(rl);
1953  DECODE_PRINTF(",");
1954  destval = fetch_data_long(destoffset);
1955  srcreg = DECODE_RM_LONG_REGISTER(rh);
1956  DECODE_PRINTF("\n");
1957  TRACE_AND_STEP();
1958  destval = and_long(destval, *srcreg);
1959  store_data_long(destoffset, destval);
1960  }
1961  else
1962  {
1963  u16 destval;
1964  u16 *srcreg;
1965 
1966  destoffset = decode_rm00_address(rl);
1967  DECODE_PRINTF(",");
1968  destval = fetch_data_word(destoffset);
1969  srcreg = DECODE_RM_WORD_REGISTER(rh);
1970  DECODE_PRINTF("\n");
1971  TRACE_AND_STEP();
1972  destval = and_word(destval, *srcreg);
1973  store_data_word(destoffset, destval);
1974  }
1975  break;
1976  case 1:
1977  if (M.x86.mode & SYSMODE_PREFIX_DATA)
1978  {
1979  u32 destval;
1980  u32 *srcreg;
1981 
1982  destoffset = decode_rm01_address(rl);
1983  DECODE_PRINTF(",");
1984  destval = fetch_data_long(destoffset);
1985  srcreg = DECODE_RM_LONG_REGISTER(rh);
1986  DECODE_PRINTF("\n");
1987  TRACE_AND_STEP();
1988  destval = and_long(destval, *srcreg);
1989  store_data_long(destoffset, destval);
1990  }
1991  else
1992  {
1993  u16 destval;
1994  u16 *srcreg;
1995 
1996  destoffset = decode_rm01_address(rl);
1997  DECODE_PRINTF(",");
1998  destval = fetch_data_word(destoffset);
1999  srcreg = DECODE_RM_WORD_REGISTER(rh);
2000  DECODE_PRINTF("\n");
2001  TRACE_AND_STEP();
2002  destval = and_word(destval, *srcreg);
2003  store_data_word(destoffset, destval);
2004  }
2005  break;
2006  case 2:
2007  if (M.x86.mode & SYSMODE_PREFIX_DATA)
2008  {
2009  u32 destval;
2010  u32 *srcreg;
2011 
2012  destoffset = decode_rm10_address(rl);
2013  DECODE_PRINTF(",");
2014  destval = fetch_data_long(destoffset);
2015  srcreg = DECODE_RM_LONG_REGISTER(rh);
2016  DECODE_PRINTF("\n");
2017  TRACE_AND_STEP();
2018  destval = and_long(destval, *srcreg);
2019  store_data_long(destoffset, destval);
2020  }
2021  else
2022  {
2023  u16 destval;
2024  u16 *srcreg;
2025 
2026  destoffset = decode_rm10_address(rl);
2027  DECODE_PRINTF(",");
2028  destval = fetch_data_word(destoffset);
2029  srcreg = DECODE_RM_WORD_REGISTER(rh);
2030  DECODE_PRINTF("\n");
2031  TRACE_AND_STEP();
2032  destval = and_word(destval, *srcreg);
2033  store_data_word(destoffset, destval);
2034  }
2035  break;
2036  case 3: /* register to register */
2037  if (M.x86.mode & SYSMODE_PREFIX_DATA)
2038  {
2039  u32 *destreg, *srcreg;
2040 
2041  destreg = DECODE_RM_LONG_REGISTER(rl);
2042  DECODE_PRINTF(",");
2043  srcreg = DECODE_RM_LONG_REGISTER(rh);
2044  DECODE_PRINTF("\n");
2045  TRACE_AND_STEP();
2046  *destreg = and_long(*destreg, *srcreg);
2047  }
2048  else
2049  {
2050  u16 *destreg, *srcreg;
2051 
2052  destreg = DECODE_RM_WORD_REGISTER(rl);
2053  DECODE_PRINTF(",");
2054  srcreg = DECODE_RM_WORD_REGISTER(rh);
2055  DECODE_PRINTF("\n");
2056  TRACE_AND_STEP();
2057  *destreg = and_word(*destreg, *srcreg);
2058  }
2059  break;
2060  }
2061  DECODE_CLEAR_SEGOVR();
2062  END_OF_INSTR();
2063 }
2064 
2065 /****************************************************************************
2066 REMARKS:
2067 Handles opcode 0x22
2068 ****************************************************************************/
2069 static void x86emuOp_and_byte_R_RM(u8 X86EMU_UNUSED(op1))
2070 {
2071  int mod, rl, rh;
2072  u8 *destreg, *srcreg;
2073  uint srcoffset;
2074  u8 srcval;
2075 
2076  START_OF_INSTR();
2077  DECODE_PRINTF("AND\t");
2078  FETCH_DECODE_MODRM(mod, rh, rl);
2079  switch (mod)
2080  {
2081  case 0:
2082  destreg = DECODE_RM_BYTE_REGISTER(rh);
2083  DECODE_PRINTF(",");
2084  srcoffset = decode_rm00_address(rl);
2085  srcval = fetch_data_byte(srcoffset);
2086  DECODE_PRINTF("\n");
2087  TRACE_AND_STEP();
2088  *destreg = and_byte(*destreg, srcval);
2089  break;
2090  case 1:
2091  destreg = DECODE_RM_BYTE_REGISTER(rh);
2092  DECODE_PRINTF(",");
2093  srcoffset = decode_rm01_address(rl);
2094  srcval = fetch_data_byte(srcoffset);
2095  DECODE_PRINTF("\n");
2096  TRACE_AND_STEP();
2097  *destreg = and_byte(*destreg, srcval);
2098  break;
2099  case 2:
2100  destreg = DECODE_RM_BYTE_REGISTER(rh);
2101  DECODE_PRINTF(",");
2102  srcoffset = decode_rm10_address(rl);
2103  srcval = fetch_data_byte(srcoffset);
2104  DECODE_PRINTF("\n");
2105  TRACE_AND_STEP();
2106  *destreg = and_byte(*destreg, srcval);
2107  break;
2108  case 3: /* register to register */
2109  destreg = DECODE_RM_BYTE_REGISTER(rh);
2110  DECODE_PRINTF(",");
2111  srcreg = DECODE_RM_BYTE_REGISTER(rl);
2112  DECODE_PRINTF("\n");
2113  TRACE_AND_STEP();
2114  *destreg = and_byte(*destreg, *srcreg);
2115  break;
2116  }
2117  DECODE_CLEAR_SEGOVR();
2118  END_OF_INSTR();
2119 }
2120 
2121 /****************************************************************************
2122 REMARKS:
2123 Handles opcode 0x23
2124 ****************************************************************************/
2125 static void x86emuOp_and_word_R_RM(u8 X86EMU_UNUSED(op1))
2126 {
2127  int mod, rl, rh;
2128  uint srcoffset;
2129 
2130  START_OF_INSTR();
2131  DECODE_PRINTF("AND\t");
2132  FETCH_DECODE_MODRM(mod, rh, rl);
2133  switch (mod)
2134  {
2135  case 0:
2136  if (M.x86.mode & SYSMODE_PREFIX_DATA)
2137  {
2138  u32 *destreg;
2139  u32 srcval;
2140 
2141  destreg = DECODE_RM_LONG_REGISTER(rh);
2142  DECODE_PRINTF(",");
2143  srcoffset = decode_rm00_address(rl);
2144  srcval = fetch_data_long(srcoffset);
2145  DECODE_PRINTF("\n");
2146  TRACE_AND_STEP();
2147  *destreg = and_long(*destreg, srcval);
2148  }
2149  else
2150  {
2151  u16 *destreg;
2152  u16 srcval;
2153 
2154  destreg = DECODE_RM_WORD_REGISTER(rh);
2155  DECODE_PRINTF(",");
2156  srcoffset = decode_rm00_address(rl);
2157  srcval = fetch_data_word(srcoffset);
2158  DECODE_PRINTF("\n");
2159  TRACE_AND_STEP();
2160  *destreg = and_word(*destreg, srcval);
2161  }
2162  break;
2163  case 1:
2164  if (M.x86.mode & SYSMODE_PREFIX_DATA)
2165  {
2166  u32 *destreg;
2167  u32 srcval;
2168 
2169  destreg = DECODE_RM_LONG_REGISTER(rh);
2170  DECODE_PRINTF(",");
2171  srcoffset = decode_rm01_address(rl);
2172  srcval = fetch_data_long(srcoffset);
2173  DECODE_PRINTF("\n");
2174  TRACE_AND_STEP();
2175  *destreg = and_long(*destreg, srcval);
2176  break;
2177  }
2178  else
2179  {
2180  u16 *destreg;
2181  u16 srcval;
2182 
2183  destreg = DECODE_RM_WORD_REGISTER(rh);
2184  DECODE_PRINTF(",");
2185  srcoffset = decode_rm01_address(rl);
2186  srcval = fetch_data_word(srcoffset);
2187  DECODE_PRINTF("\n");
2188  TRACE_AND_STEP();
2189  *destreg = and_word(*destreg, srcval);
2190  break;
2191  }
2192  case 2:
2193  if (M.x86.mode & SYSMODE_PREFIX_DATA)
2194  {
2195  u32 *destreg;
2196  u32 srcval;
2197 
2198  destreg = DECODE_RM_LONG_REGISTER(rh);
2199  DECODE_PRINTF(",");
2200  srcoffset = decode_rm10_address(rl);
2201  srcval = fetch_data_long(srcoffset);
2202  DECODE_PRINTF("\n");
2203  TRACE_AND_STEP();
2204  *destreg = and_long(*destreg, srcval);
2205  }
2206  else
2207  {
2208  u16 *destreg;
2209  u16 srcval;
2210 
2211  destreg = DECODE_RM_WORD_REGISTER(rh);
2212  DECODE_PRINTF(",");
2213  srcoffset = decode_rm10_address(rl);
2214  srcval = fetch_data_word(srcoffset);
2215  DECODE_PRINTF("\n");
2216  TRACE_AND_STEP();
2217  *destreg = and_word(*destreg, srcval);
2218  }
2219  break;
2220  case 3: /* register to register */
2221  if (M.x86.mode & SYSMODE_PREFIX_DATA)
2222  {
2223  u32 *destreg, *srcreg;
2224 
2225  destreg = DECODE_RM_LONG_REGISTER(rh);
2226  DECODE_PRINTF(",");
2227  srcreg = DECODE_RM_LONG_REGISTER(rl);
2228  DECODE_PRINTF("\n");
2229  TRACE_AND_STEP();
2230  *destreg = and_long(*destreg, *srcreg);
2231  }
2232  else
2233  {
2234  u16 *destreg, *srcreg;
2235 
2236  destreg = DECODE_RM_WORD_REGISTER(rh);
2237  DECODE_PRINTF(",");
2238  srcreg = DECODE_RM_WORD_REGISTER(rl);
2239  DECODE_PRINTF("\n");
2240  TRACE_AND_STEP();
2241  *destreg = and_word(*destreg, *srcreg);
2242  }
2243  break;
2244  }
2245  DECODE_CLEAR_SEGOVR();
2246  END_OF_INSTR();
2247 }
2248 
2249 /****************************************************************************
2250 REMARKS:
2251 Handles opcode 0x24
2252 ****************************************************************************/
2253 static void x86emuOp_and_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
2254 {
2255  u8 srcval;
2256 
2257  START_OF_INSTR();
2258  DECODE_PRINTF("AND\tAL,");
2259  srcval = fetch_byte_imm();
2260  DECODE_PRINTF2("%x\n", srcval);
2261  TRACE_AND_STEP();
2262  M.x86.R_AL = and_byte(M.x86.R_AL, srcval);
2263  DECODE_CLEAR_SEGOVR();
2264  END_OF_INSTR();
2265 }
2266 
2267 /****************************************************************************
2268 REMARKS:
2269 Handles opcode 0x25
2270 ****************************************************************************/
2271 static void x86emuOp_and_word_AX_IMM(u8 X86EMU_UNUSED(op1))
2272 {
2273  u32 srcval;
2274 
2275  START_OF_INSTR();
2276  if (M.x86.mode & SYSMODE_PREFIX_DATA)
2277  {
2278  DECODE_PRINTF("AND\tEAX,");
2279  srcval = fetch_long_imm();
2280  }
2281  else
2282  {
2283  DECODE_PRINTF("AND\tAX,");
2284  srcval = fetch_word_imm();
2285  }
2286  DECODE_PRINTF2("%x\n", srcval);
2287  TRACE_AND_STEP();
2288  if (M.x86.mode & SYSMODE_PREFIX_DATA)
2289  {
2290  M.x86.R_EAX = and_long(M.x86.R_EAX, srcval);
2291  }
2292  else
2293  {
2294  M.x86.R_AX = and_word(M.x86.R_AX, (u16) srcval);
2295  }
2296  DECODE_CLEAR_SEGOVR();
2297  END_OF_INSTR();
2298 }
2299 
2300 /****************************************************************************
2301 REMARKS:
2302 Handles opcode 0x26
2303 ****************************************************************************/
2304 static void x86emuOp_segovr_ES(u8 X86EMU_UNUSED(op1))
2305 {
2306  START_OF_INSTR();
2307  DECODE_PRINTF("ES:\n");
2308  TRACE_AND_STEP();
2309  M.x86.mode |= SYSMODE_SEGOVR_ES;
2310  /*
2311  * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
2312  * opcode subroutines we do not want to do this.
2313  */
2314  END_OF_INSTR();
2315 }
2316 
2317 /****************************************************************************
2318 REMARKS:
2319 Handles opcode 0x27
2320 ****************************************************************************/
2321 static void x86emuOp_daa(u8 X86EMU_UNUSED(op1))
2322 {
2323  START_OF_INSTR();
2324  DECODE_PRINTF("DAA\n");
2325  TRACE_AND_STEP();
2326  M.x86.R_AL = daa_byte(M.x86.R_AL);
2327  DECODE_CLEAR_SEGOVR();
2328  END_OF_INSTR();
2329 }
2330 
2331 /****************************************************************************
2332 REMARKS:
2333 Handles opcode 0x28
2334 ****************************************************************************/
2335 static void x86emuOp_sub_byte_RM_R(u8 X86EMU_UNUSED(op1))
2336 {
2337  int mod, rl, rh;
2338  u8 *destreg, *srcreg;
2339  uint destoffset;
2340  u8 destval;
2341 
2342  START_OF_INSTR();
2343  DECODE_PRINTF("SUB\t");
2344  FETCH_DECODE_MODRM(mod, rh, rl);
2345  switch (mod)
2346  {
2347  case 0:
2348  destoffset = decode_rm00_address(rl);
2349  DECODE_PRINTF(",");
2350  destval = fetch_data_byte(destoffset);
2351  srcreg = DECODE_RM_BYTE_REGISTER(rh);
2352  DECODE_PRINTF("\n");
2353  TRACE_AND_STEP();
2354  destval = sub_byte(destval, *srcreg);
2355  store_data_byte(destoffset, destval);
2356  break;
2357  case 1:
2358  destoffset = decode_rm01_address(rl);
2359  DECODE_PRINTF(",");
2360  destval = fetch_data_byte(destoffset);
2361  srcreg = DECODE_RM_BYTE_REGISTER(rh);
2362  DECODE_PRINTF("\n");
2363  TRACE_AND_STEP();
2364  destval = sub_byte(destval, *srcreg);
2365  store_data_byte(destoffset, destval);
2366  break;
2367  case 2:
2368  destoffset = decode_rm10_address(rl);
2369  DECODE_PRINTF(",");
2370  destval = fetch_data_byte(destoffset);
2371  srcreg = DECODE_RM_BYTE_REGISTER(rh);
2372  DECODE_PRINTF("\n");
2373  TRACE_AND_STEP();
2374  destval = sub_byte(destval, *srcreg);
2375  store_data_byte(destoffset, destval);
2376  break;
2377  case 3: /* register to register */
2378  destreg = DECODE_RM_BYTE_REGISTER(rl);
2379  DECODE_PRINTF(",");
2380  srcreg = DECODE_RM_BYTE_REGISTER(rh);
2381  DECODE_PRINTF("\n");
2382  TRACE_AND_STEP();
2383  *destreg = sub_byte(*destreg, *srcreg);
2384  break;
2385  }
2386  DECODE_CLEAR_SEGOVR();
2387  END_OF_INSTR();
2388 }
2389 
2390 /****************************************************************************
2391 REMARKS:
2392 Handles opcode 0x29
2393 ****************************************************************************/
2394 static void x86emuOp_sub_word_RM_R(u8 X86EMU_UNUSED(op1))
2395 {
2396  int mod, rl, rh;
2397  uint destoffset;
2398 
2399  START_OF_INSTR();
2400  DECODE_PRINTF("SUB\t");
2401  FETCH_DECODE_MODRM(mod, rh, rl);
2402  switch (mod)
2403  {
2404  case 0:
2405  if (M.x86.mode & SYSMODE_PREFIX_DATA)
2406  {
2407  u32 destval;
2408  u32 *srcreg;
2409 
2410  destoffset = decode_rm00_address(rl);
2411  DECODE_PRINTF(",");
2412  destval = fetch_data_long(destoffset);
2413  srcreg = DECODE_RM_LONG_REGISTER(rh);
2414  DECODE_PRINTF("\n");
2415  TRACE_AND_STEP();
2416  destval = sub_long(destval, *srcreg);
2417  store_data_long(destoffset, destval);
2418  }
2419  else
2420  {
2421  u16 destval;
2422  u16 *srcreg;
2423 
2424  destoffset = decode_rm00_address(rl);
2425  DECODE_PRINTF(",");
2426  destval = fetch_data_word(destoffset);
2427  srcreg = DECODE_RM_WORD_REGISTER(rh);
2428  DECODE_PRINTF("\n");
2429  TRACE_AND_STEP();
2430  destval = sub_word(destval, *srcreg);
2431  store_data_word(destoffset, destval);
2432  }
2433  break;
2434  case 1:
2435  if (M.x86.mode & SYSMODE_PREFIX_DATA)
2436  {
2437  u32 destval;
2438  u32 *srcreg;
2439 
2440  destoffset = decode_rm01_address(rl);
2441  DECODE_PRINTF(",");
2442  destval = fetch_data_long(destoffset);
2443  srcreg = DECODE_RM_LONG_REGISTER(rh);
2444  DECODE_PRINTF("\n");
2445  TRACE_AND_STEP();
2446  destval = sub_long(destval, *srcreg);
2447  store_data_long(destoffset, destval);
2448  }
2449  else
2450  {
2451  u16 destval;
2452  u16 *srcreg;
2453 
2454  destoffset = decode_rm01_address(rl);
2455  DECODE_PRINTF(",");
2456  destval = fetch_data_word(destoffset);
2457  srcreg = DECODE_RM_WORD_REGISTER(rh);
2458  DECODE_PRINTF("\n");
2459  TRACE_AND_STEP();
2460  destval = sub_word(destval, *srcreg);
2461  store_data_word(destoffset, destval);
2462  }
2463  break;
2464  case 2:
2465  if (M.x86.mode & SYSMODE_PREFIX_DATA)
2466  {
2467  u32 destval;
2468  u32 *srcreg;
2469 
2470  destoffset = decode_rm10_address(rl);
2471  DECODE_PRINTF(",");
2472  destval = fetch_data_long(destoffset);
2473  srcreg = DECODE_RM_LONG_REGISTER(rh);
2474  DECODE_PRINTF("\n");
2475  TRACE_AND_STEP();
2476  destval = sub_long(destval, *srcreg);
2477  store_data_long(destoffset, destval);
2478  }
2479  else
2480  {
2481  u16 destval;
2482  u16 *srcreg;
2483 
2484  destoffset = decode_rm10_address(rl);
2485  DECODE_PRINTF(",");
2486  destval = fetch_data_word(destoffset);
2487  srcreg = DECODE_RM_WORD_REGISTER(rh);
2488  DECODE_PRINTF("\n");
2489  TRACE_AND_STEP();
2490  destval = sub_word(destval, *srcreg);
2491  store_data_word(destoffset, destval);
2492  }
2493  break;
2494  case 3: /* register to register */
2495  if (M.x86.mode & SYSMODE_PREFIX_DATA)
2496  {
2497  u32 *destreg, *srcreg;
2498 
2499  destreg = DECODE_RM_LONG_REGISTER(rl);
2500  DECODE_PRINTF(",");
2501  srcreg = DECODE_RM_LONG_REGISTER(rh);
2502  DECODE_PRINTF("\n");
2503  TRACE_AND_STEP();
2504  *destreg = sub_long(*destreg, *srcreg);
2505  }
2506  else
2507  {
2508  u16 *destreg, *srcreg;
2509 
2510  destreg = DECODE_RM_WORD_REGISTER(rl);
2511  DECODE_PRINTF(",");
2512  srcreg = DECODE_RM_WORD_REGISTER(rh);
2513  DECODE_PRINTF("\n");
2514  TRACE_AND_STEP();
2515  *destreg = sub_word(*destreg, *srcreg);
2516  }
2517  break;
2518  }
2519  DECODE_CLEAR_SEGOVR();
2520  END_OF_INSTR();
2521 }
2522 
2523 /****************************************************************************
2524 REMARKS:
2525 Handles opcode 0x2a
2526 ****************************************************************************/
2527 static void x86emuOp_sub_byte_R_RM(u8 X86EMU_UNUSED(op1))
2528 {
2529  int mod, rl, rh;
2530  u8 *destreg, *srcreg;
2531  uint srcoffset;
2532  u8 srcval;
2533 
2534  START_OF_INSTR();
2535  DECODE_PRINTF("SUB\t");
2536  FETCH_DECODE_MODRM(mod, rh, rl);
2537  switch (mod)
2538  {
2539  case 0:
2540  destreg = DECODE_RM_BYTE_REGISTER(rh);
2541  DECODE_PRINTF(",");
2542  srcoffset = decode_rm00_address(rl);
2543  srcval = fetch_data_byte(srcoffset);
2544  DECODE_PRINTF("\n");
2545  TRACE_AND_STEP();
2546  *destreg = sub_byte(*destreg, srcval);
2547  break;
2548  case 1:
2549  destreg = DECODE_RM_BYTE_REGISTER(rh);
2550  DECODE_PRINTF(",");
2551  srcoffset = decode_rm01_address(rl);
2552  srcval = fetch_data_byte(srcoffset);
2553  DECODE_PRINTF("\n");
2554  TRACE_AND_STEP();
2555  *destreg = sub_byte(*destreg, srcval);
2556  break;
2557  case 2:
2558  destreg = DECODE_RM_BYTE_REGISTER(rh);
2559  DECODE_PRINTF(",");
2560  srcoffset = decode_rm10_address(rl);
2561  srcval = fetch_data_byte(srcoffset);
2562  DECODE_PRINTF("\n");
2563  TRACE_AND_STEP();
2564  *destreg = sub_byte(*destreg, srcval);
2565  break;
2566  case 3: /* register to register */
2567  destreg = DECODE_RM_BYTE_REGISTER(rh);
2568  DECODE_PRINTF(",");
2569  srcreg = DECODE_RM_BYTE_REGISTER(rl);
2570  DECODE_PRINTF("\n");
2571  TRACE_AND_STEP();
2572  *destreg = sub_byte(*destreg, *srcreg);
2573  break;
2574  }
2575  DECODE_CLEAR_SEGOVR();
2576  END_OF_INSTR();
2577 }
2578 
2579 /****************************************************************************
2580 REMARKS:
2581 Handles opcode 0x2b
2582 ****************************************************************************/
2583 static void x86emuOp_sub_word_R_RM(u8 X86EMU_UNUSED(op1))
2584 {
2585  int mod, rl, rh;
2586  uint srcoffset;
2587 
2588  START_OF_INSTR();
2589  DECODE_PRINTF("SUB\t");
2590  FETCH_DECODE_MODRM(mod, rh, rl);
2591  switch (mod)
2592  {
2593  case 0:
2594  if (M.x86.mode & SYSMODE_PREFIX_DATA)
2595  {
2596  u32 *destreg;
2597  u32 srcval;
2598 
2599  destreg = DECODE_RM_LONG_REGISTER(rh);
2600  DECODE_PRINTF(",");
2601  srcoffset = decode_rm00_address(rl);
2602  srcval = fetch_data_long(srcoffset);
2603  DECODE_PRINTF("\n");
2604  TRACE_AND_STEP();
2605  *destreg = sub_long(*destreg, srcval);
2606  }
2607  else
2608  {
2609  u16 *destreg;
2610  u16 srcval;
2611 
2612  destreg = DECODE_RM_WORD_REGISTER(rh);
2613  DECODE_PRINTF(",");
2614  srcoffset = decode_rm00_address(rl);
2615  srcval = fetch_data_word(srcoffset);
2616  DECODE_PRINTF("\n");
2617  TRACE_AND_STEP();
2618  *destreg = sub_word(*destreg, srcval);
2619  }
2620  break;
2621  case 1:
2622  if (M.x86.mode & SYSMODE_PREFIX_DATA)
2623  {
2624  u32 *destreg;
2625  u32 srcval;
2626 
2627  destreg = DECODE_RM_LONG_REGISTER(rh);
2628  DECODE_PRINTF(",");
2629  srcoffset = decode_rm01_address(rl);
2630  srcval = fetch_data_long(srcoffset);
2631  DECODE_PRINTF("\n");
2632  TRACE_AND_STEP();
2633  *destreg = sub_long(*destreg, srcval);
2634  }
2635  else
2636  {
2637  u16 *destreg;
2638  u16 srcval;
2639 
2640  destreg = DECODE_RM_WORD_REGISTER(rh);
2641  DECODE_PRINTF(",");
2642  srcoffset = decode_rm01_address(rl);
2643  srcval = fetch_data_word(srcoffset);
2644  DECODE_PRINTF("\n");
2645  TRACE_AND_STEP();
2646  *destreg = sub_word(*destreg, srcval);
2647  }
2648  break;
2649  case 2:
2650  if (M.x86.mode & SYSMODE_PREFIX_DATA)
2651  {
2652  u32 *destreg;
2653  u32 srcval;
2654 
2655  destreg = DECODE_RM_LONG_REGISTER(rh);
2656  DECODE_PRINTF(",");
2657  srcoffset = decode_rm10_address(rl);
2658  srcval = fetch_data_long(srcoffset);
2659  DECODE_PRINTF("\n");
2660  TRACE_AND_STEP();
2661  *destreg = sub_long(*destreg, srcval);
2662  }
2663  else
2664  {
2665  u16 *destreg;
2666  u16 srcval;
2667 
2668  destreg = DECODE_RM_WORD_REGISTER(rh);
2669  DECODE_PRINTF(",");
2670  srcoffset = decode_rm10_address(rl);
2671  srcval = fetch_data_word(srcoffset);
2672  DECODE_PRINTF("\n");
2673  TRACE_AND_STEP();
2674  *destreg = sub_word(*destreg, srcval);
2675  }
2676  break;
2677  case 3: /* register to register */
2678  if (M.x86.mode & SYSMODE_PREFIX_DATA)
2679  {
2680  u32 *destreg, *srcreg;
2681 
2682  destreg = DECODE_RM_LONG_REGISTER(rh);
2683  DECODE_PRINTF(",");
2684  srcreg = DECODE_RM_LONG_REGISTER(rl);
2685  DECODE_PRINTF("\n");
2686  TRACE_AND_STEP();
2687  *destreg = sub_long(*destreg, *srcreg);
2688  }
2689  else
2690  {
2691  u16 *destreg, *srcreg;
2692 
2693  destreg = DECODE_RM_WORD_REGISTER(rh);
2694  DECODE_PRINTF(",");
2695  srcreg = DECODE_RM_WORD_REGISTER(rl);
2696  DECODE_PRINTF("\n");
2697  TRACE_AND_STEP();
2698  *destreg = sub_word(*destreg, *srcreg);
2699  }
2700  break;
2701  }
2702  DECODE_CLEAR_SEGOVR();
2703  END_OF_INSTR();
2704 }
2705 
2706 /****************************************************************************
2707 REMARKS:
2708 Handles opcode 0x2c
2709 ****************************************************************************/
2710 static void x86emuOp_sub_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
2711 {
2712  u8 srcval;
2713 
2714  START_OF_INSTR();
2715  DECODE_PRINTF("SUB\tAL,");
2716  srcval = fetch_byte_imm();
2717  DECODE_PRINTF2("%x\n", srcval);
2718  TRACE_AND_STEP();
2719  M.x86.R_AL = sub_byte(M.x86.R_AL, srcval);
2720  DECODE_CLEAR_SEGOVR();
2721  END_OF_INSTR();
2722 }
2723 
2724 /****************************************************************************
2725 REMARKS:
2726 Handles opcode 0x2d
2727 ****************************************************************************/
2728 static void x86emuOp_sub_word_AX_IMM(u8 X86EMU_UNUSED(op1))
2729 {
2730  u32 srcval;
2731 
2732  START_OF_INSTR();
2733  if (M.x86.mode & SYSMODE_PREFIX_DATA)
2734  {
2735  DECODE_PRINTF("SUB\tEAX,");
2736  srcval = fetch_long_imm();
2737  }
2738  else
2739  {
2740  DECODE_PRINTF("SUB\tAX,");
2741  srcval = fetch_word_imm();
2742  }
2743  DECODE_PRINTF2("%x\n", srcval);
2744  TRACE_AND_STEP();
2745  if (M.x86.mode & SYSMODE_PREFIX_DATA)
2746  {
2747  M.x86.R_EAX = sub_long(M.x86.R_EAX, srcval);
2748  }
2749  else
2750  {
2751  M.x86.R_AX = sub_word(M.x86.R_AX, (u16) srcval);
2752  }
2753  DECODE_CLEAR_SEGOVR();
2754  END_OF_INSTR();
2755 }
2756 
2757 /****************************************************************************
2758 REMARKS:
2759 Handles opcode 0x2e
2760 ****************************************************************************/
2761 static void x86emuOp_segovr_CS(u8 X86EMU_UNUSED(op1))
2762 {
2763  START_OF_INSTR();
2764  DECODE_PRINTF("CS:\n");
2765  TRACE_AND_STEP();
2766  M.x86.mode |= SYSMODE_SEGOVR_CS;
2767  /* note no DECODE_CLEAR_SEGOVR here. */
2768  END_OF_INSTR();
2769 }
2770 
2771 /****************************************************************************
2772 REMARKS:
2773 Handles opcode 0x2f
2774 ****************************************************************************/
2775 static void x86emuOp_das(u8 X86EMU_UNUSED(op1))
2776 {
2777  START_OF_INSTR();
2778  DECODE_PRINTF("DAS\n");
2779  TRACE_AND_STEP();
2780  M.x86.R_AL = das_byte(M.x86.R_AL);
2781  DECODE_CLEAR_SEGOVR();
2782  END_OF_INSTR();
2783 }
2784 
2785 /****************************************************************************
2786 REMARKS:
2787 Handles opcode 0x30
2788 ****************************************************************************/
2789 static void x86emuOp_xor_byte_RM_R(u8 X86EMU_UNUSED(op1))
2790 {
2791  int mod, rl, rh;
2792  u8 *destreg, *srcreg;
2793  uint destoffset;
2794  u8 destval;
2795 
2796  START_OF_INSTR();
2797  DECODE_PRINTF("XOR\t");
2798  FETCH_DECODE_MODRM(mod, rh, rl);
2799  switch (mod)
2800  {
2801  case 0:
2802  destoffset = decode_rm00_address(rl);
2803  DECODE_PRINTF(",");
2804  destval = fetch_data_byte(destoffset);
2805  srcreg = DECODE_RM_BYTE_REGISTER(rh);
2806  DECODE_PRINTF("\n");
2807  TRACE_AND_STEP();
2808  destval = xor_byte(destval, *srcreg);
2809  store_data_byte(destoffset, destval);
2810  break;
2811  case 1:
2812  destoffset = decode_rm01_address(rl);
2813  DECODE_PRINTF(",");
2814  destval = fetch_data_byte(destoffset);
2815  srcreg = DECODE_RM_BYTE_REGISTER(rh);
2816  DECODE_PRINTF("\n");
2817  TRACE_AND_STEP();
2818  destval = xor_byte(destval, *srcreg);
2819  store_data_byte(destoffset, destval);
2820  break;
2821  case 2:
2822  destoffset = decode_rm10_address(rl);
2823  DECODE_PRINTF(",");
2824  destval = fetch_data_byte(destoffset);
2825  srcreg = DECODE_RM_BYTE_REGISTER(rh);
2826  DECODE_PRINTF("\n");
2827  TRACE_AND_STEP();
2828  destval = xor_byte(destval, *srcreg);
2829  store_data_byte(destoffset, destval);
2830  break;
2831  case 3: /* register to register */
2832  destreg = DECODE_RM_BYTE_REGISTER(rl);
2833  DECODE_PRINTF(",");
2834  srcreg = DECODE_RM_BYTE_REGISTER(rh);
2835  DECODE_PRINTF("\n");
2836  TRACE_AND_STEP();
2837  *destreg = xor_byte(*destreg, *srcreg);
2838  break;
2839  }
2840  DECODE_CLEAR_SEGOVR();
2841  END_OF_INSTR();
2842 }
2843 
2844 /****************************************************************************
2845 REMARKS:
2846 Handles opcode 0x31
2847 ****************************************************************************/
2848 static void x86emuOp_xor_word_RM_R(u8 X86EMU_UNUSED(op1))
2849 {
2850  int mod, rl, rh;
2851  uint destoffset;
2852 
2853  START_OF_INSTR();
2854  DECODE_PRINTF("XOR\t");
2855  FETCH_DECODE_MODRM(mod, rh, rl);
2856  switch (mod)
2857  {
2858  case 0:
2859  if (M.x86.mode & SYSMODE_PREFIX_DATA)
2860  {
2861  u32 destval;
2862  u32 *srcreg;
2863 
2864  destoffset = decode_rm00_address(rl);
2865  DECODE_PRINTF(",");
2866  destval = fetch_data_long(destoffset);
2867  srcreg = DECODE_RM_LONG_REGISTER(rh);
2868  DECODE_PRINTF("\n");
2869  TRACE_AND_STEP();
2870  destval = xor_long(destval, *srcreg);
2871  store_data_long(destoffset, destval);
2872  }
2873  else
2874  {
2875  u16 destval;
2876  u16 *srcreg;
2877 
2878  destoffset = decode_rm00_address(rl);
2879  DECODE_PRINTF(",");
2880  destval = fetch_data_word(destoffset);
2881  srcreg = DECODE_RM_WORD_REGISTER(rh);
2882  DECODE_PRINTF("\n");
2883  TRACE_AND_STEP();
2884  destval = xor_word(destval, *srcreg);
2885  store_data_word(destoffset, destval);
2886  }
2887  break;
2888  case 1:
2889  if (M.x86.mode & SYSMODE_PREFIX_DATA)
2890  {
2891  u32 destval;
2892  u32 *srcreg;
2893 
2894  destoffset = decode_rm01_address(rl);
2895  DECODE_PRINTF(",");
2896  destval = fetch_data_long(destoffset);
2897  srcreg = DECODE_RM_LONG_REGISTER(rh);
2898  DECODE_PRINTF("\n");
2899  TRACE_AND_STEP();
2900  destval = xor_long(destval, *srcreg);
2901  store_data_long(destoffset, destval);
2902  }
2903  else
2904  {
2905  u16 destval;
2906  u16 *srcreg;
2907 
2908  destoffset = decode_rm01_address(rl);
2909  DECODE_PRINTF(",");
2910  destval = fetch_data_word(destoffset);
2911  srcreg = DECODE_RM_WORD_REGISTER(rh);
2912  DECODE_PRINTF("\n");
2913  TRACE_AND_STEP();
2914  destval = xor_word(destval, *srcreg);
2915  store_data_word(destoffset, destval);
2916  }
2917  break;
2918  case 2:
2919  if (M.x86.mode & SYSMODE_PREFIX_DATA)
2920  {
2921  u32 destval;
2922  u32 *srcreg;
2923 
2924  destoffset = decode_rm10_address(rl);
2925  DECODE_PRINTF(",");
2926  destval = fetch_data_long(destoffset);
2927  srcreg = DECODE_RM_LONG_REGISTER(rh);
2928  DECODE_PRINTF("\n");
2929  TRACE_AND_STEP();
2930  destval = xor_long(destval, *srcreg);
2931  store_data_long(destoffset, destval);
2932  }
2933  else
2934  {
2935  u16 destval;
2936  u16 *srcreg;
2937 
2938  destoffset = decode_rm10_address(rl);
2939  DECODE_PRINTF(",");
2940  destval = fetch_data_word(destoffset);
2941  srcreg = DECODE_RM_WORD_REGISTER(rh);
2942  DECODE_PRINTF("\n");
2943  TRACE_AND_STEP();
2944  destval = xor_word(destval, *srcreg);
2945  store_data_word(destoffset, destval);
2946  }
2947  break;
2948  case 3: /* register to register */
2949  if (M.x86.mode & SYSMODE_PREFIX_DATA)
2950  {
2951  u32 *destreg, *srcreg;
2952 
2953  destreg = DECODE_RM_LONG_REGISTER(rl);
2954  DECODE_PRINTF(",");
2955  srcreg = DECODE_RM_LONG_REGISTER(rh);
2956  DECODE_PRINTF("\n");
2957  TRACE_AND_STEP();
2958  *destreg = xor_long(*destreg, *srcreg);
2959  }
2960  else
2961  {
2962  u16 *destreg, *srcreg;
2963 
2964  destreg = DECODE_RM_WORD_REGISTER(rl);
2965  DECODE_PRINTF(",");
2966  srcreg = DECODE_RM_WORD_REGISTER(rh);
2967  DECODE_PRINTF("\n");
2968  TRACE_AND_STEP();
2969  *destreg = xor_word(*destreg, *srcreg);
2970  }
2971  break;
2972  }
2973  DECODE_CLEAR_SEGOVR();
2974  END_OF_INSTR();
2975 }
2976 
2977 /****************************************************************************
2978 REMARKS:
2979 Handles opcode 0x32
2980 ****************************************************************************/
2981 static void x86emuOp_xor_byte_R_RM(u8 X86EMU_UNUSED(op1))
2982 {
2983  int mod, rl, rh;
2984  u8 *destreg, *srcreg;
2985  uint srcoffset;
2986  u8 srcval;
2987 
2988  START_OF_INSTR();
2989  DECODE_PRINTF("XOR\t");
2990  FETCH_DECODE_MODRM(mod, rh, rl);
2991  switch (mod)
2992  {
2993  case 0:
2994  destreg = DECODE_RM_BYTE_REGISTER(rh);
2995  DECODE_PRINTF(",");
2996  srcoffset = decode_rm00_address(rl);
2997  srcval = fetch_data_byte(srcoffset);
2998  DECODE_PRINTF("\n");
2999  TRACE_AND_STEP();
3000  *destreg = xor_byte(*destreg, srcval);
3001  break;
3002  case 1:
3003  destreg = DECODE_RM_BYTE_REGISTER(rh);
3004  DECODE_PRINTF(",");
3005  srcoffset = decode_rm01_address(rl);
3006  srcval = fetch_data_byte(srcoffset);
3007  DECODE_PRINTF("\n");
3008  TRACE_AND_STEP();
3009  *destreg = xor_byte(*destreg, srcval);
3010  break;
3011  case 2:
3012  destreg = DECODE_RM_BYTE_REGISTER(rh);
3013  DECODE_PRINTF(",");
3014  srcoffset = decode_rm10_address(rl);
3015  srcval = fetch_data_byte(srcoffset);
3016  DECODE_PRINTF("\n");
3017  TRACE_AND_STEP();
3018  *destreg = xor_byte(*destreg, srcval);
3019  break;
3020  case 3: /* register to register */
3021  destreg = DECODE_RM_BYTE_REGISTER(rh);
3022  DECODE_PRINTF(",");
3023  srcreg = DECODE_RM_BYTE_REGISTER(rl);
3024  DECODE_PRINTF("\n");
3025  TRACE_AND_STEP();
3026  *destreg = xor_byte(*destreg, *srcreg);
3027  break;
3028  }
3029  DECODE_CLEAR_SEGOVR();
3030  END_OF_INSTR();
3031 }
3032 
3033 /****************************************************************************
3034 REMARKS:
3035 Handles opcode 0x33
3036 ****************************************************************************/
3037 static void x86emuOp_xor_word_R_RM(u8 X86EMU_UNUSED(op1))
3038 {
3039  int mod, rl, rh;
3040  uint srcoffset;
3041 
3042  START_OF_INSTR();
3043  DECODE_PRINTF("XOR\t");
3044  FETCH_DECODE_MODRM(mod, rh, rl);
3045  switch (mod)
3046  {
3047  case 0:
3048  if (M.x86.mode & SYSMODE_PREFIX_DATA)
3049  {
3050  u32 *destreg;
3051  u32 srcval;
3052 
3053  destreg = DECODE_RM_LONG_REGISTER(rh);
3054  DECODE_PRINTF(",");
3055  srcoffset = decode_rm00_address(rl);
3056  srcval = fetch_data_long(srcoffset);
3057  DECODE_PRINTF("\n");
3058  TRACE_AND_STEP();
3059  *destreg = xor_long(*destreg, srcval);
3060  }
3061  else
3062  {
3063  u16 *destreg;
3064  u16 srcval;
3065 
3066  destreg = DECODE_RM_WORD_REGISTER(rh);
3067  DECODE_PRINTF(",");
3068  srcoffset = decode_rm00_address(rl);
3069  srcval = fetch_data_word(srcoffset);
3070  DECODE_PRINTF("\n");
3071  TRACE_AND_STEP();
3072  *destreg = xor_word(*destreg, srcval);
3073  }
3074  break;
3075  case 1:
3076  if (M.x86.mode & SYSMODE_PREFIX_DATA)
3077  {
3078  u32 *destreg;
3079  u32 srcval;
3080 
3081  destreg = DECODE_RM_LONG_REGISTER(rh);
3082  DECODE_PRINTF(",");
3083  srcoffset = decode_rm01_address(rl);
3084  srcval = fetch_data_long(srcoffset);
3085  DECODE_PRINTF("\n");
3086  TRACE_AND_STEP();
3087  *destreg = xor_long(*destreg, srcval);
3088  }
3089  else
3090  {
3091  u16 *destreg;
3092  u16 srcval;
3093 
3094  destreg = DECODE_RM_WORD_REGISTER(rh);
3095  DECODE_PRINTF(",");
3096  srcoffset = decode_rm01_address(rl);
3097  srcval = fetch_data_word(srcoffset);
3098  DECODE_PRINTF("\n");
3099  TRACE_AND_STEP();
3100  *destreg = xor_word(*destreg, srcval);
3101  }
3102  break;
3103  case 2:
3104  if (M.x86.mode & SYSMODE_PREFIX_DATA)
3105  {
3106  u32 *destreg;
3107  u32 srcval;
3108 
3109  destreg = DECODE_RM_LONG_REGISTER(rh);
3110  DECODE_PRINTF(",");
3111  srcoffset = decode_rm10_address(rl);
3112  srcval = fetch_data_long(srcoffset);
3113  DECODE_PRINTF("\n");
3114  TRACE_AND_STEP();
3115  *destreg = xor_long(*destreg, srcval);
3116  }
3117  else
3118  {
3119  u16 *destreg;
3120  u16 srcval;
3121 
3122  destreg = DECODE_RM_WORD_REGISTER(rh);
3123  DECODE_PRINTF(",");
3124  srcoffset = decode_rm10_address(rl);
3125  srcval = fetch_data_word(srcoffset);
3126  DECODE_PRINTF("\n");
3127  TRACE_AND_STEP();
3128  *destreg = xor_word(*destreg, srcval);
3129  }
3130  break;
3131  case 3: /* register to register */
3132  if (M.x86.mode & SYSMODE_PREFIX_DATA)
3133  {
3134  u32 *destreg, *srcreg;
3135 
3136  destreg = DECODE_RM_LONG_REGISTER(rh);
3137  DECODE_PRINTF(",");
3138  srcreg = DECODE_RM_LONG_REGISTER(rl);
3139  DECODE_PRINTF("\n");
3140  TRACE_AND_STEP();
3141  *destreg = xor_long(*destreg, *srcreg);
3142  }
3143  else
3144  {
3145  u16 *destreg, *srcreg;
3146 
3147  destreg = DECODE_RM_WORD_REGISTER(rh);
3148  DECODE_PRINTF(",");
3149  srcreg = DECODE_RM_WORD_REGISTER(rl);
3150  DECODE_PRINTF("\n");
3151  TRACE_AND_STEP();
3152  *destreg = xor_word(*destreg, *srcreg);
3153  }
3154  break;
3155  }
3156  DECODE_CLEAR_SEGOVR();
3157  END_OF_INSTR();
3158 }
3159 
3160 /****************************************************************************
3161 REMARKS:
3162 Handles opcode 0x34
3163 ****************************************************************************/
3164 static void x86emuOp_xor_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
3165 {
3166  u8 srcval;
3167 
3168  START_OF_INSTR();
3169  DECODE_PRINTF("XOR\tAL,");
3170  srcval = fetch_byte_imm();
3171  DECODE_PRINTF2("%x\n", srcval);
3172  TRACE_AND_STEP();
3173  M.x86.R_AL = xor_byte(M.x86.R_AL, srcval);
3174  DECODE_CLEAR_SEGOVR();
3175  END_OF_INSTR();
3176 }
3177 
3178 /****************************************************************************
3179 REMARKS:
3180 Handles opcode 0x35
3181 ****************************************************************************/
3182 static void x86emuOp_xor_word_AX_IMM(u8 X86EMU_UNUSED(op1))
3183 {
3184  u32 srcval;
3185 
3186  START_OF_INSTR();
3187  if (M.x86.mode & SYSMODE_PREFIX_DATA)
3188  {
3189  DECODE_PRINTF("XOR\tEAX,");
3190  srcval = fetch_long_imm();
3191  }
3192  else
3193  {
3194  DECODE_PRINTF("XOR\tAX,");
3195  srcval = fetch_word_imm();
3196  }
3197  DECODE_PRINTF2("%x\n", srcval);
3198  TRACE_AND_STEP();
3199  if (M.x86.mode & SYSMODE_PREFIX_DATA)
3200  {
3201  M.x86.R_EAX = xor_long(M.x86.R_EAX, srcval);
3202  }
3203  else
3204  {
3205  M.x86.R_AX = xor_word(M.x86.R_AX, (u16) srcval);
3206  }
3207  DECODE_CLEAR_SEGOVR();
3208  END_OF_INSTR();
3209 }
3210 
3211 /****************************************************************************
3212 REMARKS:
3213 Handles opcode 0x36
3214 ****************************************************************************/
3215 static void x86emuOp_segovr_SS(u8 X86EMU_UNUSED(op1))
3216 {
3217  START_OF_INSTR();
3218  DECODE_PRINTF("SS:\n");
3219  TRACE_AND_STEP();
3220  M.x86.mode |= SYSMODE_SEGOVR_SS;
3221  /* no DECODE_CLEAR_SEGOVR ! */
3222  END_OF_INSTR();
3223 }
3224 
3225 /****************************************************************************
3226 REMARKS:
3227 Handles opcode 0x37
3228 ****************************************************************************/
3229 static void x86emuOp_aaa(u8 X86EMU_UNUSED(op1))
3230 {
3231  START_OF_INSTR();
3232  DECODE_PRINTF("AAA\n");
3233  TRACE_AND_STEP();
3234  M.x86.R_AX = aaa_word(M.x86.R_AX);
3235  DECODE_CLEAR_SEGOVR();
3236  END_OF_INSTR();
3237 }
3238 
3239 /****************************************************************************
3240 REMARKS:
3241 Handles opcode 0x38
3242 ****************************************************************************/
3243 static void x86emuOp_cmp_byte_RM_R(u8 X86EMU_UNUSED(op1))
3244 {
3245  int mod, rl, rh;
3246  uint destoffset;
3247  u8 *destreg, *srcreg;
3248  u8 destval;
3249 
3250  START_OF_INSTR();
3251  DECODE_PRINTF("CMP\t");
3252  FETCH_DECODE_MODRM(mod, rh, rl);
3253  switch (mod)
3254  {
3255  case 0:
3256  destoffset = decode_rm00_address(rl);
3257  DECODE_PRINTF(",");
3258  destval = fetch_data_byte(destoffset);
3259  srcreg = DECODE_RM_BYTE_REGISTER(rh);
3260  DECODE_PRINTF("\n");
3261  TRACE_AND_STEP();
3262  cmp_byte(destval, *srcreg);
3263  break;
3264  case 1:
3265  destoffset = decode_rm01_address(rl);
3266  DECODE_PRINTF(",");
3267  destval = fetch_data_byte(destoffset);
3268  srcreg = DECODE_RM_BYTE_REGISTER(rh);
3269  DECODE_PRINTF("\n");
3270  TRACE_AND_STEP();
3271  cmp_byte(destval, *srcreg);
3272  break;
3273  case 2:
3274  destoffset = decode_rm10_address(rl);
3275  DECODE_PRINTF(",");
3276  destval = fetch_data_byte(destoffset);
3277  srcreg = DECODE_RM_BYTE_REGISTER(rh);
3278  DECODE_PRINTF("\n");
3279  TRACE_AND_STEP();
3280  cmp_byte(destval, *srcreg);
3281  break;
3282  case 3: /* register to register */
3283  destreg = DECODE_RM_BYTE_REGISTER(rl);
3284  DECODE_PRINTF(",");
3285  srcreg = DECODE_RM_BYTE_REGISTER(rh);
3286  DECODE_PRINTF("\n");
3287  TRACE_AND_STEP();
3288  cmp_byte(*destreg, *srcreg);
3289  break;
3290  }
3291  DECODE_CLEAR_SEGOVR();
3292  END_OF_INSTR();
3293 }
3294 
3295 /****************************************************************************
3296 REMARKS:
3297 Handles opcode 0x39
3298 ****************************************************************************/
3299 static void x86emuOp_cmp_word_RM_R(u8 X86EMU_UNUSED(op1))
3300 {
3301  int mod, rl, rh;
3302  uint destoffset;
3303 
3304  START_OF_INSTR();
3305  DECODE_PRINTF("CMP\t");
3306  FETCH_DECODE_MODRM(mod, rh, rl);
3307  switch (mod)
3308  {
3309  case 0:
3310  if (M.x86.mode & SYSMODE_PREFIX_DATA)
3311  {
3312  u32 destval;
3313  u32 *srcreg;
3314 
3315  destoffset = decode_rm00_address(rl);
3316  DECODE_PRINTF(",");
3317  destval = fetch_data_long(destoffset);
3318  srcreg = DECODE_RM_LONG_REGISTER(rh);
3319  DECODE_PRINTF("\n");
3320  TRACE_AND_STEP();
3321  cmp_long(destval, *srcreg);
3322  }
3323  else
3324  {
3325  u16 destval;
3326  u16 *srcreg;
3327 
3328  destoffset = decode_rm00_address(rl);
3329  DECODE_PRINTF(",");
3330  destval = fetch_data_word(destoffset);
3331  srcreg = DECODE_RM_WORD_REGISTER(rh);
3332  DECODE_PRINTF("\n");
3333  TRACE_AND_STEP();
3334  cmp_word(destval, *srcreg);
3335  }
3336  break;
3337  case 1:
3338  if (M.x86.mode & SYSMODE_PREFIX_DATA)
3339  {
3340  u32 destval;
3341  u32 *srcreg;
3342 
3343  destoffset = decode_rm01_address(rl);
3344  DECODE_PRINTF(",");
3345  destval = fetch_data_long(destoffset);
3346  srcreg = DECODE_RM_LONG_REGISTER(rh);
3347  DECODE_PRINTF("\n");
3348  TRACE_AND_STEP();
3349  cmp_long(destval, *srcreg);
3350  }
3351  else
3352  {
3353  u16 destval;
3354  u16 *srcreg;
3355 
3356  destoffset = decode_rm01_address(rl);
3357  DECODE_PRINTF(",");
3358  destval = fetch_data_word(destoffset);
3359  srcreg = DECODE_RM_WORD_REGISTER(rh);
3360  DECODE_PRINTF("\n");
3361  TRACE_AND_STEP();
3362  cmp_word(destval, *srcreg);
3363  }
3364  break;
3365  case 2:
3366  if (M.x86.mode & SYSMODE_PREFIX_DATA)
3367  {
3368  u32 destval;
3369  u32 *srcreg;
3370 
3371  destoffset = decode_rm10_address(rl);
3372  DECODE_PRINTF(",");
3373  destval = fetch_data_long(destoffset);
3374  srcreg = DECODE_RM_LONG_REGISTER(rh);
3375  DECODE_PRINTF("\n");
3376  TRACE_AND_STEP();
3377  cmp_long(destval, *srcreg);
3378  }
3379  else
3380  {
3381  u16 destval;
3382  u16 *srcreg;
3383 
3384  destoffset = decode_rm10_address(rl);
3385  DECODE_PRINTF(",");
3386  destval = fetch_data_word(destoffset);
3387  srcreg = DECODE_RM_WORD_REGISTER(rh);
3388  DECODE_PRINTF("\n");
3389  TRACE_AND_STEP();
3390  cmp_word(destval, *srcreg);
3391  }
3392  break;
3393  case 3: /* register to register */
3394  if (M.x86.mode & SYSMODE_PREFIX_DATA)
3395  {
3396  u32 *destreg, *srcreg;
3397 
3398  destreg = DECODE_RM_LONG_REGISTER(rl);
3399  DECODE_PRINTF(",");
3400  srcreg = DECODE_RM_LONG_REGISTER(rh);
3401  DECODE_PRINTF("\n");
3402  TRACE_AND_STEP();
3403  cmp_long(*destreg, *srcreg);
3404  }
3405  else
3406  {
3407  u16 *destreg, *srcreg;
3408 
3409  destreg = DECODE_RM_WORD_REGISTER(rl);
3410  DECODE_PRINTF(",");
3411  srcreg = DECODE_RM_WORD_REGISTER(rh);
3412  DECODE_PRINTF("\n");
3413  TRACE_AND_STEP();
3414  cmp_word(*destreg, *srcreg);
3415  }
3416  break;
3417  }
3418  DECODE_CLEAR_SEGOVR();
3419  END_OF_INSTR();
3420 }
3421 
3422 /****************************************************************************
3423 REMARKS:
3424 Handles opcode 0x3a
3425 ****************************************************************************/
3426 static void x86emuOp_cmp_byte_R_RM(u8 X86EMU_UNUSED(op1))
3427 {
3428  int mod, rl, rh;
3429  u8 *destreg, *srcreg;
3430  uint srcoffset;
3431  u8 srcval;
3432 
3433  START_OF_INSTR();
3434  DECODE_PRINTF("CMP\t");
3435  FETCH_DECODE_MODRM(mod, rh, rl);
3436  switch (mod)
3437  {
3438  case 0:
3439  destreg = DECODE_RM_BYTE_REGISTER(rh);
3440  DECODE_PRINTF(",");
3441  srcoffset = decode_rm00_address(rl);
3442  srcval = fetch_data_byte(srcoffset);
3443  DECODE_PRINTF("\n");
3444  TRACE_AND_STEP();
3445  cmp_byte(*destreg, srcval);
3446  break;
3447  case 1:
3448  destreg = DECODE_RM_BYTE_REGISTER(rh);
3449  DECODE_PRINTF(",");
3450  srcoffset = decode_rm01_address(rl);
3451  srcval = fetch_data_byte(srcoffset);
3452  DECODE_PRINTF("\n");
3453  TRACE_AND_STEP();
3454  cmp_byte(*destreg, srcval);
3455  break;
3456  case 2:
3457  destreg = DECODE_RM_BYTE_REGISTER(rh);
3458  DECODE_PRINTF(",");
3459  srcoffset = decode_rm10_address(rl);
3460  srcval = fetch_data_byte(srcoffset);
3461  DECODE_PRINTF("\n");
3462  TRACE_AND_STEP();
3463  cmp_byte(*destreg, srcval);
3464  break;
3465  case 3: /* register to register */
3466  destreg = DECODE_RM_BYTE_REGISTER(rh);
3467  DECODE_PRINTF(",");
3468  srcreg = DECODE_RM_BYTE_REGISTER(rl);
3469  DECODE_PRINTF("\n");
3470  TRACE_AND_STEP();
3471  cmp_byte(*destreg, *srcreg);
3472  break;
3473  }
3474  DECODE_CLEAR_SEGOVR();
3475  END_OF_INSTR();
3476 }
3477 
3478 /****************************************************************************
3479 REMARKS:
3480 Handles opcode 0x3b
3481 ****************************************************************************/
3482 static void x86emuOp_cmp_word_R_RM(u8 X86EMU_UNUSED(op1))
3483 {
3484  int mod, rl, rh;
3485  uint srcoffset;
3486 
3487  START_OF_INSTR();
3488  DECODE_PRINTF("CMP\t");
3489  FETCH_DECODE_MODRM(mod, rh, rl);
3490  switch (mod)
3491  {
3492  case 0:
3493  if (M.x86.mode & SYSMODE_PREFIX_DATA)
3494  {
3495  u32 *destreg;
3496  u32 srcval;
3497 
3498  destreg = DECODE_RM_LONG_REGISTER(rh);
3499  DECODE_PRINTF(",");
3500  srcoffset = decode_rm00_address(rl);
3501  srcval = fetch_data_long(srcoffset);
3502  DECODE_PRINTF("\n");
3503  TRACE_AND_STEP();
3504  cmp_long(*destreg, srcval);
3505  }
3506  else
3507  {
3508  u16 *destreg;
3509  u16 srcval;
3510 
3511  destreg = DECODE_RM_WORD_REGISTER(rh);
3512  DECODE_PRINTF(",");
3513  srcoffset = decode_rm00_address(rl);
3514  srcval = fetch_data_word(srcoffset);
3515  DECODE_PRINTF("\n");
3516  TRACE_AND_STEP();
3517  cmp_word(*destreg, srcval);
3518  }
3519  break;
3520  case 1:
3521  if (M.x86.mode & SYSMODE_PREFIX_DATA)
3522  {
3523  u32 *destreg;
3524  u32 srcval;
3525 
3526  destreg = DECODE_RM_LONG_REGISTER(rh);
3527  DECODE_PRINTF(",");
3528  srcoffset = decode_rm01_address(rl);
3529  srcval = fetch_data_long(srcoffset);
3530  DECODE_PRINTF("\n");
3531  TRACE_AND_STEP();
3532  cmp_long(*destreg, srcval);
3533  }
3534  else
3535  {
3536  u16 *destreg;
3537  u16 srcval;
3538 
3539  destreg = DECODE_RM_WORD_REGISTER(rh);
3540  DECODE_PRINTF(",");
3541  srcoffset = decode_rm01_address(rl);
3542  srcval = fetch_data_word(srcoffset);
3543  DECODE_PRINTF("\n");
3544  TRACE_AND_STEP();
3545  cmp_word(*destreg, srcval);
3546  }
3547  break;
3548  case 2:
3549  if (M.x86.mode & SYSMODE_PREFIX_DATA)
3550  {
3551  u32 *destreg;
3552  u32 srcval;
3553 
3554  destreg = DECODE_RM_LONG_REGISTER(rh);
3555  DECODE_PRINTF(",");
3556  srcoffset = decode_rm10_address(rl);
3557  srcval = fetch_data_long(srcoffset);
3558  DECODE_PRINTF("\n");
3559  TRACE_AND_STEP();
3560  cmp_long(*destreg, srcval);
3561  }
3562  else
3563  {
3564  u16 *destreg;
3565  u16 srcval;
3566 
3567  destreg = DECODE_RM_WORD_REGISTER(rh);
3568  DECODE_PRINTF(",");
3569  srcoffset = decode_rm10_address(rl);
3570  srcval = fetch_data_word(srcoffset);
3571  DECODE_PRINTF("\n");
3572  TRACE_AND_STEP();
3573  cmp_word(*destreg, srcval);
3574  }
3575  break;
3576  case 3: /* register to register */
3577  if (M.x86.mode & SYSMODE_PREFIX_DATA)
3578  {
3579  u32 *destreg, *srcreg;
3580 
3581  destreg = DECODE_RM_LONG_REGISTER(rh);
3582  DECODE_PRINTF(",");
3583  srcreg = DECODE_RM_LONG_REGISTER(rl);
3584  DECODE_PRINTF("\n");
3585  TRACE_AND_STEP();
3586  cmp_long(*destreg, *srcreg);
3587  }
3588  else
3589  {
3590  u16 *destreg, *srcreg;
3591 
3592  destreg = DECODE_RM_WORD_REGISTER(rh);
3593  DECODE_PRINTF(",");
3594  srcreg = DECODE_RM_WORD_REGISTER(rl);
3595  DECODE_PRINTF("\n");
3596  TRACE_AND_STEP();
3597  cmp_word(*destreg, *srcreg);
3598  }
3599  break;
3600  }
3601  DECODE_CLEAR_SEGOVR();
3602  END_OF_INSTR();
3603 }
3604 
3605 /****************************************************************************
3606 REMARKS:
3607 Handles opcode 0x3c
3608 ****************************************************************************/
3609 static void x86emuOp_cmp_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
3610 {
3611  u8 srcval;
3612 
3613  START_OF_INSTR();
3614  DECODE_PRINTF("CMP\tAL,");
3615  srcval = fetch_byte_imm();
3616  DECODE_PRINTF2("%x\n", srcval);
3617  TRACE_AND_STEP();
3618  cmp_byte(M.x86.R_AL, srcval);
3619  DECODE_CLEAR_SEGOVR();
3620  END_OF_INSTR();
3621 }
3622 
3623 /****************************************************************************
3624 REMARKS:
3625 Handles opcode 0x3d
3626 ****************************************************************************/
3627 static void x86emuOp_cmp_word_AX_IMM(u8 X86EMU_UNUSED(op1))
3628 {
3629  u32 srcval;
3630 
3631  START_OF_INSTR();
3632  if (M.x86.mode & SYSMODE_PREFIX_DATA)
3633  {
3634  DECODE_PRINTF("CMP\tEAX,");
3635  srcval = fetch_long_imm();
3636  }
3637  else
3638  {
3639  DECODE_PRINTF("CMP\tAX,");
3640  srcval = fetch_word_imm();
3641  }
3642  DECODE_PRINTF2("%x\n", srcval);
3643  TRACE_AND_STEP();
3644  if (M.x86.mode & SYSMODE_PREFIX_DATA)
3645  {
3646  cmp_long(M.x86.R_EAX, srcval);
3647  }
3648  else
3649  {
3650  cmp_word(M.x86.R_AX, (u16) srcval);
3651  }
3652  DECODE_CLEAR_SEGOVR();
3653  END_OF_INSTR();
3654 }
3655 
3656 /****************************************************************************
3657 REMARKS:
3658 Handles opcode 0x3e
3659 ****************************************************************************/
3660 static void x86emuOp_segovr_DS(u8 X86EMU_UNUSED(op1))
3661 {
3662  START_OF_INSTR();
3663  DECODE_PRINTF("DS:\n");
3664  TRACE_AND_STEP();
3665  M.x86.mode |= SYSMODE_SEGOVR_DS;
3666  /* NO DECODE_CLEAR_SEGOVR! */
3667  END_OF_INSTR();
3668 }
3669 
3670 /****************************************************************************
3671 REMARKS:
3672 Handles opcode 0x3f
3673 ****************************************************************************/
3674 static void x86emuOp_aas(u8 X86EMU_UNUSED(op1))
3675 {
3676  START_OF_INSTR();
3677  DECODE_PRINTF("AAS\n");
3678  TRACE_AND_STEP();
3679  M.x86.R_AX = aas_word(M.x86.R_AX);
3680  DECODE_CLEAR_SEGOVR();
3681  END_OF_INSTR();
3682 }
3683 
3684 /****************************************************************************
3685 REMARKS:
3686 Handles opcode 0x40
3687 ****************************************************************************/
3688 static void x86emuOp_inc_AX(u8 X86EMU_UNUSED(op1))
3689 {
3690  START_OF_INSTR();
3691  if (M.x86.mode & SYSMODE_PREFIX_DATA)
3692  {
3693  DECODE_PRINTF("INC\tEAX\n");
3694  }
3695  else
3696  {
3697  DECODE_PRINTF("INC\tAX\n");
3698  }
3699  TRACE_AND_STEP();
3700  if (M.x86.mode & SYSMODE_PREFIX_DATA)
3701  {
3702  M.x86.R_EAX = inc_long(M.x86.R_EAX);
3703  }
3704  else
3705  {
3706  M.x86.R_AX = inc_word(M.x86.R_AX);
3707  }
3708  DECODE_CLEAR_SEGOVR();
3709  END_OF_INSTR();
3710 }
3711 
3712 /****************************************************************************
3713 REMARKS:
3714 Handles opcode 0x41
3715 ****************************************************************************/
3716 static void x86emuOp_inc_CX(u8 X86EMU_UNUSED(op1))
3717 {
3718  START_OF_INSTR();
3719  if (M.x86.mode & SYSMODE_PREFIX_DATA)
3720  {
3721  DECODE_PRINTF("INC\tECX\n");
3722  }
3723  else
3724  {
3725  DECODE_PRINTF("INC\tCX\n");
3726  }
3727  TRACE_AND_STEP();
3728  if (M.x86.mode & SYSMODE_PREFIX_DATA)
3729  {
3730  M.x86.R_ECX = inc_long(M.x86.R_ECX);
3731  }
3732  else
3733  {
3734  M.x86.R_CX = inc_word(M.x86.R_CX);
3735  }
3736  DECODE_CLEAR_SEGOVR();
3737  END_OF_INSTR();
3738 }
3739 
3740 /****************************************************************************
3741 REMARKS:
3742 Handles opcode 0x42
3743 ****************************************************************************/
3744 static void x86emuOp_inc_DX(u8 X86EMU_UNUSED(op1))
3745 {
3746  START_OF_INSTR();
3747  if (M.x86.mode & SYSMODE_PREFIX_DATA)
3748  {
3749  DECODE_PRINTF("INC\tEDX\n");
3750  }
3751  else
3752  {
3753  DECODE_PRINTF("INC\tDX\n");
3754  }
3755  TRACE_AND_STEP();
3756  if (M.x86.mode & SYSMODE_PREFIX_DATA)
3757  {
3758  M.x86.R_EDX = inc_long(M.x86.R_EDX);
3759  }
3760  else
3761  {
3762  M.x86.R_DX = inc_word(M.x86.R_DX);
3763  }
3764  DECODE_CLEAR_SEGOVR();
3765  END_OF_INSTR();
3766 }
3767 
3768 /****************************************************************************
3769 REMARKS:
3770 Handles opcode 0x43
3771 ****************************************************************************/
3772 static void x86emuOp_inc_BX(u8 X86EMU_UNUSED(op1))
3773 {
3774  START_OF_INSTR();
3775  if (M.x86.mode & SYSMODE_PREFIX_DATA)
3776  {
3777  DECODE_PRINTF("INC\tEBX\n");
3778  }
3779  else
3780  {
3781  DECODE_PRINTF("INC\tBX\n");
3782  }
3783  TRACE_AND_STEP();
3784  if (M.x86.mode & SYSMODE_PREFIX_DATA)
3785  {
3786  M.x86.R_EBX = inc_long(M.x86.R_EBX);
3787  }
3788  else
3789  {
3790  M.x86.R_BX = inc_word(M.x86.R_BX);
3791  }
3792  DECODE_CLEAR_SEGOVR();
3793  END_OF_INSTR();
3794 }
3795 
3796 /****************************************************************************
3797 REMARKS:
3798 Handles opcode 0x44
3799 ****************************************************************************/
3800 static void x86emuOp_inc_SP(u8 X86EMU_UNUSED(op1))
3801 {
3802  START_OF_INSTR();
3803  if (M.x86.mode & SYSMODE_PREFIX_DATA)
3804  {
3805  DECODE_PRINTF("INC\tESP\n");
3806  }
3807  else
3808  {
3809  DECODE_PRINTF("INC\tSP\n");
3810  }
3811  TRACE_AND_STEP();
3812  if (M.x86.mode & SYSMODE_PREFIX_DATA)
3813  {
3814  M.x86.R_ESP = inc_long(M.x86.R_ESP);
3815  }
3816  else
3817  {
3818  M.x86.R_SP = inc_word(M.x86.R_SP);
3819  }
3820  DECODE_CLEAR_SEGOVR();
3821  END_OF_INSTR();
3822 }
3823 
3824 /****************************************************************************
3825 REMARKS:
3826 Handles opcode 0x45
3827 ****************************************************************************/
3828 static void x86emuOp_inc_BP(u8 X86EMU_UNUSED(op1))
3829 {
3830  START_OF_INSTR();
3831  if (M.x86.mode & SYSMODE_PREFIX_DATA)
3832  {
3833  DECODE_PRINTF("INC\tEBP\n");
3834  }
3835  else
3836  {
3837  DECODE_PRINTF("INC\tBP\n");
3838  }
3839  TRACE_AND_STEP();
3840  if (M.x86.mode & SYSMODE_PREFIX_DATA)
3841  {
3842  M.x86.R_EBP = inc_long(M.x86.R_EBP);
3843  }
3844  else
3845  {
3846  M.x86.R_BP = inc_word(M.x86.R_BP);
3847  }
3848  DECODE_CLEAR_SEGOVR();
3849  END_OF_INSTR();
3850 }
3851 
3852 /****************************************************************************
3853 REMARKS:
3854 Handles opcode 0x46
3855 ****************************************************************************/
3856 static void x86emuOp_inc_SI(u8 X86EMU_UNUSED(op1))
3857 {
3858  START_OF_INSTR();
3859  if (M.x86.mode & SYSMODE_PREFIX_DATA)
3860  {
3861  DECODE_PRINTF("INC\tESI\n");
3862  }
3863  else
3864  {
3865  DECODE_PRINTF("INC\tSI\n");
3866  }
3867  TRACE_AND_STEP();
3868  if (M.x86.mode & SYSMODE_PREFIX_DATA)
3869  {
3870  M.x86.R_ESI = inc_long(M.x86.R_ESI);
3871  }
3872  else
3873  {
3874  M.x86.R_SI = inc_word(M.x86.R_SI);
3875  }
3876  DECODE_CLEAR_SEGOVR();
3877  END_OF_INSTR();
3878 }
3879 
3880 /****************************************************************************
3881 REMARKS:
3882 Handles opcode 0x47
3883 ****************************************************************************/
3884 static void x86emuOp_inc_DI(u8 X86EMU_UNUSED(op1))
3885 {
3886  START_OF_INSTR();
3887  if (M.x86.mode & SYSMODE_PREFIX_DATA)
3888  {
3889  DECODE_PRINTF("INC\tEDI\n");
3890  }
3891  else
3892  {
3893  DECODE_PRINTF("INC\tDI\n");
3894  }
3895  TRACE_AND_STEP();
3896  if (M.x86.mode & SYSMODE_PREFIX_DATA)
3897  {
3898  M.x86.R_EDI = inc_long(M.x86.R_EDI);
3899  }
3900  else
3901  {
3902  M.x86.R_DI = inc_word(M.x86.R_DI);
3903  }
3904  DECODE_CLEAR_SEGOVR();
3905  END_OF_INSTR();
3906 }
3907 
3908 /****************************************************************************
3909 REMARKS:
3910 Handles opcode 0x48
3911 ****************************************************************************/
3912 static void x86emuOp_dec_AX(u8 X86EMU_UNUSED(op1))
3913 {
3914  START_OF_INSTR();
3915  if (M.x86.mode & SYSMODE_PREFIX_DATA)
3916  {
3917  DECODE_PRINTF("DEC\tEAX\n");
3918  }
3919  else
3920  {
3921  DECODE_PRINTF("DEC\tAX\n");
3922  }
3923  TRACE_AND_STEP();
3924  if (M.x86.mode & SYSMODE_PREFIX_DATA)
3925  {
3926  M.x86.R_EAX = dec_long(M.x86.R_EAX);
3927  }
3928  else
3929  {
3930  M.x86.R_AX = dec_word(M.x86.R_AX);
3931  }
3932  DECODE_CLEAR_SEGOVR();
3933  END_OF_INSTR();
3934 }
3935 
3936 /****************************************************************************
3937 REMARKS:
3938 Handles opcode 0x49
3939 ****************************************************************************/
3940 static void x86emuOp_dec_CX(u8 X86EMU_UNUSED(op1))
3941 {
3942  START_OF_INSTR();
3943  if (M.x86.mode & SYSMODE_PREFIX_DATA)
3944  {
3945  DECODE_PRINTF("DEC\tECX\n");
3946  }
3947  else
3948  {
3949  DECODE_PRINTF("DEC\tCX\n");
3950  }
3951  TRACE_AND_STEP();
3952  if (M.x86.mode & SYSMODE_PREFIX_DATA)
3953  {
3954  M.x86.R_ECX = dec_long(M.x86.R_ECX);
3955  }
3956  else
3957  {
3958  M.x86.R_CX = dec_word(M.x86.R_CX);
3959  }
3960  DECODE_CLEAR_SEGOVR();
3961  END_OF_INSTR();
3962 }
3963 
3964 /****************************************************************************
3965 REMARKS:
3966 Handles opcode 0x4a
3967 ****************************************************************************/
3968 static void x86emuOp_dec_DX(u8 X86EMU_UNUSED(op1))
3969 {
3970  START_OF_INSTR();
3971  if (M.x86.mode & SYSMODE_PREFIX_DATA)
3972  {
3973  DECODE_PRINTF("DEC\tEDX\n");
3974  }
3975  else
3976  {
3977  DECODE_PRINTF("DEC\tDX\n");
3978  }
3979  TRACE_AND_STEP();
3980  if (M.x86.mode & SYSMODE_PREFIX_DATA)
3981  {
3982  M.x86.R_EDX = dec_long(M.x86.R_EDX);
3983  }
3984  else
3985  {
3986  M.x86.R_DX = dec_word(M.x86.R_DX);
3987  }
3988  DECODE_CLEAR_SEGOVR();
3989  END_OF_INSTR();
3990 }
3991 
3992 /****************************************************************************
3993 REMARKS:
3994 Handles opcode 0x4b
3995 ****************************************************************************/
3996 static void x86emuOp_dec_BX(u8 X86EMU_UNUSED(op1))
3997 {
3998  START_OF_INSTR();
3999  if (M.x86.mode & SYSMODE_PREFIX_DATA)
4000  {
4001  DECODE_PRINTF("DEC\tEBX\n");
4002  }
4003  else
4004  {
4005  DECODE_PRINTF("DEC\tBX\n");
4006  }
4007  TRACE_AND_STEP();
4008  if (M.x86.mode & SYSMODE_PREFIX_DATA)
4009  {
4010  M.x86.R_EBX = dec_long(M.x86.R_EBX);
4011  }
4012  else
4013  {
4014  M.x86.R_BX = dec_word(M.x86.R_BX);
4015  }
4016  DECODE_CLEAR_SEGOVR();
4017  END_OF_INSTR();
4018 }
4019 
4020 /****************************************************************************
4021 REMARKS:
4022 Handles opcode 0x4c
4023 ****************************************************************************/
4024 static void x86emuOp_dec_SP(u8 X86EMU_UNUSED(op1))
4025 {
4026  START_OF_INSTR();
4027  if (M.x86.mode & SYSMODE_PREFIX_DATA)
4028  {
4029  DECODE_PRINTF("DEC\tESP\n");
4030  }
4031  else
4032  {
4033  DECODE_PRINTF("DEC\tSP\n");
4034  }
4035  TRACE_AND_STEP();
4036  if (M.x86.mode & SYSMODE_PREFIX_DATA)
4037  {
4038  M.x86.R_ESP = dec_long(M.x86.R_ESP);
4039  }
4040  else
4041  {
4042  M.x86.R_SP = dec_word(M.x86.R_SP);
4043  }
4044  DECODE_CLEAR_SEGOVR();
4045  END_OF_INSTR();
4046 }
4047 
4048 /****************************************************************************
4049 REMARKS:
4050 Handles opcode 0x4d
4051 ****************************************************************************/
4052 static void x86emuOp_dec_BP(u8 X86EMU_UNUSED(op1))
4053 {
4054  START_OF_INSTR();
4055  if (M.x86.mode & SYSMODE_PREFIX_DATA)
4056  {
4057  DECODE_PRINTF("DEC\tEBP\n");
4058  }
4059  else
4060  {
4061  DECODE_PRINTF("DEC\tBP\n");
4062  }
4063  TRACE_AND_STEP();
4064  if (M.x86.mode & SYSMODE_PREFIX_DATA)
4065  {
4066  M.x86.R_EBP = dec_long(M.x86.R_EBP);
4067  }
4068  else
4069  {
4070  M.x86.R_BP = dec_word(M.x86.R_BP);
4071  }
4072  DECODE_CLEAR_SEGOVR();
4073  END_OF_INSTR();
4074 }
4075 
4076 /****************************************************************************
4077 REMARKS:
4078 Handles opcode 0x4e
4079 ****************************************************************************/
4080 static void x86emuOp_dec_SI(u8 X86EMU_UNUSED(op1))
4081 {
4082  START_OF_INSTR();
4083  if (M.x86.mode & SYSMODE_PREFIX_DATA)
4084  {
4085  DECODE_PRINTF("DEC\tESI\n");
4086  }
4087  else
4088  {
4089  DECODE_PRINTF("DEC\tSI\n");
4090  }
4091  TRACE_AND_STEP();
4092  if (M.x86.mode & SYSMODE_PREFIX_DATA)
4093  {
4094  M.x86.R_ESI = dec_long(M.x86.R_ESI);
4095  }
4096  else
4097  {
4098  M.x86.R_SI = dec_word(M.x86.R_SI);
4099  }
4100  DECODE_CLEAR_SEGOVR();
4101  END_OF_INSTR();
4102 }
4103 
4104 /****************************************************************************
4105 REMARKS:
4106 Handles opcode 0x4f
4107 ****************************************************************************/
4108 static void x86emuOp_dec_DI(u8 X86EMU_UNUSED(op1))
4109 {
4110  START_OF_INSTR();
4111  if (M.x86.mode & SYSMODE_PREFIX_DATA)
4112  {
4113  DECODE_PRINTF("DEC\tEDI\n");
4114  }
4115  else
4116  {
4117  DECODE_PRINTF("DEC\tDI\n");
4118  }
4119  TRACE_AND_STEP();
4120  if (M.x86.mode & SYSMODE_PREFIX_DATA)
4121  {
4122  M.x86.R_EDI = dec_long(M.x86.R_EDI);
4123  }
4124  else
4125  {
4126  M.x86.R_DI = dec_word(M.x86.R_DI);
4127  }
4128  DECODE_CLEAR_SEGOVR();
4129  END_OF_INSTR();
4130 }
4131 
4132 /****************************************************************************
4133 REMARKS:
4134 Handles opcode 0x50
4135 ****************************************************************************/
4136 static void x86emuOp_push_AX(u8 X86EMU_UNUSED(op1))
4137 {
4138  START_OF_INSTR();
4139  if (M.x86.mode & SYSMODE_PREFIX_DATA)
4140  {
4141  DECODE_PRINTF("PUSH\tEAX\n");
4142  }
4143  else
4144  {
4145  DECODE_PRINTF("PUSH\tAX\n");
4146  }
4147  TRACE_AND_STEP();
4148  if (M.x86.mode & SYSMODE_PREFIX_DATA)
4149  {
4150  push_long(M.x86.R_EAX);
4151  }
4152  else
4153  {
4154  push_word(M.x86.R_AX);
4155  }
4156  DECODE_CLEAR_SEGOVR();
4157  END_OF_INSTR();
4158 }
4159 
4160 /****************************************************************************
4161 REMARKS:
4162 Handles opcode 0x51
4163 ****************************************************************************/
4164 static void x86emuOp_push_CX(u8 X86EMU_UNUSED(op1))
4165 {
4166  START_OF_INSTR();
4167  if (M.x86.mode & SYSMODE_PREFIX_DATA)
4168  {
4169  DECODE_PRINTF("PUSH\tECX\n");
4170  }
4171  else
4172  {
4173  DECODE_PRINTF("PUSH\tCX\n");
4174  }
4175  TRACE_AND_STEP();
4176  if (M.x86.mode & SYSMODE_PREFIX_DATA)
4177  {
4178  push_long(M.x86.R_ECX);
4179  }
4180  else
4181  {
4182  push_word(M.x86.R_CX);
4183  }
4184  DECODE_CLEAR_SEGOVR();
4185  END_OF_INSTR();
4186 }
4187 
4188 /****************************************************************************
4189 REMARKS:
4190 Handles opcode 0x52
4191 ****************************************************************************/
4192 static void x86emuOp_push_DX(u8 X86EMU_UNUSED(op1))
4193 {
4194  START_OF_INSTR();
4195  if (M.x86.mode & SYSMODE_PREFIX_DATA)
4196  {
4197  DECODE_PRINTF("PUSH\tEDX\n");
4198  }
4199  else
4200  {
4201  DECODE_PRINTF("PUSH\tDX\n");
4202  }
4203  TRACE_AND_STEP();
4204  if (M.x86.mode & SYSMODE_PREFIX_DATA)
4205  {
4206  push_long(M.x86.R_EDX);
4207  }
4208  else
4209  {
4210  push_word(M.x86.R_DX);
4211  }
4212  DECODE_CLEAR_SEGOVR();
4213  END_OF_INSTR();
4214 }
4215 
4216 /****************************************************************************
4217 REMARKS:
4218 Handles opcode 0x53
4219 ****************************************************************************/
4220 static void x86emuOp_push_BX(u8 X86EMU_UNUSED(op1))
4221 {
4222  START_OF_INSTR();
4223  if (M.x86.mode & SYSMODE_PREFIX_DATA)
4224  {
4225  DECODE_PRINTF("PUSH\tEBX\n");
4226  }
4227  else
4228  {
4229  DECODE_PRINTF("PUSH\tBX\n");
4230  }
4231  TRACE_AND_STEP();
4232  if (M.x86.mode & SYSMODE_PREFIX_DATA)
4233  {
4234  push_long(M.x86.R_EBX);
4235  }
4236  else
4237  {
4238  push_word(M.x86.R_BX);
4239  }
4240  DECODE_CLEAR_SEGOVR();
4241  END_OF_INSTR();
4242 }
4243 
4244 /****************************************************************************
4245 REMARKS:
4246 Handles opcode 0x54
4247 ****************************************************************************/
4248 static void x86emuOp_push_SP(u8 X86EMU_UNUSED(op1))
4249 {
4250  START_OF_INSTR();
4251  if (M.x86.mode & SYSMODE_PREFIX_DATA)
4252  {
4253  DECODE_PRINTF("PUSH\tESP\n");
4254  }
4255  else
4256  {
4257  DECODE_PRINTF("PUSH\tSP\n");
4258  }
4259  TRACE_AND_STEP();
4260  /* Always push (E)SP, since we are emulating an i386 and above
4261  * processor. This is necessary as some BIOS'es use this to check
4262  * what type of processor is in the system.
4263  */
4264  if (M.x86.mode & SYSMODE_PREFIX_DATA)
4265  {
4266  push_long(M.x86.R_ESP);
4267  }
4268  else
4269  {
4270  push_word((u16)(M.x86.R_SP));
4271  }
4272  DECODE_CLEAR_SEGOVR();
4273  END_OF_INSTR();
4274 }
4275 
4276 /****************************************************************************
4277 REMARKS:
4278 Handles opcode 0x55
4279 ****************************************************************************/
4280 static void x86emuOp_push_BP(u8 X86EMU_UNUSED(op1))
4281 {
4282  START_OF_INSTR();
4283  if (M.x86.mode & SYSMODE_PREFIX_DATA)
4284  {
4285  DECODE_PRINTF("PUSH\tEBP\n");
4286  }
4287  else
4288  {
4289  DECODE_PRINTF("PUSH\tBP\n");
4290  }
4291  TRACE_AND_STEP();
4292  if (M.x86.mode & SYSMODE_PREFIX_DATA)
4293  {
4294  push_long(M.x86.R_EBP);
4295  }
4296  else
4297  {
4298  push_word(M.x86.R_BP);
4299  }
4300  DECODE_CLEAR_SEGOVR();
4301  END_OF_INSTR();
4302 }
4303 
4304 /****************************************************************************
4305 REMARKS:
4306 Handles opcode 0x56
4307 ****************************************************************************/
4308 static void x86emuOp_push_SI(u8 X86EMU_UNUSED(op1))
4309 {
4310  START_OF_INSTR();
4311  if (M.x86.mode & SYSMODE_PREFIX_DATA)
4312  {
4313  DECODE_PRINTF("PUSH\tESI\n");
4314  }
4315  else
4316  {
4317  DECODE_PRINTF("PUSH\tSI\n");
4318  }
4319  TRACE_AND_STEP();
4320  if (M.x86.mode & SYSMODE_PREFIX_DATA)
4321  {
4322  push_long(M.x86.R_ESI);
4323  }
4324  else
4325  {
4326  push_word(M.x86.R_SI);
4327  }
4328  DECODE_CLEAR_SEGOVR();
4329  END_OF_INSTR();
4330 }
4331 
4332 /****************************************************************************
4333 REMARKS:
4334 Handles opcode 0x57
4335 ****************************************************************************/
4336 static void x86emuOp_push_DI(u8 X86EMU_UNUSED(op1))
4337 {
4338  START_OF_INSTR();
4339  if (M.x86.mode & SYSMODE_PREFIX_DATA)
4340  {
4341  DECODE_PRINTF("PUSH\tEDI\n");
4342  }
4343  else
4344  {
4345  DECODE_PRINTF("PUSH\tDI\n");
4346  }
4347  TRACE_AND_STEP();
4348  if (M.x86.mode & SYSMODE_PREFIX_DATA)
4349  {
4350  push_long(M.x86.R_EDI);
4351  }
4352  else
4353  {
4354  push_word(M.x86.R_DI);
4355  }
4356  DECODE_CLEAR_SEGOVR();
4357  END_OF_INSTR();
4358 }
4359 
4360 /****************************************************************************
4361 REMARKS:
4362 Handles opcode 0x58
4363 ****************************************************************************/
4364 static void x86emuOp_pop_AX(u8 X86EMU_UNUSED(op1))
4365 {
4366  START_OF_INSTR();
4367  if (M.x86.mode & SYSMODE_PREFIX_DATA)
4368  {
4369  DECODE_PRINTF("POP\tEAX\n");
4370  }
4371  else
4372  {
4373  DECODE_PRINTF("POP\tAX\n");
4374  }
4375  TRACE_AND_STEP();
4376  if (M.x86.mode & SYSMODE_PREFIX_DATA)
4377  {
4378  M.x86.R_EAX = pop_long();
4379  }
4380  else
4381  {
4382  M.x86.R_AX = pop_word();
4383  }
4384  DECODE_CLEAR_SEGOVR();
4385  END_OF_INSTR();
4386 }
4387 
4388 /****************************************************************************
4389 REMARKS:
4390 Handles opcode 0x59
4391 ****************************************************************************/
4392 static void x86emuOp_pop_CX(u8 X86EMU_UNUSED(op1))
4393 {
4394  START_OF_INSTR();
4395  if (M.x86.mode & SYSMODE_PREFIX_DATA)
4396  {
4397  DECODE_PRINTF("POP\tECX\n");
4398  }
4399  else
4400  {
4401  DECODE_PRINTF("POP\tCX\n");
4402  }
4403  TRACE_AND_STEP();
4404  if (M.x86.mode & SYSMODE_PREFIX_DATA)
4405  {
4406  M.x86.R_ECX = pop_long();
4407  }
4408  else
4409  {
4410  M.x86.R_CX = pop_word();
4411  }
4412  DECODE_CLEAR_SEGOVR();
4413  END_OF_INSTR();
4414 }
4415 
4416 /****************************************************************************
4417 REMARKS:
4418 Handles opcode 0x5a
4419 ****************************************************************************/
4420 static void x86emuOp_pop_DX(u8 X86EMU_UNUSED(op1))
4421 {
4422  START_OF_INSTR();
4423  if (M.x86.mode & SYSMODE_PREFIX_DATA)
4424  {
4425  DECODE_PRINTF("POP\tEDX\n");
4426  }
4427  else
4428  {
4429  DECODE_PRINTF("POP\tDX\n");
4430  }
4431  TRACE_AND_STEP();
4432  if (M.x86.mode & SYSMODE_PREFIX_DATA)
4433  {
4434  M.x86.R_EDX = pop_long();
4435  }
4436  else
4437  {
4438  M.x86.R_DX = pop_word();
4439  }
4440  DECODE_CLEAR_SEGOVR();
4441  END_OF_INSTR();
4442 }
4443 
4444 /****************************************************************************
4445 REMARKS:
4446 Handles opcode 0x5b
4447 ****************************************************************************/
4448 static void x86emuOp_pop_BX(u8 X86EMU_UNUSED(op1))
4449 {
4450  START_OF_INSTR();
4451  if (M.x86.mode & SYSMODE_PREFIX_DATA)
4452  {
4453  DECODE_PRINTF("POP\tEBX\n");
4454  }
4455  else
4456  {
4457  DECODE_PRINTF("POP\tBX\n");
4458  }
4459  TRACE_AND_STEP();
4460  if (M.x86.mode & SYSMODE_PREFIX_DATA)
4461  {
4462  M.x86.R_EBX = pop_long();
4463  }
4464  else
4465  {
4466  M.x86.R_BX = pop_word();
4467  }
4468  DECODE_CLEAR_SEGOVR();
4469  END_OF_INSTR();
4470 }
4471 
4472 /****************************************************************************
4473 REMARKS:
4474 Handles opcode 0x5c
4475 ****************************************************************************/
4476 static void x86emuOp_pop_SP(u8 X86EMU_UNUSED(op1))
4477 {
4478  START_OF_INSTR();
4479  if (M.x86.mode & SYSMODE_PREFIX_DATA)
4480  {
4481  DECODE_PRINTF("POP\tESP\n");
4482  }
4483  else
4484  {
4485  DECODE_PRINTF("POP\tSP\n");
4486  }
4487  TRACE_AND_STEP();
4488  if (M.x86.mode & SYSMODE_PREFIX_DATA)
4489  {
4490  M.x86.R_ESP = pop_long();
4491  }
4492  else
4493  {
4494  M.x86.R_SP = pop_word();
4495  }
4496  DECODE_CLEAR_SEGOVR();
4497  END_OF_INSTR();
4498 }
4499 
4500 /****************************************************************************
4501 REMARKS:
4502 Handles opcode 0x5d
4503 ****************************************************************************/
4504 static void x86emuOp_pop_BP(u8 X86EMU_UNUSED(op1))
4505 {
4506  START_OF_INSTR();
4507  if (M.x86.mode & SYSMODE_PREFIX_DATA)
4508  {
4509  DECODE_PRINTF("POP\tEBP\n");
4510  }
4511  else
4512  {
4513  DECODE_PRINTF("POP\tBP\n");
4514  }
4515  TRACE_AND_STEP();
4516  if (M.x86.mode & SYSMODE_PREFIX_DATA)
4517  {
4518  M.x86.R_EBP = pop_long();
4519  }
4520  else
4521  {
4522  M.x86.R_BP = pop_word();
4523  }
4524  DECODE_CLEAR_SEGOVR();
4525  END_OF_INSTR();
4526 }
4527 
4528 /****************************************************************************
4529 REMARKS:
4530 Handles opcode 0x5e
4531 ****************************************************************************/
4532 static void x86emuOp_pop_SI(u8 X86EMU_UNUSED(op1))
4533 {
4534  START_OF_INSTR();
4535  if (M.x86.mode & SYSMODE_PREFIX_DATA)
4536  {
4537  DECODE_PRINTF("POP\tESI\n");
4538  }
4539  else
4540  {
4541  DECODE_PRINTF("POP\tSI\n");
4542  }
4543  TRACE_AND_STEP();
4544  if (M.x86.mode & SYSMODE_PREFIX_DATA)
4545  {
4546  M.x86.R_ESI = pop_long();
4547  }
4548  else
4549  {
4550  M.x86.R_SI = pop_word();
4551  }
4552  DECODE_CLEAR_SEGOVR();
4553  END_OF_INSTR();
4554 }
4555 
4556 /****************************************************************************
4557 REMARKS:
4558 Handles opcode 0x5f
4559 ****************************************************************************/
4560 static void x86emuOp_pop_DI(u8 X86EMU_UNUSED(op1))
4561 {
4562  START_OF_INSTR();
4563  if (M.x86.mode & SYSMODE_PREFIX_DATA)
4564  {
4565  DECODE_PRINTF("POP\tEDI\n");
4566  }
4567  else
4568  {
4569  DECODE_PRINTF("POP\tDI\n");
4570  }
4571  TRACE_AND_STEP();
4572  if (M.x86.mode & SYSMODE_PREFIX_DATA)
4573  {
4574  M.x86.R_EDI = pop_long();
4575  }
4576  else
4577  {
4578  M.x86.R_DI = pop_word();
4579  }
4580  DECODE_CLEAR_SEGOVR();
4581  END_OF_INSTR();
4582 }
4583 
4584 /****************************************************************************
4585 REMARKS:
4586 Handles opcode 0x60
4587 ****************************************************************************/
4588 static void x86emuOp_push_all(u8 X86EMU_UNUSED(op1))
4589 {
4590  START_OF_INSTR();
4591  if (M.x86.mode & SYSMODE_PREFIX_DATA)
4592  {
4593  DECODE_PRINTF("PUSHAD\n");
4594  }
4595  else
4596  {
4597  DECODE_PRINTF("PUSHA\n");
4598  }
4599  TRACE_AND_STEP();
4600  if (M.x86.mode & SYSMODE_PREFIX_DATA)
4601  {
4602  u32 old_sp = M.x86.R_ESP;
4603 
4604  push_long(M.x86.R_EAX);
4605  push_long(M.x86.R_ECX);
4606  push_long(M.x86.R_EDX);
4607  push_long(M.x86.R_EBX);
4608  push_long(old_sp);
4609  push_long(M.x86.R_EBP);
4610  push_long(M.x86.R_ESI);
4611  push_long(M.x86.R_EDI);
4612  }
4613  else
4614  {
4615  u16 old_sp = M.x86.R_SP;
4616 
4617  push_word(M.x86.R_AX);
4618  push_word(M.x86.R_CX);
4619  push_word(M.x86.R_DX);
4620  push_word(M.x86.R_BX);
4621  push_word(old_sp);
4622  push_word(M.x86.R_BP);
4623  push_word(M.x86.R_SI);
4624  push_word(M.x86.R_DI);
4625  }
4626  DECODE_CLEAR_SEGOVR();
4627  END_OF_INSTR();
4628 }
4629 
4630 /****************************************************************************
4631 REMARKS:
4632 Handles opcode 0x61
4633 ****************************************************************************/
4634 static void x86emuOp_pop_all(u8 X86EMU_UNUSED(op1))
4635 {
4636  START_OF_INSTR();
4637  if (M.x86.mode & SYSMODE_PREFIX_DATA)
4638  {
4639  DECODE_PRINTF("POPAD\n");
4640  }
4641  else
4642  {
4643  DECODE_PRINTF("POPA\n");
4644  }
4645  TRACE_AND_STEP();
4646  if (M.x86.mode & SYSMODE_PREFIX_DATA)
4647  {
4648  M.x86.R_EDI = pop_long();
4649  M.x86.R_ESI = pop_long();
4650  M.x86.R_EBP = pop_long();
4651  M.x86.R_ESP += 4; /* skip ESP */
4652  M.x86.R_EBX = pop_long();
4653  M.x86.R_EDX = pop_long();
4654  M.x86.R_ECX = pop_long();
4655  M.x86.R_EAX = pop_long();
4656  }
4657  else
4658  {
4659  M.x86.R_DI = pop_word();
4660  M.x86.R_SI = pop_word();
4661  M.x86.R_BP = pop_word();
4662  M.x86.R_SP += 2; /* skip SP */
4663  M.x86.R_BX = pop_word();
4664  M.x86.R_DX = pop_word();
4665  M.x86.R_CX = pop_word();
4666  M.x86.R_AX = pop_word();
4667  }
4668  DECODE_CLEAR_SEGOVR();
4669  END_OF_INSTR();
4670 }
4671 
4672 /*opcode 0x62 ILLEGAL OP, calls x86emuOp_illegal_op() */
4673 /*opcode 0x63 ILLEGAL OP, calls x86emuOp_illegal_op() */
4674 
4675 /****************************************************************************
4676 REMARKS:
4677 Handles opcode 0x64
4678 ****************************************************************************/
4679 static void x86emuOp_segovr_FS(u8 X86EMU_UNUSED(op1))
4680 {
4681  START_OF_INSTR();
4682  DECODE_PRINTF("FS:\n");
4683  TRACE_AND_STEP();
4684  M.x86.mode |= SYSMODE_SEGOVR_FS;
4685  /*
4686  * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
4687  * opcode subroutines we do not want to do this.
4688  */
4689  END_OF_INSTR();
4690 }
4691 
4692 /****************************************************************************
4693 REMARKS:
4694 Handles opcode 0x65
4695 ****************************************************************************/
4696 static void x86emuOp_segovr_GS(u8 X86EMU_UNUSED(op1))
4697 {
4698  START_OF_INSTR();
4699  DECODE_PRINTF("GS:\n");
4700  TRACE_AND_STEP();
4701  M.x86.mode |= SYSMODE_SEGOVR_GS;
4702  /*
4703  * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
4704  * opcode subroutines we do not want to do this.
4705  */
4706  END_OF_INSTR();
4707 }
4708 
4709 /****************************************************************************
4710 REMARKS:
4711 Handles opcode 0x66 - prefix for 32-bit register
4712 ****************************************************************************/
4713 static void x86emuOp_prefix_data(u8 X86EMU_UNUSED(op1))
4714 {
4715  START_OF_INSTR();
4716  DECODE_PRINTF("DATA:\n");
4717  TRACE_AND_STEP();
4718  M.x86.mode |= SYSMODE_PREFIX_DATA;
4719  /* note no DECODE_CLEAR_SEGOVR here. */
4720  END_OF_INSTR();
4721 }
4722 
4723 /****************************************************************************
4724 REMARKS:
4725 Handles opcode 0x67 - prefix for 32-bit address
4726 ****************************************************************************/
4727 static void x86emuOp_prefix_addr(u8 X86EMU_UNUSED(op1))
4728 {
4729  START_OF_INSTR();
4730  DECODE_PRINTF("ADDR:\n");
4731  TRACE_AND_STEP();
4732  M.x86.mode |= SYSMODE_PREFIX_ADDR;
4733  /* note no DECODE_CLEAR_SEGOVR here. */
4734  END_OF_INSTR();
4735 }
4736 
4737 /****************************************************************************
4738 REMARKS:
4739 Handles opcode 0x68
4740 ****************************************************************************/
4741 static void x86emuOp_push_word_IMM(u8 X86EMU_UNUSED(op1))
4742 {
4743  u32 imm;
4744 
4745  START_OF_INSTR();
4746  if (M.x86.mode & SYSMODE_PREFIX_DATA)
4747  {
4748  imm = fetch_long_imm();
4749  }
4750  else
4751  {
4752  imm = fetch_word_imm();
4753  }
4754  DECODE_PRINTF2("PUSH\t%x\n", imm);
4755  TRACE_AND_STEP();
4756  if (M.x86.mode & SYSMODE_PREFIX_DATA)
4757  {
4758  push_long(imm);
4759  }
4760  else
4761  {
4762  push_word((u16) imm);
4763  }
4764  DECODE_CLEAR_SEGOVR();
4765  END_OF_INSTR();
4766 }
4767 
4768 /****************************************************************************
4769 REMARKS:
4770 Handles opcode 0x69
4771 ****************************************************************************/
4772 static void x86emuOp_imul_word_IMM(u8 X86EMU_UNUSED(op1))
4773 {
4774  int mod, rl, rh;
4775  uint srcoffset;
4776 
4777  START_OF_INSTR();
4778  DECODE_PRINTF("IMUL\t");
4779  FETCH_DECODE_MODRM(mod, rh, rl);
4780  switch (mod)
4781  {
4782  case 0:
4783  if (M.x86.mode & SYSMODE_PREFIX_DATA)
4784  {
4785  u32 *destreg;
4786  u32 srcval;
4787  u32 res_lo, res_hi;
4788  s32 imm;
4789 
4790  destreg = DECODE_RM_LONG_REGISTER(rh);
4791  DECODE_PRINTF(",");
4792  srcoffset = decode_rm00_address(rl);
4793  srcval = fetch_data_long(srcoffset);
4794  imm = fetch_long_imm();
4795  DECODE_PRINTF2(",%d\n", (s32) imm);
4796  TRACE_AND_STEP();
4797  imul_long_direct(&res_lo, &res_hi, (s32) srcval, (s32) imm);
4798  if (res_hi != 0)
4799  {
4800  SET_FLAG(F_CF);
4801  SET_FLAG(F_OF);
4802  }
4803  else
4804  {
4805  CLEAR_FLAG(F_CF);
4806  CLEAR_FLAG(F_OF);
4807  }
4808  *destreg = (u32) res_lo;
4809  }
4810  else
4811  {
4812  u16 *destreg;
4813  u16 srcval;
4814  u32 res;
4815  s16 imm;
4816 
4817  destreg = DECODE_RM_WORD_REGISTER(rh);
4818  DECODE_PRINTF(",");
4819  srcoffset = decode_rm00_address(rl);
4820  srcval = fetch_data_word(srcoffset);
4821  imm = fetch_word_imm();
4822  DECODE_PRINTF2(",%d\n", (s32) imm);
4823  TRACE_AND_STEP();
4824  res = (s16) srcval * (s16) imm;
4825  if (res > 0xFFFF)
4826  {
4827  SET_FLAG(F_CF);
4828  SET_FLAG(F_OF);
4829  }
4830  else
4831  {
4832  CLEAR_FLAG(F_CF);
4833  CLEAR_FLAG(F_OF);
4834  }
4835  *destreg = (u16) res;
4836  }
4837  break;
4838  case 1:
4839  if (M.x86.mode & SYSMODE_PREFIX_DATA)
4840  {
4841  u32 *destreg;
4842  u32 srcval;
4843  u32 res_lo, res_hi;
4844  s32 imm;
4845 
4846  destreg = DECODE_RM_LONG_REGISTER(rh);
4847  DECODE_PRINTF(",");
4848  srcoffset = decode_rm01_address(rl);
4849  srcval = fetch_data_long(srcoffset);
4850  imm = fetch_long_imm();
4851  DECODE_PRINTF2(",%d\n", (s32) imm);
4852  TRACE_AND_STEP();
4853  imul_long_direct(&res_lo, &res_hi, (s32) srcval, (s32) imm);
4854  if (res_hi != 0)
4855  {
4856  SET_FLAG(F_CF);
4857  SET_FLAG(F_OF);
4858  }
4859  else
4860  {
4861  CLEAR_FLAG(F_CF);
4862  CLEAR_FLAG(F_OF);
4863  }
4864  *destreg = (u32) res_lo;
4865  }
4866  else
4867  {
4868  u16 *destreg;
4869  u16 srcval;
4870  u32 res;
4871  s16 imm;
4872 
4873  destreg = DECODE_RM_WORD_REGISTER(rh);
4874  DECODE_PRINTF(",");
4875  srcoffset = decode_rm01_address(rl);
4876  srcval = fetch_data_word(srcoffset);
4877  imm = fetch_word_imm();
4878  DECODE_PRINTF2(",%d\n", (s32) imm);
4879  TRACE_AND_STEP();
4880  res = (s16) srcval * (s16) imm;
4881  if (res > 0xFFFF)
4882  {
4883  SET_FLAG(F_CF);
4884  SET_FLAG(F_OF);
4885  }
4886  else
4887  {
4888  CLEAR_FLAG(F_CF);
4889  CLEAR_FLAG(F_OF);
4890  }
4891  *destreg = (u16) res;
4892  }
4893  break;
4894  case 2:
4895  if (M.x86.mode & SYSMODE_PREFIX_DATA)
4896  {
4897  u32 *destreg;
4898  u32 srcval;
4899  u32 res_lo, res_hi;
4900  s32 imm;
4901 
4902  destreg = DECODE_RM_LONG_REGISTER(rh);
4903  DECODE_PRINTF(",");
4904  srcoffset = decode_rm10_address(rl);
4905  srcval = fetch_data_long(srcoffset);
4906  imm = fetch_long_imm();
4907  DECODE_PRINTF2(",%d\n", (s32) imm);
4908  TRACE_AND_STEP();
4909  imul_long_direct(&res_lo, &res_hi, (s32) srcval, (s32) imm);
4910  if (res_hi != 0)
4911  {
4912  SET_FLAG(F_CF);
4913  SET_FLAG(F_OF);
4914  }
4915  else
4916  {
4917  CLEAR_FLAG(F_CF);
4918  CLEAR_FLAG(F_OF);
4919  }
4920  *destreg = (u32) res_lo;
4921  }
4922  else
4923  {
4924  u16 *destreg;
4925  u16 srcval;
4926  u32 res;
4927  s16 imm;
4928 
4929  destreg = DECODE_RM_WORD_REGISTER(rh);
4930  DECODE_PRINTF(",");
4931  srcoffset = decode_rm10_address(rl);
4932  srcval = fetch_data_word(srcoffset);
4933  imm = fetch_word_imm();
4934  DECODE_PRINTF2(",%d\n", (s32) imm);
4935  TRACE_AND_STEP();
4936  res = (s16) srcval * (s16) imm;
4937  if (res > 0xFFFF)
4938  {
4939  SET_FLAG(F_CF);
4940  SET_FLAG(F_OF);
4941  }
4942  else
4943  {
4944  CLEAR_FLAG(F_CF);
4945  CLEAR_FLAG(F_OF);
4946  }
4947  *destreg = (u16) res;
4948  }
4949  break;
4950  case 3: /* register to register */
4951  if (M.x86.mode & SYSMODE_PREFIX_DATA)
4952  {
4953  u32 *destreg, *srcreg;
4954  u32 res_lo, res_hi;
4955  s32 imm;
4956 
4957  destreg = DECODE_RM_LONG_REGISTER(rh);
4958  DECODE_PRINTF(",");
4959  srcreg = DECODE_RM_LONG_REGISTER(rl);
4960  imm = fetch_long_imm();
4961  DECODE_PRINTF2(",%d\n", (s32) imm);
4962  TRACE_AND_STEP();
4963  imul_long_direct(&res_lo, &res_hi, (s32) *srcreg, (s32) imm);
4964  if (res_hi != 0)
4965  {
4966  SET_FLAG(F_CF);
4967  SET_FLAG(F_OF);
4968  }
4969  else
4970  {
4971  CLEAR_FLAG(F_CF);
4972  CLEAR_FLAG(F_OF);
4973  }
4974  *destreg = (u32) res_lo;
4975  }
4976  else
4977  {
4978  u16 *destreg, *srcreg;
4979  u32 res;
4980  s16 imm;
4981 
4982  destreg = DECODE_RM_WORD_REGISTER(rh);
4983  DECODE_PRINTF(",");
4984  srcreg = DECODE_RM_WORD_REGISTER(rl);
4985  imm = fetch_word_imm();
4986  DECODE_PRINTF2(",%d\n", (s32) imm);
4987  res = (s16) *srcreg * (s16) imm;
4988  if (res > 0xFFFF)
4989  {
4990  SET_FLAG(F_CF);
4991  SET_FLAG(F_OF);
4992  }
4993  else
4994  {
4995  CLEAR_FLAG(F_CF);
4996  CLEAR_FLAG(F_OF);
4997  }
4998  *destreg = (u16) res;
4999  }
5000  break;
5001  }
5002  DECODE_CLEAR_SEGOVR();
5003  END_OF_INSTR();
5004 }
5005 
5006 /****************************************************************************
5007 REMARKS:
5008 Handles opcode 0x6a
5009 ****************************************************************************/
5010 static void x86emuOp_push_byte_IMM(u8 X86EMU_UNUSED(op1))
5011 {
5012  s16 imm;
5013 
5014  START_OF_INSTR();
5015  imm = (s8) fetch_byte_imm();
5016  DECODE_PRINTF2("PUSH\t%d\n", imm);
5017  TRACE_AND_STEP();
5018  if (M.x86.mode & SYSMODE_PREFIX_DATA)
5019  {
5020  push_long((s32) imm);
5021  }
5022  else
5023  {
5024  push_word(imm);
5025  }
5026  DECODE_CLEAR_SEGOVR();
5027  END_OF_INSTR();
5028 }
5029 
5030 /****************************************************************************
5031 REMARKS:
5032 Handles opcode 0x6b
5033 ****************************************************************************/
5034 static void x86emuOp_imul_byte_IMM(u8 X86EMU_UNUSED(op1))
5035 {
5036  int mod, rl, rh;
5037  uint srcoffset;
5038  s8 imm;
5039 
5040  START_OF_INSTR();
5041  DECODE_PRINTF("IMUL\t");
5042  FETCH_DECODE_MODRM(mod, rh, rl);
5043  switch (mod)
5044  {
5045  case 0:
5046  if (M.x86.mode & SYSMODE_PREFIX_DATA)
5047  {
5048  u32 *destreg;
5049  u32 srcval;
5050  u32 res_lo, res_hi;
5051 
5052  destreg = DECODE_RM_LONG_REGISTER(rh);
5053  DECODE_PRINTF(",");
5054  srcoffset = decode_rm00_address(rl);
5055  srcval = fetch_data_long(srcoffset);
5056  imm = fetch_byte_imm();
5057  DECODE_PRINTF2(",%d\n", (s32) imm);
5058  TRACE_AND_STEP();
5059  imul_long_direct(&res_lo, &res_hi, (s32) srcval, (s32) imm);
5060  if (res_hi != 0)
5061  {
5062  SET_FLAG(F_CF);
5063  SET_FLAG(F_OF);
5064  }
5065  else
5066  {
5067  CLEAR_FLAG(F_CF);
5068  CLEAR_FLAG(F_OF);
5069  }
5070  *destreg = (u32) res_lo;
5071  }
5072  else
5073  {
5074  u16 *destreg;
5075  u16 srcval;
5076  u32 res;
5077 
5078  destreg = DECODE_RM_WORD_REGISTER(rh);
5079  DECODE_PRINTF(",");
5080  srcoffset = decode_rm00_address(rl);
5081  srcval = fetch_data_word(srcoffset);
5082  imm = fetch_byte_imm();
5083  DECODE_PRINTF2(",%d\n", (s32) imm);
5084  TRACE_AND_STEP();
5085  res = (s16) srcval * (s16) imm;
5086  if (res > 0xFFFF)
5087  {
5088  SET_FLAG(F_CF);
5089  SET_FLAG(F_OF);
5090  }
5091  else
5092  {
5093  CLEAR_FLAG(F_CF);
5094  CLEAR_FLAG(F_OF);
5095  }
5096  *destreg = (u16) res;
5097  }
5098  break;
5099  case 1:
5100  if (M.x86.mode & SYSMODE_PREFIX_DATA)
5101  {
5102  u32 *destreg;
5103  u32 srcval;
5104  u32 res_lo, res_hi;
5105 
5106  destreg = DECODE_RM_LONG_REGISTER(rh);
5107  DECODE_PRINTF(",");
5108  srcoffset = decode_rm01_address(rl);
5109  srcval = fetch_data_long(srcoffset);
5110  imm = fetch_byte_imm();
5111  DECODE_PRINTF2(",%d\n", (s32) imm);
5112  TRACE_AND_STEP();
5113  imul_long_direct(&res_lo, &res_hi, (s32) srcval, (s32) imm);
5114  if (res_hi != 0)
5115  {
5116  SET_FLAG(F_CF);
5117  SET_FLAG(F_OF);
5118  }
5119  else
5120  {
5121  CLEAR_FLAG(F_CF);
5122  CLEAR_FLAG(F_OF);
5123  }
5124  *destreg = (u32) res_lo;
5125  }
5126  else
5127  {
5128  u16 *destreg;
5129  u16 srcval;
5130  u32 res;
5131 
5132  destreg = DECODE_RM_WORD_REGISTER(rh);
5133  DECODE_PRINTF(",");
5134  srcoffset = decode_rm01_address(rl);
5135  srcval = fetch_data_word(srcoffset);
5136  imm = fetch_byte_imm();
5137  DECODE_PRINTF2(",%d\n", (s32) imm);
5138  TRACE_AND_STEP();
5139  res = (s16) srcval * (s16) imm;
5140  if (res > 0xFFFF)
5141  {
5142  SET_FLAG(F_CF);
5143  SET_FLAG(F_OF);
5144  }
5145  else
5146  {
5147  CLEAR_FLAG(F_CF);
5148  CLEAR_FLAG(F_OF);
5149  }
5150  *destreg = (u16) res;
5151  }
5152  break;
5153  case 2:
5154  if (M.x86.mode & SYSMODE_PREFIX_DATA)
5155  {
5156  u32 *destreg;
5157  u32 srcval;
5158  u32 res_lo, res_hi;
5159 
5160  destreg = DECODE_RM_LONG_REGISTER(rh);
5161  DECODE_PRINTF(",");
5162  srcoffset = decode_rm10_address(rl);
5163  srcval = fetch_data_long(srcoffset);
5164  imm = fetch_byte_imm();
5165  DECODE_PRINTF2(",%d\n", (s32) imm);
5166  TRACE_AND_STEP();
5167  imul_long_direct(&res_lo, &res_hi, (s32) srcval, (s32) imm);
5168  if (res_hi != 0)
5169  {
5170  SET_FLAG(F_CF);
5171  SET_FLAG(F_OF);
5172  }
5173  else
5174  {
5175  CLEAR_FLAG(F_CF);
5176  CLEAR_FLAG(F_OF);
5177  }
5178  *destreg = (u32) res_lo;
5179  }
5180  else
5181  {
5182  u16 *destreg;
5183  u16 srcval;
5184  u32 res;
5185 
5186  destreg = DECODE_RM_WORD_REGISTER(rh);
5187  DECODE_PRINTF(",");
5188  srcoffset = decode_rm10_address(rl);
5189  srcval = fetch_data_word(srcoffset);
5190  imm = fetch_byte_imm();
5191  DECODE_PRINTF2(",%d\n", (s32) imm);
5192  TRACE_AND_STEP();
5193  res = (s16) srcval * (s16) imm;
5194  if (res > 0xFFFF)
5195  {
5196  SET_FLAG(F_CF);
5197  SET_FLAG(F_OF);
5198  }
5199  else
5200  {
5201  CLEAR_FLAG(F_CF);
5202  CLEAR_FLAG(F_OF);
5203  }
5204  *destreg = (u16) res;
5205  }
5206  break;
5207  case 3: /* register to register */
5208  if (M.x86.mode & SYSMODE_PREFIX_DATA)
5209  {
5210  u32 *destreg, *srcreg;
5211  u32 res_lo, res_hi;
5212 
5213  destreg = DECODE_RM_LONG_REGISTER(rh);
5214  DECODE_PRINTF(",");
5215  srcreg = DECODE_RM_LONG_REGISTER(rl);
5216  imm = fetch_byte_imm();
5217  DECODE_PRINTF2(",%d\n", (s32) imm);
5218  TRACE_AND_STEP();
5219  imul_long_direct(&res_lo, &res_hi, (s32) *srcreg, (s32) imm);
5220  if (res_hi != 0)
5221  {
5222  SET_FLAG(F_CF);
5223  SET_FLAG(F_OF);
5224  }
5225  else
5226  {
5227  CLEAR_FLAG(F_CF);
5228  CLEAR_FLAG(F_OF);
5229  }
5230  *destreg = (u32) res_lo;
5231  }
5232  else
5233  {
5234  u16 *destreg, *srcreg;
5235  u32 res;
5236 
5237  destreg = DECODE_RM_WORD_REGISTER(rh);
5238  DECODE_PRINTF(",");
5239  srcreg = DECODE_RM_WORD_REGISTER(rl);
5240  imm = fetch_byte_imm();
5241  DECODE_PRINTF2(",%d\n", (s32) imm);
5242  res = (s16) *srcreg * (s16) imm;
5243  if (res > 0xFFFF)
5244  {
5245  SET_FLAG(F_CF);
5246  SET_FLAG(F_OF);
5247  }
5248  else
5249  {
5250  CLEAR_FLAG(F_CF);
5251  CLEAR_FLAG(F_OF);
5252  }
5253  *destreg = (u16) res;
5254  }
5255  break;
5256  }
5257  DECODE_CLEAR_SEGOVR();
5258  END_OF_INSTR();
5259 }
5260 
5261 /****************************************************************************
5262 REMARKS:
5263 Handles opcode 0x6c
5264 ****************************************************************************/
5265 static void x86emuOp_ins_byte(u8 X86EMU_UNUSED(op1))
5266 {
5267  START_OF_INSTR();
5268  DECODE_PRINTF("INSB\n");
5269  ins(1);
5270  TRACE_AND_STEP();
5271  DECODE_CLEAR_SEGOVR();
5272  END_OF_INSTR();
5273 }
5274 
5275 /****************************************************************************
5276 REMARKS:
5277 Handles opcode 0x6d
5278 ****************************************************************************/
5279 static void x86emuOp_ins_word(u8 X86EMU_UNUSED(op1))
5280 {
5281  START_OF_INSTR();
5282  if (M.x86.mode & SYSMODE_PREFIX_DATA)
5283  {
5284  DECODE_PRINTF("INSD\n");
5285  ins(4);
5286  }
5287  else
5288  {
5289  DECODE_PRINTF("INSW\n");
5290  ins(2);
5291  }
5292  TRACE_AND_STEP();
5293  DECODE_CLEAR_SEGOVR();
5294  END_OF_INSTR();
5295 }
5296 
5297 /****************************************************************************
5298 REMARKS:
5299 Handles opcode 0x6e
5300 ****************************************************************************/
5301 static void x86emuOp_outs_byte(u8 X86EMU_UNUSED(op1))
5302 {
5303  START_OF_INSTR();
5304  DECODE_PRINTF("OUTSB\n");
5305  outs(1);
5306  TRACE_AND_STEP();
5307  DECODE_CLEAR_SEGOVR();
5308  END_OF_INSTR();
5309 }
5310 
5311 /****************************************************************************
5312 REMARKS:
5313 Handles opcode 0x6f
5314 ****************************************************************************/
5315 static void x86emuOp_outs_word(u8 X86EMU_UNUSED(op1))
5316 {
5317  START_OF_INSTR();
5318  if (M.x86.mode & SYSMODE_PREFIX_DATA)
5319  {
5320  DECODE_PRINTF("OUTSD\n");
5321  outs(4);
5322  }
5323  else
5324  {
5325  DECODE_PRINTF("OUTSW\n");
5326  outs(2);
5327  }
5328  TRACE_AND_STEP();
5329  DECODE_CLEAR_SEGOVR();
5330  END_OF_INSTR();
5331 }
5332 
5333 /****************************************************************************
5334 REMARKS:
5335 Handles opcode 0x70
5336 ****************************************************************************/
5337 static void x86emuOp_jump_near_O(u8 X86EMU_UNUSED(op1))
5338 {
5339  s8 offset;
5340  u16 target;
5341 
5342  /* jump to byte offset if overflow flag is set */
5343  START_OF_INSTR();
5344  DECODE_PRINTF("JO\t");
5345  offset = (s8) fetch_byte_imm();
5346  target = (u16)(M.x86.R_IP + (s16) offset);
5347  DECODE_PRINTF2("%x\n", target);
5348  TRACE_AND_STEP();
5349  if (ACCESS_FLAG(F_OF))
5350  M.x86.R_IP = target;
5351  DECODE_CLEAR_SEGOVR();
5352  END_OF_INSTR();
5353 }
5354 
5355 /****************************************************************************
5356 REMARKS:
5357 Handles opcode 0x71
5358 ****************************************************************************/
5359 static void x86emuOp_jump_near_NO(u8 X86EMU_UNUSED(op1))
5360 {
5361  s8 offset;
5362  u16 target;
5363 
5364  /* jump to byte offset if overflow is not set */
5365  START_OF_INSTR();
5366  DECODE_PRINTF("JNO\t");
5367  offset = (s8) fetch_byte_imm();
5368  target = (u16)(M.x86.R_IP + (s16) offset);
5369  DECODE_PRINTF2("%x\n", target);
5370  TRACE_AND_STEP();
5371  if (!ACCESS_FLAG(F_OF))
5372  M.x86.R_IP = target;
5373  DECODE_CLEAR_SEGOVR();
5374  END_OF_INSTR();
5375 }
5376 
5377 /****************************************************************************
5378 REMARKS:
5379 Handles opcode 0x72
5380 ****************************************************************************/
5381 static void x86emuOp_jump_near_B(u8 X86EMU_UNUSED(op1))
5382 {
5383  s8 offset;
5384  u16 target;
5385 
5386  /* jump to byte offset if carry flag is set. */
5387  START_OF_INSTR();
5388  DECODE_PRINTF("JB\t");
5389  offset = (s8) fetch_byte_imm();
5390  target = (u16)(M.x86.R_IP + (s16) offset);
5391  DECODE_PRINTF2("%x\n", target);
5392  TRACE_AND_STEP();
5393  if (ACCESS_FLAG(F_CF))
5394  M.x86.R_IP = target;
5395  DECODE_CLEAR_SEGOVR();
5396  END_OF_INSTR();
5397 }
5398 
5399 /****************************************************************************
5400 REMARKS:
5401 Handles opcode 0x73
5402 ****************************************************************************/
5403 static void x86emuOp_jump_near_NB(u8 X86EMU_UNUSED(op1))
5404 {
5405  s8 offset;
5406  u16 target;
5407 
5408  /* jump to byte offset if carry flag is clear. */
5409  START_OF_INSTR();
5410  DECODE_PRINTF("JNB\t");
5411  offset = (s8) fetch_byte_imm();
5412  target = (u16)(M.x86.R_IP + (s16) offset);
5413  DECODE_PRINTF2("%x\n", target);
5414  TRACE_AND_STEP();
5415  if (!ACCESS_FLAG(F_CF))
5416  M.x86.R_IP = target;
5417  DECODE_CLEAR_SEGOVR();
5418  END_OF_INSTR();
5419 }
5420 
5421 /****************************************************************************
5422 REMARKS:
5423 Handles opcode 0x74
5424 ****************************************************************************/
5425 static void x86emuOp_jump_near_Z(u8 X86EMU_UNUSED(op1))
5426 {
5427  s8 offset;
5428  u16 target;
5429 
5430  /* jump to byte offset if zero flag is set. */
5431  START_OF_INSTR();
5432  DECODE_PRINTF("JZ\t");
5433  offset = (s8) fetch_byte_imm();
5434  target = (u16)(M.x86.R_IP + (s16) offset);
5435  DECODE_PRINTF2("%x\n", target);
5436  TRACE_AND_STEP();
5437  if (ACCESS_FLAG(F_ZF))
5438  M.x86.R_IP = target;
5439  DECODE_CLEAR_SEGOVR();
5440  END_OF_INSTR();
5441 }
5442 
5443 /****************************************************************************
5444 REMARKS:
5445 Handles opcode 0x75
5446 ****************************************************************************/
5447 static void x86emuOp_jump_near_NZ(u8 X86EMU_UNUSED(op1))
5448 {
5449  s8 offset;
5450  u16 target;
5451 
5452  /* jump to byte offset if zero flag is clear. */
5453  START_OF_INSTR();
5454  DECODE_PRINTF("JNZ\t");
5455  offset = (s8) fetch_byte_imm();
5456  target = (u16)(M.x86.R_IP + (s16) offset);
5457  DECODE_PRINTF2("%x\n", target);
5458  TRACE_AND_STEP();
5459  if (!ACCESS_FLAG(F_ZF))
5460  M.x86.R_IP = target;
5461  DECODE_CLEAR_SEGOVR();
5462  END_OF_INSTR();
5463 }
5464 
5465 /****************************************************************************
5466 REMARKS:
5467 Handles opcode 0x76
5468 ****************************************************************************/
5469 static void x86emuOp_jump_near_BE(u8 X86EMU_UNUSED(op1))
5470 {
5471  s8 offset;
5472  u16 target;
5473 
5474  /* jump to byte offset if carry flag is set or if the zero
5475  flag is set. */
5476  START_OF_INSTR();
5477  DECODE_PRINTF("JBE\t");
5478  offset = (s8) fetch_byte_imm();
5479  target = (u16)(M.x86.R_IP + (s16) offset);
5480  DECODE_PRINTF2("%x\n", target);
5481  TRACE_AND_STEP();
5482  if (ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF))
5483  M.x86.R_IP = target;
5484  DECODE_CLEAR_SEGOVR();
5485  END_OF_INSTR();
5486 }
5487 
5488 /****************************************************************************
5489 REMARKS:
5490 Handles opcode 0x77
5491 ****************************************************************************/
5492 static void x86emuOp_jump_near_NBE(u8 X86EMU_UNUSED(op1))
5493 {
5494  s8 offset;
5495  u16 target;
5496 
5497  /* jump to byte offset if carry flag is clear and if the zero
5498  flag is clear */
5499  START_OF_INSTR();
5500  DECODE_PRINTF("JNBE\t");
5501  offset = (s8) fetch_byte_imm();
5502  target = (u16)(M.x86.R_IP + (s16) offset);
5503  DECODE_PRINTF2("%x\n", target);
5504  TRACE_AND_STEP();
5505  if (!(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF)))
5506  M.x86.R_IP = target;
5507  DECODE_CLEAR_SEGOVR();
5508  END_OF_INSTR();
5509 }
5510 
5511 /****************************************************************************
5512 REMARKS:
5513 Handles opcode 0x78
5514 ****************************************************************************/
5515 static void x86emuOp_jump_near_S(u8 X86EMU_UNUSED(op1))
5516 {
5517  s8 offset;
5518  u16 target;
5519 
5520  /* jump to byte offset if sign flag is set */
5521  START_OF_INSTR();
5522  DECODE_PRINTF("JS\t");
5523  offset = (s8) fetch_byte_imm();
5524  target = (u16)(M.x86.R_IP + (s16) offset);
5525  DECODE_PRINTF2("%x\n", target);
5526  TRACE_AND_STEP();
5527  if (ACCESS_FLAG(F_SF))
5528  M.x86.R_IP = target;
5529  DECODE_CLEAR_SEGOVR();
5530  END_OF_INSTR();
5531 }
5532 
5533 /****************************************************************************
5534 REMARKS:
5535 Handles opcode 0x79
5536 ****************************************************************************/
5537 static void x86emuOp_jump_near_NS(u8 X86EMU_UNUSED(op1))
5538 {
5539  s8 offset;
5540  u16 target;
5541 
5542  /* jump to byte offset if sign flag is clear */
5543  START_OF_INSTR();
5544  DECODE_PRINTF("JNS\t");
5545  offset = (s8) fetch_byte_imm();
5546  target = (u16)(M.x86.R_IP + (s16) offset);
5547  DECODE_PRINTF2("%x\n", target);
5548  TRACE_AND_STEP();
5549  if (!ACCESS_FLAG(F_SF))
5550  M.x86.R_IP = target;
5551  DECODE_CLEAR_SEGOVR();
5552  END_OF_INSTR();
5553 }
5554 
5555 /****************************************************************************
5556 REMARKS:
5557 Handles opcode 0x7a
5558 ****************************************************************************/
5559 static void x86emuOp_jump_near_P(u8 X86EMU_UNUSED(op1))
5560 {
5561  s8 offset;
5562  u16 target;
5563 
5564  /* jump to byte offset if parity flag is set (even parity) */
5565  START_OF_INSTR();
5566  DECODE_PRINTF("JP\t");
5567  offset = (s8) fetch_byte_imm();
5568  target = (u16)(M.x86.R_IP + (s16) offset);
5569  DECODE_PRINTF2("%x\n", target);
5570  TRACE_AND_STEP();
5571  if (ACCESS_FLAG(F_PF))
5572  M.x86.R_IP = target;
5573  DECODE_CLEAR_SEGOVR();
5574  END_OF_INSTR();
5575 }
5576 
5577 /****************************************************************************
5578 REMARKS:
5579 Handles opcode 0x7b
5580 ****************************************************************************/
5581 static void x86emuOp_jump_near_NP(u8 X86EMU_UNUSED(op1))
5582 {
5583  s8 offset;
5584  u16 target;
5585 
5586  /* jump to byte offset if parity flag is clear (odd parity) */
5587  START_OF_INSTR();
5588  DECODE_PRINTF("JNP\t");
5589  offset = (s8) fetch_byte_imm();
5590  target = (u16)(M.x86.R_IP + (s16) offset);
5591  DECODE_PRINTF2("%x\n", target);
5592  TRACE_AND_STEP();
5593  if (!ACCESS_FLAG(F_PF))
5594  M.x86.R_IP = target;
5595  DECODE_CLEAR_SEGOVR();
5596  END_OF_INSTR();
5597 }
5598 
5599 /****************************************************************************
5600 REMARKS:
5601 Handles opcode 0x7c
5602 ****************************************************************************/
5603 static void x86emuOp_jump_near_L(u8 X86EMU_UNUSED(op1))
5604 {
5605  s8 offset;
5606  u16 target;
5607  int sf, of;
5608 
5609  /* jump to byte offset if sign flag not equal to overflow flag. */
5610  START_OF_INSTR();
5611  DECODE_PRINTF("JL\t");
5612  offset = (s8) fetch_byte_imm();
5613  target = (u16)(M.x86.R_IP + (s16) offset);
5614  DECODE_PRINTF2("%x\n", target);
5615  TRACE_AND_STEP();
5616  sf = ACCESS_FLAG(F_SF) != 0;
5617  of = ACCESS_FLAG(F_OF) != 0;
5618  if (sf ^ of)
5619  M.x86.R_IP = target;
5620  DECODE_CLEAR_SEGOVR();
5621  END_OF_INSTR();
5622 }
5623 
5624 /****************************************************************************
5625 REMARKS:
5626 Handles opcode 0x7d
5627 ****************************************************************************/
5628 static void x86emuOp_jump_near_NL(u8 X86EMU_UNUSED(op1))
5629 {
5630  s8 offset;
5631  u16 target;
5632  int sf, of;
5633 
5634  /* jump to byte offset if sign flag not equal to overflow flag. */
5635  START_OF_INSTR();
5636  DECODE_PRINTF("JNL\t");
5637  offset = (s8) fetch_byte_imm();
5638  target = (u16)(M.x86.R_IP + (s16) offset);
5639  DECODE_PRINTF2("%x\n", target);
5640  TRACE_AND_STEP();
5641  sf = ACCESS_FLAG(F_SF) != 0;
5642  of = ACCESS_FLAG(F_OF) != 0;
5643  /* note: inverse of above, but using == instead of xor. */
5644  if (sf == of)
5645  M.x86.R_IP = target;
5646  DECODE_CLEAR_SEGOVR();
5647  END_OF_INSTR();
5648 }
5649 
5650 /****************************************************************************
5651 REMARKS:
5652 Handles opcode 0x7e
5653 ****************************************************************************/
5654 static void x86emuOp_jump_near_LE(u8 X86EMU_UNUSED(op1))
5655 {
5656  s8 offset;
5657  u16 target;
5658  int sf, of;
5659 
5660  /* jump to byte offset if sign flag not equal to overflow flag
5661  or the zero flag is set */
5662  START_OF_INSTR();
5663  DECODE_PRINTF("JLE\t");
5664  offset = (s8) fetch_byte_imm();
5665  target = (u16)(M.x86.R_IP + (s16) offset);
5666  DECODE_PRINTF2("%x\n", target);
5667  TRACE_AND_STEP();
5668  sf = ACCESS_FLAG(F_SF) != 0;
5669  of = ACCESS_FLAG(F_OF) != 0;
5670  if ((sf ^ of) || ACCESS_FLAG(F_ZF))
5671  M.x86.R_IP = target;
5672  DECODE_CLEAR_SEGOVR();
5673  END_OF_INSTR();
5674 }
5675 
5676 /****************************************************************************
5677 REMARKS:
5678 Handles opcode 0x7f
5679 ****************************************************************************/
5680 static void x86emuOp_jump_near_NLE(u8 X86EMU_UNUSED(op1))
5681 {
5682  s8 offset;
5683  u16 target;
5684  int sf, of;
5685 
5686  /* jump to byte offset if sign flag equal to overflow flag.
5687  and the zero flag is clear */
5688  START_OF_INSTR();
5689  DECODE_PRINTF("JNLE\t");
5690  offset = (s8) fetch_byte_imm();
5691  target = (u16)(M.x86.R_IP + (s16) offset);
5692  DECODE_PRINTF2("%x\n", target);
5693  TRACE_AND_STEP();
5694  sf = ACCESS_FLAG(F_SF) != 0;
5695  of = ACCESS_FLAG(F_OF) != 0;
5696  if ((sf == of) && !ACCESS_FLAG(F_ZF))
5697  M.x86.R_IP = target;
5698  DECODE_CLEAR_SEGOVR();
5699  END_OF_INSTR();
5700 }
5701 
5702 static u8 (*opc80_byte_operation[])(u8 d, u8 s) = {
5703  add_byte, /* 00 */
5704  or_byte, /* 01 */
5705  adc_byte, /* 02 */
5706  sbb_byte, /* 03 */
5707  and_byte, /* 04 */
5708  sub_byte, /* 05 */
5709  xor_byte, /* 06 */
5710  cmp_byte, /* 07 */
5711 };
5712 
5713 /****************************************************************************
5714 REMARKS:
5715 Handles opcode 0x80
5716 ****************************************************************************/
5717 static void x86emuOp_opc80_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
5718 {
5719  int mod, rl, rh;
5720  u8 *destreg;
5721  uint destoffset;
5722  u8 imm;
5723  u8 destval;
5724 
5725  /*
5726  * Weirdo special case instruction format. Part of the opcode
5727  * held below in "RH". Doubly nested case would result, except
5728  * that the decoded instruction
5729  */
5730  START_OF_INSTR();
5731  FETCH_DECODE_MODRM(mod, rh, rl);
5732 #ifdef DEBUG
5733  if (DEBUG_DECODE())
5734  {
5735  /* XXX DECODE_PRINTF may be changed to something more
5736  general, so that it is important to leave the strings
5737  in the same format, even though the result is that the
5738  above test is done twice. */
5739 
5740  switch (rh)
5741  {
5742  case 0:
5743  DECODE_PRINTF("ADD\t");
5744  break;
5745  case 1:
5746  DECODE_PRINTF("OR\t");
5747  break;
5748  case 2:
5749  DECODE_PRINTF("ADC\t");
5750  break;
5751  case 3:
5752  DECODE_PRINTF("SBB\t");
5753  break;
5754  case 4:
5755  DECODE_PRINTF("AND\t");
5756  break;
5757  case 5:
5758  DECODE_PRINTF("SUB\t");
5759  break;
5760  case 6:
5761  DECODE_PRINTF("XOR\t");
5762  break;
5763  case 7:
5764  DECODE_PRINTF("CMP\t");
5765  break;
5766  }
5767  }
5768 #endif
5769  /* know operation, decode the mod byte to find the addressing
5770  mode. */
5771  switch (mod)
5772  {
5773  case 0:
5774  DECODE_PRINTF("BYTE PTR ");
5775  destoffset = decode_rm00_address(rl);
5776  DECODE_PRINTF(",");
5777  destval = fetch_data_byte(destoffset);
5778  imm = fetch_byte_imm();
5779  DECODE_PRINTF2("%x\n", imm);
5780  TRACE_AND_STEP();
5781  destval = (*opc80_byte_operation[rh])(destval, imm);
5782  if (rh != 7)
5783  store_data_byte(destoffset, destval);
5784  break;
5785  case 1:
5786  DECODE_PRINTF("BYTE PTR ");
5787  destoffset = decode_rm01_address(rl);
5788  DECODE_PRINTF(",");
5789  destval = fetch_data_byte(destoffset);
5790  imm = fetch_byte_imm();
5791  DECODE_PRINTF2("%x\n", imm);
5792  TRACE_AND_STEP();
5793  destval = (*opc80_byte_operation[rh])(destval, imm);
5794  if (rh != 7)
5795  store_data_byte(destoffset, destval);
5796  break;
5797  case 2:
5798  DECODE_PRINTF("BYTE PTR ");
5799  destoffset = decode_rm10_address(rl);
5800  DECODE_PRINTF(",");
5801  destval = fetch_data_byte(destoffset);
5802  imm = fetch_byte_imm();
5803  DECODE_PRINTF2("%x\n", imm);
5804  TRACE_AND_STEP();
5805  destval = (*opc80_byte_operation[rh])(destval, imm);
5806  if (rh != 7)
5807  store_data_byte(destoffset, destval);
5808  break;
5809  case 3: /* register to register */
5810  destreg = DECODE_RM_BYTE_REGISTER(rl);
5811  DECODE_PRINTF(",");
5812  imm = fetch_byte_imm();
5813  DECODE_PRINTF2("%x\n", imm);
5814  TRACE_AND_STEP();
5815  destval = (*opc80_byte_operation[rh])(*destreg, imm);
5816  if (rh != 7)
5817  *destreg = destval;
5818  break;
5819  }
5820  DECODE_CLEAR_SEGOVR();
5821  END_OF_INSTR();
5822 }
5823 
5824 static u16 (*opc81_word_operation[])(u16 d, u16 s) = {
5825  add_word, /*00 */
5826  or_word, /*01 */
5827  adc_word, /*02 */
5828  sbb_word, /*03 */
5829  and_word, /*04 */
5830  sub_word, /*05 */
5831  xor_word, /*06 */
5832  cmp_word, /*07 */
5833 };
5834 
5835 static u32 (*opc81_long_operation[])(u32 d, u32 s) = {
5836  add_long, /*00 */
5837  or_long, /*01 */
5838  adc_long, /*02 */
5839  sbb_long, /*03 */
5840  and_long, /*04 */
5841  sub_long, /*05 */
5842  xor_long, /*06 */
5843  cmp_long, /*07 */
5844 };
5845 
5846 /****************************************************************************
5847 REMARKS:
5848 Handles opcode 0x81
5849 ****************************************************************************/
5850 static void x86emuOp_opc81_word_RM_IMM(u8 X86EMU_UNUSED(op1))
5851 {
5852  int mod, rl, rh;
5853  uint destoffset;
5854 
5855  /*
5856  * Weirdo special case instruction format. Part of the opcode
5857  * held below in "RH". Doubly nested case would result, except
5858  * that the decoded instruction
5859  */
5860  START_OF_INSTR();
5861  FETCH_DECODE_MODRM(mod, rh, rl);
5862 #ifdef DEBUG
5863  if (DEBUG_DECODE())
5864  {
5865  /* XXX DECODE_PRINTF may be changed to something more
5866  general, so that it is important to leave the strings
5867  in the same format, even though the result is that the
5868  above test is done twice. */
5869 
5870  switch (rh)
5871  {
5872  case 0:
5873  DECODE_PRINTF("ADD\t");
5874  break;
5875  case 1:
5876  DECODE_PRINTF("OR\t");
5877  break;
5878  case 2:
5879  DECODE_PRINTF("ADC\t");
5880  break;
5881  case 3:
5882  DECODE_PRINTF("SBB\t");
5883  break;
5884  case 4:
5885  DECODE_PRINTF("AND\t");
5886  break;
5887  case 5:
5888  DECODE_PRINTF("SUB\t");
5889  break;
5890  case 6:
5891  DECODE_PRINTF("XOR\t");
5892  break;
5893  case 7:
5894  DECODE_PRINTF("CMP\t");
5895  break;
5896  }
5897  }
5898 #endif
5899  /*
5900  * Know operation, decode the mod byte to find the addressing
5901  * mode.
5902  */
5903  switch (mod)
5904  {
5905  case 0:
5906  if (M.x86.mode & SYSMODE_PREFIX_DATA)
5907  {
5908  u32 destval, imm;
5909 
5910  DECODE_PRINTF("DWORD PTR ");
5911  destoffset = decode_rm00_address(rl);
5912  DECODE_PRINTF(",");
5913  destval = fetch_data_long(destoffset);
5914  imm = fetch_long_imm();
5915  DECODE_PRINTF2("%x\n", imm);
5916  TRACE_AND_STEP();
5917  destval = (*opc81_long_operation[rh])(destval, imm);
5918  if (rh != 7)
5919  store_data_long(destoffset, destval);
5920  }
5921  else
5922  {
5923  u16 destval, imm;
5924 
5925  DECODE_PRINTF("WORD PTR ");
5926  destoffset = decode_rm00_address(rl);
5927  DECODE_PRINTF(",");
5928  destval = fetch_data_word(destoffset);
5929  imm = fetch_word_imm();
5930  DECODE_PRINTF2("%x\n", imm);
5931  TRACE_AND_STEP();
5932  destval = (*opc81_word_operation[rh])(destval, imm);
5933  if (rh != 7)
5934  store_data_word(destoffset, destval);
5935  }
5936  break;
5937  case 1:
5938  if (M.x86.mode & SYSMODE_PREFIX_DATA)
5939  {
5940  u32 destval, imm;
5941 
5942  DECODE_PRINTF("DWORD PTR ");
5943  destoffset = decode_rm01_address(rl);
5944  DECODE_PRINTF(",");
5945  destval = fetch_data_long(destoffset);
5946  imm = fetch_long_imm();
5947  DECODE_PRINTF2("%x\n", imm);
5948  TRACE_AND_STEP();
5949  destval = (*opc81_long_operation[rh])(destval, imm);
5950  if (rh != 7)
5951  store_data_long(destoffset, destval);
5952  }
5953  else
5954  {
5955  u16 destval, imm;
5956 
5957  DECODE_PRINTF("WORD PTR ");
5958  destoffset = decode_rm01_address(rl);
5959  DECODE_PRINTF(",");
5960  destval = fetch_data_word(destoffset);
5961  imm = fetch_word_imm();
5962  DECODE_PRINTF2("%x\n", imm);
5963  TRACE_AND_STEP();
5964  destval = (*opc81_word_operation[rh])(destval, imm);
5965  if (rh != 7)
5966  store_data_word(destoffset, destval);
5967  }
5968  break;
5969  case 2:
5970  if (M.x86.mode & SYSMODE_PREFIX_DATA)
5971  {
5972  u32 destval, imm;
5973 
5974  DECODE_PRINTF("DWORD PTR ");
5975  destoffset = decode_rm10_address(rl);
5976  DECODE_PRINTF(",");
5977  destval = fetch_data_long(destoffset);
5978  imm = fetch_long_imm();
5979  DECODE_PRINTF2("%x\n", imm);
5980  TRACE_AND_STEP();
5981  destval = (*opc81_long_operation[rh])(destval, imm);
5982  if (rh != 7)
5983  store_data_long(destoffset, destval);
5984  }
5985  else
5986  {
5987  u16 destval, imm;
5988 
5989  DECODE_PRINTF("WORD PTR ");
5990  destoffset = decode_rm10_address(rl);
5991  DECODE_PRINTF(",");
5992  destval = fetch_data_word(destoffset);
5993  imm = fetch_word_imm();
5994  DECODE_PRINTF2("%x\n", imm);
5995  TRACE_AND_STEP();
5996  destval = (*opc81_word_operation[rh])(destval, imm);
5997  if (rh != 7)
5998  store_data_word(destoffset, destval);
5999  }
6000  break;
6001  case 3: /* register to register */
6002  if (M.x86.mode & SYSMODE_PREFIX_DATA)
6003  {
6004  u32 *destreg;
6005  u32 destval, imm;
6006 
6007  destreg = DECODE_RM_LONG_REGISTER(rl);
6008  DECODE_PRINTF(",");
6009  imm = fetch_long_imm();
6010  DECODE_PRINTF2("%x\n", imm);
6011  TRACE_AND_STEP();
6012  destval = (*opc81_long_operation[rh])(*destreg, imm);
6013  if (rh != 7)
6014  *destreg = destval;
6015  }
6016  else
6017  {
6018  u16 *destreg;
6019  u16 destval, imm;
6020 
6021  destreg = DECODE_RM_WORD_REGISTER(rl);
6022  DECODE_PRINTF(",");
6023  imm = fetch_word_imm();
6024  DECODE_PRINTF2("%x\n", imm);
6025  TRACE_AND_STEP();
6026  destval = (*opc81_word_operation[rh])(*destreg, imm);
6027  if (rh != 7)
6028  *destreg = destval;
6029  }
6030  break;
6031  }
6032  DECODE_CLEAR_SEGOVR();
6033  END_OF_INSTR();
6034 }
6035 
6036 static u8 (*opc82_byte_operation[])(u8 s, u8 d) = {
6037  add_byte, /*00 */
6038  or_byte,
6039  /*01 */ /*YYY UNUSED ???? */
6040  adc_byte, /*02 */
6041  sbb_byte, /*03 */
6042  and_byte,
6043  /*04 */ /*YYY UNUSED ???? */
6044  sub_byte, /*05 */
6045  xor_byte,
6046  /*06 */ /*YYY UNUSED ???? */
6047  cmp_byte, /*07 */
6048 };
6049 
6050 /****************************************************************************
6051 REMARKS:
6052 Handles opcode 0x82
6053 ****************************************************************************/
6054 static void x86emuOp_opc82_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
6055 {
6056  int mod, rl, rh;
6057  u8 *destreg;
6058  uint destoffset;
6059  u8 imm;
6060  u8 destval;
6061 
6062  /*
6063  * Weirdo special case instruction format. Part of the opcode
6064  * held below in "RH". Doubly nested case would result, except
6065  * that the decoded instruction Similar to opcode 81, except that
6066  * the immediate byte is sign extended to a word length.
6067  */
6068  START_OF_INSTR();
6069  FETCH_DECODE_MODRM(mod, rh, rl);
6070 #ifdef DEBUG
6071  if (DEBUG_DECODE())
6072  {
6073  /* XXX DECODE_PRINTF may be changed to something more
6074  general, so that it is important to leave the strings
6075  in the same format, even though the result is that the
6076  above test is done twice. */
6077  switch (rh)
6078  {
6079  case 0:
6080  DECODE_PRINTF("ADD\t");
6081  break;
6082  case 1:
6083  DECODE_PRINTF("OR\t");
6084  break;
6085  case 2:
6086  DECODE_PRINTF("ADC\t");
6087  break;
6088  case 3:
6089  DECODE_PRINTF("SBB\t");
6090  break;
6091  case 4:
6092  DECODE_PRINTF("AND\t");
6093  break;
6094  case 5:
6095  DECODE_PRINTF("SUB\t");
6096  break;
6097  case 6:
6098  DECODE_PRINTF("XOR\t");
6099  break;
6100  case 7:
6101  DECODE_PRINTF("CMP\t");
6102  break;
6103  }
6104  }
6105 #endif
6106  /* know operation, decode the mod byte to find the addressing
6107  mode. */
6108  switch (mod)
6109  {
6110  case 0:
6111  DECODE_PRINTF("BYTE PTR ");
6112  destoffset = decode_rm00_address(rl);
6113  destval = fetch_data_byte(destoffset);
6114  imm = fetch_byte_imm();
6115  DECODE_PRINTF2(",%x\n", imm);
6116  TRACE_AND_STEP();
6117  destval = (*opc82_byte_operation[rh])(destval, imm);
6118  if (rh != 7)
6119  store_data_byte(destoffset, destval);
6120  break;
6121  case 1:
6122  DECODE_PRINTF("BYTE PTR ");
6123  destoffset = decode_rm01_address(rl);
6124  destval = fetch_data_byte(destoffset);
6125  imm = fetch_byte_imm();
6126  DECODE_PRINTF2(",%x\n", imm);
6127  TRACE_AND_STEP();
6128  destval = (*opc82_byte_operation[rh])(destval, imm);
6129  if (rh != 7)
6130  store_data_byte(destoffset, destval);
6131  break;
6132  case 2:
6133  DECODE_PRINTF("BYTE PTR ");
6134  destoffset = decode_rm10_address(rl);
6135  destval = fetch_data_byte(destoffset);
6136  imm = fetch_byte_imm();
6137  DECODE_PRINTF2(",%x\n", imm);
6138  TRACE_AND_STEP();
6139  destval = (*opc82_byte_operation[rh])(destval, imm);
6140  if (rh != 7)
6141  store_data_byte(destoffset, destval);
6142  break;
6143  case 3: /* register to register */
6144  destreg = DECODE_RM_BYTE_REGISTER(rl);
6145  imm = fetch_byte_imm();
6146  DECODE_PRINTF2(",%x\n", imm);
6147  TRACE_AND_STEP();
6148  destval = (*opc82_byte_operation[rh])(*destreg, imm);
6149  if (rh != 7)
6150  *destreg = destval;
6151  break;
6152  }
6153  DECODE_CLEAR_SEGOVR();
6154  END_OF_INSTR();
6155 }
6156 
6157 static u16 (*opc83_word_operation[])(u16 s, u16 d) = {
6158  add_word, /*00 */
6159  or_word,
6160  /*01 */ /*YYY UNUSED ???? */
6161  adc_word, /*02 */
6162  sbb_word, /*03 */
6163  and_word,
6164  /*04 */ /*YYY UNUSED ???? */
6165  sub_word, /*05 */
6166  xor_word,
6167  /*06 */ /*YYY UNUSED ???? */
6168  cmp_word, /*07 */
6169 };
6170 
6171 static u32 (*opc83_long_operation[])(u32 s, u32 d) = {
6172  add_long, /*00 */
6173  or_long,
6174  /*01 */ /*YYY UNUSED ???? */
6175  adc_long, /*02 */
6176  sbb_long, /*03 */
6177  and_long,
6178  /*04 */ /*YYY UNUSED ???? */
6179  sub_long, /*05 */
6180  xor_long,
6181  /*06 */ /*YYY UNUSED ???? */
6182  cmp_long, /*07 */
6183 };
6184 
6185 /****************************************************************************
6186 REMARKS:
6187 Handles opcode 0x83
6188 ****************************************************************************/
6189 static void x86emuOp_opc83_word_RM_IMM(u8 X86EMU_UNUSED(op1))
6190 {
6191  int mod, rl, rh;
6192  uint destoffset;
6193 
6194  /*
6195  * Weirdo special case instruction format. Part of the opcode
6196  * held below in "RH". Doubly nested case would result, except
6197  * that the decoded instruction Similar to opcode 81, except that
6198  * the immediate byte is sign extended to a word length.
6199  */
6200  START_OF_INSTR();
6201  FETCH_DECODE_MODRM(mod, rh, rl);
6202 #ifdef DEBUG
6203  if (DEBUG_DECODE())
6204  {
6205  /* XXX DECODE_PRINTF may be changed to something more
6206  general, so that it is important to leave the strings
6207  in the same format, even though the result is that the
6208  above test is done twice. */
6209  switch (rh)
6210  {
6211  case 0:
6212  DECODE_PRINTF("ADD\t");
6213  break;
6214  case 1:
6215  DECODE_PRINTF("OR\t");
6216  break;
6217  case 2:
6218  DECODE_PRINTF("ADC\t");
6219  break;
6220  case 3:
6221  DECODE_PRINTF("SBB\t");
6222  break;
6223  case 4:
6224  DECODE_PRINTF("AND\t");
6225  break;
6226  case 5:
6227  DECODE_PRINTF("SUB\t");
6228  break;
6229  case 6:
6230  DECODE_PRINTF("XOR\t");
6231  break;
6232  case 7:
6233  DECODE_PRINTF("CMP\t");
6234  break;
6235  }
6236  }
6237 #endif
6238  /* know operation, decode the mod byte to find the addressing
6239  mode. */
6240  switch (mod)
6241  {
6242  case 0:
6243  if (M.x86.mode & SYSMODE_PREFIX_DATA)
6244  {
6245  u32 destval, imm;
6246 
6247  DECODE_PRINTF("DWORD PTR ");
6248  destoffset = decode_rm00_address(rl);
6249  destval = fetch_data_long(destoffset);
6250  imm = (s8) fetch_byte_imm();
6251  DECODE_PRINTF2(",%x\n", imm);
6252  TRACE_AND_STEP();
6253  destval = (*opc83_long_operation[rh])(destval, imm);
6254  if (rh != 7)
6255  store_data_long(destoffset, destval);
6256  }
6257  else
6258  {
6259  u16 destval, imm;
6260 
6261  DECODE_PRINTF("WORD PTR ");
6262  destoffset = decode_rm00_address(rl);
6263  destval = fetch_data_word(destoffset);
6264  imm = (s8) fetch_byte_imm();
6265  DECODE_PRINTF2(",%x\n", imm);
6266  TRACE_AND_STEP();
6267  destval = (*opc83_word_operation[rh])(destval, imm);
6268  if (rh != 7)
6269  store_data_word(destoffset, destval);
6270  }
6271  break;
6272  case 1:
6273  if (M.x86.mode & SYSMODE_PREFIX_DATA)
6274  {
6275  u32 destval, imm;
6276 
6277  DECODE_PRINTF("DWORD PTR ");
6278  destoffset = decode_rm01_address(rl);
6279  destval = fetch_data_long(destoffset);
6280  imm = (s8) fetch_byte_imm();
6281  DECODE_PRINTF2(",%x\n", imm);
6282  TRACE_AND_STEP();
6283  destval = (*opc83_long_operation[rh])(destval, imm);
6284  if (rh != 7)
6285  store_data_long(destoffset, destval);
6286  }
6287  else
6288  {
6289  u16 destval, imm;
6290 
6291  DECODE_PRINTF("WORD PTR ");
6292  destoffset = decode_rm01_address(rl);
6293  destval = fetch_data_word(destoffset);
6294  imm = (s8) fetch_byte_imm();
6295  DECODE_PRINTF2(",%x\n", imm);
6296  TRACE_AND_STEP();
6297  destval = (*opc83_word_operation[rh])(destval, imm);
6298  if (rh != 7)
6299  store_data_word(destoffset, destval);
6300  }
6301  break;
6302  case 2:
6303  if (M.x86.mode & SYSMODE_PREFIX_DATA)
6304  {
6305  u32 destval, imm;
6306 
6307  DECODE_PRINTF("DWORD PTR ");
6308  destoffset = decode_rm10_address(rl);
6309  destval = fetch_data_long(destoffset);
6310  imm = (s8) fetch_byte_imm();
6311  DECODE_PRINTF2(",%x\n", imm);
6312  TRACE_AND_STEP();
6313  destval = (*opc83_long_operation[rh])(destval, imm);
6314  if (rh != 7)
6315  store_data_long(destoffset, destval);
6316  }
6317  else
6318  {
6319  u16 destval, imm;
6320 
6321  DECODE_PRINTF("WORD PTR ");
6322  destoffset = decode_rm10_address(rl);
6323  destval = fetch_data_word(destoffset);
6324  imm = (s8) fetch_byte_imm();
6325  DECODE_PRINTF2(",%x\n", imm);
6326  TRACE_AND_STEP();
6327  destval = (*opc83_word_operation[rh])(destval, imm);
6328  if (rh != 7)
6329  store_data_word(destoffset, destval);
6330  }
6331  break;
6332  case 3: /* register to register */
6333  if (M.x86.mode & SYSMODE_PREFIX_DATA)
6334  {
6335  u32 *destreg;
6336  u32 destval, imm;
6337 
6338  destreg = DECODE_RM_LONG_REGISTER(rl);
6339  imm = (s8) fetch_byte_imm();
6340  DECODE_PRINTF2(",%x\n", imm);
6341  TRACE_AND_STEP();
6342  destval = (*opc83_long_operation[rh])(*destreg, imm);
6343  if (rh != 7)
6344  *destreg = destval;
6345  }
6346  else
6347  {
6348  u16 *destreg;
6349  u16 destval, imm;
6350 
6351  destreg = DECODE_RM_WORD_REGISTER(rl);
6352  imm = (s8) fetch_byte_imm();
6353  DECODE_PRINTF2(",%x\n", imm);
6354  TRACE_AND_STEP();
6355  destval = (*opc83_word_operation[rh])(*destreg, imm);
6356  if (rh != 7)
6357  *destreg = destval;
6358  }
6359  break;
6360  }
6361  DECODE_CLEAR_SEGOVR();
6362  END_OF_INSTR();
6363 }
6364 
6365 /****************************************************************************
6366 REMARKS:
6367 Handles opcode 0x84
6368 ****************************************************************************/
6369 static void x86emuOp_test_byte_RM_R(u8 X86EMU_UNUSED(op1))
6370 {
6371  int mod, rl, rh;
6372  u8 *destreg, *srcreg;
6373  uint destoffset;
6374  u8 destval;
6375 
6376  START_OF_INSTR();
6377  DECODE_PRINTF("TEST\t");
6378  FETCH_DECODE_MODRM(mod, rh, rl);
6379  switch (mod)
6380  {
6381  case 0:
6382  destoffset = decode_rm00_address(rl);
6383  DECODE_PRINTF(",");
6384  destval = fetch_data_byte(destoffset);
6385  srcreg = DECODE_RM_BYTE_REGISTER(rh);
6386  DECODE_PRINTF("\n");
6387  TRACE_AND_STEP();
6388  test_byte(destval, *srcreg);
6389  break;
6390  case 1:
6391  destoffset = decode_rm01_address(rl);
6392  DECODE_PRINTF(",");
6393  destval = fetch_data_byte(destoffset);
6394  srcreg = DECODE_RM_BYTE_REGISTER(rh);
6395  DECODE_PRINTF("\n");
6396  TRACE_AND_STEP();
6397  test_byte(destval, *srcreg);
6398  break;
6399  case 2:
6400  destoffset = decode_rm10_address(rl);
6401  DECODE_PRINTF(",");
6402  destval = fetch_data_byte(destoffset);
6403  srcreg = DECODE_RM_BYTE_REGISTER(rh);
6404  DECODE_PRINTF("\n");
6405  TRACE_AND_STEP();
6406  test_byte(destval, *srcreg);
6407  break;
6408  case 3: /* register to register */
6409  destreg = DECODE_RM_BYTE_REGISTER(rl);
6410  DECODE_PRINTF(",");
6411  srcreg = DECODE_RM_BYTE_REGISTER(rh);
6412  DECODE_PRINTF("\n");
6413  TRACE_AND_STEP();
6414  test_byte(*destreg, *srcreg);
6415  break;
6416  }
6417  DECODE_CLEAR_SEGOVR();
6418  END_OF_INSTR();
6419 }
6420 
6421 /****************************************************************************
6422 REMARKS:
6423 Handles opcode 0x85
6424 ****************************************************************************/
6425 static void x86emuOp_test_word_RM_R(u8 X86EMU_UNUSED(op1))
6426 {
6427  int mod, rl, rh;
6428  uint destoffset;
6429 
6430  START_OF_INSTR();
6431  DECODE_PRINTF("TEST\t");
6432  FETCH_DECODE_MODRM(mod, rh, rl);
6433  switch (mod)
6434  {
6435  case 0:
6436  if (M.x86.mode & SYSMODE_PREFIX_DATA)
6437  {
6438  u32 destval;
6439  u32 *srcreg;
6440 
6441  destoffset = decode_rm00_address(rl);
6442  DECODE_PRINTF(",");
6443  destval = fetch_data_long(destoffset);
6444  srcreg = DECODE_RM_LONG_REGISTER(rh);
6445  DECODE_PRINTF("\n");
6446  TRACE_AND_STEP();
6447  test_long(destval, *srcreg);
6448  }
6449  else
6450  {
6451  u16 destval;
6452  u16 *srcreg;
6453 
6454  destoffset = decode_rm00_address(rl);
6455  DECODE_PRINTF(",");
6456  destval = fetch_data_word(destoffset);
6457  srcreg = DECODE_RM_WORD_REGISTER(rh);
6458  DECODE_PRINTF("\n");
6459  TRACE_AND_STEP();
6460  test_word(destval, *srcreg);
6461  }
6462  break;
6463  case 1:
6464  if (M.x86.mode & SYSMODE_PREFIX_DATA)
6465  {
6466  u32 destval;
6467  u32 *srcreg;
6468 
6469  destoffset = decode_rm01_address(rl);
6470  DECODE_PRINTF(",");
6471  destval = fetch_data_long(destoffset);
6472  srcreg = DECODE_RM_LONG_REGISTER(rh);
6473  DECODE_PRINTF("\n");
6474  TRACE_AND_STEP();
6475  test_long(destval, *srcreg);
6476  }
6477  else
6478  {
6479  u16 destval;
6480  u16 *srcreg;
6481 
6482  destoffset = decode_rm01_address(rl);
6483  DECODE_PRINTF(",");
6484  destval = fetch_data_word(destoffset);
6485  srcreg = DECODE_RM_WORD_REGISTER(rh);
6486  DECODE_PRINTF("\n");
6487  TRACE_AND_STEP();
6488  test_word(destval, *srcreg);
6489  }
6490  break;
6491  case 2:
6492  if (M.x86.mode & SYSMODE_PREFIX_DATA)
6493  {
6494  u32 destval;
6495  u32 *srcreg;
6496 
6497  destoffset = decode_rm10_address(rl);
6498  DECODE_PRINTF(",");
6499  destval = fetch_data_long(destoffset);
6500  srcreg = DECODE_RM_LONG_REGISTER(rh);
6501  DECODE_PRINTF("\n");
6502  TRACE_AND_STEP();
6503  test_long(destval, *srcreg);
6504  }
6505  else
6506  {
6507  u16 destval;
6508  u16 *srcreg;
6509 
6510  destoffset = decode_rm10_address(rl);
6511  DECODE_PRINTF(",");
6512  destval = fetch_data_word(destoffset);
6513  srcreg = DECODE_RM_WORD_REGISTER(rh);
6514  DECODE_PRINTF("\n");
6515  TRACE_AND_STEP();
6516  test_word(destval, *srcreg);
6517  }
6518  break;
6519  case 3: /* register to register */
6520  if (M.x86.mode & SYSMODE_PREFIX_DATA)
6521  {
6522  u32 *destreg, *srcreg;
6523 
6524  destreg = DECODE_RM_LONG_REGISTER(rl);
6525  DECODE_PRINTF(",");
6526  srcreg = DECODE_RM_LONG_REGISTER(rh);
6527  DECODE_PRINTF("\n");
6528  TRACE_AND_STEP();
6529  test_long(*destreg, *srcreg);
6530  }
6531  else
6532  {
6533  u16 *destreg, *srcreg;
6534 
6535  destreg = DECODE_RM_WORD_REGISTER(rl);
6536  DECODE_PRINTF(",");
6537  srcreg = DECODE_RM_WORD_REGISTER(rh);
6538  DECODE_PRINTF("\n");
6539  TRACE_AND_STEP();
6540  test_word(*destreg, *srcreg);
6541  }
6542  break;
6543  }
6544  DECODE_CLEAR_SEGOVR();
6545  END_OF_INSTR();
6546 }
6547 
6548 /****************************************************************************
6549 REMARKS:
6550 Handles opcode 0x86
6551 ****************************************************************************/
6552 static void x86emuOp_xchg_byte_RM_R(u8 X86EMU_UNUSED(op1))
6553 {
6554  int mod, rl, rh;
6555  u8 *destreg, *srcreg;
6556  uint destoffset;
6557  u8 destval;
6558  u8 tmp;
6559 
6560  START_OF_INSTR();
6561  DECODE_PRINTF("XCHG\t");
6562  FETCH_DECODE_MODRM(mod, rh, rl);
6563  switch (mod)
6564  {
6565  case 0:
6566  destoffset = decode_rm00_address(rl);
6567  DECODE_PRINTF(",");
6568  destval = fetch_data_byte(destoffset);
6569  srcreg = DECODE_RM_BYTE_REGISTER(rh);
6570  DECODE_PRINTF("\n");
6571  TRACE_AND_STEP();
6572  tmp = *srcreg;
6573  *srcreg = destval;
6574  destval = tmp;
6575  store_data_byte(destoffset, destval);
6576  break;
6577  case 1:
6578  destoffset = decode_rm01_address(rl);
6579  DECODE_PRINTF(",");
6580  destval = fetch_data_byte(destoffset);
6581  srcreg = DECODE_RM_BYTE_REGISTER(rh);
6582  DECODE_PRINTF("\n");
6583  TRACE_AND_STEP();
6584  tmp = *srcreg;
6585  *srcreg = destval;
6586  destval = tmp;
6587  store_data_byte(destoffset, destval);
6588  break;
6589  case 2:
6590  destoffset = decode_rm10_address(rl);
6591  DECODE_PRINTF(",");
6592  destval = fetch_data_byte(destoffset);
6593  srcreg = DECODE_RM_BYTE_REGISTER(rh);
6594  DECODE_PRINTF("\n");
6595  TRACE_AND_STEP();
6596  tmp = *srcreg;
6597  *srcreg = destval;
6598  destval = tmp;
6599  store_data_byte(destoffset, destval);
6600  break;
6601  case 3: /* register to register */
6602  destreg = DECODE_RM_BYTE_REGISTER(rl);
6603  DECODE_PRINTF(",");
6604  srcreg = DECODE_RM_BYTE_REGISTER(rh);
6605  DECODE_PRINTF("\n");
6606  TRACE_AND_STEP();
6607  tmp = *srcreg;
6608  *srcreg = *destreg;
6609  *destreg = tmp;
6610  break;
6611  }
6612  DECODE_CLEAR_SEGOVR();
6613  END_OF_INSTR();
6614 }
6615 
6616 /****************************************************************************
6617 REMARKS:
6618 Handles opcode 0x87
6619 ****************************************************************************/
6620 static void x86emuOp_xchg_word_RM_R(u8 X86EMU_UNUSED(op1))
6621 {
6622  int mod, rl, rh;
6623  uint destoffset;
6624 
6625  START_OF_INSTR();
6626  DECODE_PRINTF("XCHG\t");
6627  FETCH_DECODE_MODRM(mod, rh, rl);
6628  switch (mod)
6629  {
6630  case 0:
6631  if (M.x86.mode & SYSMODE_PREFIX_DATA)
6632  {
6633  u32 *srcreg;
6634  u32 destval, tmp;
6635 
6636  destoffset = decode_rm00_address(rl);
6637  DECODE_PRINTF(",");
6638  destval = fetch_data_long(destoffset);
6639  srcreg = DECODE_RM_LONG_REGISTER(rh);
6640  DECODE_PRINTF("\n");
6641  TRACE_AND_STEP();
6642  tmp = *srcreg;
6643  *srcreg = destval;
6644  destval = tmp;
6645  store_data_long(destoffset, destval);
6646  }
6647  else
6648  {
6649  u16 *srcreg;
6650  u16 destval, tmp;
6651 
6652  destoffset = decode_rm00_address(rl);
6653  DECODE_PRINTF(",");
6654  destval = fetch_data_word(destoffset);
6655  srcreg = DECODE_RM_WORD_REGISTER(rh);
6656  DECODE_PRINTF("\n");
6657  TRACE_AND_STEP();
6658  tmp = *srcreg;
6659  *srcreg = destval;
6660  destval = tmp;
6661  store_data_word(destoffset, destval);
6662  }
6663  break;
6664  case 1:
6665  if (M.x86.mode & SYSMODE_PREFIX_DATA)
6666  {
6667  u32 *srcreg;
6668  u32 destval, tmp;
6669 
6670  destoffset = decode_rm01_address(rl);
6671  DECODE_PRINTF(",");
6672  destval = fetch_data_long(destoffset);
6673  srcreg = DECODE_RM_LONG_REGISTER(rh);
6674  DECODE_PRINTF("\n");
6675  TRACE_AND_STEP();
6676  tmp = *srcreg;
6677  *srcreg = destval;
6678  destval = tmp;
6679  store_data_long(destoffset, destval);
6680  }
6681  else
6682  {
6683  u16 *srcreg;
6684  u16 destval, tmp;
6685 
6686  destoffset = decode_rm01_address(rl);
6687  DECODE_PRINTF(",");
6688  destval = fetch_data_word(destoffset);
6689  srcreg = DECODE_RM_WORD_REGISTER(rh);
6690  DECODE_PRINTF("\n");
6691  TRACE_AND_STEP();
6692  tmp = *srcreg;
6693  *srcreg = destval;
6694  destval = tmp;
6695  store_data_word(destoffset, destval);
6696  }
6697  break;
6698  case 2:
6699  if (M.x86.mode & SYSMODE_PREFIX_DATA)
6700  {
6701  u32 *srcreg;
6702  u32 destval, tmp;
6703 
6704  destoffset = decode_rm10_address(rl);
6705  DECODE_PRINTF(",");
6706  destval = fetch_data_long(destoffset);
6707  srcreg = DECODE_RM_LONG_REGISTER(rh);
6708  DECODE_PRINTF("\n");
6709  TRACE_AND_STEP();
6710  tmp = *srcreg;
6711  *srcreg = destval;
6712  destval = tmp;
6713  store_data_long(destoffset, destval);
6714  }
6715  else
6716  {
6717  u16 *srcreg;
6718  u16 destval, tmp;
6719 
6720  destoffset = decode_rm10_address(rl);
6721  DECODE_PRINTF(",");
6722  destval = fetch_data_word(destoffset);
6723  srcreg = DECODE_RM_WORD_REGISTER(rh);
6724  DECODE_PRINTF("\n");
6725  TRACE_AND_STEP();
6726  tmp = *srcreg;
6727  *srcreg = destval;
6728  destval = tmp;
6729  store_data_word(destoffset, destval);
6730  }
6731  break;
6732  case 3: /* register to register */
6733  if (M.x86.mode & SYSMODE_PREFIX_DATA)
6734  {
6735  u32 *destreg, *srcreg;
6736  u32 tmp;
6737 
6738  destreg = DECODE_RM_LONG_REGISTER(rl);
6739  DECODE_PRINTF(",");
6740  srcreg = DECODE_RM_LONG_REGISTER(rh);
6741  DECODE_PRINTF("\n");
6742  TRACE_AND_STEP();
6743  tmp = *srcreg;
6744  *srcreg = *destreg;
6745  *destreg = tmp;
6746  }
6747  else
6748  {
6749  u16 *destreg, *srcreg;
6750  u16 tmp;
6751 
6752  destreg = DECODE_RM_WORD_REGISTER(rl);
6753  DECODE_PRINTF(",");
6754  srcreg = DECODE_RM_WORD_REGISTER(rh);
6755  DECODE_PRINTF("\n");
6756  TRACE_AND_STEP();
6757  tmp = *srcreg;
6758  *srcreg = *destreg;
6759  *destreg = tmp;
6760  }
6761  break;
6762  }
6763  DECODE_CLEAR_SEGOVR();
6764  END_OF_INSTR();
6765 }
6766 
6767 /****************************************************************************
6768 REMARKS:
6769 Handles opcode 0x88
6770 ****************************************************************************/
6771 static void x86emuOp_mov_byte_RM_R(u8 X86EMU_UNUSED(op1))
6772 {
6773  int mod, rl, rh;
6774  u8 *destreg, *srcreg;
6775  uint destoffset;
6776 
6777  START_OF_INSTR();
6778  DECODE_PRINTF("MOV\t");
6779  FETCH_DECODE_MODRM(mod, rh, rl);
6780  switch (mod)
6781  {
6782  case 0:
6783  destoffset = decode_rm00_address(rl);
6784  DECODE_PRINTF(",");
6785  srcreg = DECODE_RM_BYTE_REGISTER(rh);
6786  DECODE_PRINTF("\n");
6787  TRACE_AND_STEP();
6788  store_data_byte(destoffset, *srcreg);
6789  break;
6790  case 1:
6791  destoffset = decode_rm01_address(rl);
6792  DECODE_PRINTF(",");
6793  srcreg = DECODE_RM_BYTE_REGISTER(rh);
6794  DECODE_PRINTF("\n");
6795  TRACE_AND_STEP();
6796  store_data_byte(destoffset, *srcreg);
6797  break;
6798  case 2:
6799  destoffset = decode_rm10_address(rl);
6800  DECODE_PRINTF(",");
6801  srcreg = DECODE_RM_BYTE_REGISTER(rh);
6802  DECODE_PRINTF("\n");
6803  TRACE_AND_STEP();
6804  store_data_byte(destoffset, *srcreg);
6805  break;
6806  case 3: /* register to register */
6807  destreg = DECODE_RM_BYTE_REGISTER(rl);
6808  DECODE_PRINTF(",");
6809  srcreg = DECODE_RM_BYTE_REGISTER(rh);
6810  DECODE_PRINTF("\n");
6811  TRACE_AND_STEP();
6812  *destreg = *srcreg;
6813  break;
6814  }
6815  DECODE_CLEAR_SEGOVR();
6816  END_OF_INSTR();
6817 }
6818 
6819 /****************************************************************************
6820 REMARKS:
6821 Handles opcode 0x89
6822 ****************************************************************************/
6823 static void x86emuOp_mov_word_RM_R(u8 X86EMU_UNUSED(op1))
6824 {
6825  int mod, rl, rh;
6826  u32 destoffset;
6827 
6828  START_OF_INSTR();
6829  DECODE_PRINTF("MOV\t");
6830  FETCH_DECODE_MODRM(mod, rh, rl);
6831  switch (mod)
6832  {
6833  case 0:
6834  if (M.x86.mode & SYSMODE_PREFIX_DATA)
6835  {
6836  u32 *srcreg;
6837 
6838  destoffset = decode_rm00_address(rl);
6839  DECODE_PRINTF(",");
6840  srcreg = DECODE_RM_LONG_REGISTER(rh);
6841  DECODE_PRINTF("\n");
6842  TRACE_AND_STEP();
6843  store_data_long(destoffset, *srcreg);
6844  }
6845  else
6846  {
6847  u16 *srcreg;
6848 
6849  destoffset = decode_rm00_address(rl);
6850  DECODE_PRINTF(",");
6851  srcreg = DECODE_RM_WORD_REGISTER(rh);
6852  DECODE_PRINTF("\n");
6853  TRACE_AND_STEP();
6854  store_data_word(destoffset, *srcreg);
6855  }
6856  break;
6857  case 1:
6858  if (M.x86.mode & SYSMODE_PREFIX_DATA)
6859  {
6860  u32 *srcreg;
6861 
6862  destoffset = decode_rm01_address(rl);
6863  DECODE_PRINTF(",");
6864  srcreg = DECODE_RM_LONG_REGISTER(rh);
6865  DECODE_PRINTF("\n");
6866  TRACE_AND_STEP();
6867  store_data_long(destoffset, *srcreg);
6868  }
6869  else
6870  {
6871  u16 *srcreg;
6872 
6873  destoffset = decode_rm01_address(rl);
6874  DECODE_PRINTF(",");
6875  srcreg = DECODE_RM_WORD_REGISTER(rh);
6876  DECODE_PRINTF("\n");
6877  TRACE_AND_STEP();
6878  store_data_word(destoffset, *srcreg);
6879  }
6880  break;
6881  case 2:
6882  if (M.x86.mode & SYSMODE_PREFIX_DATA)
6883  {
6884  u32 *srcreg;
6885 
6886  destoffset = decode_rm10_address(rl);
6887  DECODE_PRINTF(",");
6888  srcreg = DECODE_RM_LONG_REGISTER(rh);
6889  DECODE_PRINTF("\n");
6890  TRACE_AND_STEP();
6891  store_data_long(destoffset, *srcreg);
6892  }
6893  else
6894  {
6895  u16 *srcreg;
6896 
6897  destoffset = decode_rm10_address(rl);
6898  DECODE_PRINTF(",");
6899  srcreg = DECODE_RM_WORD_REGISTER(rh);
6900  DECODE_PRINTF("\n");
6901  TRACE_AND_STEP();
6902  store_data_word(destoffset, *srcreg);
6903  }
6904  break;
6905  case 3: /* register to register */
6906  if (M.x86.mode & SYSMODE_PREFIX_DATA)
6907  {
6908  u32 *destreg, *srcreg;
6909 
6910  destreg = DECODE_RM_LONG_REGISTER(rl);
6911  DECODE_PRINTF(",");
6912  srcreg = DECODE_RM_LONG_REGISTER(rh);
6913  DECODE_PRINTF("\n");
6914  TRACE_AND_STEP();
6915  *destreg = *srcreg;
6916  }
6917  else
6918  {
6919  u16 *destreg, *srcreg;
6920 
6921  destreg = DECODE_RM_WORD_REGISTER(rl);
6922  DECODE_PRINTF(",");
6923  srcreg = DECODE_RM_WORD_REGISTER(rh);
6924  DECODE_PRINTF("\n");
6925  TRACE_AND_STEP();
6926  *destreg = *srcreg;
6927  }
6928  break;
6929  }
6930  DECODE_CLEAR_SEGOVR();
6931  END_OF_INSTR();
6932 }
6933 
6934 /****************************************************************************
6935 REMARKS:
6936 Handles opcode 0x8a
6937 ****************************************************************************/
6938 static void x86emuOp_mov_byte_R_RM(u8 X86EMU_UNUSED(op1))
6939 {
6940  int mod, rl, rh;
6941  u8 *destreg, *srcreg;
6942  uint srcoffset;
6943  u8 srcval;
6944 
6945  START_OF_INSTR();
6946  DECODE_PRINTF("MOV\t");
6947  FETCH_DECODE_MODRM(mod, rh, rl);
6948  switch (mod)
6949  {
6950  case 0:
6951  destreg = DECODE_RM_BYTE_REGISTER(rh);
6952  DECODE_PRINTF(",");
6953  srcoffset = decode_rm00_address(rl);
6954  srcval = fetch_data_byte(srcoffset);
6955  DECODE_PRINTF("\n");
6956  TRACE_AND_STEP();
6957  *destreg = srcval;
6958  break;
6959  case 1:
6960  destreg = DECODE_RM_BYTE_REGISTER(rh);
6961  DECODE_PRINTF(",");
6962  srcoffset = decode_rm01_address(rl);
6963  srcval = fetch_data_byte(srcoffset);
6964  DECODE_PRINTF("\n");
6965  TRACE_AND_STEP();
6966  *destreg = srcval;
6967  break;
6968  case 2:
6969  destreg = DECODE_RM_BYTE_REGISTER(rh);
6970  DECODE_PRINTF(",");
6971  srcoffset = decode_rm10_address(rl);
6972  srcval = fetch_data_byte(srcoffset);
6973  DECODE_PRINTF("\n");
6974  TRACE_AND_STEP();
6975  *destreg = srcval;
6976  break;
6977  case 3: /* register to register */
6978  destreg = DECODE_RM_BYTE_REGISTER(rh);
6979  DECODE_PRINTF(",");
6980  srcreg = DECODE_RM_BYTE_REGISTER(rl);
6981  DECODE_PRINTF("\n");
6982  TRACE_AND_STEP();
6983  *destreg = *srcreg;
6984  break;
6985  }
6986  DECODE_CLEAR_SEGOVR();
6987  END_OF_INSTR();
6988 }
6989 
6990 /****************************************************************************
6991 REMARKS:
6992 Handles opcode 0x8b
6993 ****************************************************************************/
6994 static void x86emuOp_mov_word_R_RM(u8 X86EMU_UNUSED(op1))
6995 {
6996  int mod, rl, rh;
6997  uint srcoffset;
6998 
6999  START_OF_INSTR();
7000  DECODE_PRINTF("MOV\t");
7001  FETCH_DECODE_MODRM(mod, rh, rl);
7002  switch (mod)
7003  {
7004  case 0:
7005  if (M.x86.mode & SYSMODE_PREFIX_DATA)
7006  {
7007  u32 *destreg;
7008  u32 srcval;
7009 
7010  destreg = DECODE_RM_LONG_REGISTER(rh);
7011  DECODE_PRINTF(",");
7012  srcoffset = decode_rm00_address(rl);
7013  srcval = fetch_data_long(srcoffset);
7014  DECODE_PRINTF("\n");
7015  TRACE_AND_STEP();
7016  *destreg = srcval;
7017  }
7018  else
7019  {
7020  u16 *destreg;
7021  u16 srcval;
7022 
7023  destreg = DECODE_RM_WORD_REGISTER(rh);
7024  DECODE_PRINTF(",");
7025  srcoffset = decode_rm00_address(rl);
7026  srcval = fetch_data_word(srcoffset);
7027  DECODE_PRINTF("\n");
7028  TRACE_AND_STEP();
7029  *destreg = srcval;
7030  }
7031  break;
7032  case 1:
7033  if (M.x86.mode & SYSMODE_PREFIX_DATA)
7034  {
7035  u32 *destreg;
7036  u32 srcval;
7037 
7038  destreg = DECODE_RM_LONG_REGISTER(rh);
7039  DECODE_PRINTF(",");
7040  srcoffset = decode_rm01_address(rl);
7041  srcval = fetch_data_long(srcoffset);
7042  DECODE_PRINTF("\n");
7043  TRACE_AND_STEP();
7044  *destreg = srcval;
7045  }
7046  else
7047  {
7048  u16 *destreg;
7049  u16 srcval;
7050 
7051  destreg = DECODE_RM_WORD_REGISTER(rh);
7052  DECODE_PRINTF(",");
7053  srcoffset = decode_rm01_address(rl);
7054  srcval = fetch_data_word(srcoffset);
7055  DECODE_PRINTF("\n");
7056  TRACE_AND_STEP();
7057  *destreg = srcval;
7058  }
7059  break;
7060  case 2:
7061  if (M.x86.mode & SYSMODE_PREFIX_DATA)
7062  {
7063  u32 *destreg;
7064  u32 srcval;
7065 
7066  destreg = DECODE_RM_LONG_REGISTER(rh);
7067  DECODE_PRINTF(",");
7068  srcoffset = decode_rm10_address(rl);
7069  srcval = fetch_data_long(srcoffset);
7070  DECODE_PRINTF("\n");
7071  TRACE_AND_STEP();
7072  *destreg = srcval;
7073  }
7074  else
7075  {
7076  u16 *destreg;
7077  u16 srcval;
7078 
7079  destreg = DECODE_RM_WORD_REGISTER(rh);
7080  DECODE_PRINTF(",");
7081  srcoffset = decode_rm10_address(rl);
7082  srcval = fetch_data_word(srcoffset);
7083  DECODE_PRINTF("\n");
7084  TRACE_AND_STEP();
7085  *destreg = srcval;
7086  }
7087  break;
7088  case 3: /* register to register */
7089  if (M.x86.mode & SYSMODE_PREFIX_DATA)
7090  {
7091  u32 *destreg, *srcreg;
7092 
7093  destreg = DECODE_RM_LONG_REGISTER(rh);
7094  DECODE_PRINTF(",");
7095  srcreg = DECODE_RM_LONG_REGISTER(rl);
7096  DECODE_PRINTF("\n");
7097  TRACE_AND_STEP();
7098  *destreg = *srcreg;
7099  }
7100  else
7101  {
7102  u16 *destreg, *srcreg;
7103 
7104  destreg = DECODE_RM_WORD_REGISTER(rh);
7105  DECODE_PRINTF(",");
7106  srcreg = DECODE_RM_WORD_REGISTER(rl);
7107  DECODE_PRINTF("\n");
7108  TRACE_AND_STEP();
7109  *destreg = *srcreg;
7110  }
7111  break;
7112  }
7113  DECODE_CLEAR_SEGOVR();
7114  END_OF_INSTR();
7115 }
7116 
7117 /****************************************************************************
7118 REMARKS:
7119 Handles opcode 0x8c
7120 ****************************************************************************/
7121 static void x86emuOp_mov_word_RM_SR(u8 X86EMU_UNUSED(op1))
7122 {
7123  int mod, rl, rh;
7124  u16 *destreg, *srcreg;
7125  uint destoffset;
7126  u16 destval;
7127 
7128  START_OF_INSTR();
7129  DECODE_PRINTF("MOV\t");
7130  FETCH_DECODE_MODRM(mod, rh, rl);
7131  switch (mod)
7132  {
7133  case 0:
7134  destoffset = decode_rm00_address(rl);
7135  DECODE_PRINTF(",");
7136  srcreg = decode_rm_seg_register(rh);
7137  DECODE_PRINTF("\n");
7138  TRACE_AND_STEP();
7139  destval = *srcreg;
7140  store_data_word(destoffset, destval);
7141  break;
7142  case 1:
7143  destoffset = decode_rm01_address(rl);
7144  DECODE_PRINTF(",");
7145  srcreg = decode_rm_seg_register(rh);
7146  DECODE_PRINTF("\n");
7147  TRACE_AND_STEP();
7148  destval = *srcreg;
7149  store_data_word(destoffset, destval);
7150  break;
7151  case 2:
7152  destoffset = decode_rm10_address(rl);
7153  DECODE_PRINTF(",");
7154  srcreg = decode_rm_seg_register(rh);
7155  DECODE_PRINTF("\n");
7156  TRACE_AND_STEP();
7157  destval = *srcreg;
7158  store_data_word(destoffset, destval);
7159  break;
7160  case 3: /* register to register */
7161  destreg = DECODE_RM_WORD_REGISTER(rl);
7162  DECODE_PRINTF(",");
7163  srcreg = decode_rm_seg_register(rh);
7164  DECODE_PRINTF("\n");
7165  TRACE_AND_STEP();
7166  *destreg = *srcreg;
7167  break;
7168  }
7169  DECODE_CLEAR_SEGOVR();
7170  END_OF_INSTR();
7171 }
7172 
7173 /****************************************************************************
7174 REMARKS:
7175 Handles opcode 0x8d
7176 ****************************************************************************/
7177 static void x86emuOp_lea_word_R_M(u8 X86EMU_UNUSED(op1))
7178 {
7179  int mod, rl, rh;
7180  u16 *srcreg;
7181  uint destoffset;
7182 
7183  /*
7184  * TODO: Need to handle address size prefix!
7185  *
7186  * lea eax,[eax+ebx*2] ??
7187  */
7188 
7189  START_OF_INSTR();
7190  DECODE_PRINTF("LEA\t");
7191  FETCH_DECODE_MODRM(mod, rh, rl);
7192  switch (mod)
7193  {
7194  case 0:
7195  srcreg = DECODE_RM_WORD_REGISTER(rh);
7196  DECODE_PRINTF(",");
7197  destoffset = decode_rm00_address(rl);
7198  DECODE_PRINTF("\n");
7199  TRACE_AND_STEP();
7200  *srcreg = (u16) destoffset;
7201  break;
7202  case 1:
7203  srcreg = DECODE_RM_WORD_REGISTER(rh);
7204  DECODE_PRINTF(",");
7205  destoffset = decode_rm01_address(rl);
7206  DECODE_PRINTF("\n");
7207  TRACE_AND_STEP();
7208  *srcreg = (u16) destoffset;
7209  break;
7210  case 2:
7211  srcreg = DECODE_RM_WORD_REGISTER(rh);
7212  DECODE_PRINTF(",");
7213  destoffset = decode_rm10_address(rl);
7214  DECODE_PRINTF("\n");
7215  TRACE_AND_STEP();
7216  *srcreg = (u16) destoffset;
7217  break;
7218  case 3: /* register to register */
7219  /* undefined. Do nothing. */
7220  break;
7221  }
7222  DECODE_CLEAR_SEGOVR();
7223  END_OF_INSTR();
7224 }
7225 
7226 /****************************************************************************
7227 REMARKS:
7228 Handles opcode 0x8e
7229 ****************************************************************************/
7230 static void x86emuOp_mov_word_SR_RM(u8 X86EMU_UNUSED(op1))
7231 {
7232  int mod, rl, rh;
7233  u16 *destreg, *srcreg;
7234  uint srcoffset;
7235  u16 srcval;
7236 
7237  START_OF_INSTR();
7238  DECODE_PRINTF("MOV\t");
7239  FETCH_DECODE_MODRM(mod, rh, rl);
7240  switch (mod)
7241  {
7242  case 0:
7243  destreg = decode_rm_seg_register(rh);
7244  DECODE_PRINTF(",");
7245  srcoffset = decode_rm00_address(rl);
7246  srcval = fetch_data_word(srcoffset);
7247  DECODE_PRINTF("\n");
7248  TRACE_AND_STEP();
7249  *destreg = srcval;
7250  break;
7251  case 1:
7252  destreg = decode_rm_seg_register(rh);
7253  DECODE_PRINTF(",");
7254  srcoffset = decode_rm01_address(rl);
7255  srcval = fetch_data_word(srcoffset);
7256  DECODE_PRINTF("\n");
7257  TRACE_AND_STEP();
7258  *destreg = srcval;
7259  break;
7260  case 2:
7261  destreg = decode_rm_seg_register(rh);
7262  DECODE_PRINTF(",");
7263  srcoffset = decode_rm10_address(rl);
7264  srcval = fetch_data_word(srcoffset);
7265  DECODE_PRINTF("\n");
7266  TRACE_AND_STEP();
7267  *destreg = srcval;
7268  break;
7269  case 3: /* register to register */
7270  destreg = decode_rm_seg_register(rh);
7271  DECODE_PRINTF(",");
7272  srcreg = DECODE_RM_WORD_REGISTER(rl);
7273  DECODE_PRINTF("\n");
7274  TRACE_AND_STEP();
7275  *destreg = *srcreg;
7276  break;
7277  }
7278  /*
7279  * Clean up, and reset all the R_xSP pointers to the correct
7280  * locations. This is about 3x too much overhead (doing all the
7281  * segreg ptrs when only one is needed, but this instruction
7282  * *cannot* be that common, and this isn't too much work anyway.
7283  */
7284  DECODE_CLEAR_SEGOVR();
7285  END_OF_INSTR();
7286 }
7287 
7288 /****************************************************************************
7289 REMARKS:
7290 Handles opcode 0x8f
7291 ****************************************************************************/
7292 static void x86emuOp_pop_RM(u8 X86EMU_UNUSED(op1))
7293 {
7294  int mod, rl, rh;
7295  uint destoffset;
7296 
7297  START_OF_INSTR();
7298  DECODE_PRINTF("POP\t");
7299  FETCH_DECODE_MODRM(mod, rh, rl);
7300  if (rh != 0)
7301  {
7302  DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n");
7303  HALT_SYS();
7304  }
7305  switch (mod)
7306  {
7307  case 0:
7308  if (M.x86.mode & SYSMODE_PREFIX_DATA)
7309  {
7310  u32 destval;
7311 
7312  destoffset = decode_rm00_address(rl);
7313  DECODE_PRINTF("\n");
7314  TRACE_AND_STEP();
7315  destval = pop_long();
7316  store_data_long(destoffset, destval);
7317  }
7318  else
7319  {
7320  u16 destval;
7321 
7322  destoffset = decode_rm00_address(rl);
7323  DECODE_PRINTF("\n");
7324  TRACE_AND_STEP();
7325  destval = pop_word();
7326  store_data_word(destoffset, destval);
7327  }
7328  break;
7329  case 1:
7330  if (M.x86.mode & SYSMODE_PREFIX_DATA)
7331  {
7332  u32 destval;
7333 
7334  destoffset = decode_rm01_address(rl);
7335  DECODE_PRINTF("\n");
7336  TRACE_AND_STEP();
7337  destval = pop_long();
7338  store_data_long(destoffset, destval);
7339  }
7340  else
7341  {
7342  u16 destval;
7343 
7344  destoffset = decode_rm01_address(rl);
7345  DECODE_PRINTF("\n");
7346  TRACE_AND_STEP();
7347  destval = pop_word();
7348  store_data_word(destoffset, destval);
7349  }
7350  break;
7351  case 2:
7352  if (M.x86.mode & SYSMODE_PREFIX_DATA)
7353  {
7354  u32 destval;
7355 
7356  destoffset = decode_rm10_address(rl);
7357  DECODE_PRINTF("\n");
7358  TRACE_AND_STEP();
7359  destval = pop_long();
7360  store_data_long(destoffset, destval);
7361  }
7362  else
7363  {
7364  u16 destval;
7365 
7366  destoffset = decode_rm10_address(rl);
7367  DECODE_PRINTF("\n");
7368  TRACE_AND_STEP();
7369  destval = pop_word();
7370  store_data_word(destoffset, destval);
7371  }
7372  break;
7373  case 3: /* register to register */
7374  if (M.x86.mode & SYSMODE_PREFIX_DATA)
7375  {
7376  u32 *destreg;
7377 
7378  destreg = DECODE_RM_LONG_REGISTER(rl);
7379  DECODE_PRINTF("\n");
7380  TRACE_AND_STEP();
7381  *destreg = pop_long();
7382  }
7383  else
7384  {
7385  u16 *destreg;
7386 
7387  destreg = DECODE_RM_WORD_REGISTER(rl);
7388  DECODE_PRINTF("\n");
7389  TRACE_AND_STEP();
7390  *destreg = pop_word();
7391  }
7392  break;
7393  }
7394  DECODE_CLEAR_SEGOVR();
7395  END_OF_INSTR();
7396 }
7397 
7398 /****************************************************************************
7399 REMARKS:
7400 Handles opcode 0x90
7401 ****************************************************************************/
7402 static void x86emuOp_nop(u8 X86EMU_UNUSED(op1))
7403 {
7404  START_OF_INSTR();
7405  DECODE_PRINTF("NOP\n");
7406  TRACE_AND_STEP();
7407  DECODE_CLEAR_SEGOVR();
7408  END_OF_INSTR();
7409 }
7410 
7411 /****************************************************************************
7412 REMARKS:
7413 Handles opcode 0x91
7414 ****************************************************************************/
7415 static void x86emuOp_xchg_word_AX_CX(u8 X86EMU_UNUSED(op1))
7416 {
7417  u32 tmp;
7418 
7419  START_OF_INSTR();
7420  if (M.x86.mode & SYSMODE_PREFIX_DATA)
7421  {
7422  DECODE_PRINTF("XCHG\tEAX,ECX\n");
7423  }
7424  else
7425  {
7426  DECODE_PRINTF("XCHG\tAX,CX\n");
7427  }
7428  TRACE_AND_STEP();
7429  if (M.x86.mode & SYSMODE_PREFIX_DATA)
7430  {
7431  tmp = M.x86.R_EAX;
7432  M.x86.R_EAX = M.x86.R_ECX;
7433  M.x86.R_ECX = tmp;
7434  }
7435  else
7436  {
7437  tmp = M.x86.R_AX;
7438  M.x86.R_AX = M.x86.R_CX;
7439  M.x86.R_CX = (u16) tmp;
7440  }
7441  DECODE_CLEAR_SEGOVR();
7442  END_OF_INSTR();
7443 }
7444 
7445 /****************************************************************************
7446 REMARKS:
7447 Handles opcode 0x92
7448 ****************************************************************************/
7449 static void x86emuOp_xchg_word_AX_DX(u8 X86EMU_UNUSED(op1))
7450 {
7451  u32 tmp;
7452 
7453  START_OF_INSTR();
7454  if (M.x86.mode & SYSMODE_PREFIX_DATA)
7455  {
7456  DECODE_PRINTF("XCHG\tEAX,EDX\n");
7457  }
7458  else
7459  {
7460  DECODE_PRINTF("XCHG\tAX,DX\n");
7461  }
7462  TRACE_AND_STEP();
7463  if (M.x86.mode & SYSMODE_PREFIX_DATA)
7464  {
7465  tmp = M.x86.R_EAX;
7466  M.x86.R_EAX = M.x86.R_EDX;
7467  M.x86.R_EDX = tmp;
7468  }
7469  else
7470  {
7471  tmp = M.x86.R_AX;
7472  M.x86.R_AX = M.x86.R_DX;
7473  M.x86.R_DX = (u16) tmp;
7474  }
7475  DECODE_CLEAR_SEGOVR();
7476  END_OF_INSTR();
7477 }
7478 
7479 /****************************************************************************
7480 REMARKS:
7481 Handles opcode 0x93
7482 ****************************************************************************/
7483 static void x86emuOp_xchg_word_AX_BX(u8 X86EMU_UNUSED(op1))
7484 {
7485  u32 tmp;
7486 
7487  START_OF_INSTR();
7488  if (M.x86.mode & SYSMODE_PREFIX_DATA)
7489  {
7490  DECODE_PRINTF("XCHG\tEAX,EBX\n");
7491  }
7492  else
7493  {
7494  DECODE_PRINTF("XCHG\tAX,BX\n");
7495  }
7496  TRACE_AND_STEP();
7497  if (M.x86.mode & SYSMODE_PREFIX_DATA)
7498  {
7499  tmp = M.x86.R_EAX;
7500  M.x86.R_EAX = M.x86.R_EBX;
7501  M.x86.R_EBX = tmp;
7502  }
7503  else
7504  {
7505  tmp = M.x86.R_AX;
7506  M.x86.R_AX = M.x86.R_BX;
7507  M.x86.R_BX = (u16) tmp;
7508  }
7509  DECODE_CLEAR_SEGOVR();
7510  END_OF_INSTR();
7511 }
7512 
7513 /****************************************************************************
7514 REMARKS:
7515 Handles opcode 0x94
7516 ****************************************************************************/
7517 static void x86emuOp_xchg_word_AX_SP(u8 X86EMU_UNUSED(op1))
7518 {
7519  u32 tmp;
7520 
7521  START_OF_INSTR();
7522  if (M.x86.mode & SYSMODE_PREFIX_DATA)
7523  {
7524  DECODE_PRINTF("XCHG\tEAX,ESP\n");
7525  }
7526  else
7527  {
7528  DECODE_PRINTF("XCHG\tAX,SP\n");
7529  }
7530  TRACE_AND_STEP();
7531  if (M.x86.mode & SYSMODE_PREFIX_DATA)
7532  {
7533  tmp = M.x86.R_EAX;
7534  M.x86.R_EAX = M.x86.R_ESP;
7535  M.x86.R_ESP = tmp;
7536  }
7537  else
7538  {
7539  tmp = M.x86.R_AX;
7540  M.x86.R_AX = M.x86.R_SP;
7541  M.x86.R_SP = (u16) tmp;
7542  }
7543  DECODE_CLEAR_SEGOVR();
7544  END_OF_INSTR();
7545 }
7546 
7547 /****************************************************************************
7548 REMARKS:
7549 Handles opcode 0x95
7550 ****************************************************************************/
7551 static void x86emuOp_xchg_word_AX_BP(u8 X86EMU_UNUSED(op1))
7552 {
7553  u32 tmp;
7554 
7555  START_OF_INSTR();
7556  if (M.x86.mode & SYSMODE_PREFIX_DATA)
7557  {
7558  DECODE_PRINTF("XCHG\tEAX,EBP\n");
7559  }
7560  else
7561  {
7562  DECODE_PRINTF("XCHG\tAX,BP\n");
7563  }
7564  TRACE_AND_STEP();
7565  if (M.x86.mode & SYSMODE_PREFIX_DATA)
7566  {
7567  tmp = M.x86.R_EAX;
7568  M.x86.R_EAX = M.x86.R_EBP;
7569  M.x86.R_EBP = tmp;
7570  }
7571  else
7572  {
7573  tmp = M.x86.R_AX;
7574  M.x86.R_AX = M.x86.R_BP;
7575  M.x86.R_BP = (u16) tmp;
7576  }
7577  DECODE_CLEAR_SEGOVR();
7578  END_OF_INSTR();
7579 }
7580 
7581 /****************************************************************************
7582 REMARKS:
7583 Handles opcode 0x96
7584 ****************************************************************************/
7585 static void x86emuOp_xchg_word_AX_SI(u8 X86EMU_UNUSED(op1))
7586 {
7587  u32 tmp;
7588 
7589  START_OF_INSTR();
7590  if (M.x86.mode & SYSMODE_PREFIX_DATA)
7591  {
7592  DECODE_PRINTF("XCHG\tEAX,ESI\n");
7593  }
7594  else
7595  {
7596  DECODE_PRINTF("XCHG\tAX,SI\n");
7597  }
7598  TRACE_AND_STEP();
7599  if (M.x86.mode & SYSMODE_PREFIX_DATA)
7600  {
7601  tmp = M.x86.R_EAX;
7602  M.x86.R_EAX = M.x86.R_ESI;
7603  M.x86.R_ESI = tmp;
7604  }
7605  else
7606  {
7607  tmp = M.x86.R_AX;
7608  M.x86.R_AX = M.x86.R_SI;
7609  M.x86.R_SI = (u16) tmp;
7610  }
7611  DECODE_CLEAR_SEGOVR();
7612  END_OF_INSTR();
7613 }
7614 
7615 /****************************************************************************
7616 REMARKS:
7617 Handles opcode 0x97
7618 ****************************************************************************/
7619 static void x86emuOp_xchg_word_AX_DI(u8 X86EMU_UNUSED(op1))
7620 {
7621  u32 tmp;
7622 
7623  START_OF_INSTR();
7624  if (M.x86.mode & SYSMODE_PREFIX_DATA)
7625  {
7626  DECODE_PRINTF("XCHG\tEAX,EDI\n");
7627  }
7628  else
7629  {
7630  DECODE_PRINTF("XCHG\tAX,DI\n");
7631  }
7632  TRACE_AND_STEP();
7633  if (M.x86.mode & SYSMODE_PREFIX_DATA)
7634  {
7635  tmp = M.x86.R_EAX;
7636  M.x86.R_EAX = M.x86.R_EDI;
7637  M.x86.R_EDI = tmp;
7638  }
7639  else
7640  {
7641  tmp = M.x86.R_AX;
7642  M.x86.R_AX = M.x86.R_DI;
7643  M.x86.R_DI = (u16) tmp;
7644  }
7645  DECODE_CLEAR_SEGOVR();
7646  END_OF_INSTR();
7647 }
7648 
7649 /****************************************************************************
7650 REMARKS:
7651 Handles opcode 0x98
7652 ****************************************************************************/
7653 static void x86emuOp_cbw(u8 X86EMU_UNUSED(op1))
7654 {
7655  START_OF_INSTR();
7656  if (M.x86.mode & SYSMODE_PREFIX_DATA)
7657  {
7658  DECODE_PRINTF("CWDE\n");
7659  }
7660  else
7661  {
7662  DECODE_PRINTF("CBW\n");
7663  }
7664  TRACE_AND_STEP();
7665  if (M.x86.mode & SYSMODE_PREFIX_DATA)
7666  {
7667  if (M.x86.R_AX & 0x8000)
7668  {
7669  M.x86.R_EAX |= 0xffff0000;
7670  }
7671  else
7672  {
7673  M.x86.R_EAX &= 0x0000ffff;
7674  }
7675  }
7676  else
7677  {
7678  if (M.x86.R_AL & 0x80)
7679  {
7680  M.x86.R_AH = 0xff;
7681  }
7682  else
7683  {
7684  M.x86.R_AH = 0x0;
7685  }
7686  }
7687  DECODE_CLEAR_SEGOVR();
7688  END_OF_INSTR();
7689 }
7690 
7691 /****************************************************************************
7692 REMARKS:
7693 Handles opcode 0x99
7694 ****************************************************************************/
7695 static void x86emuOp_cwd(u8 X86EMU_UNUSED(op1))
7696 {
7697  START_OF_INSTR();
7698  if (M.x86.mode & SYSMODE_PREFIX_DATA)
7699  {
7700  DECODE_PRINTF("CDQ\n");
7701  }
7702  else
7703  {
7704  DECODE_PRINTF("CWD\n");
7705  }
7706  DECODE_PRINTF("CWD\n");
7707  TRACE_AND_STEP();
7708  if (M.x86.mode & SYSMODE_PREFIX_DATA)
7709  {
7710  if (M.x86.R_EAX & 0x80000000)
7711  {
7712  M.x86.R_EDX = 0xffffffff;
7713  }
7714  else
7715  {
7716  M.x86.R_EDX = 0x0;
7717  }
7718  }
7719  else
7720  {
7721  if (M.x86.R_AX & 0x8000)
7722  {
7723  M.x86.R_DX = 0xffff;
7724  }
7725  else
7726  {
7727  M.x86.R_DX = 0x0;
7728  }
7729  }
7730  DECODE_CLEAR_SEGOVR();
7731  END_OF_INSTR();
7732 }
7733 
7734 /****************************************************************************
7735 REMARKS:
7736 Handles opcode 0x9a
7737 ****************************************************************************/
7738 static void x86emuOp_call_far_IMM(u8 X86EMU_UNUSED(op1))
7739 {
7740  u16 farseg, faroff;
7741 
7742  START_OF_INSTR();
7743  DECODE_PRINTF("CALL\t");
7744  faroff = fetch_word_imm();
7745  farseg = fetch_word_imm();
7746  DECODE_PRINTF2("%04x:", farseg);
7747  DECODE_PRINTF2("%04x\n", faroff);
7748  CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, farseg, faroff, "FAR ");
7749 
7750  /* XXX
7751  *
7752  * Hooked interrupt vectors calling into our "BIOS" will cause
7753  * problems unless all intersegment stuff is checked for BIOS
7754  * access. Check needed here. For moment, let it alone.
7755  */
7756  TRACE_AND_STEP();
7757  push_word(M.x86.R_CS);
7758  M.x86.R_CS = farseg;
7759  push_word(M.x86.R_IP);
7760  M.x86.R_IP = faroff;
7761  DECODE_CLEAR_SEGOVR();
7762  END_OF_INSTR();
7763 }
7764 
7765 /****************************************************************************
7766 REMARKS:
7767 Handles opcode 0x9b
7768 ****************************************************************************/
7769 static void x86emuOp_wait(u8 X86EMU_UNUSED(op1))
7770 {
7771  START_OF_INSTR();
7772  DECODE_PRINTF("WAIT");
7773  TRACE_AND_STEP();
7774  /* NADA. */
7775  DECODE_CLEAR_SEGOVR();
7776  END_OF_INSTR();
7777 }
7778 
7779 /****************************************************************************
7780 REMARKS:
7781 Handles opcode 0x9c
7782 ****************************************************************************/
7783 static void x86emuOp_pushf_word(u8 X86EMU_UNUSED(op1))
7784 {
7785  u32 flags;
7786 
7787  START_OF_INSTR();
7788  if (M.x86.mode & SYSMODE_PREFIX_DATA)
7789  {
7790  DECODE_PRINTF("PUSHFD\n");
7791  }
7792  else
7793  {
7794  DECODE_PRINTF("PUSHF\n");
7795  }
7796  TRACE_AND_STEP();
7797 
7798  /* clear out *all* bits not representing flags, and turn on real bits */
7799  flags = (M.x86.R_EFLG & F_MSK) | F_ALWAYS_ON;
7800  if (M.x86.mode & SYSMODE_PREFIX_DATA)
7801  {
7802  push_long(flags);
7803  }
7804  else
7805  {
7806  push_word((u16) flags);
7807  }
7808  DECODE_CLEAR_SEGOVR();
7809  END_OF_INSTR();
7810 }
7811 
7812 /****************************************************************************
7813 REMARKS:
7814 Handles opcode 0x9d
7815 ****************************************************************************/
7816 static void x86emuOp_popf_word(u8 X86EMU_UNUSED(op1))
7817 {
7818  START_OF_INSTR();
7819  if (M.x86.mode & SYSMODE_PREFIX_DATA)
7820  {
7821  DECODE_PRINTF("POPFD\n");
7822  }
7823  else
7824  {
7825  DECODE_PRINTF("POPF\n");
7826  }
7827  TRACE_AND_STEP();
7828  if (M.x86.mode & SYSMODE_PREFIX_DATA)
7829  {
7830  M.x86.R_EFLG = pop_long();
7831  }
7832  else
7833  {
7834  M.x86.R_FLG = pop_word();
7835  }
7836  DECODE_CLEAR_SEGOVR();
7837  END_OF_INSTR();
7838 }
7839 
7840 /****************************************************************************
7841 REMARKS:
7842 Handles opcode 0x9e
7843 ****************************************************************************/
7844 static void x86emuOp_sahf(u8 X86EMU_UNUSED(op1))
7845 {
7846  START_OF_INSTR();
7847  DECODE_PRINTF("SAHF\n");
7848  TRACE_AND_STEP();
7849  /* clear the lower bits of the flag register */
7850  M.x86.R_FLG &= 0xffffff00;
7851  /* or in the AH register into the flags register */
7852  M.x86.R_FLG |= M.x86.R_AH;
7853  DECODE_CLEAR_SEGOVR();
7854  END_OF_INSTR();
7855 }
7856 
7857 /****************************************************************************
7858 REMARKS:
7859 Handles opcode 0x9f
7860 ****************************************************************************/
7861 static void x86emuOp_lahf(u8 X86EMU_UNUSED(op1))
7862 {
7863  START_OF_INSTR();
7864  DECODE_PRINTF("LAHF\n");
7865  TRACE_AND_STEP();
7866  M.x86.R_AH = (u8)(M.x86.R_FLG & 0xff);
7867  /*undocumented TC++ behavior??? Nope. It's documented, but
7868  you have too look real hard to notice it. */
7869  M.x86.R_AH |= 0x2;
7870  DECODE_CLEAR_SEGOVR();
7871  END_OF_INSTR();
7872 }
7873 
7874 /****************************************************************************
7875 REMARKS:
7876 Handles opcode 0xa0
7877 ****************************************************************************/
7878 static void x86emuOp_mov_AL_M_IMM(u8 X86EMU_UNUSED(op1))
7879 {
7880  u16 offset;
7881 
7882  START_OF_INSTR();
7883  DECODE_PRINTF("MOV\tAL,");
7884  offset = fetch_word_imm();
7885  DECODE_PRINTF2("[%04x]\n", offset);
7886  TRACE_AND_STEP();
7887  M.x86.R_AL = fetch_data_byte(offset);
7888  DECODE_CLEAR_SEGOVR();
7889  END_OF_INSTR();
7890 }
7891 
7892 /****************************************************************************
7893 REMARKS:
7894 Handles opcode 0xa1
7895 ****************************************************************************/
7896 static void x86emuOp_mov_AX_M_IMM(u8 X86EMU_UNUSED(op1))
7897 {
7898  u16 offset;
7899 
7900  START_OF_INSTR();
7901  offset = fetch_word_imm();
7902  if (M.x86.mode & SYSMODE_PREFIX_DATA)
7903  {
7904  DECODE_PRINTF2("MOV\tEAX,[%04x]\n", offset);
7905  }
7906  else
7907  {
7908  DECODE_PRINTF2("MOV\tAX,[%04x]\n", offset);
7909  }
7910  TRACE_AND_STEP();
7911  if (M.x86.mode & SYSMODE_PREFIX_DATA)
7912  {
7913  M.x86.R_EAX = fetch_data_long(offset);
7914  }
7915  else
7916  {
7917  M.x86.R_AX = fetch_data_word(offset);
7918  }
7919  DECODE_CLEAR_SEGOVR();
7920  END_OF_INSTR();
7921 }
7922 
7923 /****************************************************************************
7924 REMARKS:
7925 Handles opcode 0xa2
7926 ****************************************************************************/
7927 static void x86emuOp_mov_M_AL_IMM(u8 X86EMU_UNUSED(op1))
7928 {
7929  u16 offset;
7930 
7931  START_OF_INSTR();
7932  DECODE_PRINTF("MOV\t");
7933  offset = fetch_word_imm();
7934  DECODE_PRINTF2("[%04x],AL\n", offset);
7935  TRACE_AND_STEP();
7936  store_data_byte(offset, M.x86.R_AL);
7937  DECODE_CLEAR_SEGOVR();
7938  END_OF_INSTR();
7939 }
7940 
7941 /****************************************************************************
7942 REMARKS:
7943 Handles opcode 0xa3
7944 ****************************************************************************/
7945 static void x86emuOp_mov_M_AX_IMM(u8 X86EMU_UNUSED(op1))
7946 {
7947  u16 offset;
7948 
7949  START_OF_INSTR();
7950  offset = fetch_word_imm();
7951  if (M.x86.mode & SYSMODE_PREFIX_DATA)
7952  {
7953  DECODE_PRINTF2("MOV\t[%04x],EAX\n", offset);
7954  }
7955  else
7956  {
7957  DECODE_PRINTF2("MOV\t[%04x],AX\n", offset);
7958  }
7959  TRACE_AND_STEP();
7960  if (M.x86.mode & SYSMODE_PREFIX_DATA)
7961  {
7962  store_data_long(offset, M.x86.R_EAX);
7963  }
7964  else
7965  {
7966  store_data_word(offset, M.x86.R_AX);
7967  }
7968  DECODE_CLEAR_SEGOVR();
7969  END_OF_INSTR();
7970 }
7971 
7972 /****************************************************************************
7973 REMARKS:
7974 Handles opcode 0xa4
7975 ****************************************************************************/
7976 static void x86emuOp_movs_byte(u8 X86EMU_UNUSED(op1))
7977 {
7978  u8 val;
7979  u32 count;
7980  int inc;
7981 
7982  START_OF_INSTR();
7983  DECODE_PRINTF("MOVS\tBYTE\n");
7984  if (ACCESS_FLAG(F_DF)) /* down */
7985  inc = -1;
7986  else
7987  inc = 1;
7988  TRACE_AND_STEP();
7989  count = 1;
7990  if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE))
7991  {
7992  /* dont care whether REPE or REPNE */
7993  /* move them until CX is ZERO. */
7994  count = M.x86.R_CX;
7995  M.x86.R_CX = 0;
7996  M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7997  }
7998  while (count--)
7999  {
8000  val = fetch_data_byte(M.x86.R_SI);
8001  store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, val);
8002  M.x86.R_SI += inc;
8003  M.x86.R_DI += inc;
8004  }
8005  DECODE_CLEAR_SEGOVR();
8006  END_OF_INSTR();
8007 }
8008 
8009 /****************************************************************************
8010 REMARKS:
8011 Handles opcode 0xa5
8012 ****************************************************************************/
8013 static void x86emuOp_movs_word(u8 X86EMU_UNUSED(op1))
8014 {
8015  u32 val;
8016  int inc;
8017  u32 count;
8018 
8019  START_OF_INSTR();
8020  if (M.x86.mode & SYSMODE_PREFIX_DATA)
8021  {
8022  DECODE_PRINTF("MOVS\tDWORD\n");
8023  if (ACCESS_FLAG(F_DF)) /* down */
8024  inc = -4;
8025  else
8026  inc = 4;
8027  }
8028  else
8029  {
8030  DECODE_PRINTF("MOVS\tWORD\n");
8031  if (ACCESS_FLAG(F_DF)) /* down */
8032  inc = -2;
8033  else
8034  inc = 2;
8035  }
8036  TRACE_AND_STEP();
8037  count = 1;
8038  if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE))
8039  {
8040  /* dont care whether REPE or REPNE */
8041  /* move them until CX is ZERO. */
8042  count = M.x86.R_CX;
8043  M.x86.R_CX = 0;
8044  M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
8045  }
8046  while (count--)
8047  {
8048  if (M.x86.mode & SYSMODE_PREFIX_DATA)
8049  {
8050  val = fetch_data_long(M.x86.R_SI);
8051  store_data_long_abs(M.x86.R_ES, M.x86.R_DI, val);
8052  }
8053  else
8054  {
8055  val = fetch_data_word(M.x86.R_SI);
8056  store_data_word_abs(M.x86.R_ES, M.x86.R_DI, (u16) val);
8057  }
8058  M.x86.R_SI += inc;
8059  M.x86.R_DI += inc;
8060  }
8061  DECODE_CLEAR_SEGOVR();
8062  END_OF_INSTR();
8063 }
8064 
8065 /****************************************************************************
8066 REMARKS:
8067 Handles opcode 0xa6
8068 ****************************************************************************/
8069 static void x86emuOp_cmps_byte(u8 X86EMU_UNUSED(op1))
8070 {
8071  s8 val1, val2;
8072  int inc;
8073 
8074  START_OF_INSTR();
8075  DECODE_PRINTF("CMPS\tBYTE\n");
8076  TRACE_AND_STEP();
8077  if (ACCESS_FLAG(F_DF)) /* down */
8078  inc = -1;
8079  else
8080  inc = 1;
8081 
8082  if (M.x86.mode & SYSMODE_PREFIX_REPE)
8083  {
8084  /* REPE */
8085  /* move them until CX is ZERO. */
8086  while (M.x86.R_CX != 0)
8087  {
8088  val1 = fetch_data_byte(M.x86.R_SI);
8089  val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
8090  cmp_byte(val1, val2);
8091  M.x86.R_CX -= 1;
8092  M.x86.R_SI += inc;
8093  M.x86.R_DI += inc;
8094  if (ACCESS_FLAG(F_ZF) == 0)
8095  break;
8096  }
8097  M.x86.mode &= ~SYSMODE_PREFIX_REPE;
8098  }
8099  else if (M.x86.mode & SYSMODE_PREFIX_REPNE)
8100  {
8101  /* REPNE */
8102  /* move them until CX is ZERO. */
8103  while (M.x86.R_CX != 0)
8104  {
8105  val1 = fetch_data_byte(M.x86.R_SI);
8106  val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
8107  cmp_byte(val1, val2);
8108  M.x86.R_CX -= 1;
8109  M.x86.R_SI += inc;
8110  M.x86.R_DI += inc;
8111  if (ACCESS_FLAG(F_ZF))
8112  break; /* zero flag set means equal */
8113  }
8114  M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
8115  }
8116  else
8117  {
8118  val1 = fetch_data_byte(M.x86.R_SI);
8119  val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
8120  cmp_byte(val1, val2);
8121  M.x86.R_SI += inc;
8122  M.x86.R_DI += inc;
8123  }
8124  DECODE_CLEAR_SEGOVR();
8125  END_OF_INSTR();
8126 }
8127 
8128 /****************************************************************************
8129 REMARKS:
8130 Handles opcode 0xa7
8131 ****************************************************************************/
8132 static void x86emuOp_cmps_word(u8 X86EMU_UNUSED(op1))
8133 {
8134  u32 val1, val2;
8135  int inc;
8136 
8137  START_OF_INSTR();
8138  if (M.x86.mode & SYSMODE_PREFIX_DATA)
8139  {
8140  DECODE_PRINTF("CMPS\tDWORD\n");
8141  if (ACCESS_FLAG(F_DF)) /* down */
8142  inc = -4;
8143  else
8144  inc = 4;
8145  }
8146  else
8147  {
8148  DECODE_PRINTF("CMPS\tWORD\n");
8149  if (ACCESS_FLAG(F_DF)) /* down */
8150  inc = -2;
8151  else
8152  inc = 2;
8153  }
8154  TRACE_AND_STEP();
8155  if (M.x86.mode & SYSMODE_PREFIX_REPE)
8156  {
8157  /* REPE */
8158  /* move them until CX is ZERO. */
8159  while (M.x86.R_CX != 0)
8160  {
8161  if (M.x86.mode & SYSMODE_PREFIX_DATA)
8162  {
8163  val1 = fetch_data_long(M.x86.R_SI);
8164  val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
8165  cmp_long(val1, val2);
8166  }
8167  else
8168  {
8169  val1 = fetch_data_word(M.x86.R_SI);
8170  val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
8171  cmp_word((u16) val1, (u16) val2);
8172  }
8173  M.x86.R_CX -= 1;
8174  M.x86.R_SI += inc;
8175  M.x86.R_DI += inc;
8176  if (ACCESS_FLAG(F_ZF) == 0)
8177  break;
8178  }
8179  M.x86.mode &= ~SYSMODE_PREFIX_REPE;
8180  }
8181  else if (M.x86.mode & SYSMODE_PREFIX_REPNE)
8182  {
8183  /* REPNE */
8184  /* move them until CX is ZERO. */
8185  while (M.x86.R_CX != 0)
8186  {
8187  if (M.x86.mode & SYSMODE_PREFIX_DATA)
8188  {
8189  val1 = fetch_data_long(M.x86.R_SI);
8190  val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
8191  cmp_long(val1, val2);
8192  }
8193  else
8194  {
8195  val1 = fetch_data_word(M.x86.R_SI);
8196  val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
8197  cmp_word((u16) val1, (u16) val2);
8198  }
8199  M.x86.R_CX -= 1;
8200  M.x86.R_SI += inc;
8201  M.x86.R_DI += inc;
8202  if (ACCESS_FLAG(F_ZF))
8203  break; /* zero flag set means equal */
8204  }
8205  M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
8206  }
8207  else
8208  {
8209  if (M.x86.mode & SYSMODE_PREFIX_DATA)
8210  {
8211  val1 = fetch_data_long(M.x86.R_SI);
8212  val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
8213  cmp_long(val1, val2);
8214  }
8215  else
8216  {
8217  val1 = fetch_data_word(M.x86.R_SI);
8218  val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
8219  cmp_word((u16) val1, (u16) val2);
8220  }
8221  M.x86.R_SI += inc;
8222  M.x86.R_DI += inc;
8223  }
8224  DECODE_CLEAR_SEGOVR();
8225  END_OF_INSTR();
8226 }
8227 
8228 /****************************************************************************
8229 REMARKS:
8230 Handles opcode 0xa8
8231 ****************************************************************************/
8232 static void x86emuOp_test_AL_IMM(u8 X86EMU_UNUSED(op1))
8233 {
8234  int imm;
8235 
8236  START_OF_INSTR();
8237  DECODE_PRINTF("TEST\tAL,");
8238  imm = fetch_byte_imm();
8239  DECODE_PRINTF2("%04x\n", imm);
8240  TRACE_AND_STEP();
8241  test_byte(M.x86.R_AL, (u8) imm);
8242  DECODE_CLEAR_SEGOVR();
8243  END_OF_INSTR();
8244 }
8245 
8246 /****************************************************************************
8247 REMARKS:
8248 Handles opcode 0xa9
8249 ****************************************************************************/
8250 static void x86emuOp_test_AX_IMM(u8 X86EMU_UNUSED(op1))
8251 {
8252  u32 srcval;
8253 
8254  START_OF_INSTR();
8255  if (M.x86.mode & SYSMODE_PREFIX_DATA)
8256  {
8257  DECODE_PRINTF("TEST\tEAX,");
8258  srcval = fetch_long_imm();
8259  }
8260  else
8261  {
8262  DECODE_PRINTF("TEST\tAX,");
8263  srcval = fetch_word_imm();
8264  }
8265  DECODE_PRINTF2("%x\n", srcval);
8266  TRACE_AND_STEP();
8267  if (M.x86.mode & SYSMODE_PREFIX_DATA)
8268  {
8269  test_long(M.x86.R_EAX, srcval);
8270  }
8271  else
8272  {
8273  test_word(M.x86.R_AX, (u16) srcval);
8274  }
8275  DECODE_CLEAR_SEGOVR();
8276  END_OF_INSTR();
8277 }
8278 
8279 /****************************************************************************
8280 REMARKS:
8281 Handles opcode 0xaa
8282 ****************************************************************************/
8283 static void x86emuOp_stos_byte(u8 X86EMU_UNUSED(op1))
8284 {
8285  int inc;
8286 
8287  START_OF_INSTR();
8288  DECODE_PRINTF("STOS\tBYTE\n");
8289  if (ACCESS_FLAG(F_DF)) /* down */
8290  inc = -1;
8291  else
8292  inc = 1;
8293  TRACE_AND_STEP();
8294  if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE))
8295  {
8296  /* dont care whether REPE or REPNE */
8297  /* move them until CX is ZERO. */
8298  while (M.x86.R_CX != 0)
8299  {
8300  store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL);
8301  M.x86.R_CX -= 1;
8302  M.x86.R_DI += inc;
8303  }
8304  M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
8305  }
8306  else
8307  {
8308  store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL);
8309  M.x86.R_DI += inc;
8310  }
8311  DECODE_CLEAR_SEGOVR();
8312  END_OF_INSTR();
8313 }
8314 
8315 /****************************************************************************
8316 REMARKS:
8317 Handles opcode 0xab
8318 ****************************************************************************/
8319 static void x86emuOp_stos_word(u8 X86EMU_UNUSED(op1))
8320 {
8321  int inc;
8322  u32 count;
8323 
8324  START_OF_INSTR();
8325  if (M.x86.mode & SYSMODE_PREFIX_DATA)
8326  {
8327  DECODE_PRINTF("STOS\tDWORD\n");
8328  if (ACCESS_FLAG(F_DF)) /* down */
8329  inc = -4;
8330  else
8331  inc = 4;
8332  }
8333  else
8334  {
8335  DECODE_PRINTF("STOS\tWORD\n");
8336  if (ACCESS_FLAG(F_DF)) /* down */
8337  inc = -2;
8338  else
8339  inc = 2;
8340  }
8341  TRACE_AND_STEP();
8342  count = 1;
8343  if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE))
8344  {
8345  /* dont care whether REPE or REPNE */
8346  /* move them until CX is ZERO. */
8347  count = M.x86.R_CX;
8348  M.x86.R_CX = 0;
8349  M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
8350  }
8351  while (count--)
8352  {
8353  if (M.x86.mode & SYSMODE_PREFIX_DATA)
8354  {
8355  store_data_long_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_EAX);
8356  }
8357  else
8358  {
8359  store_data_word_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AX);
8360  }
8361  M.x86.R_DI += inc;
8362  }
8363  DECODE_CLEAR_SEGOVR();
8364  END_OF_INSTR();
8365 }
8366 
8367 /****************************************************************************
8368 REMARKS:
8369 Handles opcode 0xac
8370 ****************************************************************************/
8371 static void x86emuOp_lods_byte(u8 X86EMU_UNUSED(op1))
8372 {
8373  int inc;
8374 
8375  START_OF_INSTR();
8376  DECODE_PRINTF("LODS\tBYTE\n");
8377  TRACE_AND_STEP();
8378  if (ACCESS_FLAG(F_DF)) /* down */
8379  inc = -1;
8380  else
8381  inc = 1;
8382  if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE))
8383  {
8384  /* dont care whether REPE or REPNE */
8385  /* move them until CX is ZERO. */
8386  while (M.x86.R_CX != 0)
8387  {
8388  M.x86.R_AL = fetch_data_byte(M.x86.R_SI);
8389  M.x86.R_CX -= 1;
8390  M.x86.R_SI += inc;
8391  }
8392  M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
8393  }
8394  else
8395  {
8396  M.x86.R_AL = fetch_data_byte(M.x86.R_SI);
8397  M.x86.R_SI += inc;
8398  }
8399  DECODE_CLEAR_SEGOVR();
8400  END_OF_INSTR();
8401 }
8402 
8403 /****************************************************************************
8404 REMARKS:
8405 Handles opcode 0xad
8406 ****************************************************************************/
8407 static void x86emuOp_lods_word(u8 X86EMU_UNUSED(op1))
8408 {
8409  int inc;
8410  u32 count;
8411 
8412  START_OF_INSTR();
8413  if (M.x86.mode & SYSMODE_PREFIX_DATA)
8414  {
8415  DECODE_PRINTF("LODS\tDWORD\n");
8416  if (ACCESS_FLAG(F_DF)) /* down */
8417  inc = -4;
8418  else
8419  inc = 4;
8420  }
8421  else
8422  {
8423  DECODE_PRINTF("LODS\tWORD\n");
8424  if (ACCESS_FLAG(F_DF)) /* down */
8425  inc = -2;
8426  else
8427  inc = 2;
8428  }
8429  TRACE_AND_STEP();
8430  count = 1;
8431  if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE))
8432  {
8433  /* dont care whether REPE or REPNE */
8434  /* move them until CX is ZERO. */
8435  count = M.x86.R_CX;
8436  M.x86.R_CX = 0;
8437  M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
8438  }
8439  while (count--)
8440  {
8441  if (M.x86.mode & SYSMODE_PREFIX_DATA)
8442  {
8443  M.x86.R_EAX = fetch_data_long(M.x86.R_SI);
8444  }
8445  else
8446  {
8447  M.x86.R_AX = fetch_data_word(M.x86.R_SI);
8448  }
8449  M.x86.R_SI += inc;
8450  }
8451  DECODE_CLEAR_SEGOVR();
8452  END_OF_INSTR();
8453 }
8454 
8455 /****************************************************************************
8456 REMARKS:
8457 Handles opcode 0xae
8458 ****************************************************************************/
8459 static void x86emuOp_scas_byte(u8 X86EMU_UNUSED(op1))
8460 {
8461  s8 val2;
8462  int inc;
8463 
8464  START_OF_INSTR();
8465  DECODE_PRINTF("SCAS\tBYTE\n");
8466  TRACE_AND_STEP();
8467  if (ACCESS_FLAG(F_DF)) /* down */
8468  inc = -1;
8469  else
8470  inc = 1;
8471  if (M.x86.mode & SYSMODE_PREFIX_REPE)
8472  {
8473  /* REPE */
8474  /* move them until CX is ZERO. */
8475  while (M.x86.R_CX != 0)
8476  {
8477  val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
8478  cmp_byte(M.x86.R_AL, val2);
8479  M.x86.R_CX -= 1;
8480  M.x86.R_DI += inc;
8481  if (ACCESS_FLAG(F_ZF) == 0)
8482  break;
8483  }
8484  M.x86.mode &= ~SYSMODE_PREFIX_REPE;
8485  }
8486  else if (M.x86.mode & SYSMODE_PREFIX_REPNE)
8487  {
8488  /* REPNE */
8489  /* move them until CX is ZERO. */
8490  while (M.x86.R_CX != 0)
8491  {
8492  val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
8493  cmp_byte(M.x86.R_AL, val2);
8494  M.x86.R_CX -= 1;
8495  M.x86.R_DI += inc;
8496  if (ACCESS_FLAG(F_ZF))
8497  break; /* zero flag set means equal */
8498  }
8499  M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
8500  }
8501  else
8502  {
8503  val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
8504  cmp_byte(M.x86.R_AL, val2);
8505  M.x86.R_DI += inc;
8506  }
8507  DECODE_CLEAR_SEGOVR();
8508  END_OF_INSTR();
8509 }
8510 
8511 /****************************************************************************
8512 REMARKS:
8513 Handles opcode 0xaf
8514 ****************************************************************************/
8515 static void x86emuOp_scas_word(u8 X86EMU_UNUSED(op1))
8516 {
8517  int inc;
8518  u32 val;
8519 
8520  START_OF_INSTR();
8521  if (M.x86.mode & SYSMODE_PREFIX_DATA)
8522  {
8523  DECODE_PRINTF("SCAS\tDWORD\n");
8524  if (ACCESS_FLAG(F_DF)) /* down */
8525  inc = -4;
8526  else
8527  inc = 4;
8528  }
8529  else
8530  {
8531  DECODE_PRINTF("SCAS\tWORD\n");
8532  if (ACCESS_FLAG(F_DF)) /* down */
8533  inc = -2;
8534  else
8535  inc = 2;
8536  }
8537  TRACE_AND_STEP();
8538  if (M.x86.mode & SYSMODE_PREFIX_REPE)
8539  {
8540  /* REPE */
8541  /* move them until CX is ZERO. */
8542  while (M.x86.R_CX != 0)
8543  {
8544  if (M.x86.mode & SYSMODE_PREFIX_DATA)
8545  {
8546  val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
8547  cmp_long(M.x86.R_EAX, val);
8548  }
8549  else
8550  {
8551  val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
8552  cmp_word(M.x86.R_AX, (u16) val);
8553  }
8554  M.x86.R_CX -= 1;
8555  M.x86.R_DI += inc;
8556  if (ACCESS_FLAG(F_ZF) == 0)
8557  break;
8558  }
8559  M.x86.mode &= ~SYSMODE_PREFIX_REPE;
8560  }
8561  else if (M.x86.mode & SYSMODE_PREFIX_REPNE)
8562  {
8563  /* REPNE */
8564  /* move them until CX is ZERO. */
8565  while (M.x86.R_CX != 0)
8566  {
8567  if (M.x86.mode & SYSMODE_PREFIX_DATA)
8568  {
8569  val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
8570  cmp_long(M.x86.R_EAX, val);
8571  }
8572  else
8573  {
8574  val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
8575  cmp_word(M.x86.R_AX, (u16) val);
8576  }
8577  M.x86.R_CX -= 1;
8578  M.x86.R_DI += inc;
8579  if (ACCESS_FLAG(F_ZF))
8580  break; /* zero flag set means equal */
8581  }
8582  M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
8583  }
8584  else
8585  {
8586  if (M.x86.mode & SYSMODE_PREFIX_DATA)
8587  {
8588  val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
8589  cmp_long(M.x86.R_EAX, val);
8590  }
8591  else
8592  {
8593  val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
8594  cmp_word(M.x86.R_AX, (u16) val);
8595  }
8596  M.x86.R_DI += inc;
8597  }
8598  DECODE_CLEAR_SEGOVR();
8599  END_OF_INSTR();
8600 }
8601 
8602 /****************************************************************************
8603 REMARKS:
8604 Handles opcode 0xb0
8605 ****************************************************************************/
8606 static void x86emuOp_mov_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
8607 {
8608  u8 imm;
8609 
8610  START_OF_INSTR();
8611  DECODE_PRINTF("MOV\tAL,");
8612  imm = fetch_byte_imm();
8613  DECODE_PRINTF2("%x\n", imm);
8614  TRACE_AND_STEP();
8615  M.x86.R_AL = imm;
8616  DECODE_CLEAR_SEGOVR();
8617  END_OF_INSTR();
8618 }
8619 
8620 /****************************************************************************
8621 REMARKS:
8622 Handles opcode 0xb1
8623 ****************************************************************************/
8624 static void x86emuOp_mov_byte_CL_IMM(u8 X86EMU_UNUSED(op1))
8625 {
8626  u8 imm;
8627 
8628  START_OF_INSTR();
8629  DECODE_PRINTF("MOV\tCL,");
8630  imm = fetch_byte_imm();
8631  DECODE_PRINTF2("%x\n", imm);
8632  TRACE_AND_STEP();
8633  M.x86.R_CL = imm;
8634  DECODE_CLEAR_SEGOVR();
8635  END_OF_INSTR();
8636 }
8637 
8638 /****************************************************************************
8639 REMARKS:
8640 Handles opcode 0xb2
8641 ****************************************************************************/
8642 static void x86emuOp_mov_byte_DL_IMM(u8 X86EMU_UNUSED(op1))
8643 {
8644  u8 imm;
8645 
8646  START_OF_INSTR();
8647  DECODE_PRINTF("MOV\tDL,");
8648  imm = fetch_byte_imm();
8649  DECODE_PRINTF2("%x\n", imm);
8650  TRACE_AND_STEP();
8651  M.x86.R_DL = imm;
8652  DECODE_CLEAR_SEGOVR();
8653  END_OF_INSTR();
8654 }
8655 
8656 /****************************************************************************
8657 REMARKS:
8658 Handles opcode 0xb3
8659 ****************************************************************************/
8660 static void x86emuOp_mov_byte_BL_IMM(u8 X86EMU_UNUSED(op1))
8661 {
8662  u8 imm;
8663 
8664  START_OF_INSTR();
8665  DECODE_PRINTF("MOV\tBL,");
8666  imm = fetch_byte_imm();
8667  DECODE_PRINTF2("%x\n", imm);
8668  TRACE_AND_STEP();
8669  M.x86.R_BL = imm;
8670  DECODE_CLEAR_SEGOVR();
8671  END_OF_INSTR();
8672 }
8673 
8674 /****************************************************************************
8675 REMARKS:
8676 Handles opcode 0xb4
8677 ****************************************************************************/
8678 static void x86emuOp_mov_byte_AH_IMM(u8 X86EMU_UNUSED(op1))
8679 {
8680  u8 imm;
8681 
8682  START_OF_INSTR();
8683  DECODE_PRINTF("MOV\tAH,");
8684  imm = fetch_byte_imm();
8685  DECODE_PRINTF2("%x\n", imm);
8686  TRACE_AND_STEP();
8687  M.x86.R_AH = imm;
8688  DECODE_CLEAR_SEGOVR();
8689  END_OF_INSTR();
8690 }
8691 
8692 /****************************************************************************
8693 REMARKS:
8694 Handles opcode 0xb5
8695 ****************************************************************************/
8696 static void x86emuOp_mov_byte_CH_IMM(u8 X86EMU_UNUSED(op1))
8697 {
8698  u8 imm;
8699 
8700  START_OF_INSTR();
8701  DECODE_PRINTF("MOV\tCH,");
8702  imm = fetch_byte_imm();
8703  DECODE_PRINTF2("%x\n", imm);
8704  TRACE_AND_STEP();
8705  M.x86.R_CH = imm;
8706  DECODE_CLEAR_SEGOVR();
8707  END_OF_INSTR();
8708 }
8709 
8710 /****************************************************************************
8711 REMARKS:
8712 Handles opcode 0xb6
8713 ****************************************************************************/
8714 static void x86emuOp_mov_byte_DH_IMM(u8 X86EMU_UNUSED(op1))
8715 {
8716  u8 imm;
8717 
8718  START_OF_INSTR();
8719  DECODE_PRINTF("MOV\tDH,");
8720  imm = fetch_byte_imm();
8721  DECODE_PRINTF2("%x\n", imm);
8722  TRACE_AND_STEP();
8723  M.x86.R_DH = imm;
8724  DECODE_CLEAR_SEGOVR();
8725  END_OF_INSTR();
8726 }
8727 
8728 /****************************************************************************
8729 REMARKS:
8730 Handles opcode 0xb7
8731 ****************************************************************************/
8732 static void x86emuOp_mov_byte_BH_IMM(u8 X86EMU_UNUSED(op1))
8733 {
8734  u8 imm;
8735 
8736  START_OF_INSTR();
8737  DECODE_PRINTF("MOV\tBH,");
8738  imm = fetch_byte_imm();
8739  DECODE_PRINTF2("%x\n", imm);
8740  TRACE_AND_STEP();
8741  M.x86.R_BH = imm;
8742  DECODE_CLEAR_SEGOVR();
8743  END_OF_INSTR();
8744 }
8745 
8746 /****************************************************************************
8747 REMARKS:
8748 Handles opcode 0xb8
8749 ****************************************************************************/
8750 static void x86emuOp_mov_word_AX_IMM(u8 X86EMU_UNUSED(op1))
8751 {
8752  u32 srcval;
8753 
8754  START_OF_INSTR();
8755  if (M.x86.mode & SYSMODE_PREFIX_DATA)
8756  {
8757  DECODE_PRINTF("MOV\tEAX,");
8758  srcval = fetch_long_imm();
8759  }
8760  else
8761  {
8762  DECODE_PRINTF("MOV\tAX,");
8763  srcval = fetch_word_imm();
8764  }
8765  DECODE_PRINTF2("%x\n", srcval);
8766  TRACE_AND_STEP();
8767  if (M.x86.mode & SYSMODE_PREFIX_DATA)
8768  {
8769  M.x86.R_EAX = srcval;
8770  }
8771  else
8772  {
8773  M.x86.R_AX = (u16) srcval;
8774  }
8775  DECODE_CLEAR_SEGOVR();
8776  END_OF_INSTR();
8777 }
8778 
8779 /****************************************************************************
8780 REMARKS:
8781 Handles opcode 0xb9
8782 ****************************************************************************/
8783 static void x86emuOp_mov_word_CX_IMM(u8 X86EMU_UNUSED(op1))
8784 {
8785  u32 srcval;
8786 
8787  START_OF_INSTR();
8788  if (M.x86.mode & SYSMODE_PREFIX_DATA)
8789  {
8790  DECODE_PRINTF("MOV\tECX,");
8791  srcval = fetch_long_imm();
8792  }
8793  else
8794  {
8795  DECODE_PRINTF("MOV\tCX,");
8796  srcval = fetch_word_imm();
8797  }
8798  DECODE_PRINTF2("%x\n", srcval);
8799  TRACE_AND_STEP();
8800  if (M.x86.mode & SYSMODE_PREFIX_DATA)
8801  {
8802  M.x86.R_ECX = srcval;
8803  }
8804  else
8805  {
8806  M.x86.R_CX = (u16) srcval;
8807  }
8808  DECODE_CLEAR_SEGOVR();
8809  END_OF_INSTR();
8810 }
8811 
8812 /****************************************************************************
8813 REMARKS:
8814 Handles opcode 0xba
8815 ****************************************************************************/
8816 static void x86emuOp_mov_word_DX_IMM(u8 X86EMU_UNUSED(op1))
8817 {
8818  u32 srcval;
8819 
8820  START_OF_INSTR();
8821  if (M.x86.mode & SYSMODE_PREFIX_DATA)
8822  {
8823  DECODE_PRINTF("MOV\tEDX,");
8824  srcval = fetch_long_imm();
8825  }
8826  else
8827  {
8828  DECODE_PRINTF("MOV\tDX,");
8829  srcval = fetch_word_imm();
8830  }
8831  DECODE_PRINTF2("%x\n", srcval);
8832  TRACE_AND_STEP();
8833  if (M.x86.mode & SYSMODE_PREFIX_DATA)
8834  {
8835  M.x86.R_EDX = srcval;
8836  }
8837  else
8838  {
8839  M.x86.R_DX = (u16) srcval;
8840  }
8841  DECODE_CLEAR_SEGOVR();
8842  END_OF_INSTR();
8843 }
8844 
8845 /****************************************************************************
8846 REMARKS:
8847 Handles opcode 0xbb
8848 ****************************************************************************/
8849 static void x86emuOp_mov_word_BX_IMM(u8 X86EMU_UNUSED(op1))
8850 {
8851  u32 srcval;
8852 
8853  START_OF_INSTR();
8854  if (M.x86.mode & SYSMODE_PREFIX_DATA)
8855  {
8856  DECODE_PRINTF("MOV\tEBX,");
8857  srcval = fetch_long_imm();
8858  }
8859  else
8860  {
8861  DECODE_PRINTF("MOV\tBX,");
8862  srcval = fetch_word_imm();
8863  }
8864  DECODE_PRINTF2("%x\n", srcval);
8865  TRACE_AND_STEP();
8866  if (M.x86.mode & SYSMODE_PREFIX_DATA)
8867  {
8868  M.x86.R_EBX = srcval;
8869  }
8870  else
8871  {
8872  M.x86.R_BX = (u16) srcval;
8873  }
8874  DECODE_CLEAR_SEGOVR();
8875  END_OF_INSTR();
8876 }
8877 
8878 /****************************************************************************
8879 REMARKS:
8880 Handles opcode 0xbc
8881 ****************************************************************************/
8882 static void x86emuOp_mov_word_SP_IMM(u8 X86EMU_UNUSED(op1))
8883 {
8884  u32 srcval;
8885 
8886  START_OF_INSTR();
8887  if (M.x86.mode & SYSMODE_PREFIX_DATA)
8888  {
8889  DECODE_PRINTF("MOV\tESP,");
8890  srcval = fetch_long_imm();
8891  }
8892  else
8893  {
8894  DECODE_PRINTF("MOV\tSP,");
8895  srcval = fetch_word_imm();
8896  }
8897  DECODE_PRINTF2("%x\n", srcval);
8898  TRACE_AND_STEP();
8899  if (M.x86.mode & SYSMODE_PREFIX_DATA)
8900  {
8901  M.x86.R_ESP = srcval;
8902  }
8903  else
8904  {
8905  M.x86.R_SP = (u16) srcval;
8906  }
8907  DECODE_CLEAR_SEGOVR();
8908  END_OF_INSTR();
8909 }
8910 
8911 /****************************************************************************
8912 REMARKS:
8913 Handles opcode 0xbd
8914 ****************************************************************************/
8915 static void x86emuOp_mov_word_BP_IMM(u8 X86EMU_UNUSED(op1))
8916 {
8917  u32 srcval;
8918 
8919  START_OF_INSTR();
8920  if (M.x86.mode & SYSMODE_PREFIX_DATA)
8921  {
8922  DECODE_PRINTF("MOV\tEBP,");
8923  srcval = fetch_long_imm();
8924  }
8925  else
8926  {
8927  DECODE_PRINTF("MOV\tBP,");
8928  srcval = fetch_word_imm();
8929  }
8930  DECODE_PRINTF2("%x\n", srcval);
8931  TRACE_AND_STEP();
8932  if (M.x86.mode & SYSMODE_PREFIX_DATA)
8933  {
8934  M.x86.R_EBP = srcval;
8935  }
8936  else
8937  {
8938  M.x86.R_BP = (u16) srcval;
8939  }
8940  DECODE_CLEAR_SEGOVR();
8941  END_OF_INSTR();
8942 }
8943 
8944 /****************************************************************************
8945 REMARKS:
8946 Handles opcode 0xbe
8947 ****************************************************************************/
8948 static void x86emuOp_mov_word_SI_IMM(u8 X86EMU_UNUSED(op1))
8949 {
8950  u32 srcval;
8951 
8952  START_OF_INSTR();
8953  if (M.x86.mode & SYSMODE_PREFIX_DATA)
8954  {
8955  DECODE_PRINTF("MOV\tESI,");
8956  srcval = fetch_long_imm();
8957  }
8958  else
8959  {
8960  DECODE_PRINTF("MOV\tSI,");
8961  srcval = fetch_word_imm();
8962  }
8963  DECODE_PRINTF2("%x\n", srcval);
8964  TRACE_AND_STEP();
8965  if (M.x86.mode & SYSMODE_PREFIX_DATA)
8966  {
8967  M.x86.R_ESI = srcval;
8968  }
8969  else
8970  {
8971  M.x86.R_SI = (u16) srcval;
8972  }
8973  DECODE_CLEAR_SEGOVR();
8974  END_OF_INSTR();
8975 }
8976 
8977 /****************************************************************************
8978 REMARKS:
8979 Handles opcode 0xbf
8980 ****************************************************************************/
8981 static void x86emuOp_mov_word_DI_IMM(u8 X86EMU_UNUSED(op1))
8982 {
8983  u32 srcval;
8984 
8985  START_OF_INSTR();
8986  if (M.x86.mode & SYSMODE_PREFIX_DATA)
8987  {
8988  DECODE_PRINTF("MOV\tEDI,");
8989  srcval = fetch_long_imm();
8990  }
8991  else
8992  {
8993  DECODE_PRINTF("MOV\tDI,");
8994  srcval = fetch_word_imm();
8995  }
8996  DECODE_PRINTF2("%x\n", srcval);
8997  TRACE_AND_STEP();
8998  if (M.x86.mode & SYSMODE_PREFIX_DATA)
8999  {
9000  M.x86.R_EDI = srcval;
9001  }
9002  else
9003  {
9004  M.x86.R_DI = (u16) srcval;
9005  }
9006  DECODE_CLEAR_SEGOVR();
9007  END_OF_INSTR();
9008 }
9009 
9010 /* used by opcodes c0, d0, and d2. */
9011 static u8 (*opcD0_byte_operation[])(u8 d, u8 s) = {
9012  rol_byte, ror_byte, rcl_byte, rcr_byte,
9013  shl_byte, shr_byte, shl_byte, /* sal_byte === shl_byte by definition */
9014  sar_byte,
9015 };
9016 
9017 /****************************************************************************
9018 REMARKS:
9019 Handles opcode 0xc0
9020 ****************************************************************************/
9021 static void x86emuOp_opcC0_byte_RM_MEM(u8 X86EMU_UNUSED(op1))
9022 {
9023  int mod, rl, rh;
9024  u8 *destreg;
9025  uint destoffset;
9026  u8 destval;
9027  u8 amt;
9028 
9029  /*
9030  * Yet another weirdo special case instruction format. Part of
9031  * the opcode held below in "RH". Doubly nested case would
9032  * result, except that the decoded instruction
9033  */
9034  START_OF_INSTR();
9035  FETCH_DECODE_MODRM(mod, rh, rl);
9036 #ifdef DEBUG
9037  if (DEBUG_DECODE())
9038  {
9039  /* XXX DECODE_PRINTF may be changed to something more
9040  general, so that it is important to leave the strings
9041  in the same format, even though the result is that the
9042  above test is done twice. */
9043 
9044  switch (rh)
9045  {
9046  case 0:
9047  DECODE_PRINTF("ROL\t");
9048  break;
9049  case 1:
9050  DECODE_PRINTF("ROR\t");
9051  break;
9052  case 2:
9053  DECODE_PRINTF("RCL\t");
9054  break;
9055  case 3:
9056  DECODE_PRINTF("RCR\t");
9057  break;
9058  case 4:
9059  DECODE_PRINTF("SHL\t");
9060  break;
9061  case 5:
9062  DECODE_PRINTF("SHR\t");
9063  break;
9064  case 6:
9065  DECODE_PRINTF("SAL\t");
9066  break;
9067  case 7:
9068  DECODE_PRINTF("SAR\t");
9069  break;
9070  }
9071  }
9072 #endif
9073  /* know operation, decode the mod byte to find the addressing
9074  mode. */
9075  switch (mod)
9076  {
9077  case 0:
9078  DECODE_PRINTF("BYTE PTR ");
9079  destoffset = decode_rm00_address(rl);
9080  amt = fetch_byte_imm();
9081  DECODE_PRINTF2(",%x\n", amt);
9082  destval = fetch_data_byte(destoffset);
9083  TRACE_AND_STEP();
9084  destval = (*opcD0_byte_operation[rh])(destval, amt);
9085  store_data_byte(destoffset, destval);
9086  break;
9087  case 1:
9088  DECODE_PRINTF("BYTE PTR ");
9089  destoffset = decode_rm01_address(rl);
9090  amt = fetch_byte_imm();
9091  DECODE_PRINTF2(",%x\n", amt);
9092  destval = fetch_data_byte(destoffset);
9093  TRACE_AND_STEP();
9094  destval = (*opcD0_byte_operation[rh])(destval, amt);
9095  store_data_byte(destoffset, destval);
9096  break;
9097  case 2:
9098  DECODE_PRINTF("BYTE PTR ");
9099  destoffset = decode_rm10_address(rl);
9100  amt = fetch_byte_imm();
9101  DECODE_PRINTF2(",%x\n", amt);
9102  destval = fetch_data_byte(destoffset);
9103  TRACE_AND_STEP();
9104  destval = (*opcD0_byte_operation[rh])(destval, amt);
9105  store_data_byte(destoffset, destval);
9106  break;
9107  case 3: /* register to register */
9108  destreg = DECODE_RM_BYTE_REGISTER(rl);
9109  amt = fetch_byte_imm();
9110  DECODE_PRINTF2(",%x\n", amt);
9111  TRACE_AND_STEP();
9112  destval = (*opcD0_byte_operation[rh])(*destreg, amt);
9113  *destreg = destval;
9114  break;
9115  }
9116  DECODE_CLEAR_SEGOVR();
9117  END_OF_INSTR();
9118 }
9119 
9120 /* used by opcodes c1, d1, and d3. */
9121 static u16 (*opcD1_word_operation[])(u16 s, u8 d) = {
9122  rol_word, ror_word, rcl_word, rcr_word,
9123  shl_word, shr_word, shl_word, /* sal_byte === shl_byte by definition */
9124  sar_word,
9125 };
9126 
9127 /* used by opcodes c1, d1, and d3. */
9128 static u32 (*opcD1_long_operation[])(u32 s, u8 d) = {
9129  rol_long, ror_long, rcl_long, rcr_long,
9130  shl_long, shr_long, shl_long, /* sal_byte === shl_byte by definition */
9131  sar_long,
9132 };
9133 
9134 /****************************************************************************
9135 REMARKS:
9136 Handles opcode 0xc1
9137 ****************************************************************************/
9138 static void x86emuOp_opcC1_word_RM_MEM(u8 X86EMU_UNUSED(op1))
9139 {
9140  int mod, rl, rh;
9141  uint destoffset;
9142  u8 amt;
9143 
9144  /*
9145  * Yet another weirdo special case instruction format. Part of
9146  * the opcode held below in "RH". Doubly nested case would
9147  * result, except that the decoded instruction
9148  */
9149  START_OF_INSTR();
9150  FETCH_DECODE_MODRM(mod, rh, rl);
9151 #ifdef DEBUG
9152  if (DEBUG_DECODE())
9153  {
9154  /* XXX DECODE_PRINTF may be changed to something more
9155  general, so that it is important to leave the strings
9156  in the same format, even though the result is that the
9157  above test is done twice. */
9158 
9159  switch (rh)
9160  {
9161  case 0:
9162  DECODE_PRINTF("ROL\t");
9163  break;
9164  case 1:
9165  DECODE_PRINTF("ROR\t");
9166  break;
9167  case 2:
9168  DECODE_PRINTF("RCL\t");
9169  break;
9170  case 3:
9171  DECODE_PRINTF("RCR\t");
9172  break;
9173  case 4:
9174  DECODE_PRINTF("SHL\t");
9175  break;
9176  case 5:
9177  DECODE_PRINTF("SHR\t");
9178  break;
9179  case 6:
9180  DECODE_PRINTF("SAL\t");
9181  break;
9182  case 7:
9183  DECODE_PRINTF("SAR\t");
9184  break;
9185  }
9186  }
9187 #endif
9188  /* know operation, decode the mod byte to find the addressing
9189  mode. */
9190  switch (mod)
9191  {
9192  case 0:
9193  if (M.x86.mode & SYSMODE_PREFIX_DATA)
9194  {
9195  u32 destval;
9196 
9197  DECODE_PRINTF("DWORD PTR ");
9198  destoffset = decode_rm00_address(rl);
9199  amt = fetch_byte_imm();
9200  DECODE_PRINTF2(",%x\n", amt);
9201  destval = fetch_data_long(destoffset);
9202  TRACE_AND_STEP();
9203  destval = (*opcD1_long_operation[rh])(destval, amt);
9204  store_data_long(destoffset, destval);
9205  }
9206  else
9207  {
9208  u16 destval;
9209 
9210  DECODE_PRINTF("WORD PTR ");
9211  destoffset = decode_rm00_address(rl);
9212  amt = fetch_byte_imm();
9213  DECODE_PRINTF2(",%x\n", amt);
9214  destval = fetch_data_word(destoffset);
9215  TRACE_AND_STEP();
9216  destval = (*opcD1_word_operation[rh])(destval, amt);
9217  store_data_word(destoffset, destval);
9218  }
9219  break;
9220  case 1:
9221  if (M.x86.mode & SYSMODE_PREFIX_DATA)
9222  {
9223  u32 destval;
9224 
9225  DECODE_PRINTF("DWORD PTR ");
9226  destoffset = decode_rm01_address(rl);
9227  amt = fetch_byte_imm();
9228  DECODE_PRINTF2(",%x\n", amt);
9229  destval = fetch_data_long(destoffset);
9230  TRACE_AND_STEP();
9231  destval = (*opcD1_long_operation[rh])(destval, amt);
9232  store_data_long(destoffset, destval);
9233  }
9234  else
9235  {
9236  u16 destval;
9237 
9238  DECODE_PRINTF("WORD PTR ");
9239  destoffset = decode_rm01_address(rl);
9240  amt = fetch_byte_imm();
9241  DECODE_PRINTF2(",%x\n", amt);
9242  destval = fetch_data_word(destoffset);
9243  TRACE_AND_STEP();
9244  destval = (*opcD1_word_operation[rh])(destval, amt);
9245  store_data_word(destoffset, destval);
9246  }
9247  break;
9248  case 2:
9249  if (M.x86.mode & SYSMODE_PREFIX_DATA)
9250  {
9251  u32 destval;
9252 
9253  DECODE_PRINTF("DWORD PTR ");
9254  destoffset = decode_rm10_address(rl);
9255  amt = fetch_byte_imm();
9256  DECODE_PRINTF2(",%x\n", amt);
9257  destval = fetch_data_long(destoffset);
9258  TRACE_AND_STEP();
9259  destval = (*opcD1_long_operation[rh])(destval, amt);
9260  store_data_long(destoffset, destval);
9261  }
9262  else
9263  {
9264  u16 destval;
9265 
9266  DECODE_PRINTF("WORD PTR ");
9267  destoffset = decode_rm10_address(rl);
9268  amt = fetch_byte_imm();
9269  DECODE_PRINTF2(",%x\n", amt);
9270  destval = fetch_data_word(destoffset);
9271  TRACE_AND_STEP();
9272  destval = (*opcD1_word_operation[rh])(destval, amt);
9273  store_data_word(destoffset, destval);
9274  }
9275  break;
9276  case 3: /* register to register */
9277  if (M.x86.mode & SYSMODE_PREFIX_DATA)
9278  {
9279  u32 *destreg;
9280 
9281  destreg = DECODE_RM_LONG_REGISTER(rl);
9282  amt = fetch_byte_imm();
9283  DECODE_PRINTF2(",%x\n", amt);
9284  TRACE_AND_STEP();
9285  *destreg = (*opcD1_long_operation[rh])(*destreg, amt);
9286  }
9287  else
9288  {
9289  u16 *destreg;
9290 
9291  destreg = DECODE_RM_WORD_REGISTER(rl);
9292  amt = fetch_byte_imm();
9293  DECODE_PRINTF2(",%x\n", amt);
9294  TRACE_AND_STEP();
9295  *destreg = (*opcD1_word_operation[rh])(*destreg, amt);
9296  }
9297  break;
9298  }
9299  DECODE_CLEAR_SEGOVR();
9300  END_OF_INSTR();
9301 }
9302 
9303 /****************************************************************************
9304 REMARKS:
9305 Handles opcode 0xc2
9306 ****************************************************************************/
9307 static void x86emuOp_ret_near_IMM(u8 X86EMU_UNUSED(op1))
9308 {
9309  u16 imm;
9310 
9311  START_OF_INSTR();
9312  DECODE_PRINTF("RET\t");
9313  imm = fetch_word_imm();
9314  DECODE_PRINTF2("%x\n", imm);
9315  RETURN_TRACE("RET", M.x86.saved_cs, M.x86.saved_ip);
9316  TRACE_AND_STEP();
9317  M.x86.R_IP = pop_word();
9318  M.x86.R_SP += imm;
9319  DECODE_CLEAR_SEGOVR();
9320  END_OF_INSTR();
9321 }
9322 
9323 /****************************************************************************
9324 REMARKS:
9325 Handles opcode 0xc3
9326 ****************************************************************************/
9327 static void x86emuOp_ret_near(u8 X86EMU_UNUSED(op1))
9328 {
9329  START_OF_INSTR();
9330  DECODE_PRINTF("RET\n");
9331  RETURN_TRACE("RET", M.x86.saved_cs, M.x86.saved_ip);
9332  TRACE_AND_STEP();
9333  M.x86.R_IP = pop_word();
9334  DECODE_CLEAR_SEGOVR();
9335  END_OF_INSTR();
9336 }
9337 
9338 /****************************************************************************
9339 REMARKS:
9340 Handles opcode 0xc4
9341 ****************************************************************************/
9342 static void x86emuOp_les_R_IMM(u8 X86EMU_UNUSED(op1))
9343 {
9344  int mod, rh, rl;
9345  u16 *dstreg;
9346  uint srcoffset;
9347 
9348  START_OF_INSTR();
9349  DECODE_PRINTF("LES\t");
9350  FETCH_DECODE_MODRM(mod, rh, rl);
9351  switch (mod)
9352  {
9353  case 0:
9354  dstreg = DECODE_RM_WORD_REGISTER(rh);
9355  DECODE_PRINTF(",");
9356  srcoffset = decode_rm00_address(rl);
9357  DECODE_PRINTF("\n");
9358  TRACE_AND_STEP();
9359  *dstreg = fetch_data_word(srcoffset);
9360  M.x86.R_ES = fetch_data_word(srcoffset + 2);
9361  break;
9362  case 1:
9363  dstreg = DECODE_RM_WORD_REGISTER(rh);
9364  DECODE_PRINTF(",");
9365  srcoffset = decode_rm01_address(rl);
9366  DECODE_PRINTF("\n");
9367  TRACE_AND_STEP();
9368  *dstreg = fetch_data_word(srcoffset);
9369  M.x86.R_ES = fetch_data_word(srcoffset + 2);
9370  break;
9371  case 2:
9372  dstreg = DECODE_RM_WORD_REGISTER(rh);
9373  DECODE_PRINTF(",");
9374  srcoffset = decode_rm10_address(rl);
9375  DECODE_PRINTF("\n");
9376  TRACE_AND_STEP();
9377  *dstreg = fetch_data_word(srcoffset);
9378  M.x86.R_ES = fetch_data_word(srcoffset + 2);
9379  break;
9380  case 3: /* register to register */
9381  /* UNDEFINED! */
9382  TRACE_AND_STEP();
9383  }
9384  DECODE_CLEAR_SEGOVR();
9385  END_OF_INSTR();
9386 }
9387 
9388 /****************************************************************************
9389 REMARKS:
9390 Handles opcode 0xc5
9391 ****************************************************************************/
9392 static void x86emuOp_lds_R_IMM(u8 X86EMU_UNUSED(op1))
9393 {
9394  int mod, rh, rl;
9395  u16 *dstreg;
9396  uint srcoffset;
9397 
9398  START_OF_INSTR();
9399  DECODE_PRINTF("LDS\t");
9400  FETCH_DECODE_MODRM(mod, rh, rl);
9401  switch (mod)
9402  {
9403  case 0:
9404  dstreg = DECODE_RM_WORD_REGISTER(rh);
9405  DECODE_PRINTF(",");
9406  srcoffset = decode_rm00_address(rl);
9407  DECODE_PRINTF("\n");
9408  TRACE_AND_STEP();
9409  *dstreg = fetch_data_word(srcoffset);
9410  M.x86.R_DS = fetch_data_word(srcoffset + 2);
9411  break;
9412  case 1:
9413  dstreg = DECODE_RM_WORD_REGISTER(rh);
9414  DECODE_PRINTF(",");
9415  srcoffset = decode_rm01_address(rl);
9416  DECODE_PRINTF("\n");
9417  TRACE_AND_STEP();
9418  *dstreg = fetch_data_word(srcoffset);
9419  M.x86.R_DS = fetch_data_word(srcoffset + 2);
9420  break;
9421  case 2:
9422  dstreg = DECODE_RM_WORD_REGISTER(rh);
9423  DECODE_PRINTF(",");
9424  srcoffset = decode_rm10_address(rl);
9425  DECODE_PRINTF("\n");
9426  TRACE_AND_STEP();
9427  *dstreg = fetch_data_word(srcoffset);
9428  M.x86.R_DS = fetch_data_word(srcoffset + 2);
9429  break;
9430  case 3: /* register to register */
9431  /* UNDEFINED! */
9432  TRACE_AND_STEP();
9433  }
9434  DECODE_CLEAR_SEGOVR();
9435  END_OF_INSTR();
9436 }
9437 
9438 /****************************************************************************
9439 REMARKS:
9440 Handles opcode 0xc6
9441 ****************************************************************************/
9442 static void x86emuOp_mov_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
9443 {
9444  int mod, rl, rh;
9445  u8 *destreg;
9446  uint destoffset;
9447  u8 imm;
9448 
9449  START_OF_INSTR();
9450  DECODE_PRINTF("MOV\t");
9451  FETCH_DECODE_MODRM(mod, rh, rl);
9452  if (rh != 0)
9453  {
9454  DECODE_PRINTF("ILLEGAL DECODE OF OPCODE c6\n");
9455  HALT_SYS();
9456  }
9457  switch (mod)
9458  {
9459  case 0:
9460  DECODE_PRINTF("BYTE PTR ");
9461  destoffset = decode_rm00_address(rl);
9462  imm = fetch_byte_imm();
9463  DECODE_PRINTF2(",%2x\n", imm);
9464  TRACE_AND_STEP();
9465  store_data_byte(destoffset, imm);
9466  break;
9467  case 1:
9468  DECODE_PRINTF("BYTE PTR ");
9469  destoffset = decode_rm01_address(rl);
9470  imm = fetch_byte_imm();
9471  DECODE_PRINTF2(",%2x\n", imm);
9472  TRACE_AND_STEP();
9473  store_data_byte(destoffset, imm);
9474  break;
9475  case 2:
9476  DECODE_PRINTF("BYTE PTR ");
9477  destoffset = decode_rm10_address(rl);
9478  imm = fetch_byte_imm();
9479  DECODE_PRINTF2(",%2x\n", imm);
9480  TRACE_AND_STEP();
9481  store_data_byte(destoffset, imm);
9482  break;
9483  case 3: /* register to register */
9484  destreg = DECODE_RM_BYTE_REGISTER(rl);
9485  imm = fetch_byte_imm();
9486  DECODE_PRINTF2(",%2x\n", imm);
9487  TRACE_AND_STEP();
9488  *destreg = imm;
9489  break;
9490  }
9491  DECODE_CLEAR_SEGOVR();
9492  END_OF_INSTR();
9493 }
9494 
9495 /****************************************************************************
9496 REMARKS:
9497 Handles opcode 0xc7
9498 ****************************************************************************/
9499 static void x86emuOp_mov_word_RM_IMM(u8 X86EMU_UNUSED(op1))
9500 {
9501  int mod, rl, rh;
9502  uint destoffset;
9503 
9504  START_OF_INSTR();
9505  DECODE_PRINTF("MOV\t");
9506  FETCH_DECODE_MODRM(mod, rh, rl);
9507  if (rh != 0)
9508  {
9509  DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n");
9510  HALT_SYS();
9511  }
9512  switch (mod)
9513  {
9514  case 0:
9515  if (M.x86.mode & SYSMODE_PREFIX_DATA)
9516  {
9517  u32 imm;
9518 
9519  DECODE_PRINTF("DWORD PTR ");
9520  destoffset = decode_rm00_address(rl);
9521  imm = fetch_long_imm();
9522  DECODE_PRINTF2(",%x\n", imm);
9523  TRACE_AND_STEP();
9524  store_data_long(destoffset, imm);
9525  }
9526  else
9527  {
9528  u16 imm;
9529 
9530  DECODE_PRINTF("WORD PTR ");
9531  destoffset = decode_rm00_address(rl);
9532  imm = fetch_word_imm();
9533  DECODE_PRINTF2(",%x\n", imm);
9534  TRACE_AND_STEP();
9535  store_data_word(destoffset, imm);
9536  }
9537  break;
9538  case 1:
9539  if (M.x86.mode & SYSMODE_PREFIX_DATA)
9540  {
9541  u32 imm;
9542 
9543  DECODE_PRINTF("DWORD PTR ");
9544  destoffset = decode_rm01_address(rl);
9545  imm = fetch_long_imm();
9546  DECODE_PRINTF2(",%x\n", imm);
9547  TRACE_AND_STEP();
9548  store_data_long(destoffset, imm);
9549  }
9550  else
9551  {
9552  u16 imm;
9553 
9554  DECODE_PRINTF("WORD PTR ");
9555  destoffset = decode_rm01_address(rl);
9556  imm = fetch_word_imm();
9557  DECODE_PRINTF2(",%x\n", imm);
9558  TRACE_AND_STEP();
9559  store_data_word(destoffset, imm);
9560  }
9561  break;
9562  case 2:
9563  if (M.x86.mode & SYSMODE_PREFIX_DATA)
9564  {
9565  u32 imm;
9566 
9567  DECODE_PRINTF("DWORD PTR ");
9568  destoffset = decode_rm10_address(rl);
9569  imm = fetch_long_imm();
9570  DECODE_PRINTF2(",%x\n", imm);
9571  TRACE_AND_STEP();
9572  store_data_long(destoffset, imm);
9573  }
9574  else
9575  {
9576  u16 imm;
9577 
9578  DECODE_PRINTF("WORD PTR ");
9579  destoffset = decode_rm10_address(rl);
9580  imm = fetch_word_imm();
9581  DECODE_PRINTF2(",%x\n", imm);
9582  TRACE_AND_STEP();
9583  store_data_word(destoffset, imm);
9584  }
9585  break;
9586  case 3: /* register to register */
9587  if (M.x86.mode & SYSMODE_PREFIX_DATA)
9588  {
9589  u32 *destreg;
9590  u32 imm;
9591 
9592  destreg = DECODE_RM_LONG_REGISTER(rl);
9593  imm = fetch_long_imm();
9594  DECODE_PRINTF2(",%x\n", imm);
9595  TRACE_AND_STEP();
9596  *destreg = imm;
9597  }
9598  else
9599  {
9600  u16 *destreg;
9601  u16 imm;
9602 
9603  destreg = DECODE_RM_WORD_REGISTER(rl);
9604  imm = fetch_word_imm();
9605  DECODE_PRINTF2(",%x\n", imm);
9606  TRACE_AND_STEP();
9607  *destreg = imm;
9608  }
9609  break;
9610  }
9611  DECODE_CLEAR_SEGOVR();
9612  END_OF_INSTR();
9613 }
9614 
9615 /****************************************************************************
9616 REMARKS:
9617 Handles opcode 0xc8
9618 ****************************************************************************/
9619 static void x86emuOp_enter(u8 X86EMU_UNUSED(op1))
9620 {
9621  u16 local, frame_pointer;
9622  u8 nesting;
9623  int i;
9624 
9625  START_OF_INSTR();
9626  local = fetch_word_imm();
9627  nesting = fetch_byte_imm();
9628  DECODE_PRINTF2("ENTER %x\n", local);
9629  DECODE_PRINTF2(",%x\n", nesting);
9630  TRACE_AND_STEP();
9631  push_word(M.x86.R_BP);
9632  frame_pointer = M.x86.R_SP;
9633  if (nesting > 0)
9634  {
9635  for (i = 1; i < nesting; i++)
9636  {
9637  M.x86.R_BP -= 2;
9638  push_word(fetch_data_word_abs(M.x86.R_SS, M.x86.R_BP));
9639  }
9640  push_word(frame_pointer);
9641  }
9642  M.x86.R_BP = frame_pointer;
9643  M.x86.R_SP = (u16)(M.x86.R_SP - local);
9644  DECODE_CLEAR_SEGOVR();
9645  END_OF_INSTR();
9646 }
9647 
9648 /****************************************************************************
9649 REMARKS:
9650 Handles opcode 0xc9
9651 ****************************************************************************/
9652 static void x86emuOp_leave(u8 X86EMU_UNUSED(op1))
9653 {
9654  START_OF_INSTR();
9655  DECODE_PRINTF("LEAVE\n");
9656  TRACE_AND_STEP();
9657  M.x86.R_SP = M.x86.R_BP;
9658  M.x86.R_BP = pop_word();
9659  DECODE_CLEAR_SEGOVR();
9660  END_OF_INSTR();
9661 }
9662 
9663 /****************************************************************************
9664 REMARKS:
9665 Handles opcode 0xca
9666 ****************************************************************************/
9667 static void x86emuOp_ret_far_IMM(u8 X86EMU_UNUSED(op1))
9668 {
9669  u16 imm;
9670 
9671  START_OF_INSTR();
9672  DECODE_PRINTF("RETF\t");
9673  imm = fetch_word_imm();
9674  DECODE_PRINTF2("%x\n", imm);
9675  RETURN_TRACE("RETF", M.x86.saved_cs, M.x86.saved_ip);
9676  TRACE_AND_STEP();
9677  M.x86.R_IP = pop_word();
9678  M.x86.R_CS = pop_word();
9679  M.x86.R_SP += imm;
9680  DECODE_CLEAR_SEGOVR();
9681  END_OF_INSTR();
9682 }
9683 
9684 /****************************************************************************
9685 REMARKS:
9686 Handles opcode 0xcb
9687 ****************************************************************************/
9688 static void x86emuOp_ret_far(u8 X86EMU_UNUSED(op1))
9689 {
9690  START_OF_INSTR();
9691  DECODE_PRINTF("RETF\n");
9692  RETURN_TRACE("RETF", M.x86.saved_cs, M.x86.saved_ip);
9693  TRACE_AND_STEP();
9694  M.x86.R_IP = pop_word();
9695  M.x86.R_CS = pop_word();
9696  DECODE_CLEAR_SEGOVR();
9697  END_OF_INSTR();
9698 }
9699 
9700 /****************************************************************************
9701 REMARKS:
9702 Handles opcode 0xcc
9703 ****************************************************************************/
9704 static void x86emuOp_int3(u8 X86EMU_UNUSED(op1))
9705 {
9706  START_OF_INSTR();
9707  DECODE_PRINTF("INT 3\n");
9708  TRACE_AND_STEP();
9709  if (_X86EMU_intrTab[3])
9710  {
9711  (*_X86EMU_intrTab[3])(3);
9712  }
9713  else
9714  {
9715  push_word((u16) M.x86.R_FLG);
9716  CLEAR_FLAG(F_IF);
9717  CLEAR_FLAG(F_TF);
9718  push_word(M.x86.R_CS);
9719  M.x86.R_CS = mem_access_word(3 * 4 + 2);
9720  push_word(M.x86.R_IP);
9721  M.x86.R_IP = mem_access_word(3 * 4);
9722  }
9723  DECODE_CLEAR_SEGOVR();
9724  END_OF_INSTR();
9725 }
9726 
9727 /****************************************************************************
9728 REMARKS:
9729 Handles opcode 0xcd
9730 ****************************************************************************/
9731 static void x86emuOp_int_IMM(u8 X86EMU_UNUSED(op1))
9732 {
9733  u8 intnum;
9734 
9735  START_OF_INSTR();
9736  DECODE_PRINTF("INT\t");
9737  intnum = fetch_byte_imm();
9738  DECODE_PRINTF2("%x\n", intnum);
9739  TRACE_AND_STEP();
9740  if (_X86EMU_intrTab[intnum])
9741  {
9742  (*_X86EMU_intrTab[intnum])(intnum);
9743  }
9744  else
9745  {
9746  push_word((u16) M.x86.R_FLG);
9747  CLEAR_FLAG(F_IF);
9748  CLEAR_FLAG(F_TF);
9749  push_word(M.x86.R_CS);
9750  M.x86.R_CS = mem_access_word(intnum * 4 + 2);
9751  push_word(M.x86.R_IP);
9752  M.x86.R_IP = mem_access_word(intnum * 4);
9753  }
9754  DECODE_CLEAR_SEGOVR();
9755  END_OF_INSTR();
9756 }
9757 
9758 /****************************************************************************
9759 REMARKS:
9760 Handles opcode 0xce
9761 ****************************************************************************/
9762 static void x86emuOp_into(u8 X86EMU_UNUSED(op1))
9763 {
9764  START_OF_INSTR();
9765  DECODE_PRINTF("INTO\n");
9766  TRACE_AND_STEP();
9767  if (ACCESS_FLAG(F_OF))
9768  {
9769  if (_X86EMU_intrTab[4])
9770  {
9771  (*_X86EMU_intrTab[4])(4);
9772  }
9773  else
9774  {
9775  push_word((u16) M.x86.R_FLG);
9776  CLEAR_FLAG(F_IF);
9777  CLEAR_FLAG(F_TF);
9778  push_word(M.x86.R_CS);
9779  M.x86.R_CS = mem_access_word(4 * 4 + 2);
9780  push_word(M.x86.R_IP);
9781  M.x86.R_IP = mem_access_word(4 * 4);
9782  }
9783  }
9784  DECODE_CLEAR_SEGOVR();
9785  END_OF_INSTR();
9786 }
9787 
9788 /****************************************************************************
9789 REMARKS:
9790 Handles opcode 0xcf
9791 ****************************************************************************/
9792 static void x86emuOp_iret(u8 X86EMU_UNUSED(op1))
9793 {
9794  START_OF_INSTR();
9795  DECODE_PRINTF("IRET\n");
9796 
9797  TRACE_AND_STEP();
9798 
9799  M.x86.R_IP = pop_word();
9800  M.x86.R_CS = pop_word();
9801  M.x86.R_FLG = pop_word();
9802  DECODE_CLEAR_SEGOVR();
9803  END_OF_INSTR();
9804 }
9805 
9806 /****************************************************************************
9807 REMARKS:
9808 Handles opcode 0xd0
9809 ****************************************************************************/
9810 static void x86emuOp_opcD0_byte_RM_1(u8 X86EMU_UNUSED(op1))
9811 {
9812  int mod, rl, rh;
9813  u8 *destreg;
9814  uint destoffset;
9815  u8 destval;
9816 
9817  /*
9818  * Yet another weirdo special case instruction format. Part of
9819  * the opcode held below in "RH". Doubly nested case would
9820  * result, except that the decoded instruction
9821  */
9822  START_OF_INSTR();
9823  FETCH_DECODE_MODRM(mod, rh, rl);
9824 #ifdef DEBUG
9825  if (DEBUG_DECODE())
9826  {
9827  /* XXX DECODE_PRINTF may be changed to something more
9828  general, so that it is important to leave the strings
9829  in the same format, even though the result is that the
9830  above test is done twice. */
9831  switch (rh)
9832  {
9833  case 0:
9834  DECODE_PRINTF("ROL\t");
9835  break;
9836  case 1:
9837  DECODE_PRINTF("ROR\t");
9838  break;
9839  case 2:
9840  DECODE_PRINTF("RCL\t");
9841  break;
9842  case 3:
9843  DECODE_PRINTF("RCR\t");
9844  break;
9845  case 4:
9846  DECODE_PRINTF("SHL\t");
9847  break;
9848  case 5:
9849  DECODE_PRINTF("SHR\t");
9850  break;
9851  case 6:
9852  DECODE_PRINTF("SAL\t");
9853  break;
9854  case 7:
9855  DECODE_PRINTF("SAR\t");
9856  break;
9857  }
9858  }
9859 #endif
9860  /* know operation, decode the mod byte to find the addressing
9861  mode. */
9862  switch (mod)
9863  {
9864  case 0:
9865  DECODE_PRINTF("BYTE PTR ");
9866  destoffset = decode_rm00_address(rl);
9867  DECODE_PRINTF(",1\n");
9868  destval = fetch_data_byte(destoffset);
9869  TRACE_AND_STEP();
9870  destval = (*opcD0_byte_operation[rh])(destval, 1);
9871  store_data_byte(destoffset, destval);
9872  break;
9873  case 1:
9874  DECODE_PRINTF("BYTE PTR ");
9875  destoffset = decode_rm01_address(rl);
9876  DECODE_PRINTF(",1\n");
9877  destval = fetch_data_byte(destoffset);
9878  TRACE_AND_STEP();
9879  destval = (*opcD0_byte_operation[rh])(destval, 1);
9880  store_data_byte(destoffset, destval);
9881  break;
9882  case 2:
9883  DECODE_PRINTF("BYTE PTR ");
9884  destoffset = decode_rm10_address(rl);
9885  DECODE_PRINTF(",1\n");
9886  destval = fetch_data_byte(destoffset);
9887  TRACE_AND_STEP();
9888  destval = (*opcD0_byte_operation[rh])(destval, 1);
9889  store_data_byte(destoffset, destval);
9890  break;
9891  case 3: /* register to register */
9892  destreg = DECODE_RM_BYTE_REGISTER(rl);
9893  DECODE_PRINTF(",1\n");
9894  TRACE_AND_STEP();
9895  destval = (*opcD0_byte_operation[rh])(*destreg, 1);
9896  *destreg = destval;
9897  break;
9898  }
9899  DECODE_CLEAR_SEGOVR();
9900  END_OF_INSTR();
9901 }
9902 
9903 /****************************************************************************
9904 REMARKS:
9905 Handles opcode 0xd1
9906 ****************************************************************************/
9907 static void x86emuOp_opcD1_word_RM_1(u8 X86EMU_UNUSED(op1))
9908 {
9909  int mod, rl, rh;
9910  uint destoffset;
9911 
9912  /*
9913  * Yet another weirdo special case instruction format. Part of
9914  * the opcode held below in "RH". Doubly nested case would
9915  * result, except that the decoded instruction
9916  */
9917  START_OF_INSTR();
9918  FETCH_DECODE_MODRM(mod, rh, rl);
9919 #ifdef DEBUG
9920  if (DEBUG_DECODE())
9921  {
9922  /* XXX DECODE_PRINTF may be changed to something more
9923  general, so that it is important to leave the strings
9924  in the same format, even though the result is that the
9925  above test is done twice. */
9926  switch (rh)
9927  {
9928  case 0:
9929  DECODE_PRINTF("ROL\t");
9930  break;
9931  case 1:
9932  DECODE_PRINTF("ROR\t");
9933  break;
9934  case 2:
9935  DECODE_PRINTF("RCL\t");
9936  break;
9937  case 3:
9938  DECODE_PRINTF("RCR\t");
9939  break;
9940  case 4:
9941  DECODE_PRINTF("SHL\t");
9942  break;
9943  case 5:
9944  DECODE_PRINTF("SHR\t");
9945  break;
9946  case 6:
9947  DECODE_PRINTF("SAL\t");
9948  break;
9949  case 7:
9950  DECODE_PRINTF("SAR\t");
9951  break;
9952  }
9953  }
9954 #endif
9955  /* know operation, decode the mod byte to find the addressing
9956  mode. */
9957  switch (mod)
9958  {
9959  case 0:
9960  if (M.x86.mode & SYSMODE_PREFIX_DATA)
9961  {
9962  u32 destval;
9963 
9964  DECODE_PRINTF("DWORD PTR ");
9965  destoffset = decode_rm00_address(rl);
9966  DECODE_PRINTF(",1\n");
9967  destval = fetch_data_long(destoffset);
9968  TRACE_AND_STEP();
9969  destval = (*opcD1_long_operation[rh])(destval, 1);
9970  store_data_long(destoffset, destval);
9971  }
9972  else
9973  {
9974  u16 destval;
9975 
9976  DECODE_PRINTF("WORD PTR ");
9977  destoffset = decode_rm00_address(rl);
9978  DECODE_PRINTF(",1\n");
9979  destval = fetch_data_word(destoffset);
9980  TRACE_AND_STEP();
9981  destval = (*opcD1_word_operation[rh])(destval, 1);
9982  store_data_word(destoffset, destval);
9983  }
9984  break;
9985  case 1:
9986  if (M.x86.mode & SYSMODE_PREFIX_DATA)
9987  {
9988  u32 destval;
9989 
9990  DECODE_PRINTF("DWORD PTR ");
9991  destoffset = decode_rm01_address(rl);
9992  DECODE_PRINTF(",1\n");
9993  destval = fetch_data_long(destoffset);
9994  TRACE_AND_STEP();
9995  destval = (*opcD1_long_operation[rh])(destval, 1);
9996  store_data_long(destoffset, destval);
9997  }
9998  else
9999  {
10000  u16 destval;
10001 
10002  DECODE_PRINTF("WORD PTR ");
10003  destoffset = decode_rm01_address(rl);
10004  DECODE_PRINTF(",1\n");
10005  destval = fetch_data_word(destoffset);
10006  TRACE_AND_STEP();
10007  destval = (*opcD1_word_operation[rh])(destval, 1);
10008  store_data_word(destoffset, destval);
10009  }
10010  break;
10011  case 2:
10012  if (M.x86.mode & SYSMODE_PREFIX_DATA)
10013  {
10014  u32 destval;
10015 
10016  DECODE_PRINTF("DWORD PTR ");
10017  destoffset = decode_rm10_address(rl);
10018  DECODE_PRINTF(",1\n");
10019  destval = fetch_data_long(destoffset);
10020  TRACE_AND_STEP();
10021  destval = (*opcD1_long_operation[rh])(destval, 1);
10022  store_data_long(destoffset, destval);
10023  }
10024  else
10025  {
10026  u16 destval;
10027 
10028  DECODE_PRINTF("BYTE PTR ");
10029  destoffset = decode_rm10_address(rl);
10030  DECODE_PRINTF(",1\n");
10031  destval = fetch_data_word(destoffset);
10032  TRACE_AND_STEP();
10033  destval = (*opcD1_word_operation[rh])(destval, 1);
10034  store_data_word(destoffset, destval);
10035  }
10036  break;
10037  case 3: /* register to register */
10038  if (M.x86.mode & SYSMODE_PREFIX_DATA)
10039  {
10040  u32 destval;
10041  u32 *destreg;
10042 
10043  destreg = DECODE_RM_LONG_REGISTER(rl);
10044  DECODE_PRINTF(",1\n");
10045  TRACE_AND_STEP();
10046  destval = (*opcD1_long_operation[rh])(*destreg, 1);
10047  *destreg = destval;
10048  }
10049  else
10050  {
10051  u16 destval;
10052  u16 *destreg;
10053 
10054  destreg = DECODE_RM_WORD_REGISTER(rl);
10055  DECODE_PRINTF(",1\n");
10056  TRACE_AND_STEP();
10057  destval = (*opcD1_word_operation[rh])(*destreg, 1);
10058  *destreg = destval;
10059  }
10060  break;
10061  }
10062  DECODE_CLEAR_SEGOVR();
10063  END_OF_INSTR();
10064 }
10065 
10066 /****************************************************************************
10067 REMARKS:
10068 Handles opcode 0xd2
10069 ****************************************************************************/
10070 static void x86emuOp_opcD2_byte_RM_CL(u8 X86EMU_UNUSED(op1))
10071 {
10072  int mod, rl, rh;
10073  u8 *destreg;
10074  uint destoffset;
10075  u8 destval;
10076  u8 amt;
10077 
10078  /*
10079  * Yet another weirdo special case instruction format. Part of
10080  * the opcode held below in "RH". Doubly nested case would
10081  * result, except that the decoded instruction
10082  */
10083  START_OF_INSTR();
10084  FETCH_DECODE_MODRM(mod, rh, rl);
10085 #ifdef DEBUG
10086  if (DEBUG_DECODE())
10087  {
10088  /* XXX DECODE_PRINTF may be changed to something more
10089  general, so that it is important to leave the strings
10090  in the same format, even though the result is that the
10091  above test is done twice. */
10092  switch (rh)
10093  {
10094  case 0:
10095  DECODE_PRINTF("ROL\t");
10096  break;
10097  case 1:
10098  DECODE_PRINTF("ROR\t");
10099  break;
10100  case 2:
10101  DECODE_PRINTF("RCL\t");
10102  break;
10103  case 3:
10104  DECODE_PRINTF("RCR\t");
10105  break;
10106  case 4:
10107  DECODE_PRINTF("SHL\t");
10108  break;
10109  case 5:
10110  DECODE_PRINTF("SHR\t");
10111  break;
10112  case 6:
10113  DECODE_PRINTF("SAL\t");
10114  break;
10115  case 7:
10116  DECODE_PRINTF("SAR\t");
10117  break;
10118  }
10119  }
10120 #endif
10121  /* know operation, decode the mod byte to find the addressing
10122  mode. */
10123  amt = M.x86.R_CL;
10124  switch (mod)
10125  {
10126  case 0:
10127  DECODE_PRINTF("BYTE PTR ");
10128  destoffset = decode_rm00_address(rl);
10129  DECODE_PRINTF(",CL\n");
10130  destval = fetch_data_byte(destoffset);
10131  TRACE_AND_STEP();
10132  destval = (*opcD0_byte_operation[rh])(destval, amt);
10133  store_data_byte(destoffset, destval);
10134  break;
10135  case 1:
10136  DECODE_PRINTF("BYTE PTR ");
10137  destoffset = decode_rm01_address(rl);
10138  DECODE_PRINTF(",CL\n");
10139  destval = fetch_data_byte(destoffset);
10140  TRACE_AND_STEP();
10141  destval = (*opcD0_byte_operation[rh])(destval, amt);
10142  store_data_byte(destoffset, destval);
10143  break;
10144  case 2:
10145  DECODE_PRINTF("BYTE PTR ");
10146  destoffset = decode_rm10_address(rl);
10147  DECODE_PRINTF(",CL\n");
10148  destval = fetch_data_byte(destoffset);
10149  TRACE_AND_STEP();
10150  destval = (*opcD0_byte_operation[rh])(destval, amt);
10151  store_data_byte(destoffset, destval);
10152  break;
10153  case 3: /* register to register */
10154  destreg = DECODE_RM_BYTE_REGISTER(rl);
10155  DECODE_PRINTF(",CL\n");
10156  TRACE_AND_STEP();
10157  destval = (*opcD0_byte_operation[rh])(*destreg, amt);
10158  *destreg = destval;
10159  break;
10160  }
10161  DECODE_CLEAR_SEGOVR();
10162  END_OF_INSTR();
10163 }
10164 
10165 /****************************************************************************
10166 REMARKS:
10167 Handles opcode 0xd3
10168 ****************************************************************************/
10169 static void x86emuOp_opcD3_word_RM_CL(u8 X86EMU_UNUSED(op1))
10170 {
10171  int mod, rl, rh;
10172  uint destoffset;
10173  u8 amt;
10174 
10175  /*
10176  * Yet another weirdo special case instruction format. Part of
10177  * the opcode held below in "RH". Doubly nested case would
10178  * result, except that the decoded instruction
10179  */
10180  START_OF_INSTR();
10181  FETCH_DECODE_MODRM(mod, rh, rl);
10182 #ifdef DEBUG
10183  if (DEBUG_DECODE())
10184  {
10185  /* XXX DECODE_PRINTF may be changed to something more
10186  general, so that it is important to leave the strings
10187  in the same format, even though the result is that the
10188  above test is done twice. */
10189  switch (rh)
10190  {
10191  case 0:
10192  DECODE_PRINTF("ROL\t");
10193  break;
10194  case 1:
10195  DECODE_PRINTF("ROR\t");
10196  break;
10197  case 2:
10198  DECODE_PRINTF("RCL\t");
10199  break;
10200  case 3:
10201  DECODE_PRINTF("RCR\t");
10202  break;
10203  case 4:
10204  DECODE_PRINTF("SHL\t");
10205  break;
10206  case 5:
10207  DECODE_PRINTF("SHR\t");
10208  break;
10209  case 6:
10210  DECODE_PRINTF("SAL\t");
10211  break;
10212  case 7:
10213  DECODE_PRINTF("SAR\t");
10214  break;
10215  }
10216  }
10217 #endif
10218  /* know operation, decode the mod byte to find the addressing
10219  mode. */
10220  amt = M.x86.R_CL;
10221  switch (mod)
10222  {
10223  case 0:
10224  if (M.x86.mode & SYSMODE_PREFIX_DATA)
10225  {
10226  u32 destval;
10227 
10228  DECODE_PRINTF("DWORD PTR ");
10229  destoffset = decode_rm00_address(rl);
10230  DECODE_PRINTF(",CL\n");
10231  destval = fetch_data_long(destoffset);
10232  TRACE_AND_STEP();
10233  destval = (*opcD1_long_operation[rh])(destval, amt);
10234  store_data_long(destoffset, destval);
10235  }
10236  else
10237  {
10238  u16 destval;
10239 
10240  DECODE_PRINTF("WORD PTR ");
10241  destoffset = decode_rm00_address(rl);
10242  DECODE_PRINTF(",CL\n");
10243  destval = fetch_data_word(destoffset);
10244  TRACE_AND_STEP();
10245  destval = (*opcD1_word_operation[rh])(destval, amt);
10246  store_data_word(destoffset, destval);
10247  }
10248  break;
10249  case 1:
10250  if (M.x86.mode & SYSMODE_PREFIX_DATA)
10251  {
10252  u32 destval;
10253 
10254  DECODE_PRINTF("DWORD PTR ");
10255  destoffset = decode_rm01_address(rl);
10256  DECODE_PRINTF(",CL\n");
10257  destval = fetch_data_long(destoffset);
10258  TRACE_AND_STEP();
10259  destval = (*opcD1_long_operation[rh])(destval, amt);
10260  store_data_long(destoffset, destval);
10261  }
10262  else
10263  {
10264  u16 destval;
10265 
10266  DECODE_PRINTF("WORD PTR ");
10267  destoffset = decode_rm01_address(rl);
10268  DECODE_PRINTF(",CL\n");
10269  destval = fetch_data_word(destoffset);
10270  TRACE_AND_STEP();
10271  destval = (*opcD1_word_operation[rh])(destval, amt);
10272  store_data_word(destoffset, destval);
10273  }
10274  break;
10275  case 2:
10276  if (M.x86.mode & SYSMODE_PREFIX_DATA)
10277  {
10278  u32 destval;
10279 
10280  DECODE_PRINTF("DWORD PTR ");
10281  destoffset = decode_rm10_address(rl);
10282  DECODE_PRINTF(",CL\n");
10283  destval = fetch_data_long(destoffset);
10284  TRACE_AND_STEP();
10285  destval = (*opcD1_long_operation[rh])(destval, amt);
10286  store_data_long(destoffset, destval);
10287  }
10288  else
10289  {
10290  u16 destval;
10291 
10292  DECODE_PRINTF("WORD PTR ");
10293  destoffset = decode_rm10_address(rl);
10294  DECODE_PRINTF(",CL\n");
10295  destval = fetch_data_word(destoffset);
10296  TRACE_AND_STEP();
10297  destval = (*opcD1_word_operation[rh])(destval, amt);
10298  store_data_word(destoffset, destval);
10299  }
10300  break;
10301  case 3: /* register to register */
10302  if (M.x86.mode & SYSMODE_PREFIX_DATA)
10303  {
10304  u32 *destreg;
10305 
10306  destreg = DECODE_RM_LONG_REGISTER(rl);
10307  DECODE_PRINTF(",CL\n");
10308  TRACE_AND_STEP();
10309  *destreg = (*opcD1_long_operation[rh])(*destreg, amt);
10310  }
10311  else
10312  {
10313  u16 *destreg;
10314 
10315  destreg = DECODE_RM_WORD_REGISTER(rl);
10316  DECODE_PRINTF(",CL\n");
10317  TRACE_AND_STEP();
10318  *destreg = (*opcD1_word_operation[rh])(*destreg, amt);
10319  }
10320  break;
10321  }
10322  DECODE_CLEAR_SEGOVR();
10323  END_OF_INSTR();
10324 }
10325 
10326 /****************************************************************************
10327 REMARKS:
10328 Handles opcode 0xd4
10329 ****************************************************************************/
10330 static void x86emuOp_aam(u8 X86EMU_UNUSED(op1))
10331 {
10332  u8 a;
10333 
10334  START_OF_INSTR();
10335  DECODE_PRINTF("AAM\n");
10336  a = fetch_byte_imm(); /* this is a stupid encoding. */
10337  if (a != 10)
10338  {
10339  /* fix: add base decoding
10340  aam_word(u8 val, int base a) */
10341  DECODE_PRINTF("ERROR DECODING AAM\n");
10342  TRACE_REGS();
10343  HALT_SYS();
10344  }
10345  TRACE_AND_STEP();
10346  /* note the type change here --- returning AL and AH in AX. */
10347  M.x86.R_AX = aam_word(M.x86.R_AL);
10348  DECODE_CLEAR_SEGOVR();
10349  END_OF_INSTR();
10350 }
10351 
10352 /****************************************************************************
10353 REMARKS:
10354 Handles opcode 0xd5
10355 ****************************************************************************/
10356 static void x86emuOp_aad(u8 X86EMU_UNUSED(op1))
10357 {
10358  u8 a;
10359 
10360  START_OF_INSTR();
10361  DECODE_PRINTF("AAD\n");
10362  a = fetch_byte_imm();
10363  if (a != 10)
10364  {
10365  /* fix: add base decoding
10366  aad_word(u16 val, int base a) */
10367  DECODE_PRINTF("ERROR DECODING AAM\n");
10368  TRACE_REGS();
10369  HALT_SYS();
10370  }
10371  TRACE_AND_STEP();
10372  M.x86.R_AX = aad_word(M.x86.R_AX);
10373  DECODE_CLEAR_SEGOVR();
10374  END_OF_INSTR();
10375 }
10376 
10377 /* opcode 0xd6 ILLEGAL OPCODE */
10378 
10379 /****************************************************************************
10380 REMARKS:
10381 Handles opcode 0xd7
10382 ****************************************************************************/
10383 static void x86emuOp_xlat(u8 X86EMU_UNUSED(op1))
10384 {
10385  u16 addr;
10386 
10387  START_OF_INSTR();
10388  DECODE_PRINTF("XLAT\n");
10389  TRACE_AND_STEP();
10390  addr = (u16)(M.x86.R_BX + (u8) M.x86.R_AL);
10391  M.x86.R_AL = fetch_data_byte(addr);
10392  DECODE_CLEAR_SEGOVR();
10393  END_OF_INSTR();
10394 }
10395 
10396 /* instuctions D8 .. DF are in i87_ops.c */
10397 
10398 /****************************************************************************
10399 REMARKS:
10400 Handles opcode 0xe0
10401 ****************************************************************************/
10402 static void x86emuOp_loopne(u8 X86EMU_UNUSED(op1))
10403 {
10404  s16 ip;
10405 
10406  START_OF_INSTR();
10407  DECODE_PRINTF("LOOPNE\t");
10408  ip = (s8) fetch_byte_imm();
10409  ip += (s16) M.x86.R_IP;
10410  DECODE_PRINTF2("%04x\n", ip);
10411  TRACE_AND_STEP();
10412  M.x86.R_CX -= 1;
10413  if (M.x86.R_CX != 0 && !ACCESS_FLAG(F_ZF)) /* CX != 0 and !ZF */
10414  M.x86.R_IP = ip;
10415  DECODE_CLEAR_SEGOVR();
10416  END_OF_INSTR();
10417 }
10418 
10419 /****************************************************************************
10420 REMARKS:
10421 Handles opcode 0xe1
10422 ****************************************************************************/
10423 static void x86emuOp_loope(u8 X86EMU_UNUSED(op1))
10424 {
10425  s16 ip;
10426 
10427  START_OF_INSTR();
10428  DECODE_PRINTF("LOOPE\t");
10429  ip = (s8) fetch_byte_imm();
10430  ip += (s16) M.x86.R_IP;
10431  DECODE_PRINTF2("%04x\n", ip);
10432  TRACE_AND_STEP();
10433  M.x86.R_CX -= 1;
10434  if (M.x86.R_CX != 0 && ACCESS_FLAG(F_ZF)) /* CX != 0 and ZF */
10435  M.x86.R_IP = ip;
10436  DECODE_CLEAR_SEGOVR();
10437  END_OF_INSTR();
10438 }
10439 
10440 /****************************************************************************
10441 REMARKS:
10442 Handles opcode 0xe2
10443 ****************************************************************************/
10444 static void x86emuOp_loop(u8 X86EMU_UNUSED(op1))
10445 {
10446  s16 ip;
10447 
10448  START_OF_INSTR();
10449  DECODE_PRINTF("LOOP\t");
10450  ip = (s8) fetch_byte_imm();
10451  ip += (s16) M.x86.R_IP;
10452  DECODE_PRINTF2("%04x\n", ip);
10453  TRACE_AND_STEP();
10454  M.x86.R_CX -= 1;
10455  if (M.x86.R_CX != 0)
10456  M.x86.R_IP = ip;
10457  DECODE_CLEAR_SEGOVR();
10458  END_OF_INSTR();
10459 }
10460 
10461 /****************************************************************************
10462 REMARKS:
10463 Handles opcode 0xe3
10464 ****************************************************************************/
10465 static void x86emuOp_jcxz(u8 X86EMU_UNUSED(op1))
10466 {
10467  u16 target;
10468  s8 offset;
10469 
10470  /* jump to byte offset if overflow flag is set */
10471  START_OF_INSTR();
10472  DECODE_PRINTF("JCXZ\t");
10473  offset = (s8) fetch_byte_imm();
10474  target = (u16)(M.x86.R_IP + offset);
10475  DECODE_PRINTF2("%x\n", target);
10476  TRACE_AND_STEP();
10477  if (M.x86.R_CX == 0)
10478  M.x86.R_IP = target;
10479  DECODE_CLEAR_SEGOVR();
10480  END_OF_INSTR();
10481 }
10482 
10483 /****************************************************************************
10484 REMARKS:
10485 Handles opcode 0xe4
10486 ****************************************************************************/
10487 static void x86emuOp_in_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
10488 {
10489  u8 port;
10490 
10491  START_OF_INSTR();
10492  DECODE_PRINTF("IN\t");
10493  port = (u8) fetch_byte_imm();
10494  DECODE_PRINTF2("%x,AL\n", port);
10495  TRACE_AND_STEP();
10496  M.x86.R_AL = (*sys_inb)(port);
10497  DECODE_CLEAR_SEGOVR();
10498  END_OF_INSTR();
10499 }
10500 
10501 /****************************************************************************
10502 REMARKS:
10503 Handles opcode 0xe5
10504 ****************************************************************************/
10505 static void x86emuOp_in_word_AX_IMM(u8 X86EMU_UNUSED(op1))
10506 {
10507  u8 port;
10508 
10509  START_OF_INSTR();
10510  DECODE_PRINTF("IN\t");
10511  port = (u8) fetch_byte_imm();
10512  if (M.x86.mode & SYSMODE_PREFIX_DATA)
10513  {
10514  DECODE_PRINTF2("EAX,%x\n", port);
10515  }
10516  else
10517  {
10518  DECODE_PRINTF2("AX,%x\n", port);
10519  }
10520  TRACE_AND_STEP();
10521  if (M.x86.mode & SYSMODE_PREFIX_DATA)
10522  {
10523  M.x86.R_EAX = (*sys_inl)(port);
10524  }
10525  else
10526  {
10527  M.x86.R_AX = (*sys_inw)(port);
10528  }
10529  DECODE_CLEAR_SEGOVR();
10530  END_OF_INSTR();
10531 }
10532 
10533 /****************************************************************************
10534 REMARKS:
10535 Handles opcode 0xe6
10536 ****************************************************************************/
10537 static void x86emuOp_out_byte_IMM_AL(u8 X86EMU_UNUSED(op1))
10538 {
10539  u8 port;
10540 
10541  START_OF_INSTR();
10542  DECODE_PRINTF("OUT\t");
10543  port = (u8) fetch_byte_imm();
10544  DECODE_PRINTF2("%x,AL\n", port);
10545  TRACE_AND_STEP();
10546  (*sys_outb)(port, M.x86.R_AL);
10547  DECODE_CLEAR_SEGOVR();
10548  END_OF_INSTR();
10549 }
10550 
10551 /****************************************************************************
10552 REMARKS:
10553 Handles opcode 0xe7
10554 ****************************************************************************/
10555 static void x86emuOp_out_word_IMM_AX(u8 X86EMU_UNUSED(op1))
10556 {
10557  u8 port;
10558 
10559  START_OF_INSTR();
10560  DECODE_PRINTF("OUT\t");
10561  port = (u8) fetch_byte_imm();
10562  if (M.x86.mode & SYSMODE_PREFIX_DATA)
10563  {
10564  DECODE_PRINTF2("%x,EAX\n", port);
10565  }
10566  else
10567  {
10568  DECODE_PRINTF2("%x,AX\n", port);
10569  }
10570  TRACE_AND_STEP();
10571  if (M.x86.mode & SYSMODE_PREFIX_DATA)
10572  {
10573  (*sys_outl)(port, M.x86.R_EAX);
10574  }
10575  else
10576  {
10577  (*sys_outw)(port, M.x86.R_AX);
10578  }
10579  DECODE_CLEAR_SEGOVR();
10580  END_OF_INSTR();
10581 }
10582 
10583 /****************************************************************************
10584 REMARKS:
10585 Handles opcode 0xe8
10586 ****************************************************************************/
10587 static void x86emuOp_call_near_IMM(u8 X86EMU_UNUSED(op1))
10588 {
10589  s16 ip;
10590 
10591  START_OF_INSTR();
10592  DECODE_PRINTF("CALL\t");
10593  ip = (s16) fetch_word_imm();
10594  ip += (s16) M.x86.R_IP; /* CHECK SIGN */
10595  DECODE_PRINTF2("%04x\n", (u16) ip);
10596  CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, M.x86.R_CS, ip, "");
10597  TRACE_AND_STEP();
10598  push_word(M.x86.R_IP);
10599  M.x86.R_IP = ip;
10600  DECODE_CLEAR_SEGOVR();
10601  END_OF_INSTR();
10602 }
10603 
10604 /****************************************************************************
10605 REMARKS:
10606 Handles opcode 0xe9
10607 ****************************************************************************/
10608 static void x86emuOp_jump_near_IMM(u8 X86EMU_UNUSED(op1))
10609 {
10610  int ip;
10611 
10612  START_OF_INSTR();
10613  DECODE_PRINTF("JMP\t");
10614  ip = (s16) fetch_word_imm();
10615  ip += (s16) M.x86.R_IP;
10616  DECODE_PRINTF2("%04x\n", (u16) ip);
10617  TRACE_AND_STEP();
10618  M.x86.R_IP = (u16) ip;
10619  DECODE_CLEAR_SEGOVR();
10620  END_OF_INSTR();
10621 }
10622 
10623 /****************************************************************************
10624 REMARKS:
10625 Handles opcode 0xea
10626 ****************************************************************************/
10627 static void x86emuOp_jump_far_IMM(u8 X86EMU_UNUSED(op1))
10628 {
10629  u16 cs, ip;
10630 
10631  START_OF_INSTR();
10632  DECODE_PRINTF("JMP\tFAR ");
10633  ip = fetch_word_imm();
10634  cs = fetch_word_imm();
10635  DECODE_PRINTF2("%04x:", cs);
10636  DECODE_PRINTF2("%04x\n", ip);
10637  TRACE_AND_STEP();
10638  M.x86.R_IP = ip;
10639  M.x86.R_CS = cs;
10640  DECODE_CLEAR_SEGOVR();
10641  END_OF_INSTR();
10642 }
10643 
10644 /****************************************************************************
10645 REMARKS:
10646 Handles opcode 0xeb
10647 ****************************************************************************/
10648 static void x86emuOp_jump_byte_IMM(u8 X86EMU_UNUSED(op1))
10649 {
10650  u16 target;
10651  s8 offset;
10652 
10653  START_OF_INSTR();
10654  DECODE_PRINTF("JMP\t");
10655  offset = (s8) fetch_byte_imm();
10656  target = (u16)(M.x86.R_IP + offset);
10657  DECODE_PRINTF2("%x\n", target);
10658  TRACE_AND_STEP();
10659  M.x86.R_IP = target;
10660  DECODE_CLEAR_SEGOVR();
10661  END_OF_INSTR();
10662 }
10663 
10664 /****************************************************************************
10665 REMARKS:
10666 Handles opcode 0xec
10667 ****************************************************************************/
10668 static void x86emuOp_in_byte_AL_DX(u8 X86EMU_UNUSED(op1))
10669 {
10670  START_OF_INSTR();
10671  DECODE_PRINTF("IN\tAL,DX\n");
10672  TRACE_AND_STEP();
10673  M.x86.R_AL = (*sys_inb)(M.x86.R_DX);
10674  DECODE_CLEAR_SEGOVR();
10675  END_OF_INSTR();
10676 }
10677 
10678 /****************************************************************************
10679 REMARKS:
10680 Handles opcode 0xed
10681 ****************************************************************************/
10682 static void x86emuOp_in_word_AX_DX(u8 X86EMU_UNUSED(op1))
10683 {
10684  START_OF_INSTR();
10685  if (M.x86.mode & SYSMODE_PREFIX_DATA)
10686  {
10687  DECODE_PRINTF("IN\tEAX,DX\n");
10688  }
10689  else
10690  {
10691  DECODE_PRINTF("IN\tAX,DX\n");
10692  }
10693  TRACE_AND_STEP();
10694  if (M.x86.mode & SYSMODE_PREFIX_DATA)
10695  {
10696  M.x86.R_EAX = (*sys_inl)(M.x86.R_DX);
10697  }
10698  else
10699  {
10700  M.x86.R_AX = (*sys_inw)(M.x86.R_DX);
10701  }
10702  DECODE_CLEAR_SEGOVR();
10703  END_OF_INSTR();
10704 }
10705 
10706 /****************************************************************************
10707 REMARKS:
10708 Handles opcode 0xee
10709 ****************************************************************************/
10710 static void x86emuOp_out_byte_DX_AL(u8 X86EMU_UNUSED(op1))
10711 {
10712  START_OF_INSTR();
10713  DECODE_PRINTF("OUT\tDX,AL\n");
10714  TRACE_AND_STEP();
10715  (*sys_outb)(M.x86.R_DX, M.x86.R_AL);
10716  DECODE_CLEAR_SEGOVR();
10717  END_OF_INSTR();
10718 }
10719 
10720 /****************************************************************************
10721 REMARKS:
10722 Handles opcode 0xef
10723 ****************************************************************************/
10724 static void x86emuOp_out_word_DX_AX(u8 X86EMU_UNUSED(op1))
10725 {
10726  START_OF_INSTR();
10727  if (M.x86.mode & SYSMODE_PREFIX_DATA)
10728  {
10729  DECODE_PRINTF("OUT\tDX,EAX\n");
10730  }
10731  else
10732  {
10733  DECODE_PRINTF("OUT\tDX,AX\n");
10734  }
10735  TRACE_AND_STEP();
10736  if (M.x86.mode & SYSMODE_PREFIX_DATA)
10737  {
10738  (*sys_outl)(M.x86.R_DX, M.x86.R_EAX);
10739  }
10740  else
10741  {
10742  (*sys_outw)(M.x86.R_DX, M.x86.R_AX);
10743  }
10744  DECODE_CLEAR_SEGOVR();
10745  END_OF_INSTR();
10746 }
10747 
10748 /****************************************************************************
10749 REMARKS:
10750 Handles opcode 0xf0
10751 ****************************************************************************/
10752 static void x86emuOp_lock(u8 X86EMU_UNUSED(op1))
10753 {
10754  START_OF_INSTR();
10755  DECODE_PRINTF("LOCK:\n");
10756  TRACE_AND_STEP();
10757  DECODE_CLEAR_SEGOVR();
10758  END_OF_INSTR();
10759 }
10760 
10761 /*opcode 0xf1 ILLEGAL OPERATION */
10762 
10763 /****************************************************************************
10764 REMARKS:
10765 Handles opcode 0xf2
10766 ****************************************************************************/
10767 static void x86emuOp_repne(u8 X86EMU_UNUSED(op1))
10768 {
10769  START_OF_INSTR();
10770  DECODE_PRINTF("REPNE\n");
10771  TRACE_AND_STEP();
10772  M.x86.mode |= SYSMODE_PREFIX_REPNE;
10773  DECODE_CLEAR_SEGOVR();
10774  END_OF_INSTR();
10775 }
10776 
10777 /****************************************************************************
10778 REMARKS:
10779 Handles opcode 0xf3
10780 ****************************************************************************/
10781 static void x86emuOp_repe(u8 X86EMU_UNUSED(op1))
10782 {
10783  START_OF_INSTR();
10784  DECODE_PRINTF("REPE\n");
10785  TRACE_AND_STEP();
10786  M.x86.mode |= SYSMODE_PREFIX_REPE;
10787  DECODE_CLEAR_SEGOVR();
10788  END_OF_INSTR();
10789 }
10790 
10791 /****************************************************************************
10792 REMARKS:
10793 Handles opcode 0xf4
10794 ****************************************************************************/
10795 static void x86emuOp_halt(u8 X86EMU_UNUSED(op1))
10796 {
10797  START_OF_INSTR();
10798  DECODE_PRINTF("HALT\n");
10799  TRACE_AND_STEP();
10800  HALT_SYS();
10801  DECODE_CLEAR_SEGOVR();
10802  END_OF_INSTR();
10803 }
10804 
10805 /****************************************************************************
10806 REMARKS:
10807 Handles opcode 0xf5
10808 ****************************************************************************/
10809 static void x86emuOp_cmc(u8 X86EMU_UNUSED(op1))
10810 {
10811  /* complement the carry flag. */
10812  START_OF_INSTR();
10813  DECODE_PRINTF("CMC\n");
10814  TRACE_AND_STEP();
10815  TOGGLE_FLAG(F_CF);
10816  DECODE_CLEAR_SEGOVR();
10817  END_OF_INSTR();
10818 }
10819 
10820 /****************************************************************************
10821 REMARKS:
10822 Handles opcode 0xf6
10823 ****************************************************************************/
10824 static void x86emuOp_opcF6_byte_RM(u8 X86EMU_UNUSED(op1))
10825 {
10826  int mod, rl, rh;
10827  u8 *destreg;
10828  uint destoffset;
10829  u8 destval, srcval;
10830 
10831  /* long, drawn out code follows. Double switch for a total
10832  of 32 cases. */
10833  START_OF_INSTR();
10834  FETCH_DECODE_MODRM(mod, rh, rl);
10835  switch (mod)
10836  {
10837  case 0: /* mod=00 */
10838  switch (rh)
10839  {
10840  case 0: /* test byte imm */
10841  DECODE_PRINTF("TEST\tBYTE PTR ");
10842  destoffset = decode_rm00_address(rl);
10843  DECODE_PRINTF(",");
10844  srcval = fetch_byte_imm();
10845  DECODE_PRINTF2("%02x\n", srcval);
10846  destval = fetch_data_byte(destoffset);
10847  TRACE_AND_STEP();
10848  test_byte(destval, srcval);
10849  break;
10850  case 1:
10851  DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
10852  HALT_SYS();
10853  break;
10854  case 2:
10855  DECODE_PRINTF("NOT\tBYTE PTR ");
10856  destoffset = decode_rm00_address(rl);
10857  DECODE_PRINTF("\n");
10858  destval = fetch_data_byte(destoffset);
10859  TRACE_AND_STEP();
10860  destval = not_byte(destval);
10861  store_data_byte(destoffset, destval);
10862  break;
10863  case 3:
10864  DECODE_PRINTF("NEG\tBYTE PTR ");
10865  destoffset = decode_rm00_address(rl);
10866  DECODE_PRINTF("\n");
10867  destval = fetch_data_byte(destoffset);
10868  TRACE_AND_STEP();
10869  destval = neg_byte(destval);
10870  store_data_byte(destoffset, destval);
10871  break;
10872  case 4:
10873  DECODE_PRINTF("MUL\tBYTE PTR ");
10874  destoffset = decode_rm00_address(rl);
10875  DECODE_PRINTF("\n");
10876  destval = fetch_data_byte(destoffset);
10877  TRACE_AND_STEP();
10878  mul_byte(destval);
10879  break;
10880  case 5:
10881  DECODE_PRINTF("IMUL\tBYTE PTR ");
10882  destoffset = decode_rm00_address(rl);
10883  DECODE_PRINTF("\n");
10884  destval = fetch_data_byte(destoffset);
10885  TRACE_AND_STEP();
10886  imul_byte(destval);
10887  break;
10888  case 6:
10889  DECODE_PRINTF("DIV\tBYTE PTR ");
10890  destoffset = decode_rm00_address(rl);
10891  DECODE_PRINTF("\n");
10892  destval = fetch_data_byte(destoffset);
10893  TRACE_AND_STEP();
10894  div_byte(destval);
10895  break;
10896  case 7:
10897  DECODE_PRINTF("IDIV\tBYTE PTR ");
10898  destoffset = decode_rm00_address(rl);
10899  DECODE_PRINTF("\n");
10900  destval = fetch_data_byte(destoffset);
10901  TRACE_AND_STEP();
10902  idiv_byte(destval);
10903  break;
10904  }
10905  break; /* end mod==00 */
10906  case 1: /* mod=01 */
10907  switch (rh)
10908  {
10909  case 0: /* test byte imm */
10910  DECODE_PRINTF("TEST\tBYTE PTR ");
10911  destoffset = decode_rm01_address(rl);
10912  DECODE_PRINTF(",");
10913  srcval = fetch_byte_imm();
10914  DECODE_PRINTF2("%02x\n", srcval);
10915  destval = fetch_data_byte(destoffset);
10916  TRACE_AND_STEP();
10917  test_byte(destval, srcval);
10918  break;
10919  case 1:
10920  DECODE_PRINTF("ILLEGAL OP MOD=01 RH=01 OP=F6\n");
10921  HALT_SYS();
10922  break;
10923  case 2:
10924  DECODE_PRINTF("NOT\tBYTE PTR ");
10925  destoffset = decode_rm01_address(rl);
10926  DECODE_PRINTF("\n");
10927  destval = fetch_data_byte(destoffset);
10928  TRACE_AND_STEP();
10929  destval = not_byte(destval);
10930  store_data_byte(destoffset, destval);
10931  break;
10932  case 3:
10933  DECODE_PRINTF("NEG\tBYTE PTR ");
10934  destoffset = decode_rm01_address(rl);
10935  DECODE_PRINTF("\n");
10936  destval = fetch_data_byte(destoffset);
10937  TRACE_AND_STEP();
10938  destval = neg_byte(destval);
10939  store_data_byte(destoffset, destval);
10940  break;
10941  case 4:
10942  DECODE_PRINTF("MUL\tBYTE PTR ");
10943  destoffset = decode_rm01_address(rl);
10944  DECODE_PRINTF("\n");
10945  destval = fetch_data_byte(destoffset);
10946  TRACE_AND_STEP();
10947  mul_byte(destval);
10948  break;
10949  case 5:
10950  DECODE_PRINTF("IMUL\tBYTE PTR ");
10951  destoffset = decode_rm01_address(rl);
10952  DECODE_PRINTF("\n");
10953  destval = fetch_data_byte(destoffset);
10954  TRACE_AND_STEP();
10955  imul_byte(destval);
10956  break;
10957  case 6:
10958  DECODE_PRINTF("DIV\tBYTE PTR ");
10959  destoffset = decode_rm01_address(rl);
10960  DECODE_PRINTF("\n");
10961  destval = fetch_data_byte(destoffset);
10962  TRACE_AND_STEP();
10963  div_byte(destval);
10964  break;
10965  case 7:
10966  DECODE_PRINTF("IDIV\tBYTE PTR ");
10967  destoffset = decode_rm01_address(rl);
10968  DECODE_PRINTF("\n");
10969  destval = fetch_data_byte(destoffset);
10970  TRACE_AND_STEP();
10971  idiv_byte(destval);
10972  break;
10973  }
10974  break; /* end mod==01 */
10975  case 2: /* mod=10 */
10976  switch (rh)
10977  {
10978  case 0: /* test byte imm */
10979  DECODE_PRINTF("TEST\tBYTE PTR ");
10980  destoffset = decode_rm10_address(rl);
10981  DECODE_PRINTF(",");
10982  srcval = fetch_byte_imm();
10983  DECODE_PRINTF2("%02x\n", srcval);
10984  destval = fetch_data_byte(destoffset);
10985  TRACE_AND_STEP();
10986  test_byte(destval, srcval);
10987  break;
10988  case 1:
10989  DECODE_PRINTF("ILLEGAL OP MOD=10 RH=01 OP=F6\n");
10990  HALT_SYS();
10991  break;
10992  case 2:
10993  DECODE_PRINTF("NOT\tBYTE PTR ");
10994  destoffset = decode_rm10_address(rl);
10995  DECODE_PRINTF("\n");
10996  destval = fetch_data_byte(destoffset);
10997  TRACE_AND_STEP();
10998  destval = not_byte(destval);
10999  store_data_byte(destoffset, destval);
11000  break;
11001  case 3:
11002  DECODE_PRINTF("NEG\tBYTE PTR ");
11003  destoffset = decode_rm10_address(rl);
11004  DECODE_PRINTF("\n");
11005  destval = fetch_data_byte(destoffset);
11006  TRACE_AND_STEP();
11007  destval = neg_byte(destval);
11008  store_data_byte(destoffset, destval);
11009  break;
11010  case 4:
11011  DECODE_PRINTF("MUL\tBYTE PTR ");
11012  destoffset = decode_rm10_address(rl);
11013  DECODE_PRINTF("\n");
11014  destval = fetch_data_byte(destoffset);
11015  TRACE_AND_STEP();
11016  mul_byte(destval);
11017  break;
11018  case 5:
11019  DECODE_PRINTF("IMUL\tBYTE PTR ");
11020  destoffset = decode_rm10_address(rl);
11021  DECODE_PRINTF("\n");
11022  destval = fetch_data_byte(destoffset);
11023  TRACE_AND_STEP();
11024  imul_byte(destval);
11025  break;
11026  case 6:
11027  DECODE_PRINTF("DIV\tBYTE PTR ");
11028  destoffset = decode_rm10_address(rl);
11029  DECODE_PRINTF("\n");
11030  destval = fetch_data_byte(destoffset);
11031  TRACE_AND_STEP();
11032  div_byte(destval);
11033  break;
11034  case 7:
11035  DECODE_PRINTF("IDIV\tBYTE PTR ");
11036  destoffset = decode_rm10_address(rl);
11037  DECODE_PRINTF("\n");
11038  destval = fetch_data_byte(destoffset);
11039  TRACE_AND_STEP();
11040  idiv_byte(destval);
11041  break;
11042  }
11043  break; /* end mod==10 */
11044  case 3: /* mod=11 */
11045  switch (rh)
11046  {
11047  case 0: /* test byte imm */
11048  DECODE_PRINTF("TEST\t");
11049  destreg = DECODE_RM_BYTE_REGISTER(rl);
11050  DECODE_PRINTF(",");
11051  srcval = fetch_byte_imm();
11052  DECODE_PRINTF2("%02x\n", srcval);
11053  TRACE_AND_STEP();
11054  test_byte(*destreg, srcval);
11055  break;
11056  case 1:
11057  DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
11058  HALT_SYS();
11059  break;
11060  case 2:
11061  DECODE_PRINTF("NOT\t");
11062  destreg = DECODE_RM_BYTE_REGISTER(rl);
11063  DECODE_PRINTF("\n");
11064  TRACE_AND_STEP();
11065  *destreg = not_byte(*destreg);
11066  break;
11067  case 3:
11068  DECODE_PRINTF("NEG\t");
11069  destreg = DECODE_RM_BYTE_REGISTER(rl);
11070  DECODE_PRINTF("\n");
11071  TRACE_AND_STEP();
11072  *destreg = neg_byte(*destreg);
11073  break;
11074  case 4:
11075  DECODE_PRINTF("MUL\t");
11076  destreg = DECODE_RM_BYTE_REGISTER(rl);
11077  DECODE_PRINTF("\n");
11078  TRACE_AND_STEP();
11079  mul_byte(*destreg);
11080  break;
11081  case 5:
11082  DECODE_PRINTF("IMUL\t");
11083  destreg = DECODE_RM_BYTE_REGISTER(rl);
11084  DECODE_PRINTF("\n");
11085  TRACE_AND_STEP();
11086  imul_byte(*destreg);
11087  break;
11088  case 6:
11089  DECODE_PRINTF("DIV\t");
11090  destreg = DECODE_RM_BYTE_REGISTER(rl);
11091  DECODE_PRINTF("\n");
11092  TRACE_AND_STEP();
11093  div_byte(*destreg);
11094  break;
11095  case 7:
11096  DECODE_PRINTF("IDIV\t");
11097  destreg = DECODE_RM_BYTE_REGISTER(rl);
11098  DECODE_PRINTF("\n");
11099  TRACE_AND_STEP();
11100  idiv_byte(*destreg);
11101  break;
11102  }
11103  break; /* end mod==11 */
11104  }
11105  DECODE_CLEAR_SEGOVR();
11106  END_OF_INSTR();
11107 }
11108 
11109 /****************************************************************************
11110 REMARKS:
11111 Handles opcode 0xf7
11112 ****************************************************************************/
11113 static void x86emuOp_opcF7_word_RM(u8 X86EMU_UNUSED(op1))
11114 {
11115  int mod, rl, rh;
11116  uint destoffset;
11117 
11118  /* long, drawn out code follows. Double switch for a total
11119  of 32 cases. */
11120  START_OF_INSTR();
11121  FETCH_DECODE_MODRM(mod, rh, rl);
11122  switch (mod)
11123  {
11124  case 0: /* mod=00 */
11125  switch (rh)
11126  {
11127  case 0: /* test word imm */
11128  if (M.x86.mode & SYSMODE_PREFIX_DATA)
11129  {
11130  u32 destval, srcval;
11131 
11132  DECODE_PRINTF("TEST\tDWORD PTR ");
11133  destoffset = decode_rm00_address(rl);
11134  DECODE_PRINTF(",");
11135  srcval = fetch_long_imm();
11136  DECODE_PRINTF2("%x\n", srcval);
11137  destval = fetch_data_long(destoffset);
11138  TRACE_AND_STEP();
11139  test_long(destval, srcval);
11140  }
11141  else
11142  {
11143  u16 destval, srcval;
11144 
11145  DECODE_PRINTF("TEST\tWORD PTR ");
11146  destoffset = decode_rm00_address(rl);
11147  DECODE_PRINTF(",");
11148  srcval = fetch_word_imm();
11149  DECODE_PRINTF2("%x\n", srcval);
11150  destval = fetch_data_word(destoffset);
11151  TRACE_AND_STEP();
11152  test_word(destval, srcval);
11153  }
11154  break;
11155  case 1:
11156  DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F7\n");
11157  HALT_SYS();
11158  break;
11159  case 2:
11160  if (M.x86.mode & SYSMODE_PREFIX_DATA)
11161  {
11162  u32 destval;
11163 
11164  DECODE_PRINTF("NOT\tDWORD PTR ");
11165  destoffset = decode_rm00_address(rl);
11166  DECODE_PRINTF("\n");
11167  destval = fetch_data_long(destoffset);
11168  TRACE_AND_STEP();
11169  destval = not_long(destval);
11170  store_data_long(destoffset, destval);
11171  }
11172  else
11173  {
11174  u16 destval;
11175 
11176  DECODE_PRINTF("NOT\tWORD PTR ");
11177  destoffset = decode_rm00_address(rl);
11178  DECODE_PRINTF("\n");
11179  destval = fetch_data_word(destoffset);
11180  TRACE_AND_STEP();
11181  destval = not_word(destval);
11182  store_data_word(destoffset, destval);
11183  }
11184  break;
11185  case 3:
11186  if (M.x86.mode & SYSMODE_PREFIX_DATA)
11187  {
11188  u32 destval;
11189 
11190  DECODE_PRINTF("NEG\tDWORD PTR ");
11191  destoffset = decode_rm00_address(rl);
11192  DECODE_PRINTF("\n");
11193  destval = fetch_data_long(destoffset);
11194  TRACE_AND_STEP();
11195  destval = neg_long(destval);
11196  store_data_long(destoffset, destval);
11197  }
11198  else
11199  {
11200  u16 destval;
11201 
11202  DECODE_PRINTF("NEG\tWORD PTR ");
11203  destoffset = decode_rm00_address(rl);
11204  DECODE_PRINTF("\n");
11205  destval = fetch_data_word(destoffset);
11206  TRACE_AND_STEP();
11207  destval = neg_word(destval);
11208  store_data_word(destoffset, destval);
11209  }
11210  break;
11211  case 4:
11212  if (M.x86.mode & SYSMODE_PREFIX_DATA)
11213  {
11214  u32 destval;
11215 
11216  DECODE_PRINTF("MUL\tDWORD PTR ");
11217  destoffset = decode_rm00_address(rl);
11218  DECODE_PRINTF("\n");
11219  destval = fetch_data_long(destoffset);
11220  TRACE_AND_STEP();
11221  mul_long(destval);
11222  }
11223  else
11224  {
11225  u16 destval;
11226 
11227  DECODE_PRINTF("MUL\tWORD PTR ");
11228  destoffset = decode_rm00_address(rl);
11229  DECODE_PRINTF("\n");
11230  destval = fetch_data_word(destoffset);
11231  TRACE_AND_STEP();
11232  mul_word(destval);
11233  }
11234  break;
11235  case 5:
11236  if (M.x86.mode & SYSMODE_PREFIX_DATA)
11237  {
11238  u32 destval;
11239 
11240  DECODE_PRINTF("IMUL\tDWORD PTR ");
11241  destoffset = decode_rm00_address(rl);
11242  DECODE_PRINTF("\n");
11243  destval = fetch_data_long(destoffset);
11244  TRACE_AND_STEP();
11245  imul_long(destval);
11246  }
11247  else
11248  {
11249  u16 destval;
11250 
11251  DECODE_PRINTF("IMUL\tWORD PTR ");
11252  destoffset = decode_rm00_address(rl);
11253  DECODE_PRINTF("\n");
11254  destval = fetch_data_word(destoffset);
11255  TRACE_AND_STEP();
11256  imul_word(destval);
11257  }
11258  break;
11259  case 6:
11260  if (M.x86.mode & SYSMODE_PREFIX_DATA)
11261  {
11262  u32 destval;
11263 
11264  DECODE_PRINTF("DIV\tDWORD PTR ");
11265  destoffset = decode_rm00_address(rl);
11266  DECODE_PRINTF("\n");
11267  destval = fetch_data_long(destoffset);
11268  TRACE_AND_STEP();
11269  div_long(destval);
11270  }
11271  else
11272  {
11273  u16 destval;
11274 
11275  DECODE_PRINTF("DIV\tWORD PTR ");
11276  destoffset = decode_rm00_address(rl);
11277  DECODE_PRINTF("\n");
11278  destval = fetch_data_word(destoffset);
11279  TRACE_AND_STEP();
11280  div_word(destval);
11281  }
11282  break;
11283  case 7:
11284  if (M.x86.mode & SYSMODE_PREFIX_DATA)
11285  {
11286  u32 destval;
11287 
11288  DECODE_PRINTF("IDIV\tDWORD PTR ");
11289  destoffset = decode_rm00_address(rl);
11290  DECODE_PRINTF("\n");
11291  destval = fetch_data_long(destoffset);
11292  TRACE_AND_STEP();
11293  idiv_long(destval);
11294  }
11295  else
11296  {
11297  u16 destval;
11298 
11299  DECODE_PRINTF("IDIV\tWORD PTR ");
11300  destoffset = decode_rm00_address(rl);
11301  DECODE_PRINTF("\n");
11302  destval = fetch_data_word(destoffset);
11303  TRACE_AND_STEP();
11304  idiv_word(destval);
11305  }
11306  break;
11307  }
11308  break; /* end mod==00 */
11309  case 1: /* mod=01 */
11310  switch (rh)
11311  {
11312  case 0: /* test word imm */
11313  if (M.x86.mode & SYSMODE_PREFIX_DATA)
11314  {
11315  u32 destval, srcval;
11316 
11317  DECODE_PRINTF("TEST\tDWORD PTR ");
11318  destoffset = decode_rm01_address(rl);
11319  DECODE_PRINTF(",");
11320  srcval = fetch_long_imm();
11321  DECODE_PRINTF2("%x\n", srcval);
11322  destval = fetch_data_long(destoffset);
11323  TRACE_AND_STEP();
11324  test_long(destval, srcval);
11325  }
11326  else
11327  {
11328  u16 destval, srcval;
11329 
11330  DECODE_PRINTF("TEST\tWORD PTR ");
11331  destoffset = decode_rm01_address(rl);
11332  DECODE_PRINTF(",");
11333  srcval = fetch_word_imm();
11334  DECODE_PRINTF2("%x\n", srcval);
11335  destval = fetch_data_word(destoffset);
11336  TRACE_AND_STEP();
11337  test_word(destval, srcval);
11338  }
11339  break;
11340  case 1:
11341  DECODE_PRINTF("ILLEGAL OP MOD=01 RH=01 OP=F6\n");
11342  HALT_SYS();
11343  break;
11344  case 2:
11345  if (M.x86.mode & SYSMODE_PREFIX_DATA)
11346  {
11347  u32 destval;
11348 
11349  DECODE_PRINTF("NOT\tDWORD PTR ");
11350  destoffset = decode_rm01_address(rl);
11351  DECODE_PRINTF("\n");
11352  destval = fetch_data_long(destoffset);
11353  TRACE_AND_STEP();
11354  destval = not_long(destval);
11355  store_data_long(destoffset, destval);
11356  }
11357  else
11358  {
11359  u16 destval;
11360 
11361  DECODE_PRINTF("NOT\tWORD PTR ");
11362  destoffset = decode_rm01_address(rl);
11363  DECODE_PRINTF("\n");
11364  destval = fetch_data_word(destoffset);
11365  TRACE_AND_STEP();
11366  destval = not_word(destval);
11367  store_data_word(destoffset, destval);
11368  }
11369  break;
11370  case 3:
11371  if (M.x86.mode & SYSMODE_PREFIX_DATA)
11372  {
11373  u32 destval;
11374 
11375  DECODE_PRINTF("NEG\tDWORD PTR ");
11376  destoffset = decode_rm01_address(rl);
11377  DECODE_PRINTF("\n");
11378  destval = fetch_data_long(destoffset);
11379  TRACE_AND_STEP();
11380  destval = neg_long(destval);
11381  store_data_long(destoffset, destval);
11382  }
11383  else
11384  {
11385  u16 destval;
11386 
11387  DECODE_PRINTF("NEG\tWORD PTR ");
11388  destoffset = decode_rm01_address(rl);
11389  DECODE_PRINTF("\n");
11390  destval = fetch_data_word(destoffset);
11391  TRACE_AND_STEP();
11392  destval = neg_word(destval);
11393  store_data_word(destoffset, destval);
11394  }
11395  break;
11396  case 4:
11397  if (M.x86.mode & SYSMODE_PREFIX_DATA)
11398  {
11399  u32 destval;
11400 
11401  DECODE_PRINTF("MUL\tDWORD PTR ");
11402  destoffset = decode_rm01_address(rl);
11403  DECODE_PRINTF("\n");
11404  destval = fetch_data_long(destoffset);
11405  TRACE_AND_STEP();
11406  mul_long(destval);
11407  }
11408  else
11409  {
11410  u16 destval;
11411 
11412  DECODE_PRINTF("MUL\tWORD PTR ");
11413  destoffset = decode_rm01_address(rl);
11414  DECODE_PRINTF("\n");
11415  destval = fetch_data_word(destoffset);
11416  TRACE_AND_STEP();
11417  mul_word(destval);
11418  }
11419  break;
11420  case 5:
11421  if (M.x86.mode & SYSMODE_PREFIX_DATA)
11422  {
11423  u32 destval;
11424 
11425  DECODE_PRINTF("IMUL\tDWORD PTR ");
11426  destoffset = decode_rm01_address(rl);
11427  DECODE_PRINTF("\n");
11428  destval = fetch_data_long(destoffset);
11429  TRACE_AND_STEP();
11430  imul_long(destval);
11431  }
11432  else
11433  {
11434  u16 destval;
11435 
11436  DECODE_PRINTF("IMUL\tWORD PTR ");
11437  destoffset = decode_rm01_address(rl);
11438  DECODE_PRINTF("\n");
11439  destval = fetch_data_word(destoffset);
11440  TRACE_AND_STEP();
11441  imul_word(destval);
11442  }
11443  break;
11444  case 6:
11445  if (M.x86.mode & SYSMODE_PREFIX_DATA)
11446  {
11447  u32 destval;
11448 
11449  DECODE_PRINTF("DIV\tDWORD PTR ");
11450  destoffset = decode_rm01_address(rl);
11451  DECODE_PRINTF("\n");
11452  destval = fetch_data_long(destoffset);
11453  TRACE_AND_STEP();
11454  div_long(destval);
11455  }
11456  else
11457  {
11458  u16 destval;
11459 
11460  DECODE_PRINTF("DIV\tWORD PTR ");
11461  destoffset = decode_rm01_address(rl);
11462  DECODE_PRINTF("\n");
11463  destval = fetch_data_word(destoffset);
11464  TRACE_AND_STEP();
11465  div_word(destval);
11466  }
11467  break;
11468  case 7:
11469  if (M.x86.mode & SYSMODE_PREFIX_DATA)
11470  {
11471  u32 destval;
11472 
11473  DECODE_PRINTF("IDIV\tDWORD PTR ");
11474  destoffset = decode_rm01_address(rl);
11475  DECODE_PRINTF("\n");
11476  destval = fetch_data_long(destoffset);
11477  TRACE_AND_STEP();
11478  idiv_long(destval);
11479  }
11480  else
11481  {
11482  u16 destval;
11483 
11484  DECODE_PRINTF("IDIV\tWORD PTR ");
11485  destoffset = decode_rm01_address(rl);
11486  DECODE_PRINTF("\n");
11487  destval = fetch_data_word(destoffset);
11488  TRACE_AND_STEP();
11489  idiv_word(destval);
11490  }
11491  break;
11492  }
11493  break; /* end mod==01 */
11494  case 2: /* mod=10 */
11495  switch (rh)
11496  {
11497  case 0: /* test word imm */
11498  if (M.x86.mode & SYSMODE_PREFIX_DATA)
11499  {
11500  u32 destval, srcval;
11501 
11502  DECODE_PRINTF("TEST\tDWORD PTR ");
11503  destoffset = decode_rm10_address(rl);
11504  DECODE_PRINTF(",");
11505  srcval = fetch_long_imm();
11506  DECODE_PRINTF2("%x\n", srcval);
11507  destval = fetch_data_long(destoffset);
11508  TRACE_AND_STEP();
11509  test_long(destval, srcval);
11510  }
11511  else
11512  {
11513  u16 destval, srcval;
11514 
11515  DECODE_PRINTF("TEST\tWORD PTR ");
11516  destoffset = decode_rm10_address(rl);
11517  DECODE_PRINTF(",");
11518  srcval = fetch_word_imm();
11519  DECODE_PRINTF2("%x\n", srcval);
11520  destval = fetch_data_word(destoffset);
11521  TRACE_AND_STEP();
11522  test_word(destval, srcval);
11523  }
11524  break;
11525  case 1:
11526  DECODE_PRINTF("ILLEGAL OP MOD=10 RH=01 OP=F6\n");
11527  HALT_SYS();
11528  break;
11529  case 2:
11530  if (M.x86.mode & SYSMODE_PREFIX_DATA)
11531  {
11532  u32 destval;
11533 
11534  DECODE_PRINTF("NOT\tDWORD PTR ");
11535  destoffset = decode_rm10_address(rl);
11536  DECODE_PRINTF("\n");
11537  destval = fetch_data_long(destoffset);
11538  TRACE_AND_STEP();
11539  destval = not_long(destval);
11540  store_data_long(destoffset, destval);
11541  }
11542  else
11543  {
11544  u16 destval;
11545 
11546  DECODE_PRINTF("NOT\tWORD PTR ");
11547  destoffset = decode_rm10_address(rl);
11548  DECODE_PRINTF("\n");
11549  destval = fetch_data_word(destoffset);
11550  TRACE_AND_STEP();
11551  destval = not_word(destval);
11552  store_data_word(destoffset, destval);
11553  }
11554  break;
11555  case 3:
11556  if (M.x86.mode & SYSMODE_PREFIX_DATA)
11557  {
11558  u32 destval;
11559 
11560  DECODE_PRINTF("NEG\tDWORD PTR ");
11561  destoffset = decode_rm10_address(rl);
11562  DECODE_PRINTF("\n");
11563  destval = fetch_data_long(destoffset);
11564  TRACE_AND_STEP();
11565  destval = neg_long(destval);
11566  store_data_long(destoffset, destval);
11567  }
11568  else
11569  {
11570  u16 destval;
11571 
11572  DECODE_PRINTF("NEG\tWORD PTR ");
11573  destoffset = decode_rm10_address(rl);
11574  DECODE_PRINTF("\n");
11575  destval = fetch_data_word(destoffset);
11576  TRACE_AND_STEP();
11577  destval = neg_word(destval);
11578  store_data_word(destoffset, destval);
11579  }
11580  break;
11581  case 4:
11582  if (M.x86.mode & SYSMODE_PREFIX_DATA)
11583  {
11584  u32 destval;
11585 
11586  DECODE_PRINTF("MUL\tDWORD PTR ");
11587  destoffset = decode_rm10_address(rl);
11588  DECODE_PRINTF("\n");
11589  destval = fetch_data_long(destoffset);
11590  TRACE_AND_STEP();
11591  mul_long(destval);
11592  }
11593  else
11594  {
11595  u16 destval;
11596 
11597  DECODE_PRINTF("MUL\tWORD PTR ");
11598  destoffset = decode_rm10_address(rl);
11599  DECODE_PRINTF("\n");
11600  destval = fetch_data_word(destoffset);
11601  TRACE_AND_STEP();
11602  mul_word(destval);
11603  }
11604  break;
11605  case 5:
11606  if (M.x86.mode & SYSMODE_PREFIX_DATA)
11607  {
11608  u32 destval;
11609 
11610  DECODE_PRINTF("IMUL\tDWORD PTR ");
11611  destoffset = decode_rm10_address(rl);
11612  DECODE_PRINTF("\n");
11613  destval = fetch_data_long(destoffset);
11614  TRACE_AND_STEP();
11615  imul_long(destval);
11616  }
11617  else
11618  {
11619  u16 destval;
11620 
11621  DECODE_PRINTF("IMUL\tWORD PTR ");
11622  destoffset = decode_rm10_address(rl);
11623  DECODE_PRINTF("\n");
11624  destval = fetch_data_word(destoffset);
11625  TRACE_AND_STEP();
11626  imul_word(destval);
11627  }
11628  break;
11629  case 6:
11630  if (M.x86.mode & SYSMODE_PREFIX_DATA)
11631  {
11632  u32 destval;
11633 
11634  DECODE_PRINTF("DIV\tDWORD PTR ");
11635  destoffset = decode_rm10_address(rl);
11636  DECODE_PRINTF("\n");
11637  destval = fetch_data_long(destoffset);
11638  TRACE_AND_STEP();
11639  div_long(destval);
11640  }
11641  else
11642  {
11643  u16 destval;
11644 
11645  DECODE_PRINTF("DIV\tWORD PTR ");
11646  destoffset = decode_rm10_address(rl);
11647  DECODE_PRINTF("\n");
11648  destval = fetch_data_word(destoffset);
11649  TRACE_AND_STEP();
11650  div_word(destval);
11651  }
11652  break;
11653  case 7:
11654  if (M.x86.mode & SYSMODE_PREFIX_DATA)
11655  {
11656  u32 destval;
11657 
11658  DECODE_PRINTF("IDIV\tDWORD PTR ");
11659  destoffset = decode_rm10_address(rl);
11660  DECODE_PRINTF("\n");
11661  destval = fetch_data_long(destoffset);
11662  TRACE_AND_STEP();
11663  idiv_long(destval);
11664  }
11665  else
11666  {
11667  u16 destval;
11668 
11669  DECODE_PRINTF("IDIV\tWORD PTR ");
11670  destoffset = decode_rm10_address(rl);
11671  DECODE_PRINTF("\n");
11672  destval = fetch_data_word(destoffset);
11673  TRACE_AND_STEP();
11674  idiv_word(destval);
11675  }
11676  break;
11677  }
11678  break; /* end mod==10 */
11679  case 3: /* mod=11 */
11680  switch (rh)
11681  {
11682  case 0: /* test word imm */
11683  if (M.x86.mode & SYSMODE_PREFIX_DATA)
11684  {
11685  u32 *destreg;
11686  u32 srcval;
11687 
11688  DECODE_PRINTF("TEST\t");
11689  destreg = DECODE_RM_LONG_REGISTER(rl);
11690  DECODE_PRINTF(",");
11691  srcval = fetch_long_imm();
11692  DECODE_PRINTF2("%x\n", srcval);
11693  TRACE_AND_STEP();
11694  test_long(*destreg, srcval);
11695  }
11696  else
11697  {
11698  u16 *destreg;
11699  u16 srcval;
11700 
11701  DECODE_PRINTF("TEST\t");
11702  destreg = DECODE_RM_WORD_REGISTER(rl);
11703  DECODE_PRINTF(",");
11704  srcval = fetch_word_imm();
11705  DECODE_PRINTF2("%x\n", srcval);
11706  TRACE_AND_STEP();
11707  test_word(*destreg, srcval);
11708  }
11709  break;
11710  case 1:
11711  DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
11712  HALT_SYS();
11713  break;
11714  case 2:
11715  if (M.x86.mode & SYSMODE_PREFIX_DATA)
11716  {
11717  u32 *destreg;
11718 
11719  DECODE_PRINTF("NOT\t");
11720  destreg = DECODE_RM_LONG_REGISTER(rl);
11721  DECODE_PRINTF("\n");
11722  TRACE_AND_STEP();
11723  *destreg = not_long(*destreg);
11724  }
11725  else
11726  {
11727  u16 *destreg;
11728 
11729  DECODE_PRINTF("NOT\t");
11730  destreg = DECODE_RM_WORD_REGISTER(rl);
11731  DECODE_PRINTF("\n");
11732  TRACE_AND_STEP();
11733  *destreg = not_word(*destreg);
11734  }
11735  break;
11736  case 3:
11737  if (M.x86.mode & SYSMODE_PREFIX_DATA)
11738  {
11739  u32 *destreg;
11740 
11741  DECODE_PRINTF("NEG\t");
11742  destreg = DECODE_RM_LONG_REGISTER(rl);
11743  DECODE_PRINTF("\n");
11744  TRACE_AND_STEP();
11745  *destreg = neg_long(*destreg);
11746  }
11747  else
11748  {
11749  u16 *destreg;
11750 
11751  DECODE_PRINTF("NEG\t");
11752  destreg = DECODE_RM_WORD_REGISTER(rl);
11753  DECODE_PRINTF("\n");
11754  TRACE_AND_STEP();
11755  *destreg = neg_word(*destreg);
11756  }
11757  break;
11758  case 4:
11759  if (M.x86.mode & SYSMODE_PREFIX_DATA)
11760  {
11761  u32 *destreg;
11762 
11763  DECODE_PRINTF("MUL\t");
11764  destreg = DECODE_RM_LONG_REGISTER(rl);
11765  DECODE_PRINTF("\n");
11766  TRACE_AND_STEP();
11767  mul_long(*destreg);
11768  }
11769  else
11770  {
11771  u16 *destreg;
11772 
11773  DECODE_PRINTF("MUL\t");
11774  destreg = DECODE_RM_WORD_REGISTER(rl);
11775  DECODE_PRINTF("\n");
11776  TRACE_AND_STEP();
11777  mul_word(*destreg);
11778  }
11779  break;
11780  case 5:
11781  if (M.x86.mode & SYSMODE_PREFIX_DATA)
11782  {
11783  u32 *destreg;
11784 
11785  DECODE_PRINTF("IMUL\t");
11786  destreg = DECODE_RM_LONG_REGISTER(rl);
11787  DECODE_PRINTF("\n");
11788  TRACE_AND_STEP();
11789  imul_long(*destreg);
11790  }
11791  else
11792  {
11793  u16 *destreg;
11794 
11795  DECODE_PRINTF("IMUL\t");
11796  destreg = DECODE_RM_WORD_REGISTER(rl);
11797  DECODE_PRINTF("\n");
11798  TRACE_AND_STEP();
11799  imul_word(*destreg);
11800  }
11801  break;
11802  case 6:
11803  if (M.x86.mode & SYSMODE_PREFIX_DATA)
11804  {
11805  u32 *destreg;
11806 
11807  DECODE_PRINTF("DIV\t");
11808  destreg = DECODE_RM_LONG_REGISTER(rl);
11809  DECODE_PRINTF("\n");
11810  TRACE_AND_STEP();
11811  div_long(*destreg);
11812  }
11813  else
11814  {
11815  u16 *destreg;
11816 
11817  DECODE_PRINTF("DIV\t");
11818  destreg = DECODE_RM_WORD_REGISTER(rl);
11819  DECODE_PRINTF("\n");
11820  TRACE_AND_STEP();
11821  div_word(*destreg);
11822  }
11823  break;
11824  case 7:
11825  if (M.x86.mode & SYSMODE_PREFIX_DATA)
11826  {
11827  u32 *destreg;
11828 
11829  DECODE_PRINTF("IDIV\t");
11830  destreg = DECODE_RM_LONG_REGISTER(rl);
11831  DECODE_PRINTF("\n");
11832  TRACE_AND_STEP();
11833  idiv_long(*destreg);
11834  }
11835  else
11836  {
11837  u16 *destreg;
11838 
11839  DECODE_PRINTF("IDIV\t");
11840  destreg = DECODE_RM_WORD_REGISTER(rl);
11841  DECODE_PRINTF("\n");
11842  TRACE_AND_STEP();
11843  idiv_word(*destreg);
11844  }
11845  break;
11846  }
11847  break; /* end mod==11 */
11848  }
11849  DECODE_CLEAR_SEGOVR();
11850  END_OF_INSTR();
11851 }
11852 
11853 /****************************************************************************
11854 REMARKS:
11855 Handles opcode 0xf8
11856 ****************************************************************************/
11857 static void x86emuOp_clc(u8 X86EMU_UNUSED(op1))
11858 {
11859  /* clear the carry flag. */
11860  START_OF_INSTR();
11861  DECODE_PRINTF("CLC\n");
11862  TRACE_AND_STEP();
11863  CLEAR_FLAG(F_CF);
11864  DECODE_CLEAR_SEGOVR();
11865  END_OF_INSTR();
11866 }
11867 
11868 /****************************************************************************
11869 REMARKS:
11870 Handles opcode 0xf9
11871 ****************************************************************************/
11872 static void x86emuOp_stc(u8 X86EMU_UNUSED(op1))
11873 {
11874  /* set the carry flag. */
11875  START_OF_INSTR();
11876  DECODE_PRINTF("STC\n");
11877  TRACE_AND_STEP();
11878  SET_FLAG(F_CF);
11879  DECODE_CLEAR_SEGOVR();
11880  END_OF_INSTR();
11881 }
11882 
11883 /****************************************************************************
11884 REMARKS:
11885 Handles opcode 0xfa
11886 ****************************************************************************/
11887 static void x86emuOp_cli(u8 X86EMU_UNUSED(op1))
11888 {
11889  /* clear interrupts. */
11890  START_OF_INSTR();
11891  DECODE_PRINTF("CLI\n");
11892  TRACE_AND_STEP();
11893  CLEAR_FLAG(F_IF);
11894  DECODE_CLEAR_SEGOVR();
11895  END_OF_INSTR();
11896 }
11897 
11898 /****************************************************************************
11899 REMARKS:
11900 Handles opcode 0xfb
11901 ****************************************************************************/
11902 static void x86emuOp_sti(u8 X86EMU_UNUSED(op1))
11903 {
11904  /* enable interrupts. */
11905  START_OF_INSTR();
11906  DECODE_PRINTF("STI\n");
11907  TRACE_AND_STEP();
11908  SET_FLAG(F_IF);
11909  DECODE_CLEAR_SEGOVR();
11910  END_OF_INSTR();
11911 }
11912 
11913 /****************************************************************************
11914 REMARKS:
11915 Handles opcode 0xfc
11916 ****************************************************************************/
11917 static void x86emuOp_cld(u8 X86EMU_UNUSED(op1))
11918 {
11919  /* clear interrupts. */
11920  START_OF_INSTR();
11921  DECODE_PRINTF("CLD\n");
11922  TRACE_AND_STEP();
11923  CLEAR_FLAG(F_DF);
11924  DECODE_CLEAR_SEGOVR();
11925  END_OF_INSTR();
11926 }
11927 
11928 /****************************************************************************
11929 REMARKS:
11930 Handles opcode 0xfd
11931 ****************************************************************************/
11932 static void x86emuOp_std(u8 X86EMU_UNUSED(op1))
11933 {
11934  /* clear interrupts. */
11935  START_OF_INSTR();
11936  DECODE_PRINTF("STD\n");
11937  TRACE_AND_STEP();
11938  SET_FLAG(F_DF);
11939  DECODE_CLEAR_SEGOVR();
11940  END_OF_INSTR();
11941 }
11942 
11943 /****************************************************************************
11944 REMARKS:
11945 Handles opcode 0xfe
11946 ****************************************************************************/
11947 static void x86emuOp_opcFE_byte_RM(u8 X86EMU_UNUSED(op1))
11948 {
11949  int mod, rh, rl;
11950  u8 destval;
11951  uint destoffset;
11952  u8 *destreg;
11953 
11954  /* Yet another special case instruction. */
11955  START_OF_INSTR();
11956  FETCH_DECODE_MODRM(mod, rh, rl);
11957 #ifdef DEBUG
11958  if (DEBUG_DECODE())
11959  {
11960  /* XXX DECODE_PRINTF may be changed to something more
11961  general, so that it is important to leave the strings
11962  in the same format, even though the result is that the
11963  above test is done twice. */
11964 
11965  switch (rh)
11966  {
11967  case 0:
11968  DECODE_PRINTF("INC\t");
11969  break;
11970  case 1:
11971  DECODE_PRINTF("DEC\t");
11972  break;
11973  case 2:
11974  case 3:
11975  case 4:
11976  case 5:
11977  case 6:
11978  case 7:
11979  DECODE_PRINTF2("ILLEGAL OP MAJOR OP 0xFE MINOR OP %x \n", mod);
11980  HALT_SYS();
11981  break;
11982  }
11983  }
11984 #endif
11985  switch (mod)
11986  {
11987  case 0:
11988  DECODE_PRINTF("BYTE PTR ");
11989  destoffset = decode_rm00_address(rl);
11990  DECODE_PRINTF("\n");
11991  switch (rh)
11992  {
11993  case 0: /* inc word ptr ... */
11994  destval = fetch_data_byte(destoffset);
11995  TRACE_AND_STEP();
11996  destval = inc_byte(destval);
11997  store_data_byte(destoffset, destval);
11998  break;
11999  case 1: /* dec word ptr ... */
12000  destval = fetch_data_byte(destoffset);
12001  TRACE_AND_STEP();
12002  destval = dec_byte(destval);
12003  store_data_byte(destoffset, destval);
12004  break;
12005  }
12006  break;
12007  case 1:
12008  DECODE_PRINTF("BYTE PTR ");
12009  destoffset = decode_rm01_address(rl);
12010  DECODE_PRINTF("\n");
12011  switch (rh)
12012  {
12013  case 0:
12014  destval = fetch_data_byte(destoffset);
12015  TRACE_AND_STEP();
12016  destval = inc_byte(destval);
12017  store_data_byte(destoffset, destval);
12018  break;
12019  case 1:
12020  destval = fetch_data_byte(destoffset);
12021  TRACE_AND_STEP();
12022  destval = dec_byte(destval);
12023  store_data_byte(destoffset, destval);
12024  break;
12025  }
12026  break;
12027  case 2:
12028  DECODE_PRINTF("BYTE PTR ");
12029  destoffset = decode_rm10_address(rl);
12030  DECODE_PRINTF("\n");
12031  switch (rh)
12032  {
12033  case 0:
12034  destval = fetch_data_byte(destoffset);
12035  TRACE_AND_STEP();
12036  destval = inc_byte(destval);
12037  store_data_byte(destoffset, destval);
12038  break;
12039  case 1:
12040  destval = fetch_data_byte(destoffset);
12041  TRACE_AND_STEP();
12042  destval = dec_byte(destval);
12043  store_data_byte(destoffset, destval);
12044  break;
12045  }
12046  break;
12047  case 3:
12048  destreg = DECODE_RM_BYTE_REGISTER(rl);
12049  DECODE_PRINTF("\n");
12050  switch (rh)
12051  {
12052  case 0:
12053  TRACE_AND_STEP();
12054  *destreg = inc_byte(*destreg);
12055  break;
12056  case 1:
12057  TRACE_AND_STEP();
12058  *destreg = dec_byte(*destreg);
12059  break;
12060  }
12061  break;
12062  }
12063  DECODE_CLEAR_SEGOVR();
12064  END_OF_INSTR();
12065 }
12066 
12067 /****************************************************************************
12068 REMARKS:
12069 Handles opcode 0xff
12070 ****************************************************************************/
12071 static void x86emuOp_opcFF_word_RM(u8 X86EMU_UNUSED(op1))
12072 {
12073  int mod, rh, rl;
12074  uint destoffset = 0;
12075  u16 *destreg;
12076  u16 destval, destval2;
12077 
12078  /* Yet another special case instruction. */
12079  START_OF_INSTR();
12080  FETCH_DECODE_MODRM(mod, rh, rl);
12081 #ifdef DEBUG
12082  if (DEBUG_DECODE())
12083  {
12084  /* XXX DECODE_PRINTF may be changed to something more
12085  general, so that it is important to leave the strings
12086  in the same format, even though the result is that the
12087  above test is done twice. */
12088 
12089  switch (rh)
12090  {
12091  case 0:
12092  if (M.x86.mode & SYSMODE_PREFIX_DATA)
12093  {
12094  DECODE_PRINTF("INC\tDWORD PTR ");
12095  }
12096  else
12097  {
12098  DECODE_PRINTF("INC\tWORD PTR ");
12099  }
12100  break;
12101  case 1:
12102  if (M.x86.mode & SYSMODE_PREFIX_DATA)
12103  {
12104  DECODE_PRINTF("DEC\tDWORD PTR ");
12105  }
12106  else
12107  {
12108  DECODE_PRINTF("DEC\tWORD PTR ");
12109  }
12110  break;
12111  case 2:
12112  DECODE_PRINTF("CALL\t");
12113  break;
12114  case 3:
12115  DECODE_PRINTF("CALL\tFAR ");
12116  break;
12117  case 4:
12118  DECODE_PRINTF("JMP\t");
12119  break;
12120  case 5:
12121  DECODE_PRINTF("JMP\tFAR ");
12122  break;
12123  case 6:
12124  DECODE_PRINTF("PUSH\t");
12125  break;
12126  case 7:
12127  DECODE_PRINTF("ILLEGAL DECODING OF OPCODE FF\t");
12128  HALT_SYS();
12129  break;
12130  }
12131  }
12132 #endif
12133  switch (mod)
12134  {
12135  case 0:
12136  destoffset = decode_rm00_address(rl);
12137  DECODE_PRINTF("\n");
12138  switch (rh)
12139  {
12140  case 0: /* inc word ptr ... */
12141  if (M.x86.mode & SYSMODE_PREFIX_DATA)
12142  {
12143  u32 destval;
12144 
12145  destval = fetch_data_long(destoffset);
12146  TRACE_AND_STEP();
12147  destval = inc_long(destval);
12148  store_data_long(destoffset, destval);
12149  }
12150  else
12151  {
12152  u16 destval;
12153 
12154  destval = fetch_data_word(destoffset);
12155  TRACE_AND_STEP();
12156  destval = inc_word(destval);
12157  store_data_word(destoffset, destval);
12158  }
12159  break;
12160  case 1: /* dec word ptr ... */
12161  if (M.x86.mode & SYSMODE_PREFIX_DATA)
12162  {
12163  u32 destval;
12164 
12165  destval = fetch_data_long(destoffset);
12166  TRACE_AND_STEP();
12167  destval = dec_long(destval);
12168  store_data_long(destoffset, destval);
12169  }
12170  else
12171  {
12172  u16 destval;
12173 
12174  destval = fetch_data_word(destoffset);
12175  TRACE_AND_STEP();
12176  destval = dec_word(destval);
12177  store_data_word(destoffset, destval);
12178  }
12179  break;
12180  case 2: /* call word ptr ... */
12181  destval = fetch_data_word(destoffset);
12182  TRACE_AND_STEP();
12183  push_word(M.x86.R_IP);
12184  M.x86.R_IP = destval;
12185  break;
12186  case 3: /* call far ptr ... */
12187  destval = fetch_data_word(destoffset);
12188  destval2 = fetch_data_word(destoffset + 2);
12189  TRACE_AND_STEP();
12190  push_word(M.x86.R_CS);
12191  M.x86.R_CS = destval2;
12192  push_word(M.x86.R_IP);
12193  M.x86.R_IP = destval;
12194  break;
12195  case 4: /* jmp word ptr ... */
12196  destval = fetch_data_word(destoffset);
12197  TRACE_AND_STEP();
12198  M.x86.R_IP = destval;
12199  break;
12200  case 5: /* jmp far ptr ... */
12201  destval = fetch_data_word(destoffset);
12202  destval2 = fetch_data_word(destoffset + 2);
12203  TRACE_AND_STEP();
12204  M.x86.R_IP = destval;
12205  M.x86.R_CS = destval2;
12206  break;
12207  case 6: /* push word ptr ... */
12208  if (M.x86.mode & SYSMODE_PREFIX_DATA)
12209  {
12210  u32 destval;
12211 
12212  destval = fetch_data_long(destoffset);
12213  TRACE_AND_STEP();
12214  push_long(destval);
12215  }
12216  else
12217  {
12218  u16 destval;
12219 
12220  destval = fetch_data_word(destoffset);
12221  TRACE_AND_STEP();
12222  push_word(destval);
12223  }
12224  break;
12225  }
12226  break;
12227  case 1:
12228  destoffset = decode_rm01_address(rl);
12229  DECODE_PRINTF("\n");
12230  switch (rh)
12231  {
12232  case 0:
12233  if (M.x86.mode & SYSMODE_PREFIX_DATA)
12234  {
12235  u32 destval;
12236 
12237  destval = fetch_data_long(destoffset);
12238  TRACE_AND_STEP();
12239  destval = inc_long(destval);
12240  store_data_long(destoffset, destval);
12241  }
12242  else
12243  {
12244  u16 destval;
12245 
12246  destval = fetch_data_word(destoffset);
12247  TRACE_AND_STEP();
12248  destval = inc_word(destval);
12249  store_data_word(destoffset, destval);
12250  }
12251  break;
12252  case 1:
12253  if (M.x86.mode & SYSMODE_PREFIX_DATA)
12254  {
12255  u32 destval;
12256 
12257  destval = fetch_data_long(destoffset);
12258  TRACE_AND_STEP();
12259  destval = dec_long(destval);
12260  store_data_long(destoffset, destval);
12261  }
12262  else
12263  {
12264  u16 destval;
12265 
12266  destval = fetch_data_word(destoffset);
12267  TRACE_AND_STEP();
12268  destval = dec_word(destval);
12269  store_data_word(destoffset, destval);
12270  }
12271  break;
12272  case 2: /* call word ptr ... */
12273  destval = fetch_data_word(destoffset);
12274  TRACE_AND_STEP();
12275  push_word(M.x86.R_IP);
12276  M.x86.R_IP = destval;
12277  break;
12278  case 3: /* call far ptr ... */
12279  destval = fetch_data_word(destoffset);
12280  destval2 = fetch_data_word(destoffset + 2);
12281  TRACE_AND_STEP();
12282  push_word(M.x86.R_CS);
12283  M.x86.R_CS = destval2;
12284  push_word(M.x86.R_IP);
12285  M.x86.R_IP = destval;
12286  break;
12287  case 4: /* jmp word ptr ... */
12288  destval = fetch_data_word(destoffset);
12289  TRACE_AND_STEP();
12290  M.x86.R_IP = destval;
12291  break;
12292  case 5: /* jmp far ptr ... */
12293  destval = fetch_data_word(destoffset);
12294  destval2 = fetch_data_word(destoffset + 2);
12295  TRACE_AND_STEP();
12296  M.x86.R_IP = destval;
12297  M.x86.R_CS = destval2;
12298  break;
12299  case 6: /* push word ptr ... */
12300  if (M.x86.mode & SYSMODE_PREFIX_DATA)
12301  {
12302  u32 destval;
12303 
12304  destval = fetch_data_long(destoffset);
12305  TRACE_AND_STEP();
12306  push_long(destval);
12307  }
12308  else
12309  {
12310  u16 destval;
12311 
12312  destval = fetch_data_word(destoffset);
12313  TRACE_AND_STEP();
12314  push_word(destval);
12315  }
12316  break;
12317  }
12318  break;
12319  case 2:
12320  destoffset = decode_rm10_address(rl);
12321  DECODE_PRINTF("\n");
12322  switch (rh)
12323  {
12324  case 0:
12325  if (M.x86.mode & SYSMODE_PREFIX_DATA)
12326  {
12327  u32 destval;
12328 
12329  destval = fetch_data_long(destoffset);
12330  TRACE_AND_STEP();
12331  destval = inc_long(destval);
12332  store_data_long(destoffset, destval);
12333  }
12334  else
12335  {
12336  u16 destval;
12337 
12338  destval = fetch_data_word(destoffset);
12339  TRACE_AND_STEP();
12340  destval = inc_word(destval);
12341  store_data_word(destoffset, destval);
12342  }
12343  break;
12344  case 1:
12345  if (M.x86.mode & SYSMODE_PREFIX_DATA)
12346  {
12347  u32 destval;
12348 
12349  destval = fetch_data_long(destoffset);
12350  TRACE_AND_STEP();
12351  destval = dec_long(destval);
12352  store_data_long(destoffset, destval);
12353  }
12354  else
12355  {
12356  u16 destval;
12357 
12358  destval = fetch_data_word(destoffset);
12359  TRACE_AND_STEP();
12360  destval = dec_word(destval);
12361  store_data_word(destoffset, destval);
12362  }
12363  break;
12364  case 2: /* call word ptr ... */
12365  destval = fetch_data_word(destoffset);
12366  TRACE_AND_STEP();
12367  push_word(M.x86.R_IP);
12368  M.x86.R_IP = destval;
12369  break;
12370  case 3: /* call far ptr ... */
12371  destval = fetch_data_word(destoffset);
12372  destval2 = fetch_data_word(destoffset + 2);
12373  TRACE_AND_STEP();
12374  push_word(M.x86.R_CS);
12375  M.x86.R_CS = destval2;
12376  push_word(M.x86.R_IP);
12377  M.x86.R_IP = destval;
12378  break;
12379  case 4: /* jmp word ptr ... */
12380  destval = fetch_data_word(destoffset);
12381  TRACE_AND_STEP();
12382  M.x86.R_IP = destval;
12383  break;
12384  case 5: /* jmp far ptr ... */
12385  destval = fetch_data_word(destoffset);
12386  destval2 = fetch_data_word(destoffset + 2);
12387  TRACE_AND_STEP();
12388  M.x86.R_IP = destval;
12389  M.x86.R_CS = destval2;
12390  break;
12391  case 6: /* push word ptr ... */
12392  if (M.x86.mode & SYSMODE_PREFIX_DATA)
12393  {
12394  u32 destval;
12395 
12396  destval = fetch_data_long(destoffset);
12397  TRACE_AND_STEP();
12398  push_long(destval);
12399  }
12400  else
12401  {
12402  u16 destval;
12403 
12404  destval = fetch_data_word(destoffset);
12405  TRACE_AND_STEP();
12406  push_word(destval);
12407  }
12408  break;
12409  }
12410  break;
12411  case 3:
12412  switch (rh)
12413  {
12414  case 0:
12415  if (M.x86.mode & SYSMODE_PREFIX_DATA)
12416  {
12417  u32 *destreg;
12418 
12419  destreg = DECODE_RM_LONG_REGISTER(rl);
12420  DECODE_PRINTF("\n");
12421  TRACE_AND_STEP();
12422  *destreg = inc_long(*destreg);
12423  }
12424  else
12425  {
12426  u16 *destreg;
12427 
12428  destreg = DECODE_RM_WORD_REGISTER(rl);
12429  DECODE_PRINTF("\n");
12430  TRACE_AND_STEP();
12431  *destreg = inc_word(*destreg);
12432  }
12433  break;
12434  case 1:
12435  if (M.x86.mode & SYSMODE_PREFIX_DATA)
12436  {
12437  u32 *destreg;
12438 
12439  destreg = DECODE_RM_LONG_REGISTER(rl);
12440  DECODE_PRINTF("\n");
12441  TRACE_AND_STEP();
12442  *destreg = dec_long(*destreg);
12443  }
12444  else
12445  {
12446  u16 *destreg;
12447 
12448  destreg = DECODE_RM_WORD_REGISTER(rl);
12449  DECODE_PRINTF("\n");
12450  TRACE_AND_STEP();
12451  *destreg = dec_word(*destreg);
12452  }
12453  break;
12454  case 2: /* call word ptr ... */
12455  destreg = DECODE_RM_WORD_REGISTER(rl);
12456  DECODE_PRINTF("\n");
12457  TRACE_AND_STEP();
12458  push_word(M.x86.R_IP);
12459  M.x86.R_IP = *destreg;
12460  break;
12461  case 3: /* jmp far ptr ... */
12462  DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n");
12463  TRACE_AND_STEP();
12464  HALT_SYS();
12465  break;
12466 
12467  case 4: /* jmp ... */
12468  destreg = DECODE_RM_WORD_REGISTER(rl);
12469  DECODE_PRINTF("\n");
12470  TRACE_AND_STEP();
12471  M.x86.R_IP = (u16)(*destreg);
12472  break;
12473  case 5: /* jmp far ptr ... */
12474  DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n");
12475  TRACE_AND_STEP();
12476  HALT_SYS();
12477  break;
12478  case 6:
12479  if (M.x86.mode & SYSMODE_PREFIX_DATA)
12480  {
12481  u32 *destreg;
12482 
12483  destreg = DECODE_RM_LONG_REGISTER(rl);
12484  DECODE_PRINTF("\n");
12485  TRACE_AND_STEP();
12486  push_long(*destreg);
12487  }
12488  else
12489  {
12490  u16 *destreg;
12491 
12492  destreg = DECODE_RM_WORD_REGISTER(rl);
12493  DECODE_PRINTF("\n");
12494  TRACE_AND_STEP();
12495  push_word(*destreg);
12496  }
12497  break;
12498  }
12499  break;
12500  }
12501  DECODE_CLEAR_SEGOVR();
12502  END_OF_INSTR();
12503 }
12504 
12505 /***************************************************************************
12506  * Single byte operation code table:
12507  **************************************************************************/
12508 void (*x86emu_optab[256])(u8) = {
12509  /* 0x00 */ x86emuOp_add_byte_RM_R,
12510  /* 0x01 */ x86emuOp_add_word_RM_R,
12511  /* 0x02 */ x86emuOp_add_byte_R_RM,
12512  /* 0x03 */ x86emuOp_add_word_R_RM,
12513  /* 0x04 */ x86emuOp_add_byte_AL_IMM,
12514  /* 0x05 */ x86emuOp_add_word_AX_IMM,
12515  /* 0x06 */ x86emuOp_push_ES,
12516  /* 0x07 */ x86emuOp_pop_ES,
12517 
12518  /* 0x08 */ x86emuOp_or_byte_RM_R,
12519  /* 0x09 */ x86emuOp_or_word_RM_R,
12520  /* 0x0a */ x86emuOp_or_byte_R_RM,
12521  /* 0x0b */ x86emuOp_or_word_R_RM,
12522  /* 0x0c */ x86emuOp_or_byte_AL_IMM,
12523  /* 0x0d */ x86emuOp_or_word_AX_IMM,
12524  /* 0x0e */ x86emuOp_push_CS,
12525  /* 0x0f */ x86emuOp_two_byte,
12526 
12527  /* 0x10 */ x86emuOp_adc_byte_RM_R,
12528  /* 0x11 */ x86emuOp_adc_word_RM_R,
12529  /* 0x12 */ x86emuOp_adc_byte_R_RM,
12530  /* 0x13 */ x86emuOp_adc_word_R_RM,
12531  /* 0x14 */ x86emuOp_adc_byte_AL_IMM,
12532  /* 0x15 */ x86emuOp_adc_word_AX_IMM,
12533  /* 0x16 */ x86emuOp_push_SS,
12534  /* 0x17 */ x86emuOp_pop_SS,
12535 
12536  /* 0x18 */ x86emuOp_sbb_byte_RM_R,
12537  /* 0x19 */ x86emuOp_sbb_word_RM_R,
12538  /* 0x1a */ x86emuOp_sbb_byte_R_RM,
12539  /* 0x1b */ x86emuOp_sbb_word_R_RM,
12540  /* 0x1c */ x86emuOp_sbb_byte_AL_IMM,
12541  /* 0x1d */ x86emuOp_sbb_word_AX_IMM,
12542  /* 0x1e */ x86emuOp_push_DS,
12543  /* 0x1f */ x86emuOp_pop_DS,
12544 
12545  /* 0x20 */ x86emuOp_and_byte_RM_R,
12546  /* 0x21 */ x86emuOp_and_word_RM_R,
12547  /* 0x22 */ x86emuOp_and_byte_R_RM,
12548  /* 0x23 */ x86emuOp_and_word_R_RM,
12549  /* 0x24 */ x86emuOp_and_byte_AL_IMM,
12550  /* 0x25 */ x86emuOp_and_word_AX_IMM,
12551  /* 0x26 */ x86emuOp_segovr_ES,
12552  /* 0x27 */ x86emuOp_daa,
12553 
12554  /* 0x28 */ x86emuOp_sub_byte_RM_R,
12555  /* 0x29 */ x86emuOp_sub_word_RM_R,
12556  /* 0x2a */ x86emuOp_sub_byte_R_RM,
12557  /* 0x2b */ x86emuOp_sub_word_R_RM,
12558  /* 0x2c */ x86emuOp_sub_byte_AL_IMM,
12559  /* 0x2d */ x86emuOp_sub_word_AX_IMM,
12560  /* 0x2e */ x86emuOp_segovr_CS,
12561  /* 0x2f */ x86emuOp_das,
12562 
12563  /* 0x30 */ x86emuOp_xor_byte_RM_R,
12564  /* 0x31 */ x86emuOp_xor_word_RM_R,
12565  /* 0x32 */ x86emuOp_xor_byte_R_RM,
12566  /* 0x33 */ x86emuOp_xor_word_R_RM,
12567  /* 0x34 */ x86emuOp_xor_byte_AL_IMM,
12568  /* 0x35 */ x86emuOp_xor_word_AX_IMM,
12569  /* 0x36 */ x86emuOp_segovr_SS,
12570  /* 0x37 */ x86emuOp_aaa,
12571 
12572  /* 0x38 */ x86emuOp_cmp_byte_RM_R,
12573  /* 0x39 */ x86emuOp_cmp_word_RM_R,
12574  /* 0x3a */ x86emuOp_cmp_byte_R_RM,
12575  /* 0x3b */ x86emuOp_cmp_word_R_RM,
12576  /* 0x3c */ x86emuOp_cmp_byte_AL_IMM,
12577  /* 0x3d */ x86emuOp_cmp_word_AX_IMM,
12578  /* 0x3e */ x86emuOp_segovr_DS,
12579  /* 0x3f */ x86emuOp_aas,
12580 
12581  /* 0x40 */ x86emuOp_inc_AX,
12582  /* 0x41 */ x86emuOp_inc_CX,
12583  /* 0x42 */ x86emuOp_inc_DX,
12584  /* 0x43 */ x86emuOp_inc_BX,
12585  /* 0x44 */ x86emuOp_inc_SP,
12586  /* 0x45 */ x86emuOp_inc_BP,
12587  /* 0x46 */ x86emuOp_inc_SI,
12588  /* 0x47 */ x86emuOp_inc_DI,
12589 
12590  /* 0x48 */ x86emuOp_dec_AX,
12591  /* 0x49 */ x86emuOp_dec_CX,
12592  /* 0x4a */ x86emuOp_dec_DX,
12593  /* 0x4b */ x86emuOp_dec_BX,
12594  /* 0x4c */ x86emuOp_dec_SP,
12595  /* 0x4d */ x86emuOp_dec_BP,
12596  /* 0x4e */ x86emuOp_dec_SI,
12597  /* 0x4f */ x86emuOp_dec_DI,
12598 
12599  /* 0x50 */ x86emuOp_push_AX,
12600  /* 0x51 */ x86emuOp_push_CX,
12601  /* 0x52 */ x86emuOp_push_DX,
12602  /* 0x53 */ x86emuOp_push_BX,
12603  /* 0x54 */ x86emuOp_push_SP,
12604  /* 0x55 */ x86emuOp_push_BP,
12605  /* 0x56 */ x86emuOp_push_SI,
12606  /* 0x57 */ x86emuOp_push_DI,
12607 
12608  /* 0x58 */ x86emuOp_pop_AX,
12609  /* 0x59 */ x86emuOp_pop_CX,
12610  /* 0x5a */ x86emuOp_pop_DX,
12611  /* 0x5b */ x86emuOp_pop_BX,
12612  /* 0x5c */ x86emuOp_pop_SP,
12613  /* 0x5d */ x86emuOp_pop_BP,
12614  /* 0x5e */ x86emuOp_pop_SI,
12615  /* 0x5f */ x86emuOp_pop_DI,
12616 
12617  /* 0x60 */ x86emuOp_push_all,
12618  /* 0x61 */ x86emuOp_pop_all,
12619  /* 0x62 */ x86emuOp_illegal_op, /* bound */
12620  /* 0x63 */ x86emuOp_illegal_op, /* arpl */
12621  /* 0x64 */ x86emuOp_segovr_FS,
12622  /* 0x65 */ x86emuOp_segovr_GS,
12623  /* 0x66 */ x86emuOp_prefix_data,
12624  /* 0x67 */ x86emuOp_prefix_addr,
12625 
12626  /* 0x68 */ x86emuOp_push_word_IMM,
12627  /* 0x69 */ x86emuOp_imul_word_IMM,
12628  /* 0x6a */ x86emuOp_push_byte_IMM,
12629  /* 0x6b */ x86emuOp_imul_byte_IMM,
12630  /* 0x6c */ x86emuOp_ins_byte,
12631  /* 0x6d */ x86emuOp_ins_word,
12632  /* 0x6e */ x86emuOp_outs_byte,
12633  /* 0x6f */ x86emuOp_outs_word,
12634 
12635  /* 0x70 */ x86emuOp_jump_near_O,
12636  /* 0x71 */ x86emuOp_jump_near_NO,
12637  /* 0x72 */ x86emuOp_jump_near_B,
12638  /* 0x73 */ x86emuOp_jump_near_NB,
12639  /* 0x74 */ x86emuOp_jump_near_Z,
12640  /* 0x75 */ x86emuOp_jump_near_NZ,
12641  /* 0x76 */ x86emuOp_jump_near_BE,
12642  /* 0x77 */ x86emuOp_jump_near_NBE,
12643 
12644  /* 0x78 */ x86emuOp_jump_near_S,
12645  /* 0x79 */ x86emuOp_jump_near_NS,
12646  /* 0x7a */ x86emuOp_jump_near_P,
12647  /* 0x7b */ x86emuOp_jump_near_NP,
12648  /* 0x7c */ x86emuOp_jump_near_L,
12649  /* 0x7d */ x86emuOp_jump_near_NL,
12650  /* 0x7e */ x86emuOp_jump_near_LE,
12651  /* 0x7f */ x86emuOp_jump_near_NLE,
12652 
12653  /* 0x80 */ x86emuOp_opc80_byte_RM_IMM,
12654  /* 0x81 */ x86emuOp_opc81_word_RM_IMM,
12655  /* 0x82 */ x86emuOp_opc82_byte_RM_IMM,
12656  /* 0x83 */ x86emuOp_opc83_word_RM_IMM,
12657  /* 0x84 */ x86emuOp_test_byte_RM_R,
12658  /* 0x85 */ x86emuOp_test_word_RM_R,
12659  /* 0x86 */ x86emuOp_xchg_byte_RM_R,
12660  /* 0x87 */ x86emuOp_xchg_word_RM_R,
12661 
12662  /* 0x88 */ x86emuOp_mov_byte_RM_R,
12663  /* 0x89 */ x86emuOp_mov_word_RM_R,
12664  /* 0x8a */ x86emuOp_mov_byte_R_RM,
12665  /* 0x8b */ x86emuOp_mov_word_R_RM,
12666  /* 0x8c */ x86emuOp_mov_word_RM_SR,
12667  /* 0x8d */ x86emuOp_lea_word_R_M,
12668  /* 0x8e */ x86emuOp_mov_word_SR_RM,
12669  /* 0x8f */ x86emuOp_pop_RM,
12670 
12671  /* 0x90 */ x86emuOp_nop,
12672  /* 0x91 */ x86emuOp_xchg_word_AX_CX,
12673  /* 0x92 */ x86emuOp_xchg_word_AX_DX,
12674  /* 0x93 */ x86emuOp_xchg_word_AX_BX,
12675  /* 0x94 */ x86emuOp_xchg_word_AX_SP,
12676  /* 0x95 */ x86emuOp_xchg_word_AX_BP,
12677  /* 0x96 */ x86emuOp_xchg_word_AX_SI,
12678  /* 0x97 */ x86emuOp_xchg_word_AX_DI,
12679 
12680  /* 0x98 */ x86emuOp_cbw,
12681  /* 0x99 */ x86emuOp_cwd,
12682  /* 0x9a */ x86emuOp_call_far_IMM,
12683  /* 0x9b */ x86emuOp_wait,
12684  /* 0x9c */ x86emuOp_pushf_word,
12685  /* 0x9d */ x86emuOp_popf_word,
12686  /* 0x9e */ x86emuOp_sahf,
12687  /* 0x9f */ x86emuOp_lahf,
12688 
12689  /* 0xa0 */ x86emuOp_mov_AL_M_IMM,
12690  /* 0xa1 */ x86emuOp_mov_AX_M_IMM,
12691  /* 0xa2 */ x86emuOp_mov_M_AL_IMM,
12692  /* 0xa3 */ x86emuOp_mov_M_AX_IMM,
12693  /* 0xa4 */ x86emuOp_movs_byte,
12694  /* 0xa5 */ x86emuOp_movs_word,
12695  /* 0xa6 */ x86emuOp_cmps_byte,
12696  /* 0xa7 */ x86emuOp_cmps_word,
12697  /* 0xa8 */ x86emuOp_test_AL_IMM,
12698  /* 0xa9 */ x86emuOp_test_AX_IMM,
12699  /* 0xaa */ x86emuOp_stos_byte,
12700  /* 0xab */ x86emuOp_stos_word,
12701  /* 0xac */ x86emuOp_lods_byte,
12702  /* 0xad */ x86emuOp_lods_word,
12703  /* 0xac */ x86emuOp_scas_byte,
12704  /* 0xad */ x86emuOp_scas_word,
12705 
12706  /* 0xb0 */ x86emuOp_mov_byte_AL_IMM,
12707  /* 0xb1 */ x86emuOp_mov_byte_CL_IMM,
12708  /* 0xb2 */ x86emuOp_mov_byte_DL_IMM,
12709  /* 0xb3 */ x86emuOp_mov_byte_BL_IMM,
12710  /* 0xb4 */ x86emuOp_mov_byte_AH_IMM,
12711  /* 0xb5 */ x86emuOp_mov_byte_CH_IMM,
12712  /* 0xb6 */ x86emuOp_mov_byte_DH_IMM,
12713  /* 0xb7 */ x86emuOp_mov_byte_BH_IMM,
12714 
12715  /* 0xb8 */ x86emuOp_mov_word_AX_IMM,
12716  /* 0xb9 */ x86emuOp_mov_word_CX_IMM,
12717  /* 0xba */ x86emuOp_mov_word_DX_IMM,
12718  /* 0xbb */ x86emuOp_mov_word_BX_IMM,
12719  /* 0xbc */ x86emuOp_mov_word_SP_IMM,
12720  /* 0xbd */ x86emuOp_mov_word_BP_IMM,
12721  /* 0xbe */ x86emuOp_mov_word_SI_IMM,
12722  /* 0xbf */ x86emuOp_mov_word_DI_IMM,
12723 
12724  /* 0xc0 */ x86emuOp_opcC0_byte_RM_MEM,
12725  /* 0xc1 */ x86emuOp_opcC1_word_RM_MEM,
12726  /* 0xc2 */ x86emuOp_ret_near_IMM,
12727  /* 0xc3 */ x86emuOp_ret_near,
12728  /* 0xc4 */ x86emuOp_les_R_IMM,
12729  /* 0xc5 */ x86emuOp_lds_R_IMM,
12730  /* 0xc6 */ x86emuOp_mov_byte_RM_IMM,
12731  /* 0xc7 */ x86emuOp_mov_word_RM_IMM,
12732  /* 0xc8 */ x86emuOp_enter,
12733  /* 0xc9 */ x86emuOp_leave,
12734  /* 0xca */ x86emuOp_ret_far_IMM,
12735  /* 0xcb */ x86emuOp_ret_far,
12736  /* 0xcc */ x86emuOp_int3,
12737  /* 0xcd */ x86emuOp_int_IMM,
12738  /* 0xce */ x86emuOp_into,
12739  /* 0xcf */ x86emuOp_iret,
12740 
12741  /* 0xd0 */ x86emuOp_opcD0_byte_RM_1,
12742  /* 0xd1 */ x86emuOp_opcD1_word_RM_1,
12743  /* 0xd2 */ x86emuOp_opcD2_byte_RM_CL,
12744  /* 0xd3 */ x86emuOp_opcD3_word_RM_CL,
12745  /* 0xd4 */ x86emuOp_aam,
12746  /* 0xd5 */ x86emuOp_aad,
12747  /* 0xd6 */ x86emuOp_illegal_op, /* Undocumented SETALC instruction */
12748  /* 0xd7 */ x86emuOp_xlat,
12749  /* 0xd8 */ x86emuOp_esc_coprocess_d8,
12750  /* 0xd9 */ x86emuOp_esc_coprocess_d9,
12751  /* 0xda */ x86emuOp_esc_coprocess_da,
12752  /* 0xdb */ x86emuOp_esc_coprocess_db,
12753  /* 0xdc */ x86emuOp_esc_coprocess_dc,
12754  /* 0xdd */ x86emuOp_esc_coprocess_dd,
12755  /* 0xde */ x86emuOp_esc_coprocess_de,
12756  /* 0xdf */ x86emuOp_esc_coprocess_df,
12757 
12758  /* 0xe0 */ x86emuOp_loopne,
12759  /* 0xe1 */ x86emuOp_loope,
12760  /* 0xe2 */ x86emuOp_loop,
12761  /* 0xe3 */ x86emuOp_jcxz,
12762  /* 0xe4 */ x86emuOp_in_byte_AL_IMM,
12763  /* 0xe5 */ x86emuOp_in_word_AX_IMM,
12764  /* 0xe6 */ x86emuOp_out_byte_IMM_AL,
12765  /* 0xe7 */ x86emuOp_out_word_IMM_AX,
12766 
12767  /* 0xe8 */ x86emuOp_call_near_IMM,
12768  /* 0xe9 */ x86emuOp_jump_near_IMM,
12769  /* 0xea */ x86emuOp_jump_far_IMM,
12770  /* 0xeb */ x86emuOp_jump_byte_IMM,
12771  /* 0xec */ x86emuOp_in_byte_AL_DX,
12772  /* 0xed */ x86emuOp_in_word_AX_DX,
12773  /* 0xee */ x86emuOp_out_byte_DX_AL,
12774  /* 0xef */ x86emuOp_out_word_DX_AX,
12775 
12776  /* 0xf0 */ x86emuOp_lock,
12777  /* 0xf1 */ x86emuOp_illegal_op,
12778  /* 0xf2 */ x86emuOp_repne,
12779  /* 0xf3 */ x86emuOp_repe,
12780  /* 0xf4 */ x86emuOp_halt,
12781  /* 0xf5 */ x86emuOp_cmc,
12782  /* 0xf6 */ x86emuOp_opcF6_byte_RM,
12783  /* 0xf7 */ x86emuOp_opcF7_word_RM,
12784 
12785  /* 0xf8 */ x86emuOp_clc,
12786  /* 0xf9 */ x86emuOp_stc,
12787  /* 0xfa */ x86emuOp_cli,
12788  /* 0xfb */ x86emuOp_sti,
12789  /* 0xfc */ x86emuOp_cld,
12790  /* 0xfd */ x86emuOp_std,
12791  /* 0xfe */ x86emuOp_opcFE_byte_RM,
12792  /* 0xff */ x86emuOp_opcFF_word_RM,
12793 };