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