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