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