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