]> git.ipfire.org Git - people/teissler/ipfire-2.x.git/blob - src/hwinfo/src/x86emu/ops2.c
Kleiner netter neuer Versuch.
[people/teissler/ipfire-2.x.git] / src / hwinfo / 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 /* $XFree86: xc/extras/x86emu/src/x86emu/ops2.c,v 1.6tsi Exp $ */
41
42 #include "x86emu/x86emui.h"
43
44 /*----------------------------- Implementation ----------------------------*/
45
46 /****************************************************************************
47 PARAMETERS:
48 op1 - Instruction op code
49
50 REMARKS:
51 Handles illegal opcodes.
52 ****************************************************************************/
53 static 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 /****************************************************************************
68 REMARKS:
69 Handles opcode 0x0f,0x80-0x8F
70 ****************************************************************************/
71 static 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 /****************************************************************************
160 REMARKS:
161 Handles opcode 0x0f,0x90-0x9F
162 ****************************************************************************/
163 static 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 /****************************************************************************
270 REMARKS:
271 Handles opcode 0x0f,0xa0
272 ****************************************************************************/
273 static 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 /****************************************************************************
284 REMARKS:
285 Handles opcode 0x0f,0xa1
286 ****************************************************************************/
287 static 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 /****************************************************************************
298 REMARKS:
299 Handles opcode 0x0f,0xa3
300 ****************************************************************************/
301 static 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 /****************************************************************************
419 REMARKS:
420 Handles opcode 0x0f,0xa4
421 ****************************************************************************/
422 static 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 /****************************************************************************
556 REMARKS:
557 Handles opcode 0x0f,0xa5
558 ****************************************************************************/
559 static 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 /****************************************************************************
676 REMARKS:
677 Handles opcode 0x0f,0xa8
678 ****************************************************************************/
679 static 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 /****************************************************************************
690 REMARKS:
691 Handles opcode 0x0f,0xa9
692 ****************************************************************************/
693 static 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 /****************************************************************************
705 REMARKS:
706 Handles opcode 0x0f,0xaa
707 ****************************************************************************/
708 static 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 /****************************************************************************
845 REMARKS:
846 Handles opcode 0x0f,0xac
847 ****************************************************************************/
848 static 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 /****************************************************************************
982 REMARKS:
983 Handles opcode 0x0f,0xad
984 ****************************************************************************/
985 static 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 /****************************************************************************
1102 REMARKS:
1103 Handles opcode 0x0f,0xaf
1104 ****************************************************************************/
1105 static 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 /****************************************************************************
1279 REMARKS:
1280 Handles opcode 0x0f,0xb2
1281 ****************************************************************************/
1282 static 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 /****************************************************************************
1328 REMARKS:
1329 Handles opcode 0x0f,0xb3
1330 ****************************************************************************/
1331 static 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 /****************************************************************************
1467 REMARKS:
1468 Handles opcode 0x0f,0xb4
1469 ****************************************************************************/
1470 static 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 /****************************************************************************
1516 REMARKS:
1517 Handles opcode 0x0f,0xb5
1518 ****************************************************************************/
1519 static 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 /****************************************************************************
1565 REMARKS:
1566 Handles opcode 0x0f,0xb6
1567 ****************************************************************************/
1568 static 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 /****************************************************************************
1681 REMARKS:
1682 Handles opcode 0x0f,0xb7
1683 ****************************************************************************/
1684 static 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 /****************************************************************************
1737 REMARKS:
1738 Handles opcode 0x0f,0xba
1739 ****************************************************************************/
1740 static 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 /****************************************************************************
1987 REMARKS:
1988 Handles opcode 0x0f,0xbb
1989 ****************************************************************************/
1990 static 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 /****************************************************************************
2126 REMARKS:
2127 Handles opcode 0x0f,0xbc
2128 ****************************************************************************/
2129 static 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 /****************************************************************************
2242 REMARKS:
2243 Handles opcode 0x0f,0xbd
2244 ****************************************************************************/
2245 static 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 /****************************************************************************
2358 REMARKS:
2359 Handles opcode 0x0f,0xbe
2360 ****************************************************************************/
2361 static 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 /****************************************************************************
2474 REMARKS:
2475 Handles opcode 0x0f,0xbf
2476 ****************************************************************************/
2477 static 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 **************************************************************************/
2532 void (*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 };