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