The Pedigree Project  0.1
ops2.c
1 /*
2  * Copyright (c) 2008-2014, Pedigree Developers
3  *
4  * Please see the CONTRIB file in the root of the source tree for a full
5  * list of contributors.
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #include "x86emu/x86emui.h"
21 
22 /*----------------------------- Implementation ----------------------------*/
23 
24 /****************************************************************************
25 PARAMETERS:
26 op1 - Instruction op code
27 
28 REMARKS:
29 Handles illegal opcodes.
30 ****************************************************************************/
31 static void x86emuOp2_illegal_op(u8 op2)
32 {
33  START_OF_INSTR();
34  DECODE_PRINTF("ILLEGAL EXTENDED X86 OPCODE\n");
35  TRACE_REGS();
36  printk(
37  "%04x:%04x: %02X ILLEGAL EXTENDED X86 OPCODE!\n", M.x86.R_CS,
38  M.x86.R_IP - 2, op2);
39  HALT_SYS();
40  END_OF_INSTR();
41 }
42 
43 #define xorl(a, b) ((a) && !(b)) || (!(a) && (b))
44 
45 /****************************************************************************
46 REMARKS:
47 Handles opcode 0x0f,0x31
48 ****************************************************************************/
49 static void x86emuOp2_rdtsc(u8 X86EMU_UNUSED(op2))
50 {
51 #ifdef __HAS_LONG_LONG__
52  static u64 counter = 0;
53 #else
54  static u32 counter = 0;
55 #endif
56 
57  counter += 0x10000;
58 
59  /* read timestamp counter */
60  /*
61  * Note that instead of actually trying to accurately measure this, we just
62  * increase the counter by a fixed amount every time we hit one of these
63  * instructions. Feel free to come up with a better method.
64  */
65  START_OF_INSTR();
66  DECODE_PRINTF("RDTSC\n");
67  TRACE_AND_STEP();
68 #ifdef __HAS_LONG_LONG__
69  M.x86.R_EAX = counter & 0xffffffff;
70  M.x86.R_EDX = counter >> 32;
71 #else
72  M.x86.R_EAX = counter;
73  M.x86.R_EDX = 0;
74 #endif
75  DECODE_CLEAR_SEGOVR();
76  END_OF_INSTR();
77 }
78 
79 /****************************************************************************
80 REMARKS:
81 Handles opcode 0x0f,0x80-0x8F
82 ****************************************************************************/
83 static void x86emuOp2_long_jump(u8 op2)
84 {
85  s32 target;
86  const char *name = 0;
87  int cond = 0;
88 
89  /* conditional jump to word offset. */
90  START_OF_INSTR();
91  switch (op2)
92  {
93  case 0x80:
94  name = "JO\t";
95  cond = ACCESS_FLAG(F_OF);
96  break;
97  case 0x81:
98  name = "JNO\t";
99  cond = !ACCESS_FLAG(F_OF);
100  break;
101  case 0x82:
102  name = "JB\t";
103  cond = ACCESS_FLAG(F_CF);
104  break;
105  case 0x83:
106  name = "JNB\t";
107  cond = !ACCESS_FLAG(F_CF);
108  break;
109  case 0x84:
110  name = "JZ\t";
111  cond = ACCESS_FLAG(F_ZF);
112  break;
113  case 0x85:
114  name = "JNZ\t";
115  cond = !ACCESS_FLAG(F_ZF);
116  break;
117  case 0x86:
118  name = "JBE\t";
119  cond = ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF);
120  break;
121  case 0x87:
122  name = "JNBE\t";
123  cond = !(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF));
124  break;
125  case 0x88:
126  name = "JS\t";
127  cond = ACCESS_FLAG(F_SF);
128  break;
129  case 0x89:
130  name = "JNS\t";
131  cond = !ACCESS_FLAG(F_SF);
132  break;
133  case 0x8a:
134  name = "JP\t";
135  cond = ACCESS_FLAG(F_PF);
136  break;
137  case 0x8b:
138  name = "JNP\t";
139  cond = !ACCESS_FLAG(F_PF);
140  break;
141  case 0x8c:
142  name = "JL\t";
143  cond = xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
144  break;
145  case 0x8d:
146  name = "JNL\t";
147  cond = !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)));
148  break;
149  case 0x8e:
150  name = "JLE\t";
151  cond =
152  (xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
153  ACCESS_FLAG(F_ZF));
154  break;
155  case 0x8f:
156  name = "JNLE\t";
157  cond =
158  !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
159  ACCESS_FLAG(F_ZF));
160  break;
161  }
162  DECODE_PRINTF(name);
163  (void) name;
164  target = (s16) fetch_word_imm();
165  target += (s16) M.x86.R_IP;
166  DECODE_PRINTF2("%04x\n", target);
167  TRACE_AND_STEP();
168  if (cond)
169  M.x86.R_IP = (u16) target;
170  DECODE_CLEAR_SEGOVR();
171  END_OF_INSTR();
172 }
173 
174 /****************************************************************************
175 REMARKS:
176 Handles opcode 0x0f,0x90-0x9F
177 ****************************************************************************/
178 static void x86emuOp2_set_byte(u8 op2)
179 {
180  int mod, rl, rh;
181  uint destoffset;
182  u8 *destreg;
183  const char *name = 0;
184  int cond = 0;
185 
186  START_OF_INSTR();
187  switch (op2)
188  {
189  case 0x90:
190  name = "SETO\t";
191  cond = ACCESS_FLAG(F_OF);
192  break;
193  case 0x91:
194  name = "SETNO\t";
195  cond = !ACCESS_FLAG(F_OF);
196  break;
197  case 0x92:
198  name = "SETB\t";
199  cond = ACCESS_FLAG(F_CF);
200  break;
201  case 0x93:
202  name = "SETNB\t";
203  cond = !ACCESS_FLAG(F_CF);
204  break;
205  case 0x94:
206  name = "SETZ\t";
207  cond = ACCESS_FLAG(F_ZF);
208  break;
209  case 0x95:
210  name = "SETNZ\t";
211  cond = !ACCESS_FLAG(F_ZF);
212  break;
213  case 0x96:
214  name = "SETBE\t";
215  cond = ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF);
216  break;
217  case 0x97:
218  name = "SETNBE\t";
219  cond = !(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF));
220  break;
221  case 0x98:
222  name = "SETS\t";
223  cond = ACCESS_FLAG(F_SF);
224  break;
225  case 0x99:
226  name = "SETNS\t";
227  cond = !ACCESS_FLAG(F_SF);
228  break;
229  case 0x9a:
230  name = "SETP\t";
231  cond = ACCESS_FLAG(F_PF);
232  break;
233  case 0x9b:
234  name = "SETNP\t";
235  cond = !ACCESS_FLAG(F_PF);
236  break;
237  case 0x9c:
238  name = "SETL\t";
239  cond = xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
240  break;
241  case 0x9d:
242  name = "SETNL\t";
243  cond = xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
244  break;
245  case 0x9e:
246  name = "SETLE\t";
247  cond =
248  (xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
249  ACCESS_FLAG(F_ZF));
250  break;
251  case 0x9f:
252  name = "SETNLE\t";
253  cond =
254  !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
255  ACCESS_FLAG(F_ZF));
256  break;
257  }
258  DECODE_PRINTF(name);
259  (void) name;
260  FETCH_DECODE_MODRM(mod, rh, rl);
261  switch (mod)
262  {
263  case 0:
264  destoffset = decode_rm00_address(rl);
265  TRACE_AND_STEP();
266  store_data_byte(destoffset, cond ? 0x01 : 0x00);
267  break;
268  case 1:
269  destoffset = decode_rm01_address(rl);
270  TRACE_AND_STEP();
271  store_data_byte(destoffset, cond ? 0x01 : 0x00);
272  break;
273  case 2:
274  destoffset = decode_rm10_address(rl);
275  TRACE_AND_STEP();
276  store_data_byte(destoffset, cond ? 0x01 : 0x00);
277  break;
278  case 3: /* register to register */
279  destreg = DECODE_RM_BYTE_REGISTER(rl);
280  TRACE_AND_STEP();
281  *destreg = cond ? 0x01 : 0x00;
282  break;
283  }
284  DECODE_CLEAR_SEGOVR();
285  END_OF_INSTR();
286 }
287 
288 /****************************************************************************
289 REMARKS:
290 Handles opcode 0x0f,0xa0
291 ****************************************************************************/
292 static void x86emuOp2_push_FS(u8 X86EMU_UNUSED(op2))
293 {
294  START_OF_INSTR();
295  DECODE_PRINTF("PUSH\tFS\n");
296  TRACE_AND_STEP();
297  push_word(M.x86.R_FS);
298  DECODE_CLEAR_SEGOVR();
299  END_OF_INSTR();
300 }
301 
302 /****************************************************************************
303 REMARKS:
304 Handles opcode 0x0f,0xa1
305 ****************************************************************************/
306 static void x86emuOp2_pop_FS(u8 X86EMU_UNUSED(op2))
307 {
308  START_OF_INSTR();
309  DECODE_PRINTF("POP\tFS\n");
310  TRACE_AND_STEP();
311  M.x86.R_FS = pop_word();
312  DECODE_CLEAR_SEGOVR();
313  END_OF_INSTR();
314 }
315 
316 /****************************************************************************
317 REMARKS:
318 Handles opcode 0x0f,0xa3
319 ****************************************************************************/
320 static void x86emuOp2_bt_R(u8 X86EMU_UNUSED(op2))
321 {
322  int mod, rl, rh;
323  uint srcoffset;
324  int bit, disp;
325 
326  START_OF_INSTR();
327  DECODE_PRINTF("BT\t");
328  FETCH_DECODE_MODRM(mod, rh, rl);
329  switch (mod)
330  {
331  case 0:
332  if (M.x86.mode & SYSMODE_PREFIX_DATA)
333  {
334  u32 srcval;
335  u32 *shiftreg;
336 
337  srcoffset = decode_rm00_address(rl);
338  DECODE_PRINTF(",");
339  shiftreg = DECODE_RM_LONG_REGISTER(rh);
340  TRACE_AND_STEP();
341  bit = *shiftreg & 0x1F;
342  disp = (s16) *shiftreg >> 5;
343  srcval = fetch_data_long(srcoffset + disp);
344  CONDITIONAL_SET_FLAG(srcval & (0x1 << bit), F_CF);
345  }
346  else
347  {
348  u16 srcval;
349  u16 *shiftreg;
350 
351  srcoffset = decode_rm00_address(rl);
352  DECODE_PRINTF(",");
353  shiftreg = DECODE_RM_WORD_REGISTER(rh);
354  TRACE_AND_STEP();
355  bit = *shiftreg & 0xF;
356  disp = (s16) *shiftreg >> 4;
357  srcval = fetch_data_word(srcoffset + disp);
358  CONDITIONAL_SET_FLAG(srcval & (0x1 << bit), F_CF);
359  }
360  break;
361  case 1:
362  if (M.x86.mode & SYSMODE_PREFIX_DATA)
363  {
364  u32 srcval;
365  u32 *shiftreg;
366 
367  srcoffset = decode_rm01_address(rl);
368  DECODE_PRINTF(",");
369  shiftreg = DECODE_RM_LONG_REGISTER(rh);
370  TRACE_AND_STEP();
371  bit = *shiftreg & 0x1F;
372  disp = (s16) *shiftreg >> 5;
373  srcval = fetch_data_long(srcoffset + disp);
374  CONDITIONAL_SET_FLAG(srcval & (0x1 << bit), F_CF);
375  }
376  else
377  {
378  u16 srcval;
379  u16 *shiftreg;
380 
381  srcoffset = decode_rm01_address(rl);
382  DECODE_PRINTF(",");
383  shiftreg = DECODE_RM_WORD_REGISTER(rh);
384  TRACE_AND_STEP();
385  bit = *shiftreg & 0xF;
386  disp = (s16) *shiftreg >> 4;
387  srcval = fetch_data_word(srcoffset + disp);
388  CONDITIONAL_SET_FLAG(srcval & (0x1 << bit), F_CF);
389  }
390  break;
391  case 2:
392  if (M.x86.mode & SYSMODE_PREFIX_DATA)
393  {
394  u32 srcval;
395  u32 *shiftreg;
396 
397  srcoffset = decode_rm10_address(rl);
398  DECODE_PRINTF(",");
399  shiftreg = DECODE_RM_LONG_REGISTER(rh);
400  TRACE_AND_STEP();
401  bit = *shiftreg & 0x1F;
402  disp = (s16) *shiftreg >> 5;
403  srcval = fetch_data_long(srcoffset + disp);
404  CONDITIONAL_SET_FLAG(srcval & (0x1 << bit), F_CF);
405  }
406  else
407  {
408  u16 srcval;
409  u16 *shiftreg;
410 
411  srcoffset = decode_rm10_address(rl);
412  DECODE_PRINTF(",");
413  shiftreg = DECODE_RM_WORD_REGISTER(rh);
414  TRACE_AND_STEP();
415  bit = *shiftreg & 0xF;
416  disp = (s16) *shiftreg >> 4;
417  srcval = fetch_data_word(srcoffset + disp);
418  CONDITIONAL_SET_FLAG(srcval & (0x1 << bit), F_CF);
419  }
420  break;
421  case 3: /* register to register */
422  if (M.x86.mode & SYSMODE_PREFIX_DATA)
423  {
424  u32 *srcreg, *shiftreg;
425 
426  srcreg = DECODE_RM_LONG_REGISTER(rl);
427  DECODE_PRINTF(",");
428  shiftreg = DECODE_RM_LONG_REGISTER(rh);
429  TRACE_AND_STEP();
430  bit = *shiftreg & 0x1F;
431  CONDITIONAL_SET_FLAG(*srcreg & (0x1 << bit), F_CF);
432  }
433  else
434  {
435  u16 *srcreg, *shiftreg;
436 
437  srcreg = DECODE_RM_WORD_REGISTER(rl);
438  DECODE_PRINTF(",");
439  shiftreg = DECODE_RM_WORD_REGISTER(rh);
440  TRACE_AND_STEP();
441  bit = *shiftreg & 0xF;
442  CONDITIONAL_SET_FLAG(*srcreg & (0x1 << bit), F_CF);
443  }
444  break;
445  }
446  DECODE_CLEAR_SEGOVR();
447  END_OF_INSTR();
448 }
449 
450 /****************************************************************************
451 REMARKS:
452 Handles opcode 0x0f,0xa4
453 ****************************************************************************/
454 static void x86emuOp2_shld_IMM(u8 X86EMU_UNUSED(op2))
455 {
456  int mod, rl, rh;
457  uint destoffset;
458  u8 shift;
459 
460  START_OF_INSTR();
461  DECODE_PRINTF("SHLD\t");
462  FETCH_DECODE_MODRM(mod, rh, rl);
463  switch (mod)
464  {
465  case 0:
466  if (M.x86.mode & SYSMODE_PREFIX_DATA)
467  {
468  u32 destval;
469  u32 *shiftreg;
470 
471  destoffset = decode_rm00_address(rl);
472  DECODE_PRINTF(",");
473  shiftreg = DECODE_RM_LONG_REGISTER(rh);
474  DECODE_PRINTF(",");
475  shift = fetch_byte_imm();
476  DECODE_PRINTF2("%d\n", shift);
477  TRACE_AND_STEP();
478  destval = fetch_data_long(destoffset);
479  destval = shld_long(destval, *shiftreg, shift);
480  store_data_long(destoffset, destval);
481  }
482  else
483  {
484  u16 destval;
485  u16 *shiftreg;
486 
487  destoffset = decode_rm00_address(rl);
488  DECODE_PRINTF(",");
489  shiftreg = DECODE_RM_WORD_REGISTER(rh);
490  DECODE_PRINTF(",");
491  shift = fetch_byte_imm();
492  DECODE_PRINTF2("%d\n", shift);
493  TRACE_AND_STEP();
494  destval = fetch_data_word(destoffset);
495  destval = shld_word(destval, *shiftreg, shift);
496  store_data_word(destoffset, destval);
497  }
498  break;
499  case 1:
500  if (M.x86.mode & SYSMODE_PREFIX_DATA)
501  {
502  u32 destval;
503  u32 *shiftreg;
504 
505  destoffset = decode_rm01_address(rl);
506  DECODE_PRINTF(",");
507  shiftreg = DECODE_RM_LONG_REGISTER(rh);
508  DECODE_PRINTF(",");
509  shift = fetch_byte_imm();
510  DECODE_PRINTF2("%d\n", shift);
511  TRACE_AND_STEP();
512  destval = fetch_data_long(destoffset);
513  destval = shld_long(destval, *shiftreg, shift);
514  store_data_long(destoffset, destval);
515  }
516  else
517  {
518  u16 destval;
519  u16 *shiftreg;
520 
521  destoffset = decode_rm01_address(rl);
522  DECODE_PRINTF(",");
523  shiftreg = DECODE_RM_WORD_REGISTER(rh);
524  DECODE_PRINTF(",");
525  shift = fetch_byte_imm();
526  DECODE_PRINTF2("%d\n", shift);
527  TRACE_AND_STEP();
528  destval = fetch_data_word(destoffset);
529  destval = shld_word(destval, *shiftreg, shift);
530  store_data_word(destoffset, destval);
531  }
532  break;
533  case 2:
534  if (M.x86.mode & SYSMODE_PREFIX_DATA)
535  {
536  u32 destval;
537  u32 *shiftreg;
538 
539  destoffset = decode_rm10_address(rl);
540  DECODE_PRINTF(",");
541  shiftreg = DECODE_RM_LONG_REGISTER(rh);
542  DECODE_PRINTF(",");
543  shift = fetch_byte_imm();
544  DECODE_PRINTF2("%d\n", shift);
545  TRACE_AND_STEP();
546  destval = fetch_data_long(destoffset);
547  destval = shld_long(destval, *shiftreg, shift);
548  store_data_long(destoffset, destval);
549  }
550  else
551  {
552  u16 destval;
553  u16 *shiftreg;
554 
555  destoffset = decode_rm10_address(rl);
556  DECODE_PRINTF(",");
557  shiftreg = DECODE_RM_WORD_REGISTER(rh);
558  DECODE_PRINTF(",");
559  shift = fetch_byte_imm();
560  DECODE_PRINTF2("%d\n", shift);
561  TRACE_AND_STEP();
562  destval = fetch_data_word(destoffset);
563  destval = shld_word(destval, *shiftreg, shift);
564  store_data_word(destoffset, destval);
565  }
566  break;
567  case 3: /* register to register */
568  if (M.x86.mode & SYSMODE_PREFIX_DATA)
569  {
570  u32 *destreg, *shiftreg;
571 
572  destreg = DECODE_RM_LONG_REGISTER(rl);
573  DECODE_PRINTF(",");
574  shiftreg = DECODE_RM_LONG_REGISTER(rh);
575  DECODE_PRINTF(",");
576  shift = fetch_byte_imm();
577  DECODE_PRINTF2("%d\n", shift);
578  TRACE_AND_STEP();
579  *destreg = shld_long(*destreg, *shiftreg, shift);
580  }
581  else
582  {
583  u16 *destreg, *shiftreg;
584 
585  destreg = DECODE_RM_WORD_REGISTER(rl);
586  DECODE_PRINTF(",");
587  shiftreg = DECODE_RM_WORD_REGISTER(rh);
588  DECODE_PRINTF(",");
589  shift = fetch_byte_imm();
590  DECODE_PRINTF2("%d\n", shift);
591  TRACE_AND_STEP();
592  *destreg = shld_word(*destreg, *shiftreg, shift);
593  }
594  break;
595  }
596  DECODE_CLEAR_SEGOVR();
597  END_OF_INSTR();
598 }
599 
600 /****************************************************************************
601 REMARKS:
602 Handles opcode 0x0f,0xa5
603 ****************************************************************************/
604 static void x86emuOp2_shld_CL(u8 X86EMU_UNUSED(op2))
605 {
606  int mod, rl, rh;
607  uint destoffset;
608 
609  START_OF_INSTR();
610  DECODE_PRINTF("SHLD\t");
611  FETCH_DECODE_MODRM(mod, rh, rl);
612  switch (mod)
613  {
614  case 0:
615  if (M.x86.mode & SYSMODE_PREFIX_DATA)
616  {
617  u32 destval;
618  u32 *shiftreg;
619 
620  destoffset = decode_rm00_address(rl);
621  DECODE_PRINTF(",");
622  shiftreg = DECODE_RM_LONG_REGISTER(rh);
623  DECODE_PRINTF(",CL\n");
624  TRACE_AND_STEP();
625  destval = fetch_data_long(destoffset);
626  destval = shld_long(destval, *shiftreg, M.x86.R_CL);
627  store_data_long(destoffset, destval);
628  }
629  else
630  {
631  u16 destval;
632  u16 *shiftreg;
633 
634  destoffset = decode_rm00_address(rl);
635  DECODE_PRINTF(",");
636  shiftreg = DECODE_RM_WORD_REGISTER(rh);
637  DECODE_PRINTF(",CL\n");
638  TRACE_AND_STEP();
639  destval = fetch_data_word(destoffset);
640  destval = shld_word(destval, *shiftreg, M.x86.R_CL);
641  store_data_word(destoffset, destval);
642  }
643  break;
644  case 1:
645  if (M.x86.mode & SYSMODE_PREFIX_DATA)
646  {
647  u32 destval;
648  u32 *shiftreg;
649 
650  destoffset = decode_rm01_address(rl);
651  DECODE_PRINTF(",");
652  shiftreg = DECODE_RM_LONG_REGISTER(rh);
653  DECODE_PRINTF(",CL\n");
654  TRACE_AND_STEP();
655  destval = fetch_data_long(destoffset);
656  destval = shld_long(destval, *shiftreg, M.x86.R_CL);
657  store_data_long(destoffset, destval);
658  }
659  else
660  {
661  u16 destval;
662  u16 *shiftreg;
663 
664  destoffset = decode_rm01_address(rl);
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  break;
674  case 2:
675  if (M.x86.mode & SYSMODE_PREFIX_DATA)
676  {
677  u32 destval;
678  u32 *shiftreg;
679 
680  destoffset = decode_rm10_address(rl);
681  DECODE_PRINTF(",");
682  shiftreg = DECODE_RM_LONG_REGISTER(rh);
683  DECODE_PRINTF(",CL\n");
684  TRACE_AND_STEP();
685  destval = fetch_data_long(destoffset);
686  destval = shld_long(destval, *shiftreg, M.x86.R_CL);
687  store_data_long(destoffset, destval);
688  }
689  else
690  {
691  u16 destval;
692  u16 *shiftreg;
693 
694  destoffset = decode_rm10_address(rl);
695  DECODE_PRINTF(",");
696  shiftreg = DECODE_RM_WORD_REGISTER(rh);
697  DECODE_PRINTF(",CL\n");
698  TRACE_AND_STEP();
699  destval = fetch_data_word(destoffset);
700  destval = shld_word(destval, *shiftreg, M.x86.R_CL);
701  store_data_word(destoffset, destval);
702  }
703  break;
704  case 3: /* register to register */
705  if (M.x86.mode & SYSMODE_PREFIX_DATA)
706  {
707  u32 *destreg, *shiftreg;
708 
709  destreg = DECODE_RM_LONG_REGISTER(rl);
710  DECODE_PRINTF(",");
711  shiftreg = DECODE_RM_LONG_REGISTER(rh);
712  DECODE_PRINTF(",CL\n");
713  TRACE_AND_STEP();
714  *destreg = shld_long(*destreg, *shiftreg, M.x86.R_CL);
715  }
716  else
717  {
718  u16 *destreg, *shiftreg;
719 
720  destreg = DECODE_RM_WORD_REGISTER(rl);
721  DECODE_PRINTF(",");
722  shiftreg = DECODE_RM_WORD_REGISTER(rh);
723  DECODE_PRINTF(",CL\n");
724  TRACE_AND_STEP();
725  *destreg = shld_word(*destreg, *shiftreg, M.x86.R_CL);
726  }
727  break;
728  }
729  DECODE_CLEAR_SEGOVR();
730  END_OF_INSTR();
731 }
732 
733 /****************************************************************************
734 REMARKS:
735 Handles opcode 0x0f,0xa8
736 ****************************************************************************/
737 static void x86emuOp2_push_GS(u8 X86EMU_UNUSED(op2))
738 {
739  START_OF_INSTR();
740  DECODE_PRINTF("PUSH\tGS\n");
741  TRACE_AND_STEP();
742  push_word(M.x86.R_GS);
743  DECODE_CLEAR_SEGOVR();
744  END_OF_INSTR();
745 }
746 
747 /****************************************************************************
748 REMARKS:
749 Handles opcode 0x0f,0xa9
750 ****************************************************************************/
751 static void x86emuOp2_pop_GS(u8 X86EMU_UNUSED(op2))
752 {
753  START_OF_INSTR();
754  DECODE_PRINTF("POP\tGS\n");
755  TRACE_AND_STEP();
756  M.x86.R_GS = pop_word();
757  DECODE_CLEAR_SEGOVR();
758  END_OF_INSTR();
759 }
760 
761 /****************************************************************************
762 REMARKS:
763 Handles opcode 0x0f,0xab
764 ****************************************************************************/
765 static void x86emuOp2_bts_R(u8 X86EMU_UNUSED(op2))
766 {
767  int mod, rl, rh;
768  uint srcoffset;
769  int bit, disp;
770 
771  START_OF_INSTR();
772  DECODE_PRINTF("BTS\t");
773  FETCH_DECODE_MODRM(mod, rh, rl);
774  switch (mod)
775  {
776  case 0:
777  if (M.x86.mode & SYSMODE_PREFIX_DATA)
778  {
779  u32 srcval, mask;
780  u32 *shiftreg;
781 
782  srcoffset = decode_rm00_address(rl);
783  DECODE_PRINTF(",");
784  shiftreg = DECODE_RM_LONG_REGISTER(rh);
785  TRACE_AND_STEP();
786  bit = *shiftreg & 0x1F;
787  disp = (s16) *shiftreg >> 5;
788  srcval = fetch_data_long(srcoffset + disp);
789  mask = (0x1 << bit);
790  CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
791  store_data_long(srcoffset + disp, srcval | mask);
792  }
793  else
794  {
795  u16 srcval, mask;
796  u16 *shiftreg;
797 
798  srcoffset = decode_rm00_address(rl);
799  DECODE_PRINTF(",");
800  shiftreg = DECODE_RM_WORD_REGISTER(rh);
801  TRACE_AND_STEP();
802  bit = *shiftreg & 0xF;
803  disp = (s16) *shiftreg >> 4;
804  srcval = fetch_data_word(srcoffset + disp);
805  mask = (u16)(0x1 << bit);
806  CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
807  store_data_word(srcoffset + disp, srcval | mask);
808  }
809  break;
810  case 1:
811  if (M.x86.mode & SYSMODE_PREFIX_DATA)
812  {
813  u32 srcval, mask;
814  u32 *shiftreg;
815 
816  srcoffset = decode_rm01_address(rl);
817  DECODE_PRINTF(",");
818  shiftreg = DECODE_RM_LONG_REGISTER(rh);
819  TRACE_AND_STEP();
820  bit = *shiftreg & 0x1F;
821  disp = (s16) *shiftreg >> 5;
822  srcval = fetch_data_long(srcoffset + disp);
823  mask = (0x1 << bit);
824  CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
825  store_data_long(srcoffset + disp, srcval | mask);
826  }
827  else
828  {
829  u16 srcval, mask;
830  u16 *shiftreg;
831 
832  srcoffset = decode_rm01_address(rl);
833  DECODE_PRINTF(",");
834  shiftreg = DECODE_RM_WORD_REGISTER(rh);
835  TRACE_AND_STEP();
836  bit = *shiftreg & 0xF;
837  disp = (s16) *shiftreg >> 4;
838  srcval = fetch_data_word(srcoffset + disp);
839  mask = (u16)(0x1 << bit);
840  CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
841  store_data_word(srcoffset + disp, srcval | mask);
842  }
843  break;
844  case 2:
845  if (M.x86.mode & SYSMODE_PREFIX_DATA)
846  {
847  u32 srcval, mask;
848  u32 *shiftreg;
849 
850  srcoffset = decode_rm10_address(rl);
851  DECODE_PRINTF(",");
852  shiftreg = DECODE_RM_LONG_REGISTER(rh);
853  TRACE_AND_STEP();
854  bit = *shiftreg & 0x1F;
855  disp = (s16) *shiftreg >> 5;
856  srcval = fetch_data_long(srcoffset + disp);
857  mask = (0x1 << bit);
858  CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
859  store_data_long(srcoffset + disp, srcval | mask);
860  }
861  else
862  {
863  u16 srcval, mask;
864  u16 *shiftreg;
865 
866  srcoffset = decode_rm10_address(rl);
867  DECODE_PRINTF(",");
868  shiftreg = DECODE_RM_WORD_REGISTER(rh);
869  TRACE_AND_STEP();
870  bit = *shiftreg & 0xF;
871  disp = (s16) *shiftreg >> 4;
872  srcval = fetch_data_word(srcoffset + disp);
873  mask = (u16)(0x1 << bit);
874  CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
875  store_data_word(srcoffset + disp, srcval | mask);
876  }
877  break;
878  case 3: /* register to register */
879  if (M.x86.mode & SYSMODE_PREFIX_DATA)
880  {
881  u32 *srcreg, *shiftreg;
882  u32 mask;
883 
884  srcreg = DECODE_RM_LONG_REGISTER(rl);
885  DECODE_PRINTF(",");
886  shiftreg = DECODE_RM_LONG_REGISTER(rh);
887  TRACE_AND_STEP();
888  bit = *shiftreg & 0x1F;
889  mask = (0x1 << bit);
890  CONDITIONAL_SET_FLAG(*srcreg & mask, F_CF);
891  *srcreg |= mask;
892  }
893  else
894  {
895  u16 *srcreg, *shiftreg;
896  u16 mask;
897 
898  srcreg = DECODE_RM_WORD_REGISTER(rl);
899  DECODE_PRINTF(",");
900  shiftreg = DECODE_RM_WORD_REGISTER(rh);
901  TRACE_AND_STEP();
902  bit = *shiftreg & 0xF;
903  mask = (u16)(0x1 << bit);
904  CONDITIONAL_SET_FLAG(*srcreg & mask, F_CF);
905  *srcreg |= mask;
906  }
907  break;
908  }
909  DECODE_CLEAR_SEGOVR();
910  END_OF_INSTR();
911 }
912 
913 /****************************************************************************
914 REMARKS:
915 Handles opcode 0x0f,0xac
916 ****************************************************************************/
917 static void x86emuOp2_shrd_IMM(u8 X86EMU_UNUSED(op2))
918 {
919  int mod, rl, rh;
920  uint destoffset;
921  u8 shift;
922 
923  START_OF_INSTR();
924  DECODE_PRINTF("SHLD\t");
925  FETCH_DECODE_MODRM(mod, rh, rl);
926  switch (mod)
927  {
928  case 0:
929  if (M.x86.mode & SYSMODE_PREFIX_DATA)
930  {
931  u32 destval;
932  u32 *shiftreg;
933 
934  destoffset = decode_rm00_address(rl);
935  DECODE_PRINTF(",");
936  shiftreg = DECODE_RM_LONG_REGISTER(rh);
937  DECODE_PRINTF(",");
938  shift = fetch_byte_imm();
939  DECODE_PRINTF2("%d\n", shift);
940  TRACE_AND_STEP();
941  destval = fetch_data_long(destoffset);
942  destval = shrd_long(destval, *shiftreg, shift);
943  store_data_long(destoffset, destval);
944  }
945  else
946  {
947  u16 destval;
948  u16 *shiftreg;
949 
950  destoffset = decode_rm00_address(rl);
951  DECODE_PRINTF(",");
952  shiftreg = DECODE_RM_WORD_REGISTER(rh);
953  DECODE_PRINTF(",");
954  shift = fetch_byte_imm();
955  DECODE_PRINTF2("%d\n", shift);
956  TRACE_AND_STEP();
957  destval = fetch_data_word(destoffset);
958  destval = shrd_word(destval, *shiftreg, shift);
959  store_data_word(destoffset, destval);
960  }
961  break;
962  case 1:
963  if (M.x86.mode & SYSMODE_PREFIX_DATA)
964  {
965  u32 destval;
966  u32 *shiftreg;
967 
968  destoffset = decode_rm01_address(rl);
969  DECODE_PRINTF(",");
970  shiftreg = DECODE_RM_LONG_REGISTER(rh);
971  DECODE_PRINTF(",");
972  shift = fetch_byte_imm();
973  DECODE_PRINTF2("%d\n", shift);
974  TRACE_AND_STEP();
975  destval = fetch_data_long(destoffset);
976  destval = shrd_long(destval, *shiftreg, shift);
977  store_data_long(destoffset, destval);
978  }
979  else
980  {
981  u16 destval;
982  u16 *shiftreg;
983 
984  destoffset = decode_rm01_address(rl);
985  DECODE_PRINTF(",");
986  shiftreg = DECODE_RM_WORD_REGISTER(rh);
987  DECODE_PRINTF(",");
988  shift = fetch_byte_imm();
989  DECODE_PRINTF2("%d\n", shift);
990  TRACE_AND_STEP();
991  destval = fetch_data_word(destoffset);
992  destval = shrd_word(destval, *shiftreg, shift);
993  store_data_word(destoffset, destval);
994  }
995  break;
996  case 2:
997  if (M.x86.mode & SYSMODE_PREFIX_DATA)
998  {
999  u32 destval;
1000  u32 *shiftreg;
1001 
1002  destoffset = decode_rm10_address(rl);
1003  DECODE_PRINTF(",");
1004  shiftreg = DECODE_RM_LONG_REGISTER(rh);
1005  DECODE_PRINTF(",");
1006  shift = fetch_byte_imm();
1007  DECODE_PRINTF2("%d\n", shift);
1008  TRACE_AND_STEP();
1009  destval = fetch_data_long(destoffset);
1010  destval = shrd_long(destval, *shiftreg, shift);
1011  store_data_long(destoffset, destval);
1012  }
1013  else
1014  {
1015  u16 destval;
1016  u16 *shiftreg;
1017 
1018  destoffset = decode_rm10_address(rl);
1019  DECODE_PRINTF(",");
1020  shiftreg = DECODE_RM_WORD_REGISTER(rh);
1021  DECODE_PRINTF(",");
1022  shift = fetch_byte_imm();
1023  DECODE_PRINTF2("%d\n", shift);
1024  TRACE_AND_STEP();
1025  destval = fetch_data_word(destoffset);
1026  destval = shrd_word(destval, *shiftreg, shift);
1027  store_data_word(destoffset, destval);
1028  }
1029  break;
1030  case 3: /* register to register */
1031  if (M.x86.mode & SYSMODE_PREFIX_DATA)
1032  {
1033  u32 *destreg, *shiftreg;
1034 
1035  destreg = DECODE_RM_LONG_REGISTER(rl);
1036  DECODE_PRINTF(",");
1037  shiftreg = DECODE_RM_LONG_REGISTER(rh);
1038  DECODE_PRINTF(",");
1039  shift = fetch_byte_imm();
1040  DECODE_PRINTF2("%d\n", shift);
1041  TRACE_AND_STEP();
1042  *destreg = shrd_long(*destreg, *shiftreg, shift);
1043  }
1044  else
1045  {
1046  u16 *destreg, *shiftreg;
1047 
1048  destreg = DECODE_RM_WORD_REGISTER(rl);
1049  DECODE_PRINTF(",");
1050  shiftreg = DECODE_RM_WORD_REGISTER(rh);
1051  DECODE_PRINTF(",");
1052  shift = fetch_byte_imm();
1053  DECODE_PRINTF2("%d\n", shift);
1054  TRACE_AND_STEP();
1055  *destreg = shrd_word(*destreg, *shiftreg, shift);
1056  }
1057  break;
1058  }
1059  DECODE_CLEAR_SEGOVR();
1060  END_OF_INSTR();
1061 }
1062 
1063 /****************************************************************************
1064 REMARKS:
1065 Handles opcode 0x0f,0xad
1066 ****************************************************************************/
1067 static void x86emuOp2_shrd_CL(u8 X86EMU_UNUSED(op2))
1068 {
1069  int mod, rl, rh;
1070  uint destoffset;
1071 
1072  START_OF_INSTR();
1073  DECODE_PRINTF("SHLD\t");
1074  FETCH_DECODE_MODRM(mod, rh, rl);
1075  switch (mod)
1076  {
1077  case 0:
1078  if (M.x86.mode & SYSMODE_PREFIX_DATA)
1079  {
1080  u32 destval;
1081  u32 *shiftreg;
1082 
1083  destoffset = decode_rm00_address(rl);
1084  DECODE_PRINTF(",");
1085  shiftreg = DECODE_RM_LONG_REGISTER(rh);
1086  DECODE_PRINTF(",CL\n");
1087  TRACE_AND_STEP();
1088  destval = fetch_data_long(destoffset);
1089  destval = shrd_long(destval, *shiftreg, M.x86.R_CL);
1090  store_data_long(destoffset, destval);
1091  }
1092  else
1093  {
1094  u16 destval;
1095  u16 *shiftreg;
1096 
1097  destoffset = decode_rm00_address(rl);
1098  DECODE_PRINTF(",");
1099  shiftreg = DECODE_RM_WORD_REGISTER(rh);
1100  DECODE_PRINTF(",CL\n");
1101  TRACE_AND_STEP();
1102  destval = fetch_data_word(destoffset);
1103  destval = shrd_word(destval, *shiftreg, M.x86.R_CL);
1104  store_data_word(destoffset, destval);
1105  }
1106  break;
1107  case 1:
1108  if (M.x86.mode & SYSMODE_PREFIX_DATA)
1109  {
1110  u32 destval;
1111  u32 *shiftreg;
1112 
1113  destoffset = decode_rm01_address(rl);
1114  DECODE_PRINTF(",");
1115  shiftreg = DECODE_RM_LONG_REGISTER(rh);
1116  DECODE_PRINTF(",CL\n");
1117  TRACE_AND_STEP();
1118  destval = fetch_data_long(destoffset);
1119  destval = shrd_long(destval, *shiftreg, M.x86.R_CL);
1120  store_data_long(destoffset, destval);
1121  }
1122  else
1123  {
1124  u16 destval;
1125  u16 *shiftreg;
1126 
1127  destoffset = decode_rm01_address(rl);
1128  DECODE_PRINTF(",");
1129  shiftreg = DECODE_RM_WORD_REGISTER(rh);
1130  DECODE_PRINTF(",CL\n");
1131  TRACE_AND_STEP();
1132  destval = fetch_data_word(destoffset);
1133  destval = shrd_word(destval, *shiftreg, M.x86.R_CL);
1134  store_data_word(destoffset, destval);
1135  }
1136  break;
1137  case 2:
1138  if (M.x86.mode & SYSMODE_PREFIX_DATA)
1139  {
1140  u32 destval;
1141  u32 *shiftreg;
1142 
1143  destoffset = decode_rm10_address(rl);
1144  DECODE_PRINTF(",");
1145  shiftreg = DECODE_RM_LONG_REGISTER(rh);
1146  DECODE_PRINTF(",CL\n");
1147  TRACE_AND_STEP();
1148  destval = fetch_data_long(destoffset);
1149  destval = shrd_long(destval, *shiftreg, M.x86.R_CL);
1150  store_data_long(destoffset, destval);
1151  }
1152  else
1153  {
1154  u16 destval;
1155  u16 *shiftreg;
1156 
1157  destoffset = decode_rm10_address(rl);
1158  DECODE_PRINTF(",");
1159  shiftreg = DECODE_RM_WORD_REGISTER(rh);
1160  DECODE_PRINTF(",CL\n");
1161  TRACE_AND_STEP();
1162  destval = fetch_data_word(destoffset);
1163  destval = shrd_word(destval, *shiftreg, M.x86.R_CL);
1164  store_data_word(destoffset, destval);
1165  }
1166  break;
1167  case 3: /* register to register */
1168  if (M.x86.mode & SYSMODE_PREFIX_DATA)
1169  {
1170  u32 *destreg, *shiftreg;
1171 
1172  destreg = DECODE_RM_LONG_REGISTER(rl);
1173  DECODE_PRINTF(",");
1174  shiftreg = DECODE_RM_LONG_REGISTER(rh);
1175  DECODE_PRINTF(",CL\n");
1176  TRACE_AND_STEP();
1177  *destreg = shrd_long(*destreg, *shiftreg, M.x86.R_CL);
1178  }
1179  else
1180  {
1181  u16 *destreg, *shiftreg;
1182 
1183  destreg = DECODE_RM_WORD_REGISTER(rl);
1184  DECODE_PRINTF(",");
1185  shiftreg = DECODE_RM_WORD_REGISTER(rh);
1186  DECODE_PRINTF(",CL\n");
1187  TRACE_AND_STEP();
1188  *destreg = shrd_word(*destreg, *shiftreg, M.x86.R_CL);
1189  }
1190  break;
1191  }
1192  DECODE_CLEAR_SEGOVR();
1193  END_OF_INSTR();
1194 }
1195 
1196 /****************************************************************************
1197 REMARKS:
1198 Handles opcode 0x0f,0xaf
1199 ****************************************************************************/
1200 static void x86emuOp2_imul_R_RM(u8 X86EMU_UNUSED(op2))
1201 {
1202  int mod, rl, rh;
1203  uint srcoffset;
1204 
1205  START_OF_INSTR();
1206  DECODE_PRINTF("IMUL\t");
1207  FETCH_DECODE_MODRM(mod, rh, rl);
1208  switch (mod)
1209  {
1210  case 0:
1211  if (M.x86.mode & SYSMODE_PREFIX_DATA)
1212  {
1213  u32 *destreg;
1214  u32 srcval;
1215  u32 res_lo, res_hi;
1216 
1217  destreg = DECODE_RM_LONG_REGISTER(rh);
1218  DECODE_PRINTF(",");
1219  srcoffset = decode_rm00_address(rl);
1220  srcval = fetch_data_long(srcoffset);
1221  TRACE_AND_STEP();
1222  imul_long_direct(
1223  &res_lo, &res_hi, (s32) *destreg, (s32) srcval);
1224  if (res_hi != 0)
1225  {
1226  SET_FLAG(F_CF);
1227  SET_FLAG(F_OF);
1228  }
1229  else
1230  {
1231  CLEAR_FLAG(F_CF);
1232  CLEAR_FLAG(F_OF);
1233  }
1234  *destreg = (u32) res_lo;
1235  }
1236  else
1237  {
1238  u16 *destreg;
1239  u16 srcval;
1240  u32 res;
1241 
1242  destreg = DECODE_RM_WORD_REGISTER(rh);
1243  DECODE_PRINTF(",");
1244  srcoffset = decode_rm00_address(rl);
1245  srcval = fetch_data_word(srcoffset);
1246  TRACE_AND_STEP();
1247  res = (s16) *destreg * (s16) srcval;
1248  if (res > 0xFFFF)
1249  {
1250  SET_FLAG(F_CF);
1251  SET_FLAG(F_OF);
1252  }
1253  else
1254  {
1255  CLEAR_FLAG(F_CF);
1256  CLEAR_FLAG(F_OF);
1257  }
1258  *destreg = (u16) res;
1259  }
1260  break;
1261  case 1:
1262  if (M.x86.mode & SYSMODE_PREFIX_DATA)
1263  {
1264  u32 *destreg;
1265  u32 srcval;
1266  u32 res_lo, res_hi;
1267 
1268  destreg = DECODE_RM_LONG_REGISTER(rh);
1269  DECODE_PRINTF(",");
1270  srcoffset = decode_rm01_address(rl);
1271  srcval = fetch_data_long(srcoffset);
1272  TRACE_AND_STEP();
1273  imul_long_direct(
1274  &res_lo, &res_hi, (s32) *destreg, (s32) srcval);
1275  if (res_hi != 0)
1276  {
1277  SET_FLAG(F_CF);
1278  SET_FLAG(F_OF);
1279  }
1280  else
1281  {
1282  CLEAR_FLAG(F_CF);
1283  CLEAR_FLAG(F_OF);
1284  }
1285  *destreg = (u32) res_lo;
1286  }
1287  else
1288  {
1289  u16 *destreg;
1290  u16 srcval;
1291  u32 res;
1292 
1293  destreg = DECODE_RM_WORD_REGISTER(rh);
1294  DECODE_PRINTF(",");
1295  srcoffset = decode_rm01_address(rl);
1296  srcval = fetch_data_word(srcoffset);
1297  TRACE_AND_STEP();
1298  res = (s16) *destreg * (s16) srcval;
1299  if (res > 0xFFFF)
1300  {
1301  SET_FLAG(F_CF);
1302  SET_FLAG(F_OF);
1303  }
1304  else
1305  {
1306  CLEAR_FLAG(F_CF);
1307  CLEAR_FLAG(F_OF);
1308  }
1309  *destreg = (u16) res;
1310  }
1311  break;
1312  case 2:
1313  if (M.x86.mode & SYSMODE_PREFIX_DATA)
1314  {
1315  u32 *destreg;
1316  u32 srcval;
1317  u32 res_lo, res_hi;
1318 
1319  destreg = DECODE_RM_LONG_REGISTER(rh);
1320  DECODE_PRINTF(",");
1321  srcoffset = decode_rm10_address(rl);
1322  srcval = fetch_data_long(srcoffset);
1323  TRACE_AND_STEP();
1324  imul_long_direct(
1325  &res_lo, &res_hi, (s32) *destreg, (s32) srcval);
1326  if (res_hi != 0)
1327  {
1328  SET_FLAG(F_CF);
1329  SET_FLAG(F_OF);
1330  }
1331  else
1332  {
1333  CLEAR_FLAG(F_CF);
1334  CLEAR_FLAG(F_OF);
1335  }
1336  *destreg = (u32) res_lo;
1337  }
1338  else
1339  {
1340  u16 *destreg;
1341  u16 srcval;
1342  u32 res;
1343 
1344  destreg = DECODE_RM_WORD_REGISTER(rh);
1345  DECODE_PRINTF(",");
1346  srcoffset = decode_rm10_address(rl);
1347  srcval = fetch_data_word(srcoffset);
1348  TRACE_AND_STEP();
1349  res = (s16) *destreg * (s16) srcval;
1350  if (res > 0xFFFF)
1351  {
1352  SET_FLAG(F_CF);
1353  SET_FLAG(F_OF);
1354  }
1355  else
1356  {
1357  CLEAR_FLAG(F_CF);
1358  CLEAR_FLAG(F_OF);
1359  }
1360  *destreg = (u16) res;
1361  }
1362  break;
1363  case 3: /* register to register */
1364  if (M.x86.mode & SYSMODE_PREFIX_DATA)
1365  {
1366  u32 *destreg, *srcreg;
1367  u32 res_lo, res_hi;
1368 
1369  destreg = DECODE_RM_LONG_REGISTER(rh);
1370  DECODE_PRINTF(",");
1371  srcreg = DECODE_RM_LONG_REGISTER(rl);
1372  TRACE_AND_STEP();
1373  imul_long_direct(
1374  &res_lo, &res_hi, (s32) *destreg, (s32) *srcreg);
1375  if (res_hi != 0)
1376  {
1377  SET_FLAG(F_CF);
1378  SET_FLAG(F_OF);
1379  }
1380  else
1381  {
1382  CLEAR_FLAG(F_CF);
1383  CLEAR_FLAG(F_OF);
1384  }
1385  *destreg = (u32) res_lo;
1386  }
1387  else
1388  {
1389  u16 *destreg, *srcreg;
1390  u32 res;
1391 
1392  destreg = DECODE_RM_WORD_REGISTER(rh);
1393  DECODE_PRINTF(",");
1394  srcreg = DECODE_RM_WORD_REGISTER(rl);
1395  res = (s16) *destreg * (s16) *srcreg;
1396  if (res > 0xFFFF)
1397  {
1398  SET_FLAG(F_CF);
1399  SET_FLAG(F_OF);
1400  }
1401  else
1402  {
1403  CLEAR_FLAG(F_CF);
1404  CLEAR_FLAG(F_OF);
1405  }
1406  *destreg = (u16) res;
1407  }
1408  break;
1409  }
1410  DECODE_CLEAR_SEGOVR();
1411  END_OF_INSTR();
1412 }
1413 
1414 /****************************************************************************
1415 REMARKS:
1416 Handles opcode 0x0f,0xb2
1417 ****************************************************************************/
1418 static void x86emuOp2_lss_R_IMM(u8 X86EMU_UNUSED(op2))
1419 {
1420  int mod, rh, rl;
1421  u16 *dstreg;
1422  uint srcoffset;
1423 
1424  START_OF_INSTR();
1425  DECODE_PRINTF("LSS\t");
1426  FETCH_DECODE_MODRM(mod, rh, rl);
1427  switch (mod)
1428  {
1429  case 0:
1430  dstreg = DECODE_RM_WORD_REGISTER(rh);
1431  DECODE_PRINTF(",");
1432  srcoffset = decode_rm00_address(rl);
1433  DECODE_PRINTF("\n");
1434  TRACE_AND_STEP();
1435  *dstreg = fetch_data_word(srcoffset);
1436  M.x86.R_SS = fetch_data_word(srcoffset + 2);
1437  break;
1438  case 1:
1439  dstreg = DECODE_RM_WORD_REGISTER(rh);
1440  DECODE_PRINTF(",");
1441  srcoffset = decode_rm01_address(rl);
1442  DECODE_PRINTF("\n");
1443  TRACE_AND_STEP();
1444  *dstreg = fetch_data_word(srcoffset);
1445  M.x86.R_SS = fetch_data_word(srcoffset + 2);
1446  break;
1447  case 2:
1448  dstreg = DECODE_RM_WORD_REGISTER(rh);
1449  DECODE_PRINTF(",");
1450  srcoffset = decode_rm10_address(rl);
1451  DECODE_PRINTF("\n");
1452  TRACE_AND_STEP();
1453  *dstreg = fetch_data_word(srcoffset);
1454  M.x86.R_SS = fetch_data_word(srcoffset + 2);
1455  break;
1456  case 3: /* register to register */
1457  /* UNDEFINED! */
1458  TRACE_AND_STEP();
1459  }
1460  DECODE_CLEAR_SEGOVR();
1461  END_OF_INSTR();
1462 }
1463 
1464 /****************************************************************************
1465 REMARKS:
1466 Handles opcode 0x0f,0xb3
1467 ****************************************************************************/
1468 static void x86emuOp2_btr_R(u8 X86EMU_UNUSED(op2))
1469 {
1470  int mod, rl, rh;
1471  uint srcoffset;
1472  int bit, disp;
1473 
1474  START_OF_INSTR();
1475  DECODE_PRINTF("BTR\t");
1476  FETCH_DECODE_MODRM(mod, rh, rl);
1477  switch (mod)
1478  {
1479  case 0:
1480  if (M.x86.mode & SYSMODE_PREFIX_DATA)
1481  {
1482  u32 srcval, mask;
1483  u32 *shiftreg;
1484 
1485  srcoffset = decode_rm00_address(rl);
1486  DECODE_PRINTF(",");
1487  shiftreg = DECODE_RM_LONG_REGISTER(rh);
1488  TRACE_AND_STEP();
1489  bit = *shiftreg & 0x1F;
1490  disp = (s16) *shiftreg >> 5;
1491  srcval = fetch_data_long(srcoffset + disp);
1492  mask = (0x1 << bit);
1493  CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
1494  store_data_long(srcoffset + disp, srcval & ~mask);
1495  }
1496  else
1497  {
1498  u16 srcval, mask;
1499  u16 *shiftreg;
1500 
1501  srcoffset = decode_rm00_address(rl);
1502  DECODE_PRINTF(",");
1503  shiftreg = DECODE_RM_WORD_REGISTER(rh);
1504  TRACE_AND_STEP();
1505  bit = *shiftreg & 0xF;
1506  disp = (s16) *shiftreg >> 4;
1507  srcval = fetch_data_word(srcoffset + disp);
1508  mask = (u16)(0x1 << bit);
1509  CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
1510  store_data_word(srcoffset + disp, (u16)(srcval & ~mask));
1511  }
1512  break;
1513  case 1:
1514  if (M.x86.mode & SYSMODE_PREFIX_DATA)
1515  {
1516  u32 srcval, mask;
1517  u32 *shiftreg;
1518 
1519  srcoffset = decode_rm01_address(rl);
1520  DECODE_PRINTF(",");
1521  shiftreg = DECODE_RM_LONG_REGISTER(rh);
1522  TRACE_AND_STEP();
1523  bit = *shiftreg & 0x1F;
1524  disp = (s16) *shiftreg >> 5;
1525  srcval = fetch_data_long(srcoffset + disp);
1526  mask = (0x1 << bit);
1527  CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
1528  store_data_long(srcoffset + disp, srcval & ~mask);
1529  }
1530  else
1531  {
1532  u16 srcval, mask;
1533  u16 *shiftreg;
1534 
1535  srcoffset = decode_rm01_address(rl);
1536  DECODE_PRINTF(",");
1537  shiftreg = DECODE_RM_WORD_REGISTER(rh);
1538  TRACE_AND_STEP();
1539  bit = *shiftreg & 0xF;
1540  disp = (s16) *shiftreg >> 4;
1541  srcval = fetch_data_word(srcoffset + disp);
1542  mask = (u16)(0x1 << bit);
1543  CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
1544  store_data_word(srcoffset + disp, (u16)(srcval & ~mask));
1545  }
1546  break;
1547  case 2:
1548  if (M.x86.mode & SYSMODE_PREFIX_DATA)
1549  {
1550  u32 srcval, mask;
1551  u32 *shiftreg;
1552 
1553  srcoffset = decode_rm10_address(rl);
1554  DECODE_PRINTF(",");
1555  shiftreg = DECODE_RM_LONG_REGISTER(rh);
1556  TRACE_AND_STEP();
1557  bit = *shiftreg & 0x1F;
1558  disp = (s16) *shiftreg >> 5;
1559  srcval = fetch_data_long(srcoffset + disp);
1560  mask = (0x1 << bit);
1561  CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
1562  store_data_long(srcoffset + disp, srcval & ~mask);
1563  }
1564  else
1565  {
1566  u16 srcval, mask;
1567  u16 *shiftreg;
1568 
1569  srcoffset = decode_rm10_address(rl);
1570  DECODE_PRINTF(",");
1571  shiftreg = DECODE_RM_WORD_REGISTER(rh);
1572  TRACE_AND_STEP();
1573  bit = *shiftreg & 0xF;
1574  disp = (s16) *shiftreg >> 4;
1575  srcval = fetch_data_word(srcoffset + disp);
1576  mask = (u16)(0x1 << bit);
1577  CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
1578  store_data_word(srcoffset + disp, (u16)(srcval & ~mask));
1579  }
1580  break;
1581  case 3: /* register to register */
1582  if (M.x86.mode & SYSMODE_PREFIX_DATA)
1583  {
1584  u32 *srcreg, *shiftreg;
1585  u32 mask;
1586 
1587  srcreg = DECODE_RM_LONG_REGISTER(rl);
1588  DECODE_PRINTF(",");
1589  shiftreg = DECODE_RM_LONG_REGISTER(rh);
1590  TRACE_AND_STEP();
1591  bit = *shiftreg & 0x1F;
1592  mask = (0x1 << bit);
1593  CONDITIONAL_SET_FLAG(*srcreg & mask, F_CF);
1594  *srcreg &= ~mask;
1595  }
1596  else
1597  {
1598  u16 *srcreg, *shiftreg;
1599  u16 mask;
1600 
1601  srcreg = DECODE_RM_WORD_REGISTER(rl);
1602  DECODE_PRINTF(",");
1603  shiftreg = DECODE_RM_WORD_REGISTER(rh);
1604  TRACE_AND_STEP();
1605  bit = *shiftreg & 0xF;
1606  mask = (u16)(0x1 << bit);
1607  CONDITIONAL_SET_FLAG(*srcreg & mask, F_CF);
1608  *srcreg &= ~mask;
1609  }
1610  break;
1611  }
1612  DECODE_CLEAR_SEGOVR();
1613  END_OF_INSTR();
1614 }
1615 
1616 /****************************************************************************
1617 REMARKS:
1618 Handles opcode 0x0f,0xb4
1619 ****************************************************************************/
1620 static void x86emuOp2_lfs_R_IMM(u8 X86EMU_UNUSED(op2))
1621 {
1622  int mod, rh, rl;
1623  u16 *dstreg;
1624  uint srcoffset;
1625 
1626  START_OF_INSTR();
1627  DECODE_PRINTF("LFS\t");
1628  FETCH_DECODE_MODRM(mod, rh, rl);
1629  switch (mod)
1630  {
1631  case 0:
1632  dstreg = DECODE_RM_WORD_REGISTER(rh);
1633  DECODE_PRINTF(",");
1634  srcoffset = decode_rm00_address(rl);
1635  DECODE_PRINTF("\n");
1636  TRACE_AND_STEP();
1637  *dstreg = fetch_data_word(srcoffset);
1638  M.x86.R_FS = fetch_data_word(srcoffset + 2);
1639  break;
1640  case 1:
1641  dstreg = DECODE_RM_WORD_REGISTER(rh);
1642  DECODE_PRINTF(",");
1643  srcoffset = decode_rm01_address(rl);
1644  DECODE_PRINTF("\n");
1645  TRACE_AND_STEP();
1646  *dstreg = fetch_data_word(srcoffset);
1647  M.x86.R_FS = fetch_data_word(srcoffset + 2);
1648  break;
1649  case 2:
1650  dstreg = DECODE_RM_WORD_REGISTER(rh);
1651  DECODE_PRINTF(",");
1652  srcoffset = decode_rm10_address(rl);
1653  DECODE_PRINTF("\n");
1654  TRACE_AND_STEP();
1655  *dstreg = fetch_data_word(srcoffset);
1656  M.x86.R_FS = fetch_data_word(srcoffset + 2);
1657  break;
1658  case 3: /* register to register */
1659  /* UNDEFINED! */
1660  TRACE_AND_STEP();
1661  }
1662  DECODE_CLEAR_SEGOVR();
1663  END_OF_INSTR();
1664 }
1665 
1666 /****************************************************************************
1667 REMARKS:
1668 Handles opcode 0x0f,0xb5
1669 ****************************************************************************/
1670 static void x86emuOp2_lgs_R_IMM(u8 X86EMU_UNUSED(op2))
1671 {
1672  int mod, rh, rl;
1673  u16 *dstreg;
1674  uint srcoffset;
1675 
1676  START_OF_INSTR();
1677  DECODE_PRINTF("LGS\t");
1678  FETCH_DECODE_MODRM(mod, rh, rl);
1679  switch (mod)
1680  {
1681  case 0:
1682  dstreg = DECODE_RM_WORD_REGISTER(rh);
1683  DECODE_PRINTF(",");
1684  srcoffset = decode_rm00_address(rl);
1685  DECODE_PRINTF("\n");
1686  TRACE_AND_STEP();
1687  *dstreg = fetch_data_word(srcoffset);
1688  M.x86.R_GS = fetch_data_word(srcoffset + 2);
1689  break;
1690  case 1:
1691  dstreg = DECODE_RM_WORD_REGISTER(rh);
1692  DECODE_PRINTF(",");
1693  srcoffset = decode_rm01_address(rl);
1694  DECODE_PRINTF("\n");
1695  TRACE_AND_STEP();
1696  *dstreg = fetch_data_word(srcoffset);
1697  M.x86.R_GS = fetch_data_word(srcoffset + 2);
1698  break;
1699  case 2:
1700  dstreg = DECODE_RM_WORD_REGISTER(rh);
1701  DECODE_PRINTF(",");
1702  srcoffset = decode_rm10_address(rl);
1703  DECODE_PRINTF("\n");
1704  TRACE_AND_STEP();
1705  *dstreg = fetch_data_word(srcoffset);
1706  M.x86.R_GS = fetch_data_word(srcoffset + 2);
1707  break;
1708  case 3: /* register to register */
1709  /* UNDEFINED! */
1710  TRACE_AND_STEP();
1711  }
1712  DECODE_CLEAR_SEGOVR();
1713  END_OF_INSTR();
1714 }
1715 
1716 /****************************************************************************
1717 REMARKS:
1718 Handles opcode 0x0f,0xb6
1719 ****************************************************************************/
1720 static void x86emuOp2_movzx_byte_R_RM(u8 X86EMU_UNUSED(op2))
1721 {
1722  int mod, rl, rh;
1723  uint srcoffset;
1724 
1725  START_OF_INSTR();
1726  DECODE_PRINTF("MOVZX\t");
1727  FETCH_DECODE_MODRM(mod, rh, rl);
1728  switch (mod)
1729  {
1730  case 0:
1731  if (M.x86.mode & SYSMODE_PREFIX_DATA)
1732  {
1733  u32 *destreg;
1734  u32 srcval;
1735 
1736  destreg = DECODE_RM_LONG_REGISTER(rh);
1737  DECODE_PRINTF(",");
1738  srcoffset = decode_rm00_address(rl);
1739  srcval = fetch_data_byte(srcoffset);
1740  DECODE_PRINTF("\n");
1741  TRACE_AND_STEP();
1742  *destreg = srcval;
1743  }
1744  else
1745  {
1746  u16 *destreg;
1747  u16 srcval;
1748 
1749  destreg = DECODE_RM_WORD_REGISTER(rh);
1750  DECODE_PRINTF(",");
1751  srcoffset = decode_rm00_address(rl);
1752  srcval = fetch_data_byte(srcoffset);
1753  DECODE_PRINTF("\n");
1754  TRACE_AND_STEP();
1755  *destreg = srcval;
1756  }
1757  break;
1758  case 1:
1759  if (M.x86.mode & SYSMODE_PREFIX_DATA)
1760  {
1761  u32 *destreg;
1762  u32 srcval;
1763 
1764  destreg = DECODE_RM_LONG_REGISTER(rh);
1765  DECODE_PRINTF(",");
1766  srcoffset = decode_rm01_address(rl);
1767  srcval = fetch_data_byte(srcoffset);
1768  DECODE_PRINTF("\n");
1769  TRACE_AND_STEP();
1770  *destreg = srcval;
1771  }
1772  else
1773  {
1774  u16 *destreg;
1775  u16 srcval;
1776 
1777  destreg = DECODE_RM_WORD_REGISTER(rh);
1778  DECODE_PRINTF(",");
1779  srcoffset = decode_rm01_address(rl);
1780  srcval = fetch_data_byte(srcoffset);
1781  DECODE_PRINTF("\n");
1782  TRACE_AND_STEP();
1783  *destreg = srcval;
1784  }
1785  break;
1786  case 2:
1787  if (M.x86.mode & SYSMODE_PREFIX_DATA)
1788  {
1789  u32 *destreg;
1790  u32 srcval;
1791 
1792  destreg = DECODE_RM_LONG_REGISTER(rh);
1793  DECODE_PRINTF(",");
1794  srcoffset = decode_rm10_address(rl);
1795  srcval = fetch_data_byte(srcoffset);
1796  DECODE_PRINTF("\n");
1797  TRACE_AND_STEP();
1798  *destreg = srcval;
1799  }
1800  else
1801  {
1802  u16 *destreg;
1803  u16 srcval;
1804 
1805  destreg = DECODE_RM_WORD_REGISTER(rh);
1806  DECODE_PRINTF(",");
1807  srcoffset = decode_rm10_address(rl);
1808  srcval = fetch_data_byte(srcoffset);
1809  DECODE_PRINTF("\n");
1810  TRACE_AND_STEP();
1811  *destreg = srcval;
1812  }
1813  break;
1814  case 3: /* register to register */
1815  if (M.x86.mode & SYSMODE_PREFIX_DATA)
1816  {
1817  u32 *destreg;
1818  u8 *srcreg;
1819 
1820  destreg = DECODE_RM_LONG_REGISTER(rh);
1821  DECODE_PRINTF(",");
1822  srcreg = DECODE_RM_BYTE_REGISTER(rl);
1823  DECODE_PRINTF("\n");
1824  TRACE_AND_STEP();
1825  *destreg = *srcreg;
1826  }
1827  else
1828  {
1829  u16 *destreg;
1830  u8 *srcreg;
1831 
1832  destreg = DECODE_RM_WORD_REGISTER(rh);
1833  DECODE_PRINTF(",");
1834  srcreg = DECODE_RM_BYTE_REGISTER(rl);
1835  DECODE_PRINTF("\n");
1836  TRACE_AND_STEP();
1837  *destreg = *srcreg;
1838  }
1839  break;
1840  }
1841  DECODE_CLEAR_SEGOVR();
1842  END_OF_INSTR();
1843 }
1844 
1845 /****************************************************************************
1846 REMARKS:
1847 Handles opcode 0x0f,0xb7
1848 ****************************************************************************/
1849 static void x86emuOp2_movzx_word_R_RM(u8 X86EMU_UNUSED(op2))
1850 {
1851  int mod, rl, rh;
1852  uint srcoffset;
1853  u32 *destreg;
1854  u32 srcval;
1855  u16 *srcreg;
1856 
1857  START_OF_INSTR();
1858  DECODE_PRINTF("MOVZX\t");
1859  FETCH_DECODE_MODRM(mod, rh, rl);
1860  switch (mod)
1861  {
1862  case 0:
1863  destreg = DECODE_RM_LONG_REGISTER(rh);
1864  DECODE_PRINTF(",");
1865  srcoffset = decode_rm00_address(rl);
1866  srcval = fetch_data_word(srcoffset);
1867  DECODE_PRINTF("\n");
1868  TRACE_AND_STEP();
1869  *destreg = srcval;
1870  break;
1871  case 1:
1872  destreg = DECODE_RM_LONG_REGISTER(rh);
1873  DECODE_PRINTF(",");
1874  srcoffset = decode_rm01_address(rl);
1875  srcval = fetch_data_word(srcoffset);
1876  DECODE_PRINTF("\n");
1877  TRACE_AND_STEP();
1878  *destreg = srcval;
1879  break;
1880  case 2:
1881  destreg = DECODE_RM_LONG_REGISTER(rh);
1882  DECODE_PRINTF(",");
1883  srcoffset = decode_rm10_address(rl);
1884  srcval = fetch_data_word(srcoffset);
1885  DECODE_PRINTF("\n");
1886  TRACE_AND_STEP();
1887  *destreg = srcval;
1888  break;
1889  case 3: /* register to register */
1890  destreg = DECODE_RM_LONG_REGISTER(rh);
1891  DECODE_PRINTF(",");
1892  srcreg = DECODE_RM_WORD_REGISTER(rl);
1893  DECODE_PRINTF("\n");
1894  TRACE_AND_STEP();
1895  *destreg = *srcreg;
1896  break;
1897  }
1898  DECODE_CLEAR_SEGOVR();
1899  END_OF_INSTR();
1900 }
1901 
1902 /****************************************************************************
1903 REMARKS:
1904 Handles opcode 0x0f,0xba
1905 ****************************************************************************/
1906 static void x86emuOp2_btX_I(u8 X86EMU_UNUSED(op2))
1907 {
1908  int mod, rl, rh;
1909  uint srcoffset;
1910  int bit;
1911 
1912  START_OF_INSTR();
1913  FETCH_DECODE_MODRM(mod, rh, rl);
1914  switch (rh)
1915  {
1916  case 4:
1917  DECODE_PRINTF("BT\t");
1918  break;
1919  case 5:
1920  DECODE_PRINTF("BTS\t");
1921  break;
1922  case 6:
1923  DECODE_PRINTF("BTR\t");
1924  break;
1925  case 7:
1926  DECODE_PRINTF("BTC\t");
1927  break;
1928  default:
1929  DECODE_PRINTF("ILLEGAL EXTENDED X86 OPCODE\n");
1930  TRACE_REGS();
1931  printk(
1932  "%04x:%04x: %02X%02X ILLEGAL EXTENDED X86 OPCODE EXTENSION!\n",
1933  M.x86.R_CS, M.x86.R_IP - 3, op2, (mod << 6) | (rh << 3) | rl);
1934  HALT_SYS();
1935  }
1936  switch (mod)
1937  {
1938  case 0:
1939  if (M.x86.mode & SYSMODE_PREFIX_DATA)
1940  {
1941  u32 srcval, mask;
1942  u8 shift;
1943 
1944  srcoffset = decode_rm00_address(rl);
1945  DECODE_PRINTF(",");
1946  shift = fetch_byte_imm();
1947  TRACE_AND_STEP();
1948  bit = shift & 0x1F;
1949  srcval = fetch_data_long(srcoffset);
1950  mask = (0x1 << bit);
1951  CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
1952  switch (rh)
1953  {
1954  case 5:
1955  store_data_long(srcoffset, srcval | mask);
1956  break;
1957  case 6:
1958  store_data_long(srcoffset, srcval & ~mask);
1959  break;
1960  case 7:
1961  store_data_long(srcoffset, srcval ^ mask);
1962  break;
1963  default:
1964  break;
1965  }
1966  }
1967  else
1968  {
1969  u16 srcval, mask;
1970  u8 shift;
1971 
1972  srcoffset = decode_rm00_address(rl);
1973  DECODE_PRINTF(",");
1974  shift = fetch_byte_imm();
1975  TRACE_AND_STEP();
1976  bit = shift & 0xF;
1977  srcval = fetch_data_word(srcoffset);
1978  mask = (0x1 << bit);
1979  CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
1980  switch (rh)
1981  {
1982  case 5:
1983  store_data_word(srcoffset, srcval | mask);
1984  break;
1985  case 6:
1986  store_data_word(srcoffset, srcval & ~mask);
1987  break;
1988  case 7:
1989  store_data_word(srcoffset, srcval ^ mask);
1990  break;
1991  default:
1992  break;
1993  }
1994  }
1995  break;
1996  case 1:
1997  if (M.x86.mode & SYSMODE_PREFIX_DATA)
1998  {
1999  u32 srcval, mask;
2000  u8 shift;
2001 
2002  srcoffset = decode_rm01_address(rl);
2003  DECODE_PRINTF(",");
2004  shift = fetch_byte_imm();
2005  TRACE_AND_STEP();
2006  bit = shift & 0x1F;
2007  srcval = fetch_data_long(srcoffset);
2008  mask = (0x1 << bit);
2009  CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
2010  switch (rh)
2011  {
2012  case 5:
2013  store_data_long(srcoffset, srcval | mask);
2014  break;
2015  case 6:
2016  store_data_long(srcoffset, srcval & ~mask);
2017  break;
2018  case 7:
2019  store_data_long(srcoffset, srcval ^ mask);
2020  break;
2021  default:
2022  break;
2023  }
2024  }
2025  else
2026  {
2027  u16 srcval, mask;
2028  u8 shift;
2029 
2030  srcoffset = decode_rm01_address(rl);
2031  DECODE_PRINTF(",");
2032  shift = fetch_byte_imm();
2033  TRACE_AND_STEP();
2034  bit = shift & 0xF;
2035  srcval = fetch_data_word(srcoffset);
2036  mask = (0x1 << bit);
2037  CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
2038  switch (rh)
2039  {
2040  case 5:
2041  store_data_word(srcoffset, srcval | mask);
2042  break;
2043  case 6:
2044  store_data_word(srcoffset, srcval & ~mask);
2045  break;
2046  case 7:
2047  store_data_word(srcoffset, srcval ^ mask);
2048  break;
2049  default:
2050  break;
2051  }
2052  }
2053  break;
2054  case 2:
2055  if (M.x86.mode & SYSMODE_PREFIX_DATA)
2056  {
2057  u32 srcval, mask;
2058  u8 shift;
2059 
2060  srcoffset = decode_rm10_address(rl);
2061  DECODE_PRINTF(",");
2062  shift = fetch_byte_imm();
2063  TRACE_AND_STEP();
2064  bit = shift & 0x1F;
2065  srcval = fetch_data_long(srcoffset);
2066  mask = (0x1 << bit);
2067  CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
2068  switch (rh)
2069  {
2070  case 5:
2071  store_data_long(srcoffset, srcval | mask);
2072  break;
2073  case 6:
2074  store_data_long(srcoffset, srcval & ~mask);
2075  break;
2076  case 7:
2077  store_data_long(srcoffset, srcval ^ mask);
2078  break;
2079  default:
2080  break;
2081  }
2082  }
2083  else
2084  {
2085  u16 srcval, mask;
2086  u8 shift;
2087 
2088  srcoffset = decode_rm10_address(rl);
2089  DECODE_PRINTF(",");
2090  shift = fetch_byte_imm();
2091  TRACE_AND_STEP();
2092  bit = shift & 0xF;
2093  srcval = fetch_data_word(srcoffset);
2094  mask = (0x1 << bit);
2095  CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
2096  switch (rh)
2097  {
2098  case 5:
2099  store_data_word(srcoffset, srcval | mask);
2100  break;
2101  case 6:
2102  store_data_word(srcoffset, srcval & ~mask);
2103  break;
2104  case 7:
2105  store_data_word(srcoffset, srcval ^ mask);
2106  break;
2107  default:
2108  break;
2109  }
2110  }
2111  break;
2112  case 3: /* register to register */
2113  if (M.x86.mode & SYSMODE_PREFIX_DATA)
2114  {
2115  u32 *srcreg;
2116  u32 mask;
2117  u8 shift;
2118 
2119  srcreg = DECODE_RM_LONG_REGISTER(rl);
2120  DECODE_PRINTF(",");
2121  shift = fetch_byte_imm();
2122  TRACE_AND_STEP();
2123  bit = shift & 0x1F;
2124  mask = (0x1 << bit);
2125  CONDITIONAL_SET_FLAG(*srcreg & mask, F_CF);
2126  switch (rh)
2127  {
2128  case 5:
2129  *srcreg |= mask;
2130  break;
2131  case 6:
2132  *srcreg &= ~mask;
2133  break;
2134  case 7:
2135  *srcreg ^= mask;
2136  break;
2137  default:
2138  break;
2139  }
2140  }
2141  else
2142  {
2143  u16 *srcreg;
2144  u16 mask;
2145  u8 shift;
2146 
2147  srcreg = DECODE_RM_WORD_REGISTER(rl);
2148  DECODE_PRINTF(",");
2149  shift = fetch_byte_imm();
2150  TRACE_AND_STEP();
2151  bit = shift & 0xF;
2152  mask = (0x1 << bit);
2153  CONDITIONAL_SET_FLAG(*srcreg & mask, F_CF);
2154  switch (rh)
2155  {
2156  case 5:
2157  *srcreg |= mask;
2158  break;
2159  case 6:
2160  *srcreg &= ~mask;
2161  break;
2162  case 7:
2163  *srcreg ^= mask;
2164  break;
2165  default:
2166  break;
2167  }
2168  }
2169  break;
2170  }
2171  DECODE_CLEAR_SEGOVR();
2172  END_OF_INSTR();
2173 }
2174 
2175 /****************************************************************************
2176 REMARKS:
2177 Handles opcode 0x0f,0xbb
2178 ****************************************************************************/
2179 static void x86emuOp2_btc_R(u8 X86EMU_UNUSED(op2))
2180 {
2181  int mod, rl, rh;
2182  uint srcoffset;
2183  int bit, disp;
2184 
2185  START_OF_INSTR();
2186  DECODE_PRINTF("BTC\t");
2187  FETCH_DECODE_MODRM(mod, rh, rl);
2188  switch (mod)
2189  {
2190  case 0:
2191  if (M.x86.mode & SYSMODE_PREFIX_DATA)
2192  {
2193  u32 srcval, mask;
2194  u32 *shiftreg;
2195 
2196  srcoffset = decode_rm00_address(rl);
2197  DECODE_PRINTF(",");
2198  shiftreg = DECODE_RM_LONG_REGISTER(rh);
2199  TRACE_AND_STEP();
2200  bit = *shiftreg & 0x1F;
2201  disp = (s16) *shiftreg >> 5;
2202  srcval = fetch_data_long(srcoffset + disp);
2203  mask = (0x1 << bit);
2204  CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
2205  store_data_long(srcoffset + disp, srcval ^ mask);
2206  }
2207  else
2208  {
2209  u16 srcval, mask;
2210  u16 *shiftreg;
2211 
2212  srcoffset = decode_rm00_address(rl);
2213  DECODE_PRINTF(",");
2214  shiftreg = DECODE_RM_WORD_REGISTER(rh);
2215  TRACE_AND_STEP();
2216  bit = *shiftreg & 0xF;
2217  disp = (s16) *shiftreg >> 4;
2218  srcval = fetch_data_word(srcoffset + disp);
2219  mask = (u16)(0x1 << bit);
2220  CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
2221  store_data_word(srcoffset + disp, (u16)(srcval ^ mask));
2222  }
2223  break;
2224  case 1:
2225  if (M.x86.mode & SYSMODE_PREFIX_DATA)
2226  {
2227  u32 srcval, mask;
2228  u32 *shiftreg;
2229 
2230  srcoffset = decode_rm01_address(rl);
2231  DECODE_PRINTF(",");
2232  shiftreg = DECODE_RM_LONG_REGISTER(rh);
2233  TRACE_AND_STEP();
2234  bit = *shiftreg & 0x1F;
2235  disp = (s16) *shiftreg >> 5;
2236  srcval = fetch_data_long(srcoffset + disp);
2237  mask = (0x1 << bit);
2238  CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
2239  store_data_long(srcoffset + disp, srcval ^ mask);
2240  }
2241  else
2242  {
2243  u16 srcval, mask;
2244  u16 *shiftreg;
2245 
2246  srcoffset = decode_rm01_address(rl);
2247  DECODE_PRINTF(",");
2248  shiftreg = DECODE_RM_WORD_REGISTER(rh);
2249  TRACE_AND_STEP();
2250  bit = *shiftreg & 0xF;
2251  disp = (s16) *shiftreg >> 4;
2252  srcval = fetch_data_word(srcoffset + disp);
2253  mask = (u16)(0x1 << bit);
2254  CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
2255  store_data_word(srcoffset + disp, (u16)(srcval ^ mask));
2256  }
2257  break;
2258  case 2:
2259  if (M.x86.mode & SYSMODE_PREFIX_DATA)
2260  {
2261  u32 srcval, mask;
2262  u32 *shiftreg;
2263 
2264  srcoffset = decode_rm10_address(rl);
2265  DECODE_PRINTF(",");
2266  shiftreg = DECODE_RM_LONG_REGISTER(rh);
2267  TRACE_AND_STEP();
2268  bit = *shiftreg & 0x1F;
2269  disp = (s16) *shiftreg >> 5;
2270  srcval = fetch_data_long(srcoffset + disp);
2271  mask = (0x1 << bit);
2272  CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
2273  store_data_long(srcoffset + disp, srcval ^ mask);
2274  }
2275  else
2276  {
2277  u16 srcval, mask;
2278  u16 *shiftreg;
2279 
2280  srcoffset = decode_rm10_address(rl);
2281  DECODE_PRINTF(",");
2282  shiftreg = DECODE_RM_WORD_REGISTER(rh);
2283  TRACE_AND_STEP();
2284  bit = *shiftreg & 0xF;
2285  disp = (s16) *shiftreg >> 4;
2286  srcval = fetch_data_word(srcoffset + disp);
2287  mask = (u16)(0x1 << bit);
2288  CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
2289  store_data_word(srcoffset + disp, (u16)(srcval ^ mask));
2290  }
2291  break;
2292  case 3: /* register to register */
2293  if (M.x86.mode & SYSMODE_PREFIX_DATA)
2294  {
2295  u32 *srcreg, *shiftreg;
2296  u32 mask;
2297 
2298  srcreg = DECODE_RM_LONG_REGISTER(rl);
2299  DECODE_PRINTF(",");
2300  shiftreg = DECODE_RM_LONG_REGISTER(rh);
2301  TRACE_AND_STEP();
2302  bit = *shiftreg & 0x1F;
2303  mask = (0x1 << bit);
2304  CONDITIONAL_SET_FLAG(*srcreg & mask, F_CF);
2305  *srcreg ^= mask;
2306  }
2307  else
2308  {
2309  u16 *srcreg, *shiftreg;
2310  u16 mask;
2311 
2312  srcreg = DECODE_RM_WORD_REGISTER(rl);
2313  DECODE_PRINTF(",");
2314  shiftreg = DECODE_RM_WORD_REGISTER(rh);
2315  TRACE_AND_STEP();
2316  bit = *shiftreg & 0xF;
2317  mask = (u16)(0x1 << bit);
2318  CONDITIONAL_SET_FLAG(*srcreg & mask, F_CF);
2319  *srcreg ^= mask;
2320  }
2321  break;
2322  }
2323  DECODE_CLEAR_SEGOVR();
2324  END_OF_INSTR();
2325 }
2326 
2327 /****************************************************************************
2328 REMARKS:
2329 Handles opcode 0x0f,0xbc
2330 ****************************************************************************/
2331 static void x86emuOp2_bsf(u8 X86EMU_UNUSED(op2))
2332 {
2333  int mod, rl, rh;
2334  uint srcoffset;
2335 
2336  START_OF_INSTR();
2337  DECODE_PRINTF("BSF\t");
2338  FETCH_DECODE_MODRM(mod, rh, rl);
2339  switch (mod)
2340  {
2341  case 0:
2342  if (M.x86.mode & SYSMODE_PREFIX_DATA)
2343  {
2344  u32 srcval, *dstreg;
2345 
2346  srcoffset = decode_rm00_address(rl);
2347  DECODE_PRINTF(",");
2348  dstreg = DECODE_RM_LONG_REGISTER(rh);
2349  TRACE_AND_STEP();
2350  srcval = fetch_data_long(srcoffset);
2351  CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2352  for (*dstreg = 0; *dstreg < 32; (*dstreg)++)
2353  if ((srcval >> *dstreg) & 1)
2354  break;
2355  }
2356  else
2357  {
2358  u16 srcval, *dstreg;
2359 
2360  srcoffset = decode_rm00_address(rl);
2361  DECODE_PRINTF(",");
2362  dstreg = DECODE_RM_WORD_REGISTER(rh);
2363  TRACE_AND_STEP();
2364  srcval = fetch_data_word(srcoffset);
2365  CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2366  for (*dstreg = 0; *dstreg < 16; (*dstreg)++)
2367  if ((srcval >> *dstreg) & 1)
2368  break;
2369  }
2370  break;
2371  case 1:
2372  if (M.x86.mode & SYSMODE_PREFIX_DATA)
2373  {
2374  u32 srcval, *dstreg;
2375 
2376  srcoffset = decode_rm01_address(rl);
2377  DECODE_PRINTF(",");
2378  dstreg = DECODE_RM_LONG_REGISTER(rh);
2379  TRACE_AND_STEP();
2380  srcval = fetch_data_long(srcoffset);
2381  CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2382  for (*dstreg = 0; *dstreg < 32; (*dstreg)++)
2383  if ((srcval >> *dstreg) & 1)
2384  break;
2385  }
2386  else
2387  {
2388  u16 srcval, *dstreg;
2389 
2390  srcoffset = decode_rm01_address(rl);
2391  DECODE_PRINTF(",");
2392  dstreg = DECODE_RM_WORD_REGISTER(rh);
2393  TRACE_AND_STEP();
2394  srcval = fetch_data_word(srcoffset);
2395  CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2396  for (*dstreg = 0; *dstreg < 16; (*dstreg)++)
2397  if ((srcval >> *dstreg) & 1)
2398  break;
2399  }
2400  break;
2401  case 2:
2402  if (M.x86.mode & SYSMODE_PREFIX_DATA)
2403  {
2404  u32 srcval, *dstreg;
2405 
2406  srcoffset = decode_rm10_address(rl);
2407  DECODE_PRINTF(",");
2408  dstreg = DECODE_RM_LONG_REGISTER(rh);
2409  TRACE_AND_STEP();
2410  srcval = fetch_data_long(srcoffset);
2411  CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2412  for (*dstreg = 0; *dstreg < 32; (*dstreg)++)
2413  if ((srcval >> *dstreg) & 1)
2414  break;
2415  }
2416  else
2417  {
2418  u16 srcval, *dstreg;
2419 
2420  srcoffset = decode_rm10_address(rl);
2421  DECODE_PRINTF(",");
2422  dstreg = DECODE_RM_WORD_REGISTER(rh);
2423  TRACE_AND_STEP();
2424  srcval = fetch_data_word(srcoffset);
2425  CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2426  for (*dstreg = 0; *dstreg < 16; (*dstreg)++)
2427  if ((srcval >> *dstreg) & 1)
2428  break;
2429  }
2430  break;
2431  case 3: /* register to register */
2432  if (M.x86.mode & SYSMODE_PREFIX_DATA)
2433  {
2434  u32 srcval, *dstreg;
2435 
2436  srcval = *DECODE_RM_LONG_REGISTER(rl);
2437  DECODE_PRINTF(",");
2438  dstreg = DECODE_RM_LONG_REGISTER(rh);
2439  TRACE_AND_STEP();
2440  CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2441  for (*dstreg = 0; *dstreg < 32; (*dstreg)++)
2442  if ((srcval >> *dstreg) & 1)
2443  break;
2444  }
2445  else
2446  {
2447  u16 srcval, *dstreg;
2448 
2449  srcval = *DECODE_RM_WORD_REGISTER(rl);
2450  DECODE_PRINTF(",");
2451  dstreg = DECODE_RM_WORD_REGISTER(rh);
2452  TRACE_AND_STEP();
2453  CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2454  for (*dstreg = 0; *dstreg < 16; (*dstreg)++)
2455  if ((srcval >> *dstreg) & 1)
2456  break;
2457  }
2458  break;
2459  }
2460  DECODE_CLEAR_SEGOVR();
2461  END_OF_INSTR();
2462 }
2463 
2464 /****************************************************************************
2465 REMARKS:
2466 Handles opcode 0x0f,0xbd
2467 ****************************************************************************/
2468 static void x86emuOp2_bsr(u8 X86EMU_UNUSED(op2))
2469 {
2470  int mod, rl, rh;
2471  uint srcoffset;
2472 
2473  START_OF_INSTR();
2474  DECODE_PRINTF("BSR\t");
2475  FETCH_DECODE_MODRM(mod, rh, rl);
2476  switch (mod)
2477  {
2478  case 0:
2479  if (M.x86.mode & SYSMODE_PREFIX_DATA)
2480  {
2481  u32 srcval, *dstreg;
2482 
2483  srcoffset = decode_rm00_address(rl);
2484  DECODE_PRINTF(",");
2485  dstreg = DECODE_RM_LONG_REGISTER(rh);
2486  TRACE_AND_STEP();
2487  srcval = fetch_data_long(srcoffset);
2488  CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2489  for (*dstreg = 31; *dstreg > 0; (*dstreg)--)
2490  if ((srcval >> *dstreg) & 1)
2491  break;
2492  }
2493  else
2494  {
2495  u16 srcval, *dstreg;
2496 
2497  srcoffset = decode_rm00_address(rl);
2498  DECODE_PRINTF(",");
2499  dstreg = DECODE_RM_WORD_REGISTER(rh);
2500  TRACE_AND_STEP();
2501  srcval = fetch_data_word(srcoffset);
2502  CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2503  for (*dstreg = 15; *dstreg > 0; (*dstreg)--)
2504  if ((srcval >> *dstreg) & 1)
2505  break;
2506  }
2507  break;
2508  case 1:
2509  if (M.x86.mode & SYSMODE_PREFIX_DATA)
2510  {
2511  u32 srcval, *dstreg;
2512 
2513  srcoffset = decode_rm01_address(rl);
2514  DECODE_PRINTF(",");
2515  dstreg = DECODE_RM_LONG_REGISTER(rh);
2516  TRACE_AND_STEP();
2517  srcval = fetch_data_long(srcoffset);
2518  CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2519  for (*dstreg = 31; *dstreg > 0; (*dstreg)--)
2520  if ((srcval >> *dstreg) & 1)
2521  break;
2522  }
2523  else
2524  {
2525  u16 srcval, *dstreg;
2526 
2527  srcoffset = decode_rm01_address(rl);
2528  DECODE_PRINTF(",");
2529  dstreg = DECODE_RM_WORD_REGISTER(rh);
2530  TRACE_AND_STEP();
2531  srcval = fetch_data_word(srcoffset);
2532  CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2533  for (*dstreg = 15; *dstreg > 0; (*dstreg)--)
2534  if ((srcval >> *dstreg) & 1)
2535  break;
2536  }
2537  break;
2538  case 2:
2539  if (M.x86.mode & SYSMODE_PREFIX_DATA)
2540  {
2541  u32 srcval, *dstreg;
2542 
2543  srcoffset = decode_rm10_address(rl);
2544  DECODE_PRINTF(",");
2545  dstreg = DECODE_RM_LONG_REGISTER(rh);
2546  TRACE_AND_STEP();
2547  srcval = fetch_data_long(srcoffset);
2548  CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2549  for (*dstreg = 31; *dstreg > 0; (*dstreg)--)
2550  if ((srcval >> *dstreg) & 1)
2551  break;
2552  }
2553  else
2554  {
2555  u16 srcval, *dstreg;
2556 
2557  srcoffset = decode_rm10_address(rl);
2558  DECODE_PRINTF(",");
2559  dstreg = DECODE_RM_WORD_REGISTER(rh);
2560  TRACE_AND_STEP();
2561  srcval = fetch_data_word(srcoffset);
2562  CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2563  for (*dstreg = 15; *dstreg > 0; (*dstreg)--)
2564  if ((srcval >> *dstreg) & 1)
2565  break;
2566  }
2567  break;
2568  case 3: /* register to register */
2569  if (M.x86.mode & SYSMODE_PREFIX_DATA)
2570  {
2571  u32 srcval, *dstreg;
2572 
2573  srcval = *DECODE_RM_LONG_REGISTER(rl);
2574  DECODE_PRINTF(",");
2575  dstreg = DECODE_RM_LONG_REGISTER(rh);
2576  TRACE_AND_STEP();
2577  CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2578  for (*dstreg = 31; *dstreg > 0; (*dstreg)--)
2579  if ((srcval >> *dstreg) & 1)
2580  break;
2581  }
2582  else
2583  {
2584  u16 srcval, *dstreg;
2585 
2586  srcval = *DECODE_RM_WORD_REGISTER(rl);
2587  DECODE_PRINTF(",");
2588  dstreg = DECODE_RM_WORD_REGISTER(rh);
2589  TRACE_AND_STEP();
2590  CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
2591  for (*dstreg = 15; *dstreg > 0; (*dstreg)--)
2592  if ((srcval >> *dstreg) & 1)
2593  break;
2594  }
2595  break;
2596  }
2597  DECODE_CLEAR_SEGOVR();
2598  END_OF_INSTR();
2599 }
2600 
2601 /****************************************************************************
2602 REMARKS:
2603 Handles opcode 0x0f,0xbe
2604 ****************************************************************************/
2605 static void x86emuOp2_movsx_byte_R_RM(u8 X86EMU_UNUSED(op2))
2606 {
2607  int mod, rl, rh;
2608  uint srcoffset;
2609 
2610  START_OF_INSTR();
2611  DECODE_PRINTF("MOVSX\t");
2612  FETCH_DECODE_MODRM(mod, rh, rl);
2613  switch (mod)
2614  {
2615  case 0:
2616  if (M.x86.mode & SYSMODE_PREFIX_DATA)
2617  {
2618  u32 *destreg;
2619  u32 srcval;
2620 
2621  destreg = DECODE_RM_LONG_REGISTER(rh);
2622  DECODE_PRINTF(",");
2623  srcoffset = decode_rm00_address(rl);
2624  srcval = (s32)((s8) fetch_data_byte(srcoffset));
2625  DECODE_PRINTF("\n");
2626  TRACE_AND_STEP();
2627  *destreg = srcval;
2628  }
2629  else
2630  {
2631  u16 *destreg;
2632  u16 srcval;
2633 
2634  destreg = DECODE_RM_WORD_REGISTER(rh);
2635  DECODE_PRINTF(",");
2636  srcoffset = decode_rm00_address(rl);
2637  srcval = (s16)((s8) fetch_data_byte(srcoffset));
2638  DECODE_PRINTF("\n");
2639  TRACE_AND_STEP();
2640  *destreg = srcval;
2641  }
2642  break;
2643  case 1:
2644  if (M.x86.mode & SYSMODE_PREFIX_DATA)
2645  {
2646  u32 *destreg;
2647  u32 srcval;
2648 
2649  destreg = DECODE_RM_LONG_REGISTER(rh);
2650  DECODE_PRINTF(",");
2651  srcoffset = decode_rm01_address(rl);
2652  srcval = (s32)((s8) fetch_data_byte(srcoffset));
2653  DECODE_PRINTF("\n");
2654  TRACE_AND_STEP();
2655  *destreg = srcval;
2656  }
2657  else
2658  {
2659  u16 *destreg;
2660  u16 srcval;
2661 
2662  destreg = DECODE_RM_WORD_REGISTER(rh);
2663  DECODE_PRINTF(",");
2664  srcoffset = decode_rm01_address(rl);
2665  srcval = (s16)((s8) fetch_data_byte(srcoffset));
2666  DECODE_PRINTF("\n");
2667  TRACE_AND_STEP();
2668  *destreg = srcval;
2669  }
2670  break;
2671  case 2:
2672  if (M.x86.mode & SYSMODE_PREFIX_DATA)
2673  {
2674  u32 *destreg;
2675  u32 srcval;
2676 
2677  destreg = DECODE_RM_LONG_REGISTER(rh);
2678  DECODE_PRINTF(",");
2679  srcoffset = decode_rm10_address(rl);
2680  srcval = (s32)((s8) fetch_data_byte(srcoffset));
2681  DECODE_PRINTF("\n");
2682  TRACE_AND_STEP();
2683  *destreg = srcval;
2684  }
2685  else
2686  {
2687  u16 *destreg;
2688  u16 srcval;
2689 
2690  destreg = DECODE_RM_WORD_REGISTER(rh);
2691  DECODE_PRINTF(",");
2692  srcoffset = decode_rm10_address(rl);
2693  srcval = (s16)((s8) fetch_data_byte(srcoffset));
2694  DECODE_PRINTF("\n");
2695  TRACE_AND_STEP();
2696  *destreg = srcval;
2697  }
2698  break;
2699  case 3: /* register to register */
2700  if (M.x86.mode & SYSMODE_PREFIX_DATA)
2701  {
2702  u32 *destreg;
2703  u8 *srcreg;
2704 
2705  destreg = DECODE_RM_LONG_REGISTER(rh);
2706  DECODE_PRINTF(",");
2707  srcreg = DECODE_RM_BYTE_REGISTER(rl);
2708  DECODE_PRINTF("\n");
2709  TRACE_AND_STEP();
2710  *destreg = (s32)((s8) *srcreg);
2711  }
2712  else
2713  {
2714  u16 *destreg;
2715  u8 *srcreg;
2716 
2717  destreg = DECODE_RM_WORD_REGISTER(rh);
2718  DECODE_PRINTF(",");
2719  srcreg = DECODE_RM_BYTE_REGISTER(rl);
2720  DECODE_PRINTF("\n");
2721  TRACE_AND_STEP();
2722  *destreg = (s16)((s8) *srcreg);
2723  }
2724  break;
2725  }
2726  DECODE_CLEAR_SEGOVR();
2727  END_OF_INSTR();
2728 }
2729 
2730 /****************************************************************************
2731 REMARKS:
2732 Handles opcode 0x0f,0xbf
2733 ****************************************************************************/
2734 static void x86emuOp2_movsx_word_R_RM(u8 X86EMU_UNUSED(op2))
2735 {
2736  int mod, rl, rh;
2737  uint srcoffset;
2738  u32 *destreg;
2739  u32 srcval;
2740  u16 *srcreg;
2741 
2742  START_OF_INSTR();
2743  DECODE_PRINTF("MOVSX\t");
2744  FETCH_DECODE_MODRM(mod, rh, rl);
2745  switch (mod)
2746  {
2747  case 0:
2748  destreg = DECODE_RM_LONG_REGISTER(rh);
2749  DECODE_PRINTF(",");
2750  srcoffset = decode_rm00_address(rl);
2751  srcval = (s32)((s16) fetch_data_word(srcoffset));
2752  DECODE_PRINTF("\n");
2753  TRACE_AND_STEP();
2754  *destreg = srcval;
2755  break;
2756  case 1:
2757  destreg = DECODE_RM_LONG_REGISTER(rh);
2758  DECODE_PRINTF(",");
2759  srcoffset = decode_rm01_address(rl);
2760  srcval = (s32)((s16) fetch_data_word(srcoffset));
2761  DECODE_PRINTF("\n");
2762  TRACE_AND_STEP();
2763  *destreg = srcval;
2764  break;
2765  case 2:
2766  destreg = DECODE_RM_LONG_REGISTER(rh);
2767  DECODE_PRINTF(",");
2768  srcoffset = decode_rm10_address(rl);
2769  srcval = (s32)((s16) fetch_data_word(srcoffset));
2770  DECODE_PRINTF("\n");
2771  TRACE_AND_STEP();
2772  *destreg = srcval;
2773  break;
2774  case 3: /* register to register */
2775  destreg = DECODE_RM_LONG_REGISTER(rh);
2776  DECODE_PRINTF(",");
2777  srcreg = DECODE_RM_WORD_REGISTER(rl);
2778  DECODE_PRINTF("\n");
2779  TRACE_AND_STEP();
2780  *destreg = (s32)((s16) *srcreg);
2781  break;
2782  }
2783  DECODE_CLEAR_SEGOVR();
2784  END_OF_INSTR();
2785 }
2786 
2787 /***************************************************************************
2788  * Double byte operation code table:
2789  **************************************************************************/
2790 void (*x86emu_optab2[256])(u8) = {
2791  /* 0x00 */ x86emuOp2_illegal_op, /* Group F (ring 0 PM) */
2792  /* 0x01 */ x86emuOp2_illegal_op, /* Group G (ring 0 PM) */
2793  /* 0x02 */ x86emuOp2_illegal_op, /* lar (ring 0 PM) */
2794  /* 0x03 */ x86emuOp2_illegal_op, /* lsl (ring 0 PM) */
2795  /* 0x04 */ x86emuOp2_illegal_op,
2796  /* 0x05 */ x86emuOp2_illegal_op, /* loadall (undocumented) */
2797  /* 0x06 */ x86emuOp2_illegal_op, /* clts (ring 0 PM) */
2798  /* 0x07 */ x86emuOp2_illegal_op, /* loadall (undocumented) */
2799  /* 0x08 */ x86emuOp2_illegal_op, /* invd (ring 0 PM) */
2800  /* 0x09 */ x86emuOp2_illegal_op, /* wbinvd (ring 0 PM) */
2801  /* 0x0a */ x86emuOp2_illegal_op,
2802  /* 0x0b */ x86emuOp2_illegal_op,
2803  /* 0x0c */ x86emuOp2_illegal_op,
2804  /* 0x0d */ x86emuOp2_illegal_op,
2805  /* 0x0e */ x86emuOp2_illegal_op,
2806  /* 0x0f */ x86emuOp2_illegal_op,
2807 
2808  /* 0x10 */ x86emuOp2_illegal_op,
2809  /* 0x11 */ x86emuOp2_illegal_op,
2810  /* 0x12 */ x86emuOp2_illegal_op,
2811  /* 0x13 */ x86emuOp2_illegal_op,
2812  /* 0x14 */ x86emuOp2_illegal_op,
2813  /* 0x15 */ x86emuOp2_illegal_op,
2814  /* 0x16 */ x86emuOp2_illegal_op,
2815  /* 0x17 */ x86emuOp2_illegal_op,
2816  /* 0x18 */ x86emuOp2_illegal_op,
2817  /* 0x19 */ x86emuOp2_illegal_op,
2818  /* 0x1a */ x86emuOp2_illegal_op,
2819  /* 0x1b */ x86emuOp2_illegal_op,
2820  /* 0x1c */ x86emuOp2_illegal_op,
2821  /* 0x1d */ x86emuOp2_illegal_op,
2822  /* 0x1e */ x86emuOp2_illegal_op,
2823  /* 0x1f */ x86emuOp2_illegal_op,
2824 
2825  /* 0x20 */ x86emuOp2_illegal_op, /* mov reg32,creg (ring 0 PM) */
2826  /* 0x21 */ x86emuOp2_illegal_op, /* mov reg32,dreg (ring 0 PM) */
2827  /* 0x22 */ x86emuOp2_illegal_op, /* mov creg,reg32 (ring 0 PM) */
2828  /* 0x23 */ x86emuOp2_illegal_op, /* mov dreg,reg32 (ring 0 PM) */
2829  /* 0x24 */ x86emuOp2_illegal_op, /* mov reg32,treg (ring 0 PM) */
2830  /* 0x25 */ x86emuOp2_illegal_op,
2831  /* 0x26 */ x86emuOp2_illegal_op, /* mov treg,reg32 (ring 0 PM) */
2832  /* 0x27 */ x86emuOp2_illegal_op,
2833  /* 0x28 */ x86emuOp2_illegal_op,
2834  /* 0x29 */ x86emuOp2_illegal_op,
2835  /* 0x2a */ x86emuOp2_illegal_op,
2836  /* 0x2b */ x86emuOp2_illegal_op,
2837  /* 0x2c */ x86emuOp2_illegal_op,
2838  /* 0x2d */ x86emuOp2_illegal_op,
2839  /* 0x2e */ x86emuOp2_illegal_op,
2840  /* 0x2f */ x86emuOp2_illegal_op,
2841 
2842  /* 0x30 */ x86emuOp2_illegal_op,
2843  /* 0x31 */ x86emuOp2_rdtsc,
2844  /* 0x32 */ x86emuOp2_illegal_op,
2845  /* 0x33 */ x86emuOp2_illegal_op,
2846  /* 0x34 */ x86emuOp2_illegal_op,
2847  /* 0x35 */ x86emuOp2_illegal_op,
2848  /* 0x36 */ x86emuOp2_illegal_op,
2849  /* 0x37 */ x86emuOp2_illegal_op,
2850  /* 0x38 */ x86emuOp2_illegal_op,
2851  /* 0x39 */ x86emuOp2_illegal_op,
2852  /* 0x3a */ x86emuOp2_illegal_op,
2853  /* 0x3b */ x86emuOp2_illegal_op,
2854  /* 0x3c */ x86emuOp2_illegal_op,
2855  /* 0x3d */ x86emuOp2_illegal_op,
2856  /* 0x3e */ x86emuOp2_illegal_op,
2857  /* 0x3f */ x86emuOp2_illegal_op,
2858 
2859  /* 0x40 */ x86emuOp2_illegal_op,
2860  /* 0x41 */ x86emuOp2_illegal_op,
2861  /* 0x42 */ x86emuOp2_illegal_op,
2862  /* 0x43 */ x86emuOp2_illegal_op,
2863  /* 0x44 */ x86emuOp2_illegal_op,
2864  /* 0x45 */ x86emuOp2_illegal_op,
2865  /* 0x46 */ x86emuOp2_illegal_op,
2866  /* 0x47 */ x86emuOp2_illegal_op,
2867  /* 0x48 */ x86emuOp2_illegal_op,
2868  /* 0x49 */ x86emuOp2_illegal_op,
2869  /* 0x4a */ x86emuOp2_illegal_op,
2870  /* 0x4b */ x86emuOp2_illegal_op,
2871  /* 0x4c */ x86emuOp2_illegal_op,
2872  /* 0x4d */ x86emuOp2_illegal_op,
2873  /* 0x4e */ x86emuOp2_illegal_op,
2874  /* 0x4f */ x86emuOp2_illegal_op,
2875 
2876  /* 0x50 */ x86emuOp2_illegal_op,
2877  /* 0x51 */ x86emuOp2_illegal_op,
2878  /* 0x52 */ x86emuOp2_illegal_op,
2879  /* 0x53 */ x86emuOp2_illegal_op,
2880  /* 0x54 */ x86emuOp2_illegal_op,
2881  /* 0x55 */ x86emuOp2_illegal_op,
2882  /* 0x56 */ x86emuOp2_illegal_op,
2883  /* 0x57 */ x86emuOp2_illegal_op,
2884  /* 0x58 */ x86emuOp2_illegal_op,
2885  /* 0x59 */ x86emuOp2_illegal_op,
2886  /* 0x5a */ x86emuOp2_illegal_op,
2887  /* 0x5b */ x86emuOp2_illegal_op,
2888  /* 0x5c */ x86emuOp2_illegal_op,
2889  /* 0x5d */ x86emuOp2_illegal_op,
2890  /* 0x5e */ x86emuOp2_illegal_op,
2891  /* 0x5f */ x86emuOp2_illegal_op,
2892 
2893  /* 0x60 */ x86emuOp2_illegal_op,
2894  /* 0x61 */ x86emuOp2_illegal_op,
2895  /* 0x62 */ x86emuOp2_illegal_op,
2896  /* 0x63 */ x86emuOp2_illegal_op,
2897  /* 0x64 */ x86emuOp2_illegal_op,
2898  /* 0x65 */ x86emuOp2_illegal_op,
2899  /* 0x66 */ x86emuOp2_illegal_op,
2900  /* 0x67 */ x86emuOp2_illegal_op,
2901  /* 0x68 */ x86emuOp2_illegal_op,
2902  /* 0x69 */ x86emuOp2_illegal_op,
2903  /* 0x6a */ x86emuOp2_illegal_op,
2904  /* 0x6b */ x86emuOp2_illegal_op,
2905  /* 0x6c */ x86emuOp2_illegal_op,
2906  /* 0x6d */ x86emuOp2_illegal_op,
2907  /* 0x6e */ x86emuOp2_illegal_op,
2908  /* 0x6f */ x86emuOp2_illegal_op,
2909 
2910  /* 0x70 */ x86emuOp2_illegal_op,
2911  /* 0x71 */ x86emuOp2_illegal_op,
2912  /* 0x72 */ x86emuOp2_illegal_op,
2913  /* 0x73 */ x86emuOp2_illegal_op,
2914  /* 0x74 */ x86emuOp2_illegal_op,
2915  /* 0x75 */ x86emuOp2_illegal_op,
2916  /* 0x76 */ x86emuOp2_illegal_op,
2917  /* 0x77 */ x86emuOp2_illegal_op,
2918  /* 0x78 */ x86emuOp2_illegal_op,
2919  /* 0x79 */ x86emuOp2_illegal_op,
2920  /* 0x7a */ x86emuOp2_illegal_op,
2921  /* 0x7b */ x86emuOp2_illegal_op,
2922  /* 0x7c */ x86emuOp2_illegal_op,
2923  /* 0x7d */ x86emuOp2_illegal_op,
2924  /* 0x7e */ x86emuOp2_illegal_op,
2925  /* 0x7f */ x86emuOp2_illegal_op,
2926 
2927  /* 0x80 */ x86emuOp2_long_jump,
2928  /* 0x81 */ x86emuOp2_long_jump,
2929  /* 0x82 */ x86emuOp2_long_jump,
2930  /* 0x83 */ x86emuOp2_long_jump,
2931  /* 0x84 */ x86emuOp2_long_jump,
2932  /* 0x85 */ x86emuOp2_long_jump,
2933  /* 0x86 */ x86emuOp2_long_jump,
2934  /* 0x87 */ x86emuOp2_long_jump,
2935  /* 0x88 */ x86emuOp2_long_jump,
2936  /* 0x89 */ x86emuOp2_long_jump,
2937  /* 0x8a */ x86emuOp2_long_jump,
2938  /* 0x8b */ x86emuOp2_long_jump,
2939  /* 0x8c */ x86emuOp2_long_jump,
2940  /* 0x8d */ x86emuOp2_long_jump,
2941  /* 0x8e */ x86emuOp2_long_jump,
2942  /* 0x8f */ x86emuOp2_long_jump,
2943 
2944  /* 0x90 */ x86emuOp2_set_byte,
2945  /* 0x91 */ x86emuOp2_set_byte,
2946  /* 0x92 */ x86emuOp2_set_byte,
2947  /* 0x93 */ x86emuOp2_set_byte,
2948  /* 0x94 */ x86emuOp2_set_byte,
2949  /* 0x95 */ x86emuOp2_set_byte,
2950  /* 0x96 */ x86emuOp2_set_byte,
2951  /* 0x97 */ x86emuOp2_set_byte,
2952  /* 0x98 */ x86emuOp2_set_byte,
2953  /* 0x99 */ x86emuOp2_set_byte,
2954  /* 0x9a */ x86emuOp2_set_byte,
2955  /* 0x9b */ x86emuOp2_set_byte,
2956  /* 0x9c */ x86emuOp2_set_byte,
2957  /* 0x9d */ x86emuOp2_set_byte,
2958  /* 0x9e */ x86emuOp2_set_byte,
2959  /* 0x9f */ x86emuOp2_set_byte,
2960 
2961  /* 0xa0 */ x86emuOp2_push_FS,
2962  /* 0xa1 */ x86emuOp2_pop_FS,
2963  /* 0xa2 */ x86emuOp2_illegal_op,
2964  /* 0xa3 */ x86emuOp2_bt_R,
2965  /* 0xa4 */ x86emuOp2_shld_IMM,
2966  /* 0xa5 */ x86emuOp2_shld_CL,
2967  /* 0xa6 */ x86emuOp2_illegal_op,
2968  /* 0xa7 */ x86emuOp2_illegal_op,
2969  /* 0xa8 */ x86emuOp2_push_GS,
2970  /* 0xa9 */ x86emuOp2_pop_GS,
2971  /* 0xaa */ x86emuOp2_illegal_op,
2972  /* 0xab */ x86emuOp2_bts_R,
2973  /* 0xac */ x86emuOp2_shrd_IMM,
2974  /* 0xad */ x86emuOp2_shrd_CL,
2975  /* 0xae */ x86emuOp2_illegal_op,
2976  /* 0xaf */ x86emuOp2_imul_R_RM,
2977 
2978  /* 0xb0 */ x86emuOp2_illegal_op, /* TODO: cmpxchg */
2979  /* 0xb1 */ x86emuOp2_illegal_op, /* TODO: cmpxchg */
2980  /* 0xb2 */ x86emuOp2_lss_R_IMM,
2981  /* 0xb3 */ x86emuOp2_btr_R,
2982  /* 0xb4 */ x86emuOp2_lfs_R_IMM,
2983  /* 0xb5 */ x86emuOp2_lgs_R_IMM,
2984  /* 0xb6 */ x86emuOp2_movzx_byte_R_RM,
2985  /* 0xb7 */ x86emuOp2_movzx_word_R_RM,
2986  /* 0xb8 */ x86emuOp2_illegal_op,
2987  /* 0xb9 */ x86emuOp2_illegal_op,
2988  /* 0xba */ x86emuOp2_btX_I,
2989  /* 0xbb */ x86emuOp2_btc_R,
2990  /* 0xbc */ x86emuOp2_bsf,
2991  /* 0xbd */ x86emuOp2_bsr,
2992  /* 0xbe */ x86emuOp2_movsx_byte_R_RM,
2993  /* 0xbf */ x86emuOp2_movsx_word_R_RM,
2994 
2995  /* 0xc0 */ x86emuOp2_illegal_op, /* TODO: xadd */
2996  /* 0xc1 */ x86emuOp2_illegal_op, /* TODO: xadd */
2997  /* 0xc2 */ x86emuOp2_illegal_op,
2998  /* 0xc3 */ x86emuOp2_illegal_op,
2999  /* 0xc4 */ x86emuOp2_illegal_op,
3000  /* 0xc5 */ x86emuOp2_illegal_op,
3001  /* 0xc6 */ x86emuOp2_illegal_op,
3002  /* 0xc7 */ x86emuOp2_illegal_op,
3003  /* 0xc8 */ x86emuOp2_illegal_op, /* TODO: bswap */
3004  /* 0xc9 */ x86emuOp2_illegal_op, /* TODO: bswap */
3005  /* 0xca */ x86emuOp2_illegal_op, /* TODO: bswap */
3006  /* 0xcb */ x86emuOp2_illegal_op, /* TODO: bswap */
3007  /* 0xcc */ x86emuOp2_illegal_op, /* TODO: bswap */
3008  /* 0xcd */ x86emuOp2_illegal_op, /* TODO: bswap */
3009  /* 0xce */ x86emuOp2_illegal_op, /* TODO: bswap */
3010  /* 0xcf */ x86emuOp2_illegal_op, /* TODO: bswap */
3011 
3012  /* 0xd0 */ x86emuOp2_illegal_op,
3013  /* 0xd1 */ x86emuOp2_illegal_op,
3014  /* 0xd2 */ x86emuOp2_illegal_op,
3015  /* 0xd3 */ x86emuOp2_illegal_op,
3016  /* 0xd4 */ x86emuOp2_illegal_op,
3017  /* 0xd5 */ x86emuOp2_illegal_op,
3018  /* 0xd6 */ x86emuOp2_illegal_op,
3019  /* 0xd7 */ x86emuOp2_illegal_op,
3020  /* 0xd8 */ x86emuOp2_illegal_op,
3021  /* 0xd9 */ x86emuOp2_illegal_op,
3022  /* 0xda */ x86emuOp2_illegal_op,
3023  /* 0xdb */ x86emuOp2_illegal_op,
3024  /* 0xdc */ x86emuOp2_illegal_op,
3025  /* 0xdd */ x86emuOp2_illegal_op,
3026  /* 0xde */ x86emuOp2_illegal_op,
3027  /* 0xdf */ x86emuOp2_illegal_op,
3028 
3029  /* 0xe0 */ x86emuOp2_illegal_op,
3030  /* 0xe1 */ x86emuOp2_illegal_op,
3031  /* 0xe2 */ x86emuOp2_illegal_op,
3032  /* 0xe3 */ x86emuOp2_illegal_op,
3033  /* 0xe4 */ x86emuOp2_illegal_op,
3034  /* 0xe5 */ x86emuOp2_illegal_op,
3035  /* 0xe6 */ x86emuOp2_illegal_op,
3036  /* 0xe7 */ x86emuOp2_illegal_op,
3037  /* 0xe8 */ x86emuOp2_illegal_op,
3038  /* 0xe9 */ x86emuOp2_illegal_op,
3039  /* 0xea */ x86emuOp2_illegal_op,
3040  /* 0xeb */ x86emuOp2_illegal_op,
3041  /* 0xec */ x86emuOp2_illegal_op,
3042  /* 0xed */ x86emuOp2_illegal_op,
3043  /* 0xee */ x86emuOp2_illegal_op,
3044  /* 0xef */ x86emuOp2_illegal_op,
3045 
3046  /* 0xf0 */ x86emuOp2_illegal_op,
3047  /* 0xf1 */ x86emuOp2_illegal_op,
3048  /* 0xf2 */ x86emuOp2_illegal_op,
3049  /* 0xf3 */ x86emuOp2_illegal_op,
3050  /* 0xf4 */ x86emuOp2_illegal_op,
3051  /* 0xf5 */ x86emuOp2_illegal_op,
3052  /* 0xf6 */ x86emuOp2_illegal_op,
3053  /* 0xf7 */ x86emuOp2_illegal_op,
3054  /* 0xf8 */ x86emuOp2_illegal_op,
3055  /* 0xf9 */ x86emuOp2_illegal_op,
3056  /* 0xfa */ x86emuOp2_illegal_op,
3057  /* 0xfb */ x86emuOp2_illegal_op,
3058  /* 0xfc */ x86emuOp2_illegal_op,
3059  /* 0xfd */ x86emuOp2_illegal_op,
3060  /* 0xfe */ x86emuOp2_illegal_op,
3061  /* 0xff */ x86emuOp2_illegal_op,
3062 };