1 /****************************************************************************
2 *
3 *						Realmode X86 Emulator Library
4 *
5 *            	Copyright (C) 1996-1999 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 "x86emu/x86emui.h"
42 
43 #undef bswap_32
44 #define bswap_32(x) (((x & 0xff000000) >> 24) | \
45 		     ((x & 0x00ff0000) >> 8) | \
46 		     ((x & 0x0000ff00) << 8) | \
47 		     ((x & 0x000000ff) << 24))
48 
49 /*----------------------------- Implementation ----------------------------*/
50 
51 /****************************************************************************
52 PARAMETERS:
53 op1 - Instruction op code
54 
55 REMARKS:
56 Handles illegal opcodes.
57 ****************************************************************************/
58 static void
x86emuOp2_illegal_op(u8 op2)59 x86emuOp2_illegal_op(u8 op2)
60 {
61     START_OF_INSTR();
62     DECODE_PRINTF("ILLEGAL EXTENDED X86 OPCODE\n");
63     TRACE_REGS();
64     printk("%04x:%04x: %02X ILLEGAL EXTENDED X86 OPCODE!\n",
65            M.x86.R_CS, M.x86.R_IP - 2, op2);
66     HALT_SYS();
67     END_OF_INSTR();
68 }
69 
70 #define xorl(a,b)   ((a) && !(b)) || (!(a) && (b))
71 
72 /****************************************************************************
73 REMARKS:
74 Handles opcode 0x0f,0x31
75 ****************************************************************************/
76 static void
x86emuOp2_rdtsc(u8 X86EMU_UNUSED (op2))77 x86emuOp2_rdtsc(u8 X86EMU_UNUSED(op2))
78 {
79 #ifdef __HAS_LONG_LONG__
80     static u64 counter = 0;
81 #else
82     static u32 counter = 0;
83 #endif
84 
85     counter += 0x10000;
86 
87     /* read timestamp counter */
88     /*
89      * Note that instead of actually trying to accurately measure this, we just
90      * increase the counter by a fixed amount every time we hit one of these
91      * instructions.  Feel free to come up with a better method.
92      */
93     START_OF_INSTR();
94     DECODE_PRINTF("RDTSC\n");
95     TRACE_AND_STEP();
96 #ifdef __HAS_LONG_LONG__
97     M.x86.R_EAX = counter & 0xffffffff;
98     M.x86.R_EDX = counter >> 32;
99 #else
100     M.x86.R_EAX = counter;
101     M.x86.R_EDX = 0;
102 #endif
103     DECODE_CLEAR_SEGOVR();
104     END_OF_INSTR();
105 }
106 
107 /****************************************************************************
108 REMARKS:
109 Handles opcode 0x0f,0x80-0x8F
110 ****************************************************************************/
111 static void
x86emuOp2_long_jump(u8 op2)112 x86emuOp2_long_jump(u8 op2)
113 {
114     s32 target;
115     const char *name = NULL;
116     int cond = 0;
117 
118     /* conditional jump to word offset. */
119     START_OF_INSTR();
120     switch (op2) {
121     case 0x80:
122         name = "JO\t";
123         cond = ACCESS_FLAG(F_OF);
124         break;
125     case 0x81:
126         name = "JNO\t";
127         cond = !ACCESS_FLAG(F_OF);
128         break;
129     case 0x82:
130         name = "JB\t";
131         cond = ACCESS_FLAG(F_CF);
132         break;
133     case 0x83:
134         name = "JNB\t";
135         cond = !ACCESS_FLAG(F_CF);
136         break;
137     case 0x84:
138         name = "JZ\t";
139         cond = ACCESS_FLAG(F_ZF);
140         break;
141     case 0x85:
142         name = "JNZ\t";
143         cond = !ACCESS_FLAG(F_ZF);
144         break;
145     case 0x86:
146         name = "JBE\t";
147         cond = ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF);
148         break;
149     case 0x87:
150         name = "JNBE\t";
151         cond = !(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF));
152         break;
153     case 0x88:
154         name = "JS\t";
155         cond = ACCESS_FLAG(F_SF);
156         break;
157     case 0x89:
158         name = "JNS\t";
159         cond = !ACCESS_FLAG(F_SF);
160         break;
161     case 0x8a:
162         name = "JP\t";
163         cond = ACCESS_FLAG(F_PF);
164         break;
165     case 0x8b:
166         name = "JNP\t";
167         cond = !ACCESS_FLAG(F_PF);
168         break;
169     case 0x8c:
170         name = "JL\t";
171         cond = xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
172         break;
173     case 0x8d:
174         name = "JNL\t";
175         cond = !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)));
176         break;
177     case 0x8e:
178         name = "JLE\t";
179         cond = (xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
180                 ACCESS_FLAG(F_ZF));
181         break;
182     case 0x8f:
183         name = "JNLE\t";
184         cond = !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
185                  ACCESS_FLAG(F_ZF));
186         break;
187     }
188     DECODE_PRINTF(name);
189     (void) name;
190     target = (s16) fetch_word_imm();
191     target += (s16) M.x86.R_IP;
192     DECODE_PRINTF2("%04x\n", target);
193     TRACE_AND_STEP();
194     if (cond)
195         M.x86.R_IP = (u16) target;
196     DECODE_CLEAR_SEGOVR();
197     END_OF_INSTR();
198 }
199 
200 /****************************************************************************
201 REMARKS:
202 Handles opcode 0x0f,0x90-0x9F
203 ****************************************************************************/
204 static void
x86emuOp2_set_byte(u8 op2)205 x86emuOp2_set_byte(u8 op2)
206 {
207     int mod, rl, rh;
208     uint destoffset;
209     u8 *destreg;
210     const char *name = NULL;
211     int cond = 0;
212 
213     START_OF_INSTR();
214     switch (op2) {
215     case 0x90:
216         name = "SETO\t";
217         cond = ACCESS_FLAG(F_OF);
218         break;
219     case 0x91:
220         name = "SETNO\t";
221         cond = !ACCESS_FLAG(F_OF);
222         break;
223     case 0x92:
224         name = "SETB\t";
225         cond = ACCESS_FLAG(F_CF);
226         break;
227     case 0x93:
228         name = "SETNB\t";
229         cond = !ACCESS_FLAG(F_CF);
230         break;
231     case 0x94:
232         name = "SETZ\t";
233         cond = ACCESS_FLAG(F_ZF);
234         break;
235     case 0x95:
236         name = "SETNZ\t";
237         cond = !ACCESS_FLAG(F_ZF);
238         break;
239     case 0x96:
240         name = "SETBE\t";
241         cond = ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF);
242         break;
243     case 0x97:
244         name = "SETNBE\t";
245         cond = !(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF));
246         break;
247     case 0x98:
248         name = "SETS\t";
249         cond = ACCESS_FLAG(F_SF);
250         break;
251     case 0x99:
252         name = "SETNS\t";
253         cond = !ACCESS_FLAG(F_SF);
254         break;
255     case 0x9a:
256         name = "SETP\t";
257         cond = ACCESS_FLAG(F_PF);
258         break;
259     case 0x9b:
260         name = "SETNP\t";
261         cond = !ACCESS_FLAG(F_PF);
262         break;
263     case 0x9c:
264         name = "SETL\t";
265         cond = xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
266         break;
267     case 0x9d:
268         name = "SETNL\t";
269         cond = xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
270         break;
271     case 0x9e:
272         name = "SETLE\t";
273         cond = (xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
274                 ACCESS_FLAG(F_ZF));
275         break;
276     case 0x9f:
277         name = "SETNLE\t";
278         cond = !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
279                  ACCESS_FLAG(F_ZF));
280         break;
281     }
282     DECODE_PRINTF(name);
283     (void) name;
284     FETCH_DECODE_MODRM(mod, rh, rl);
285     switch (mod) {
286     case 0:
287         destoffset = decode_rm00_address(rl);
288         TRACE_AND_STEP();
289         store_data_byte(destoffset, cond ? 0x01 : 0x00);
290         break;
291     case 1:
292         destoffset = decode_rm01_address(rl);
293         TRACE_AND_STEP();
294         store_data_byte(destoffset, cond ? 0x01 : 0x00);
295         break;
296     case 2:
297         destoffset = decode_rm10_address(rl);
298         TRACE_AND_STEP();
299         store_data_byte(destoffset, cond ? 0x01 : 0x00);
300         break;
301     case 3:                    /* register to register */
302         destreg = DECODE_RM_BYTE_REGISTER(rl);
303         TRACE_AND_STEP();
304         *destreg = cond ? 0x01 : 0x00;
305         break;
306     }
307     DECODE_CLEAR_SEGOVR();
308     END_OF_INSTR();
309 }
310 
311 /****************************************************************************
312 REMARKS:
313 Handles opcode 0x0f,0xa0
314 ****************************************************************************/
315 static void
x86emuOp2_push_FS(u8 X86EMU_UNUSED (op2))316 x86emuOp2_push_FS(u8 X86EMU_UNUSED(op2))
317 {
318     START_OF_INSTR();
319     DECODE_PRINTF("PUSH\tFS\n");
320     TRACE_AND_STEP();
321     push_word(M.x86.R_FS);
322     DECODE_CLEAR_SEGOVR();
323     END_OF_INSTR();
324 }
325 
326 /****************************************************************************
327 REMARKS:
328 Handles opcode 0x0f,0xa1
329 ****************************************************************************/
330 static void
x86emuOp2_pop_FS(u8 X86EMU_UNUSED (op2))331 x86emuOp2_pop_FS(u8 X86EMU_UNUSED(op2))
332 {
333     START_OF_INSTR();
334     DECODE_PRINTF("POP\tFS\n");
335     TRACE_AND_STEP();
336     M.x86.R_FS = pop_word();
337     DECODE_CLEAR_SEGOVR();
338     END_OF_INSTR();
339 }
340 
341 /****************************************************************************
342 REMARKS: CPUID takes EAX/ECX as inputs, writes EAX/EBX/ECX/EDX as output
343 Handles opcode 0x0f,0xa2
344 ****************************************************************************/
345 static void
x86emuOp2_cpuid(u8 X86EMU_UNUSED (op2))346 x86emuOp2_cpuid(u8 X86EMU_UNUSED(op2))
347 {
348     START_OF_INSTR();
349     DECODE_PRINTF("CPUID\n");
350     TRACE_AND_STEP();
351     cpuid();
352     DECODE_CLEAR_SEGOVR();
353     END_OF_INSTR();
354 }
355 
356 /****************************************************************************
357 REMARKS:
358 Handles opcode 0x0f,0xa3
359 ****************************************************************************/
360 static void
x86emuOp2_bt_R(u8 X86EMU_UNUSED (op2))361 x86emuOp2_bt_R(u8 X86EMU_UNUSED(op2))
362 {
363     int mod, rl, rh;
364     uint srcoffset;
365     int bit, disp;
366 
367     START_OF_INSTR();
368     DECODE_PRINTF("BT\t");
369     FETCH_DECODE_MODRM(mod, rh, rl);
370     switch (mod) {
371     case 0:
372         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
373             u32 srcval;
374             u32 *shiftreg;
375 
376             srcoffset = decode_rm00_address(rl);
377             DECODE_PRINTF(",");
378             shiftreg = DECODE_RM_LONG_REGISTER(rh);
379             TRACE_AND_STEP();
380             bit = *shiftreg & 0x1F;
381             disp = (s16) * shiftreg >> 5;
382             srcval = fetch_data_long(srcoffset + disp);
383             CONDITIONAL_SET_FLAG(srcval & (0x1 << bit), F_CF);
384         }
385         else {
386             u16 srcval;
387             u16 *shiftreg;
388 
389             srcoffset = decode_rm00_address(rl);
390             DECODE_PRINTF(",");
391             shiftreg = DECODE_RM_WORD_REGISTER(rh);
392             TRACE_AND_STEP();
393             bit = *shiftreg & 0xF;
394             disp = (s16) * shiftreg >> 4;
395             srcval = fetch_data_word(srcoffset + disp);
396             CONDITIONAL_SET_FLAG(srcval & (0x1 << bit), F_CF);
397         }
398         break;
399     case 1:
400         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
401             u32 srcval;
402             u32 *shiftreg;
403 
404             srcoffset = decode_rm01_address(rl);
405             DECODE_PRINTF(",");
406             shiftreg = DECODE_RM_LONG_REGISTER(rh);
407             TRACE_AND_STEP();
408             bit = *shiftreg & 0x1F;
409             disp = (s16) * shiftreg >> 5;
410             srcval = fetch_data_long(srcoffset + disp);
411             CONDITIONAL_SET_FLAG(srcval & (0x1 << bit), F_CF);
412         }
413         else {
414             u16 srcval;
415             u16 *shiftreg;
416 
417             srcoffset = decode_rm01_address(rl);
418             DECODE_PRINTF(",");
419             shiftreg = DECODE_RM_WORD_REGISTER(rh);
420             TRACE_AND_STEP();
421             bit = *shiftreg & 0xF;
422             disp = (s16) * shiftreg >> 4;
423             srcval = fetch_data_word(srcoffset + disp);
424             CONDITIONAL_SET_FLAG(srcval & (0x1 << bit), F_CF);
425         }
426         break;
427     case 2:
428         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
429             u32 srcval;
430             u32 *shiftreg;
431 
432             srcoffset = decode_rm10_address(rl);
433             DECODE_PRINTF(",");
434             shiftreg = DECODE_RM_LONG_REGISTER(rh);
435             TRACE_AND_STEP();
436             bit = *shiftreg & 0x1F;
437             disp = (s16) * shiftreg >> 5;
438             srcval = fetch_data_long(srcoffset + disp);
439             CONDITIONAL_SET_FLAG(srcval & (0x1 << bit), F_CF);
440         }
441         else {
442             u16 srcval;
443             u16 *shiftreg;
444 
445             srcoffset = decode_rm10_address(rl);
446             DECODE_PRINTF(",");
447             shiftreg = DECODE_RM_WORD_REGISTER(rh);
448             TRACE_AND_STEP();
449             bit = *shiftreg & 0xF;
450             disp = (s16) * shiftreg >> 4;
451             srcval = fetch_data_word(srcoffset + disp);
452             CONDITIONAL_SET_FLAG(srcval & (0x1 << bit), F_CF);
453         }
454         break;
455     case 3:                    /* register to register */
456         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
457             u32 *srcreg, *shiftreg;
458 
459             srcreg = DECODE_RM_LONG_REGISTER(rl);
460             DECODE_PRINTF(",");
461             shiftreg = DECODE_RM_LONG_REGISTER(rh);
462             TRACE_AND_STEP();
463             bit = *shiftreg & 0x1F;
464             CONDITIONAL_SET_FLAG(*srcreg & (0x1 << bit), F_CF);
465         }
466         else {
467             u16 *srcreg, *shiftreg;
468 
469             srcreg = DECODE_RM_WORD_REGISTER(rl);
470             DECODE_PRINTF(",");
471             shiftreg = DECODE_RM_WORD_REGISTER(rh);
472             TRACE_AND_STEP();
473             bit = *shiftreg & 0xF;
474             CONDITIONAL_SET_FLAG(*srcreg & (0x1 << bit), F_CF);
475         }
476         break;
477     }
478     DECODE_CLEAR_SEGOVR();
479     END_OF_INSTR();
480 }
481 
482 /****************************************************************************
483 REMARKS:
484 Handles opcode 0x0f,0xa4
485 ****************************************************************************/
486 static void
x86emuOp2_shld_IMM(u8 X86EMU_UNUSED (op2))487 x86emuOp2_shld_IMM(u8 X86EMU_UNUSED(op2))
488 {
489     int mod, rl, rh;
490     uint destoffset;
491     u8 shift;
492 
493     START_OF_INSTR();
494     DECODE_PRINTF("SHLD\t");
495     FETCH_DECODE_MODRM(mod, rh, rl);
496     switch (mod) {
497     case 0:
498         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
499             u32 destval;
500             u32 *shiftreg;
501 
502             destoffset = decode_rm00_address(rl);
503             DECODE_PRINTF(",");
504             shiftreg = DECODE_RM_LONG_REGISTER(rh);
505             DECODE_PRINTF(",");
506             shift = fetch_byte_imm();
507             DECODE_PRINTF2("%d\n", shift);
508             TRACE_AND_STEP();
509             destval = fetch_data_long(destoffset);
510             destval = shld_long(destval, *shiftreg, shift);
511             store_data_long(destoffset, destval);
512         }
513         else {
514             u16 destval;
515             u16 *shiftreg;
516 
517             destoffset = decode_rm00_address(rl);
518             DECODE_PRINTF(",");
519             shiftreg = DECODE_RM_WORD_REGISTER(rh);
520             DECODE_PRINTF(",");
521             shift = fetch_byte_imm();
522             DECODE_PRINTF2("%d\n", shift);
523             TRACE_AND_STEP();
524             destval = fetch_data_word(destoffset);
525             destval = shld_word(destval, *shiftreg, shift);
526             store_data_word(destoffset, destval);
527         }
528         break;
529     case 1:
530         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
531             u32 destval;
532             u32 *shiftreg;
533 
534             destoffset = decode_rm01_address(rl);
535             DECODE_PRINTF(",");
536             shiftreg = DECODE_RM_LONG_REGISTER(rh);
537             DECODE_PRINTF(",");
538             shift = fetch_byte_imm();
539             DECODE_PRINTF2("%d\n", shift);
540             TRACE_AND_STEP();
541             destval = fetch_data_long(destoffset);
542             destval = shld_long(destval, *shiftreg, shift);
543             store_data_long(destoffset, destval);
544         }
545         else {
546             u16 destval;
547             u16 *shiftreg;
548 
549             destoffset = decode_rm01_address(rl);
550             DECODE_PRINTF(",");
551             shiftreg = DECODE_RM_WORD_REGISTER(rh);
552             DECODE_PRINTF(",");
553             shift = fetch_byte_imm();
554             DECODE_PRINTF2("%d\n", shift);
555             TRACE_AND_STEP();
556             destval = fetch_data_word(destoffset);
557             destval = shld_word(destval, *shiftreg, shift);
558             store_data_word(destoffset, destval);
559         }
560         break;
561     case 2:
562         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
563             u32 destval;
564             u32 *shiftreg;
565 
566             destoffset = decode_rm10_address(rl);
567             DECODE_PRINTF(",");
568             shiftreg = DECODE_RM_LONG_REGISTER(rh);
569             DECODE_PRINTF(",");
570             shift = fetch_byte_imm();
571             DECODE_PRINTF2("%d\n", shift);
572             TRACE_AND_STEP();
573             destval = fetch_data_long(destoffset);
574             destval = shld_long(destval, *shiftreg, shift);
575             store_data_long(destoffset, destval);
576         }
577         else {
578             u16 destval;
579             u16 *shiftreg;
580 
581             destoffset = decode_rm10_address(rl);
582             DECODE_PRINTF(",");
583             shiftreg = DECODE_RM_WORD_REGISTER(rh);
584             DECODE_PRINTF(",");
585             shift = fetch_byte_imm();
586             DECODE_PRINTF2("%d\n", shift);
587             TRACE_AND_STEP();
588             destval = fetch_data_word(destoffset);
589             destval = shld_word(destval, *shiftreg, shift);
590             store_data_word(destoffset, destval);
591         }
592         break;
593     case 3:                    /* register to register */
594         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
595             u32 *destreg, *shiftreg;
596 
597             destreg = DECODE_RM_LONG_REGISTER(rl);
598             DECODE_PRINTF(",");
599             shiftreg = DECODE_RM_LONG_REGISTER(rh);
600             DECODE_PRINTF(",");
601             shift = fetch_byte_imm();
602             DECODE_PRINTF2("%d\n", shift);
603             TRACE_AND_STEP();
604             *destreg = shld_long(*destreg, *shiftreg, shift);
605         }
606         else {
607             u16 *destreg, *shiftreg;
608 
609             destreg = DECODE_RM_WORD_REGISTER(rl);
610             DECODE_PRINTF(",");
611             shiftreg = DECODE_RM_WORD_REGISTER(rh);
612             DECODE_PRINTF(",");
613             shift = fetch_byte_imm();
614             DECODE_PRINTF2("%d\n", shift);
615             TRACE_AND_STEP();
616             *destreg = shld_word(*destreg, *shiftreg, shift);
617         }
618         break;
619     }
620     DECODE_CLEAR_SEGOVR();
621     END_OF_INSTR();
622 }
623 
624 /****************************************************************************
625 REMARKS:
626 Handles opcode 0x0f,0xa5
627 ****************************************************************************/
628 static void
x86emuOp2_shld_CL(u8 X86EMU_UNUSED (op2))629 x86emuOp2_shld_CL(u8 X86EMU_UNUSED(op2))
630 {
631     int mod, rl, rh;
632     uint destoffset;
633 
634     START_OF_INSTR();
635     DECODE_PRINTF("SHLD\t");
636     FETCH_DECODE_MODRM(mod, rh, rl);
637     switch (mod) {
638     case 0:
639         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
640             u32 destval;
641             u32 *shiftreg;
642 
643             destoffset = decode_rm00_address(rl);
644             DECODE_PRINTF(",");
645             shiftreg = DECODE_RM_LONG_REGISTER(rh);
646             DECODE_PRINTF(",CL\n");
647             TRACE_AND_STEP();
648             destval = fetch_data_long(destoffset);
649             destval = shld_long(destval, *shiftreg, M.x86.R_CL);
650             store_data_long(destoffset, destval);
651         }
652         else {
653             u16 destval;
654             u16 *shiftreg;
655 
656             destoffset = decode_rm00_address(rl);
657             DECODE_PRINTF(",");
658             shiftreg = DECODE_RM_WORD_REGISTER(rh);
659             DECODE_PRINTF(",CL\n");
660             TRACE_AND_STEP();
661             destval = fetch_data_word(destoffset);
662             destval = shld_word(destval, *shiftreg, M.x86.R_CL);
663             store_data_word(destoffset, destval);
664         }
665         break;
666     case 1:
667         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
668             u32 destval;
669             u32 *shiftreg;
670 
671             destoffset = decode_rm01_address(rl);
672             DECODE_PRINTF(",");
673             shiftreg = DECODE_RM_LONG_REGISTER(rh);
674             DECODE_PRINTF(",CL\n");
675             TRACE_AND_STEP();
676             destval = fetch_data_long(destoffset);
677             destval = shld_long(destval, *shiftreg, M.x86.R_CL);
678             store_data_long(destoffset, destval);
679         }
680         else {
681             u16 destval;
682             u16 *shiftreg;
683 
684             destoffset = decode_rm01_address(rl);
685             DECODE_PRINTF(",");
686             shiftreg = DECODE_RM_WORD_REGISTER(rh);
687             DECODE_PRINTF(",CL\n");
688             TRACE_AND_STEP();
689             destval = fetch_data_word(destoffset);
690             destval = shld_word(destval, *shiftreg, M.x86.R_CL);
691             store_data_word(destoffset, destval);
692         }
693         break;
694     case 2:
695         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
696             u32 destval;
697             u32 *shiftreg;
698 
699             destoffset = decode_rm10_address(rl);
700             DECODE_PRINTF(",");
701             shiftreg = DECODE_RM_LONG_REGISTER(rh);
702             DECODE_PRINTF(",CL\n");
703             TRACE_AND_STEP();
704             destval = fetch_data_long(destoffset);
705             destval = shld_long(destval, *shiftreg, M.x86.R_CL);
706             store_data_long(destoffset, destval);
707         }
708         else {
709             u16 destval;
710             u16 *shiftreg;
711 
712             destoffset = decode_rm10_address(rl);
713             DECODE_PRINTF(",");
714             shiftreg = DECODE_RM_WORD_REGISTER(rh);
715             DECODE_PRINTF(",CL\n");
716             TRACE_AND_STEP();
717             destval = fetch_data_word(destoffset);
718             destval = shld_word(destval, *shiftreg, M.x86.R_CL);
719             store_data_word(destoffset, destval);
720         }
721         break;
722     case 3:                    /* register to register */
723         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
724             u32 *destreg, *shiftreg;
725 
726             destreg = DECODE_RM_LONG_REGISTER(rl);
727             DECODE_PRINTF(",");
728             shiftreg = DECODE_RM_LONG_REGISTER(rh);
729             DECODE_PRINTF(",CL\n");
730             TRACE_AND_STEP();
731             *destreg = shld_long(*destreg, *shiftreg, M.x86.R_CL);
732         }
733         else {
734             u16 *destreg, *shiftreg;
735 
736             destreg = DECODE_RM_WORD_REGISTER(rl);
737             DECODE_PRINTF(",");
738             shiftreg = DECODE_RM_WORD_REGISTER(rh);
739             DECODE_PRINTF(",CL\n");
740             TRACE_AND_STEP();
741             *destreg = shld_word(*destreg, *shiftreg, M.x86.R_CL);
742         }
743         break;
744     }
745     DECODE_CLEAR_SEGOVR();
746     END_OF_INSTR();
747 }
748 
749 /****************************************************************************
750 REMARKS:
751 Handles opcode 0x0f,0xa8
752 ****************************************************************************/
753 static void
x86emuOp2_push_GS(u8 X86EMU_UNUSED (op2))754 x86emuOp2_push_GS(u8 X86EMU_UNUSED(op2))
755 {
756     START_OF_INSTR();
757     DECODE_PRINTF("PUSH\tGS\n");
758     TRACE_AND_STEP();
759     push_word(M.x86.R_GS);
760     DECODE_CLEAR_SEGOVR();
761     END_OF_INSTR();
762 }
763 
764 /****************************************************************************
765 REMARKS:
766 Handles opcode 0x0f,0xa9
767 ****************************************************************************/
768 static void
x86emuOp2_pop_GS(u8 X86EMU_UNUSED (op2))769 x86emuOp2_pop_GS(u8 X86EMU_UNUSED(op2))
770 {
771     START_OF_INSTR();
772     DECODE_PRINTF("POP\tGS\n");
773     TRACE_AND_STEP();
774     M.x86.R_GS = pop_word();
775     DECODE_CLEAR_SEGOVR();
776     END_OF_INSTR();
777 }
778 
779 /****************************************************************************
780 REMARKS:
781 Handles opcode 0x0f,0xab
782 ****************************************************************************/
783 static void
x86emuOp2_bts_R(u8 X86EMU_UNUSED (op2))784 x86emuOp2_bts_R(u8 X86EMU_UNUSED(op2))
785 {
786     int mod, rl, rh;
787     uint srcoffset;
788     int bit, disp;
789 
790     START_OF_INSTR();
791     DECODE_PRINTF("BTS\t");
792     FETCH_DECODE_MODRM(mod, rh, rl);
793     switch (mod) {
794     case 0:
795         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
796             u32 srcval, mask;
797             u32 *shiftreg;
798 
799             srcoffset = decode_rm00_address(rl);
800             DECODE_PRINTF(",");
801             shiftreg = DECODE_RM_LONG_REGISTER(rh);
802             TRACE_AND_STEP();
803             bit = *shiftreg & 0x1F;
804             disp = (s16) * shiftreg >> 5;
805             srcval = fetch_data_long(srcoffset + disp);
806             mask = (0x1 << bit);
807             CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
808             store_data_long(srcoffset + disp, srcval | mask);
809         }
810         else {
811             u16 srcval, mask;
812             u16 *shiftreg;
813 
814             srcoffset = decode_rm00_address(rl);
815             DECODE_PRINTF(",");
816             shiftreg = DECODE_RM_WORD_REGISTER(rh);
817             TRACE_AND_STEP();
818             bit = *shiftreg & 0xF;
819             disp = (s16) * shiftreg >> 4;
820             srcval = fetch_data_word(srcoffset + disp);
821             mask = (u16) (0x1 << bit);
822             CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
823             store_data_word(srcoffset + disp, srcval | mask);
824         }
825         break;
826     case 1:
827         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
828             u32 srcval, mask;
829             u32 *shiftreg;
830 
831             srcoffset = decode_rm01_address(rl);
832             DECODE_PRINTF(",");
833             shiftreg = DECODE_RM_LONG_REGISTER(rh);
834             TRACE_AND_STEP();
835             bit = *shiftreg & 0x1F;
836             disp = (s16) * shiftreg >> 5;
837             srcval = fetch_data_long(srcoffset + disp);
838             mask = (0x1 << bit);
839             CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
840             store_data_long(srcoffset + disp, srcval | mask);
841         }
842         else {
843             u16 srcval, mask;
844             u16 *shiftreg;
845 
846             srcoffset = decode_rm01_address(rl);
847             DECODE_PRINTF(",");
848             shiftreg = DECODE_RM_WORD_REGISTER(rh);
849             TRACE_AND_STEP();
850             bit = *shiftreg & 0xF;
851             disp = (s16) * shiftreg >> 4;
852             srcval = fetch_data_word(srcoffset + disp);
853             mask = (u16) (0x1 << bit);
854             CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
855             store_data_word(srcoffset + disp, srcval | mask);
856         }
857         break;
858     case 2:
859         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
860             u32 srcval, mask;
861             u32 *shiftreg;
862 
863             srcoffset = decode_rm10_address(rl);
864             DECODE_PRINTF(",");
865             shiftreg = DECODE_RM_LONG_REGISTER(rh);
866             TRACE_AND_STEP();
867             bit = *shiftreg & 0x1F;
868             disp = (s16) * shiftreg >> 5;
869             srcval = fetch_data_long(srcoffset + disp);
870             mask = (0x1 << bit);
871             CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
872             store_data_long(srcoffset + disp, srcval | mask);
873         }
874         else {
875             u16 srcval, mask;
876             u16 *shiftreg;
877 
878             srcoffset = decode_rm10_address(rl);
879             DECODE_PRINTF(",");
880             shiftreg = DECODE_RM_WORD_REGISTER(rh);
881             TRACE_AND_STEP();
882             bit = *shiftreg & 0xF;
883             disp = (s16) * shiftreg >> 4;
884             srcval = fetch_data_word(srcoffset + disp);
885             mask = (u16) (0x1 << bit);
886             CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
887             store_data_word(srcoffset + disp, srcval | mask);
888         }
889         break;
890     case 3:                    /* register to register */
891         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
892             u32 *srcreg, *shiftreg;
893             u32 mask;
894 
895             srcreg = DECODE_RM_LONG_REGISTER(rl);
896             DECODE_PRINTF(",");
897             shiftreg = DECODE_RM_LONG_REGISTER(rh);
898             TRACE_AND_STEP();
899             bit = *shiftreg & 0x1F;
900             mask = (0x1 << bit);
901             CONDITIONAL_SET_FLAG(*srcreg & mask, F_CF);
902             *srcreg |= mask;
903         }
904         else {
905             u16 *srcreg, *shiftreg;
906             u16 mask;
907 
908             srcreg = DECODE_RM_WORD_REGISTER(rl);
909             DECODE_PRINTF(",");
910             shiftreg = DECODE_RM_WORD_REGISTER(rh);
911             TRACE_AND_STEP();
912             bit = *shiftreg & 0xF;
913             mask = (u16) (0x1 << bit);
914             CONDITIONAL_SET_FLAG(*srcreg & mask, F_CF);
915             *srcreg |= mask;
916         }
917         break;
918     }
919     DECODE_CLEAR_SEGOVR();
920     END_OF_INSTR();
921 }
922 
923 /****************************************************************************
924 REMARKS:
925 Handles opcode 0x0f,0xac
926 ****************************************************************************/
927 static void
x86emuOp2_shrd_IMM(u8 X86EMU_UNUSED (op2))928 x86emuOp2_shrd_IMM(u8 X86EMU_UNUSED(op2))
929 {
930     int mod, rl, rh;
931     uint destoffset;
932     u8 shift;
933 
934     START_OF_INSTR();
935     DECODE_PRINTF("SHLD\t");
936     FETCH_DECODE_MODRM(mod, rh, rl);
937     switch (mod) {
938     case 0:
939         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
940             u32 destval;
941             u32 *shiftreg;
942 
943             destoffset = decode_rm00_address(rl);
944             DECODE_PRINTF(",");
945             shiftreg = DECODE_RM_LONG_REGISTER(rh);
946             DECODE_PRINTF(",");
947             shift = fetch_byte_imm();
948             DECODE_PRINTF2("%d\n", shift);
949             TRACE_AND_STEP();
950             destval = fetch_data_long(destoffset);
951             destval = shrd_long(destval, *shiftreg, shift);
952             store_data_long(destoffset, destval);
953         }
954         else {
955             u16 destval;
956             u16 *shiftreg;
957 
958             destoffset = decode_rm00_address(rl);
959             DECODE_PRINTF(",");
960             shiftreg = DECODE_RM_WORD_REGISTER(rh);
961             DECODE_PRINTF(",");
962             shift = fetch_byte_imm();
963             DECODE_PRINTF2("%d\n", shift);
964             TRACE_AND_STEP();
965             destval = fetch_data_word(destoffset);
966             destval = shrd_word(destval, *shiftreg, shift);
967             store_data_word(destoffset, destval);
968         }
969         break;
970     case 1:
971         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
972             u32 destval;
973             u32 *shiftreg;
974 
975             destoffset = decode_rm01_address(rl);
976             DECODE_PRINTF(",");
977             shiftreg = DECODE_RM_LONG_REGISTER(rh);
978             DECODE_PRINTF(",");
979             shift = fetch_byte_imm();
980             DECODE_PRINTF2("%d\n", shift);
981             TRACE_AND_STEP();
982             destval = fetch_data_long(destoffset);
983             destval = shrd_long(destval, *shiftreg, shift);
984             store_data_long(destoffset, destval);
985         }
986         else {
987             u16 destval;
988             u16 *shiftreg;
989 
990             destoffset = decode_rm01_address(rl);
991             DECODE_PRINTF(",");
992             shiftreg = DECODE_RM_WORD_REGISTER(rh);
993             DECODE_PRINTF(",");
994             shift = fetch_byte_imm();
995             DECODE_PRINTF2("%d\n", shift);
996             TRACE_AND_STEP();
997             destval = fetch_data_word(destoffset);
998             destval = shrd_word(destval, *shiftreg, shift);
999             store_data_word(destoffset, destval);
1000         }
1001         break;
1002     case 2:
1003         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1004             u32 destval;
1005             u32 *shiftreg;
1006 
1007             destoffset = decode_rm10_address(rl);
1008             DECODE_PRINTF(",");
1009             shiftreg = DECODE_RM_LONG_REGISTER(rh);
1010             DECODE_PRINTF(",");
1011             shift = fetch_byte_imm();
1012             DECODE_PRINTF2("%d\n", shift);
1013             TRACE_AND_STEP();
1014             destval = fetch_data_long(destoffset);
1015             destval = shrd_long(destval, *shiftreg, shift);
1016             store_data_long(destoffset, destval);
1017         }
1018         else {
1019             u16 destval;
1020             u16 *shiftreg;
1021 
1022             destoffset = decode_rm10_address(rl);
1023             DECODE_PRINTF(",");
1024             shiftreg = DECODE_RM_WORD_REGISTER(rh);
1025             DECODE_PRINTF(",");
1026             shift = fetch_byte_imm();
1027             DECODE_PRINTF2("%d\n", shift);
1028             TRACE_AND_STEP();
1029             destval = fetch_data_word(destoffset);
1030             destval = shrd_word(destval, *shiftreg, shift);
1031             store_data_word(destoffset, destval);
1032         }
1033         break;
1034     case 3:                    /* register to register */
1035         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1036             u32 *destreg, *shiftreg;
1037 
1038             destreg = DECODE_RM_LONG_REGISTER(rl);
1039             DECODE_PRINTF(",");
1040             shiftreg = DECODE_RM_LONG_REGISTER(rh);
1041             DECODE_PRINTF(",");
1042             shift = fetch_byte_imm();
1043             DECODE_PRINTF2("%d\n", shift);
1044             TRACE_AND_STEP();
1045             *destreg = shrd_long(*destreg, *shiftreg, shift);
1046         }
1047         else {
1048             u16 *destreg, *shiftreg;
1049 
1050             destreg = DECODE_RM_WORD_REGISTER(rl);
1051             DECODE_PRINTF(",");
1052             shiftreg = DECODE_RM_WORD_REGISTER(rh);
1053             DECODE_PRINTF(",");
1054             shift = fetch_byte_imm();
1055             DECODE_PRINTF2("%d\n", shift);
1056             TRACE_AND_STEP();
1057             *destreg = shrd_word(*destreg, *shiftreg, shift);
1058         }
1059         break;
1060     }
1061     DECODE_CLEAR_SEGOVR();
1062     END_OF_INSTR();
1063 }
1064 
1065 /****************************************************************************
1066 REMARKS:
1067 Handles opcode 0x0f,0xad
1068 ****************************************************************************/
1069 static void
x86emuOp2_shrd_CL(u8 X86EMU_UNUSED (op2))1070 x86emuOp2_shrd_CL(u8 X86EMU_UNUSED(op2))
1071 {
1072     int mod, rl, rh;
1073     uint destoffset;
1074 
1075     START_OF_INSTR();
1076     DECODE_PRINTF("SHLD\t");
1077     FETCH_DECODE_MODRM(mod, rh, rl);
1078     switch (mod) {
1079     case 0:
1080         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1081             u32 destval;
1082             u32 *shiftreg;
1083 
1084             destoffset = decode_rm00_address(rl);
1085             DECODE_PRINTF(",");
1086             shiftreg = DECODE_RM_LONG_REGISTER(rh);
1087             DECODE_PRINTF(",CL\n");
1088             TRACE_AND_STEP();
1089             destval = fetch_data_long(destoffset);
1090             destval = shrd_long(destval, *shiftreg, M.x86.R_CL);
1091             store_data_long(destoffset, destval);
1092         }
1093         else {
1094             u16 destval;
1095             u16 *shiftreg;
1096 
1097             destoffset = decode_rm00_address(rl);
1098             DECODE_PRINTF(",");
1099             shiftreg = DECODE_RM_WORD_REGISTER(rh);
1100             DECODE_PRINTF(",CL\n");
1101             TRACE_AND_STEP();
1102             destval = fetch_data_word(destoffset);
1103             destval = shrd_word(destval, *shiftreg, M.x86.R_CL);
1104             store_data_word(destoffset, destval);
1105         }
1106         break;
1107     case 1:
1108         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1109             u32 destval;
1110             u32 *shiftreg;
1111 
1112             destoffset = decode_rm01_address(rl);
1113             DECODE_PRINTF(",");
1114             shiftreg = DECODE_RM_LONG_REGISTER(rh);
1115             DECODE_PRINTF(",CL\n");
1116             TRACE_AND_STEP();
1117             destval = fetch_data_long(destoffset);
1118             destval = shrd_long(destval, *shiftreg, M.x86.R_CL);
1119             store_data_long(destoffset, destval);
1120         }
1121         else {
1122             u16 destval;
1123             u16 *shiftreg;
1124 
1125             destoffset = decode_rm01_address(rl);
1126             DECODE_PRINTF(",");
1127             shiftreg = DECODE_RM_WORD_REGISTER(rh);
1128             DECODE_PRINTF(",CL\n");
1129             TRACE_AND_STEP();
1130             destval = fetch_data_word(destoffset);
1131             destval = shrd_word(destval, *shiftreg, M.x86.R_CL);
1132             store_data_word(destoffset, destval);
1133         }
1134         break;
1135     case 2:
1136         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1137             u32 destval;
1138             u32 *shiftreg;
1139 
1140             destoffset = decode_rm10_address(rl);
1141             DECODE_PRINTF(",");
1142             shiftreg = DECODE_RM_LONG_REGISTER(rh);
1143             DECODE_PRINTF(",CL\n");
1144             TRACE_AND_STEP();
1145             destval = fetch_data_long(destoffset);
1146             destval = shrd_long(destval, *shiftreg, M.x86.R_CL);
1147             store_data_long(destoffset, destval);
1148         }
1149         else {
1150             u16 destval;
1151             u16 *shiftreg;
1152 
1153             destoffset = decode_rm10_address(rl);
1154             DECODE_PRINTF(",");
1155             shiftreg = DECODE_RM_WORD_REGISTER(rh);
1156             DECODE_PRINTF(",CL\n");
1157             TRACE_AND_STEP();
1158             destval = fetch_data_word(destoffset);
1159             destval = shrd_word(destval, *shiftreg, M.x86.R_CL);
1160             store_data_word(destoffset, destval);
1161         }
1162         break;
1163     case 3:                    /* register to register */
1164         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1165             u32 *destreg, *shiftreg;
1166 
1167             destreg = DECODE_RM_LONG_REGISTER(rl);
1168             DECODE_PRINTF(",");
1169             shiftreg = DECODE_RM_LONG_REGISTER(rh);
1170             DECODE_PRINTF(",CL\n");
1171             TRACE_AND_STEP();
1172             *destreg = shrd_long(*destreg, *shiftreg, M.x86.R_CL);
1173         }
1174         else {
1175             u16 *destreg, *shiftreg;
1176 
1177             destreg = DECODE_RM_WORD_REGISTER(rl);
1178             DECODE_PRINTF(",");
1179             shiftreg = DECODE_RM_WORD_REGISTER(rh);
1180             DECODE_PRINTF(",CL\n");
1181             TRACE_AND_STEP();
1182             *destreg = shrd_word(*destreg, *shiftreg, M.x86.R_CL);
1183         }
1184         break;
1185     }
1186     DECODE_CLEAR_SEGOVR();
1187     END_OF_INSTR();
1188 }
1189 
1190 /****************************************************************************
1191 REMARKS:
1192 Handles opcode 0x0f,0xaf
1193 ****************************************************************************/
1194 static void
x86emuOp2_imul_R_RM(u8 X86EMU_UNUSED (op2))1195 x86emuOp2_imul_R_RM(u8 X86EMU_UNUSED(op2))
1196 {
1197     int mod, rl, rh;
1198     uint srcoffset;
1199 
1200     START_OF_INSTR();
1201     DECODE_PRINTF("IMUL\t");
1202     FETCH_DECODE_MODRM(mod, rh, rl);
1203     switch (mod) {
1204     case 0:
1205         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1206             u32 *destreg;
1207             u32 srcval;
1208             u32 res_lo, res_hi;
1209 
1210             destreg = DECODE_RM_LONG_REGISTER(rh);
1211             DECODE_PRINTF(",");
1212             srcoffset = decode_rm00_address(rl);
1213             srcval = fetch_data_long(srcoffset);
1214             TRACE_AND_STEP();
1215             imul_long_direct(&res_lo, &res_hi, (s32) * destreg, (s32) srcval);
1216             if (res_hi != 0) {
1217                 SET_FLAG(F_CF);
1218                 SET_FLAG(F_OF);
1219             }
1220             else {
1221                 CLEAR_FLAG(F_CF);
1222                 CLEAR_FLAG(F_OF);
1223             }
1224             *destreg = (u32) res_lo;
1225         }
1226         else {
1227             u16 *destreg;
1228             u16 srcval;
1229             u32 res;
1230 
1231             destreg = DECODE_RM_WORD_REGISTER(rh);
1232             DECODE_PRINTF(",");
1233             srcoffset = decode_rm00_address(rl);
1234             srcval = fetch_data_word(srcoffset);
1235             TRACE_AND_STEP();
1236             res = (s16) * destreg * (s16) srcval;
1237             if (res > 0xFFFF) {
1238                 SET_FLAG(F_CF);
1239                 SET_FLAG(F_OF);
1240             }
1241             else {
1242                 CLEAR_FLAG(F_CF);
1243                 CLEAR_FLAG(F_OF);
1244             }
1245             *destreg = (u16) res;
1246         }
1247         break;
1248     case 1:
1249         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1250             u32 *destreg;
1251             u32 srcval;
1252             u32 res_lo, res_hi;
1253 
1254             destreg = DECODE_RM_LONG_REGISTER(rh);
1255             DECODE_PRINTF(",");
1256             srcoffset = decode_rm01_address(rl);
1257             srcval = fetch_data_long(srcoffset);
1258             TRACE_AND_STEP();
1259             imul_long_direct(&res_lo, &res_hi, (s32) * destreg, (s32) srcval);
1260             if (res_hi != 0) {
1261                 SET_FLAG(F_CF);
1262                 SET_FLAG(F_OF);
1263             }
1264             else {
1265                 CLEAR_FLAG(F_CF);
1266                 CLEAR_FLAG(F_OF);
1267             }
1268             *destreg = (u32) res_lo;
1269         }
1270         else {
1271             u16 *destreg;
1272             u16 srcval;
1273             u32 res;
1274 
1275             destreg = DECODE_RM_WORD_REGISTER(rh);
1276             DECODE_PRINTF(",");
1277             srcoffset = decode_rm01_address(rl);
1278             srcval = fetch_data_word(srcoffset);
1279             TRACE_AND_STEP();
1280             res = (s16) * destreg * (s16) srcval;
1281             if (res > 0xFFFF) {
1282                 SET_FLAG(F_CF);
1283                 SET_FLAG(F_OF);
1284             }
1285             else {
1286                 CLEAR_FLAG(F_CF);
1287                 CLEAR_FLAG(F_OF);
1288             }
1289             *destreg = (u16) res;
1290         }
1291         break;
1292     case 2:
1293         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1294             u32 *destreg;
1295             u32 srcval;
1296             u32 res_lo, res_hi;
1297 
1298             destreg = DECODE_RM_LONG_REGISTER(rh);
1299             DECODE_PRINTF(",");
1300             srcoffset = decode_rm10_address(rl);
1301             srcval = fetch_data_long(srcoffset);
1302             TRACE_AND_STEP();
1303             imul_long_direct(&res_lo, &res_hi, (s32) * destreg, (s32) srcval);
1304             if (res_hi != 0) {
1305                 SET_FLAG(F_CF);
1306                 SET_FLAG(F_OF);
1307             }
1308             else {
1309                 CLEAR_FLAG(F_CF);
1310                 CLEAR_FLAG(F_OF);
1311             }
1312             *destreg = (u32) res_lo;
1313         }
1314         else {
1315             u16 *destreg;
1316             u16 srcval;
1317             u32 res;
1318 
1319             destreg = DECODE_RM_WORD_REGISTER(rh);
1320             DECODE_PRINTF(",");
1321             srcoffset = decode_rm10_address(rl);
1322             srcval = fetch_data_word(srcoffset);
1323             TRACE_AND_STEP();
1324             res = (s16) * destreg * (s16) srcval;
1325             if (res > 0xFFFF) {
1326                 SET_FLAG(F_CF);
1327                 SET_FLAG(F_OF);
1328             }
1329             else {
1330                 CLEAR_FLAG(F_CF);
1331                 CLEAR_FLAG(F_OF);
1332             }
1333             *destreg = (u16) res;
1334         }
1335         break;
1336     case 3:                    /* register to register */
1337         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1338             u32 *destreg, *srcreg;
1339             u32 res_lo, res_hi;
1340 
1341             destreg = DECODE_RM_LONG_REGISTER(rh);
1342             DECODE_PRINTF(",");
1343             srcreg = DECODE_RM_LONG_REGISTER(rl);
1344             TRACE_AND_STEP();
1345             imul_long_direct(&res_lo, &res_hi, (s32) * destreg, (s32) * srcreg);
1346             if (res_hi != 0) {
1347                 SET_FLAG(F_CF);
1348                 SET_FLAG(F_OF);
1349             }
1350             else {
1351                 CLEAR_FLAG(F_CF);
1352                 CLEAR_FLAG(F_OF);
1353             }
1354             *destreg = (u32) res_lo;
1355         }
1356         else {
1357             u16 *destreg, *srcreg;
1358             u32 res;
1359 
1360             destreg = DECODE_RM_WORD_REGISTER(rh);
1361             DECODE_PRINTF(",");
1362             srcreg = DECODE_RM_WORD_REGISTER(rl);
1363             res = (s16) * destreg * (s16) * srcreg;
1364             if (res > 0xFFFF) {
1365                 SET_FLAG(F_CF);
1366                 SET_FLAG(F_OF);
1367             }
1368             else {
1369                 CLEAR_FLAG(F_CF);
1370                 CLEAR_FLAG(F_OF);
1371             }
1372             *destreg = (u16) res;
1373         }
1374         break;
1375     }
1376     DECODE_CLEAR_SEGOVR();
1377     END_OF_INSTR();
1378 }
1379 
1380 /****************************************************************************
1381 REMARKS:
1382 Handles opcode 0x0f,0xb2
1383 ****************************************************************************/
1384 static void
x86emuOp2_lss_R_IMM(u8 X86EMU_UNUSED (op2))1385 x86emuOp2_lss_R_IMM(u8 X86EMU_UNUSED(op2))
1386 {
1387     int mod, rh, rl;
1388     u16 *dstreg;
1389     uint srcoffset;
1390 
1391     START_OF_INSTR();
1392     DECODE_PRINTF("LSS\t");
1393     FETCH_DECODE_MODRM(mod, rh, rl);
1394     switch (mod) {
1395     case 0:
1396         dstreg = DECODE_RM_WORD_REGISTER(rh);
1397         DECODE_PRINTF(",");
1398         srcoffset = decode_rm00_address(rl);
1399         DECODE_PRINTF("\n");
1400         TRACE_AND_STEP();
1401         *dstreg = fetch_data_word(srcoffset);
1402         M.x86.R_SS = fetch_data_word(srcoffset + 2);
1403         break;
1404     case 1:
1405         dstreg = DECODE_RM_WORD_REGISTER(rh);
1406         DECODE_PRINTF(",");
1407         srcoffset = decode_rm01_address(rl);
1408         DECODE_PRINTF("\n");
1409         TRACE_AND_STEP();
1410         *dstreg = fetch_data_word(srcoffset);
1411         M.x86.R_SS = fetch_data_word(srcoffset + 2);
1412         break;
1413     case 2:
1414         dstreg = DECODE_RM_WORD_REGISTER(rh);
1415         DECODE_PRINTF(",");
1416         srcoffset = decode_rm10_address(rl);
1417         DECODE_PRINTF("\n");
1418         TRACE_AND_STEP();
1419         *dstreg = fetch_data_word(srcoffset);
1420         M.x86.R_SS = fetch_data_word(srcoffset + 2);
1421         break;
1422     case 3:                    /* register to register */
1423         /* UNDEFINED! */
1424         TRACE_AND_STEP();
1425     }
1426     DECODE_CLEAR_SEGOVR();
1427     END_OF_INSTR();
1428 }
1429 
1430 /****************************************************************************
1431 REMARKS:
1432 Handles opcode 0x0f,0xb3
1433 ****************************************************************************/
1434 static void
x86emuOp2_btr_R(u8 X86EMU_UNUSED (op2))1435 x86emuOp2_btr_R(u8 X86EMU_UNUSED(op2))
1436 {
1437     int mod, rl, rh;
1438     uint srcoffset;
1439     int bit, disp;
1440 
1441     START_OF_INSTR();
1442     DECODE_PRINTF("BTR\t");
1443     FETCH_DECODE_MODRM(mod, rh, rl);
1444     switch (mod) {
1445     case 0:
1446         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1447             u32 srcval, mask;
1448             u32 *shiftreg;
1449 
1450             srcoffset = decode_rm00_address(rl);
1451             DECODE_PRINTF(",");
1452             shiftreg = DECODE_RM_LONG_REGISTER(rh);
1453             TRACE_AND_STEP();
1454             bit = *shiftreg & 0x1F;
1455             disp = (s16) * shiftreg >> 5;
1456             srcval = fetch_data_long(srcoffset + disp);
1457             mask = (0x1 << bit);
1458             CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
1459             store_data_long(srcoffset + disp, srcval & ~mask);
1460         }
1461         else {
1462             u16 srcval, mask;
1463             u16 *shiftreg;
1464 
1465             srcoffset = decode_rm00_address(rl);
1466             DECODE_PRINTF(",");
1467             shiftreg = DECODE_RM_WORD_REGISTER(rh);
1468             TRACE_AND_STEP();
1469             bit = *shiftreg & 0xF;
1470             disp = (s16) * shiftreg >> 4;
1471             srcval = fetch_data_word(srcoffset + disp);
1472             mask = (u16) (0x1 << bit);
1473             CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
1474             store_data_word(srcoffset + disp, (u16) (srcval & ~mask));
1475         }
1476         break;
1477     case 1:
1478         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1479             u32 srcval, mask;
1480             u32 *shiftreg;
1481 
1482             srcoffset = decode_rm01_address(rl);
1483             DECODE_PRINTF(",");
1484             shiftreg = DECODE_RM_LONG_REGISTER(rh);
1485             TRACE_AND_STEP();
1486             bit = *shiftreg & 0x1F;
1487             disp = (s16) * shiftreg >> 5;
1488             srcval = fetch_data_long(srcoffset + disp);
1489             mask = (0x1 << bit);
1490             CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
1491             store_data_long(srcoffset + disp, srcval & ~mask);
1492         }
1493         else {
1494             u16 srcval, mask;
1495             u16 *shiftreg;
1496 
1497             srcoffset = decode_rm01_address(rl);
1498             DECODE_PRINTF(",");
1499             shiftreg = DECODE_RM_WORD_REGISTER(rh);
1500             TRACE_AND_STEP();
1501             bit = *shiftreg & 0xF;
1502             disp = (s16) * shiftreg >> 4;
1503             srcval = fetch_data_word(srcoffset + disp);
1504             mask = (u16) (0x1 << bit);
1505             CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
1506             store_data_word(srcoffset + disp, (u16) (srcval & ~mask));
1507         }
1508         break;
1509     case 2:
1510         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1511             u32 srcval, mask;
1512             u32 *shiftreg;
1513 
1514             srcoffset = decode_rm10_address(rl);
1515             DECODE_PRINTF(",");
1516             shiftreg = DECODE_RM_LONG_REGISTER(rh);
1517             TRACE_AND_STEP();
1518             bit = *shiftreg & 0x1F;
1519             disp = (s16) * shiftreg >> 5;
1520             srcval = fetch_data_long(srcoffset + disp);
1521             mask = (0x1 << bit);
1522             CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
1523             store_data_long(srcoffset + disp, srcval & ~mask);
1524         }
1525         else {
1526             u16 srcval, mask;
1527             u16 *shiftreg;
1528 
1529             srcoffset = decode_rm10_address(rl);
1530             DECODE_PRINTF(",");
1531             shiftreg = DECODE_RM_WORD_REGISTER(rh);
1532             TRACE_AND_STEP();
1533             bit = *shiftreg & 0xF;
1534             disp = (s16) * shiftreg >> 4;
1535             srcval = fetch_data_word(srcoffset + disp);
1536             mask = (u16) (0x1 << bit);
1537             CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
1538             store_data_word(srcoffset + disp, (u16) (srcval & ~mask));
1539         }
1540         break;
1541     case 3:                    /* register to register */
1542         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1543             u32 *srcreg, *shiftreg;
1544             u32 mask;
1545 
1546             srcreg = DECODE_RM_LONG_REGISTER(rl);
1547             DECODE_PRINTF(",");
1548             shiftreg = DECODE_RM_LONG_REGISTER(rh);
1549             TRACE_AND_STEP();
1550             bit = *shiftreg & 0x1F;
1551             mask = (0x1 << bit);
1552             CONDITIONAL_SET_FLAG(*srcreg & mask, F_CF);
1553             *srcreg &= ~mask;
1554         }
1555         else {
1556             u16 *srcreg, *shiftreg;
1557             u16 mask;
1558 
1559             srcreg = DECODE_RM_WORD_REGISTER(rl);
1560             DECODE_PRINTF(",");
1561             shiftreg = DECODE_RM_WORD_REGISTER(rh);
1562             TRACE_AND_STEP();
1563             bit = *shiftreg & 0xF;
1564             mask = (u16) (0x1 << bit);
1565             CONDITIONAL_SET_FLAG(*srcreg & mask, F_CF);
1566             *srcreg &= ~mask;
1567         }
1568         break;
1569     }
1570     DECODE_CLEAR_SEGOVR();
1571     END_OF_INSTR();
1572 }
1573 
1574 /****************************************************************************
1575 REMARKS:
1576 Handles opcode 0x0f,0xb4
1577 ****************************************************************************/
1578 static void
x86emuOp2_lfs_R_IMM(u8 X86EMU_UNUSED (op2))1579 x86emuOp2_lfs_R_IMM(u8 X86EMU_UNUSED(op2))
1580 {
1581     int mod, rh, rl;
1582     u16 *dstreg;
1583     uint srcoffset;
1584 
1585     START_OF_INSTR();
1586     DECODE_PRINTF("LFS\t");
1587     FETCH_DECODE_MODRM(mod, rh, rl);
1588     switch (mod) {
1589     case 0:
1590         dstreg = DECODE_RM_WORD_REGISTER(rh);
1591         DECODE_PRINTF(",");
1592         srcoffset = decode_rm00_address(rl);
1593         DECODE_PRINTF("\n");
1594         TRACE_AND_STEP();
1595         *dstreg = fetch_data_word(srcoffset);
1596         M.x86.R_FS = fetch_data_word(srcoffset + 2);
1597         break;
1598     case 1:
1599         dstreg = DECODE_RM_WORD_REGISTER(rh);
1600         DECODE_PRINTF(",");
1601         srcoffset = decode_rm01_address(rl);
1602         DECODE_PRINTF("\n");
1603         TRACE_AND_STEP();
1604         *dstreg = fetch_data_word(srcoffset);
1605         M.x86.R_FS = fetch_data_word(srcoffset + 2);
1606         break;
1607     case 2:
1608         dstreg = DECODE_RM_WORD_REGISTER(rh);
1609         DECODE_PRINTF(",");
1610         srcoffset = decode_rm10_address(rl);
1611         DECODE_PRINTF("\n");
1612         TRACE_AND_STEP();
1613         *dstreg = fetch_data_word(srcoffset);
1614         M.x86.R_FS = fetch_data_word(srcoffset + 2);
1615         break;
1616     case 3:                    /* register to register */
1617         /* UNDEFINED! */
1618         TRACE_AND_STEP();
1619     }
1620     DECODE_CLEAR_SEGOVR();
1621     END_OF_INSTR();
1622 }
1623 
1624 /****************************************************************************
1625 REMARKS:
1626 Handles opcode 0x0f,0xb5
1627 ****************************************************************************/
1628 static void
x86emuOp2_lgs_R_IMM(u8 X86EMU_UNUSED (op2))1629 x86emuOp2_lgs_R_IMM(u8 X86EMU_UNUSED(op2))
1630 {
1631     int mod, rh, rl;
1632     u16 *dstreg;
1633     uint srcoffset;
1634 
1635     START_OF_INSTR();
1636     DECODE_PRINTF("LGS\t");
1637     FETCH_DECODE_MODRM(mod, rh, rl);
1638     switch (mod) {
1639     case 0:
1640         dstreg = DECODE_RM_WORD_REGISTER(rh);
1641         DECODE_PRINTF(",");
1642         srcoffset = decode_rm00_address(rl);
1643         DECODE_PRINTF("\n");
1644         TRACE_AND_STEP();
1645         *dstreg = fetch_data_word(srcoffset);
1646         M.x86.R_GS = fetch_data_word(srcoffset + 2);
1647         break;
1648     case 1:
1649         dstreg = DECODE_RM_WORD_REGISTER(rh);
1650         DECODE_PRINTF(",");
1651         srcoffset = decode_rm01_address(rl);
1652         DECODE_PRINTF("\n");
1653         TRACE_AND_STEP();
1654         *dstreg = fetch_data_word(srcoffset);
1655         M.x86.R_GS = fetch_data_word(srcoffset + 2);
1656         break;
1657     case 2:
1658         dstreg = DECODE_RM_WORD_REGISTER(rh);
1659         DECODE_PRINTF(",");
1660         srcoffset = decode_rm10_address(rl);
1661         DECODE_PRINTF("\n");
1662         TRACE_AND_STEP();
1663         *dstreg = fetch_data_word(srcoffset);
1664         M.x86.R_GS = fetch_data_word(srcoffset + 2);
1665         break;
1666     case 3:                    /* register to register */
1667         /* UNDEFINED! */
1668         TRACE_AND_STEP();
1669     }
1670     DECODE_CLEAR_SEGOVR();
1671     END_OF_INSTR();
1672 }
1673 
1674 /****************************************************************************
1675 REMARKS:
1676 Handles opcode 0x0f,0xb6
1677 ****************************************************************************/
1678 static void
x86emuOp2_movzx_byte_R_RM(u8 X86EMU_UNUSED (op2))1679 x86emuOp2_movzx_byte_R_RM(u8 X86EMU_UNUSED(op2))
1680 {
1681     int mod, rl, rh;
1682     uint srcoffset;
1683 
1684     START_OF_INSTR();
1685     DECODE_PRINTF("MOVZX\t");
1686     FETCH_DECODE_MODRM(mod, rh, rl);
1687     switch (mod) {
1688     case 0:
1689         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1690             u32 *destreg;
1691             u32 srcval;
1692 
1693             destreg = DECODE_RM_LONG_REGISTER(rh);
1694             DECODE_PRINTF(",");
1695             srcoffset = decode_rm00_address(rl);
1696             srcval = fetch_data_byte(srcoffset);
1697             DECODE_PRINTF("\n");
1698             TRACE_AND_STEP();
1699             *destreg = srcval;
1700         }
1701         else {
1702             u16 *destreg;
1703             u16 srcval;
1704 
1705             destreg = DECODE_RM_WORD_REGISTER(rh);
1706             DECODE_PRINTF(",");
1707             srcoffset = decode_rm00_address(rl);
1708             srcval = fetch_data_byte(srcoffset);
1709             DECODE_PRINTF("\n");
1710             TRACE_AND_STEP();
1711             *destreg = srcval;
1712         }
1713         break;
1714     case 1:
1715         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1716             u32 *destreg;
1717             u32 srcval;
1718 
1719             destreg = DECODE_RM_LONG_REGISTER(rh);
1720             DECODE_PRINTF(",");
1721             srcoffset = decode_rm01_address(rl);
1722             srcval = fetch_data_byte(srcoffset);
1723             DECODE_PRINTF("\n");
1724             TRACE_AND_STEP();
1725             *destreg = srcval;
1726         }
1727         else {
1728             u16 *destreg;
1729             u16 srcval;
1730 
1731             destreg = DECODE_RM_WORD_REGISTER(rh);
1732             DECODE_PRINTF(",");
1733             srcoffset = decode_rm01_address(rl);
1734             srcval = fetch_data_byte(srcoffset);
1735             DECODE_PRINTF("\n");
1736             TRACE_AND_STEP();
1737             *destreg = srcval;
1738         }
1739         break;
1740     case 2:
1741         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1742             u32 *destreg;
1743             u32 srcval;
1744 
1745             destreg = DECODE_RM_LONG_REGISTER(rh);
1746             DECODE_PRINTF(",");
1747             srcoffset = decode_rm10_address(rl);
1748             srcval = fetch_data_byte(srcoffset);
1749             DECODE_PRINTF("\n");
1750             TRACE_AND_STEP();
1751             *destreg = srcval;
1752         }
1753         else {
1754             u16 *destreg;
1755             u16 srcval;
1756 
1757             destreg = DECODE_RM_WORD_REGISTER(rh);
1758             DECODE_PRINTF(",");
1759             srcoffset = decode_rm10_address(rl);
1760             srcval = fetch_data_byte(srcoffset);
1761             DECODE_PRINTF("\n");
1762             TRACE_AND_STEP();
1763             *destreg = srcval;
1764         }
1765         break;
1766     case 3:                    /* register to register */
1767         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1768             u32 *destreg;
1769             u8 *srcreg;
1770 
1771             destreg = DECODE_RM_LONG_REGISTER(rh);
1772             DECODE_PRINTF(",");
1773             srcreg = DECODE_RM_BYTE_REGISTER(rl);
1774             DECODE_PRINTF("\n");
1775             TRACE_AND_STEP();
1776             *destreg = *srcreg;
1777         }
1778         else {
1779             u16 *destreg;
1780             u8 *srcreg;
1781 
1782             destreg = DECODE_RM_WORD_REGISTER(rh);
1783             DECODE_PRINTF(",");
1784             srcreg = DECODE_RM_BYTE_REGISTER(rl);
1785             DECODE_PRINTF("\n");
1786             TRACE_AND_STEP();
1787             *destreg = *srcreg;
1788         }
1789         break;
1790     }
1791     DECODE_CLEAR_SEGOVR();
1792     END_OF_INSTR();
1793 }
1794 
1795 /****************************************************************************
1796 REMARKS:
1797 Handles opcode 0x0f,0xb7
1798 ****************************************************************************/
1799 static void
x86emuOp2_movzx_word_R_RM(u8 X86EMU_UNUSED (op2))1800 x86emuOp2_movzx_word_R_RM(u8 X86EMU_UNUSED(op2))
1801 {
1802     int mod, rl, rh;
1803     uint srcoffset;
1804     u32 *destreg;
1805     u32 srcval;
1806     u16 *srcreg;
1807 
1808     START_OF_INSTR();
1809     DECODE_PRINTF("MOVZX\t");
1810     FETCH_DECODE_MODRM(mod, rh, rl);
1811     switch (mod) {
1812     case 0:
1813         destreg = DECODE_RM_LONG_REGISTER(rh);
1814         DECODE_PRINTF(",");
1815         srcoffset = decode_rm00_address(rl);
1816         srcval = fetch_data_word(srcoffset);
1817         DECODE_PRINTF("\n");
1818         TRACE_AND_STEP();
1819         *destreg = srcval;
1820         break;
1821     case 1:
1822         destreg = DECODE_RM_LONG_REGISTER(rh);
1823         DECODE_PRINTF(",");
1824         srcoffset = decode_rm01_address(rl);
1825         srcval = fetch_data_word(srcoffset);
1826         DECODE_PRINTF("\n");
1827         TRACE_AND_STEP();
1828         *destreg = srcval;
1829         break;
1830     case 2:
1831         destreg = DECODE_RM_LONG_REGISTER(rh);
1832         DECODE_PRINTF(",");
1833         srcoffset = decode_rm10_address(rl);
1834         srcval = fetch_data_word(srcoffset);
1835         DECODE_PRINTF("\n");
1836         TRACE_AND_STEP();
1837         *destreg = srcval;
1838         break;
1839     case 3:                    /* register to register */
1840         destreg = DECODE_RM_LONG_REGISTER(rh);
1841         DECODE_PRINTF(",");
1842         srcreg = DECODE_RM_WORD_REGISTER(rl);
1843         DECODE_PRINTF("\n");
1844         TRACE_AND_STEP();
1845         *destreg = *srcreg;
1846         break;
1847     }
1848     DECODE_CLEAR_SEGOVR();
1849     END_OF_INSTR();
1850 }
1851 
1852 /****************************************************************************
1853 REMARKS:
1854 Handles opcode 0x0f,0xba
1855 ****************************************************************************/
1856 static void
x86emuOp2_btX_I(u8 X86EMU_UNUSED (op2))1857 x86emuOp2_btX_I(u8 X86EMU_UNUSED(op2))
1858 {
1859     int mod, rl, rh;
1860     uint srcoffset;
1861     int bit;
1862 
1863     START_OF_INSTR();
1864     FETCH_DECODE_MODRM(mod, rh, rl);
1865     switch (rh) {
1866     case 4:
1867         DECODE_PRINTF("BT\t");
1868         break;
1869     case 5:
1870         DECODE_PRINTF("BTS\t");
1871         break;
1872     case 6:
1873         DECODE_PRINTF("BTR\t");
1874         break;
1875     case 7:
1876         DECODE_PRINTF("BTC\t");
1877         break;
1878     default:
1879         DECODE_PRINTF("ILLEGAL EXTENDED X86 OPCODE\n");
1880         TRACE_REGS();
1881         printk("%04x:%04x: %02X%02X ILLEGAL EXTENDED X86 OPCODE EXTENSION!\n",
1882                M.x86.R_CS, M.x86.R_IP - 3, op2, (mod << 6) | (rh << 3) | rl);
1883         HALT_SYS();
1884     }
1885     switch (mod) {
1886     case 0:
1887         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1888             u32 srcval, mask;
1889             u8 shift;
1890 
1891             srcoffset = decode_rm00_address(rl);
1892             DECODE_PRINTF(",");
1893             shift = fetch_byte_imm();
1894             TRACE_AND_STEP();
1895             bit = shift & 0x1F;
1896             srcval = fetch_data_long(srcoffset);
1897             mask = (0x1 << bit);
1898             CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
1899             switch (rh) {
1900             case 5:
1901                 store_data_long(srcoffset, srcval | mask);
1902                 break;
1903             case 6:
1904                 store_data_long(srcoffset, srcval & ~mask);
1905                 break;
1906             case 7:
1907                 store_data_long(srcoffset, srcval ^ mask);
1908                 break;
1909             default:
1910                 break;
1911             }
1912         }
1913         else {
1914             u16 srcval, mask;
1915             u8 shift;
1916 
1917             srcoffset = decode_rm00_address(rl);
1918             DECODE_PRINTF(",");
1919             shift = fetch_byte_imm();
1920             TRACE_AND_STEP();
1921             bit = shift & 0xF;
1922             srcval = fetch_data_word(srcoffset);
1923             mask = (0x1 << bit);
1924             CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
1925             switch (rh) {
1926             case 5:
1927                 store_data_word(srcoffset, srcval | mask);
1928                 break;
1929             case 6:
1930                 store_data_word(srcoffset, srcval & ~mask);
1931                 break;
1932             case 7:
1933                 store_data_word(srcoffset, srcval ^ mask);
1934                 break;
1935             default:
1936                 break;
1937             }
1938         }
1939         break;
1940     case 1:
1941         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1942             u32 srcval, mask;
1943             u8 shift;
1944 
1945             srcoffset = decode_rm01_address(rl);
1946             DECODE_PRINTF(",");
1947             shift = fetch_byte_imm();
1948             TRACE_AND_STEP();
1949             bit = shift & 0x1F;
1950             srcval = fetch_data_long(srcoffset);
1951             mask = (0x1 << bit);
1952             CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
1953             switch (rh) {
1954             case 5:
1955                 store_data_long(srcoffset, srcval | mask);
1956                 break;
1957             case 6:
1958                 store_data_long(srcoffset, srcval & ~mask);
1959                 break;
1960             case 7:
1961                 store_data_long(srcoffset, srcval ^ mask);
1962                 break;
1963             default:
1964                 break;
1965             }
1966         }
1967         else {
1968             u16 srcval, mask;
1969             u8 shift;
1970 
1971             srcoffset = decode_rm01_address(rl);
1972             DECODE_PRINTF(",");
1973             shift = fetch_byte_imm();
1974             TRACE_AND_STEP();
1975             bit = shift & 0xF;
1976             srcval = fetch_data_word(srcoffset);
1977             mask = (0x1 << bit);
1978             CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
1979             switch (rh) {
1980             case 5:
1981                 store_data_word(srcoffset, srcval | mask);
1982                 break;
1983             case 6:
1984                 store_data_word(srcoffset, srcval & ~mask);
1985                 break;
1986             case 7:
1987                 store_data_word(srcoffset, srcval ^ mask);
1988                 break;
1989             default:
1990                 break;
1991             }
1992         }
1993         break;
1994     case 2:
1995         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1996             u32 srcval, mask;
1997             u8 shift;
1998 
1999             srcoffset = decode_rm10_address(rl);
2000             DECODE_PRINTF(",");
2001             shift = fetch_byte_imm();
2002             TRACE_AND_STEP();
2003             bit = shift & 0x1F;
2004             srcval = fetch_data_long(srcoffset);
2005             mask = (0x1 << bit);
2006             CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
2007             switch (rh) {
2008             case 5:
2009                 store_data_long(srcoffset, srcval | mask);
2010                 break;
2011             case 6:
2012                 store_data_long(srcoffset, srcval & ~mask);
2013                 break;
2014             case 7:
2015                 store_data_long(srcoffset, srcval ^ mask);
2016                 break;
2017             default:
2018                 break;
2019             }
2020         }
2021         else {
2022             u16 srcval, mask;
2023             u8 shift;
2024 
2025             srcoffset = decode_rm10_address(rl);
2026             DECODE_PRINTF(",");
2027             shift = fetch_byte_imm();
2028             TRACE_AND_STEP();
2029             bit = shift & 0xF;
2030             srcval = fetch_data_word(srcoffset);
2031             mask = (0x1 << bit);
2032             CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
2033             switch (rh) {
2034             case 5:
2035                 store_data_word(srcoffset, srcval | mask);
2036                 break;
2037             case 6:
2038                 store_data_word(srcoffset, srcval & ~mask);
2039                 break;
2040             case 7:
2041                 store_data_word(srcoffset, srcval ^ mask);
2042                 break;
2043             default:
2044                 break;
2045             }
2046         }
2047         break;
2048     case 3:                    /* register to register */
2049         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2050             u32 *srcreg;
2051             u32 mask;
2052             u8 shift;
2053 
2054             srcreg = DECODE_RM_LONG_REGISTER(rl);
2055             DECODE_PRINTF(",");
2056             shift = fetch_byte_imm();
2057             TRACE_AND_STEP();
2058             bit = shift & 0x1F;
2059             mask = (0x1 << bit);
2060             CONDITIONAL_SET_FLAG(*srcreg & mask, F_CF);
2061             switch (rh) {
2062             case 5:
2063                 *srcreg |= mask;
2064                 break;
2065             case 6:
2066                 *srcreg &= ~mask;
2067                 break;
2068             case 7:
2069                 *srcreg ^= mask;
2070                 break;
2071             default:
2072                 break;
2073             }
2074         }
2075         else {
2076             u16 *srcreg;
2077             u16 mask;
2078             u8 shift;
2079 
2080             srcreg = DECODE_RM_WORD_REGISTER(rl);
2081             DECODE_PRINTF(",");
2082             shift = fetch_byte_imm();
2083             TRACE_AND_STEP();
2084             bit = shift & 0xF;
2085             mask = (0x1 << bit);
2086             CONDITIONAL_SET_FLAG(*srcreg & mask, F_CF);
2087             switch (rh) {
2088             case 5:
2089                 *srcreg |= mask;
2090                 break;
2091             case 6:
2092                 *srcreg &= ~mask;
2093                 break;
2094             case 7:
2095                 *srcreg ^= mask;
2096                 break;
2097             default:
2098                 break;
2099             }
2100         }
2101         break;
2102     }
2103     DECODE_CLEAR_SEGOVR();
2104     END_OF_INSTR();
2105 }
2106 
2107 /****************************************************************************
2108 REMARKS:
2109 Handles opcode 0x0f,0xbb
2110 ****************************************************************************/
2111 static void
x86emuOp2_btc_R(u8 X86EMU_UNUSED (op2))2112 x86emuOp2_btc_R(u8 X86EMU_UNUSED(op2))
2113 {
2114     int mod, rl, rh;
2115     uint srcoffset;
2116     int bit, disp;
2117 
2118     START_OF_INSTR();
2119     DECODE_PRINTF("BTC\t");
2120     FETCH_DECODE_MODRM(mod, rh, rl);
2121     switch (mod) {
2122     case 0:
2123         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2124             u32 srcval, mask;
2125             u32 *shiftreg;
2126 
2127             srcoffset = decode_rm00_address(rl);
2128             DECODE_PRINTF(",");
2129             shiftreg = DECODE_RM_LONG_REGISTER(rh);
2130             TRACE_AND_STEP();
2131             bit = *shiftreg & 0x1F;
2132             disp = (s16) * shiftreg >> 5;
2133             srcval = fetch_data_long(srcoffset + disp);
2134             mask = (0x1 << bit);
2135             CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
2136             store_data_long(srcoffset + disp, srcval ^ mask);
2137         }
2138         else {
2139             u16 srcval, mask;
2140             u16 *shiftreg;
2141 
2142             srcoffset = decode_rm00_address(rl);
2143             DECODE_PRINTF(",");
2144             shiftreg = DECODE_RM_WORD_REGISTER(rh);
2145             TRACE_AND_STEP();
2146             bit = *shiftreg & 0xF;
2147             disp = (s16) * shiftreg >> 4;
2148             srcval = fetch_data_word(srcoffset + disp);
2149             mask = (u16) (0x1 << bit);
2150             CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
2151             store_data_word(srcoffset + disp, (u16) (srcval ^ mask));
2152         }
2153         break;
2154     case 1:
2155         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2156             u32 srcval, mask;
2157             u32 *shiftreg;
2158 
2159             srcoffset = decode_rm01_address(rl);
2160             DECODE_PRINTF(",");
2161             shiftreg = DECODE_RM_LONG_REGISTER(rh);
2162             TRACE_AND_STEP();
2163             bit = *shiftreg & 0x1F;
2164             disp = (s16) * shiftreg >> 5;
2165             srcval = fetch_data_long(srcoffset + disp);
2166             mask = (0x1 << bit);
2167             CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
2168             store_data_long(srcoffset + disp, srcval ^ mask);
2169         }
2170         else {
2171             u16 srcval, mask;
2172             u16 *shiftreg;
2173 
2174             srcoffset = decode_rm01_address(rl);
2175             DECODE_PRINTF(",");
2176             shiftreg = DECODE_RM_WORD_REGISTER(rh);
2177             TRACE_AND_STEP();
2178             bit = *shiftreg & 0xF;
2179             disp = (s16) * shiftreg >> 4;
2180             srcval = fetch_data_word(srcoffset + disp);
2181             mask = (u16) (0x1 << bit);
2182             CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
2183             store_data_word(srcoffset + disp, (u16) (srcval ^ mask));
2184         }
2185         break;
2186     case 2:
2187         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2188             u32 srcval, mask;
2189             u32 *shiftreg;
2190 
2191             srcoffset = decode_rm10_address(rl);
2192             DECODE_PRINTF(",");
2193             shiftreg = DECODE_RM_LONG_REGISTER(rh);
2194             TRACE_AND_STEP();
2195             bit = *shiftreg & 0x1F;
2196             disp = (s16) * shiftreg >> 5;
2197             srcval = fetch_data_long(srcoffset + disp);
2198             mask = (0x1 << bit);
2199             CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
2200             store_data_long(srcoffset + disp, srcval ^ mask);
2201         }
2202         else {
2203             u16 srcval, mask;
2204             u16 *shiftreg;
2205 
2206             srcoffset = decode_rm10_address(rl);
2207             DECODE_PRINTF(",");
2208             shiftreg = DECODE_RM_WORD_REGISTER(rh);
2209             TRACE_AND_STEP();
2210             bit = *shiftreg & 0xF;
2211             disp = (s16) * shiftreg >> 4;
2212             srcval = fetch_data_word(srcoffset + disp);
2213             mask = (u16) (0x1 << bit);
2214             CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
2215             store_data_word(srcoffset + disp, (u16) (srcval ^ mask));
2216         }
2217         break;
2218     case 3:                    /* register to register */
2219         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2220             u32 *srcreg, *shiftreg;
2221             u32 mask;
2222 
2223             srcreg = DECODE_RM_LONG_REGISTER(rl);
2224             DECODE_PRINTF(",");
2225             shiftreg = DECODE_RM_LONG_REGISTER(rh);
2226             TRACE_AND_STEP();
2227             bit = *shiftreg & 0x1F;
2228             mask = (0x1 << bit);
2229             CONDITIONAL_SET_FLAG(*srcreg & mask, F_CF);
2230             *srcreg ^= mask;
2231         }
2232         else {
2233             u16 *srcreg, *shiftreg;
2234             u16 mask;
2235 
2236             srcreg = DECODE_RM_WORD_REGISTER(rl);
2237             DECODE_PRINTF(",");
2238             shiftreg = DECODE_RM_WORD_REGISTER(rh);
2239             TRACE_AND_STEP();
2240             bit = *shiftreg & 0xF;
2241             mask = (u16) (0x1 << bit);
2242             CONDITIONAL_SET_FLAG(*srcreg & mask, F_CF);
2243             *srcreg ^= mask;
2244         }
2245         break;
2246     }
2247     DECODE_CLEAR_SEGOVR();
2248     END_OF_INSTR();
2249 }
2250 
2251 /****************************************************************************
2252 REMARKS:
2253 Handles opcode 0x0f,0xbc
2254 ****************************************************************************/
2255 static void
x86emuOp2_bsf(u8 X86EMU_UNUSED (op2))2256 x86emuOp2_bsf(u8 X86EMU_UNUSED(op2))
2257 {
2258     int mod, rl, rh;
2259     uint srcoffset;
2260 
2261     START_OF_INSTR();
2262     DECODE_PRINTF("BSF\t");
2263     FETCH_DECODE_MODRM(mod, rh, rl);
2264     switch (mod) {
2265     case 0:
2266         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2267             u32 srcval, *dstreg;
2268 
2269             srcoffset = decode_rm00_address(rl);
2270             DECODE_PRINTF(",");
2271             dstreg = DECODE_RM_LONG_REGISTER(rh);
2272             TRACE_AND_STEP();
2273             srcval = fetch_data_long(srcoffset);
2274             CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2275             for (*dstreg = 0; *dstreg < 32; (*dstreg)++)
2276                 if ((srcval >> *dstreg) & 1)
2277                     break;
2278         }
2279         else {
2280             u16 srcval, *dstreg;
2281 
2282             srcoffset = decode_rm00_address(rl);
2283             DECODE_PRINTF(",");
2284             dstreg = DECODE_RM_WORD_REGISTER(rh);
2285             TRACE_AND_STEP();
2286             srcval = fetch_data_word(srcoffset);
2287             CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2288             for (*dstreg = 0; *dstreg < 16; (*dstreg)++)
2289                 if ((srcval >> *dstreg) & 1)
2290                     break;
2291         }
2292         break;
2293     case 1:
2294         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2295             u32 srcval, *dstreg;
2296 
2297             srcoffset = decode_rm01_address(rl);
2298             DECODE_PRINTF(",");
2299             dstreg = DECODE_RM_LONG_REGISTER(rh);
2300             TRACE_AND_STEP();
2301             srcval = fetch_data_long(srcoffset);
2302             CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2303             for (*dstreg = 0; *dstreg < 32; (*dstreg)++)
2304                 if ((srcval >> *dstreg) & 1)
2305                     break;
2306         }
2307         else {
2308             u16 srcval, *dstreg;
2309 
2310             srcoffset = decode_rm01_address(rl);
2311             DECODE_PRINTF(",");
2312             dstreg = DECODE_RM_WORD_REGISTER(rh);
2313             TRACE_AND_STEP();
2314             srcval = fetch_data_word(srcoffset);
2315             CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2316             for (*dstreg = 0; *dstreg < 16; (*dstreg)++)
2317                 if ((srcval >> *dstreg) & 1)
2318                     break;
2319         }
2320         break;
2321     case 2:
2322         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2323             u32 srcval, *dstreg;
2324 
2325             srcoffset = decode_rm10_address(rl);
2326             DECODE_PRINTF(",");
2327             dstreg = DECODE_RM_LONG_REGISTER(rh);
2328             TRACE_AND_STEP();
2329             srcval = fetch_data_long(srcoffset);
2330             CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2331             for (*dstreg = 0; *dstreg < 32; (*dstreg)++)
2332                 if ((srcval >> *dstreg) & 1)
2333                     break;
2334         }
2335         else {
2336             u16 srcval, *dstreg;
2337 
2338             srcoffset = decode_rm10_address(rl);
2339             DECODE_PRINTF(",");
2340             dstreg = DECODE_RM_WORD_REGISTER(rh);
2341             TRACE_AND_STEP();
2342             srcval = fetch_data_word(srcoffset);
2343             CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2344             for (*dstreg = 0; *dstreg < 16; (*dstreg)++)
2345                 if ((srcval >> *dstreg) & 1)
2346                     break;
2347         }
2348         break;
2349     case 3:                    /* register to register */
2350         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2351             u32 srcval, *dstreg;
2352 
2353             srcval = *DECODE_RM_LONG_REGISTER(rl);
2354             DECODE_PRINTF(",");
2355             dstreg = DECODE_RM_LONG_REGISTER(rh);
2356             TRACE_AND_STEP();
2357             CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2358             for (*dstreg = 0; *dstreg < 32; (*dstreg)++)
2359                 if ((srcval >> *dstreg) & 1)
2360                     break;
2361         }
2362         else {
2363             u16 srcval, *dstreg;
2364 
2365             srcval = *DECODE_RM_WORD_REGISTER(rl);
2366             DECODE_PRINTF(",");
2367             dstreg = DECODE_RM_WORD_REGISTER(rh);
2368             TRACE_AND_STEP();
2369             CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2370             for (*dstreg = 0; *dstreg < 16; (*dstreg)++)
2371                 if ((srcval >> *dstreg) & 1)
2372                     break;
2373         }
2374         break;
2375     }
2376     DECODE_CLEAR_SEGOVR();
2377     END_OF_INSTR();
2378 }
2379 
2380 /****************************************************************************
2381 REMARKS:
2382 Handles opcode 0x0f,0xbd
2383 ****************************************************************************/
2384 static void
x86emuOp2_bsr(u8 X86EMU_UNUSED (op2))2385 x86emuOp2_bsr(u8 X86EMU_UNUSED(op2))
2386 {
2387     int mod, rl, rh;
2388     uint srcoffset;
2389 
2390     START_OF_INSTR();
2391     DECODE_PRINTF("BSR\t");
2392     FETCH_DECODE_MODRM(mod, rh, rl);
2393     switch (mod) {
2394     case 0:
2395         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2396             u32 srcval, *dstreg;
2397 
2398             srcoffset = decode_rm00_address(rl);
2399             DECODE_PRINTF(",");
2400             dstreg = DECODE_RM_LONG_REGISTER(rh);
2401             TRACE_AND_STEP();
2402             srcval = fetch_data_long(srcoffset);
2403             CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2404             for (*dstreg = 31; *dstreg > 0; (*dstreg)--)
2405                 if ((srcval >> *dstreg) & 1)
2406                     break;
2407         }
2408         else {
2409             u16 srcval, *dstreg;
2410 
2411             srcoffset = decode_rm00_address(rl);
2412             DECODE_PRINTF(",");
2413             dstreg = DECODE_RM_WORD_REGISTER(rh);
2414             TRACE_AND_STEP();
2415             srcval = fetch_data_word(srcoffset);
2416             CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2417             for (*dstreg = 15; *dstreg > 0; (*dstreg)--)
2418                 if ((srcval >> *dstreg) & 1)
2419                     break;
2420         }
2421         break;
2422     case 1:
2423         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2424             u32 srcval, *dstreg;
2425 
2426             srcoffset = decode_rm01_address(rl);
2427             DECODE_PRINTF(",");
2428             dstreg = DECODE_RM_LONG_REGISTER(rh);
2429             TRACE_AND_STEP();
2430             srcval = fetch_data_long(srcoffset);
2431             CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2432             for (*dstreg = 31; *dstreg > 0; (*dstreg)--)
2433                 if ((srcval >> *dstreg) & 1)
2434                     break;
2435         }
2436         else {
2437             u16 srcval, *dstreg;
2438 
2439             srcoffset = decode_rm01_address(rl);
2440             DECODE_PRINTF(",");
2441             dstreg = DECODE_RM_WORD_REGISTER(rh);
2442             TRACE_AND_STEP();
2443             srcval = fetch_data_word(srcoffset);
2444             CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2445             for (*dstreg = 15; *dstreg > 0; (*dstreg)--)
2446                 if ((srcval >> *dstreg) & 1)
2447                     break;
2448         }
2449         break;
2450     case 2:
2451         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2452             u32 srcval, *dstreg;
2453 
2454             srcoffset = decode_rm10_address(rl);
2455             DECODE_PRINTF(",");
2456             dstreg = DECODE_RM_LONG_REGISTER(rh);
2457             TRACE_AND_STEP();
2458             srcval = fetch_data_long(srcoffset);
2459             CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2460             for (*dstreg = 31; *dstreg > 0; (*dstreg)--)
2461                 if ((srcval >> *dstreg) & 1)
2462                     break;
2463         }
2464         else {
2465             u16 srcval, *dstreg;
2466 
2467             srcoffset = decode_rm10_address(rl);
2468             DECODE_PRINTF(",");
2469             dstreg = DECODE_RM_WORD_REGISTER(rh);
2470             TRACE_AND_STEP();
2471             srcval = fetch_data_word(srcoffset);
2472             CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2473             for (*dstreg = 15; *dstreg > 0; (*dstreg)--)
2474                 if ((srcval >> *dstreg) & 1)
2475                     break;
2476         }
2477         break;
2478     case 3:                    /* register to register */
2479         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2480             u32 srcval, *dstreg;
2481 
2482             srcval = *DECODE_RM_LONG_REGISTER(rl);
2483             DECODE_PRINTF(",");
2484             dstreg = DECODE_RM_LONG_REGISTER(rh);
2485             TRACE_AND_STEP();
2486             CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2487             for (*dstreg = 31; *dstreg > 0; (*dstreg)--)
2488                 if ((srcval >> *dstreg) & 1)
2489                     break;
2490         }
2491         else {
2492             u16 srcval, *dstreg;
2493 
2494             srcval = *DECODE_RM_WORD_REGISTER(rl);
2495             DECODE_PRINTF(",");
2496             dstreg = DECODE_RM_WORD_REGISTER(rh);
2497             TRACE_AND_STEP();
2498             CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2499             for (*dstreg = 15; *dstreg > 0; (*dstreg)--)
2500                 if ((srcval >> *dstreg) & 1)
2501                     break;
2502         }
2503         break;
2504     }
2505     DECODE_CLEAR_SEGOVR();
2506     END_OF_INSTR();
2507 }
2508 
2509 /****************************************************************************
2510 REMARKS:
2511 Handles opcode 0x0f,0xbe
2512 ****************************************************************************/
2513 static void
x86emuOp2_movsx_byte_R_RM(u8 X86EMU_UNUSED (op2))2514 x86emuOp2_movsx_byte_R_RM(u8 X86EMU_UNUSED(op2))
2515 {
2516     int mod, rl, rh;
2517     uint srcoffset;
2518 
2519     START_OF_INSTR();
2520     DECODE_PRINTF("MOVSX\t");
2521     FETCH_DECODE_MODRM(mod, rh, rl);
2522     switch (mod) {
2523     case 0:
2524         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2525             u32 *destreg;
2526             u32 srcval;
2527 
2528             destreg = DECODE_RM_LONG_REGISTER(rh);
2529             DECODE_PRINTF(",");
2530             srcoffset = decode_rm00_address(rl);
2531             srcval = (s32) ((s8) fetch_data_byte(srcoffset));
2532             DECODE_PRINTF("\n");
2533             TRACE_AND_STEP();
2534             *destreg = srcval;
2535         }
2536         else {
2537             u16 *destreg;
2538             u16 srcval;
2539 
2540             destreg = DECODE_RM_WORD_REGISTER(rh);
2541             DECODE_PRINTF(",");
2542             srcoffset = decode_rm00_address(rl);
2543             srcval = (s16) ((s8) fetch_data_byte(srcoffset));
2544             DECODE_PRINTF("\n");
2545             TRACE_AND_STEP();
2546             *destreg = srcval;
2547         }
2548         break;
2549     case 1:
2550         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2551             u32 *destreg;
2552             u32 srcval;
2553 
2554             destreg = DECODE_RM_LONG_REGISTER(rh);
2555             DECODE_PRINTF(",");
2556             srcoffset = decode_rm01_address(rl);
2557             srcval = (s32) ((s8) fetch_data_byte(srcoffset));
2558             DECODE_PRINTF("\n");
2559             TRACE_AND_STEP();
2560             *destreg = srcval;
2561         }
2562         else {
2563             u16 *destreg;
2564             u16 srcval;
2565 
2566             destreg = DECODE_RM_WORD_REGISTER(rh);
2567             DECODE_PRINTF(",");
2568             srcoffset = decode_rm01_address(rl);
2569             srcval = (s16) ((s8) fetch_data_byte(srcoffset));
2570             DECODE_PRINTF("\n");
2571             TRACE_AND_STEP();
2572             *destreg = srcval;
2573         }
2574         break;
2575     case 2:
2576         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2577             u32 *destreg;
2578             u32 srcval;
2579 
2580             destreg = DECODE_RM_LONG_REGISTER(rh);
2581             DECODE_PRINTF(",");
2582             srcoffset = decode_rm10_address(rl);
2583             srcval = (s32) ((s8) fetch_data_byte(srcoffset));
2584             DECODE_PRINTF("\n");
2585             TRACE_AND_STEP();
2586             *destreg = srcval;
2587         }
2588         else {
2589             u16 *destreg;
2590             u16 srcval;
2591 
2592             destreg = DECODE_RM_WORD_REGISTER(rh);
2593             DECODE_PRINTF(",");
2594             srcoffset = decode_rm10_address(rl);
2595             srcval = (s16) ((s8) fetch_data_byte(srcoffset));
2596             DECODE_PRINTF("\n");
2597             TRACE_AND_STEP();
2598             *destreg = srcval;
2599         }
2600         break;
2601     case 3:                    /* register to register */
2602         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2603             u32 *destreg;
2604             u8 *srcreg;
2605 
2606             destreg = DECODE_RM_LONG_REGISTER(rh);
2607             DECODE_PRINTF(",");
2608             srcreg = DECODE_RM_BYTE_REGISTER(rl);
2609             DECODE_PRINTF("\n");
2610             TRACE_AND_STEP();
2611             *destreg = (s32) ((s8) * srcreg);
2612         }
2613         else {
2614             u16 *destreg;
2615             u8 *srcreg;
2616 
2617             destreg = DECODE_RM_WORD_REGISTER(rh);
2618             DECODE_PRINTF(",");
2619             srcreg = DECODE_RM_BYTE_REGISTER(rl);
2620             DECODE_PRINTF("\n");
2621             TRACE_AND_STEP();
2622             *destreg = (s16) ((s8) * srcreg);
2623         }
2624         break;
2625     }
2626     DECODE_CLEAR_SEGOVR();
2627     END_OF_INSTR();
2628 }
2629 
2630 /****************************************************************************
2631 REMARKS:
2632 Handles opcode 0x0f,0xbf
2633 ****************************************************************************/
2634 static void
x86emuOp2_movsx_word_R_RM(u8 X86EMU_UNUSED (op2))2635 x86emuOp2_movsx_word_R_RM(u8 X86EMU_UNUSED(op2))
2636 {
2637     int mod, rl, rh;
2638     uint srcoffset;
2639     u32 *destreg;
2640     u32 srcval;
2641     u16 *srcreg;
2642 
2643     START_OF_INSTR();
2644     DECODE_PRINTF("MOVSX\t");
2645     FETCH_DECODE_MODRM(mod, rh, rl);
2646     switch (mod) {
2647     case 0:
2648         destreg = DECODE_RM_LONG_REGISTER(rh);
2649         DECODE_PRINTF(",");
2650         srcoffset = decode_rm00_address(rl);
2651         srcval = (s32) ((s16) fetch_data_word(srcoffset));
2652         DECODE_PRINTF("\n");
2653         TRACE_AND_STEP();
2654         *destreg = srcval;
2655         break;
2656     case 1:
2657         destreg = DECODE_RM_LONG_REGISTER(rh);
2658         DECODE_PRINTF(",");
2659         srcoffset = decode_rm01_address(rl);
2660         srcval = (s32) ((s16) fetch_data_word(srcoffset));
2661         DECODE_PRINTF("\n");
2662         TRACE_AND_STEP();
2663         *destreg = srcval;
2664         break;
2665     case 2:
2666         destreg = DECODE_RM_LONG_REGISTER(rh);
2667         DECODE_PRINTF(",");
2668         srcoffset = decode_rm10_address(rl);
2669         srcval = (s32) ((s16) fetch_data_word(srcoffset));
2670         DECODE_PRINTF("\n");
2671         TRACE_AND_STEP();
2672         *destreg = srcval;
2673         break;
2674     case 3:                    /* register to register */
2675         destreg = DECODE_RM_LONG_REGISTER(rh);
2676         DECODE_PRINTF(",");
2677         srcreg = DECODE_RM_WORD_REGISTER(rl);
2678         DECODE_PRINTF("\n");
2679         TRACE_AND_STEP();
2680         *destreg = (s32) ((s16) * srcreg);
2681         break;
2682     }
2683     DECODE_CLEAR_SEGOVR();
2684     END_OF_INSTR();
2685 }
2686 
2687 /* Handles opcodes 0xc8-0xcf */
2688 static void
x86emuOp2_bswap(u8 X86EMU_UNUSED (op2))2689 x86emuOp2_bswap(u8 X86EMU_UNUSED(op2))
2690 {
2691     START_OF_INSTR();
2692     DECODE_PRINTF("BSWAP\n");
2693     TRACE_AND_STEP();
2694 
2695     switch (op2) {
2696     case 0xc8:
2697         M.x86.R_EAX = bswap_32(M.x86.R_EAX);
2698         break;
2699     case 0xc9:
2700         M.x86.R_ECX = bswap_32(M.x86.R_ECX);
2701         break;
2702     case 0xca:
2703         M.x86.R_EDX = bswap_32(M.x86.R_EDX);
2704         break;
2705     case 0xcb:
2706         M.x86.R_EBX = bswap_32(M.x86.R_EBX);
2707         break;
2708     case 0xcc:
2709         M.x86.R_ESP = bswap_32(M.x86.R_ESP);
2710         break;
2711     case 0xcd:
2712         M.x86.R_EBP = bswap_32(M.x86.R_EBP);
2713         break;
2714     case 0xce:
2715         M.x86.R_ESI = bswap_32(M.x86.R_ESI);
2716         break;
2717     case 0xcf:
2718         M.x86.R_EDI = bswap_32(M.x86.R_EDI);
2719         break;
2720     default:
2721         /* can't happen */
2722         break;
2723     }
2724 
2725     DECODE_CLEAR_SEGOVR();
2726     END_OF_INSTR();
2727 }
2728 
2729 /***************************************************************************
2730  * Double byte operation code table:
2731  **************************************************************************/
2732 void (*x86emu_optab2[256]) (u8) = {
2733                                         /*  0x00 */ x86emuOp2_illegal_op,
2734                                         /* Group F (ring 0 PM)      */
2735                                                 /*  0x01 */ x86emuOp2_illegal_op,
2736                                                 /* Group G (ring 0 PM)      */
2737                                                 /*  0x02 */ x86emuOp2_illegal_op,
2738                                                 /* lar (ring 0 PM)          */
2739                                                 /*  0x03 */ x86emuOp2_illegal_op,
2740                                                 /* lsl (ring 0 PM)          */
2741 /*  0x04 */ x86emuOp2_illegal_op,
2742                                                 /*  0x05 */ x86emuOp2_illegal_op,
2743                                                 /* loadall (undocumented)   */
2744                                                 /*  0x06 */ x86emuOp2_illegal_op,
2745                                                 /* clts (ring 0 PM)         */
2746                                                 /*  0x07 */ x86emuOp2_illegal_op,
2747                                                 /* loadall (undocumented)   */
2748                                                 /*  0x08 */ x86emuOp2_illegal_op,
2749                                                 /* invd (ring 0 PM)         */
2750                                                 /*  0x09 */ x86emuOp2_illegal_op,
2751                                                 /* wbinvd (ring 0 PM)       */
2752 /*  0x0a */ x86emuOp2_illegal_op,
2753 /*  0x0b */ x86emuOp2_illegal_op,
2754 /*  0x0c */ x86emuOp2_illegal_op,
2755 /*  0x0d */ x86emuOp2_illegal_op,
2756 /*  0x0e */ x86emuOp2_illegal_op,
2757 /*  0x0f */ x86emuOp2_illegal_op,
2758 /*  0x10 */ x86emuOp2_illegal_op,
2759 /*  0x11 */ x86emuOp2_illegal_op,
2760 /*  0x12 */ x86emuOp2_illegal_op,
2761 /*  0x13 */ x86emuOp2_illegal_op,
2762 /*  0x14 */ x86emuOp2_illegal_op,
2763 /*  0x15 */ x86emuOp2_illegal_op,
2764 /*  0x16 */ x86emuOp2_illegal_op,
2765 /*  0x17 */ x86emuOp2_illegal_op,
2766 /*  0x18 */ x86emuOp2_illegal_op,
2767 /*  0x19 */ x86emuOp2_illegal_op,
2768 /*  0x1a */ x86emuOp2_illegal_op,
2769 /*  0x1b */ x86emuOp2_illegal_op,
2770 /*  0x1c */ x86emuOp2_illegal_op,
2771 /*  0x1d */ x86emuOp2_illegal_op,
2772 /*  0x1e */ x86emuOp2_illegal_op,
2773 /*  0x1f */ x86emuOp2_illegal_op,
2774                                                 /*  0x20 */ x86emuOp2_illegal_op,
2775                                                 /* mov reg32,creg (ring 0 PM) */
2776                                                 /*  0x21 */ x86emuOp2_illegal_op,
2777                                                 /* mov reg32,dreg (ring 0 PM) */
2778                                                 /*  0x22 */ x86emuOp2_illegal_op,
2779                                                 /* mov creg,reg32 (ring 0 PM) */
2780                                                 /*  0x23 */ x86emuOp2_illegal_op,
2781                                                 /* mov dreg,reg32 (ring 0 PM) */
2782                                                 /*  0x24 */ x86emuOp2_illegal_op,
2783                                                 /* mov reg32,treg (ring 0 PM) */
2784 /*  0x25 */ x86emuOp2_illegal_op,
2785                                                 /*  0x26 */ x86emuOp2_illegal_op,
2786                                                 /* mov treg,reg32 (ring 0 PM) */
2787 /*  0x27 */ x86emuOp2_illegal_op,
2788 /*  0x28 */ x86emuOp2_illegal_op,
2789 /*  0x29 */ x86emuOp2_illegal_op,
2790 /*  0x2a */ x86emuOp2_illegal_op,
2791 /*  0x2b */ x86emuOp2_illegal_op,
2792 /*  0x2c */ x86emuOp2_illegal_op,
2793 /*  0x2d */ x86emuOp2_illegal_op,
2794 /*  0x2e */ x86emuOp2_illegal_op,
2795 /*  0x2f */ x86emuOp2_illegal_op,
2796 /*  0x30 */ x86emuOp2_illegal_op,
2797 /*  0x31 */ x86emuOp2_rdtsc,
2798 /*  0x32 */ x86emuOp2_illegal_op,
2799 /*  0x33 */ x86emuOp2_illegal_op,
2800 /*  0x34 */ x86emuOp2_illegal_op,
2801 /*  0x35 */ x86emuOp2_illegal_op,
2802 /*  0x36 */ x86emuOp2_illegal_op,
2803 /*  0x37 */ x86emuOp2_illegal_op,
2804 /*  0x38 */ x86emuOp2_illegal_op,
2805 /*  0x39 */ x86emuOp2_illegal_op,
2806 /*  0x3a */ x86emuOp2_illegal_op,
2807 /*  0x3b */ x86emuOp2_illegal_op,
2808 /*  0x3c */ x86emuOp2_illegal_op,
2809 /*  0x3d */ x86emuOp2_illegal_op,
2810 /*  0x3e */ x86emuOp2_illegal_op,
2811 /*  0x3f */ x86emuOp2_illegal_op,
2812 /*  0x40 */ x86emuOp2_illegal_op,
2813 /*  0x41 */ x86emuOp2_illegal_op,
2814 /*  0x42 */ x86emuOp2_illegal_op,
2815 /*  0x43 */ x86emuOp2_illegal_op,
2816 /*  0x44 */ x86emuOp2_illegal_op,
2817 /*  0x45 */ x86emuOp2_illegal_op,
2818 /*  0x46 */ x86emuOp2_illegal_op,
2819 /*  0x47 */ x86emuOp2_illegal_op,
2820 /*  0x48 */ x86emuOp2_illegal_op,
2821 /*  0x49 */ x86emuOp2_illegal_op,
2822 /*  0x4a */ x86emuOp2_illegal_op,
2823 /*  0x4b */ x86emuOp2_illegal_op,
2824 /*  0x4c */ x86emuOp2_illegal_op,
2825 /*  0x4d */ x86emuOp2_illegal_op,
2826 /*  0x4e */ x86emuOp2_illegal_op,
2827 /*  0x4f */ x86emuOp2_illegal_op,
2828 /*  0x50 */ x86emuOp2_illegal_op,
2829 /*  0x51 */ x86emuOp2_illegal_op,
2830 /*  0x52 */ x86emuOp2_illegal_op,
2831 /*  0x53 */ x86emuOp2_illegal_op,
2832 /*  0x54 */ x86emuOp2_illegal_op,
2833 /*  0x55 */ x86emuOp2_illegal_op,
2834 /*  0x56 */ x86emuOp2_illegal_op,
2835 /*  0x57 */ x86emuOp2_illegal_op,
2836 /*  0x58 */ x86emuOp2_illegal_op,
2837 /*  0x59 */ x86emuOp2_illegal_op,
2838 /*  0x5a */ x86emuOp2_illegal_op,
2839 /*  0x5b */ x86emuOp2_illegal_op,
2840 /*  0x5c */ x86emuOp2_illegal_op,
2841 /*  0x5d */ x86emuOp2_illegal_op,
2842 /*  0x5e */ x86emuOp2_illegal_op,
2843 /*  0x5f */ x86emuOp2_illegal_op,
2844 /*  0x60 */ x86emuOp2_illegal_op,
2845 /*  0x61 */ x86emuOp2_illegal_op,
2846 /*  0x62 */ x86emuOp2_illegal_op,
2847 /*  0x63 */ x86emuOp2_illegal_op,
2848 /*  0x64 */ x86emuOp2_illegal_op,
2849 /*  0x65 */ x86emuOp2_illegal_op,
2850 /*  0x66 */ x86emuOp2_illegal_op,
2851 /*  0x67 */ x86emuOp2_illegal_op,
2852 /*  0x68 */ x86emuOp2_illegal_op,
2853 /*  0x69 */ x86emuOp2_illegal_op,
2854 /*  0x6a */ x86emuOp2_illegal_op,
2855 /*  0x6b */ x86emuOp2_illegal_op,
2856 /*  0x6c */ x86emuOp2_illegal_op,
2857 /*  0x6d */ x86emuOp2_illegal_op,
2858 /*  0x6e */ x86emuOp2_illegal_op,
2859 /*  0x6f */ x86emuOp2_illegal_op,
2860 /*  0x70 */ x86emuOp2_illegal_op,
2861 /*  0x71 */ x86emuOp2_illegal_op,
2862 /*  0x72 */ x86emuOp2_illegal_op,
2863 /*  0x73 */ x86emuOp2_illegal_op,
2864 /*  0x74 */ x86emuOp2_illegal_op,
2865 /*  0x75 */ x86emuOp2_illegal_op,
2866 /*  0x76 */ x86emuOp2_illegal_op,
2867 /*  0x77 */ x86emuOp2_illegal_op,
2868 /*  0x78 */ x86emuOp2_illegal_op,
2869 /*  0x79 */ x86emuOp2_illegal_op,
2870 /*  0x7a */ x86emuOp2_illegal_op,
2871 /*  0x7b */ x86emuOp2_illegal_op,
2872 /*  0x7c */ x86emuOp2_illegal_op,
2873 /*  0x7d */ x86emuOp2_illegal_op,
2874 /*  0x7e */ x86emuOp2_illegal_op,
2875 /*  0x7f */ x86emuOp2_illegal_op,
2876 /*  0x80 */ x86emuOp2_long_jump,
2877 /*  0x81 */ x86emuOp2_long_jump,
2878 /*  0x82 */ x86emuOp2_long_jump,
2879 /*  0x83 */ x86emuOp2_long_jump,
2880 /*  0x84 */ x86emuOp2_long_jump,
2881 /*  0x85 */ x86emuOp2_long_jump,
2882 /*  0x86 */ x86emuOp2_long_jump,
2883 /*  0x87 */ x86emuOp2_long_jump,
2884 /*  0x88 */ x86emuOp2_long_jump,
2885 /*  0x89 */ x86emuOp2_long_jump,
2886 /*  0x8a */ x86emuOp2_long_jump,
2887 /*  0x8b */ x86emuOp2_long_jump,
2888 /*  0x8c */ x86emuOp2_long_jump,
2889 /*  0x8d */ x86emuOp2_long_jump,
2890 /*  0x8e */ x86emuOp2_long_jump,
2891 /*  0x8f */ x86emuOp2_long_jump,
2892 /*  0x90 */ x86emuOp2_set_byte,
2893 /*  0x91 */ x86emuOp2_set_byte,
2894 /*  0x92 */ x86emuOp2_set_byte,
2895 /*  0x93 */ x86emuOp2_set_byte,
2896 /*  0x94 */ x86emuOp2_set_byte,
2897 /*  0x95 */ x86emuOp2_set_byte,
2898 /*  0x96 */ x86emuOp2_set_byte,
2899 /*  0x97 */ x86emuOp2_set_byte,
2900 /*  0x98 */ x86emuOp2_set_byte,
2901 /*  0x99 */ x86emuOp2_set_byte,
2902 /*  0x9a */ x86emuOp2_set_byte,
2903 /*  0x9b */ x86emuOp2_set_byte,
2904 /*  0x9c */ x86emuOp2_set_byte,
2905 /*  0x9d */ x86emuOp2_set_byte,
2906 /*  0x9e */ x86emuOp2_set_byte,
2907 /*  0x9f */ x86emuOp2_set_byte,
2908 /*  0xa0 */ x86emuOp2_push_FS,
2909 /*  0xa1 */ x86emuOp2_pop_FS,
2910 /*  0xa2 */ x86emuOp2_cpuid,
2911 /*  0xa3 */ x86emuOp2_bt_R,
2912 /*  0xa4 */ x86emuOp2_shld_IMM,
2913 /*  0xa5 */ x86emuOp2_shld_CL,
2914 /*  0xa6 */ x86emuOp2_illegal_op,
2915 /*  0xa7 */ x86emuOp2_illegal_op,
2916 /*  0xa8 */ x86emuOp2_push_GS,
2917 /*  0xa9 */ x86emuOp2_pop_GS,
2918 /*  0xaa */ x86emuOp2_illegal_op,
2919 /*  0xab */ x86emuOp2_bts_R,
2920 /*  0xac */ x86emuOp2_shrd_IMM,
2921 /*  0xad */ x86emuOp2_shrd_CL,
2922 /*  0xae */ x86emuOp2_illegal_op,
2923 /*  0xaf */ x86emuOp2_imul_R_RM,
2924                                                 /*  0xb0 */ x86emuOp2_illegal_op,
2925                                                 /* TODO: cmpxchg */
2926                                                 /*  0xb1 */ x86emuOp2_illegal_op,
2927                                                 /* TODO: cmpxchg */
2928 /*  0xb2 */ x86emuOp2_lss_R_IMM,
2929 /*  0xb3 */ x86emuOp2_btr_R,
2930 /*  0xb4 */ x86emuOp2_lfs_R_IMM,
2931 /*  0xb5 */ x86emuOp2_lgs_R_IMM,
2932 /*  0xb6 */ x86emuOp2_movzx_byte_R_RM,
2933 /*  0xb7 */ x86emuOp2_movzx_word_R_RM,
2934 /*  0xb8 */ x86emuOp2_illegal_op,
2935 /*  0xb9 */ x86emuOp2_illegal_op,
2936 /*  0xba */ x86emuOp2_btX_I,
2937 /*  0xbb */ x86emuOp2_btc_R,
2938 /*  0xbc */ x86emuOp2_bsf,
2939 /*  0xbd */ x86emuOp2_bsr,
2940 /*  0xbe */ x86emuOp2_movsx_byte_R_RM,
2941 /*  0xbf */ x86emuOp2_movsx_word_R_RM,
2942                                                 /*  0xc0 */ x86emuOp2_illegal_op,
2943                                                 /* TODO: xadd */
2944                                                 /*  0xc1 */ x86emuOp2_illegal_op,
2945                                                 /* TODO: xadd */
2946 /*  0xc2 */ x86emuOp2_illegal_op,
2947 /*  0xc3 */ x86emuOp2_illegal_op,
2948 /*  0xc4 */ x86emuOp2_illegal_op,
2949 /*  0xc5 */ x86emuOp2_illegal_op,
2950 /*  0xc6 */ x86emuOp2_illegal_op,
2951 /*  0xc7 */ x86emuOp2_illegal_op,
2952 /*  0xc8 */ x86emuOp2_bswap,
2953 /*  0xc9 */ x86emuOp2_bswap,
2954 /*  0xca */ x86emuOp2_bswap,
2955 /*  0xcb */ x86emuOp2_bswap,
2956 /*  0xcc */ x86emuOp2_bswap,
2957 /*  0xcd */ x86emuOp2_bswap,
2958 /*  0xce */ x86emuOp2_bswap,
2959 /*  0xcf */ x86emuOp2_bswap,
2960 /*  0xd0 */ x86emuOp2_illegal_op,
2961 /*  0xd1 */ x86emuOp2_illegal_op,
2962 /*  0xd2 */ x86emuOp2_illegal_op,
2963 /*  0xd3 */ x86emuOp2_illegal_op,
2964 /*  0xd4 */ x86emuOp2_illegal_op,
2965 /*  0xd5 */ x86emuOp2_illegal_op,
2966 /*  0xd6 */ x86emuOp2_illegal_op,
2967 /*  0xd7 */ x86emuOp2_illegal_op,
2968 /*  0xd8 */ x86emuOp2_illegal_op,
2969 /*  0xd9 */ x86emuOp2_illegal_op,
2970 /*  0xda */ x86emuOp2_illegal_op,
2971 /*  0xdb */ x86emuOp2_illegal_op,
2972 /*  0xdc */ x86emuOp2_illegal_op,
2973 /*  0xdd */ x86emuOp2_illegal_op,
2974 /*  0xde */ x86emuOp2_illegal_op,
2975 /*  0xdf */ x86emuOp2_illegal_op,
2976 /*  0xe0 */ x86emuOp2_illegal_op,
2977 /*  0xe1 */ x86emuOp2_illegal_op,
2978 /*  0xe2 */ x86emuOp2_illegal_op,
2979 /*  0xe3 */ x86emuOp2_illegal_op,
2980 /*  0xe4 */ x86emuOp2_illegal_op,
2981 /*  0xe5 */ x86emuOp2_illegal_op,
2982 /*  0xe6 */ x86emuOp2_illegal_op,
2983 /*  0xe7 */ x86emuOp2_illegal_op,
2984 /*  0xe8 */ x86emuOp2_illegal_op,
2985 /*  0xe9 */ x86emuOp2_illegal_op,
2986 /*  0xea */ x86emuOp2_illegal_op,
2987 /*  0xeb */ x86emuOp2_illegal_op,
2988 /*  0xec */ x86emuOp2_illegal_op,
2989 /*  0xed */ x86emuOp2_illegal_op,
2990 /*  0xee */ x86emuOp2_illegal_op,
2991 /*  0xef */ x86emuOp2_illegal_op,
2992 /*  0xf0 */ x86emuOp2_illegal_op,
2993 /*  0xf1 */ x86emuOp2_illegal_op,
2994 /*  0xf2 */ x86emuOp2_illegal_op,
2995 /*  0xf3 */ x86emuOp2_illegal_op,
2996 /*  0xf4 */ x86emuOp2_illegal_op,
2997 /*  0xf5 */ x86emuOp2_illegal_op,
2998 /*  0xf6 */ x86emuOp2_illegal_op,
2999 /*  0xf7 */ x86emuOp2_illegal_op,
3000 /*  0xf8 */ x86emuOp2_illegal_op,
3001 /*  0xf9 */ x86emuOp2_illegal_op,
3002 /*  0xfa */ x86emuOp2_illegal_op,
3003 /*  0xfb */ x86emuOp2_illegal_op,
3004 /*  0xfc */ x86emuOp2_illegal_op,
3005 /*  0xfd */ x86emuOp2_illegal_op,
3006 /*  0xfe */ x86emuOp2_illegal_op,
3007 /*  0xff */ x86emuOp2_illegal_op,
3008 };
3009