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