Merge branch 'master' of git://git.denx.de/u-boot-mpc83xx
[platform/kernel/u-boot.git] / drivers / bios_emulator / x86emu / ops2.c
1 /****************************************************************************
2 *
3 *                       Realmode X86 Emulator Library
4 *
5 *  Copyright (C) 2007 Freescale Semiconductor, Inc.
6 *  Jason Jin <Jason.jin@freescale.com>
7 *
8 *               Copyright (C) 1991-2004 SciTech Software, Inc.
9 *                    Copyright (C) David Mosberger-Tang
10 *                      Copyright (C) 1999 Egbert Eich
11 *
12 *  ========================================================================
13 *
14 *  Permission to use, copy, modify, distribute, and sell this software and
15 *  its documentation for any purpose is hereby granted without fee,
16 *  provided that the above copyright notice appear in all copies and that
17 *  both that copyright notice and this permission notice appear in
18 *  supporting documentation, and that the name of the authors not be used
19 *  in advertising or publicity pertaining to distribution of the software
20 *  without specific, written prior permission.  The authors makes no
21 *  representations about the suitability of this software for any purpose.
22 *  It is provided "as is" without express or implied warranty.
23 *
24 *  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
25 *  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
26 *  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
27 *  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
28 *  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
29 *  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
30 *  PERFORMANCE OF THIS SOFTWARE.
31 *
32 *  ========================================================================
33 *
34 * Language:     ANSI C
35 * Environment:  Any
36 * Developer:    Kendall Bennett
37 *
38 * Description:  This file includes subroutines to implement the decoding
39 *               and emulation of all the x86 extended two-byte processor
40 *               instructions.
41 *
42 ****************************************************************************/
43
44 #include <common.h>
45 #include "x86emu/x86emui.h"
46
47 /*----------------------------- Implementation ----------------------------*/
48
49 /****************************************************************************
50 PARAMETERS:
51 op1 - Instruction op code
52
53 REMARKS:
54 Handles illegal opcodes.
55 ****************************************************************************/
56 void x86emuOp2_illegal_op(
57     u8 op2)
58 {
59     START_OF_INSTR();
60     DECODE_PRINTF("ILLEGAL EXTENDED X86 OPCODE\n");
61     TRACE_REGS();
62     printk("%04x:%04x: %02X ILLEGAL EXTENDED X86 OPCODE!\n",
63         M.x86.R_CS, M.x86.R_IP-2,op2);
64     HALT_SYS();
65     END_OF_INSTR();
66 }
67
68 #define xorl(a,b)   ((a) && !(b)) || (!(a) && (b))
69
70 /****************************************************************************
71 REMARKS:
72 Handles opcode 0x0f,0x80-0x8F
73 ****************************************************************************/
74 int x86emu_check_jump_condition(u8 op)
75 {
76     switch (op) {
77       case 0x0:
78         DECODE_PRINTF("JO\t");
79         return ACCESS_FLAG(F_OF);
80       case 0x1:
81         DECODE_PRINTF("JNO\t");
82         return !ACCESS_FLAG(F_OF);
83         break;
84       case 0x2:
85         DECODE_PRINTF("JB\t");
86         return ACCESS_FLAG(F_CF);
87         break;
88       case 0x3:
89         DECODE_PRINTF("JNB\t");
90         return !ACCESS_FLAG(F_CF);
91         break;
92       case 0x4:
93         DECODE_PRINTF("JZ\t");
94         return ACCESS_FLAG(F_ZF);
95         break;
96       case 0x5:
97         DECODE_PRINTF("JNZ\t");
98         return !ACCESS_FLAG(F_ZF);
99         break;
100       case 0x6:
101         DECODE_PRINTF("JBE\t");
102         return ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF);
103         break;
104       case 0x7:
105         DECODE_PRINTF("JNBE\t");
106         return !(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF));
107         break;
108       case 0x8:
109         DECODE_PRINTF("JS\t");
110         return ACCESS_FLAG(F_SF);
111         break;
112       case 0x9:
113         DECODE_PRINTF("JNS\t");
114         return !ACCESS_FLAG(F_SF);
115         break;
116       case 0xa:
117         DECODE_PRINTF("JP\t");
118         return ACCESS_FLAG(F_PF);
119         break;
120       case 0xb:
121         DECODE_PRINTF("JNP\t");
122         return !ACCESS_FLAG(F_PF);
123         break;
124       case 0xc:
125         DECODE_PRINTF("JL\t");
126         return xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
127         break;
128       case 0xd:
129         DECODE_PRINTF("JNL\t");
130         return !xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
131         break;
132       case 0xe:
133         DECODE_PRINTF("JLE\t");
134         return (xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
135                 ACCESS_FLAG(F_ZF));
136         break;
137       default:
138         DECODE_PRINTF("JNLE\t");
139         return !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
140                  ACCESS_FLAG(F_ZF));
141     }
142 }
143
144 void x86emuOp2_long_jump(u8 op2)
145 {
146     s32 target;
147     int cond;
148
149     /* conditional jump to word offset. */
150     START_OF_INSTR();
151     cond = x86emu_check_jump_condition(op2 & 0xF);
152     target = (s16) fetch_word_imm();
153     target += (s16) M.x86.R_IP;
154     DECODE_PRINTF2("%04x\n", target);
155     TRACE_AND_STEP();
156     if (cond)
157         M.x86.R_IP = (u16)target;
158     DECODE_CLEAR_SEGOVR();
159     END_OF_INSTR();
160 }
161
162 /****************************************************************************
163 REMARKS:
164 Handles opcode 0x0f,0x90-0x9F
165 ****************************************************************************/
166 void x86emuOp2_set_byte(u8 op2)
167 {
168     int mod, rl, rh;
169     uint destoffset;
170     u8  *destreg;
171     char *name = 0;
172     int cond = 0;
173
174     START_OF_INSTR();
175     switch (op2) {
176       case 0x90:
177         name = "SETO\t";
178         cond =  ACCESS_FLAG(F_OF);
179         break;
180       case 0x91:
181         name = "SETNO\t";
182         cond = !ACCESS_FLAG(F_OF);
183         break;
184       case 0x92:
185         name = "SETB\t";
186         cond = ACCESS_FLAG(F_CF);
187         break;
188       case 0x93:
189         name = "SETNB\t";
190         cond = !ACCESS_FLAG(F_CF);
191         break;
192       case 0x94:
193         name = "SETZ\t";
194         cond = ACCESS_FLAG(F_ZF);
195         break;
196       case 0x95:
197         name = "SETNZ\t";
198         cond = !ACCESS_FLAG(F_ZF);
199         break;
200       case 0x96:
201         name = "SETBE\t";
202         cond = ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF);
203         break;
204       case 0x97:
205         name = "SETNBE\t";
206         cond = !(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF));
207         break;
208       case 0x98:
209         name = "SETS\t";
210         cond = ACCESS_FLAG(F_SF);
211         break;
212       case 0x99:
213         name = "SETNS\t";
214         cond = !ACCESS_FLAG(F_SF);
215         break;
216       case 0x9a:
217         name = "SETP\t";
218         cond = ACCESS_FLAG(F_PF);
219         break;
220       case 0x9b:
221         name = "SETNP\t";
222         cond = !ACCESS_FLAG(F_PF);
223         break;
224       case 0x9c:
225         name = "SETL\t";
226         cond = xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
227         break;
228       case 0x9d:
229         name = "SETNL\t";
230         cond = !xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
231         break;
232       case 0x9e:
233         name = "SETLE\t";
234         cond = (xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
235                 ACCESS_FLAG(F_ZF));
236         break;
237       case 0x9f:
238         name = "SETNLE\t";
239         cond = !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
240                  ACCESS_FLAG(F_ZF));
241         break;
242     }
243     DECODE_PRINTF(name);
244     FETCH_DECODE_MODRM(mod, rh, rl);
245     if (mod < 3) {
246         destoffset = decode_rmXX_address(mod, rl);
247         TRACE_AND_STEP();
248         store_data_byte(destoffset, cond ? 0x01 : 0x00);
249     } else {                     /* register to register */
250         destreg = DECODE_RM_BYTE_REGISTER(rl);
251         TRACE_AND_STEP();
252         *destreg = cond ? 0x01 : 0x00;
253     }
254     DECODE_CLEAR_SEGOVR();
255     END_OF_INSTR();
256 }
257
258 /****************************************************************************
259 REMARKS:
260 Handles opcode 0x0f,0xa0
261 ****************************************************************************/
262 void x86emuOp2_push_FS(u8 X86EMU_UNUSED(op2))
263 {
264     START_OF_INSTR();
265     DECODE_PRINTF("PUSH\tFS\n");
266     TRACE_AND_STEP();
267     push_word(M.x86.R_FS);
268     DECODE_CLEAR_SEGOVR();
269     END_OF_INSTR();
270 }
271
272 /****************************************************************************
273 REMARKS:
274 Handles opcode 0x0f,0xa1
275 ****************************************************************************/
276 void x86emuOp2_pop_FS(u8 X86EMU_UNUSED(op2))
277 {
278     START_OF_INSTR();
279     DECODE_PRINTF("POP\tFS\n");
280     TRACE_AND_STEP();
281     M.x86.R_FS = pop_word();
282     DECODE_CLEAR_SEGOVR();
283     END_OF_INSTR();
284 }
285
286 /****************************************************************************
287 REMARKS:
288 Handles opcode 0x0f,0xa3
289 ****************************************************************************/
290 void x86emuOp2_bt_R(u8 X86EMU_UNUSED(op2))
291 {
292     int mod, rl, rh;
293     uint srcoffset;
294     int bit,disp;
295
296     START_OF_INSTR();
297     DECODE_PRINTF("BT\t");
298     FETCH_DECODE_MODRM(mod, rh, rl);
299     if (mod < 3) {
300         srcoffset = decode_rmXX_address(mod, rl);
301         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
302             u32 srcval;
303             u32 *shiftreg;
304
305             DECODE_PRINTF(",");
306             shiftreg = DECODE_RM_LONG_REGISTER(rh);
307             TRACE_AND_STEP();
308             bit = *shiftreg & 0x1F;
309             disp = (s16)*shiftreg >> 5;
310             srcval = fetch_data_long(srcoffset+disp);
311             CONDITIONAL_SET_FLAG(srcval & (0x1 << bit),F_CF);
312         } else {
313             u16 srcval;
314             u16 *shiftreg;
315
316             DECODE_PRINTF(",");
317             shiftreg = DECODE_RM_WORD_REGISTER(rh);
318             TRACE_AND_STEP();
319             bit = *shiftreg & 0xF;
320             disp = (s16)*shiftreg >> 4;
321             srcval = fetch_data_word(srcoffset+disp);
322             CONDITIONAL_SET_FLAG(srcval & (0x1 << bit),F_CF);
323         }
324     } else {                     /* register to register */
325         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
326             u32 *srcreg,*shiftreg;
327
328             srcreg = DECODE_RM_LONG_REGISTER(rl);
329             DECODE_PRINTF(",");
330             shiftreg = DECODE_RM_LONG_REGISTER(rh);
331             TRACE_AND_STEP();
332             bit = *shiftreg & 0x1F;
333             CONDITIONAL_SET_FLAG(*srcreg & (0x1 << bit),F_CF);
334         } else {
335             u16 *srcreg,*shiftreg;
336
337             srcreg = DECODE_RM_WORD_REGISTER(rl);
338             DECODE_PRINTF(",");
339             shiftreg = DECODE_RM_WORD_REGISTER(rh);
340             TRACE_AND_STEP();
341             bit = *shiftreg & 0xF;
342             CONDITIONAL_SET_FLAG(*srcreg & (0x1 << bit),F_CF);
343         }
344     }
345     DECODE_CLEAR_SEGOVR();
346     END_OF_INSTR();
347 }
348
349 /****************************************************************************
350 REMARKS:
351 Handles opcode 0x0f,0xa4
352 ****************************************************************************/
353 void x86emuOp2_shld_IMM(u8 X86EMU_UNUSED(op2))
354 {
355     int mod, rl, rh;
356     uint destoffset;
357     u8 shift;
358
359     START_OF_INSTR();
360     DECODE_PRINTF("SHLD\t");
361     FETCH_DECODE_MODRM(mod, rh, rl);
362     if (mod < 3) {
363         destoffset = decode_rmXX_address(mod, rl);
364         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
365             u32 destval;
366             u32 *shiftreg;
367
368             DECODE_PRINTF(",");
369             shiftreg = DECODE_RM_LONG_REGISTER(rh);
370             DECODE_PRINTF(",");
371             shift = fetch_byte_imm();
372             DECODE_PRINTF2("%d\n", shift);
373             TRACE_AND_STEP();
374             destval = fetch_data_long(destoffset);
375             destval = shld_long(destval,*shiftreg,shift);
376             store_data_long(destoffset, destval);
377         } else {
378             u16 destval;
379             u16 *shiftreg;
380
381             DECODE_PRINTF(",");
382             shiftreg = DECODE_RM_WORD_REGISTER(rh);
383             DECODE_PRINTF(",");
384             shift = fetch_byte_imm();
385             DECODE_PRINTF2("%d\n", shift);
386             TRACE_AND_STEP();
387             destval = fetch_data_word(destoffset);
388             destval = shld_word(destval,*shiftreg,shift);
389             store_data_word(destoffset, destval);
390         }
391     } else {                     /* register to register */
392         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
393             u32 *destreg,*shiftreg;
394
395             destreg = DECODE_RM_LONG_REGISTER(rl);
396             DECODE_PRINTF(",");
397             shiftreg = DECODE_RM_LONG_REGISTER(rh);
398             DECODE_PRINTF(",");
399             shift = fetch_byte_imm();
400             DECODE_PRINTF2("%d\n", shift);
401             TRACE_AND_STEP();
402             *destreg = shld_long(*destreg,*shiftreg,shift);
403         } else {
404             u16 *destreg,*shiftreg;
405
406             destreg = DECODE_RM_WORD_REGISTER(rl);
407             DECODE_PRINTF(",");
408             shiftreg = DECODE_RM_WORD_REGISTER(rh);
409             DECODE_PRINTF(",");
410             shift = fetch_byte_imm();
411             DECODE_PRINTF2("%d\n", shift);
412             TRACE_AND_STEP();
413             *destreg = shld_word(*destreg,*shiftreg,shift);
414         }
415     }
416     DECODE_CLEAR_SEGOVR();
417     END_OF_INSTR();
418 }
419
420 /****************************************************************************
421 REMARKS:
422 Handles opcode 0x0f,0xa5
423 ****************************************************************************/
424 void x86emuOp2_shld_CL(u8 X86EMU_UNUSED(op2))
425 {
426     int mod, rl, rh;
427     uint destoffset;
428
429     START_OF_INSTR();
430     DECODE_PRINTF("SHLD\t");
431     FETCH_DECODE_MODRM(mod, rh, rl);
432     if (mod < 3) {
433         destoffset = decode_rmXX_address(mod, rl);
434         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
435             u32 destval;
436             u32 *shiftreg;
437
438             DECODE_PRINTF(",");
439             shiftreg = DECODE_RM_LONG_REGISTER(rh);
440             DECODE_PRINTF(",CL\n");
441             TRACE_AND_STEP();
442             destval = fetch_data_long(destoffset);
443             destval = shld_long(destval,*shiftreg,M.x86.R_CL);
444             store_data_long(destoffset, destval);
445         } else {
446             u16 destval;
447             u16 *shiftreg;
448
449             DECODE_PRINTF(",");
450             shiftreg = DECODE_RM_WORD_REGISTER(rh);
451             DECODE_PRINTF(",CL\n");
452             TRACE_AND_STEP();
453             destval = fetch_data_word(destoffset);
454             destval = shld_word(destval,*shiftreg,M.x86.R_CL);
455             store_data_word(destoffset, destval);
456         }
457     } else {                     /* register to register */
458         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
459             u32 *destreg,*shiftreg;
460
461             destreg = DECODE_RM_LONG_REGISTER(rl);
462             DECODE_PRINTF(",");
463             shiftreg = DECODE_RM_LONG_REGISTER(rh);
464             DECODE_PRINTF(",CL\n");
465             TRACE_AND_STEP();
466             *destreg = shld_long(*destreg,*shiftreg,M.x86.R_CL);
467         } else {
468             u16 *destreg,*shiftreg;
469
470             destreg = DECODE_RM_WORD_REGISTER(rl);
471             DECODE_PRINTF(",");
472             shiftreg = DECODE_RM_WORD_REGISTER(rh);
473             DECODE_PRINTF(",CL\n");
474             TRACE_AND_STEP();
475             *destreg = shld_word(*destreg,*shiftreg,M.x86.R_CL);
476         }
477     }
478     DECODE_CLEAR_SEGOVR();
479     END_OF_INSTR();
480 }
481
482 /****************************************************************************
483 REMARKS:
484 Handles opcode 0x0f,0xa8
485 ****************************************************************************/
486 void x86emuOp2_push_GS(u8 X86EMU_UNUSED(op2))
487 {
488     START_OF_INSTR();
489     DECODE_PRINTF("PUSH\tGS\n");
490     TRACE_AND_STEP();
491     push_word(M.x86.R_GS);
492     DECODE_CLEAR_SEGOVR();
493     END_OF_INSTR();
494 }
495
496 /****************************************************************************
497 REMARKS:
498 Handles opcode 0x0f,0xa9
499 ****************************************************************************/
500 void x86emuOp2_pop_GS(u8 X86EMU_UNUSED(op2))
501 {
502     START_OF_INSTR();
503     DECODE_PRINTF("POP\tGS\n");
504     TRACE_AND_STEP();
505     M.x86.R_GS = pop_word();
506     DECODE_CLEAR_SEGOVR();
507     END_OF_INSTR();
508 }
509
510 /****************************************************************************
511 REMARKS:
512 Handles opcode 0x0f,0xaa
513 ****************************************************************************/
514 void x86emuOp2_bts_R(u8 X86EMU_UNUSED(op2))
515 {
516     int mod, rl, rh;
517     uint srcoffset;
518     int bit,disp;
519
520     START_OF_INSTR();
521     DECODE_PRINTF("BTS\t");
522     FETCH_DECODE_MODRM(mod, rh, rl);
523     if (mod < 3) {
524         srcoffset = decode_rmXX_address(mod, rl);
525         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
526             u32 srcval,mask;
527             u32 *shiftreg;
528
529             DECODE_PRINTF(",");
530             shiftreg = DECODE_RM_LONG_REGISTER(rh);
531             TRACE_AND_STEP();
532             bit = *shiftreg & 0x1F;
533             disp = (s16)*shiftreg >> 5;
534             srcval = fetch_data_long(srcoffset+disp);
535             mask = (0x1 << bit);
536             CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
537             store_data_long(srcoffset+disp, srcval | mask);
538         } else {
539             u16 srcval,mask;
540             u16 *shiftreg;
541
542             DECODE_PRINTF(",");
543             shiftreg = DECODE_RM_WORD_REGISTER(rh);
544             TRACE_AND_STEP();
545             bit = *shiftreg & 0xF;
546             disp = (s16)*shiftreg >> 4;
547             srcval = fetch_data_word(srcoffset+disp);
548             mask = (u16)(0x1 << bit);
549             CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
550             store_data_word(srcoffset+disp, srcval | mask);
551         }
552     } else {                     /* register to register */
553         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
554             u32 *srcreg,*shiftreg;
555             u32 mask;
556
557             srcreg = DECODE_RM_LONG_REGISTER(rl);
558             DECODE_PRINTF(",");
559             shiftreg = DECODE_RM_LONG_REGISTER(rh);
560             TRACE_AND_STEP();
561             bit = *shiftreg & 0x1F;
562             mask = (0x1 << bit);
563             CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
564             *srcreg |= mask;
565         } else {
566             u16 *srcreg,*shiftreg;
567             u16 mask;
568
569             srcreg = DECODE_RM_WORD_REGISTER(rl);
570             DECODE_PRINTF(",");
571             shiftreg = DECODE_RM_WORD_REGISTER(rh);
572             TRACE_AND_STEP();
573             bit = *shiftreg & 0xF;
574             mask = (u16)(0x1 << bit);
575             CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
576             *srcreg |= mask;
577         }
578     }
579     DECODE_CLEAR_SEGOVR();
580     END_OF_INSTR();
581 }
582
583 /****************************************************************************
584 REMARKS:
585 Handles opcode 0x0f,0xac
586 ****************************************************************************/
587 void x86emuOp2_shrd_IMM(u8 X86EMU_UNUSED(op2))
588 {
589     int mod, rl, rh;
590     uint destoffset;
591     u8 shift;
592
593     START_OF_INSTR();
594     DECODE_PRINTF("SHLD\t");
595     FETCH_DECODE_MODRM(mod, rh, rl);
596     if (mod < 3) {
597         destoffset = decode_rmXX_address(mod, rl);
598         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
599             u32 destval;
600             u32 *shiftreg;
601
602             DECODE_PRINTF(",");
603             shiftreg = DECODE_RM_LONG_REGISTER(rh);
604             DECODE_PRINTF(",");
605             shift = fetch_byte_imm();
606             DECODE_PRINTF2("%d\n", shift);
607             TRACE_AND_STEP();
608             destval = fetch_data_long(destoffset);
609             destval = shrd_long(destval,*shiftreg,shift);
610             store_data_long(destoffset, destval);
611         } else {
612             u16 destval;
613             u16 *shiftreg;
614
615             DECODE_PRINTF(",");
616             shiftreg = DECODE_RM_WORD_REGISTER(rh);
617             DECODE_PRINTF(",");
618             shift = fetch_byte_imm();
619             DECODE_PRINTF2("%d\n", shift);
620             TRACE_AND_STEP();
621             destval = fetch_data_word(destoffset);
622             destval = shrd_word(destval,*shiftreg,shift);
623             store_data_word(destoffset, destval);
624         }
625     } else {                     /* register to register */
626         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
627             u32 *destreg,*shiftreg;
628
629             destreg = DECODE_RM_LONG_REGISTER(rl);
630             DECODE_PRINTF(",");
631             shiftreg = DECODE_RM_LONG_REGISTER(rh);
632             DECODE_PRINTF(",");
633             shift = fetch_byte_imm();
634             DECODE_PRINTF2("%d\n", shift);
635             TRACE_AND_STEP();
636             *destreg = shrd_long(*destreg,*shiftreg,shift);
637         } else {
638             u16 *destreg,*shiftreg;
639
640             destreg = DECODE_RM_WORD_REGISTER(rl);
641             DECODE_PRINTF(",");
642             shiftreg = DECODE_RM_WORD_REGISTER(rh);
643             DECODE_PRINTF(",");
644             shift = fetch_byte_imm();
645             DECODE_PRINTF2("%d\n", shift);
646             TRACE_AND_STEP();
647             *destreg = shrd_word(*destreg,*shiftreg,shift);
648         }
649     }
650     DECODE_CLEAR_SEGOVR();
651     END_OF_INSTR();
652 }
653
654 /****************************************************************************
655 REMARKS:
656 Handles opcode 0x0f,0xad
657 ****************************************************************************/
658 void x86emuOp2_shrd_CL(u8 X86EMU_UNUSED(op2))
659 {
660     int mod, rl, rh;
661     uint destoffset;
662
663     START_OF_INSTR();
664     DECODE_PRINTF("SHLD\t");
665     FETCH_DECODE_MODRM(mod, rh, rl);
666     if (mod < 3) {
667         destoffset = decode_rmXX_address(mod, rl);
668         DECODE_PRINTF(",");
669         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
670             u32 destval;
671             u32 *shiftreg;
672
673             shiftreg = DECODE_RM_LONG_REGISTER(rh);
674             DECODE_PRINTF(",CL\n");
675             TRACE_AND_STEP();
676             destval = fetch_data_long(destoffset);
677             destval = shrd_long(destval,*shiftreg,M.x86.R_CL);
678             store_data_long(destoffset, destval);
679         } else {
680             u16 destval;
681             u16 *shiftreg;
682
683             shiftreg = DECODE_RM_WORD_REGISTER(rh);
684             DECODE_PRINTF(",CL\n");
685             TRACE_AND_STEP();
686             destval = fetch_data_word(destoffset);
687             destval = shrd_word(destval,*shiftreg,M.x86.R_CL);
688             store_data_word(destoffset, destval);
689         }
690     } else {                     /* register to register */
691         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
692             u32 *destreg,*shiftreg;
693
694             destreg = DECODE_RM_LONG_REGISTER(rl);
695             DECODE_PRINTF(",");
696             shiftreg = DECODE_RM_LONG_REGISTER(rh);
697             DECODE_PRINTF(",CL\n");
698             TRACE_AND_STEP();
699             *destreg = shrd_long(*destreg,*shiftreg,M.x86.R_CL);
700         } else {
701             u16 *destreg,*shiftreg;
702
703             destreg = DECODE_RM_WORD_REGISTER(rl);
704             DECODE_PRINTF(",");
705             shiftreg = DECODE_RM_WORD_REGISTER(rh);
706             DECODE_PRINTF(",CL\n");
707             TRACE_AND_STEP();
708             *destreg = shrd_word(*destreg,*shiftreg,M.x86.R_CL);
709         }
710     }
711     DECODE_CLEAR_SEGOVR();
712     END_OF_INSTR();
713 }
714
715 /****************************************************************************
716 REMARKS:
717 Handles opcode 0x0f,0xaf
718 ****************************************************************************/
719 void x86emuOp2_imul_R_RM(u8 X86EMU_UNUSED(op2))
720 {
721     int mod, rl, rh;
722     uint srcoffset;
723
724     START_OF_INSTR();
725     DECODE_PRINTF("IMUL\t");
726     FETCH_DECODE_MODRM(mod, rh, rl);
727     if (mod < 3) {
728         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
729             u32 *destreg;
730             u32 srcval;
731             u32 res_lo,res_hi;
732
733             destreg = DECODE_RM_LONG_REGISTER(rh);
734             DECODE_PRINTF(",");
735             srcoffset = decode_rmXX_address(mod, rl);
736             srcval = fetch_data_long(srcoffset);
737             TRACE_AND_STEP();
738             imul_long_direct(&res_lo,&res_hi,(s32)*destreg,(s32)srcval);
739             if (res_hi != 0) {
740                 SET_FLAG(F_CF);
741                 SET_FLAG(F_OF);
742             } else {
743                 CLEAR_FLAG(F_CF);
744                 CLEAR_FLAG(F_OF);
745             }
746             *destreg = (u32)res_lo;
747         } else {
748             u16 *destreg;
749             u16 srcval;
750             u32 res;
751
752             destreg = DECODE_RM_WORD_REGISTER(rh);
753             DECODE_PRINTF(",");
754             srcoffset = decode_rmXX_address(mod, rl);
755             srcval = fetch_data_word(srcoffset);
756             TRACE_AND_STEP();
757             res = (s16)*destreg * (s16)srcval;
758             if (res > 0xFFFF) {
759                 SET_FLAG(F_CF);
760                 SET_FLAG(F_OF);
761             } else {
762                 CLEAR_FLAG(F_CF);
763                 CLEAR_FLAG(F_OF);
764             }
765             *destreg = (u16)res;
766         }
767     } else {                     /* register to register */
768         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
769             u32 *destreg,*srcreg;
770             u32 res_lo,res_hi;
771
772             destreg = DECODE_RM_LONG_REGISTER(rh);
773             DECODE_PRINTF(",");
774             srcreg = DECODE_RM_LONG_REGISTER(rl);
775             TRACE_AND_STEP();
776             imul_long_direct(&res_lo,&res_hi,(s32)*destreg,(s32)*srcreg);
777             if (res_hi != 0) {
778                 SET_FLAG(F_CF);
779                 SET_FLAG(F_OF);
780             } else {
781                 CLEAR_FLAG(F_CF);
782                 CLEAR_FLAG(F_OF);
783             }
784             *destreg = (u32)res_lo;
785         } else {
786             u16 *destreg,*srcreg;
787             u32 res;
788
789             destreg = DECODE_RM_WORD_REGISTER(rh);
790             DECODE_PRINTF(",");
791             srcreg = DECODE_RM_WORD_REGISTER(rl);
792             res = (s16)*destreg * (s16)*srcreg;
793             if (res > 0xFFFF) {
794                 SET_FLAG(F_CF);
795                 SET_FLAG(F_OF);
796             } else {
797                 CLEAR_FLAG(F_CF);
798                 CLEAR_FLAG(F_OF);
799             }
800             *destreg = (u16)res;
801         }
802     }
803     DECODE_CLEAR_SEGOVR();
804     END_OF_INSTR();
805 }
806
807 /****************************************************************************
808 REMARKS:
809 Handles opcode 0x0f,0xb2
810 ****************************************************************************/
811 void x86emuOp2_lss_R_IMM(u8 X86EMU_UNUSED(op2))
812 {
813     int mod, rh, rl;
814     u16 *dstreg;
815     uint srcoffset;
816
817     START_OF_INSTR();
818     DECODE_PRINTF("LSS\t");
819     FETCH_DECODE_MODRM(mod, rh, rl);
820     if (mod < 3) {
821         dstreg = DECODE_RM_WORD_REGISTER(rh);
822         DECODE_PRINTF(",");
823         srcoffset = decode_rmXX_address(mod, rl);
824         DECODE_PRINTF("\n");
825         TRACE_AND_STEP();
826         *dstreg = fetch_data_word(srcoffset);
827         M.x86.R_SS = fetch_data_word(srcoffset + 2);
828     } else {                     /* register to register */
829         /* UNDEFINED! */
830         TRACE_AND_STEP();
831     }
832     DECODE_CLEAR_SEGOVR();
833     END_OF_INSTR();
834 }
835
836 /****************************************************************************
837 REMARKS:
838 Handles opcode 0x0f,0xb3
839 ****************************************************************************/
840 void x86emuOp2_btr_R(u8 X86EMU_UNUSED(op2))
841 {
842     int mod, rl, rh;
843     uint srcoffset;
844     int bit,disp;
845
846     START_OF_INSTR();
847     DECODE_PRINTF("BTR\t");
848     FETCH_DECODE_MODRM(mod, rh, rl);
849     if (mod < 3) {
850         srcoffset = decode_rmXX_address(mod, rl);
851         DECODE_PRINTF(",");
852         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
853             u32 srcval,mask;
854             u32 *shiftreg;
855
856             shiftreg = DECODE_RM_LONG_REGISTER(rh);
857             TRACE_AND_STEP();
858             bit = *shiftreg & 0x1F;
859             disp = (s16)*shiftreg >> 5;
860             srcval = fetch_data_long(srcoffset+disp);
861             mask = (0x1 << bit);
862             CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
863             store_data_long(srcoffset+disp, srcval & ~mask);
864         } else {
865             u16 srcval,mask;
866             u16 *shiftreg;
867
868             shiftreg = DECODE_RM_WORD_REGISTER(rh);
869             TRACE_AND_STEP();
870             bit = *shiftreg & 0xF;
871             disp = (s16)*shiftreg >> 4;
872             srcval = fetch_data_word(srcoffset+disp);
873             mask = (u16)(0x1 << bit);
874             CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
875             store_data_word(srcoffset+disp, (u16)(srcval & ~mask));
876         }
877     } else {                     /* register to register */
878         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
879             u32 *srcreg,*shiftreg;
880             u32 mask;
881
882             srcreg = DECODE_RM_LONG_REGISTER(rl);
883             DECODE_PRINTF(",");
884             shiftreg = DECODE_RM_LONG_REGISTER(rh);
885             TRACE_AND_STEP();
886             bit = *shiftreg & 0x1F;
887             mask = (0x1 << bit);
888             CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
889             *srcreg &= ~mask;
890         } else {
891             u16 *srcreg,*shiftreg;
892             u16 mask;
893
894             srcreg = DECODE_RM_WORD_REGISTER(rl);
895             DECODE_PRINTF(",");
896             shiftreg = DECODE_RM_WORD_REGISTER(rh);
897             TRACE_AND_STEP();
898             bit = *shiftreg & 0xF;
899             mask = (u16)(0x1 << bit);
900             CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
901             *srcreg &= ~mask;
902         }
903     }
904     DECODE_CLEAR_SEGOVR();
905     END_OF_INSTR();
906 }
907
908 /****************************************************************************
909 REMARKS:
910 Handles opcode 0x0f,0xb4
911 ****************************************************************************/
912 void x86emuOp2_lfs_R_IMM(u8 X86EMU_UNUSED(op2))
913 {
914     int mod, rh, rl;
915     u16 *dstreg;
916     uint srcoffset;
917
918     START_OF_INSTR();
919     DECODE_PRINTF("LFS\t");
920     FETCH_DECODE_MODRM(mod, rh, rl);
921     if (mod < 3) {
922         dstreg = DECODE_RM_WORD_REGISTER(rh);
923         DECODE_PRINTF(",");
924         srcoffset = decode_rmXX_address(mod, rl);
925         DECODE_PRINTF("\n");
926         TRACE_AND_STEP();
927         *dstreg = fetch_data_word(srcoffset);
928         M.x86.R_FS = fetch_data_word(srcoffset + 2);
929     } else {                     /* register to register */
930         /* UNDEFINED! */
931         TRACE_AND_STEP();
932     }
933     DECODE_CLEAR_SEGOVR();
934     END_OF_INSTR();
935 }
936
937 /****************************************************************************
938 REMARKS:
939 Handles opcode 0x0f,0xb5
940 ****************************************************************************/
941 void x86emuOp2_lgs_R_IMM(u8 X86EMU_UNUSED(op2))
942 {
943     int mod, rh, rl;
944     u16 *dstreg;
945     uint srcoffset;
946
947     START_OF_INSTR();
948     DECODE_PRINTF("LGS\t");
949     FETCH_DECODE_MODRM(mod, rh, rl);
950     if (mod < 3) {
951         dstreg = DECODE_RM_WORD_REGISTER(rh);
952         DECODE_PRINTF(",");
953         srcoffset = decode_rmXX_address(mod, rl);
954         DECODE_PRINTF("\n");
955         TRACE_AND_STEP();
956         *dstreg = fetch_data_word(srcoffset);
957         M.x86.R_GS = fetch_data_word(srcoffset + 2);
958     } else {                     /* register to register */
959         /* UNDEFINED! */
960         TRACE_AND_STEP();
961     }
962     DECODE_CLEAR_SEGOVR();
963     END_OF_INSTR();
964 }
965
966 /****************************************************************************
967 REMARKS:
968 Handles opcode 0x0f,0xb6
969 ****************************************************************************/
970 void x86emuOp2_movzx_byte_R_RM(u8 X86EMU_UNUSED(op2))
971 {
972     int mod, rl, rh;
973     uint srcoffset;
974
975     START_OF_INSTR();
976     DECODE_PRINTF("MOVZX\t");
977     FETCH_DECODE_MODRM(mod, rh, rl);
978     if (mod < 3) {
979         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
980             u32 *destreg;
981             u32 srcval;
982
983             destreg = DECODE_RM_LONG_REGISTER(rh);
984             DECODE_PRINTF(",");
985             srcoffset = decode_rmXX_address(mod, rl);
986             srcval = fetch_data_byte(srcoffset);
987             DECODE_PRINTF("\n");
988             TRACE_AND_STEP();
989             *destreg = srcval;
990         } else {
991             u16 *destreg;
992             u16 srcval;
993
994             destreg = DECODE_RM_WORD_REGISTER(rh);
995             DECODE_PRINTF(",");
996             srcoffset = decode_rmXX_address(mod, rl);
997             srcval = fetch_data_byte(srcoffset);
998             DECODE_PRINTF("\n");
999             TRACE_AND_STEP();
1000             *destreg = srcval;
1001         }
1002     } else {                     /* register to register */
1003         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1004             u32 *destreg;
1005             u8  *srcreg;
1006
1007             destreg = DECODE_RM_LONG_REGISTER(rh);
1008             DECODE_PRINTF(",");
1009             srcreg = DECODE_RM_BYTE_REGISTER(rl);
1010             DECODE_PRINTF("\n");
1011             TRACE_AND_STEP();
1012             *destreg = *srcreg;
1013         } else {
1014             u16 *destreg;
1015             u8  *srcreg;
1016
1017             destreg = DECODE_RM_WORD_REGISTER(rh);
1018             DECODE_PRINTF(",");
1019             srcreg = DECODE_RM_BYTE_REGISTER(rl);
1020             DECODE_PRINTF("\n");
1021             TRACE_AND_STEP();
1022             *destreg = *srcreg;
1023         }
1024     }
1025     DECODE_CLEAR_SEGOVR();
1026     END_OF_INSTR();
1027 }
1028
1029 /****************************************************************************
1030 REMARKS:
1031 Handles opcode 0x0f,0xb7
1032 ****************************************************************************/
1033 void x86emuOp2_movzx_word_R_RM(u8 X86EMU_UNUSED(op2))
1034 {
1035     int mod, rl, rh;
1036     uint srcoffset;
1037     u32 *destreg;
1038     u32 srcval;
1039     u16 *srcreg;
1040
1041     START_OF_INSTR();
1042     DECODE_PRINTF("MOVZX\t");
1043     FETCH_DECODE_MODRM(mod, rh, rl);
1044     if (mod < 3) {
1045         destreg = DECODE_RM_LONG_REGISTER(rh);
1046         DECODE_PRINTF(",");
1047         srcoffset = decode_rmXX_address(mod, rl);
1048         srcval = fetch_data_word(srcoffset);
1049         DECODE_PRINTF("\n");
1050         TRACE_AND_STEP();
1051         *destreg = srcval;
1052     } else {                     /* register to register */
1053         destreg = DECODE_RM_LONG_REGISTER(rh);
1054         DECODE_PRINTF(",");
1055         srcreg = DECODE_RM_WORD_REGISTER(rl);
1056         DECODE_PRINTF("\n");
1057         TRACE_AND_STEP();
1058         *destreg = *srcreg;
1059     }
1060     DECODE_CLEAR_SEGOVR();
1061     END_OF_INSTR();
1062 }
1063
1064 /****************************************************************************
1065 REMARKS:
1066 Handles opcode 0x0f,0xba
1067 ****************************************************************************/
1068 void x86emuOp2_btX_I(u8 X86EMU_UNUSED(op2))
1069 {
1070     int mod, rl, rh;
1071     uint srcoffset;
1072     u8 shift;
1073     int bit;
1074
1075     START_OF_INSTR();
1076     FETCH_DECODE_MODRM(mod, rh, rl);
1077     switch (rh) {
1078     case 4:
1079         DECODE_PRINTF("BT\t");
1080         break;
1081     case 5:
1082         DECODE_PRINTF("BTS\t");
1083         break;
1084     case 6:
1085         DECODE_PRINTF("BTR\t");
1086         break;
1087     case 7:
1088         DECODE_PRINTF("BTC\t");
1089         break;
1090     default:
1091         DECODE_PRINTF("ILLEGAL EXTENDED X86 OPCODE\n");
1092         TRACE_REGS();
1093         printk("%04x:%04x: %02X%02X ILLEGAL EXTENDED X86 OPCODE EXTENSION!\n",
1094                 M.x86.R_CS, M.x86.R_IP-3,op2, (mod<<6)|(rh<<3)|rl);
1095         HALT_SYS();
1096     }
1097     if (mod < 3) {
1098
1099         srcoffset = decode_rmXX_address(mod, rl);
1100         shift = fetch_byte_imm();
1101         DECODE_PRINTF2(",%d\n", shift);
1102         TRACE_AND_STEP();
1103
1104         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1105             u32 srcval, mask;
1106
1107             bit = shift & 0x1F;
1108             srcval = fetch_data_long(srcoffset);
1109             mask = (0x1 << bit);
1110             CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1111             switch (rh) {
1112             case 5:
1113                 store_data_long(srcoffset, srcval | mask);
1114                 break;
1115             case 6:
1116                 store_data_long(srcoffset, srcval & ~mask);
1117                 break;
1118             case 7:
1119                 store_data_long(srcoffset, srcval ^ mask);
1120                 break;
1121             default:
1122                 break;
1123             }
1124         } else {
1125             u16 srcval, mask;
1126
1127             bit = shift & 0xF;
1128             srcval = fetch_data_word(srcoffset);
1129             mask = (0x1 << bit);
1130             CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1131             switch (rh) {
1132             case 5:
1133                 store_data_word(srcoffset, srcval | mask);
1134                 break;
1135             case 6:
1136                 store_data_word(srcoffset, srcval & ~mask);
1137                 break;
1138             case 7:
1139                 store_data_word(srcoffset, srcval ^ mask);
1140                 break;
1141             default:
1142                 break;
1143             }
1144         }
1145     } else {                     /* register to register */
1146         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1147             u32 *srcreg;
1148             u32 mask;
1149
1150             srcreg = DECODE_RM_LONG_REGISTER(rl);
1151             shift = fetch_byte_imm();
1152             DECODE_PRINTF2(",%d\n", shift);
1153             TRACE_AND_STEP();
1154             bit = shift & 0x1F;
1155             mask = (0x1 << bit);
1156             CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
1157             switch (rh) {
1158             case 5:
1159                 *srcreg |= mask;
1160                 break;
1161             case 6:
1162                 *srcreg &= ~mask;
1163                 break;
1164             case 7:
1165                 *srcreg ^= mask;
1166                 break;
1167             default:
1168                 break;
1169             }
1170         } else {
1171             u16 *srcreg;
1172             u16 mask;
1173
1174             srcreg = DECODE_RM_WORD_REGISTER(rl);
1175             shift = fetch_byte_imm();
1176             DECODE_PRINTF2(",%d\n", shift);
1177             TRACE_AND_STEP();
1178             bit = shift & 0xF;
1179             mask = (0x1 << bit);
1180             CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
1181             switch (rh) {
1182             case 5:
1183                 *srcreg |= mask;
1184                 break;
1185             case 6:
1186                 *srcreg &= ~mask;
1187                 break;
1188             case 7:
1189                 *srcreg ^= mask;
1190                 break;
1191             default:
1192                 break;
1193             }
1194         }
1195     }
1196     DECODE_CLEAR_SEGOVR();
1197     END_OF_INSTR();
1198 }
1199
1200 /****************************************************************************
1201 REMARKS:
1202 Handles opcode 0x0f,0xbb
1203 ****************************************************************************/
1204 void x86emuOp2_btc_R(u8 X86EMU_UNUSED(op2))
1205 {
1206     int mod, rl, rh;
1207     uint srcoffset;
1208     int bit,disp;
1209
1210     START_OF_INSTR();
1211     DECODE_PRINTF("BTC\t");
1212     FETCH_DECODE_MODRM(mod, rh, rl);
1213     if (mod < 3) {
1214         srcoffset = decode_rmXX_address(mod, rl);
1215         DECODE_PRINTF(",");
1216         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1217             u32 srcval,mask;
1218             u32 *shiftreg;
1219
1220             shiftreg = DECODE_RM_LONG_REGISTER(rh);
1221             TRACE_AND_STEP();
1222             bit = *shiftreg & 0x1F;
1223             disp = (s16)*shiftreg >> 5;
1224             srcval = fetch_data_long(srcoffset+disp);
1225             mask = (0x1 << bit);
1226             CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1227             store_data_long(srcoffset+disp, srcval ^ mask);
1228         } else {
1229             u16 srcval,mask;
1230             u16 *shiftreg;
1231
1232             shiftreg = DECODE_RM_WORD_REGISTER(rh);
1233             TRACE_AND_STEP();
1234             bit = *shiftreg & 0xF;
1235             disp = (s16)*shiftreg >> 4;
1236             srcval = fetch_data_word(srcoffset+disp);
1237             mask = (u16)(0x1 << bit);
1238             CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1239             store_data_word(srcoffset+disp, (u16)(srcval ^ mask));
1240         }
1241     } else {                     /* register to register */
1242         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1243             u32 *srcreg,*shiftreg;
1244             u32 mask;
1245
1246             srcreg = DECODE_RM_LONG_REGISTER(rl);
1247             DECODE_PRINTF(",");
1248             shiftreg = DECODE_RM_LONG_REGISTER(rh);
1249             TRACE_AND_STEP();
1250             bit = *shiftreg & 0x1F;
1251             mask = (0x1 << bit);
1252             CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
1253             *srcreg ^= mask;
1254         } else {
1255             u16 *srcreg,*shiftreg;
1256             u16 mask;
1257
1258             srcreg = DECODE_RM_WORD_REGISTER(rl);
1259             DECODE_PRINTF(",");
1260             shiftreg = DECODE_RM_WORD_REGISTER(rh);
1261             TRACE_AND_STEP();
1262             bit = *shiftreg & 0xF;
1263             mask = (u16)(0x1 << bit);
1264             CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
1265             *srcreg ^= mask;
1266         }
1267     }
1268     DECODE_CLEAR_SEGOVR();
1269     END_OF_INSTR();
1270 }
1271
1272 /****************************************************************************
1273 REMARKS:
1274 Handles opcode 0x0f,0xbc
1275 ****************************************************************************/
1276 void x86emuOp2_bsf(u8 X86EMU_UNUSED(op2))
1277 {
1278     int mod, rl, rh;
1279     uint srcoffset;
1280
1281     START_OF_INSTR();
1282     DECODE_PRINTF("BSF\n");
1283     FETCH_DECODE_MODRM(mod, rh, rl);
1284     if (mod < 3) {
1285         srcoffset = decode_rmXX_address(mod, rl);
1286         DECODE_PRINTF(",");
1287         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1288             u32 srcval, *dstreg;
1289
1290             dstreg = DECODE_RM_LONG_REGISTER(rh);
1291             TRACE_AND_STEP();
1292             srcval = fetch_data_long(srcoffset);
1293             CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
1294             for(*dstreg = 0; *dstreg < 32; (*dstreg)++)
1295                 if ((srcval >> *dstreg) & 1) break;
1296         } else {
1297             u16 srcval, *dstreg;
1298
1299             dstreg = DECODE_RM_WORD_REGISTER(rh);
1300             TRACE_AND_STEP();
1301             srcval = fetch_data_word(srcoffset);
1302             CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
1303             for(*dstreg = 0; *dstreg < 16; (*dstreg)++)
1304                 if ((srcval >> *dstreg) & 1) break;
1305         }
1306     } else {             /* register to register */
1307         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1308             u32 *srcreg, *dstreg;
1309
1310             srcreg = DECODE_RM_LONG_REGISTER(rl);
1311             DECODE_PRINTF(",");
1312             dstreg = DECODE_RM_LONG_REGISTER(rh);
1313             TRACE_AND_STEP();
1314             CONDITIONAL_SET_FLAG(*srcreg == 0, F_ZF);
1315             for(*dstreg = 0; *dstreg < 32; (*dstreg)++)
1316                 if ((*srcreg >> *dstreg) & 1) break;
1317         } else {
1318             u16 *srcreg, *dstreg;
1319
1320             srcreg = DECODE_RM_WORD_REGISTER(rl);
1321             DECODE_PRINTF(",");
1322             dstreg = DECODE_RM_WORD_REGISTER(rh);
1323             TRACE_AND_STEP();
1324             CONDITIONAL_SET_FLAG(*srcreg == 0, F_ZF);
1325             for(*dstreg = 0; *dstreg < 16; (*dstreg)++)
1326                 if ((*srcreg >> *dstreg) & 1) break;
1327         }
1328     }
1329     DECODE_CLEAR_SEGOVR();
1330     END_OF_INSTR();
1331 }
1332
1333 /****************************************************************************
1334 REMARKS:
1335 Handles opcode 0x0f,0xbd
1336 ****************************************************************************/
1337 void x86emuOp2_bsr(u8 X86EMU_UNUSED(op2))
1338 {
1339     int mod, rl, rh;
1340     uint srcoffset;
1341
1342     START_OF_INSTR();
1343     DECODE_PRINTF("BSF\n");
1344     FETCH_DECODE_MODRM(mod, rh, rl);
1345     if (mod < 3) {
1346         srcoffset = decode_rmXX_address(mod, rl);
1347         DECODE_PRINTF(",");
1348         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1349             u32 srcval, *dstreg;
1350
1351             dstreg = DECODE_RM_LONG_REGISTER(rh);
1352             TRACE_AND_STEP();
1353             srcval = fetch_data_long(srcoffset);
1354             CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
1355             for(*dstreg = 31; *dstreg > 0; (*dstreg)--)
1356                 if ((srcval >> *dstreg) & 1) break;
1357         } else {
1358             u16 srcval, *dstreg;
1359
1360             dstreg = DECODE_RM_WORD_REGISTER(rh);
1361             TRACE_AND_STEP();
1362             srcval = fetch_data_word(srcoffset);
1363             CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
1364             for(*dstreg = 15; *dstreg > 0; (*dstreg)--)
1365                 if ((srcval >> *dstreg) & 1) break;
1366         }
1367     } else {             /* register to register */
1368         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1369             u32 *srcreg, *dstreg;
1370
1371             srcreg = DECODE_RM_LONG_REGISTER(rl);
1372             DECODE_PRINTF(",");
1373             dstreg = DECODE_RM_LONG_REGISTER(rh);
1374             TRACE_AND_STEP();
1375             CONDITIONAL_SET_FLAG(*srcreg == 0, F_ZF);
1376             for(*dstreg = 31; *dstreg > 0; (*dstreg)--)
1377                 if ((*srcreg >> *dstreg) & 1) break;
1378         } else {
1379             u16 *srcreg, *dstreg;
1380
1381             srcreg = DECODE_RM_WORD_REGISTER(rl);
1382             DECODE_PRINTF(",");
1383             dstreg = DECODE_RM_WORD_REGISTER(rh);
1384             TRACE_AND_STEP();
1385             CONDITIONAL_SET_FLAG(*srcreg == 0, F_ZF);
1386             for(*dstreg = 15; *dstreg > 0; (*dstreg)--)
1387                 if ((*srcreg >> *dstreg) & 1) break;
1388         }
1389     }
1390     DECODE_CLEAR_SEGOVR();
1391     END_OF_INSTR();
1392 }
1393
1394 /****************************************************************************
1395 REMARKS:
1396 Handles opcode 0x0f,0xbe
1397 ****************************************************************************/
1398 void x86emuOp2_movsx_byte_R_RM(u8 X86EMU_UNUSED(op2))
1399 {
1400     int mod, rl, rh;
1401     uint srcoffset;
1402
1403     START_OF_INSTR();
1404     DECODE_PRINTF("MOVSX\t");
1405     FETCH_DECODE_MODRM(mod, rh, rl);
1406     if (mod < 3) {
1407         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1408             u32 *destreg;
1409             u32 srcval;
1410
1411             destreg = DECODE_RM_LONG_REGISTER(rh);
1412             DECODE_PRINTF(",");
1413             srcoffset = decode_rmXX_address(mod, rl);
1414             srcval = (s32)((s8)fetch_data_byte(srcoffset));
1415             DECODE_PRINTF("\n");
1416             TRACE_AND_STEP();
1417             *destreg = srcval;
1418         } else {
1419             u16 *destreg;
1420             u16 srcval;
1421
1422             destreg = DECODE_RM_WORD_REGISTER(rh);
1423             DECODE_PRINTF(",");
1424             srcoffset = decode_rmXX_address(mod, rl);
1425             srcval = (s16)((s8)fetch_data_byte(srcoffset));
1426             DECODE_PRINTF("\n");
1427             TRACE_AND_STEP();
1428             *destreg = srcval;
1429         }
1430     } else {                     /* register to register */
1431         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1432             u32 *destreg;
1433             u8  *srcreg;
1434
1435             destreg = DECODE_RM_LONG_REGISTER(rh);
1436             DECODE_PRINTF(",");
1437             srcreg = DECODE_RM_BYTE_REGISTER(rl);
1438             DECODE_PRINTF("\n");
1439             TRACE_AND_STEP();
1440             *destreg = (s32)((s8)*srcreg);
1441         } else {
1442             u16 *destreg;
1443             u8  *srcreg;
1444
1445             destreg = DECODE_RM_WORD_REGISTER(rh);
1446             DECODE_PRINTF(",");
1447             srcreg = DECODE_RM_BYTE_REGISTER(rl);
1448             DECODE_PRINTF("\n");
1449             TRACE_AND_STEP();
1450             *destreg = (s16)((s8)*srcreg);
1451         }
1452     }
1453     DECODE_CLEAR_SEGOVR();
1454     END_OF_INSTR();
1455 }
1456
1457 /****************************************************************************
1458 REMARKS:
1459 Handles opcode 0x0f,0xbf
1460 ****************************************************************************/
1461 void x86emuOp2_movsx_word_R_RM(u8 X86EMU_UNUSED(op2))
1462 {
1463     int mod, rl, rh;
1464     uint srcoffset;
1465     u32 *destreg;
1466     u32 srcval;
1467     u16 *srcreg;
1468
1469     START_OF_INSTR();
1470     DECODE_PRINTF("MOVSX\t");
1471     FETCH_DECODE_MODRM(mod, rh, rl);
1472     if (mod < 3) {
1473         destreg = DECODE_RM_LONG_REGISTER(rh);
1474         DECODE_PRINTF(",");
1475         srcoffset = decode_rmXX_address(mod, rl);
1476         srcval = (s32)((s16)fetch_data_word(srcoffset));
1477         DECODE_PRINTF("\n");
1478         TRACE_AND_STEP();
1479         *destreg = srcval;
1480     } else {                     /* register to register */
1481         destreg = DECODE_RM_LONG_REGISTER(rh);
1482         DECODE_PRINTF(",");
1483         srcreg = DECODE_RM_WORD_REGISTER(rl);
1484         DECODE_PRINTF("\n");
1485         TRACE_AND_STEP();
1486         *destreg = (s32)((s16)*srcreg);
1487     }
1488     DECODE_CLEAR_SEGOVR();
1489     END_OF_INSTR();
1490 }
1491
1492 /***************************************************************************
1493  * Double byte operation code table:
1494  **************************************************************************/
1495 void (*x86emu_optab2[256])(u8) =
1496 {
1497 /*  0x00 */ x86emuOp2_illegal_op,  /* Group F (ring 0 PM)      */
1498 /*  0x01 */ x86emuOp2_illegal_op,  /* Group G (ring 0 PM)      */
1499 /*  0x02 */ x86emuOp2_illegal_op,  /* lar (ring 0 PM)          */
1500 /*  0x03 */ x86emuOp2_illegal_op,  /* lsl (ring 0 PM)          */
1501 /*  0x04 */ x86emuOp2_illegal_op,
1502 /*  0x05 */ x86emuOp2_illegal_op,  /* loadall (undocumented)   */
1503 /*  0x06 */ x86emuOp2_illegal_op,  /* clts (ring 0 PM)         */
1504 /*  0x07 */ x86emuOp2_illegal_op,  /* loadall (undocumented)   */
1505 /*  0x08 */ x86emuOp2_illegal_op,  /* invd (ring 0 PM)         */
1506 /*  0x09 */ x86emuOp2_illegal_op,  /* wbinvd (ring 0 PM)       */
1507 /*  0x0a */ x86emuOp2_illegal_op,
1508 /*  0x0b */ x86emuOp2_illegal_op,
1509 /*  0x0c */ x86emuOp2_illegal_op,
1510 /*  0x0d */ x86emuOp2_illegal_op,
1511 /*  0x0e */ x86emuOp2_illegal_op,
1512 /*  0x0f */ x86emuOp2_illegal_op,
1513
1514 /*  0x10 */ x86emuOp2_illegal_op,
1515 /*  0x11 */ x86emuOp2_illegal_op,
1516 /*  0x12 */ x86emuOp2_illegal_op,
1517 /*  0x13 */ x86emuOp2_illegal_op,
1518 /*  0x14 */ x86emuOp2_illegal_op,
1519 /*  0x15 */ x86emuOp2_illegal_op,
1520 /*  0x16 */ x86emuOp2_illegal_op,
1521 /*  0x17 */ x86emuOp2_illegal_op,
1522 /*  0x18 */ x86emuOp2_illegal_op,
1523 /*  0x19 */ x86emuOp2_illegal_op,
1524 /*  0x1a */ x86emuOp2_illegal_op,
1525 /*  0x1b */ x86emuOp2_illegal_op,
1526 /*  0x1c */ x86emuOp2_illegal_op,
1527 /*  0x1d */ x86emuOp2_illegal_op,
1528 /*  0x1e */ x86emuOp2_illegal_op,
1529 /*  0x1f */ x86emuOp2_illegal_op,
1530
1531 /*  0x20 */ x86emuOp2_illegal_op,  /* mov reg32,creg (ring 0 PM) */
1532 /*  0x21 */ x86emuOp2_illegal_op,  /* mov reg32,dreg (ring 0 PM) */
1533 /*  0x22 */ x86emuOp2_illegal_op,  /* mov creg,reg32 (ring 0 PM) */
1534 /*  0x23 */ x86emuOp2_illegal_op,  /* mov dreg,reg32 (ring 0 PM) */
1535 /*  0x24 */ x86emuOp2_illegal_op,  /* mov reg32,treg (ring 0 PM) */
1536 /*  0x25 */ x86emuOp2_illegal_op,
1537 /*  0x26 */ x86emuOp2_illegal_op,  /* mov treg,reg32 (ring 0 PM) */
1538 /*  0x27 */ x86emuOp2_illegal_op,
1539 /*  0x28 */ x86emuOp2_illegal_op,
1540 /*  0x29 */ x86emuOp2_illegal_op,
1541 /*  0x2a */ x86emuOp2_illegal_op,
1542 /*  0x2b */ x86emuOp2_illegal_op,
1543 /*  0x2c */ x86emuOp2_illegal_op,
1544 /*  0x2d */ x86emuOp2_illegal_op,
1545 /*  0x2e */ x86emuOp2_illegal_op,
1546 /*  0x2f */ x86emuOp2_illegal_op,
1547
1548 /*  0x30 */ x86emuOp2_illegal_op,
1549 /*  0x31 */ x86emuOp2_illegal_op,
1550 /*  0x32 */ x86emuOp2_illegal_op,
1551 /*  0x33 */ x86emuOp2_illegal_op,
1552 /*  0x34 */ x86emuOp2_illegal_op,
1553 /*  0x35 */ x86emuOp2_illegal_op,
1554 /*  0x36 */ x86emuOp2_illegal_op,
1555 /*  0x37 */ x86emuOp2_illegal_op,
1556 /*  0x38 */ x86emuOp2_illegal_op,
1557 /*  0x39 */ x86emuOp2_illegal_op,
1558 /*  0x3a */ x86emuOp2_illegal_op,
1559 /*  0x3b */ x86emuOp2_illegal_op,
1560 /*  0x3c */ x86emuOp2_illegal_op,
1561 /*  0x3d */ x86emuOp2_illegal_op,
1562 /*  0x3e */ x86emuOp2_illegal_op,
1563 /*  0x3f */ x86emuOp2_illegal_op,
1564
1565 /*  0x40 */ x86emuOp2_illegal_op,
1566 /*  0x41 */ x86emuOp2_illegal_op,
1567 /*  0x42 */ x86emuOp2_illegal_op,
1568 /*  0x43 */ x86emuOp2_illegal_op,
1569 /*  0x44 */ x86emuOp2_illegal_op,
1570 /*  0x45 */ x86emuOp2_illegal_op,
1571 /*  0x46 */ x86emuOp2_illegal_op,
1572 /*  0x47 */ x86emuOp2_illegal_op,
1573 /*  0x48 */ x86emuOp2_illegal_op,
1574 /*  0x49 */ x86emuOp2_illegal_op,
1575 /*  0x4a */ x86emuOp2_illegal_op,
1576 /*  0x4b */ x86emuOp2_illegal_op,
1577 /*  0x4c */ x86emuOp2_illegal_op,
1578 /*  0x4d */ x86emuOp2_illegal_op,
1579 /*  0x4e */ x86emuOp2_illegal_op,
1580 /*  0x4f */ x86emuOp2_illegal_op,
1581
1582 /*  0x50 */ x86emuOp2_illegal_op,
1583 /*  0x51 */ x86emuOp2_illegal_op,
1584 /*  0x52 */ x86emuOp2_illegal_op,
1585 /*  0x53 */ x86emuOp2_illegal_op,
1586 /*  0x54 */ x86emuOp2_illegal_op,
1587 /*  0x55 */ x86emuOp2_illegal_op,
1588 /*  0x56 */ x86emuOp2_illegal_op,
1589 /*  0x57 */ x86emuOp2_illegal_op,
1590 /*  0x58 */ x86emuOp2_illegal_op,
1591 /*  0x59 */ x86emuOp2_illegal_op,
1592 /*  0x5a */ x86emuOp2_illegal_op,
1593 /*  0x5b */ x86emuOp2_illegal_op,
1594 /*  0x5c */ x86emuOp2_illegal_op,
1595 /*  0x5d */ x86emuOp2_illegal_op,
1596 /*  0x5e */ x86emuOp2_illegal_op,
1597 /*  0x5f */ x86emuOp2_illegal_op,
1598
1599 /*  0x60 */ x86emuOp2_illegal_op,
1600 /*  0x61 */ x86emuOp2_illegal_op,
1601 /*  0x62 */ x86emuOp2_illegal_op,
1602 /*  0x63 */ x86emuOp2_illegal_op,
1603 /*  0x64 */ x86emuOp2_illegal_op,
1604 /*  0x65 */ x86emuOp2_illegal_op,
1605 /*  0x66 */ x86emuOp2_illegal_op,
1606 /*  0x67 */ x86emuOp2_illegal_op,
1607 /*  0x68 */ x86emuOp2_illegal_op,
1608 /*  0x69 */ x86emuOp2_illegal_op,
1609 /*  0x6a */ x86emuOp2_illegal_op,
1610 /*  0x6b */ x86emuOp2_illegal_op,
1611 /*  0x6c */ x86emuOp2_illegal_op,
1612 /*  0x6d */ x86emuOp2_illegal_op,
1613 /*  0x6e */ x86emuOp2_illegal_op,
1614 /*  0x6f */ x86emuOp2_illegal_op,
1615
1616 /*  0x70 */ x86emuOp2_illegal_op,
1617 /*  0x71 */ x86emuOp2_illegal_op,
1618 /*  0x72 */ x86emuOp2_illegal_op,
1619 /*  0x73 */ x86emuOp2_illegal_op,
1620 /*  0x74 */ x86emuOp2_illegal_op,
1621 /*  0x75 */ x86emuOp2_illegal_op,
1622 /*  0x76 */ x86emuOp2_illegal_op,
1623 /*  0x77 */ x86emuOp2_illegal_op,
1624 /*  0x78 */ x86emuOp2_illegal_op,
1625 /*  0x79 */ x86emuOp2_illegal_op,
1626 /*  0x7a */ x86emuOp2_illegal_op,
1627 /*  0x7b */ x86emuOp2_illegal_op,
1628 /*  0x7c */ x86emuOp2_illegal_op,
1629 /*  0x7d */ x86emuOp2_illegal_op,
1630 /*  0x7e */ x86emuOp2_illegal_op,
1631 /*  0x7f */ x86emuOp2_illegal_op,
1632
1633 /*  0x80 */ x86emuOp2_long_jump,
1634 /*  0x81 */ x86emuOp2_long_jump,
1635 /*  0x82 */ x86emuOp2_long_jump,
1636 /*  0x83 */ x86emuOp2_long_jump,
1637 /*  0x84 */ x86emuOp2_long_jump,
1638 /*  0x85 */ x86emuOp2_long_jump,
1639 /*  0x86 */ x86emuOp2_long_jump,
1640 /*  0x87 */ x86emuOp2_long_jump,
1641 /*  0x88 */ x86emuOp2_long_jump,
1642 /*  0x89 */ x86emuOp2_long_jump,
1643 /*  0x8a */ x86emuOp2_long_jump,
1644 /*  0x8b */ x86emuOp2_long_jump,
1645 /*  0x8c */ x86emuOp2_long_jump,
1646 /*  0x8d */ x86emuOp2_long_jump,
1647 /*  0x8e */ x86emuOp2_long_jump,
1648 /*  0x8f */ x86emuOp2_long_jump,
1649
1650 /*  0x90 */ x86emuOp2_set_byte,
1651 /*  0x91 */ x86emuOp2_set_byte,
1652 /*  0x92 */ x86emuOp2_set_byte,
1653 /*  0x93 */ x86emuOp2_set_byte,
1654 /*  0x94 */ x86emuOp2_set_byte,
1655 /*  0x95 */ x86emuOp2_set_byte,
1656 /*  0x96 */ x86emuOp2_set_byte,
1657 /*  0x97 */ x86emuOp2_set_byte,
1658 /*  0x98 */ x86emuOp2_set_byte,
1659 /*  0x99 */ x86emuOp2_set_byte,
1660 /*  0x9a */ x86emuOp2_set_byte,
1661 /*  0x9b */ x86emuOp2_set_byte,
1662 /*  0x9c */ x86emuOp2_set_byte,
1663 /*  0x9d */ x86emuOp2_set_byte,
1664 /*  0x9e */ x86emuOp2_set_byte,
1665 /*  0x9f */ x86emuOp2_set_byte,
1666
1667 /*  0xa0 */ x86emuOp2_push_FS,
1668 /*  0xa1 */ x86emuOp2_pop_FS,
1669 /*  0xa2 */ x86emuOp2_illegal_op,
1670 /*  0xa3 */ x86emuOp2_bt_R,
1671 /*  0xa4 */ x86emuOp2_shld_IMM,
1672 /*  0xa5 */ x86emuOp2_shld_CL,
1673 /*  0xa6 */ x86emuOp2_illegal_op,
1674 /*  0xa7 */ x86emuOp2_illegal_op,
1675 /*  0xa8 */ x86emuOp2_push_GS,
1676 /*  0xa9 */ x86emuOp2_pop_GS,
1677 /*  0xaa */ x86emuOp2_illegal_op,
1678 /*  0xab */ x86emuOp2_bt_R,
1679 /*  0xac */ x86emuOp2_shrd_IMM,
1680 /*  0xad */ x86emuOp2_shrd_CL,
1681 /*  0xae */ x86emuOp2_illegal_op,
1682 /*  0xaf */ x86emuOp2_imul_R_RM,
1683
1684 /*  0xb0 */ x86emuOp2_illegal_op,  /* TODO: cmpxchg */
1685 /*  0xb1 */ x86emuOp2_illegal_op,  /* TODO: cmpxchg */
1686 /*  0xb2 */ x86emuOp2_lss_R_IMM,
1687 /*  0xb3 */ x86emuOp2_btr_R,
1688 /*  0xb4 */ x86emuOp2_lfs_R_IMM,
1689 /*  0xb5 */ x86emuOp2_lgs_R_IMM,
1690 /*  0xb6 */ x86emuOp2_movzx_byte_R_RM,
1691 /*  0xb7 */ x86emuOp2_movzx_word_R_RM,
1692 /*  0xb8 */ x86emuOp2_illegal_op,
1693 /*  0xb9 */ x86emuOp2_illegal_op,
1694 /*  0xba */ x86emuOp2_btX_I,
1695 /*  0xbb */ x86emuOp2_btc_R,
1696 /*  0xbc */ x86emuOp2_bsf,
1697 /*  0xbd */ x86emuOp2_bsr,
1698 /*  0xbe */ x86emuOp2_movsx_byte_R_RM,
1699 /*  0xbf */ x86emuOp2_movsx_word_R_RM,
1700
1701 /*  0xc0 */ x86emuOp2_illegal_op,  /* TODO: xadd */
1702 /*  0xc1 */ x86emuOp2_illegal_op,  /* TODO: xadd */
1703 /*  0xc2 */ x86emuOp2_illegal_op,
1704 /*  0xc3 */ x86emuOp2_illegal_op,
1705 /*  0xc4 */ x86emuOp2_illegal_op,
1706 /*  0xc5 */ x86emuOp2_illegal_op,
1707 /*  0xc6 */ x86emuOp2_illegal_op,
1708 /*  0xc7 */ x86emuOp2_illegal_op,
1709 /*  0xc8 */ x86emuOp2_illegal_op,  /* TODO: bswap */
1710 /*  0xc9 */ x86emuOp2_illegal_op,  /* TODO: bswap */
1711 /*  0xca */ x86emuOp2_illegal_op,  /* TODO: bswap */
1712 /*  0xcb */ x86emuOp2_illegal_op,  /* TODO: bswap */
1713 /*  0xcc */ x86emuOp2_illegal_op,  /* TODO: bswap */
1714 /*  0xcd */ x86emuOp2_illegal_op,  /* TODO: bswap */
1715 /*  0xce */ x86emuOp2_illegal_op,  /* TODO: bswap */
1716 /*  0xcf */ x86emuOp2_illegal_op,  /* TODO: bswap */
1717
1718 /*  0xd0 */ x86emuOp2_illegal_op,
1719 /*  0xd1 */ x86emuOp2_illegal_op,
1720 /*  0xd2 */ x86emuOp2_illegal_op,
1721 /*  0xd3 */ x86emuOp2_illegal_op,
1722 /*  0xd4 */ x86emuOp2_illegal_op,
1723 /*  0xd5 */ x86emuOp2_illegal_op,
1724 /*  0xd6 */ x86emuOp2_illegal_op,
1725 /*  0xd7 */ x86emuOp2_illegal_op,
1726 /*  0xd8 */ x86emuOp2_illegal_op,
1727 /*  0xd9 */ x86emuOp2_illegal_op,
1728 /*  0xda */ x86emuOp2_illegal_op,
1729 /*  0xdb */ x86emuOp2_illegal_op,
1730 /*  0xdc */ x86emuOp2_illegal_op,
1731 /*  0xdd */ x86emuOp2_illegal_op,
1732 /*  0xde */ x86emuOp2_illegal_op,
1733 /*  0xdf */ x86emuOp2_illegal_op,
1734
1735 /*  0xe0 */ x86emuOp2_illegal_op,
1736 /*  0xe1 */ x86emuOp2_illegal_op,
1737 /*  0xe2 */ x86emuOp2_illegal_op,
1738 /*  0xe3 */ x86emuOp2_illegal_op,
1739 /*  0xe4 */ x86emuOp2_illegal_op,
1740 /*  0xe5 */ x86emuOp2_illegal_op,
1741 /*  0xe6 */ x86emuOp2_illegal_op,
1742 /*  0xe7 */ x86emuOp2_illegal_op,
1743 /*  0xe8 */ x86emuOp2_illegal_op,
1744 /*  0xe9 */ x86emuOp2_illegal_op,
1745 /*  0xea */ x86emuOp2_illegal_op,
1746 /*  0xeb */ x86emuOp2_illegal_op,
1747 /*  0xec */ x86emuOp2_illegal_op,
1748 /*  0xed */ x86emuOp2_illegal_op,
1749 /*  0xee */ x86emuOp2_illegal_op,
1750 /*  0xef */ x86emuOp2_illegal_op,
1751
1752 /*  0xf0 */ x86emuOp2_illegal_op,
1753 /*  0xf1 */ x86emuOp2_illegal_op,
1754 /*  0xf2 */ x86emuOp2_illegal_op,
1755 /*  0xf3 */ x86emuOp2_illegal_op,
1756 /*  0xf4 */ x86emuOp2_illegal_op,
1757 /*  0xf5 */ x86emuOp2_illegal_op,
1758 /*  0xf6 */ x86emuOp2_illegal_op,
1759 /*  0xf7 */ x86emuOp2_illegal_op,
1760 /*  0xf8 */ x86emuOp2_illegal_op,
1761 /*  0xf9 */ x86emuOp2_illegal_op,
1762 /*  0xfa */ x86emuOp2_illegal_op,
1763 /*  0xfb */ x86emuOp2_illegal_op,
1764 /*  0xfc */ x86emuOp2_illegal_op,
1765 /*  0xfd */ x86emuOp2_illegal_op,
1766 /*  0xfe */ x86emuOp2_illegal_op,
1767 /*  0xff */ x86emuOp2_illegal_op,
1768 };