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