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