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