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