xref: /openbmc/u-boot/drivers/bios_emulator/x86emu/ops2.c (revision f4e7e2d12164c3235c3f5e19a68a503623029d35)
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