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