Print phys_base_ptr in testvbe.
[v86d.git] / libs / x86emu / ops.c
blob4f504c99d7b9204be79f9374a006cfedf35b5a60
1 /****************************************************************************
3 * Realmode X86 Emulator Library
5 * Copyright (C) 1996-1999 SciTech Software, Inc.
6 * Copyright (C) David Mosberger-Tang
7 * Copyright (C) 1999 Egbert Eich
9 * ========================================================================
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.
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.
29 * ========================================================================
31 * Language: ANSI C
32 * Environment: Any
33 * Developer: Kendall Bennett
35 * Description: This file includes subroutines to implement the decoding
36 * and emulation of all the x86 processor instructions.
38 * There are approximately 250 subroutines in here, which correspond
39 * to the 256 byte-"opcodes" found on the 8086. The table which
40 * dispatches this is found in the files optab.[ch].
42 * Each opcode proc has a comment preceeding it which gives it's table
43 * address. Several opcodes are missing (undefined) in the table.
45 * Each proc includes information for decoding (DECODE_PRINTF and
46 * DECODE_PRINTF2), debugging (TRACE_REGS, SINGLE_STEP), and misc
47 * functions (START_OF_INSTR, END_OF_INSTR).
49 * Many of the procedures are *VERY* similar in coding. This has
50 * allowed for a very large amount of code to be generated in a fairly
51 * short amount of time (i.e. cut, paste, and modify). The result is
52 * that much of the code below could have been folded into subroutines
53 * for a large reduction in size of this file. The downside would be
54 * that there would be a penalty in execution speed. The file could
55 * also have been *MUCH* larger by inlining certain functions which
56 * were called. This could have resulted even faster execution. The
57 * prime directive I used to decide whether to inline the code or to
58 * modularize it, was basically: 1) no unnecessary subroutine calls,
59 * 2) no routines more than about 200 lines in size, and 3) modularize
60 * any code that I might not get right the first time. The fetch_*
61 * subroutines fall into the latter category. The The decode_* fall
62 * into the second category. The coding of the "switch(mod){ .... }"
63 * in many of the subroutines below falls into the first category.
64 * Especially, the coding of {add,and,or,sub,...}_{byte,word}
65 * subroutines are an especially glaring case of the third guideline.
66 * Since so much of the code is cloned from other modules (compare
67 * opcode #00 to opcode #01), making the basic operations subroutine
68 * calls is especially important; otherwise mistakes in coding an
69 * "add" would represent a nightmare in maintenance.
71 ****************************************************************************/
73 #include "x86emu/x86emui.h"
75 /*----------------------------- Implementation ----------------------------*/
77 /****************************************************************************
78 PARAMETERS:
79 op1 - Instruction op code
81 REMARKS:
82 Handles illegal opcodes.
83 ****************************************************************************/
84 static void x86emuOp_illegal_op(
85 u8 op1)
87 START_OF_INSTR();
88 if (M.x86.R_SP != 0) {
89 DECODE_PRINTF("ILLEGAL X86 OPCODE\n");
90 TRACE_REGS();
91 printk("%04x:%04x: %02X ILLEGAL X86 OPCODE!\n",
92 M.x86.R_CS, M.x86.R_IP-1,op1);
93 HALT_SYS();
95 else {
96 /* If we get here, it means the stack pointer is back to zero
97 * so we are just returning from an emulator service call
98 * so therte is no need to display an error message. We trap
99 * the emulator with an 0xF1 opcode to finish the service
100 * call.
102 X86EMU_halt_sys();
104 END_OF_INSTR();
107 /****************************************************************************
108 REMARKS:
109 Handles opcode 0x00
110 ****************************************************************************/
111 static void x86emuOp_add_byte_RM_R(u8 X86EMU_UNUSED(op1))
113 int mod, rl, rh;
114 uint destoffset;
115 u8 *destreg, *srcreg;
116 u8 destval;
118 START_OF_INSTR();
119 DECODE_PRINTF("ADD\t");
120 FETCH_DECODE_MODRM(mod, rh, rl);
121 switch (mod) {
122 case 0:
123 destoffset = decode_rm00_address(rl);
124 DECODE_PRINTF(",");
125 destval = fetch_data_byte(destoffset);
126 srcreg = DECODE_RM_BYTE_REGISTER(rh);
127 DECODE_PRINTF("\n");
128 TRACE_AND_STEP();
129 destval = add_byte(destval, *srcreg);
130 store_data_byte(destoffset, destval);
131 break;
132 case 1:
133 destoffset = decode_rm01_address(rl);
134 DECODE_PRINTF(",");
135 destval = fetch_data_byte(destoffset);
136 srcreg = DECODE_RM_BYTE_REGISTER(rh);
137 DECODE_PRINTF("\n");
138 TRACE_AND_STEP();
139 destval = add_byte(destval, *srcreg);
140 store_data_byte(destoffset, destval);
141 break;
142 case 2:
143 destoffset = decode_rm10_address(rl);
144 DECODE_PRINTF(",");
145 destval = fetch_data_byte(destoffset);
146 srcreg = DECODE_RM_BYTE_REGISTER(rh);
147 DECODE_PRINTF("\n");
148 TRACE_AND_STEP();
149 destval = add_byte(destval, *srcreg);
150 store_data_byte(destoffset, destval);
151 break;
152 case 3: /* register to register */
153 destreg = DECODE_RM_BYTE_REGISTER(rl);
154 DECODE_PRINTF(",");
155 srcreg = DECODE_RM_BYTE_REGISTER(rh);
156 DECODE_PRINTF("\n");
157 TRACE_AND_STEP();
158 *destreg = add_byte(*destreg, *srcreg);
159 break;
161 DECODE_CLEAR_SEGOVR();
162 END_OF_INSTR();
165 /****************************************************************************
166 REMARKS:
167 Handles opcode 0x01
168 ****************************************************************************/
169 static void x86emuOp_add_word_RM_R(u8 X86EMU_UNUSED(op1))
171 int mod, rl, rh;
172 uint destoffset;
174 START_OF_INSTR();
175 DECODE_PRINTF("ADD\t");
176 FETCH_DECODE_MODRM(mod, rh, rl);
177 switch (mod) {
178 case 0:
179 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
180 u32 destval;
181 u32 *srcreg;
183 destoffset = decode_rm00_address(rl);
184 DECODE_PRINTF(",");
185 destval = fetch_data_long(destoffset);
186 srcreg = DECODE_RM_LONG_REGISTER(rh);
187 DECODE_PRINTF("\n");
188 TRACE_AND_STEP();
189 destval = add_long(destval, *srcreg);
190 store_data_long(destoffset, destval);
191 } else {
192 u16 destval;
193 u16 *srcreg;
195 destoffset = decode_rm00_address(rl);
196 DECODE_PRINTF(",");
197 destval = fetch_data_word(destoffset);
198 srcreg = DECODE_RM_WORD_REGISTER(rh);
199 DECODE_PRINTF("\n");
200 TRACE_AND_STEP();
201 destval = add_word(destval, *srcreg);
202 store_data_word(destoffset, destval);
204 break;
205 case 1:
206 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
207 u32 destval;
208 u32 *srcreg;
210 destoffset = decode_rm01_address(rl);
211 DECODE_PRINTF(",");
212 destval = fetch_data_long(destoffset);
213 srcreg = DECODE_RM_LONG_REGISTER(rh);
214 DECODE_PRINTF("\n");
215 TRACE_AND_STEP();
216 destval = add_long(destval, *srcreg);
217 store_data_long(destoffset, destval);
218 } else {
219 u16 destval;
220 u16 *srcreg;
222 destoffset = decode_rm01_address(rl);
223 DECODE_PRINTF(",");
224 destval = fetch_data_word(destoffset);
225 srcreg = DECODE_RM_WORD_REGISTER(rh);
226 DECODE_PRINTF("\n");
227 TRACE_AND_STEP();
228 destval = add_word(destval, *srcreg);
229 store_data_word(destoffset, destval);
231 break;
232 case 2:
233 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
234 u32 destval;
235 u32 *srcreg;
237 destoffset = decode_rm10_address(rl);
238 DECODE_PRINTF(",");
239 destval = fetch_data_long(destoffset);
240 srcreg = DECODE_RM_LONG_REGISTER(rh);
241 DECODE_PRINTF("\n");
242 TRACE_AND_STEP();
243 destval = add_long(destval, *srcreg);
244 store_data_long(destoffset, destval);
245 } else {
246 u16 destval;
247 u16 *srcreg;
249 destoffset = decode_rm10_address(rl);
250 DECODE_PRINTF(",");
251 destval = fetch_data_word(destoffset);
252 srcreg = DECODE_RM_WORD_REGISTER(rh);
253 DECODE_PRINTF("\n");
254 TRACE_AND_STEP();
255 destval = add_word(destval, *srcreg);
256 store_data_word(destoffset, destval);
258 break;
259 case 3: /* register to register */
260 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
261 u32 *destreg,*srcreg;
263 destreg = DECODE_RM_LONG_REGISTER(rl);
264 DECODE_PRINTF(",");
265 srcreg = DECODE_RM_LONG_REGISTER(rh);
266 DECODE_PRINTF("\n");
267 TRACE_AND_STEP();
268 *destreg = add_long(*destreg, *srcreg);
269 } else {
270 u16 *destreg,*srcreg;
272 destreg = DECODE_RM_WORD_REGISTER(rl);
273 DECODE_PRINTF(",");
274 srcreg = DECODE_RM_WORD_REGISTER(rh);
275 DECODE_PRINTF("\n");
276 TRACE_AND_STEP();
277 *destreg = add_word(*destreg, *srcreg);
279 break;
281 DECODE_CLEAR_SEGOVR();
282 END_OF_INSTR();
285 /****************************************************************************
286 REMARKS:
287 Handles opcode 0x02
288 ****************************************************************************/
289 static void x86emuOp_add_byte_R_RM(u8 X86EMU_UNUSED(op1))
291 int mod, rl, rh;
292 u8 *destreg, *srcreg;
293 uint srcoffset;
294 u8 srcval;
296 START_OF_INSTR();
297 DECODE_PRINTF("ADD\t");
298 FETCH_DECODE_MODRM(mod, rh, rl);
299 switch (mod) {
300 case 0:
301 destreg = DECODE_RM_BYTE_REGISTER(rh);
302 DECODE_PRINTF(",");
303 srcoffset = decode_rm00_address(rl);
304 srcval = fetch_data_byte(srcoffset);
305 DECODE_PRINTF("\n");
306 TRACE_AND_STEP();
307 *destreg = add_byte(*destreg, srcval);
308 break;
309 case 1:
310 destreg = DECODE_RM_BYTE_REGISTER(rh);
311 DECODE_PRINTF(",");
312 srcoffset = decode_rm01_address(rl);
313 srcval = fetch_data_byte(srcoffset);
314 DECODE_PRINTF("\n");
315 TRACE_AND_STEP();
316 *destreg = add_byte(*destreg, srcval);
317 break;
318 case 2:
319 destreg = DECODE_RM_BYTE_REGISTER(rh);
320 DECODE_PRINTF(",");
321 srcoffset = decode_rm10_address(rl);
322 srcval = fetch_data_byte(srcoffset);
323 DECODE_PRINTF("\n");
324 TRACE_AND_STEP();
325 *destreg = add_byte(*destreg, srcval);
326 break;
327 case 3: /* register to register */
328 destreg = DECODE_RM_BYTE_REGISTER(rh);
329 DECODE_PRINTF(",");
330 srcreg = DECODE_RM_BYTE_REGISTER(rl);
331 DECODE_PRINTF("\n");
332 TRACE_AND_STEP();
333 *destreg = add_byte(*destreg, *srcreg);
334 break;
336 DECODE_CLEAR_SEGOVR();
337 END_OF_INSTR();
340 /****************************************************************************
341 REMARKS:
342 Handles opcode 0x03
343 ****************************************************************************/
344 static void x86emuOp_add_word_R_RM(u8 X86EMU_UNUSED(op1))
346 int mod, rl, rh;
347 uint srcoffset;
349 START_OF_INSTR();
350 DECODE_PRINTF("ADD\t");
351 FETCH_DECODE_MODRM(mod, rh, rl);
352 switch (mod) {
353 case 0:
354 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
355 u32 *destreg;
356 u32 srcval;
358 destreg = DECODE_RM_LONG_REGISTER(rh);
359 DECODE_PRINTF(",");
360 srcoffset = decode_rm00_address(rl);
361 srcval = fetch_data_long(srcoffset);
362 DECODE_PRINTF("\n");
363 TRACE_AND_STEP();
364 *destreg = add_long(*destreg, srcval);
365 } else {
366 u16 *destreg;
367 u16 srcval;
369 destreg = DECODE_RM_WORD_REGISTER(rh);
370 DECODE_PRINTF(",");
371 srcoffset = decode_rm00_address(rl);
372 srcval = fetch_data_word(srcoffset);
373 DECODE_PRINTF("\n");
374 TRACE_AND_STEP();
375 *destreg = add_word(*destreg, srcval);
377 break;
378 case 1:
379 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
380 u32 *destreg;
381 u32 srcval;
383 destreg = DECODE_RM_LONG_REGISTER(rh);
384 DECODE_PRINTF(",");
385 srcoffset = decode_rm01_address(rl);
386 srcval = fetch_data_long(srcoffset);
387 DECODE_PRINTF("\n");
388 TRACE_AND_STEP();
389 *destreg = add_long(*destreg, srcval);
390 } else {
391 u16 *destreg;
392 u16 srcval;
394 destreg = DECODE_RM_WORD_REGISTER(rh);
395 DECODE_PRINTF(",");
396 srcoffset = decode_rm01_address(rl);
397 srcval = fetch_data_word(srcoffset);
398 DECODE_PRINTF("\n");
399 TRACE_AND_STEP();
400 *destreg = add_word(*destreg, srcval);
402 break;
403 case 2:
404 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
405 u32 *destreg;
406 u32 srcval;
408 destreg = DECODE_RM_LONG_REGISTER(rh);
409 DECODE_PRINTF(",");
410 srcoffset = decode_rm10_address(rl);
411 srcval = fetch_data_long(srcoffset);
412 DECODE_PRINTF("\n");
413 TRACE_AND_STEP();
414 *destreg = add_long(*destreg, srcval);
415 } else {
416 u16 *destreg;
417 u16 srcval;
419 destreg = DECODE_RM_WORD_REGISTER(rh);
420 DECODE_PRINTF(",");
421 srcoffset = decode_rm10_address(rl);
422 srcval = fetch_data_word(srcoffset);
423 DECODE_PRINTF("\n");
424 TRACE_AND_STEP();
425 *destreg = add_word(*destreg, srcval);
427 break;
428 case 3: /* register to register */
429 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
430 u32 *destreg,*srcreg;
432 destreg = DECODE_RM_LONG_REGISTER(rh);
433 DECODE_PRINTF(",");
434 srcreg = DECODE_RM_LONG_REGISTER(rl);
435 DECODE_PRINTF("\n");
436 TRACE_AND_STEP();
437 *destreg = add_long(*destreg, *srcreg);
438 } else {
439 u16 *destreg,*srcreg;
441 destreg = DECODE_RM_WORD_REGISTER(rh);
442 DECODE_PRINTF(",");
443 srcreg = DECODE_RM_WORD_REGISTER(rl);
444 DECODE_PRINTF("\n");
445 TRACE_AND_STEP();
446 *destreg = add_word(*destreg, *srcreg);
448 break;
450 DECODE_CLEAR_SEGOVR();
451 END_OF_INSTR();
454 /****************************************************************************
455 REMARKS:
456 Handles opcode 0x04
457 ****************************************************************************/
458 static void x86emuOp_add_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
460 u8 srcval;
462 START_OF_INSTR();
463 DECODE_PRINTF("ADD\tAL,");
464 srcval = fetch_byte_imm();
465 DECODE_PRINTF2("%x\n", srcval);
466 TRACE_AND_STEP();
467 M.x86.R_AL = add_byte(M.x86.R_AL, srcval);
468 DECODE_CLEAR_SEGOVR();
469 END_OF_INSTR();
472 /****************************************************************************
473 REMARKS:
474 Handles opcode 0x05
475 ****************************************************************************/
476 static void x86emuOp_add_word_AX_IMM(u8 X86EMU_UNUSED(op1))
478 u32 srcval;
480 START_OF_INSTR();
481 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
482 DECODE_PRINTF("ADD\tEAX,");
483 srcval = fetch_long_imm();
484 } else {
485 DECODE_PRINTF("ADD\tAX,");
486 srcval = fetch_word_imm();
488 DECODE_PRINTF2("%x\n", srcval);
489 TRACE_AND_STEP();
490 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
491 M.x86.R_EAX = add_long(M.x86.R_EAX, srcval);
492 } else {
493 M.x86.R_AX = add_word(M.x86.R_AX, (u16)srcval);
495 DECODE_CLEAR_SEGOVR();
496 END_OF_INSTR();
499 /****************************************************************************
500 REMARKS:
501 Handles opcode 0x06
502 ****************************************************************************/
503 static void x86emuOp_push_ES(u8 X86EMU_UNUSED(op1))
505 START_OF_INSTR();
506 DECODE_PRINTF("PUSH\tES\n");
507 TRACE_AND_STEP();
508 push_word(M.x86.R_ES);
509 DECODE_CLEAR_SEGOVR();
510 END_OF_INSTR();
513 /****************************************************************************
514 REMARKS:
515 Handles opcode 0x07
516 ****************************************************************************/
517 static void x86emuOp_pop_ES(u8 X86EMU_UNUSED(op1))
519 START_OF_INSTR();
520 DECODE_PRINTF("POP\tES\n");
521 TRACE_AND_STEP();
522 M.x86.R_ES = pop_word();
523 DECODE_CLEAR_SEGOVR();
524 END_OF_INSTR();
527 /****************************************************************************
528 REMARKS:
529 Handles opcode 0x08
530 ****************************************************************************/
531 static void x86emuOp_or_byte_RM_R(u8 X86EMU_UNUSED(op1))
533 int mod, rl, rh;
534 u8 *destreg, *srcreg;
535 uint destoffset;
536 u8 destval;
538 START_OF_INSTR();
539 DECODE_PRINTF("OR\t");
540 FETCH_DECODE_MODRM(mod, rh, rl);
541 switch (mod) {
542 case 0:
543 destoffset = decode_rm00_address(rl);
544 DECODE_PRINTF(",");
545 destval = fetch_data_byte(destoffset);
546 srcreg = DECODE_RM_BYTE_REGISTER(rh);
547 DECODE_PRINTF("\n");
548 TRACE_AND_STEP();
549 destval = or_byte(destval, *srcreg);
550 store_data_byte(destoffset, destval);
551 break;
552 case 1:
553 destoffset = decode_rm01_address(rl);
554 DECODE_PRINTF(",");
555 destval = fetch_data_byte(destoffset);
556 srcreg = DECODE_RM_BYTE_REGISTER(rh);
557 DECODE_PRINTF("\n");
558 TRACE_AND_STEP();
559 destval = or_byte(destval, *srcreg);
560 store_data_byte(destoffset, destval);
561 break;
562 case 2:
563 destoffset = decode_rm10_address(rl);
564 DECODE_PRINTF(",");
565 destval = fetch_data_byte(destoffset);
566 srcreg = DECODE_RM_BYTE_REGISTER(rh);
567 DECODE_PRINTF("\n");
568 TRACE_AND_STEP();
569 destval = or_byte(destval, *srcreg);
570 store_data_byte(destoffset, destval);
571 break;
572 case 3: /* register to register */
573 destreg = DECODE_RM_BYTE_REGISTER(rl);
574 DECODE_PRINTF(",");
575 srcreg = DECODE_RM_BYTE_REGISTER(rh);
576 DECODE_PRINTF("\n");
577 TRACE_AND_STEP();
578 *destreg = or_byte(*destreg, *srcreg);
579 break;
581 DECODE_CLEAR_SEGOVR();
582 END_OF_INSTR();
585 /****************************************************************************
586 REMARKS:
587 Handles opcode 0x09
588 ****************************************************************************/
589 static void x86emuOp_or_word_RM_R(u8 X86EMU_UNUSED(op1))
591 int mod, rl, rh;
592 uint destoffset;
594 START_OF_INSTR();
595 DECODE_PRINTF("OR\t");
596 FETCH_DECODE_MODRM(mod, rh, rl);
597 switch (mod) {
598 case 0:
599 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
600 u32 destval;
601 u32 *srcreg;
603 destoffset = decode_rm00_address(rl);
604 DECODE_PRINTF(",");
605 destval = fetch_data_long(destoffset);
606 srcreg = DECODE_RM_LONG_REGISTER(rh);
607 DECODE_PRINTF("\n");
608 TRACE_AND_STEP();
609 destval = or_long(destval, *srcreg);
610 store_data_long(destoffset, destval);
611 } else {
612 u16 destval;
613 u16 *srcreg;
615 destoffset = decode_rm00_address(rl);
616 DECODE_PRINTF(",");
617 destval = fetch_data_word(destoffset);
618 srcreg = DECODE_RM_WORD_REGISTER(rh);
619 DECODE_PRINTF("\n");
620 TRACE_AND_STEP();
621 destval = or_word(destval, *srcreg);
622 store_data_word(destoffset, destval);
624 break;
625 case 1:
626 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
627 u32 destval;
628 u32 *srcreg;
630 destoffset = decode_rm01_address(rl);
631 DECODE_PRINTF(",");
632 destval = fetch_data_long(destoffset);
633 srcreg = DECODE_RM_LONG_REGISTER(rh);
634 DECODE_PRINTF("\n");
635 TRACE_AND_STEP();
636 destval = or_long(destval, *srcreg);
637 store_data_long(destoffset, destval);
638 } else {
639 u16 destval;
640 u16 *srcreg;
642 destoffset = decode_rm01_address(rl);
643 DECODE_PRINTF(",");
644 destval = fetch_data_word(destoffset);
645 srcreg = DECODE_RM_WORD_REGISTER(rh);
646 DECODE_PRINTF("\n");
647 TRACE_AND_STEP();
648 destval = or_word(destval, *srcreg);
649 store_data_word(destoffset, destval);
651 break;
652 case 2:
653 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
654 u32 destval;
655 u32 *srcreg;
657 destoffset = decode_rm10_address(rl);
658 DECODE_PRINTF(",");
659 destval = fetch_data_long(destoffset);
660 srcreg = DECODE_RM_LONG_REGISTER(rh);
661 DECODE_PRINTF("\n");
662 TRACE_AND_STEP();
663 destval = or_long(destval, *srcreg);
664 store_data_long(destoffset, destval);
665 } else {
666 u16 destval;
667 u16 *srcreg;
669 destoffset = decode_rm10_address(rl);
670 DECODE_PRINTF(",");
671 destval = fetch_data_word(destoffset);
672 srcreg = DECODE_RM_WORD_REGISTER(rh);
673 DECODE_PRINTF("\n");
674 TRACE_AND_STEP();
675 destval = or_word(destval, *srcreg);
676 store_data_word(destoffset, destval);
678 break;
679 case 3: /* register to register */
680 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
681 u32 *destreg,*srcreg;
683 destreg = DECODE_RM_LONG_REGISTER(rl);
684 DECODE_PRINTF(",");
685 srcreg = DECODE_RM_LONG_REGISTER(rh);
686 DECODE_PRINTF("\n");
687 TRACE_AND_STEP();
688 *destreg = or_long(*destreg, *srcreg);
689 } else {
690 u16 *destreg,*srcreg;
692 destreg = DECODE_RM_WORD_REGISTER(rl);
693 DECODE_PRINTF(",");
694 srcreg = DECODE_RM_WORD_REGISTER(rh);
695 DECODE_PRINTF("\n");
696 TRACE_AND_STEP();
697 *destreg = or_word(*destreg, *srcreg);
699 break;
701 DECODE_CLEAR_SEGOVR();
702 END_OF_INSTR();
705 /****************************************************************************
706 REMARKS:
707 Handles opcode 0x0a
708 ****************************************************************************/
709 static void x86emuOp_or_byte_R_RM(u8 X86EMU_UNUSED(op1))
711 int mod, rl, rh;
712 u8 *destreg, *srcreg;
713 uint srcoffset;
714 u8 srcval;
716 START_OF_INSTR();
717 DECODE_PRINTF("OR\t");
718 FETCH_DECODE_MODRM(mod, rh, rl);
719 switch (mod) {
720 case 0:
721 destreg = DECODE_RM_BYTE_REGISTER(rh);
722 DECODE_PRINTF(",");
723 srcoffset = decode_rm00_address(rl);
724 srcval = fetch_data_byte(srcoffset);
725 DECODE_PRINTF("\n");
726 TRACE_AND_STEP();
727 *destreg = or_byte(*destreg, srcval);
728 break;
729 case 1:
730 destreg = DECODE_RM_BYTE_REGISTER(rh);
731 DECODE_PRINTF(",");
732 srcoffset = decode_rm01_address(rl);
733 srcval = fetch_data_byte(srcoffset);
734 DECODE_PRINTF("\n");
735 TRACE_AND_STEP();
736 *destreg = or_byte(*destreg, srcval);
737 break;
738 case 2:
739 destreg = DECODE_RM_BYTE_REGISTER(rh);
740 DECODE_PRINTF(",");
741 srcoffset = decode_rm10_address(rl);
742 srcval = fetch_data_byte(srcoffset);
743 DECODE_PRINTF("\n");
744 TRACE_AND_STEP();
745 *destreg = or_byte(*destreg, srcval);
746 break;
747 case 3: /* register to register */
748 destreg = DECODE_RM_BYTE_REGISTER(rh);
749 DECODE_PRINTF(",");
750 srcreg = DECODE_RM_BYTE_REGISTER(rl);
751 DECODE_PRINTF("\n");
752 TRACE_AND_STEP();
753 *destreg = or_byte(*destreg, *srcreg);
754 break;
756 DECODE_CLEAR_SEGOVR();
757 END_OF_INSTR();
760 /****************************************************************************
761 REMARKS:
762 Handles opcode 0x0b
763 ****************************************************************************/
764 static void x86emuOp_or_word_R_RM(u8 X86EMU_UNUSED(op1))
766 int mod, rl, rh;
767 uint srcoffset;
769 START_OF_INSTR();
770 DECODE_PRINTF("OR\t");
771 FETCH_DECODE_MODRM(mod, rh, rl);
772 switch (mod) {
773 case 0:
774 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
775 u32 *destreg;
776 u32 srcval;
778 destreg = DECODE_RM_LONG_REGISTER(rh);
779 DECODE_PRINTF(",");
780 srcoffset = decode_rm00_address(rl);
781 srcval = fetch_data_long(srcoffset);
782 DECODE_PRINTF("\n");
783 TRACE_AND_STEP();
784 *destreg = or_long(*destreg, srcval);
785 } else {
786 u16 *destreg;
787 u16 srcval;
789 destreg = DECODE_RM_WORD_REGISTER(rh);
790 DECODE_PRINTF(",");
791 srcoffset = decode_rm00_address(rl);
792 srcval = fetch_data_word(srcoffset);
793 DECODE_PRINTF("\n");
794 TRACE_AND_STEP();
795 *destreg = or_word(*destreg, srcval);
797 break;
798 case 1:
799 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
800 u32 *destreg;
801 u32 srcval;
803 destreg = DECODE_RM_LONG_REGISTER(rh);
804 DECODE_PRINTF(",");
805 srcoffset = decode_rm01_address(rl);
806 srcval = fetch_data_long(srcoffset);
807 DECODE_PRINTF("\n");
808 TRACE_AND_STEP();
809 *destreg = or_long(*destreg, srcval);
810 } else {
811 u16 *destreg;
812 u16 srcval;
814 destreg = DECODE_RM_WORD_REGISTER(rh);
815 DECODE_PRINTF(",");
816 srcoffset = decode_rm01_address(rl);
817 srcval = fetch_data_word(srcoffset);
818 DECODE_PRINTF("\n");
819 TRACE_AND_STEP();
820 *destreg = or_word(*destreg, srcval);
822 break;
823 case 2:
824 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
825 u32 *destreg;
826 u32 srcval;
828 destreg = DECODE_RM_LONG_REGISTER(rh);
829 DECODE_PRINTF(",");
830 srcoffset = decode_rm10_address(rl);
831 srcval = fetch_data_long(srcoffset);
832 DECODE_PRINTF("\n");
833 TRACE_AND_STEP();
834 *destreg = or_long(*destreg, srcval);
835 } else {
836 u16 *destreg;
837 u16 srcval;
839 destreg = DECODE_RM_WORD_REGISTER(rh);
840 DECODE_PRINTF(",");
841 srcoffset = decode_rm10_address(rl);
842 srcval = fetch_data_word(srcoffset);
843 DECODE_PRINTF("\n");
844 TRACE_AND_STEP();
845 *destreg = or_word(*destreg, srcval);
847 break;
848 case 3: /* register to register */
849 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
850 u32 *destreg,*srcreg;
852 destreg = DECODE_RM_LONG_REGISTER(rh);
853 DECODE_PRINTF(",");
854 srcreg = DECODE_RM_LONG_REGISTER(rl);
855 DECODE_PRINTF("\n");
856 TRACE_AND_STEP();
857 *destreg = or_long(*destreg, *srcreg);
858 } else {
859 u16 *destreg,*srcreg;
861 destreg = DECODE_RM_WORD_REGISTER(rh);
862 DECODE_PRINTF(",");
863 srcreg = DECODE_RM_WORD_REGISTER(rl);
864 DECODE_PRINTF("\n");
865 TRACE_AND_STEP();
866 *destreg = or_word(*destreg, *srcreg);
868 break;
870 DECODE_CLEAR_SEGOVR();
871 END_OF_INSTR();
874 /****************************************************************************
875 REMARKS:
876 Handles opcode 0x0c
877 ****************************************************************************/
878 static void x86emuOp_or_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
880 u8 srcval;
882 START_OF_INSTR();
883 DECODE_PRINTF("OR\tAL,");
884 srcval = fetch_byte_imm();
885 DECODE_PRINTF2("%x\n", srcval);
886 TRACE_AND_STEP();
887 M.x86.R_AL = or_byte(M.x86.R_AL, srcval);
888 DECODE_CLEAR_SEGOVR();
889 END_OF_INSTR();
892 /****************************************************************************
893 REMARKS:
894 Handles opcode 0x0d
895 ****************************************************************************/
896 static void x86emuOp_or_word_AX_IMM(u8 X86EMU_UNUSED(op1))
898 u32 srcval;
900 START_OF_INSTR();
901 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
902 DECODE_PRINTF("OR\tEAX,");
903 srcval = fetch_long_imm();
904 } else {
905 DECODE_PRINTF("OR\tAX,");
906 srcval = fetch_word_imm();
908 DECODE_PRINTF2("%x\n", srcval);
909 TRACE_AND_STEP();
910 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
911 M.x86.R_EAX = or_long(M.x86.R_EAX, srcval);
912 } else {
913 M.x86.R_AX = or_word(M.x86.R_AX, (u16)srcval);
915 DECODE_CLEAR_SEGOVR();
916 END_OF_INSTR();
919 /****************************************************************************
920 REMARKS:
921 Handles opcode 0x0e
922 ****************************************************************************/
923 static void x86emuOp_push_CS(u8 X86EMU_UNUSED(op1))
925 START_OF_INSTR();
926 DECODE_PRINTF("PUSH\tCS\n");
927 TRACE_AND_STEP();
928 push_word(M.x86.R_CS);
929 DECODE_CLEAR_SEGOVR();
930 END_OF_INSTR();
933 /****************************************************************************
934 REMARKS:
935 Handles opcode 0x0f. Escape for two-byte opcode (286 or better)
936 ****************************************************************************/
937 static void x86emuOp_two_byte(u8 X86EMU_UNUSED(op1))
939 u8 op2 = (*sys_rdb)(((u32)M.x86.R_CS << 4) + (M.x86.R_IP++));
940 INC_DECODED_INST_LEN(1);
941 (*x86emu_optab2[op2])(op2);
944 /****************************************************************************
945 REMARKS:
946 Handles opcode 0x10
947 ****************************************************************************/
948 static void x86emuOp_adc_byte_RM_R(u8 X86EMU_UNUSED(op1))
950 int mod, rl, rh;
951 u8 *destreg, *srcreg;
952 uint destoffset;
953 u8 destval;
955 START_OF_INSTR();
956 DECODE_PRINTF("ADC\t");
957 FETCH_DECODE_MODRM(mod, rh, rl);
958 switch (mod) {
959 case 0:
960 destoffset = decode_rm00_address(rl);
961 DECODE_PRINTF(",");
962 destval = fetch_data_byte(destoffset);
963 srcreg = DECODE_RM_BYTE_REGISTER(rh);
964 DECODE_PRINTF("\n");
965 TRACE_AND_STEP();
966 destval = adc_byte(destval, *srcreg);
967 store_data_byte(destoffset, destval);
968 break;
969 case 1:
970 destoffset = decode_rm01_address(rl);
971 DECODE_PRINTF(",");
972 destval = fetch_data_byte(destoffset);
973 srcreg = DECODE_RM_BYTE_REGISTER(rh);
974 DECODE_PRINTF("\n");
975 TRACE_AND_STEP();
976 destval = adc_byte(destval, *srcreg);
977 store_data_byte(destoffset, destval);
978 break;
979 case 2:
980 destoffset = decode_rm10_address(rl);
981 DECODE_PRINTF(",");
982 destval = fetch_data_byte(destoffset);
983 srcreg = DECODE_RM_BYTE_REGISTER(rh);
984 DECODE_PRINTF("\n");
985 TRACE_AND_STEP();
986 destval = adc_byte(destval, *srcreg);
987 store_data_byte(destoffset, destval);
988 break;
989 case 3: /* register to register */
990 destreg = DECODE_RM_BYTE_REGISTER(rl);
991 DECODE_PRINTF(",");
992 srcreg = DECODE_RM_BYTE_REGISTER(rh);
993 DECODE_PRINTF("\n");
994 TRACE_AND_STEP();
995 *destreg = adc_byte(*destreg, *srcreg);
996 break;
998 DECODE_CLEAR_SEGOVR();
999 END_OF_INSTR();
1002 /****************************************************************************
1003 REMARKS:
1004 Handles opcode 0x11
1005 ****************************************************************************/
1006 static void x86emuOp_adc_word_RM_R(u8 X86EMU_UNUSED(op1))
1008 int mod, rl, rh;
1009 uint destoffset;
1011 START_OF_INSTR();
1012 DECODE_PRINTF("ADC\t");
1013 FETCH_DECODE_MODRM(mod, rh, rl);
1014 switch (mod) {
1015 case 0:
1016 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1017 u32 destval;
1018 u32 *srcreg;
1020 destoffset = decode_rm00_address(rl);
1021 DECODE_PRINTF(",");
1022 destval = fetch_data_long(destoffset);
1023 srcreg = DECODE_RM_LONG_REGISTER(rh);
1024 DECODE_PRINTF("\n");
1025 TRACE_AND_STEP();
1026 destval = adc_long(destval, *srcreg);
1027 store_data_long(destoffset, destval);
1028 } else {
1029 u16 destval;
1030 u16 *srcreg;
1032 destoffset = decode_rm00_address(rl);
1033 DECODE_PRINTF(",");
1034 destval = fetch_data_word(destoffset);
1035 srcreg = DECODE_RM_WORD_REGISTER(rh);
1036 DECODE_PRINTF("\n");
1037 TRACE_AND_STEP();
1038 destval = adc_word(destval, *srcreg);
1039 store_data_word(destoffset, destval);
1041 break;
1042 case 1:
1043 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1044 u32 destval;
1045 u32 *srcreg;
1047 destoffset = decode_rm01_address(rl);
1048 DECODE_PRINTF(",");
1049 destval = fetch_data_long(destoffset);
1050 srcreg = DECODE_RM_LONG_REGISTER(rh);
1051 DECODE_PRINTF("\n");
1052 TRACE_AND_STEP();
1053 destval = adc_long(destval, *srcreg);
1054 store_data_long(destoffset, destval);
1055 } else {
1056 u16 destval;
1057 u16 *srcreg;
1059 destoffset = decode_rm01_address(rl);
1060 DECODE_PRINTF(",");
1061 destval = fetch_data_word(destoffset);
1062 srcreg = DECODE_RM_WORD_REGISTER(rh);
1063 DECODE_PRINTF("\n");
1064 TRACE_AND_STEP();
1065 destval = adc_word(destval, *srcreg);
1066 store_data_word(destoffset, destval);
1068 break;
1069 case 2:
1070 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1071 u32 destval;
1072 u32 *srcreg;
1074 destoffset = decode_rm10_address(rl);
1075 DECODE_PRINTF(",");
1076 destval = fetch_data_long(destoffset);
1077 srcreg = DECODE_RM_LONG_REGISTER(rh);
1078 DECODE_PRINTF("\n");
1079 TRACE_AND_STEP();
1080 destval = adc_long(destval, *srcreg);
1081 store_data_long(destoffset, destval);
1082 } else {
1083 u16 destval;
1084 u16 *srcreg;
1086 destoffset = decode_rm10_address(rl);
1087 DECODE_PRINTF(",");
1088 destval = fetch_data_word(destoffset);
1089 srcreg = DECODE_RM_WORD_REGISTER(rh);
1090 DECODE_PRINTF("\n");
1091 TRACE_AND_STEP();
1092 destval = adc_word(destval, *srcreg);
1093 store_data_word(destoffset, destval);
1095 break;
1096 case 3: /* register to register */
1097 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1098 u32 *destreg,*srcreg;
1100 destreg = DECODE_RM_LONG_REGISTER(rl);
1101 DECODE_PRINTF(",");
1102 srcreg = DECODE_RM_LONG_REGISTER(rh);
1103 DECODE_PRINTF("\n");
1104 TRACE_AND_STEP();
1105 *destreg = adc_long(*destreg, *srcreg);
1106 } else {
1107 u16 *destreg,*srcreg;
1109 destreg = DECODE_RM_WORD_REGISTER(rl);
1110 DECODE_PRINTF(",");
1111 srcreg = DECODE_RM_WORD_REGISTER(rh);
1112 DECODE_PRINTF("\n");
1113 TRACE_AND_STEP();
1114 *destreg = adc_word(*destreg, *srcreg);
1116 break;
1118 DECODE_CLEAR_SEGOVR();
1119 END_OF_INSTR();
1122 /****************************************************************************
1123 REMARKS:
1124 Handles opcode 0x12
1125 ****************************************************************************/
1126 static void x86emuOp_adc_byte_R_RM(u8 X86EMU_UNUSED(op1))
1128 int mod, rl, rh;
1129 u8 *destreg, *srcreg;
1130 uint srcoffset;
1131 u8 srcval;
1133 START_OF_INSTR();
1134 DECODE_PRINTF("ADC\t");
1135 FETCH_DECODE_MODRM(mod, rh, rl);
1136 switch (mod) {
1137 case 0:
1138 destreg = DECODE_RM_BYTE_REGISTER(rh);
1139 DECODE_PRINTF(",");
1140 srcoffset = decode_rm00_address(rl);
1141 srcval = fetch_data_byte(srcoffset);
1142 DECODE_PRINTF("\n");
1143 TRACE_AND_STEP();
1144 *destreg = adc_byte(*destreg, srcval);
1145 break;
1146 case 1:
1147 destreg = DECODE_RM_BYTE_REGISTER(rh);
1148 DECODE_PRINTF(",");
1149 srcoffset = decode_rm01_address(rl);
1150 srcval = fetch_data_byte(srcoffset);
1151 DECODE_PRINTF("\n");
1152 TRACE_AND_STEP();
1153 *destreg = adc_byte(*destreg, srcval);
1154 break;
1155 case 2:
1156 destreg = DECODE_RM_BYTE_REGISTER(rh);
1157 DECODE_PRINTF(",");
1158 srcoffset = decode_rm10_address(rl);
1159 srcval = fetch_data_byte(srcoffset);
1160 DECODE_PRINTF("\n");
1161 TRACE_AND_STEP();
1162 *destreg = adc_byte(*destreg, srcval);
1163 break;
1164 case 3: /* register to register */
1165 destreg = DECODE_RM_BYTE_REGISTER(rh);
1166 DECODE_PRINTF(",");
1167 srcreg = DECODE_RM_BYTE_REGISTER(rl);
1168 DECODE_PRINTF("\n");
1169 TRACE_AND_STEP();
1170 *destreg = adc_byte(*destreg, *srcreg);
1171 break;
1173 DECODE_CLEAR_SEGOVR();
1174 END_OF_INSTR();
1177 /****************************************************************************
1178 REMARKS:
1179 Handles opcode 0x13
1180 ****************************************************************************/
1181 static void x86emuOp_adc_word_R_RM(u8 X86EMU_UNUSED(op1))
1183 int mod, rl, rh;
1184 uint srcoffset;
1186 START_OF_INSTR();
1187 DECODE_PRINTF("ADC\t");
1188 FETCH_DECODE_MODRM(mod, rh, rl);
1189 switch (mod) {
1190 case 0:
1191 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1192 u32 *destreg;
1193 u32 srcval;
1195 destreg = DECODE_RM_LONG_REGISTER(rh);
1196 DECODE_PRINTF(",");
1197 srcoffset = decode_rm00_address(rl);
1198 srcval = fetch_data_long(srcoffset);
1199 DECODE_PRINTF("\n");
1200 TRACE_AND_STEP();
1201 *destreg = adc_long(*destreg, srcval);
1202 } else {
1203 u16 *destreg;
1204 u16 srcval;
1206 destreg = DECODE_RM_WORD_REGISTER(rh);
1207 DECODE_PRINTF(",");
1208 srcoffset = decode_rm00_address(rl);
1209 srcval = fetch_data_word(srcoffset);
1210 DECODE_PRINTF("\n");
1211 TRACE_AND_STEP();
1212 *destreg = adc_word(*destreg, srcval);
1214 break;
1215 case 1:
1216 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1217 u32 *destreg;
1218 u32 srcval;
1220 destreg = DECODE_RM_LONG_REGISTER(rh);
1221 DECODE_PRINTF(",");
1222 srcoffset = decode_rm01_address(rl);
1223 srcval = fetch_data_long(srcoffset);
1224 DECODE_PRINTF("\n");
1225 TRACE_AND_STEP();
1226 *destreg = adc_long(*destreg, srcval);
1227 } else {
1228 u16 *destreg;
1229 u16 srcval;
1231 destreg = DECODE_RM_WORD_REGISTER(rh);
1232 DECODE_PRINTF(",");
1233 srcoffset = decode_rm01_address(rl);
1234 srcval = fetch_data_word(srcoffset);
1235 DECODE_PRINTF("\n");
1236 TRACE_AND_STEP();
1237 *destreg = adc_word(*destreg, srcval);
1239 break;
1240 case 2:
1241 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1242 u32 *destreg;
1243 u32 srcval;
1245 destreg = DECODE_RM_LONG_REGISTER(rh);
1246 DECODE_PRINTF(",");
1247 srcoffset = decode_rm10_address(rl);
1248 srcval = fetch_data_long(srcoffset);
1249 DECODE_PRINTF("\n");
1250 TRACE_AND_STEP();
1251 *destreg = adc_long(*destreg, srcval);
1252 } else {
1253 u16 *destreg;
1254 u16 srcval;
1256 destreg = DECODE_RM_WORD_REGISTER(rh);
1257 DECODE_PRINTF(",");
1258 srcoffset = decode_rm10_address(rl);
1259 srcval = fetch_data_word(srcoffset);
1260 DECODE_PRINTF("\n");
1261 TRACE_AND_STEP();
1262 *destreg = adc_word(*destreg, srcval);
1264 break;
1265 case 3: /* register to register */
1266 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1267 u32 *destreg,*srcreg;
1269 destreg = DECODE_RM_LONG_REGISTER(rh);
1270 DECODE_PRINTF(",");
1271 srcreg = DECODE_RM_LONG_REGISTER(rl);
1272 DECODE_PRINTF("\n");
1273 TRACE_AND_STEP();
1274 *destreg = adc_long(*destreg, *srcreg);
1275 } else {
1276 u16 *destreg,*srcreg;
1278 destreg = DECODE_RM_WORD_REGISTER(rh);
1279 DECODE_PRINTF(",");
1280 srcreg = DECODE_RM_WORD_REGISTER(rl);
1281 DECODE_PRINTF("\n");
1282 TRACE_AND_STEP();
1283 *destreg = adc_word(*destreg, *srcreg);
1285 break;
1287 DECODE_CLEAR_SEGOVR();
1288 END_OF_INSTR();
1291 /****************************************************************************
1292 REMARKS:
1293 Handles opcode 0x14
1294 ****************************************************************************/
1295 static void x86emuOp_adc_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
1297 u8 srcval;
1299 START_OF_INSTR();
1300 DECODE_PRINTF("ADC\tAL,");
1301 srcval = fetch_byte_imm();
1302 DECODE_PRINTF2("%x\n", srcval);
1303 TRACE_AND_STEP();
1304 M.x86.R_AL = adc_byte(M.x86.R_AL, srcval);
1305 DECODE_CLEAR_SEGOVR();
1306 END_OF_INSTR();
1309 /****************************************************************************
1310 REMARKS:
1311 Handles opcode 0x15
1312 ****************************************************************************/
1313 static void x86emuOp_adc_word_AX_IMM(u8 X86EMU_UNUSED(op1))
1315 u32 srcval;
1317 START_OF_INSTR();
1318 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1319 DECODE_PRINTF("ADC\tEAX,");
1320 srcval = fetch_long_imm();
1321 } else {
1322 DECODE_PRINTF("ADC\tAX,");
1323 srcval = fetch_word_imm();
1325 DECODE_PRINTF2("%x\n", srcval);
1326 TRACE_AND_STEP();
1327 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1328 M.x86.R_EAX = adc_long(M.x86.R_EAX, srcval);
1329 } else {
1330 M.x86.R_AX = adc_word(M.x86.R_AX, (u16)srcval);
1332 DECODE_CLEAR_SEGOVR();
1333 END_OF_INSTR();
1336 /****************************************************************************
1337 REMARKS:
1338 Handles opcode 0x16
1339 ****************************************************************************/
1340 static void x86emuOp_push_SS(u8 X86EMU_UNUSED(op1))
1342 START_OF_INSTR();
1343 DECODE_PRINTF("PUSH\tSS\n");
1344 TRACE_AND_STEP();
1345 push_word(M.x86.R_SS);
1346 DECODE_CLEAR_SEGOVR();
1347 END_OF_INSTR();
1350 /****************************************************************************
1351 REMARKS:
1352 Handles opcode 0x17
1353 ****************************************************************************/
1354 static void x86emuOp_pop_SS(u8 X86EMU_UNUSED(op1))
1356 START_OF_INSTR();
1357 DECODE_PRINTF("POP\tSS\n");
1358 TRACE_AND_STEP();
1359 M.x86.R_SS = pop_word();
1360 DECODE_CLEAR_SEGOVR();
1361 END_OF_INSTR();
1364 /****************************************************************************
1365 REMARKS:
1366 Handles opcode 0x18
1367 ****************************************************************************/
1368 static void x86emuOp_sbb_byte_RM_R(u8 X86EMU_UNUSED(op1))
1370 int mod, rl, rh;
1371 u8 *destreg, *srcreg;
1372 uint destoffset;
1373 u8 destval;
1375 START_OF_INSTR();
1376 DECODE_PRINTF("SBB\t");
1377 FETCH_DECODE_MODRM(mod, rh, rl);
1378 switch (mod) {
1379 case 0:
1380 destoffset = decode_rm00_address(rl);
1381 DECODE_PRINTF(",");
1382 destval = fetch_data_byte(destoffset);
1383 srcreg = DECODE_RM_BYTE_REGISTER(rh);
1384 DECODE_PRINTF("\n");
1385 TRACE_AND_STEP();
1386 destval = sbb_byte(destval, *srcreg);
1387 store_data_byte(destoffset, destval);
1388 break;
1389 case 1:
1390 destoffset = decode_rm01_address(rl);
1391 DECODE_PRINTF(",");
1392 destval = fetch_data_byte(destoffset);
1393 srcreg = DECODE_RM_BYTE_REGISTER(rh);
1394 DECODE_PRINTF("\n");
1395 TRACE_AND_STEP();
1396 destval = sbb_byte(destval, *srcreg);
1397 store_data_byte(destoffset, destval);
1398 break;
1399 case 2:
1400 destoffset = decode_rm10_address(rl);
1401 DECODE_PRINTF(",");
1402 destval = fetch_data_byte(destoffset);
1403 srcreg = DECODE_RM_BYTE_REGISTER(rh);
1404 DECODE_PRINTF("\n");
1405 TRACE_AND_STEP();
1406 destval = sbb_byte(destval, *srcreg);
1407 store_data_byte(destoffset, destval);
1408 break;
1409 case 3: /* register to register */
1410 destreg = DECODE_RM_BYTE_REGISTER(rl);
1411 DECODE_PRINTF(",");
1412 srcreg = DECODE_RM_BYTE_REGISTER(rh);
1413 DECODE_PRINTF("\n");
1414 TRACE_AND_STEP();
1415 *destreg = sbb_byte(*destreg, *srcreg);
1416 break;
1418 DECODE_CLEAR_SEGOVR();
1419 END_OF_INSTR();
1422 /****************************************************************************
1423 REMARKS:
1424 Handles opcode 0x19
1425 ****************************************************************************/
1426 static void x86emuOp_sbb_word_RM_R(u8 X86EMU_UNUSED(op1))
1428 int mod, rl, rh;
1429 uint destoffset;
1431 START_OF_INSTR();
1432 DECODE_PRINTF("SBB\t");
1433 FETCH_DECODE_MODRM(mod, rh, rl);
1434 switch (mod) {
1435 case 0:
1436 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1437 u32 destval;
1438 u32 *srcreg;
1440 destoffset = decode_rm00_address(rl);
1441 DECODE_PRINTF(",");
1442 destval = fetch_data_long(destoffset);
1443 srcreg = DECODE_RM_LONG_REGISTER(rh);
1444 DECODE_PRINTF("\n");
1445 TRACE_AND_STEP();
1446 destval = sbb_long(destval, *srcreg);
1447 store_data_long(destoffset, destval);
1448 } else {
1449 u16 destval;
1450 u16 *srcreg;
1452 destoffset = decode_rm00_address(rl);
1453 DECODE_PRINTF(",");
1454 destval = fetch_data_word(destoffset);
1455 srcreg = DECODE_RM_WORD_REGISTER(rh);
1456 DECODE_PRINTF("\n");
1457 TRACE_AND_STEP();
1458 destval = sbb_word(destval, *srcreg);
1459 store_data_word(destoffset, destval);
1461 break;
1462 case 1:
1463 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1464 u32 destval;
1465 u32 *srcreg;
1467 destoffset = decode_rm01_address(rl);
1468 DECODE_PRINTF(",");
1469 destval = fetch_data_long(destoffset);
1470 srcreg = DECODE_RM_LONG_REGISTER(rh);
1471 DECODE_PRINTF("\n");
1472 TRACE_AND_STEP();
1473 destval = sbb_long(destval, *srcreg);
1474 store_data_long(destoffset, destval);
1475 } else {
1476 u16 destval;
1477 u16 *srcreg;
1479 destoffset = decode_rm01_address(rl);
1480 DECODE_PRINTF(",");
1481 destval = fetch_data_word(destoffset);
1482 srcreg = DECODE_RM_WORD_REGISTER(rh);
1483 DECODE_PRINTF("\n");
1484 TRACE_AND_STEP();
1485 destval = sbb_word(destval, *srcreg);
1486 store_data_word(destoffset, destval);
1488 break;
1489 case 2:
1490 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1491 u32 destval;
1492 u32 *srcreg;
1494 destoffset = decode_rm10_address(rl);
1495 DECODE_PRINTF(",");
1496 destval = fetch_data_long(destoffset);
1497 srcreg = DECODE_RM_LONG_REGISTER(rh);
1498 DECODE_PRINTF("\n");
1499 TRACE_AND_STEP();
1500 destval = sbb_long(destval, *srcreg);
1501 store_data_long(destoffset, destval);
1502 } else {
1503 u16 destval;
1504 u16 *srcreg;
1506 destoffset = decode_rm10_address(rl);
1507 DECODE_PRINTF(",");
1508 destval = fetch_data_word(destoffset);
1509 srcreg = DECODE_RM_WORD_REGISTER(rh);
1510 DECODE_PRINTF("\n");
1511 TRACE_AND_STEP();
1512 destval = sbb_word(destval, *srcreg);
1513 store_data_word(destoffset, destval);
1515 break;
1516 case 3: /* register to register */
1517 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1518 u32 *destreg,*srcreg;
1520 destreg = DECODE_RM_LONG_REGISTER(rl);
1521 DECODE_PRINTF(",");
1522 srcreg = DECODE_RM_LONG_REGISTER(rh);
1523 DECODE_PRINTF("\n");
1524 TRACE_AND_STEP();
1525 *destreg = sbb_long(*destreg, *srcreg);
1526 } else {
1527 u16 *destreg,*srcreg;
1529 destreg = DECODE_RM_WORD_REGISTER(rl);
1530 DECODE_PRINTF(",");
1531 srcreg = DECODE_RM_WORD_REGISTER(rh);
1532 DECODE_PRINTF("\n");
1533 TRACE_AND_STEP();
1534 *destreg = sbb_word(*destreg, *srcreg);
1536 break;
1538 DECODE_CLEAR_SEGOVR();
1539 END_OF_INSTR();
1542 /****************************************************************************
1543 REMARKS:
1544 Handles opcode 0x1a
1545 ****************************************************************************/
1546 static void x86emuOp_sbb_byte_R_RM(u8 X86EMU_UNUSED(op1))
1548 int mod, rl, rh;
1549 u8 *destreg, *srcreg;
1550 uint srcoffset;
1551 u8 srcval;
1553 START_OF_INSTR();
1554 DECODE_PRINTF("SBB\t");
1555 FETCH_DECODE_MODRM(mod, rh, rl);
1556 switch (mod) {
1557 case 0:
1558 destreg = DECODE_RM_BYTE_REGISTER(rh);
1559 DECODE_PRINTF(",");
1560 srcoffset = decode_rm00_address(rl);
1561 srcval = fetch_data_byte(srcoffset);
1562 DECODE_PRINTF("\n");
1563 TRACE_AND_STEP();
1564 *destreg = sbb_byte(*destreg, srcval);
1565 break;
1566 case 1:
1567 destreg = DECODE_RM_BYTE_REGISTER(rh);
1568 DECODE_PRINTF(",");
1569 srcoffset = decode_rm01_address(rl);
1570 srcval = fetch_data_byte(srcoffset);
1571 DECODE_PRINTF("\n");
1572 TRACE_AND_STEP();
1573 *destreg = sbb_byte(*destreg, srcval);
1574 break;
1575 case 2:
1576 destreg = DECODE_RM_BYTE_REGISTER(rh);
1577 DECODE_PRINTF(",");
1578 srcoffset = decode_rm10_address(rl);
1579 srcval = fetch_data_byte(srcoffset);
1580 DECODE_PRINTF("\n");
1581 TRACE_AND_STEP();
1582 *destreg = sbb_byte(*destreg, srcval);
1583 break;
1584 case 3: /* register to register */
1585 destreg = DECODE_RM_BYTE_REGISTER(rh);
1586 DECODE_PRINTF(",");
1587 srcreg = DECODE_RM_BYTE_REGISTER(rl);
1588 DECODE_PRINTF("\n");
1589 TRACE_AND_STEP();
1590 *destreg = sbb_byte(*destreg, *srcreg);
1591 break;
1593 DECODE_CLEAR_SEGOVR();
1594 END_OF_INSTR();
1597 /****************************************************************************
1598 REMARKS:
1599 Handles opcode 0x1b
1600 ****************************************************************************/
1601 static void x86emuOp_sbb_word_R_RM(u8 X86EMU_UNUSED(op1))
1603 int mod, rl, rh;
1604 uint srcoffset;
1606 START_OF_INSTR();
1607 DECODE_PRINTF("SBB\t");
1608 FETCH_DECODE_MODRM(mod, rh, rl);
1609 switch (mod) {
1610 case 0:
1611 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1612 u32 *destreg;
1613 u32 srcval;
1615 destreg = DECODE_RM_LONG_REGISTER(rh);
1616 DECODE_PRINTF(",");
1617 srcoffset = decode_rm00_address(rl);
1618 srcval = fetch_data_long(srcoffset);
1619 DECODE_PRINTF("\n");
1620 TRACE_AND_STEP();
1621 *destreg = sbb_long(*destreg, srcval);
1622 } else {
1623 u16 *destreg;
1624 u16 srcval;
1626 destreg = DECODE_RM_WORD_REGISTER(rh);
1627 DECODE_PRINTF(",");
1628 srcoffset = decode_rm00_address(rl);
1629 srcval = fetch_data_word(srcoffset);
1630 DECODE_PRINTF("\n");
1631 TRACE_AND_STEP();
1632 *destreg = sbb_word(*destreg, srcval);
1634 break;
1635 case 1:
1636 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1637 u32 *destreg;
1638 u32 srcval;
1640 destreg = DECODE_RM_LONG_REGISTER(rh);
1641 DECODE_PRINTF(",");
1642 srcoffset = decode_rm01_address(rl);
1643 srcval = fetch_data_long(srcoffset);
1644 DECODE_PRINTF("\n");
1645 TRACE_AND_STEP();
1646 *destreg = sbb_long(*destreg, srcval);
1647 } else {
1648 u16 *destreg;
1649 u16 srcval;
1651 destreg = DECODE_RM_WORD_REGISTER(rh);
1652 DECODE_PRINTF(",");
1653 srcoffset = decode_rm01_address(rl);
1654 srcval = fetch_data_word(srcoffset);
1655 DECODE_PRINTF("\n");
1656 TRACE_AND_STEP();
1657 *destreg = sbb_word(*destreg, srcval);
1659 break;
1660 case 2:
1661 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1662 u32 *destreg;
1663 u32 srcval;
1665 destreg = DECODE_RM_LONG_REGISTER(rh);
1666 DECODE_PRINTF(",");
1667 srcoffset = decode_rm10_address(rl);
1668 srcval = fetch_data_long(srcoffset);
1669 DECODE_PRINTF("\n");
1670 TRACE_AND_STEP();
1671 *destreg = sbb_long(*destreg, srcval);
1672 } else {
1673 u16 *destreg;
1674 u16 srcval;
1676 destreg = DECODE_RM_WORD_REGISTER(rh);
1677 DECODE_PRINTF(",");
1678 srcoffset = decode_rm10_address(rl);
1679 srcval = fetch_data_word(srcoffset);
1680 DECODE_PRINTF("\n");
1681 TRACE_AND_STEP();
1682 *destreg = sbb_word(*destreg, srcval);
1684 break;
1685 case 3: /* register to register */
1686 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1687 u32 *destreg,*srcreg;
1689 destreg = DECODE_RM_LONG_REGISTER(rh);
1690 DECODE_PRINTF(",");
1691 srcreg = DECODE_RM_LONG_REGISTER(rl);
1692 DECODE_PRINTF("\n");
1693 TRACE_AND_STEP();
1694 *destreg = sbb_long(*destreg, *srcreg);
1695 } else {
1696 u16 *destreg,*srcreg;
1698 destreg = DECODE_RM_WORD_REGISTER(rh);
1699 DECODE_PRINTF(",");
1700 srcreg = DECODE_RM_WORD_REGISTER(rl);
1701 DECODE_PRINTF("\n");
1702 TRACE_AND_STEP();
1703 *destreg = sbb_word(*destreg, *srcreg);
1705 break;
1707 DECODE_CLEAR_SEGOVR();
1708 END_OF_INSTR();
1711 /****************************************************************************
1712 REMARKS:
1713 Handles opcode 0x1c
1714 ****************************************************************************/
1715 static void x86emuOp_sbb_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
1717 u8 srcval;
1719 START_OF_INSTR();
1720 DECODE_PRINTF("SBB\tAL,");
1721 srcval = fetch_byte_imm();
1722 DECODE_PRINTF2("%x\n", srcval);
1723 TRACE_AND_STEP();
1724 M.x86.R_AL = sbb_byte(M.x86.R_AL, srcval);
1725 DECODE_CLEAR_SEGOVR();
1726 END_OF_INSTR();
1729 /****************************************************************************
1730 REMARKS:
1731 Handles opcode 0x1d
1732 ****************************************************************************/
1733 static void x86emuOp_sbb_word_AX_IMM(u8 X86EMU_UNUSED(op1))
1735 u32 srcval;
1737 START_OF_INSTR();
1738 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1739 DECODE_PRINTF("SBB\tEAX,");
1740 srcval = fetch_long_imm();
1741 } else {
1742 DECODE_PRINTF("SBB\tAX,");
1743 srcval = fetch_word_imm();
1745 DECODE_PRINTF2("%x\n", srcval);
1746 TRACE_AND_STEP();
1747 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1748 M.x86.R_EAX = sbb_long(M.x86.R_EAX, srcval);
1749 } else {
1750 M.x86.R_AX = sbb_word(M.x86.R_AX, (u16)srcval);
1752 DECODE_CLEAR_SEGOVR();
1753 END_OF_INSTR();
1756 /****************************************************************************
1757 REMARKS:
1758 Handles opcode 0x1e
1759 ****************************************************************************/
1760 static void x86emuOp_push_DS(u8 X86EMU_UNUSED(op1))
1762 START_OF_INSTR();
1763 DECODE_PRINTF("PUSH\tDS\n");
1764 TRACE_AND_STEP();
1765 push_word(M.x86.R_DS);
1766 DECODE_CLEAR_SEGOVR();
1767 END_OF_INSTR();
1770 /****************************************************************************
1771 REMARKS:
1772 Handles opcode 0x1f
1773 ****************************************************************************/
1774 static void x86emuOp_pop_DS(u8 X86EMU_UNUSED(op1))
1776 START_OF_INSTR();
1777 DECODE_PRINTF("POP\tDS\n");
1778 TRACE_AND_STEP();
1779 M.x86.R_DS = pop_word();
1780 DECODE_CLEAR_SEGOVR();
1781 END_OF_INSTR();
1784 /****************************************************************************
1785 REMARKS:
1786 Handles opcode 0x20
1787 ****************************************************************************/
1788 static void x86emuOp_and_byte_RM_R(u8 X86EMU_UNUSED(op1))
1790 int mod, rl, rh;
1791 u8 *destreg, *srcreg;
1792 uint destoffset;
1793 u8 destval;
1795 START_OF_INSTR();
1796 DECODE_PRINTF("AND\t");
1797 FETCH_DECODE_MODRM(mod, rh, rl);
1799 switch (mod) {
1800 case 0:
1801 destoffset = decode_rm00_address(rl);
1802 DECODE_PRINTF(",");
1803 destval = fetch_data_byte(destoffset);
1804 srcreg = DECODE_RM_BYTE_REGISTER(rh);
1805 DECODE_PRINTF("\n");
1806 TRACE_AND_STEP();
1807 destval = and_byte(destval, *srcreg);
1808 store_data_byte(destoffset, destval);
1809 break;
1811 case 1:
1812 destoffset = decode_rm01_address(rl);
1813 DECODE_PRINTF(",");
1814 destval = fetch_data_byte(destoffset);
1815 srcreg = DECODE_RM_BYTE_REGISTER(rh);
1816 DECODE_PRINTF("\n");
1817 TRACE_AND_STEP();
1818 destval = and_byte(destval, *srcreg);
1819 store_data_byte(destoffset, destval);
1820 break;
1822 case 2:
1823 destoffset = decode_rm10_address(rl);
1824 DECODE_PRINTF(",");
1825 destval = fetch_data_byte(destoffset);
1826 srcreg = DECODE_RM_BYTE_REGISTER(rh);
1827 DECODE_PRINTF("\n");
1828 TRACE_AND_STEP();
1829 destval = and_byte(destval, *srcreg);
1830 store_data_byte(destoffset, destval);
1831 break;
1833 case 3: /* register to register */
1834 destreg = DECODE_RM_BYTE_REGISTER(rl);
1835 DECODE_PRINTF(",");
1836 srcreg = DECODE_RM_BYTE_REGISTER(rh);
1837 DECODE_PRINTF("\n");
1838 TRACE_AND_STEP();
1839 *destreg = and_byte(*destreg, *srcreg);
1840 break;
1842 DECODE_CLEAR_SEGOVR();
1843 END_OF_INSTR();
1846 /****************************************************************************
1847 REMARKS:
1848 Handles opcode 0x21
1849 ****************************************************************************/
1850 static void x86emuOp_and_word_RM_R(u8 X86EMU_UNUSED(op1))
1852 int mod, rl, rh;
1853 uint destoffset;
1855 START_OF_INSTR();
1856 DECODE_PRINTF("AND\t");
1857 FETCH_DECODE_MODRM(mod, rh, rl);
1858 switch (mod) {
1859 case 0:
1860 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1861 u32 destval;
1862 u32 *srcreg;
1864 destoffset = decode_rm00_address(rl);
1865 DECODE_PRINTF(",");
1866 destval = fetch_data_long(destoffset);
1867 srcreg = DECODE_RM_LONG_REGISTER(rh);
1868 DECODE_PRINTF("\n");
1869 TRACE_AND_STEP();
1870 destval = and_long(destval, *srcreg);
1871 store_data_long(destoffset, destval);
1872 } else {
1873 u16 destval;
1874 u16 *srcreg;
1876 destoffset = decode_rm00_address(rl);
1877 DECODE_PRINTF(",");
1878 destval = fetch_data_word(destoffset);
1879 srcreg = DECODE_RM_WORD_REGISTER(rh);
1880 DECODE_PRINTF("\n");
1881 TRACE_AND_STEP();
1882 destval = and_word(destval, *srcreg);
1883 store_data_word(destoffset, destval);
1885 break;
1886 case 1:
1887 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1888 u32 destval;
1889 u32 *srcreg;
1891 destoffset = decode_rm01_address(rl);
1892 DECODE_PRINTF(",");
1893 destval = fetch_data_long(destoffset);
1894 srcreg = DECODE_RM_LONG_REGISTER(rh);
1895 DECODE_PRINTF("\n");
1896 TRACE_AND_STEP();
1897 destval = and_long(destval, *srcreg);
1898 store_data_long(destoffset, destval);
1899 } else {
1900 u16 destval;
1901 u16 *srcreg;
1903 destoffset = decode_rm01_address(rl);
1904 DECODE_PRINTF(",");
1905 destval = fetch_data_word(destoffset);
1906 srcreg = DECODE_RM_WORD_REGISTER(rh);
1907 DECODE_PRINTF("\n");
1908 TRACE_AND_STEP();
1909 destval = and_word(destval, *srcreg);
1910 store_data_word(destoffset, destval);
1912 break;
1913 case 2:
1914 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1915 u32 destval;
1916 u32 *srcreg;
1918 destoffset = decode_rm10_address(rl);
1919 DECODE_PRINTF(",");
1920 destval = fetch_data_long(destoffset);
1921 srcreg = DECODE_RM_LONG_REGISTER(rh);
1922 DECODE_PRINTF("\n");
1923 TRACE_AND_STEP();
1924 destval = and_long(destval, *srcreg);
1925 store_data_long(destoffset, destval);
1926 } else {
1927 u16 destval;
1928 u16 *srcreg;
1930 destoffset = decode_rm10_address(rl);
1931 DECODE_PRINTF(",");
1932 destval = fetch_data_word(destoffset);
1933 srcreg = DECODE_RM_WORD_REGISTER(rh);
1934 DECODE_PRINTF("\n");
1935 TRACE_AND_STEP();
1936 destval = and_word(destval, *srcreg);
1937 store_data_word(destoffset, destval);
1939 break;
1940 case 3: /* register to register */
1941 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1942 u32 *destreg,*srcreg;
1944 destreg = DECODE_RM_LONG_REGISTER(rl);
1945 DECODE_PRINTF(",");
1946 srcreg = DECODE_RM_LONG_REGISTER(rh);
1947 DECODE_PRINTF("\n");
1948 TRACE_AND_STEP();
1949 *destreg = and_long(*destreg, *srcreg);
1950 } else {
1951 u16 *destreg,*srcreg;
1953 destreg = DECODE_RM_WORD_REGISTER(rl);
1954 DECODE_PRINTF(",");
1955 srcreg = DECODE_RM_WORD_REGISTER(rh);
1956 DECODE_PRINTF("\n");
1957 TRACE_AND_STEP();
1958 *destreg = and_word(*destreg, *srcreg);
1960 break;
1962 DECODE_CLEAR_SEGOVR();
1963 END_OF_INSTR();
1966 /****************************************************************************
1967 REMARKS:
1968 Handles opcode 0x22
1969 ****************************************************************************/
1970 static void x86emuOp_and_byte_R_RM(u8 X86EMU_UNUSED(op1))
1972 int mod, rl, rh;
1973 u8 *destreg, *srcreg;
1974 uint srcoffset;
1975 u8 srcval;
1977 START_OF_INSTR();
1978 DECODE_PRINTF("AND\t");
1979 FETCH_DECODE_MODRM(mod, rh, rl);
1980 switch (mod) {
1981 case 0:
1982 destreg = DECODE_RM_BYTE_REGISTER(rh);
1983 DECODE_PRINTF(",");
1984 srcoffset = decode_rm00_address(rl);
1985 srcval = fetch_data_byte(srcoffset);
1986 DECODE_PRINTF("\n");
1987 TRACE_AND_STEP();
1988 *destreg = and_byte(*destreg, srcval);
1989 break;
1990 case 1:
1991 destreg = DECODE_RM_BYTE_REGISTER(rh);
1992 DECODE_PRINTF(",");
1993 srcoffset = decode_rm01_address(rl);
1994 srcval = fetch_data_byte(srcoffset);
1995 DECODE_PRINTF("\n");
1996 TRACE_AND_STEP();
1997 *destreg = and_byte(*destreg, srcval);
1998 break;
1999 case 2:
2000 destreg = DECODE_RM_BYTE_REGISTER(rh);
2001 DECODE_PRINTF(",");
2002 srcoffset = decode_rm10_address(rl);
2003 srcval = fetch_data_byte(srcoffset);
2004 DECODE_PRINTF("\n");
2005 TRACE_AND_STEP();
2006 *destreg = and_byte(*destreg, srcval);
2007 break;
2008 case 3: /* register to register */
2009 destreg = DECODE_RM_BYTE_REGISTER(rh);
2010 DECODE_PRINTF(",");
2011 srcreg = DECODE_RM_BYTE_REGISTER(rl);
2012 DECODE_PRINTF("\n");
2013 TRACE_AND_STEP();
2014 *destreg = and_byte(*destreg, *srcreg);
2015 break;
2017 DECODE_CLEAR_SEGOVR();
2018 END_OF_INSTR();
2021 /****************************************************************************
2022 REMARKS:
2023 Handles opcode 0x23
2024 ****************************************************************************/
2025 static void x86emuOp_and_word_R_RM(u8 X86EMU_UNUSED(op1))
2027 int mod, rl, rh;
2028 uint srcoffset;
2030 START_OF_INSTR();
2031 DECODE_PRINTF("AND\t");
2032 FETCH_DECODE_MODRM(mod, rh, rl);
2033 switch (mod) {
2034 case 0:
2035 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2036 u32 *destreg;
2037 u32 srcval;
2039 destreg = DECODE_RM_LONG_REGISTER(rh);
2040 DECODE_PRINTF(",");
2041 srcoffset = decode_rm00_address(rl);
2042 srcval = fetch_data_long(srcoffset);
2043 DECODE_PRINTF("\n");
2044 TRACE_AND_STEP();
2045 *destreg = and_long(*destreg, srcval);
2046 } else {
2047 u16 *destreg;
2048 u16 srcval;
2050 destreg = DECODE_RM_WORD_REGISTER(rh);
2051 DECODE_PRINTF(",");
2052 srcoffset = decode_rm00_address(rl);
2053 srcval = fetch_data_word(srcoffset);
2054 DECODE_PRINTF("\n");
2055 TRACE_AND_STEP();
2056 *destreg = and_word(*destreg, srcval);
2058 break;
2059 case 1:
2060 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2061 u32 *destreg;
2062 u32 srcval;
2064 destreg = DECODE_RM_LONG_REGISTER(rh);
2065 DECODE_PRINTF(",");
2066 srcoffset = decode_rm01_address(rl);
2067 srcval = fetch_data_long(srcoffset);
2068 DECODE_PRINTF("\n");
2069 TRACE_AND_STEP();
2070 *destreg = and_long(*destreg, srcval);
2071 break;
2072 } else {
2073 u16 *destreg;
2074 u16 srcval;
2076 destreg = DECODE_RM_WORD_REGISTER(rh);
2077 DECODE_PRINTF(",");
2078 srcoffset = decode_rm01_address(rl);
2079 srcval = fetch_data_word(srcoffset);
2080 DECODE_PRINTF("\n");
2081 TRACE_AND_STEP();
2082 *destreg = and_word(*destreg, srcval);
2083 break;
2085 case 2:
2086 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2087 u32 *destreg;
2088 u32 srcval;
2090 destreg = DECODE_RM_LONG_REGISTER(rh);
2091 DECODE_PRINTF(",");
2092 srcoffset = decode_rm10_address(rl);
2093 srcval = fetch_data_long(srcoffset);
2094 DECODE_PRINTF("\n");
2095 TRACE_AND_STEP();
2096 *destreg = and_long(*destreg, srcval);
2097 } else {
2098 u16 *destreg;
2099 u16 srcval;
2101 destreg = DECODE_RM_WORD_REGISTER(rh);
2102 DECODE_PRINTF(",");
2103 srcoffset = decode_rm10_address(rl);
2104 srcval = fetch_data_word(srcoffset);
2105 DECODE_PRINTF("\n");
2106 TRACE_AND_STEP();
2107 *destreg = and_word(*destreg, srcval);
2109 break;
2110 case 3: /* register to register */
2111 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2112 u32 *destreg,*srcreg;
2114 destreg = DECODE_RM_LONG_REGISTER(rh);
2115 DECODE_PRINTF(",");
2116 srcreg = DECODE_RM_LONG_REGISTER(rl);
2117 DECODE_PRINTF("\n");
2118 TRACE_AND_STEP();
2119 *destreg = and_long(*destreg, *srcreg);
2120 } else {
2121 u16 *destreg,*srcreg;
2123 destreg = DECODE_RM_WORD_REGISTER(rh);
2124 DECODE_PRINTF(",");
2125 srcreg = DECODE_RM_WORD_REGISTER(rl);
2126 DECODE_PRINTF("\n");
2127 TRACE_AND_STEP();
2128 *destreg = and_word(*destreg, *srcreg);
2130 break;
2132 DECODE_CLEAR_SEGOVR();
2133 END_OF_INSTR();
2136 /****************************************************************************
2137 REMARKS:
2138 Handles opcode 0x24
2139 ****************************************************************************/
2140 static void x86emuOp_and_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
2142 u8 srcval;
2144 START_OF_INSTR();
2145 DECODE_PRINTF("AND\tAL,");
2146 srcval = fetch_byte_imm();
2147 DECODE_PRINTF2("%x\n", srcval);
2148 TRACE_AND_STEP();
2149 M.x86.R_AL = and_byte(M.x86.R_AL, srcval);
2150 DECODE_CLEAR_SEGOVR();
2151 END_OF_INSTR();
2154 /****************************************************************************
2155 REMARKS:
2156 Handles opcode 0x25
2157 ****************************************************************************/
2158 static void x86emuOp_and_word_AX_IMM(u8 X86EMU_UNUSED(op1))
2160 u32 srcval;
2162 START_OF_INSTR();
2163 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2164 DECODE_PRINTF("AND\tEAX,");
2165 srcval = fetch_long_imm();
2166 } else {
2167 DECODE_PRINTF("AND\tAX,");
2168 srcval = fetch_word_imm();
2170 DECODE_PRINTF2("%x\n", srcval);
2171 TRACE_AND_STEP();
2172 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2173 M.x86.R_EAX = and_long(M.x86.R_EAX, srcval);
2174 } else {
2175 M.x86.R_AX = and_word(M.x86.R_AX, (u16)srcval);
2177 DECODE_CLEAR_SEGOVR();
2178 END_OF_INSTR();
2181 /****************************************************************************
2182 REMARKS:
2183 Handles opcode 0x26
2184 ****************************************************************************/
2185 static void x86emuOp_segovr_ES(u8 X86EMU_UNUSED(op1))
2187 START_OF_INSTR();
2188 DECODE_PRINTF("ES:\n");
2189 TRACE_AND_STEP();
2190 M.x86.mode |= SYSMODE_SEGOVR_ES;
2192 * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
2193 * opcode subroutines we do not want to do this.
2195 END_OF_INSTR();
2198 /****************************************************************************
2199 REMARKS:
2200 Handles opcode 0x27
2201 ****************************************************************************/
2202 static void x86emuOp_daa(u8 X86EMU_UNUSED(op1))
2204 START_OF_INSTR();
2205 DECODE_PRINTF("DAA\n");
2206 TRACE_AND_STEP();
2207 M.x86.R_AL = daa_byte(M.x86.R_AL);
2208 DECODE_CLEAR_SEGOVR();
2209 END_OF_INSTR();
2212 /****************************************************************************
2213 REMARKS:
2214 Handles opcode 0x28
2215 ****************************************************************************/
2216 static void x86emuOp_sub_byte_RM_R(u8 X86EMU_UNUSED(op1))
2218 int mod, rl, rh;
2219 u8 *destreg, *srcreg;
2220 uint destoffset;
2221 u8 destval;
2223 START_OF_INSTR();
2224 DECODE_PRINTF("SUB\t");
2225 FETCH_DECODE_MODRM(mod, rh, rl);
2226 switch (mod) {
2227 case 0:
2228 destoffset = decode_rm00_address(rl);
2229 DECODE_PRINTF(",");
2230 destval = fetch_data_byte(destoffset);
2231 srcreg = DECODE_RM_BYTE_REGISTER(rh);
2232 DECODE_PRINTF("\n");
2233 TRACE_AND_STEP();
2234 destval = sub_byte(destval, *srcreg);
2235 store_data_byte(destoffset, destval);
2236 break;
2237 case 1:
2238 destoffset = decode_rm01_address(rl);
2239 DECODE_PRINTF(",");
2240 destval = fetch_data_byte(destoffset);
2241 srcreg = DECODE_RM_BYTE_REGISTER(rh);
2242 DECODE_PRINTF("\n");
2243 TRACE_AND_STEP();
2244 destval = sub_byte(destval, *srcreg);
2245 store_data_byte(destoffset, destval);
2246 break;
2247 case 2:
2248 destoffset = decode_rm10_address(rl);
2249 DECODE_PRINTF(",");
2250 destval = fetch_data_byte(destoffset);
2251 srcreg = DECODE_RM_BYTE_REGISTER(rh);
2252 DECODE_PRINTF("\n");
2253 TRACE_AND_STEP();
2254 destval = sub_byte(destval, *srcreg);
2255 store_data_byte(destoffset, destval);
2256 break;
2257 case 3: /* register to register */
2258 destreg = DECODE_RM_BYTE_REGISTER(rl);
2259 DECODE_PRINTF(",");
2260 srcreg = DECODE_RM_BYTE_REGISTER(rh);
2261 DECODE_PRINTF("\n");
2262 TRACE_AND_STEP();
2263 *destreg = sub_byte(*destreg, *srcreg);
2264 break;
2266 DECODE_CLEAR_SEGOVR();
2267 END_OF_INSTR();
2270 /****************************************************************************
2271 REMARKS:
2272 Handles opcode 0x29
2273 ****************************************************************************/
2274 static void x86emuOp_sub_word_RM_R(u8 X86EMU_UNUSED(op1))
2276 int mod, rl, rh;
2277 uint destoffset;
2279 START_OF_INSTR();
2280 DECODE_PRINTF("SUB\t");
2281 FETCH_DECODE_MODRM(mod, rh, rl);
2282 switch (mod) {
2283 case 0:
2284 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2285 u32 destval;
2286 u32 *srcreg;
2288 destoffset = decode_rm00_address(rl);
2289 DECODE_PRINTF(",");
2290 destval = fetch_data_long(destoffset);
2291 srcreg = DECODE_RM_LONG_REGISTER(rh);
2292 DECODE_PRINTF("\n");
2293 TRACE_AND_STEP();
2294 destval = sub_long(destval, *srcreg);
2295 store_data_long(destoffset, destval);
2296 } else {
2297 u16 destval;
2298 u16 *srcreg;
2300 destoffset = decode_rm00_address(rl);
2301 DECODE_PRINTF(",");
2302 destval = fetch_data_word(destoffset);
2303 srcreg = DECODE_RM_WORD_REGISTER(rh);
2304 DECODE_PRINTF("\n");
2305 TRACE_AND_STEP();
2306 destval = sub_word(destval, *srcreg);
2307 store_data_word(destoffset, destval);
2309 break;
2310 case 1:
2311 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2312 u32 destval;
2313 u32 *srcreg;
2315 destoffset = decode_rm01_address(rl);
2316 DECODE_PRINTF(",");
2317 destval = fetch_data_long(destoffset);
2318 srcreg = DECODE_RM_LONG_REGISTER(rh);
2319 DECODE_PRINTF("\n");
2320 TRACE_AND_STEP();
2321 destval = sub_long(destval, *srcreg);
2322 store_data_long(destoffset, destval);
2323 } else {
2324 u16 destval;
2325 u16 *srcreg;
2327 destoffset = decode_rm01_address(rl);
2328 DECODE_PRINTF(",");
2329 destval = fetch_data_word(destoffset);
2330 srcreg = DECODE_RM_WORD_REGISTER(rh);
2331 DECODE_PRINTF("\n");
2332 TRACE_AND_STEP();
2333 destval = sub_word(destval, *srcreg);
2334 store_data_word(destoffset, destval);
2336 break;
2337 case 2:
2338 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2339 u32 destval;
2340 u32 *srcreg;
2342 destoffset = decode_rm10_address(rl);
2343 DECODE_PRINTF(",");
2344 destval = fetch_data_long(destoffset);
2345 srcreg = DECODE_RM_LONG_REGISTER(rh);
2346 DECODE_PRINTF("\n");
2347 TRACE_AND_STEP();
2348 destval = sub_long(destval, *srcreg);
2349 store_data_long(destoffset, destval);
2350 } else {
2351 u16 destval;
2352 u16 *srcreg;
2354 destoffset = decode_rm10_address(rl);
2355 DECODE_PRINTF(",");
2356 destval = fetch_data_word(destoffset);
2357 srcreg = DECODE_RM_WORD_REGISTER(rh);
2358 DECODE_PRINTF("\n");
2359 TRACE_AND_STEP();
2360 destval = sub_word(destval, *srcreg);
2361 store_data_word(destoffset, destval);
2363 break;
2364 case 3: /* register to register */
2365 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2366 u32 *destreg,*srcreg;
2368 destreg = DECODE_RM_LONG_REGISTER(rl);
2369 DECODE_PRINTF(",");
2370 srcreg = DECODE_RM_LONG_REGISTER(rh);
2371 DECODE_PRINTF("\n");
2372 TRACE_AND_STEP();
2373 *destreg = sub_long(*destreg, *srcreg);
2374 } else {
2375 u16 *destreg,*srcreg;
2377 destreg = DECODE_RM_WORD_REGISTER(rl);
2378 DECODE_PRINTF(",");
2379 srcreg = DECODE_RM_WORD_REGISTER(rh);
2380 DECODE_PRINTF("\n");
2381 TRACE_AND_STEP();
2382 *destreg = sub_word(*destreg, *srcreg);
2384 break;
2386 DECODE_CLEAR_SEGOVR();
2387 END_OF_INSTR();
2390 /****************************************************************************
2391 REMARKS:
2392 Handles opcode 0x2a
2393 ****************************************************************************/
2394 static void x86emuOp_sub_byte_R_RM(u8 X86EMU_UNUSED(op1))
2396 int mod, rl, rh;
2397 u8 *destreg, *srcreg;
2398 uint srcoffset;
2399 u8 srcval;
2401 START_OF_INSTR();
2402 DECODE_PRINTF("SUB\t");
2403 FETCH_DECODE_MODRM(mod, rh, rl);
2404 switch (mod) {
2405 case 0:
2406 destreg = DECODE_RM_BYTE_REGISTER(rh);
2407 DECODE_PRINTF(",");
2408 srcoffset = decode_rm00_address(rl);
2409 srcval = fetch_data_byte(srcoffset);
2410 DECODE_PRINTF("\n");
2411 TRACE_AND_STEP();
2412 *destreg = sub_byte(*destreg, srcval);
2413 break;
2414 case 1:
2415 destreg = DECODE_RM_BYTE_REGISTER(rh);
2416 DECODE_PRINTF(",");
2417 srcoffset = decode_rm01_address(rl);
2418 srcval = fetch_data_byte(srcoffset);
2419 DECODE_PRINTF("\n");
2420 TRACE_AND_STEP();
2421 *destreg = sub_byte(*destreg, srcval);
2422 break;
2423 case 2:
2424 destreg = DECODE_RM_BYTE_REGISTER(rh);
2425 DECODE_PRINTF(",");
2426 srcoffset = decode_rm10_address(rl);
2427 srcval = fetch_data_byte(srcoffset);
2428 DECODE_PRINTF("\n");
2429 TRACE_AND_STEP();
2430 *destreg = sub_byte(*destreg, srcval);
2431 break;
2432 case 3: /* register to register */
2433 destreg = DECODE_RM_BYTE_REGISTER(rh);
2434 DECODE_PRINTF(",");
2435 srcreg = DECODE_RM_BYTE_REGISTER(rl);
2436 DECODE_PRINTF("\n");
2437 TRACE_AND_STEP();
2438 *destreg = sub_byte(*destreg, *srcreg);
2439 break;
2441 DECODE_CLEAR_SEGOVR();
2442 END_OF_INSTR();
2445 /****************************************************************************
2446 REMARKS:
2447 Handles opcode 0x2b
2448 ****************************************************************************/
2449 static void x86emuOp_sub_word_R_RM(u8 X86EMU_UNUSED(op1))
2451 int mod, rl, rh;
2452 uint srcoffset;
2454 START_OF_INSTR();
2455 DECODE_PRINTF("SUB\t");
2456 FETCH_DECODE_MODRM(mod, rh, rl);
2457 switch (mod) {
2458 case 0:
2459 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2460 u32 *destreg;
2461 u32 srcval;
2463 destreg = DECODE_RM_LONG_REGISTER(rh);
2464 DECODE_PRINTF(",");
2465 srcoffset = decode_rm00_address(rl);
2466 srcval = fetch_data_long(srcoffset);
2467 DECODE_PRINTF("\n");
2468 TRACE_AND_STEP();
2469 *destreg = sub_long(*destreg, srcval);
2470 } else {
2471 u16 *destreg;
2472 u16 srcval;
2474 destreg = DECODE_RM_WORD_REGISTER(rh);
2475 DECODE_PRINTF(",");
2476 srcoffset = decode_rm00_address(rl);
2477 srcval = fetch_data_word(srcoffset);
2478 DECODE_PRINTF("\n");
2479 TRACE_AND_STEP();
2480 *destreg = sub_word(*destreg, srcval);
2482 break;
2483 case 1:
2484 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2485 u32 *destreg;
2486 u32 srcval;
2488 destreg = DECODE_RM_LONG_REGISTER(rh);
2489 DECODE_PRINTF(",");
2490 srcoffset = decode_rm01_address(rl);
2491 srcval = fetch_data_long(srcoffset);
2492 DECODE_PRINTF("\n");
2493 TRACE_AND_STEP();
2494 *destreg = sub_long(*destreg, srcval);
2495 } else {
2496 u16 *destreg;
2497 u16 srcval;
2499 destreg = DECODE_RM_WORD_REGISTER(rh);
2500 DECODE_PRINTF(",");
2501 srcoffset = decode_rm01_address(rl);
2502 srcval = fetch_data_word(srcoffset);
2503 DECODE_PRINTF("\n");
2504 TRACE_AND_STEP();
2505 *destreg = sub_word(*destreg, srcval);
2507 break;
2508 case 2:
2509 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2510 u32 *destreg;
2511 u32 srcval;
2513 destreg = DECODE_RM_LONG_REGISTER(rh);
2514 DECODE_PRINTF(",");
2515 srcoffset = decode_rm10_address(rl);
2516 srcval = fetch_data_long(srcoffset);
2517 DECODE_PRINTF("\n");
2518 TRACE_AND_STEP();
2519 *destreg = sub_long(*destreg, srcval);
2520 } else {
2521 u16 *destreg;
2522 u16 srcval;
2524 destreg = DECODE_RM_WORD_REGISTER(rh);
2525 DECODE_PRINTF(",");
2526 srcoffset = decode_rm10_address(rl);
2527 srcval = fetch_data_word(srcoffset);
2528 DECODE_PRINTF("\n");
2529 TRACE_AND_STEP();
2530 *destreg = sub_word(*destreg, srcval);
2532 break;
2533 case 3: /* register to register */
2534 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2535 u32 *destreg,*srcreg;
2537 destreg = DECODE_RM_LONG_REGISTER(rh);
2538 DECODE_PRINTF(",");
2539 srcreg = DECODE_RM_LONG_REGISTER(rl);
2540 DECODE_PRINTF("\n");
2541 TRACE_AND_STEP();
2542 *destreg = sub_long(*destreg, *srcreg);
2543 } else {
2544 u16 *destreg,*srcreg;
2546 destreg = DECODE_RM_WORD_REGISTER(rh);
2547 DECODE_PRINTF(",");
2548 srcreg = DECODE_RM_WORD_REGISTER(rl);
2549 DECODE_PRINTF("\n");
2550 TRACE_AND_STEP();
2551 *destreg = sub_word(*destreg, *srcreg);
2553 break;
2555 DECODE_CLEAR_SEGOVR();
2556 END_OF_INSTR();
2559 /****************************************************************************
2560 REMARKS:
2561 Handles opcode 0x2c
2562 ****************************************************************************/
2563 static void x86emuOp_sub_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
2565 u8 srcval;
2567 START_OF_INSTR();
2568 DECODE_PRINTF("SUB\tAL,");
2569 srcval = fetch_byte_imm();
2570 DECODE_PRINTF2("%x\n", srcval);
2571 TRACE_AND_STEP();
2572 M.x86.R_AL = sub_byte(M.x86.R_AL, srcval);
2573 DECODE_CLEAR_SEGOVR();
2574 END_OF_INSTR();
2577 /****************************************************************************
2578 REMARKS:
2579 Handles opcode 0x2d
2580 ****************************************************************************/
2581 static void x86emuOp_sub_word_AX_IMM(u8 X86EMU_UNUSED(op1))
2583 u32 srcval;
2585 START_OF_INSTR();
2586 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2587 DECODE_PRINTF("SUB\tEAX,");
2588 srcval = fetch_long_imm();
2589 } else {
2590 DECODE_PRINTF("SUB\tAX,");
2591 srcval = fetch_word_imm();
2593 DECODE_PRINTF2("%x\n", srcval);
2594 TRACE_AND_STEP();
2595 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2596 M.x86.R_EAX = sub_long(M.x86.R_EAX, srcval);
2597 } else {
2598 M.x86.R_AX = sub_word(M.x86.R_AX, (u16)srcval);
2600 DECODE_CLEAR_SEGOVR();
2601 END_OF_INSTR();
2604 /****************************************************************************
2605 REMARKS:
2606 Handles opcode 0x2e
2607 ****************************************************************************/
2608 static void x86emuOp_segovr_CS(u8 X86EMU_UNUSED(op1))
2610 START_OF_INSTR();
2611 DECODE_PRINTF("CS:\n");
2612 TRACE_AND_STEP();
2613 M.x86.mode |= SYSMODE_SEGOVR_CS;
2614 /* note no DECODE_CLEAR_SEGOVR here. */
2615 END_OF_INSTR();
2618 /****************************************************************************
2619 REMARKS:
2620 Handles opcode 0x2f
2621 ****************************************************************************/
2622 static void x86emuOp_das(u8 X86EMU_UNUSED(op1))
2624 START_OF_INSTR();
2625 DECODE_PRINTF("DAS\n");
2626 TRACE_AND_STEP();
2627 M.x86.R_AL = das_byte(M.x86.R_AL);
2628 DECODE_CLEAR_SEGOVR();
2629 END_OF_INSTR();
2632 /****************************************************************************
2633 REMARKS:
2634 Handles opcode 0x30
2635 ****************************************************************************/
2636 static void x86emuOp_xor_byte_RM_R(u8 X86EMU_UNUSED(op1))
2638 int mod, rl, rh;
2639 u8 *destreg, *srcreg;
2640 uint destoffset;
2641 u8 destval;
2643 START_OF_INSTR();
2644 DECODE_PRINTF("XOR\t");
2645 FETCH_DECODE_MODRM(mod, rh, rl);
2646 switch (mod) {
2647 case 0:
2648 destoffset = decode_rm00_address(rl);
2649 DECODE_PRINTF(",");
2650 destval = fetch_data_byte(destoffset);
2651 srcreg = DECODE_RM_BYTE_REGISTER(rh);
2652 DECODE_PRINTF("\n");
2653 TRACE_AND_STEP();
2654 destval = xor_byte(destval, *srcreg);
2655 store_data_byte(destoffset, destval);
2656 break;
2657 case 1:
2658 destoffset = decode_rm01_address(rl);
2659 DECODE_PRINTF(",");
2660 destval = fetch_data_byte(destoffset);
2661 srcreg = DECODE_RM_BYTE_REGISTER(rh);
2662 DECODE_PRINTF("\n");
2663 TRACE_AND_STEP();
2664 destval = xor_byte(destval, *srcreg);
2665 store_data_byte(destoffset, destval);
2666 break;
2667 case 2:
2668 destoffset = decode_rm10_address(rl);
2669 DECODE_PRINTF(",");
2670 destval = fetch_data_byte(destoffset);
2671 srcreg = DECODE_RM_BYTE_REGISTER(rh);
2672 DECODE_PRINTF("\n");
2673 TRACE_AND_STEP();
2674 destval = xor_byte(destval, *srcreg);
2675 store_data_byte(destoffset, destval);
2676 break;
2677 case 3: /* register to register */
2678 destreg = DECODE_RM_BYTE_REGISTER(rl);
2679 DECODE_PRINTF(",");
2680 srcreg = DECODE_RM_BYTE_REGISTER(rh);
2681 DECODE_PRINTF("\n");
2682 TRACE_AND_STEP();
2683 *destreg = xor_byte(*destreg, *srcreg);
2684 break;
2686 DECODE_CLEAR_SEGOVR();
2687 END_OF_INSTR();
2690 /****************************************************************************
2691 REMARKS:
2692 Handles opcode 0x31
2693 ****************************************************************************/
2694 static void x86emuOp_xor_word_RM_R(u8 X86EMU_UNUSED(op1))
2696 int mod, rl, rh;
2697 uint destoffset;
2699 START_OF_INSTR();
2700 DECODE_PRINTF("XOR\t");
2701 FETCH_DECODE_MODRM(mod, rh, rl);
2702 switch (mod) {
2703 case 0:
2704 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2705 u32 destval;
2706 u32 *srcreg;
2708 destoffset = decode_rm00_address(rl);
2709 DECODE_PRINTF(",");
2710 destval = fetch_data_long(destoffset);
2711 srcreg = DECODE_RM_LONG_REGISTER(rh);
2712 DECODE_PRINTF("\n");
2713 TRACE_AND_STEP();
2714 destval = xor_long(destval, *srcreg);
2715 store_data_long(destoffset, destval);
2716 } else {
2717 u16 destval;
2718 u16 *srcreg;
2720 destoffset = decode_rm00_address(rl);
2721 DECODE_PRINTF(",");
2722 destval = fetch_data_word(destoffset);
2723 srcreg = DECODE_RM_WORD_REGISTER(rh);
2724 DECODE_PRINTF("\n");
2725 TRACE_AND_STEP();
2726 destval = xor_word(destval, *srcreg);
2727 store_data_word(destoffset, destval);
2729 break;
2730 case 1:
2731 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2732 u32 destval;
2733 u32 *srcreg;
2735 destoffset = decode_rm01_address(rl);
2736 DECODE_PRINTF(",");
2737 destval = fetch_data_long(destoffset);
2738 srcreg = DECODE_RM_LONG_REGISTER(rh);
2739 DECODE_PRINTF("\n");
2740 TRACE_AND_STEP();
2741 destval = xor_long(destval, *srcreg);
2742 store_data_long(destoffset, destval);
2743 } else {
2744 u16 destval;
2745 u16 *srcreg;
2747 destoffset = decode_rm01_address(rl);
2748 DECODE_PRINTF(",");
2749 destval = fetch_data_word(destoffset);
2750 srcreg = DECODE_RM_WORD_REGISTER(rh);
2751 DECODE_PRINTF("\n");
2752 TRACE_AND_STEP();
2753 destval = xor_word(destval, *srcreg);
2754 store_data_word(destoffset, destval);
2756 break;
2757 case 2:
2758 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2759 u32 destval;
2760 u32 *srcreg;
2762 destoffset = decode_rm10_address(rl);
2763 DECODE_PRINTF(",");
2764 destval = fetch_data_long(destoffset);
2765 srcreg = DECODE_RM_LONG_REGISTER(rh);
2766 DECODE_PRINTF("\n");
2767 TRACE_AND_STEP();
2768 destval = xor_long(destval, *srcreg);
2769 store_data_long(destoffset, destval);
2770 } else {
2771 u16 destval;
2772 u16 *srcreg;
2774 destoffset = decode_rm10_address(rl);
2775 DECODE_PRINTF(",");
2776 destval = fetch_data_word(destoffset);
2777 srcreg = DECODE_RM_WORD_REGISTER(rh);
2778 DECODE_PRINTF("\n");
2779 TRACE_AND_STEP();
2780 destval = xor_word(destval, *srcreg);
2781 store_data_word(destoffset, destval);
2783 break;
2784 case 3: /* register to register */
2785 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2786 u32 *destreg,*srcreg;
2788 destreg = DECODE_RM_LONG_REGISTER(rl);
2789 DECODE_PRINTF(",");
2790 srcreg = DECODE_RM_LONG_REGISTER(rh);
2791 DECODE_PRINTF("\n");
2792 TRACE_AND_STEP();
2793 *destreg = xor_long(*destreg, *srcreg);
2794 } else {
2795 u16 *destreg,*srcreg;
2797 destreg = DECODE_RM_WORD_REGISTER(rl);
2798 DECODE_PRINTF(",");
2799 srcreg = DECODE_RM_WORD_REGISTER(rh);
2800 DECODE_PRINTF("\n");
2801 TRACE_AND_STEP();
2802 *destreg = xor_word(*destreg, *srcreg);
2804 break;
2806 DECODE_CLEAR_SEGOVR();
2807 END_OF_INSTR();
2810 /****************************************************************************
2811 REMARKS:
2812 Handles opcode 0x32
2813 ****************************************************************************/
2814 static void x86emuOp_xor_byte_R_RM(u8 X86EMU_UNUSED(op1))
2816 int mod, rl, rh;
2817 u8 *destreg, *srcreg;
2818 uint srcoffset;
2819 u8 srcval;
2821 START_OF_INSTR();
2822 DECODE_PRINTF("XOR\t");
2823 FETCH_DECODE_MODRM(mod, rh, rl);
2824 switch (mod) {
2825 case 0:
2826 destreg = DECODE_RM_BYTE_REGISTER(rh);
2827 DECODE_PRINTF(",");
2828 srcoffset = decode_rm00_address(rl);
2829 srcval = fetch_data_byte(srcoffset);
2830 DECODE_PRINTF("\n");
2831 TRACE_AND_STEP();
2832 *destreg = xor_byte(*destreg, srcval);
2833 break;
2834 case 1:
2835 destreg = DECODE_RM_BYTE_REGISTER(rh);
2836 DECODE_PRINTF(",");
2837 srcoffset = decode_rm01_address(rl);
2838 srcval = fetch_data_byte(srcoffset);
2839 DECODE_PRINTF("\n");
2840 TRACE_AND_STEP();
2841 *destreg = xor_byte(*destreg, srcval);
2842 break;
2843 case 2:
2844 destreg = DECODE_RM_BYTE_REGISTER(rh);
2845 DECODE_PRINTF(",");
2846 srcoffset = decode_rm10_address(rl);
2847 srcval = fetch_data_byte(srcoffset);
2848 DECODE_PRINTF("\n");
2849 TRACE_AND_STEP();
2850 *destreg = xor_byte(*destreg, srcval);
2851 break;
2852 case 3: /* register to register */
2853 destreg = DECODE_RM_BYTE_REGISTER(rh);
2854 DECODE_PRINTF(",");
2855 srcreg = DECODE_RM_BYTE_REGISTER(rl);
2856 DECODE_PRINTF("\n");
2857 TRACE_AND_STEP();
2858 *destreg = xor_byte(*destreg, *srcreg);
2859 break;
2861 DECODE_CLEAR_SEGOVR();
2862 END_OF_INSTR();
2865 /****************************************************************************
2866 REMARKS:
2867 Handles opcode 0x33
2868 ****************************************************************************/
2869 static void x86emuOp_xor_word_R_RM(u8 X86EMU_UNUSED(op1))
2871 int mod, rl, rh;
2872 uint srcoffset;
2874 START_OF_INSTR();
2875 DECODE_PRINTF("XOR\t");
2876 FETCH_DECODE_MODRM(mod, rh, rl);
2877 switch (mod) {
2878 case 0:
2879 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2880 u32 *destreg;
2881 u32 srcval;
2883 destreg = DECODE_RM_LONG_REGISTER(rh);
2884 DECODE_PRINTF(",");
2885 srcoffset = decode_rm00_address(rl);
2886 srcval = fetch_data_long(srcoffset);
2887 DECODE_PRINTF("\n");
2888 TRACE_AND_STEP();
2889 *destreg = xor_long(*destreg, srcval);
2890 } else {
2891 u16 *destreg;
2892 u16 srcval;
2894 destreg = DECODE_RM_WORD_REGISTER(rh);
2895 DECODE_PRINTF(",");
2896 srcoffset = decode_rm00_address(rl);
2897 srcval = fetch_data_word(srcoffset);
2898 DECODE_PRINTF("\n");
2899 TRACE_AND_STEP();
2900 *destreg = xor_word(*destreg, srcval);
2902 break;
2903 case 1:
2904 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2905 u32 *destreg;
2906 u32 srcval;
2908 destreg = DECODE_RM_LONG_REGISTER(rh);
2909 DECODE_PRINTF(",");
2910 srcoffset = decode_rm01_address(rl);
2911 srcval = fetch_data_long(srcoffset);
2912 DECODE_PRINTF("\n");
2913 TRACE_AND_STEP();
2914 *destreg = xor_long(*destreg, srcval);
2915 } else {
2916 u16 *destreg;
2917 u16 srcval;
2919 destreg = DECODE_RM_WORD_REGISTER(rh);
2920 DECODE_PRINTF(",");
2921 srcoffset = decode_rm01_address(rl);
2922 srcval = fetch_data_word(srcoffset);
2923 DECODE_PRINTF("\n");
2924 TRACE_AND_STEP();
2925 *destreg = xor_word(*destreg, srcval);
2927 break;
2928 case 2:
2929 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2930 u32 *destreg;
2931 u32 srcval;
2933 destreg = DECODE_RM_LONG_REGISTER(rh);
2934 DECODE_PRINTF(",");
2935 srcoffset = decode_rm10_address(rl);
2936 srcval = fetch_data_long(srcoffset);
2937 DECODE_PRINTF("\n");
2938 TRACE_AND_STEP();
2939 *destreg = xor_long(*destreg, srcval);
2940 } else {
2941 u16 *destreg;
2942 u16 srcval;
2944 destreg = DECODE_RM_WORD_REGISTER(rh);
2945 DECODE_PRINTF(",");
2946 srcoffset = decode_rm10_address(rl);
2947 srcval = fetch_data_word(srcoffset);
2948 DECODE_PRINTF("\n");
2949 TRACE_AND_STEP();
2950 *destreg = xor_word(*destreg, srcval);
2952 break;
2953 case 3: /* register to register */
2954 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2955 u32 *destreg,*srcreg;
2957 destreg = DECODE_RM_LONG_REGISTER(rh);
2958 DECODE_PRINTF(",");
2959 srcreg = DECODE_RM_LONG_REGISTER(rl);
2960 DECODE_PRINTF("\n");
2961 TRACE_AND_STEP();
2962 *destreg = xor_long(*destreg, *srcreg);
2963 } else {
2964 u16 *destreg,*srcreg;
2966 destreg = DECODE_RM_WORD_REGISTER(rh);
2967 DECODE_PRINTF(",");
2968 srcreg = DECODE_RM_WORD_REGISTER(rl);
2969 DECODE_PRINTF("\n");
2970 TRACE_AND_STEP();
2971 *destreg = xor_word(*destreg, *srcreg);
2973 break;
2975 DECODE_CLEAR_SEGOVR();
2976 END_OF_INSTR();
2979 /****************************************************************************
2980 REMARKS:
2981 Handles opcode 0x34
2982 ****************************************************************************/
2983 static void x86emuOp_xor_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
2985 u8 srcval;
2987 START_OF_INSTR();
2988 DECODE_PRINTF("XOR\tAL,");
2989 srcval = fetch_byte_imm();
2990 DECODE_PRINTF2("%x\n", srcval);
2991 TRACE_AND_STEP();
2992 M.x86.R_AL = xor_byte(M.x86.R_AL, srcval);
2993 DECODE_CLEAR_SEGOVR();
2994 END_OF_INSTR();
2997 /****************************************************************************
2998 REMARKS:
2999 Handles opcode 0x35
3000 ****************************************************************************/
3001 static void x86emuOp_xor_word_AX_IMM(u8 X86EMU_UNUSED(op1))
3003 u32 srcval;
3005 START_OF_INSTR();
3006 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3007 DECODE_PRINTF("XOR\tEAX,");
3008 srcval = fetch_long_imm();
3009 } else {
3010 DECODE_PRINTF("XOR\tAX,");
3011 srcval = fetch_word_imm();
3013 DECODE_PRINTF2("%x\n", srcval);
3014 TRACE_AND_STEP();
3015 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3016 M.x86.R_EAX = xor_long(M.x86.R_EAX, srcval);
3017 } else {
3018 M.x86.R_AX = xor_word(M.x86.R_AX, (u16)srcval);
3020 DECODE_CLEAR_SEGOVR();
3021 END_OF_INSTR();
3024 /****************************************************************************
3025 REMARKS:
3026 Handles opcode 0x36
3027 ****************************************************************************/
3028 static void x86emuOp_segovr_SS(u8 X86EMU_UNUSED(op1))
3030 START_OF_INSTR();
3031 DECODE_PRINTF("SS:\n");
3032 TRACE_AND_STEP();
3033 M.x86.mode |= SYSMODE_SEGOVR_SS;
3034 /* no DECODE_CLEAR_SEGOVR ! */
3035 END_OF_INSTR();
3038 /****************************************************************************
3039 REMARKS:
3040 Handles opcode 0x37
3041 ****************************************************************************/
3042 static void x86emuOp_aaa(u8 X86EMU_UNUSED(op1))
3044 START_OF_INSTR();
3045 DECODE_PRINTF("AAA\n");
3046 TRACE_AND_STEP();
3047 M.x86.R_AX = aaa_word(M.x86.R_AX);
3048 DECODE_CLEAR_SEGOVR();
3049 END_OF_INSTR();
3052 /****************************************************************************
3053 REMARKS:
3054 Handles opcode 0x38
3055 ****************************************************************************/
3056 static void x86emuOp_cmp_byte_RM_R(u8 X86EMU_UNUSED(op1))
3058 int mod, rl, rh;
3059 uint destoffset;
3060 u8 *destreg, *srcreg;
3061 u8 destval;
3063 START_OF_INSTR();
3064 DECODE_PRINTF("CMP\t");
3065 FETCH_DECODE_MODRM(mod, rh, rl);
3066 switch (mod) {
3067 case 0:
3068 destoffset = decode_rm00_address(rl);
3069 DECODE_PRINTF(",");
3070 destval = fetch_data_byte(destoffset);
3071 srcreg = DECODE_RM_BYTE_REGISTER(rh);
3072 DECODE_PRINTF("\n");
3073 TRACE_AND_STEP();
3074 cmp_byte(destval, *srcreg);
3075 break;
3076 case 1:
3077 destoffset = decode_rm01_address(rl);
3078 DECODE_PRINTF(",");
3079 destval = fetch_data_byte(destoffset);
3080 srcreg = DECODE_RM_BYTE_REGISTER(rh);
3081 DECODE_PRINTF("\n");
3082 TRACE_AND_STEP();
3083 cmp_byte(destval, *srcreg);
3084 break;
3085 case 2:
3086 destoffset = decode_rm10_address(rl);
3087 DECODE_PRINTF(",");
3088 destval = fetch_data_byte(destoffset);
3089 srcreg = DECODE_RM_BYTE_REGISTER(rh);
3090 DECODE_PRINTF("\n");
3091 TRACE_AND_STEP();
3092 cmp_byte(destval, *srcreg);
3093 break;
3094 case 3: /* register to register */
3095 destreg = DECODE_RM_BYTE_REGISTER(rl);
3096 DECODE_PRINTF(",");
3097 srcreg = DECODE_RM_BYTE_REGISTER(rh);
3098 DECODE_PRINTF("\n");
3099 TRACE_AND_STEP();
3100 cmp_byte(*destreg, *srcreg);
3101 break;
3103 DECODE_CLEAR_SEGOVR();
3104 END_OF_INSTR();
3107 /****************************************************************************
3108 REMARKS:
3109 Handles opcode 0x39
3110 ****************************************************************************/
3111 static void x86emuOp_cmp_word_RM_R(u8 X86EMU_UNUSED(op1))
3113 int mod, rl, rh;
3114 uint destoffset;
3116 START_OF_INSTR();
3117 DECODE_PRINTF("CMP\t");
3118 FETCH_DECODE_MODRM(mod, rh, rl);
3119 switch (mod) {
3120 case 0:
3121 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3122 u32 destval;
3123 u32 *srcreg;
3125 destoffset = decode_rm00_address(rl);
3126 DECODE_PRINTF(",");
3127 destval = fetch_data_long(destoffset);
3128 srcreg = DECODE_RM_LONG_REGISTER(rh);
3129 DECODE_PRINTF("\n");
3130 TRACE_AND_STEP();
3131 cmp_long(destval, *srcreg);
3132 } else {
3133 u16 destval;
3134 u16 *srcreg;
3136 destoffset = decode_rm00_address(rl);
3137 DECODE_PRINTF(",");
3138 destval = fetch_data_word(destoffset);
3139 srcreg = DECODE_RM_WORD_REGISTER(rh);
3140 DECODE_PRINTF("\n");
3141 TRACE_AND_STEP();
3142 cmp_word(destval, *srcreg);
3144 break;
3145 case 1:
3146 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3147 u32 destval;
3148 u32 *srcreg;
3150 destoffset = decode_rm01_address(rl);
3151 DECODE_PRINTF(",");
3152 destval = fetch_data_long(destoffset);
3153 srcreg = DECODE_RM_LONG_REGISTER(rh);
3154 DECODE_PRINTF("\n");
3155 TRACE_AND_STEP();
3156 cmp_long(destval, *srcreg);
3157 } else {
3158 u16 destval;
3159 u16 *srcreg;
3161 destoffset = decode_rm01_address(rl);
3162 DECODE_PRINTF(",");
3163 destval = fetch_data_word(destoffset);
3164 srcreg = DECODE_RM_WORD_REGISTER(rh);
3165 DECODE_PRINTF("\n");
3166 TRACE_AND_STEP();
3167 cmp_word(destval, *srcreg);
3169 break;
3170 case 2:
3171 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3172 u32 destval;
3173 u32 *srcreg;
3175 destoffset = decode_rm10_address(rl);
3176 DECODE_PRINTF(",");
3177 destval = fetch_data_long(destoffset);
3178 srcreg = DECODE_RM_LONG_REGISTER(rh);
3179 DECODE_PRINTF("\n");
3180 TRACE_AND_STEP();
3181 cmp_long(destval, *srcreg);
3182 } else {
3183 u16 destval;
3184 u16 *srcreg;
3186 destoffset = decode_rm10_address(rl);
3187 DECODE_PRINTF(",");
3188 destval = fetch_data_word(destoffset);
3189 srcreg = DECODE_RM_WORD_REGISTER(rh);
3190 DECODE_PRINTF("\n");
3191 TRACE_AND_STEP();
3192 cmp_word(destval, *srcreg);
3194 break;
3195 case 3: /* register to register */
3196 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3197 u32 *destreg,*srcreg;
3199 destreg = DECODE_RM_LONG_REGISTER(rl);
3200 DECODE_PRINTF(",");
3201 srcreg = DECODE_RM_LONG_REGISTER(rh);
3202 DECODE_PRINTF("\n");
3203 TRACE_AND_STEP();
3204 cmp_long(*destreg, *srcreg);
3205 } else {
3206 u16 *destreg,*srcreg;
3208 destreg = DECODE_RM_WORD_REGISTER(rl);
3209 DECODE_PRINTF(",");
3210 srcreg = DECODE_RM_WORD_REGISTER(rh);
3211 DECODE_PRINTF("\n");
3212 TRACE_AND_STEP();
3213 cmp_word(*destreg, *srcreg);
3215 break;
3217 DECODE_CLEAR_SEGOVR();
3218 END_OF_INSTR();
3221 /****************************************************************************
3222 REMARKS:
3223 Handles opcode 0x3a
3224 ****************************************************************************/
3225 static void x86emuOp_cmp_byte_R_RM(u8 X86EMU_UNUSED(op1))
3227 int mod, rl, rh;
3228 u8 *destreg, *srcreg;
3229 uint srcoffset;
3230 u8 srcval;
3232 START_OF_INSTR();
3233 DECODE_PRINTF("CMP\t");
3234 FETCH_DECODE_MODRM(mod, rh, rl);
3235 switch (mod) {
3236 case 0:
3237 destreg = DECODE_RM_BYTE_REGISTER(rh);
3238 DECODE_PRINTF(",");
3239 srcoffset = decode_rm00_address(rl);
3240 srcval = fetch_data_byte(srcoffset);
3241 DECODE_PRINTF("\n");
3242 TRACE_AND_STEP();
3243 cmp_byte(*destreg, srcval);
3244 break;
3245 case 1:
3246 destreg = DECODE_RM_BYTE_REGISTER(rh);
3247 DECODE_PRINTF(",");
3248 srcoffset = decode_rm01_address(rl);
3249 srcval = fetch_data_byte(srcoffset);
3250 DECODE_PRINTF("\n");
3251 TRACE_AND_STEP();
3252 cmp_byte(*destreg, srcval);
3253 break;
3254 case 2:
3255 destreg = DECODE_RM_BYTE_REGISTER(rh);
3256 DECODE_PRINTF(",");
3257 srcoffset = decode_rm10_address(rl);
3258 srcval = fetch_data_byte(srcoffset);
3259 DECODE_PRINTF("\n");
3260 TRACE_AND_STEP();
3261 cmp_byte(*destreg, srcval);
3262 break;
3263 case 3: /* register to register */
3264 destreg = DECODE_RM_BYTE_REGISTER(rh);
3265 DECODE_PRINTF(",");
3266 srcreg = DECODE_RM_BYTE_REGISTER(rl);
3267 DECODE_PRINTF("\n");
3268 TRACE_AND_STEP();
3269 cmp_byte(*destreg, *srcreg);
3270 break;
3272 DECODE_CLEAR_SEGOVR();
3273 END_OF_INSTR();
3276 /****************************************************************************
3277 REMARKS:
3278 Handles opcode 0x3b
3279 ****************************************************************************/
3280 static void x86emuOp_cmp_word_R_RM(u8 X86EMU_UNUSED(op1))
3282 int mod, rl, rh;
3283 uint srcoffset;
3285 START_OF_INSTR();
3286 DECODE_PRINTF("CMP\t");
3287 FETCH_DECODE_MODRM(mod, rh, rl);
3288 switch (mod) {
3289 case 0:
3290 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3291 u32 *destreg;
3292 u32 srcval;
3294 destreg = DECODE_RM_LONG_REGISTER(rh);
3295 DECODE_PRINTF(",");
3296 srcoffset = decode_rm00_address(rl);
3297 srcval = fetch_data_long(srcoffset);
3298 DECODE_PRINTF("\n");
3299 TRACE_AND_STEP();
3300 cmp_long(*destreg, srcval);
3301 } else {
3302 u16 *destreg;
3303 u16 srcval;
3305 destreg = DECODE_RM_WORD_REGISTER(rh);
3306 DECODE_PRINTF(",");
3307 srcoffset = decode_rm00_address(rl);
3308 srcval = fetch_data_word(srcoffset);
3309 DECODE_PRINTF("\n");
3310 TRACE_AND_STEP();
3311 cmp_word(*destreg, srcval);
3313 break;
3314 case 1:
3315 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3316 u32 *destreg;
3317 u32 srcval;
3319 destreg = DECODE_RM_LONG_REGISTER(rh);
3320 DECODE_PRINTF(",");
3321 srcoffset = decode_rm01_address(rl);
3322 srcval = fetch_data_long(srcoffset);
3323 DECODE_PRINTF("\n");
3324 TRACE_AND_STEP();
3325 cmp_long(*destreg, srcval);
3326 } else {
3327 u16 *destreg;
3328 u16 srcval;
3330 destreg = DECODE_RM_WORD_REGISTER(rh);
3331 DECODE_PRINTF(",");
3332 srcoffset = decode_rm01_address(rl);
3333 srcval = fetch_data_word(srcoffset);
3334 DECODE_PRINTF("\n");
3335 TRACE_AND_STEP();
3336 cmp_word(*destreg, srcval);
3338 break;
3339 case 2:
3340 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3341 u32 *destreg;
3342 u32 srcval;
3344 destreg = DECODE_RM_LONG_REGISTER(rh);
3345 DECODE_PRINTF(",");
3346 srcoffset = decode_rm10_address(rl);
3347 srcval = fetch_data_long(srcoffset);
3348 DECODE_PRINTF("\n");
3349 TRACE_AND_STEP();
3350 cmp_long(*destreg, srcval);
3351 } else {
3352 u16 *destreg;
3353 u16 srcval;
3355 destreg = DECODE_RM_WORD_REGISTER(rh);
3356 DECODE_PRINTF(",");
3357 srcoffset = decode_rm10_address(rl);
3358 srcval = fetch_data_word(srcoffset);
3359 DECODE_PRINTF("\n");
3360 TRACE_AND_STEP();
3361 cmp_word(*destreg, srcval);
3363 break;
3364 case 3: /* register to register */
3365 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3366 u32 *destreg,*srcreg;
3368 destreg = DECODE_RM_LONG_REGISTER(rh);
3369 DECODE_PRINTF(",");
3370 srcreg = DECODE_RM_LONG_REGISTER(rl);
3371 DECODE_PRINTF("\n");
3372 TRACE_AND_STEP();
3373 cmp_long(*destreg, *srcreg);
3374 } else {
3375 u16 *destreg,*srcreg;
3377 destreg = DECODE_RM_WORD_REGISTER(rh);
3378 DECODE_PRINTF(",");
3379 srcreg = DECODE_RM_WORD_REGISTER(rl);
3380 DECODE_PRINTF("\n");
3381 TRACE_AND_STEP();
3382 cmp_word(*destreg, *srcreg);
3384 break;
3386 DECODE_CLEAR_SEGOVR();
3387 END_OF_INSTR();
3390 /****************************************************************************
3391 REMARKS:
3392 Handles opcode 0x3c
3393 ****************************************************************************/
3394 static void x86emuOp_cmp_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
3396 u8 srcval;
3398 START_OF_INSTR();
3399 DECODE_PRINTF("CMP\tAL,");
3400 srcval = fetch_byte_imm();
3401 DECODE_PRINTF2("%x\n", srcval);
3402 TRACE_AND_STEP();
3403 cmp_byte(M.x86.R_AL, srcval);
3404 DECODE_CLEAR_SEGOVR();
3405 END_OF_INSTR();
3408 /****************************************************************************
3409 REMARKS:
3410 Handles opcode 0x3d
3411 ****************************************************************************/
3412 static void x86emuOp_cmp_word_AX_IMM(u8 X86EMU_UNUSED(op1))
3414 u32 srcval;
3416 START_OF_INSTR();
3417 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3418 DECODE_PRINTF("CMP\tEAX,");
3419 srcval = fetch_long_imm();
3420 } else {
3421 DECODE_PRINTF("CMP\tAX,");
3422 srcval = fetch_word_imm();
3424 DECODE_PRINTF2("%x\n", srcval);
3425 TRACE_AND_STEP();
3426 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3427 cmp_long(M.x86.R_EAX, srcval);
3428 } else {
3429 cmp_word(M.x86.R_AX, (u16)srcval);
3431 DECODE_CLEAR_SEGOVR();
3432 END_OF_INSTR();
3435 /****************************************************************************
3436 REMARKS:
3437 Handles opcode 0x3e
3438 ****************************************************************************/
3439 static void x86emuOp_segovr_DS(u8 X86EMU_UNUSED(op1))
3441 START_OF_INSTR();
3442 DECODE_PRINTF("DS:\n");
3443 TRACE_AND_STEP();
3444 M.x86.mode |= SYSMODE_SEGOVR_DS;
3445 /* NO DECODE_CLEAR_SEGOVR! */
3446 END_OF_INSTR();
3449 /****************************************************************************
3450 REMARKS:
3451 Handles opcode 0x3f
3452 ****************************************************************************/
3453 static void x86emuOp_aas(u8 X86EMU_UNUSED(op1))
3455 START_OF_INSTR();
3456 DECODE_PRINTF("AAS\n");
3457 TRACE_AND_STEP();
3458 M.x86.R_AX = aas_word(M.x86.R_AX);
3459 DECODE_CLEAR_SEGOVR();
3460 END_OF_INSTR();
3463 /****************************************************************************
3464 REMARKS:
3465 Handles opcode 0x40
3466 ****************************************************************************/
3467 static void x86emuOp_inc_AX(u8 X86EMU_UNUSED(op1))
3469 START_OF_INSTR();
3470 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3471 DECODE_PRINTF("INC\tEAX\n");
3472 } else {
3473 DECODE_PRINTF("INC\tAX\n");
3475 TRACE_AND_STEP();
3476 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3477 M.x86.R_EAX = inc_long(M.x86.R_EAX);
3478 } else {
3479 M.x86.R_AX = inc_word(M.x86.R_AX);
3481 DECODE_CLEAR_SEGOVR();
3482 END_OF_INSTR();
3485 /****************************************************************************
3486 REMARKS:
3487 Handles opcode 0x41
3488 ****************************************************************************/
3489 static void x86emuOp_inc_CX(u8 X86EMU_UNUSED(op1))
3491 START_OF_INSTR();
3492 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3493 DECODE_PRINTF("INC\tECX\n");
3494 } else {
3495 DECODE_PRINTF("INC\tCX\n");
3497 TRACE_AND_STEP();
3498 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3499 M.x86.R_ECX = inc_long(M.x86.R_ECX);
3500 } else {
3501 M.x86.R_CX = inc_word(M.x86.R_CX);
3503 DECODE_CLEAR_SEGOVR();
3504 END_OF_INSTR();
3507 /****************************************************************************
3508 REMARKS:
3509 Handles opcode 0x42
3510 ****************************************************************************/
3511 static void x86emuOp_inc_DX(u8 X86EMU_UNUSED(op1))
3513 START_OF_INSTR();
3514 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3515 DECODE_PRINTF("INC\tEDX\n");
3516 } else {
3517 DECODE_PRINTF("INC\tDX\n");
3519 TRACE_AND_STEP();
3520 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3521 M.x86.R_EDX = inc_long(M.x86.R_EDX);
3522 } else {
3523 M.x86.R_DX = inc_word(M.x86.R_DX);
3525 DECODE_CLEAR_SEGOVR();
3526 END_OF_INSTR();
3529 /****************************************************************************
3530 REMARKS:
3531 Handles opcode 0x43
3532 ****************************************************************************/
3533 static void x86emuOp_inc_BX(u8 X86EMU_UNUSED(op1))
3535 START_OF_INSTR();
3536 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3537 DECODE_PRINTF("INC\tEBX\n");
3538 } else {
3539 DECODE_PRINTF("INC\tBX\n");
3541 TRACE_AND_STEP();
3542 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3543 M.x86.R_EBX = inc_long(M.x86.R_EBX);
3544 } else {
3545 M.x86.R_BX = inc_word(M.x86.R_BX);
3547 DECODE_CLEAR_SEGOVR();
3548 END_OF_INSTR();
3551 /****************************************************************************
3552 REMARKS:
3553 Handles opcode 0x44
3554 ****************************************************************************/
3555 static void x86emuOp_inc_SP(u8 X86EMU_UNUSED(op1))
3557 START_OF_INSTR();
3558 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3559 DECODE_PRINTF("INC\tESP\n");
3560 } else {
3561 DECODE_PRINTF("INC\tSP\n");
3563 TRACE_AND_STEP();
3564 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3565 M.x86.R_ESP = inc_long(M.x86.R_ESP);
3566 } else {
3567 M.x86.R_SP = inc_word(M.x86.R_SP);
3569 DECODE_CLEAR_SEGOVR();
3570 END_OF_INSTR();
3573 /****************************************************************************
3574 REMARKS:
3575 Handles opcode 0x45
3576 ****************************************************************************/
3577 static void x86emuOp_inc_BP(u8 X86EMU_UNUSED(op1))
3579 START_OF_INSTR();
3580 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3581 DECODE_PRINTF("INC\tEBP\n");
3582 } else {
3583 DECODE_PRINTF("INC\tBP\n");
3585 TRACE_AND_STEP();
3586 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3587 M.x86.R_EBP = inc_long(M.x86.R_EBP);
3588 } else {
3589 M.x86.R_BP = inc_word(M.x86.R_BP);
3591 DECODE_CLEAR_SEGOVR();
3592 END_OF_INSTR();
3595 /****************************************************************************
3596 REMARKS:
3597 Handles opcode 0x46
3598 ****************************************************************************/
3599 static void x86emuOp_inc_SI(u8 X86EMU_UNUSED(op1))
3601 START_OF_INSTR();
3602 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3603 DECODE_PRINTF("INC\tESI\n");
3604 } else {
3605 DECODE_PRINTF("INC\tSI\n");
3607 TRACE_AND_STEP();
3608 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3609 M.x86.R_ESI = inc_long(M.x86.R_ESI);
3610 } else {
3611 M.x86.R_SI = inc_word(M.x86.R_SI);
3613 DECODE_CLEAR_SEGOVR();
3614 END_OF_INSTR();
3617 /****************************************************************************
3618 REMARKS:
3619 Handles opcode 0x47
3620 ****************************************************************************/
3621 static void x86emuOp_inc_DI(u8 X86EMU_UNUSED(op1))
3623 START_OF_INSTR();
3624 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3625 DECODE_PRINTF("INC\tEDI\n");
3626 } else {
3627 DECODE_PRINTF("INC\tDI\n");
3629 TRACE_AND_STEP();
3630 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3631 M.x86.R_EDI = inc_long(M.x86.R_EDI);
3632 } else {
3633 M.x86.R_DI = inc_word(M.x86.R_DI);
3635 DECODE_CLEAR_SEGOVR();
3636 END_OF_INSTR();
3639 /****************************************************************************
3640 REMARKS:
3641 Handles opcode 0x48
3642 ****************************************************************************/
3643 static void x86emuOp_dec_AX(u8 X86EMU_UNUSED(op1))
3645 START_OF_INSTR();
3646 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3647 DECODE_PRINTF("DEC\tEAX\n");
3648 } else {
3649 DECODE_PRINTF("DEC\tAX\n");
3651 TRACE_AND_STEP();
3652 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3653 M.x86.R_EAX = dec_long(M.x86.R_EAX);
3654 } else {
3655 M.x86.R_AX = dec_word(M.x86.R_AX);
3657 DECODE_CLEAR_SEGOVR();
3658 END_OF_INSTR();
3661 /****************************************************************************
3662 REMARKS:
3663 Handles opcode 0x49
3664 ****************************************************************************/
3665 static void x86emuOp_dec_CX(u8 X86EMU_UNUSED(op1))
3667 START_OF_INSTR();
3668 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3669 DECODE_PRINTF("DEC\tECX\n");
3670 } else {
3671 DECODE_PRINTF("DEC\tCX\n");
3673 TRACE_AND_STEP();
3674 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3675 M.x86.R_ECX = dec_long(M.x86.R_ECX);
3676 } else {
3677 M.x86.R_CX = dec_word(M.x86.R_CX);
3679 DECODE_CLEAR_SEGOVR();
3680 END_OF_INSTR();
3683 /****************************************************************************
3684 REMARKS:
3685 Handles opcode 0x4a
3686 ****************************************************************************/
3687 static void x86emuOp_dec_DX(u8 X86EMU_UNUSED(op1))
3689 START_OF_INSTR();
3690 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3691 DECODE_PRINTF("DEC\tEDX\n");
3692 } else {
3693 DECODE_PRINTF("DEC\tDX\n");
3695 TRACE_AND_STEP();
3696 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3697 M.x86.R_EDX = dec_long(M.x86.R_EDX);
3698 } else {
3699 M.x86.R_DX = dec_word(M.x86.R_DX);
3701 DECODE_CLEAR_SEGOVR();
3702 END_OF_INSTR();
3705 /****************************************************************************
3706 REMARKS:
3707 Handles opcode 0x4b
3708 ****************************************************************************/
3709 static void x86emuOp_dec_BX(u8 X86EMU_UNUSED(op1))
3711 START_OF_INSTR();
3712 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3713 DECODE_PRINTF("DEC\tEBX\n");
3714 } else {
3715 DECODE_PRINTF("DEC\tBX\n");
3717 TRACE_AND_STEP();
3718 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3719 M.x86.R_EBX = dec_long(M.x86.R_EBX);
3720 } else {
3721 M.x86.R_BX = dec_word(M.x86.R_BX);
3723 DECODE_CLEAR_SEGOVR();
3724 END_OF_INSTR();
3727 /****************************************************************************
3728 REMARKS:
3729 Handles opcode 0x4c
3730 ****************************************************************************/
3731 static void x86emuOp_dec_SP(u8 X86EMU_UNUSED(op1))
3733 START_OF_INSTR();
3734 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3735 DECODE_PRINTF("DEC\tESP\n");
3736 } else {
3737 DECODE_PRINTF("DEC\tSP\n");
3739 TRACE_AND_STEP();
3740 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3741 M.x86.R_ESP = dec_long(M.x86.R_ESP);
3742 } else {
3743 M.x86.R_SP = dec_word(M.x86.R_SP);
3745 DECODE_CLEAR_SEGOVR();
3746 END_OF_INSTR();
3749 /****************************************************************************
3750 REMARKS:
3751 Handles opcode 0x4d
3752 ****************************************************************************/
3753 static void x86emuOp_dec_BP(u8 X86EMU_UNUSED(op1))
3755 START_OF_INSTR();
3756 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3757 DECODE_PRINTF("DEC\tEBP\n");
3758 } else {
3759 DECODE_PRINTF("DEC\tBP\n");
3761 TRACE_AND_STEP();
3762 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3763 M.x86.R_EBP = dec_long(M.x86.R_EBP);
3764 } else {
3765 M.x86.R_BP = dec_word(M.x86.R_BP);
3767 DECODE_CLEAR_SEGOVR();
3768 END_OF_INSTR();
3771 /****************************************************************************
3772 REMARKS:
3773 Handles opcode 0x4e
3774 ****************************************************************************/
3775 static void x86emuOp_dec_SI(u8 X86EMU_UNUSED(op1))
3777 START_OF_INSTR();
3778 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3779 DECODE_PRINTF("DEC\tESI\n");
3780 } else {
3781 DECODE_PRINTF("DEC\tSI\n");
3783 TRACE_AND_STEP();
3784 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3785 M.x86.R_ESI = dec_long(M.x86.R_ESI);
3786 } else {
3787 M.x86.R_SI = dec_word(M.x86.R_SI);
3789 DECODE_CLEAR_SEGOVR();
3790 END_OF_INSTR();
3793 /****************************************************************************
3794 REMARKS:
3795 Handles opcode 0x4f
3796 ****************************************************************************/
3797 static void x86emuOp_dec_DI(u8 X86EMU_UNUSED(op1))
3799 START_OF_INSTR();
3800 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3801 DECODE_PRINTF("DEC\tEDI\n");
3802 } else {
3803 DECODE_PRINTF("DEC\tDI\n");
3805 TRACE_AND_STEP();
3806 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3807 M.x86.R_EDI = dec_long(M.x86.R_EDI);
3808 } else {
3809 M.x86.R_DI = dec_word(M.x86.R_DI);
3811 DECODE_CLEAR_SEGOVR();
3812 END_OF_INSTR();
3815 /****************************************************************************
3816 REMARKS:
3817 Handles opcode 0x50
3818 ****************************************************************************/
3819 static void x86emuOp_push_AX(u8 X86EMU_UNUSED(op1))
3821 START_OF_INSTR();
3822 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3823 DECODE_PRINTF("PUSH\tEAX\n");
3824 } else {
3825 DECODE_PRINTF("PUSH\tAX\n");
3827 TRACE_AND_STEP();
3828 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3829 push_long(M.x86.R_EAX);
3830 } else {
3831 push_word(M.x86.R_AX);
3833 DECODE_CLEAR_SEGOVR();
3834 END_OF_INSTR();
3837 /****************************************************************************
3838 REMARKS:
3839 Handles opcode 0x51
3840 ****************************************************************************/
3841 static void x86emuOp_push_CX(u8 X86EMU_UNUSED(op1))
3843 START_OF_INSTR();
3844 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3845 DECODE_PRINTF("PUSH\tECX\n");
3846 } else {
3847 DECODE_PRINTF("PUSH\tCX\n");
3849 TRACE_AND_STEP();
3850 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3851 push_long(M.x86.R_ECX);
3852 } else {
3853 push_word(M.x86.R_CX);
3855 DECODE_CLEAR_SEGOVR();
3856 END_OF_INSTR();
3859 /****************************************************************************
3860 REMARKS:
3861 Handles opcode 0x52
3862 ****************************************************************************/
3863 static void x86emuOp_push_DX(u8 X86EMU_UNUSED(op1))
3865 START_OF_INSTR();
3866 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3867 DECODE_PRINTF("PUSH\tEDX\n");
3868 } else {
3869 DECODE_PRINTF("PUSH\tDX\n");
3871 TRACE_AND_STEP();
3872 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3873 push_long(M.x86.R_EDX);
3874 } else {
3875 push_word(M.x86.R_DX);
3877 DECODE_CLEAR_SEGOVR();
3878 END_OF_INSTR();
3881 /****************************************************************************
3882 REMARKS:
3883 Handles opcode 0x53
3884 ****************************************************************************/
3885 static void x86emuOp_push_BX(u8 X86EMU_UNUSED(op1))
3887 START_OF_INSTR();
3888 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3889 DECODE_PRINTF("PUSH\tEBX\n");
3890 } else {
3891 DECODE_PRINTF("PUSH\tBX\n");
3893 TRACE_AND_STEP();
3894 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3895 push_long(M.x86.R_EBX);
3896 } else {
3897 push_word(M.x86.R_BX);
3899 DECODE_CLEAR_SEGOVR();
3900 END_OF_INSTR();
3903 /****************************************************************************
3904 REMARKS:
3905 Handles opcode 0x54
3906 ****************************************************************************/
3907 static void x86emuOp_push_SP(u8 X86EMU_UNUSED(op1))
3909 START_OF_INSTR();
3910 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3911 DECODE_PRINTF("PUSH\tESP\n");
3912 } else {
3913 DECODE_PRINTF("PUSH\tSP\n");
3915 TRACE_AND_STEP();
3916 /* Always push (E)SP, since we are emulating an i386 and above
3917 * processor. This is necessary as some BIOS'es use this to check
3918 * what type of processor is in the system.
3920 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3921 push_long(M.x86.R_ESP);
3922 } else {
3923 push_word((u16)(M.x86.R_SP));
3925 DECODE_CLEAR_SEGOVR();
3926 END_OF_INSTR();
3929 /****************************************************************************
3930 REMARKS:
3931 Handles opcode 0x55
3932 ****************************************************************************/
3933 static void x86emuOp_push_BP(u8 X86EMU_UNUSED(op1))
3935 START_OF_INSTR();
3936 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3937 DECODE_PRINTF("PUSH\tEBP\n");
3938 } else {
3939 DECODE_PRINTF("PUSH\tBP\n");
3941 TRACE_AND_STEP();
3942 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3943 push_long(M.x86.R_EBP);
3944 } else {
3945 push_word(M.x86.R_BP);
3947 DECODE_CLEAR_SEGOVR();
3948 END_OF_INSTR();
3951 /****************************************************************************
3952 REMARKS:
3953 Handles opcode 0x56
3954 ****************************************************************************/
3955 static void x86emuOp_push_SI(u8 X86EMU_UNUSED(op1))
3957 START_OF_INSTR();
3958 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3959 DECODE_PRINTF("PUSH\tESI\n");
3960 } else {
3961 DECODE_PRINTF("PUSH\tSI\n");
3963 TRACE_AND_STEP();
3964 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3965 push_long(M.x86.R_ESI);
3966 } else {
3967 push_word(M.x86.R_SI);
3969 DECODE_CLEAR_SEGOVR();
3970 END_OF_INSTR();
3973 /****************************************************************************
3974 REMARKS:
3975 Handles opcode 0x57
3976 ****************************************************************************/
3977 static void x86emuOp_push_DI(u8 X86EMU_UNUSED(op1))
3979 START_OF_INSTR();
3980 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3981 DECODE_PRINTF("PUSH\tEDI\n");
3982 } else {
3983 DECODE_PRINTF("PUSH\tDI\n");
3985 TRACE_AND_STEP();
3986 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3987 push_long(M.x86.R_EDI);
3988 } else {
3989 push_word(M.x86.R_DI);
3991 DECODE_CLEAR_SEGOVR();
3992 END_OF_INSTR();
3995 /****************************************************************************
3996 REMARKS:
3997 Handles opcode 0x58
3998 ****************************************************************************/
3999 static void x86emuOp_pop_AX(u8 X86EMU_UNUSED(op1))
4001 START_OF_INSTR();
4002 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4003 DECODE_PRINTF("POP\tEAX\n");
4004 } else {
4005 DECODE_PRINTF("POP\tAX\n");
4007 TRACE_AND_STEP();
4008 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4009 M.x86.R_EAX = pop_long();
4010 } else {
4011 M.x86.R_AX = pop_word();
4013 DECODE_CLEAR_SEGOVR();
4014 END_OF_INSTR();
4017 /****************************************************************************
4018 REMARKS:
4019 Handles opcode 0x59
4020 ****************************************************************************/
4021 static void x86emuOp_pop_CX(u8 X86EMU_UNUSED(op1))
4023 START_OF_INSTR();
4024 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4025 DECODE_PRINTF("POP\tECX\n");
4026 } else {
4027 DECODE_PRINTF("POP\tCX\n");
4029 TRACE_AND_STEP();
4030 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4031 M.x86.R_ECX = pop_long();
4032 } else {
4033 M.x86.R_CX = pop_word();
4035 DECODE_CLEAR_SEGOVR();
4036 END_OF_INSTR();
4039 /****************************************************************************
4040 REMARKS:
4041 Handles opcode 0x5a
4042 ****************************************************************************/
4043 static void x86emuOp_pop_DX(u8 X86EMU_UNUSED(op1))
4045 START_OF_INSTR();
4046 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4047 DECODE_PRINTF("POP\tEDX\n");
4048 } else {
4049 DECODE_PRINTF("POP\tDX\n");
4051 TRACE_AND_STEP();
4052 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4053 M.x86.R_EDX = pop_long();
4054 } else {
4055 M.x86.R_DX = pop_word();
4057 DECODE_CLEAR_SEGOVR();
4058 END_OF_INSTR();
4061 /****************************************************************************
4062 REMARKS:
4063 Handles opcode 0x5b
4064 ****************************************************************************/
4065 static void x86emuOp_pop_BX(u8 X86EMU_UNUSED(op1))
4067 START_OF_INSTR();
4068 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4069 DECODE_PRINTF("POP\tEBX\n");
4070 } else {
4071 DECODE_PRINTF("POP\tBX\n");
4073 TRACE_AND_STEP();
4074 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4075 M.x86.R_EBX = pop_long();
4076 } else {
4077 M.x86.R_BX = pop_word();
4079 DECODE_CLEAR_SEGOVR();
4080 END_OF_INSTR();
4083 /****************************************************************************
4084 REMARKS:
4085 Handles opcode 0x5c
4086 ****************************************************************************/
4087 static void x86emuOp_pop_SP(u8 X86EMU_UNUSED(op1))
4089 START_OF_INSTR();
4090 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4091 DECODE_PRINTF("POP\tESP\n");
4092 } else {
4093 DECODE_PRINTF("POP\tSP\n");
4095 TRACE_AND_STEP();
4096 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4097 M.x86.R_ESP = pop_long();
4098 } else {
4099 M.x86.R_SP = pop_word();
4101 DECODE_CLEAR_SEGOVR();
4102 END_OF_INSTR();
4105 /****************************************************************************
4106 REMARKS:
4107 Handles opcode 0x5d
4108 ****************************************************************************/
4109 static void x86emuOp_pop_BP(u8 X86EMU_UNUSED(op1))
4111 START_OF_INSTR();
4112 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4113 DECODE_PRINTF("POP\tEBP\n");
4114 } else {
4115 DECODE_PRINTF("POP\tBP\n");
4117 TRACE_AND_STEP();
4118 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4119 M.x86.R_EBP = pop_long();
4120 } else {
4121 M.x86.R_BP = pop_word();
4123 DECODE_CLEAR_SEGOVR();
4124 END_OF_INSTR();
4127 /****************************************************************************
4128 REMARKS:
4129 Handles opcode 0x5e
4130 ****************************************************************************/
4131 static void x86emuOp_pop_SI(u8 X86EMU_UNUSED(op1))
4133 START_OF_INSTR();
4134 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4135 DECODE_PRINTF("POP\tESI\n");
4136 } else {
4137 DECODE_PRINTF("POP\tSI\n");
4139 TRACE_AND_STEP();
4140 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4141 M.x86.R_ESI = pop_long();
4142 } else {
4143 M.x86.R_SI = pop_word();
4145 DECODE_CLEAR_SEGOVR();
4146 END_OF_INSTR();
4149 /****************************************************************************
4150 REMARKS:
4151 Handles opcode 0x5f
4152 ****************************************************************************/
4153 static void x86emuOp_pop_DI(u8 X86EMU_UNUSED(op1))
4155 START_OF_INSTR();
4156 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4157 DECODE_PRINTF("POP\tEDI\n");
4158 } else {
4159 DECODE_PRINTF("POP\tDI\n");
4161 TRACE_AND_STEP();
4162 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4163 M.x86.R_EDI = pop_long();
4164 } else {
4165 M.x86.R_DI = pop_word();
4167 DECODE_CLEAR_SEGOVR();
4168 END_OF_INSTR();
4171 /****************************************************************************
4172 REMARKS:
4173 Handles opcode 0x60
4174 ****************************************************************************/
4175 static void x86emuOp_push_all(u8 X86EMU_UNUSED(op1))
4177 START_OF_INSTR();
4178 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4179 DECODE_PRINTF("PUSHAD\n");
4180 } else {
4181 DECODE_PRINTF("PUSHA\n");
4183 TRACE_AND_STEP();
4184 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4185 u32 old_sp = M.x86.R_ESP;
4187 push_long(M.x86.R_EAX);
4188 push_long(M.x86.R_ECX);
4189 push_long(M.x86.R_EDX);
4190 push_long(M.x86.R_EBX);
4191 push_long(old_sp);
4192 push_long(M.x86.R_EBP);
4193 push_long(M.x86.R_ESI);
4194 push_long(M.x86.R_EDI);
4195 } else {
4196 u16 old_sp = M.x86.R_SP;
4198 push_word(M.x86.R_AX);
4199 push_word(M.x86.R_CX);
4200 push_word(M.x86.R_DX);
4201 push_word(M.x86.R_BX);
4202 push_word(old_sp);
4203 push_word(M.x86.R_BP);
4204 push_word(M.x86.R_SI);
4205 push_word(M.x86.R_DI);
4207 DECODE_CLEAR_SEGOVR();
4208 END_OF_INSTR();
4211 /****************************************************************************
4212 REMARKS:
4213 Handles opcode 0x61
4214 ****************************************************************************/
4215 static void x86emuOp_pop_all(u8 X86EMU_UNUSED(op1))
4217 START_OF_INSTR();
4218 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4219 DECODE_PRINTF("POPAD\n");
4220 } else {
4221 DECODE_PRINTF("POPA\n");
4223 TRACE_AND_STEP();
4224 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4225 M.x86.R_EDI = pop_long();
4226 M.x86.R_ESI = pop_long();
4227 M.x86.R_EBP = pop_long();
4228 M.x86.R_ESP += 4; /* skip ESP */
4229 M.x86.R_EBX = pop_long();
4230 M.x86.R_EDX = pop_long();
4231 M.x86.R_ECX = pop_long();
4232 M.x86.R_EAX = pop_long();
4233 } else {
4234 M.x86.R_DI = pop_word();
4235 M.x86.R_SI = pop_word();
4236 M.x86.R_BP = pop_word();
4237 M.x86.R_SP += 2; /* skip SP */
4238 M.x86.R_BX = pop_word();
4239 M.x86.R_DX = pop_word();
4240 M.x86.R_CX = pop_word();
4241 M.x86.R_AX = pop_word();
4243 DECODE_CLEAR_SEGOVR();
4244 END_OF_INSTR();
4247 /*opcode 0x62 ILLEGAL OP, calls x86emuOp_illegal_op() */
4248 /*opcode 0x63 ILLEGAL OP, calls x86emuOp_illegal_op() */
4250 /****************************************************************************
4251 REMARKS:
4252 Handles opcode 0x64
4253 ****************************************************************************/
4254 static void x86emuOp_segovr_FS(u8 X86EMU_UNUSED(op1))
4256 START_OF_INSTR();
4257 DECODE_PRINTF("FS:\n");
4258 TRACE_AND_STEP();
4259 M.x86.mode |= SYSMODE_SEGOVR_FS;
4261 * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
4262 * opcode subroutines we do not want to do this.
4264 END_OF_INSTR();
4267 /****************************************************************************
4268 REMARKS:
4269 Handles opcode 0x65
4270 ****************************************************************************/
4271 static void x86emuOp_segovr_GS(u8 X86EMU_UNUSED(op1))
4273 START_OF_INSTR();
4274 DECODE_PRINTF("GS:\n");
4275 TRACE_AND_STEP();
4276 M.x86.mode |= SYSMODE_SEGOVR_GS;
4278 * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
4279 * opcode subroutines we do not want to do this.
4281 END_OF_INSTR();
4284 /****************************************************************************
4285 REMARKS:
4286 Handles opcode 0x66 - prefix for 32-bit register
4287 ****************************************************************************/
4288 static void x86emuOp_prefix_data(u8 X86EMU_UNUSED(op1))
4290 START_OF_INSTR();
4291 DECODE_PRINTF("DATA:\n");
4292 TRACE_AND_STEP();
4293 M.x86.mode |= SYSMODE_PREFIX_DATA;
4294 /* note no DECODE_CLEAR_SEGOVR here. */
4295 END_OF_INSTR();
4298 /****************************************************************************
4299 REMARKS:
4300 Handles opcode 0x67 - prefix for 32-bit address
4301 ****************************************************************************/
4302 static void x86emuOp_prefix_addr(u8 X86EMU_UNUSED(op1))
4304 START_OF_INSTR();
4305 DECODE_PRINTF("ADDR:\n");
4306 TRACE_AND_STEP();
4307 M.x86.mode |= SYSMODE_PREFIX_ADDR;
4308 /* note no DECODE_CLEAR_SEGOVR here. */
4309 END_OF_INSTR();
4312 /****************************************************************************
4313 REMARKS:
4314 Handles opcode 0x68
4315 ****************************************************************************/
4316 static void x86emuOp_push_word_IMM(u8 X86EMU_UNUSED(op1))
4318 u32 imm;
4320 START_OF_INSTR();
4321 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4322 imm = fetch_long_imm();
4323 } else {
4324 imm = fetch_word_imm();
4326 DECODE_PRINTF2("PUSH\t%x\n", imm);
4327 TRACE_AND_STEP();
4328 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4329 push_long(imm);
4330 } else {
4331 push_word((u16)imm);
4333 DECODE_CLEAR_SEGOVR();
4334 END_OF_INSTR();
4337 /****************************************************************************
4338 REMARKS:
4339 Handles opcode 0x69
4340 ****************************************************************************/
4341 static void x86emuOp_imul_word_IMM(u8 X86EMU_UNUSED(op1))
4343 int mod, rl, rh;
4344 uint srcoffset;
4346 START_OF_INSTR();
4347 DECODE_PRINTF("IMUL\t");
4348 FETCH_DECODE_MODRM(mod, rh, rl);
4349 switch (mod) {
4350 case 0:
4351 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4352 u32 *destreg;
4353 u32 srcval;
4354 u32 res_lo,res_hi;
4355 s32 imm;
4357 destreg = DECODE_RM_LONG_REGISTER(rh);
4358 DECODE_PRINTF(",");
4359 srcoffset = decode_rm00_address(rl);
4360 srcval = fetch_data_long(srcoffset);
4361 imm = fetch_long_imm();
4362 DECODE_PRINTF2(",%d\n", (s32)imm);
4363 TRACE_AND_STEP();
4364 imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
4365 if (res_hi != 0) {
4366 SET_FLAG(F_CF);
4367 SET_FLAG(F_OF);
4368 } else {
4369 CLEAR_FLAG(F_CF);
4370 CLEAR_FLAG(F_OF);
4372 *destreg = (u32)res_lo;
4373 } else {
4374 u16 *destreg;
4375 u16 srcval;
4376 u32 res;
4377 s16 imm;
4379 destreg = DECODE_RM_WORD_REGISTER(rh);
4380 DECODE_PRINTF(",");
4381 srcoffset = decode_rm00_address(rl);
4382 srcval = fetch_data_word(srcoffset);
4383 imm = fetch_word_imm();
4384 DECODE_PRINTF2(",%d\n", (s32)imm);
4385 TRACE_AND_STEP();
4386 res = (s16)srcval * (s16)imm;
4387 if (res > 0xFFFF) {
4388 SET_FLAG(F_CF);
4389 SET_FLAG(F_OF);
4390 } else {
4391 CLEAR_FLAG(F_CF);
4392 CLEAR_FLAG(F_OF);
4394 *destreg = (u16)res;
4396 break;
4397 case 1:
4398 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4399 u32 *destreg;
4400 u32 srcval;
4401 u32 res_lo,res_hi;
4402 s32 imm;
4404 destreg = DECODE_RM_LONG_REGISTER(rh);
4405 DECODE_PRINTF(",");
4406 srcoffset = decode_rm01_address(rl);
4407 srcval = fetch_data_long(srcoffset);
4408 imm = fetch_long_imm();
4409 DECODE_PRINTF2(",%d\n", (s32)imm);
4410 TRACE_AND_STEP();
4411 imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
4412 if (res_hi != 0) {
4413 SET_FLAG(F_CF);
4414 SET_FLAG(F_OF);
4415 } else {
4416 CLEAR_FLAG(F_CF);
4417 CLEAR_FLAG(F_OF);
4419 *destreg = (u32)res_lo;
4420 } else {
4421 u16 *destreg;
4422 u16 srcval;
4423 u32 res;
4424 s16 imm;
4426 destreg = DECODE_RM_WORD_REGISTER(rh);
4427 DECODE_PRINTF(",");
4428 srcoffset = decode_rm01_address(rl);
4429 srcval = fetch_data_word(srcoffset);
4430 imm = fetch_word_imm();
4431 DECODE_PRINTF2(",%d\n", (s32)imm);
4432 TRACE_AND_STEP();
4433 res = (s16)srcval * (s16)imm;
4434 if (res > 0xFFFF) {
4435 SET_FLAG(F_CF);
4436 SET_FLAG(F_OF);
4437 } else {
4438 CLEAR_FLAG(F_CF);
4439 CLEAR_FLAG(F_OF);
4441 *destreg = (u16)res;
4443 break;
4444 case 2:
4445 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4446 u32 *destreg;
4447 u32 srcval;
4448 u32 res_lo,res_hi;
4449 s32 imm;
4451 destreg = DECODE_RM_LONG_REGISTER(rh);
4452 DECODE_PRINTF(",");
4453 srcoffset = decode_rm10_address(rl);
4454 srcval = fetch_data_long(srcoffset);
4455 imm = fetch_long_imm();
4456 DECODE_PRINTF2(",%d\n", (s32)imm);
4457 TRACE_AND_STEP();
4458 imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
4459 if (res_hi != 0) {
4460 SET_FLAG(F_CF);
4461 SET_FLAG(F_OF);
4462 } else {
4463 CLEAR_FLAG(F_CF);
4464 CLEAR_FLAG(F_OF);
4466 *destreg = (u32)res_lo;
4467 } else {
4468 u16 *destreg;
4469 u16 srcval;
4470 u32 res;
4471 s16 imm;
4473 destreg = DECODE_RM_WORD_REGISTER(rh);
4474 DECODE_PRINTF(",");
4475 srcoffset = decode_rm10_address(rl);
4476 srcval = fetch_data_word(srcoffset);
4477 imm = fetch_word_imm();
4478 DECODE_PRINTF2(",%d\n", (s32)imm);
4479 TRACE_AND_STEP();
4480 res = (s16)srcval * (s16)imm;
4481 if (res > 0xFFFF) {
4482 SET_FLAG(F_CF);
4483 SET_FLAG(F_OF);
4484 } else {
4485 CLEAR_FLAG(F_CF);
4486 CLEAR_FLAG(F_OF);
4488 *destreg = (u16)res;
4490 break;
4491 case 3: /* register to register */
4492 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4493 u32 *destreg,*srcreg;
4494 u32 res_lo,res_hi;
4495 s32 imm;
4497 destreg = DECODE_RM_LONG_REGISTER(rh);
4498 DECODE_PRINTF(",");
4499 srcreg = DECODE_RM_LONG_REGISTER(rl);
4500 imm = fetch_long_imm();
4501 DECODE_PRINTF2(",%d\n", (s32)imm);
4502 TRACE_AND_STEP();
4503 imul_long_direct(&res_lo,&res_hi,(s32)*srcreg,(s32)imm);
4504 if (res_hi != 0) {
4505 SET_FLAG(F_CF);
4506 SET_FLAG(F_OF);
4507 } else {
4508 CLEAR_FLAG(F_CF);
4509 CLEAR_FLAG(F_OF);
4511 *destreg = (u32)res_lo;
4512 } else {
4513 u16 *destreg,*srcreg;
4514 u32 res;
4515 s16 imm;
4517 destreg = DECODE_RM_WORD_REGISTER(rh);
4518 DECODE_PRINTF(",");
4519 srcreg = DECODE_RM_WORD_REGISTER(rl);
4520 imm = fetch_word_imm();
4521 DECODE_PRINTF2(",%d\n", (s32)imm);
4522 res = (s16)*srcreg * (s16)imm;
4523 if (res > 0xFFFF) {
4524 SET_FLAG(F_CF);
4525 SET_FLAG(F_OF);
4526 } else {
4527 CLEAR_FLAG(F_CF);
4528 CLEAR_FLAG(F_OF);
4530 *destreg = (u16)res;
4532 break;
4534 DECODE_CLEAR_SEGOVR();
4535 END_OF_INSTR();
4538 /****************************************************************************
4539 REMARKS:
4540 Handles opcode 0x6a
4541 ****************************************************************************/
4542 static void x86emuOp_push_byte_IMM(u8 X86EMU_UNUSED(op1))
4544 s16 imm;
4546 START_OF_INSTR();
4547 imm = (s8)fetch_byte_imm();
4548 DECODE_PRINTF2("PUSH\t%d\n", imm);
4549 TRACE_AND_STEP();
4550 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4551 push_long((s32)imm);
4552 } else {
4553 push_word(imm);
4555 DECODE_CLEAR_SEGOVR();
4556 END_OF_INSTR();
4559 /****************************************************************************
4560 REMARKS:
4561 Handles opcode 0x6b
4562 ****************************************************************************/
4563 static void x86emuOp_imul_byte_IMM(u8 X86EMU_UNUSED(op1))
4565 int mod, rl, rh;
4566 uint srcoffset;
4567 s8 imm;
4569 START_OF_INSTR();
4570 DECODE_PRINTF("IMUL\t");
4571 FETCH_DECODE_MODRM(mod, rh, rl);
4572 switch (mod) {
4573 case 0:
4574 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4575 u32 *destreg;
4576 u32 srcval;
4577 u32 res_lo,res_hi;
4579 destreg = DECODE_RM_LONG_REGISTER(rh);
4580 DECODE_PRINTF(",");
4581 srcoffset = decode_rm00_address(rl);
4582 srcval = fetch_data_long(srcoffset);
4583 imm = fetch_byte_imm();
4584 DECODE_PRINTF2(",%d\n", (s32)imm);
4585 TRACE_AND_STEP();
4586 imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
4587 if (res_hi != 0) {
4588 SET_FLAG(F_CF);
4589 SET_FLAG(F_OF);
4590 } else {
4591 CLEAR_FLAG(F_CF);
4592 CLEAR_FLAG(F_OF);
4594 *destreg = (u32)res_lo;
4595 } else {
4596 u16 *destreg;
4597 u16 srcval;
4598 u32 res;
4600 destreg = DECODE_RM_WORD_REGISTER(rh);
4601 DECODE_PRINTF(",");
4602 srcoffset = decode_rm00_address(rl);
4603 srcval = fetch_data_word(srcoffset);
4604 imm = fetch_byte_imm();
4605 DECODE_PRINTF2(",%d\n", (s32)imm);
4606 TRACE_AND_STEP();
4607 res = (s16)srcval * (s16)imm;
4608 if (res > 0xFFFF) {
4609 SET_FLAG(F_CF);
4610 SET_FLAG(F_OF);
4611 } else {
4612 CLEAR_FLAG(F_CF);
4613 CLEAR_FLAG(F_OF);
4615 *destreg = (u16)res;
4617 break;
4618 case 1:
4619 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4620 u32 *destreg;
4621 u32 srcval;
4622 u32 res_lo,res_hi;
4624 destreg = DECODE_RM_LONG_REGISTER(rh);
4625 DECODE_PRINTF(",");
4626 srcoffset = decode_rm01_address(rl);
4627 srcval = fetch_data_long(srcoffset);
4628 imm = fetch_byte_imm();
4629 DECODE_PRINTF2(",%d\n", (s32)imm);
4630 TRACE_AND_STEP();
4631 imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
4632 if (res_hi != 0) {
4633 SET_FLAG(F_CF);
4634 SET_FLAG(F_OF);
4635 } else {
4636 CLEAR_FLAG(F_CF);
4637 CLEAR_FLAG(F_OF);
4639 *destreg = (u32)res_lo;
4640 } else {
4641 u16 *destreg;
4642 u16 srcval;
4643 u32 res;
4645 destreg = DECODE_RM_WORD_REGISTER(rh);
4646 DECODE_PRINTF(",");
4647 srcoffset = decode_rm01_address(rl);
4648 srcval = fetch_data_word(srcoffset);
4649 imm = fetch_byte_imm();
4650 DECODE_PRINTF2(",%d\n", (s32)imm);
4651 TRACE_AND_STEP();
4652 res = (s16)srcval * (s16)imm;
4653 if (res > 0xFFFF) {
4654 SET_FLAG(F_CF);
4655 SET_FLAG(F_OF);
4656 } else {
4657 CLEAR_FLAG(F_CF);
4658 CLEAR_FLAG(F_OF);
4660 *destreg = (u16)res;
4662 break;
4663 case 2:
4664 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4665 u32 *destreg;
4666 u32 srcval;
4667 u32 res_lo,res_hi;
4669 destreg = DECODE_RM_LONG_REGISTER(rh);
4670 DECODE_PRINTF(",");
4671 srcoffset = decode_rm10_address(rl);
4672 srcval = fetch_data_long(srcoffset);
4673 imm = fetch_byte_imm();
4674 DECODE_PRINTF2(",%d\n", (s32)imm);
4675 TRACE_AND_STEP();
4676 imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
4677 if (res_hi != 0) {
4678 SET_FLAG(F_CF);
4679 SET_FLAG(F_OF);
4680 } else {
4681 CLEAR_FLAG(F_CF);
4682 CLEAR_FLAG(F_OF);
4684 *destreg = (u32)res_lo;
4685 } else {
4686 u16 *destreg;
4687 u16 srcval;
4688 u32 res;
4690 destreg = DECODE_RM_WORD_REGISTER(rh);
4691 DECODE_PRINTF(",");
4692 srcoffset = decode_rm10_address(rl);
4693 srcval = fetch_data_word(srcoffset);
4694 imm = fetch_byte_imm();
4695 DECODE_PRINTF2(",%d\n", (s32)imm);
4696 TRACE_AND_STEP();
4697 res = (s16)srcval * (s16)imm;
4698 if (res > 0xFFFF) {
4699 SET_FLAG(F_CF);
4700 SET_FLAG(F_OF);
4701 } else {
4702 CLEAR_FLAG(F_CF);
4703 CLEAR_FLAG(F_OF);
4705 *destreg = (u16)res;
4707 break;
4708 case 3: /* register to register */
4709 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4710 u32 *destreg,*srcreg;
4711 u32 res_lo,res_hi;
4713 destreg = DECODE_RM_LONG_REGISTER(rh);
4714 DECODE_PRINTF(",");
4715 srcreg = DECODE_RM_LONG_REGISTER(rl);
4716 imm = fetch_byte_imm();
4717 DECODE_PRINTF2(",%d\n", (s32)imm);
4718 TRACE_AND_STEP();
4719 imul_long_direct(&res_lo,&res_hi,(s32)*srcreg,(s32)imm);
4720 if (res_hi != 0) {
4721 SET_FLAG(F_CF);
4722 SET_FLAG(F_OF);
4723 } else {
4724 CLEAR_FLAG(F_CF);
4725 CLEAR_FLAG(F_OF);
4727 *destreg = (u32)res_lo;
4728 } else {
4729 u16 *destreg,*srcreg;
4730 u32 res;
4732 destreg = DECODE_RM_WORD_REGISTER(rh);
4733 DECODE_PRINTF(",");
4734 srcreg = DECODE_RM_WORD_REGISTER(rl);
4735 imm = fetch_byte_imm();
4736 DECODE_PRINTF2(",%d\n", (s32)imm);
4737 res = (s16)*srcreg * (s16)imm;
4738 if (res > 0xFFFF) {
4739 SET_FLAG(F_CF);
4740 SET_FLAG(F_OF);
4741 } else {
4742 CLEAR_FLAG(F_CF);
4743 CLEAR_FLAG(F_OF);
4745 *destreg = (u16)res;
4747 break;
4749 DECODE_CLEAR_SEGOVR();
4750 END_OF_INSTR();
4753 /****************************************************************************
4754 REMARKS:
4755 Handles opcode 0x6c
4756 ****************************************************************************/
4757 static void x86emuOp_ins_byte(u8 X86EMU_UNUSED(op1))
4759 START_OF_INSTR();
4760 DECODE_PRINTF("INSB\n");
4761 ins(1);
4762 TRACE_AND_STEP();
4763 DECODE_CLEAR_SEGOVR();
4764 END_OF_INSTR();
4767 /****************************************************************************
4768 REMARKS:
4769 Handles opcode 0x6d
4770 ****************************************************************************/
4771 static void x86emuOp_ins_word(u8 X86EMU_UNUSED(op1))
4773 START_OF_INSTR();
4774 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4775 DECODE_PRINTF("INSD\n");
4776 ins(4);
4777 } else {
4778 DECODE_PRINTF("INSW\n");
4779 ins(2);
4781 TRACE_AND_STEP();
4782 DECODE_CLEAR_SEGOVR();
4783 END_OF_INSTR();
4786 /****************************************************************************
4787 REMARKS:
4788 Handles opcode 0x6e
4789 ****************************************************************************/
4790 static void x86emuOp_outs_byte(u8 X86EMU_UNUSED(op1))
4792 START_OF_INSTR();
4793 DECODE_PRINTF("OUTSB\n");
4794 outs(1);
4795 TRACE_AND_STEP();
4796 DECODE_CLEAR_SEGOVR();
4797 END_OF_INSTR();
4800 /****************************************************************************
4801 REMARKS:
4802 Handles opcode 0x6f
4803 ****************************************************************************/
4804 static void x86emuOp_outs_word(u8 X86EMU_UNUSED(op1))
4806 START_OF_INSTR();
4807 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4808 DECODE_PRINTF("OUTSD\n");
4809 outs(4);
4810 } else {
4811 DECODE_PRINTF("OUTSW\n");
4812 outs(2);
4814 TRACE_AND_STEP();
4815 DECODE_CLEAR_SEGOVR();
4816 END_OF_INSTR();
4819 /****************************************************************************
4820 REMARKS:
4821 Handles opcode 0x70
4822 ****************************************************************************/
4823 static void x86emuOp_jump_near_O(u8 X86EMU_UNUSED(op1))
4825 s8 offset;
4826 u16 target;
4828 /* jump to byte offset if overflow flag is set */
4829 START_OF_INSTR();
4830 DECODE_PRINTF("JO\t");
4831 offset = (s8)fetch_byte_imm();
4832 target = (u16)(M.x86.R_IP + (s16)offset);
4833 DECODE_PRINTF2("%x\n", target);
4834 TRACE_AND_STEP();
4835 if (ACCESS_FLAG(F_OF))
4836 M.x86.R_IP = target;
4837 DECODE_CLEAR_SEGOVR();
4838 END_OF_INSTR();
4841 /****************************************************************************
4842 REMARKS:
4843 Handles opcode 0x71
4844 ****************************************************************************/
4845 static void x86emuOp_jump_near_NO(u8 X86EMU_UNUSED(op1))
4847 s8 offset;
4848 u16 target;
4850 /* jump to byte offset if overflow is not set */
4851 START_OF_INSTR();
4852 DECODE_PRINTF("JNO\t");
4853 offset = (s8)fetch_byte_imm();
4854 target = (u16)(M.x86.R_IP + (s16)offset);
4855 DECODE_PRINTF2("%x\n", target);
4856 TRACE_AND_STEP();
4857 if (!ACCESS_FLAG(F_OF))
4858 M.x86.R_IP = target;
4859 DECODE_CLEAR_SEGOVR();
4860 END_OF_INSTR();
4863 /****************************************************************************
4864 REMARKS:
4865 Handles opcode 0x72
4866 ****************************************************************************/
4867 static void x86emuOp_jump_near_B(u8 X86EMU_UNUSED(op1))
4869 s8 offset;
4870 u16 target;
4872 /* jump to byte offset if carry flag is set. */
4873 START_OF_INSTR();
4874 DECODE_PRINTF("JB\t");
4875 offset = (s8)fetch_byte_imm();
4876 target = (u16)(M.x86.R_IP + (s16)offset);
4877 DECODE_PRINTF2("%x\n", target);
4878 TRACE_AND_STEP();
4879 if (ACCESS_FLAG(F_CF))
4880 M.x86.R_IP = target;
4881 DECODE_CLEAR_SEGOVR();
4882 END_OF_INSTR();
4885 /****************************************************************************
4886 REMARKS:
4887 Handles opcode 0x73
4888 ****************************************************************************/
4889 static void x86emuOp_jump_near_NB(u8 X86EMU_UNUSED(op1))
4891 s8 offset;
4892 u16 target;
4894 /* jump to byte offset if carry flag is clear. */
4895 START_OF_INSTR();
4896 DECODE_PRINTF("JNB\t");
4897 offset = (s8)fetch_byte_imm();
4898 target = (u16)(M.x86.R_IP + (s16)offset);
4899 DECODE_PRINTF2("%x\n", target);
4900 TRACE_AND_STEP();
4901 if (!ACCESS_FLAG(F_CF))
4902 M.x86.R_IP = target;
4903 DECODE_CLEAR_SEGOVR();
4904 END_OF_INSTR();
4907 /****************************************************************************
4908 REMARKS:
4909 Handles opcode 0x74
4910 ****************************************************************************/
4911 static void x86emuOp_jump_near_Z(u8 X86EMU_UNUSED(op1))
4913 s8 offset;
4914 u16 target;
4916 /* jump to byte offset if zero flag is set. */
4917 START_OF_INSTR();
4918 DECODE_PRINTF("JZ\t");
4919 offset = (s8)fetch_byte_imm();
4920 target = (u16)(M.x86.R_IP + (s16)offset);
4921 DECODE_PRINTF2("%x\n", target);
4922 TRACE_AND_STEP();
4923 if (ACCESS_FLAG(F_ZF))
4924 M.x86.R_IP = target;
4925 DECODE_CLEAR_SEGOVR();
4926 END_OF_INSTR();
4929 /****************************************************************************
4930 REMARKS:
4931 Handles opcode 0x75
4932 ****************************************************************************/
4933 static void x86emuOp_jump_near_NZ(u8 X86EMU_UNUSED(op1))
4935 s8 offset;
4936 u16 target;
4938 /* jump to byte offset if zero flag is clear. */
4939 START_OF_INSTR();
4940 DECODE_PRINTF("JNZ\t");
4941 offset = (s8)fetch_byte_imm();
4942 target = (u16)(M.x86.R_IP + (s16)offset);
4943 DECODE_PRINTF2("%x\n", target);
4944 TRACE_AND_STEP();
4945 if (!ACCESS_FLAG(F_ZF))
4946 M.x86.R_IP = target;
4947 DECODE_CLEAR_SEGOVR();
4948 END_OF_INSTR();
4951 /****************************************************************************
4952 REMARKS:
4953 Handles opcode 0x76
4954 ****************************************************************************/
4955 static void x86emuOp_jump_near_BE(u8 X86EMU_UNUSED(op1))
4957 s8 offset;
4958 u16 target;
4960 /* jump to byte offset if carry flag is set or if the zero
4961 flag is set. */
4962 START_OF_INSTR();
4963 DECODE_PRINTF("JBE\t");
4964 offset = (s8)fetch_byte_imm();
4965 target = (u16)(M.x86.R_IP + (s16)offset);
4966 DECODE_PRINTF2("%x\n", target);
4967 TRACE_AND_STEP();
4968 if (ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF))
4969 M.x86.R_IP = target;
4970 DECODE_CLEAR_SEGOVR();
4971 END_OF_INSTR();
4974 /****************************************************************************
4975 REMARKS:
4976 Handles opcode 0x77
4977 ****************************************************************************/
4978 static void x86emuOp_jump_near_NBE(u8 X86EMU_UNUSED(op1))
4980 s8 offset;
4981 u16 target;
4983 /* jump to byte offset if carry flag is clear and if the zero
4984 flag is clear */
4985 START_OF_INSTR();
4986 DECODE_PRINTF("JNBE\t");
4987 offset = (s8)fetch_byte_imm();
4988 target = (u16)(M.x86.R_IP + (s16)offset);
4989 DECODE_PRINTF2("%x\n", target);
4990 TRACE_AND_STEP();
4991 if (!(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF)))
4992 M.x86.R_IP = target;
4993 DECODE_CLEAR_SEGOVR();
4994 END_OF_INSTR();
4997 /****************************************************************************
4998 REMARKS:
4999 Handles opcode 0x78
5000 ****************************************************************************/
5001 static void x86emuOp_jump_near_S(u8 X86EMU_UNUSED(op1))
5003 s8 offset;
5004 u16 target;
5006 /* jump to byte offset if sign flag is set */
5007 START_OF_INSTR();
5008 DECODE_PRINTF("JS\t");
5009 offset = (s8)fetch_byte_imm();
5010 target = (u16)(M.x86.R_IP + (s16)offset);
5011 DECODE_PRINTF2("%x\n", target);
5012 TRACE_AND_STEP();
5013 if (ACCESS_FLAG(F_SF))
5014 M.x86.R_IP = target;
5015 DECODE_CLEAR_SEGOVR();
5016 END_OF_INSTR();
5019 /****************************************************************************
5020 REMARKS:
5021 Handles opcode 0x79
5022 ****************************************************************************/
5023 static void x86emuOp_jump_near_NS(u8 X86EMU_UNUSED(op1))
5025 s8 offset;
5026 u16 target;
5028 /* jump to byte offset if sign flag is clear */
5029 START_OF_INSTR();
5030 DECODE_PRINTF("JNS\t");
5031 offset = (s8)fetch_byte_imm();
5032 target = (u16)(M.x86.R_IP + (s16)offset);
5033 DECODE_PRINTF2("%x\n", target);
5034 TRACE_AND_STEP();
5035 if (!ACCESS_FLAG(F_SF))
5036 M.x86.R_IP = target;
5037 DECODE_CLEAR_SEGOVR();
5038 END_OF_INSTR();
5041 /****************************************************************************
5042 REMARKS:
5043 Handles opcode 0x7a
5044 ****************************************************************************/
5045 static void x86emuOp_jump_near_P(u8 X86EMU_UNUSED(op1))
5047 s8 offset;
5048 u16 target;
5050 /* jump to byte offset if parity flag is set (even parity) */
5051 START_OF_INSTR();
5052 DECODE_PRINTF("JP\t");
5053 offset = (s8)fetch_byte_imm();
5054 target = (u16)(M.x86.R_IP + (s16)offset);
5055 DECODE_PRINTF2("%x\n", target);
5056 TRACE_AND_STEP();
5057 if (ACCESS_FLAG(F_PF))
5058 M.x86.R_IP = target;
5059 DECODE_CLEAR_SEGOVR();
5060 END_OF_INSTR();
5063 /****************************************************************************
5064 REMARKS:
5065 Handles opcode 0x7b
5066 ****************************************************************************/
5067 static void x86emuOp_jump_near_NP(u8 X86EMU_UNUSED(op1))
5069 s8 offset;
5070 u16 target;
5072 /* jump to byte offset if parity flag is clear (odd parity) */
5073 START_OF_INSTR();
5074 DECODE_PRINTF("JNP\t");
5075 offset = (s8)fetch_byte_imm();
5076 target = (u16)(M.x86.R_IP + (s16)offset);
5077 DECODE_PRINTF2("%x\n", target);
5078 TRACE_AND_STEP();
5079 if (!ACCESS_FLAG(F_PF))
5080 M.x86.R_IP = target;
5081 DECODE_CLEAR_SEGOVR();
5082 END_OF_INSTR();
5085 /****************************************************************************
5086 REMARKS:
5087 Handles opcode 0x7c
5088 ****************************************************************************/
5089 static void x86emuOp_jump_near_L(u8 X86EMU_UNUSED(op1))
5091 s8 offset;
5092 u16 target;
5093 int sf, of;
5095 /* jump to byte offset if sign flag not equal to overflow flag. */
5096 START_OF_INSTR();
5097 DECODE_PRINTF("JL\t");
5098 offset = (s8)fetch_byte_imm();
5099 target = (u16)(M.x86.R_IP + (s16)offset);
5100 DECODE_PRINTF2("%x\n", target);
5101 TRACE_AND_STEP();
5102 sf = ACCESS_FLAG(F_SF) != 0;
5103 of = ACCESS_FLAG(F_OF) != 0;
5104 if (sf ^ of)
5105 M.x86.R_IP = target;
5106 DECODE_CLEAR_SEGOVR();
5107 END_OF_INSTR();
5110 /****************************************************************************
5111 REMARKS:
5112 Handles opcode 0x7d
5113 ****************************************************************************/
5114 static void x86emuOp_jump_near_NL(u8 X86EMU_UNUSED(op1))
5116 s8 offset;
5117 u16 target;
5118 int sf, of;
5120 /* jump to byte offset if sign flag not equal to overflow flag. */
5121 START_OF_INSTR();
5122 DECODE_PRINTF("JNL\t");
5123 offset = (s8)fetch_byte_imm();
5124 target = (u16)(M.x86.R_IP + (s16)offset);
5125 DECODE_PRINTF2("%x\n", target);
5126 TRACE_AND_STEP();
5127 sf = ACCESS_FLAG(F_SF) != 0;
5128 of = ACCESS_FLAG(F_OF) != 0;
5129 /* note: inverse of above, but using == instead of xor. */
5130 if (sf == of)
5131 M.x86.R_IP = target;
5132 DECODE_CLEAR_SEGOVR();
5133 END_OF_INSTR();
5136 /****************************************************************************
5137 REMARKS:
5138 Handles opcode 0x7e
5139 ****************************************************************************/
5140 static void x86emuOp_jump_near_LE(u8 X86EMU_UNUSED(op1))
5142 s8 offset;
5143 u16 target;
5144 int sf, of;
5146 /* jump to byte offset if sign flag not equal to overflow flag
5147 or the zero flag is set */
5148 START_OF_INSTR();
5149 DECODE_PRINTF("JLE\t");
5150 offset = (s8)fetch_byte_imm();
5151 target = (u16)(M.x86.R_IP + (s16)offset);
5152 DECODE_PRINTF2("%x\n", target);
5153 TRACE_AND_STEP();
5154 sf = ACCESS_FLAG(F_SF) != 0;
5155 of = ACCESS_FLAG(F_OF) != 0;
5156 if ((sf ^ of) || ACCESS_FLAG(F_ZF))
5157 M.x86.R_IP = target;
5158 DECODE_CLEAR_SEGOVR();
5159 END_OF_INSTR();
5162 /****************************************************************************
5163 REMARKS:
5164 Handles opcode 0x7f
5165 ****************************************************************************/
5166 static void x86emuOp_jump_near_NLE(u8 X86EMU_UNUSED(op1))
5168 s8 offset;
5169 u16 target;
5170 int sf, of;
5172 /* jump to byte offset if sign flag equal to overflow flag.
5173 and the zero flag is clear */
5174 START_OF_INSTR();
5175 DECODE_PRINTF("JNLE\t");
5176 offset = (s8)fetch_byte_imm();
5177 target = (u16)(M.x86.R_IP + (s16)offset);
5178 DECODE_PRINTF2("%x\n", target);
5179 TRACE_AND_STEP();
5180 sf = ACCESS_FLAG(F_SF) != 0;
5181 of = ACCESS_FLAG(F_OF) != 0;
5182 if ((sf == of) && !ACCESS_FLAG(F_ZF))
5183 M.x86.R_IP = target;
5184 DECODE_CLEAR_SEGOVR();
5185 END_OF_INSTR();
5188 static u8 (*opc80_byte_operation[])(u8 d, u8 s) =
5190 add_byte, /* 00 */
5191 or_byte, /* 01 */
5192 adc_byte, /* 02 */
5193 sbb_byte, /* 03 */
5194 and_byte, /* 04 */
5195 sub_byte, /* 05 */
5196 xor_byte, /* 06 */
5197 cmp_byte, /* 07 */
5200 /****************************************************************************
5201 REMARKS:
5202 Handles opcode 0x80
5203 ****************************************************************************/
5204 static void x86emuOp_opc80_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
5206 int mod, rl, rh;
5207 u8 *destreg;
5208 uint destoffset;
5209 u8 imm;
5210 u8 destval;
5213 * Weirdo special case instruction format. Part of the opcode
5214 * held below in "RH". Doubly nested case would result, except
5215 * that the decoded instruction
5217 START_OF_INSTR();
5218 FETCH_DECODE_MODRM(mod, rh, rl);
5219 #ifdef DEBUG
5220 if (DEBUG_DECODE()) {
5221 /* XXX DECODE_PRINTF may be changed to something more
5222 general, so that it is important to leave the strings
5223 in the same format, even though the result is that the
5224 above test is done twice. */
5226 switch (rh) {
5227 case 0:
5228 DECODE_PRINTF("ADD\t");
5229 break;
5230 case 1:
5231 DECODE_PRINTF("OR\t");
5232 break;
5233 case 2:
5234 DECODE_PRINTF("ADC\t");
5235 break;
5236 case 3:
5237 DECODE_PRINTF("SBB\t");
5238 break;
5239 case 4:
5240 DECODE_PRINTF("AND\t");
5241 break;
5242 case 5:
5243 DECODE_PRINTF("SUB\t");
5244 break;
5245 case 6:
5246 DECODE_PRINTF("XOR\t");
5247 break;
5248 case 7:
5249 DECODE_PRINTF("CMP\t");
5250 break;
5253 #endif
5254 /* know operation, decode the mod byte to find the addressing
5255 mode. */
5256 switch (mod) {
5257 case 0:
5258 DECODE_PRINTF("BYTE PTR ");
5259 destoffset = decode_rm00_address(rl);
5260 DECODE_PRINTF(",");
5261 destval = fetch_data_byte(destoffset);
5262 imm = fetch_byte_imm();
5263 DECODE_PRINTF2("%x\n", imm);
5264 TRACE_AND_STEP();
5265 destval = (*opc80_byte_operation[rh]) (destval, imm);
5266 if (rh != 7)
5267 store_data_byte(destoffset, destval);
5268 break;
5269 case 1:
5270 DECODE_PRINTF("BYTE PTR ");
5271 destoffset = decode_rm01_address(rl);
5272 DECODE_PRINTF(",");
5273 destval = fetch_data_byte(destoffset);
5274 imm = fetch_byte_imm();
5275 DECODE_PRINTF2("%x\n", imm);
5276 TRACE_AND_STEP();
5277 destval = (*opc80_byte_operation[rh]) (destval, imm);
5278 if (rh != 7)
5279 store_data_byte(destoffset, destval);
5280 break;
5281 case 2:
5282 DECODE_PRINTF("BYTE PTR ");
5283 destoffset = decode_rm10_address(rl);
5284 DECODE_PRINTF(",");
5285 destval = fetch_data_byte(destoffset);
5286 imm = fetch_byte_imm();
5287 DECODE_PRINTF2("%x\n", imm);
5288 TRACE_AND_STEP();
5289 destval = (*opc80_byte_operation[rh]) (destval, imm);
5290 if (rh != 7)
5291 store_data_byte(destoffset, destval);
5292 break;
5293 case 3: /* register to register */
5294 destreg = DECODE_RM_BYTE_REGISTER(rl);
5295 DECODE_PRINTF(",");
5296 imm = fetch_byte_imm();
5297 DECODE_PRINTF2("%x\n", imm);
5298 TRACE_AND_STEP();
5299 destval = (*opc80_byte_operation[rh]) (*destreg, imm);
5300 if (rh != 7)
5301 *destreg = destval;
5302 break;
5304 DECODE_CLEAR_SEGOVR();
5305 END_OF_INSTR();
5308 static u16 (*opc81_word_operation[])(u16 d, u16 s) =
5310 add_word, /*00 */
5311 or_word, /*01 */
5312 adc_word, /*02 */
5313 sbb_word, /*03 */
5314 and_word, /*04 */
5315 sub_word, /*05 */
5316 xor_word, /*06 */
5317 cmp_word, /*07 */
5320 static u32 (*opc81_long_operation[])(u32 d, u32 s) =
5322 add_long, /*00 */
5323 or_long, /*01 */
5324 adc_long, /*02 */
5325 sbb_long, /*03 */
5326 and_long, /*04 */
5327 sub_long, /*05 */
5328 xor_long, /*06 */
5329 cmp_long, /*07 */
5332 /****************************************************************************
5333 REMARKS:
5334 Handles opcode 0x81
5335 ****************************************************************************/
5336 static void x86emuOp_opc81_word_RM_IMM(u8 X86EMU_UNUSED(op1))
5338 int mod, rl, rh;
5339 uint destoffset;
5342 * Weirdo special case instruction format. Part of the opcode
5343 * held below in "RH". Doubly nested case would result, except
5344 * that the decoded instruction
5346 START_OF_INSTR();
5347 FETCH_DECODE_MODRM(mod, rh, rl);
5348 #ifdef DEBUG
5349 if (DEBUG_DECODE()) {
5350 /* XXX DECODE_PRINTF may be changed to something more
5351 general, so that it is important to leave the strings
5352 in the same format, even though the result is that the
5353 above test is done twice. */
5355 switch (rh) {
5356 case 0:
5357 DECODE_PRINTF("ADD\t");
5358 break;
5359 case 1:
5360 DECODE_PRINTF("OR\t");
5361 break;
5362 case 2:
5363 DECODE_PRINTF("ADC\t");
5364 break;
5365 case 3:
5366 DECODE_PRINTF("SBB\t");
5367 break;
5368 case 4:
5369 DECODE_PRINTF("AND\t");
5370 break;
5371 case 5:
5372 DECODE_PRINTF("SUB\t");
5373 break;
5374 case 6:
5375 DECODE_PRINTF("XOR\t");
5376 break;
5377 case 7:
5378 DECODE_PRINTF("CMP\t");
5379 break;
5382 #endif
5384 * Know operation, decode the mod byte to find the addressing
5385 * mode.
5387 switch (mod) {
5388 case 0:
5389 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5390 u32 destval,imm;
5392 DECODE_PRINTF("DWORD PTR ");
5393 destoffset = decode_rm00_address(rl);
5394 DECODE_PRINTF(",");
5395 destval = fetch_data_long(destoffset);
5396 imm = fetch_long_imm();
5397 DECODE_PRINTF2("%x\n", imm);
5398 TRACE_AND_STEP();
5399 destval = (*opc81_long_operation[rh]) (destval, imm);
5400 if (rh != 7)
5401 store_data_long(destoffset, destval);
5402 } else {
5403 u16 destval,imm;
5405 DECODE_PRINTF("WORD PTR ");
5406 destoffset = decode_rm00_address(rl);
5407 DECODE_PRINTF(",");
5408 destval = fetch_data_word(destoffset);
5409 imm = fetch_word_imm();
5410 DECODE_PRINTF2("%x\n", imm);
5411 TRACE_AND_STEP();
5412 destval = (*opc81_word_operation[rh]) (destval, imm);
5413 if (rh != 7)
5414 store_data_word(destoffset, destval);
5416 break;
5417 case 1:
5418 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5419 u32 destval,imm;
5421 DECODE_PRINTF("DWORD PTR ");
5422 destoffset = decode_rm01_address(rl);
5423 DECODE_PRINTF(",");
5424 destval = fetch_data_long(destoffset);
5425 imm = fetch_long_imm();
5426 DECODE_PRINTF2("%x\n", imm);
5427 TRACE_AND_STEP();
5428 destval = (*opc81_long_operation[rh]) (destval, imm);
5429 if (rh != 7)
5430 store_data_long(destoffset, destval);
5431 } else {
5432 u16 destval,imm;
5434 DECODE_PRINTF("WORD PTR ");
5435 destoffset = decode_rm01_address(rl);
5436 DECODE_PRINTF(",");
5437 destval = fetch_data_word(destoffset);
5438 imm = fetch_word_imm();
5439 DECODE_PRINTF2("%x\n", imm);
5440 TRACE_AND_STEP();
5441 destval = (*opc81_word_operation[rh]) (destval, imm);
5442 if (rh != 7)
5443 store_data_word(destoffset, destval);
5445 break;
5446 case 2:
5447 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5448 u32 destval,imm;
5450 DECODE_PRINTF("DWORD PTR ");
5451 destoffset = decode_rm10_address(rl);
5452 DECODE_PRINTF(",");
5453 destval = fetch_data_long(destoffset);
5454 imm = fetch_long_imm();
5455 DECODE_PRINTF2("%x\n", imm);
5456 TRACE_AND_STEP();
5457 destval = (*opc81_long_operation[rh]) (destval, imm);
5458 if (rh != 7)
5459 store_data_long(destoffset, destval);
5460 } else {
5461 u16 destval,imm;
5463 DECODE_PRINTF("WORD PTR ");
5464 destoffset = decode_rm10_address(rl);
5465 DECODE_PRINTF(",");
5466 destval = fetch_data_word(destoffset);
5467 imm = fetch_word_imm();
5468 DECODE_PRINTF2("%x\n", imm);
5469 TRACE_AND_STEP();
5470 destval = (*opc81_word_operation[rh]) (destval, imm);
5471 if (rh != 7)
5472 store_data_word(destoffset, destval);
5474 break;
5475 case 3: /* register to register */
5476 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5477 u32 *destreg;
5478 u32 destval,imm;
5480 destreg = DECODE_RM_LONG_REGISTER(rl);
5481 DECODE_PRINTF(",");
5482 imm = fetch_long_imm();
5483 DECODE_PRINTF2("%x\n", imm);
5484 TRACE_AND_STEP();
5485 destval = (*opc81_long_operation[rh]) (*destreg, imm);
5486 if (rh != 7)
5487 *destreg = destval;
5488 } else {
5489 u16 *destreg;
5490 u16 destval,imm;
5492 destreg = DECODE_RM_WORD_REGISTER(rl);
5493 DECODE_PRINTF(",");
5494 imm = fetch_word_imm();
5495 DECODE_PRINTF2("%x\n", imm);
5496 TRACE_AND_STEP();
5497 destval = (*opc81_word_operation[rh]) (*destreg, imm);
5498 if (rh != 7)
5499 *destreg = destval;
5501 break;
5503 DECODE_CLEAR_SEGOVR();
5504 END_OF_INSTR();
5507 static u8 (*opc82_byte_operation[])(u8 s, u8 d) =
5509 add_byte, /*00 */
5510 or_byte, /*01 *//*YYY UNUSED ???? */
5511 adc_byte, /*02 */
5512 sbb_byte, /*03 */
5513 and_byte, /*04 *//*YYY UNUSED ???? */
5514 sub_byte, /*05 */
5515 xor_byte, /*06 *//*YYY UNUSED ???? */
5516 cmp_byte, /*07 */
5519 /****************************************************************************
5520 REMARKS:
5521 Handles opcode 0x82
5522 ****************************************************************************/
5523 static void x86emuOp_opc82_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
5525 int mod, rl, rh;
5526 u8 *destreg;
5527 uint destoffset;
5528 u8 imm;
5529 u8 destval;
5532 * Weirdo special case instruction format. Part of the opcode
5533 * held below in "RH". Doubly nested case would result, except
5534 * that the decoded instruction Similar to opcode 81, except that
5535 * the immediate byte is sign extended to a word length.
5537 START_OF_INSTR();
5538 FETCH_DECODE_MODRM(mod, rh, rl);
5539 #ifdef DEBUG
5540 if (DEBUG_DECODE()) {
5541 /* XXX DECODE_PRINTF may be changed to something more
5542 general, so that it is important to leave the strings
5543 in the same format, even though the result is that the
5544 above test is done twice. */
5545 switch (rh) {
5546 case 0:
5547 DECODE_PRINTF("ADD\t");
5548 break;
5549 case 1:
5550 DECODE_PRINTF("OR\t");
5551 break;
5552 case 2:
5553 DECODE_PRINTF("ADC\t");
5554 break;
5555 case 3:
5556 DECODE_PRINTF("SBB\t");
5557 break;
5558 case 4:
5559 DECODE_PRINTF("AND\t");
5560 break;
5561 case 5:
5562 DECODE_PRINTF("SUB\t");
5563 break;
5564 case 6:
5565 DECODE_PRINTF("XOR\t");
5566 break;
5567 case 7:
5568 DECODE_PRINTF("CMP\t");
5569 break;
5572 #endif
5573 /* know operation, decode the mod byte to find the addressing
5574 mode. */
5575 switch (mod) {
5576 case 0:
5577 DECODE_PRINTF("BYTE PTR ");
5578 destoffset = decode_rm00_address(rl);
5579 destval = fetch_data_byte(destoffset);
5580 imm = fetch_byte_imm();
5581 DECODE_PRINTF2(",%x\n", imm);
5582 TRACE_AND_STEP();
5583 destval = (*opc82_byte_operation[rh]) (destval, imm);
5584 if (rh != 7)
5585 store_data_byte(destoffset, destval);
5586 break;
5587 case 1:
5588 DECODE_PRINTF("BYTE PTR ");
5589 destoffset = decode_rm01_address(rl);
5590 destval = fetch_data_byte(destoffset);
5591 imm = fetch_byte_imm();
5592 DECODE_PRINTF2(",%x\n", imm);
5593 TRACE_AND_STEP();
5594 destval = (*opc82_byte_operation[rh]) (destval, imm);
5595 if (rh != 7)
5596 store_data_byte(destoffset, destval);
5597 break;
5598 case 2:
5599 DECODE_PRINTF("BYTE PTR ");
5600 destoffset = decode_rm10_address(rl);
5601 destval = fetch_data_byte(destoffset);
5602 imm = fetch_byte_imm();
5603 DECODE_PRINTF2(",%x\n", imm);
5604 TRACE_AND_STEP();
5605 destval = (*opc82_byte_operation[rh]) (destval, imm);
5606 if (rh != 7)
5607 store_data_byte(destoffset, destval);
5608 break;
5609 case 3: /* register to register */
5610 destreg = DECODE_RM_BYTE_REGISTER(rl);
5611 imm = fetch_byte_imm();
5612 DECODE_PRINTF2(",%x\n", imm);
5613 TRACE_AND_STEP();
5614 destval = (*opc82_byte_operation[rh]) (*destreg, imm);
5615 if (rh != 7)
5616 *destreg = destval;
5617 break;
5619 DECODE_CLEAR_SEGOVR();
5620 END_OF_INSTR();
5623 static u16 (*opc83_word_operation[])(u16 s, u16 d) =
5625 add_word, /*00 */
5626 or_word, /*01 *//*YYY UNUSED ???? */
5627 adc_word, /*02 */
5628 sbb_word, /*03 */
5629 and_word, /*04 *//*YYY UNUSED ???? */
5630 sub_word, /*05 */
5631 xor_word, /*06 *//*YYY UNUSED ???? */
5632 cmp_word, /*07 */
5635 static u32 (*opc83_long_operation[])(u32 s, u32 d) =
5637 add_long, /*00 */
5638 or_long, /*01 *//*YYY UNUSED ???? */
5639 adc_long, /*02 */
5640 sbb_long, /*03 */
5641 and_long, /*04 *//*YYY UNUSED ???? */
5642 sub_long, /*05 */
5643 xor_long, /*06 *//*YYY UNUSED ???? */
5644 cmp_long, /*07 */
5647 /****************************************************************************
5648 REMARKS:
5649 Handles opcode 0x83
5650 ****************************************************************************/
5651 static void x86emuOp_opc83_word_RM_IMM(u8 X86EMU_UNUSED(op1))
5653 int mod, rl, rh;
5654 uint destoffset;
5657 * Weirdo special case instruction format. Part of the opcode
5658 * held below in "RH". Doubly nested case would result, except
5659 * that the decoded instruction Similar to opcode 81, except that
5660 * the immediate byte is sign extended to a word length.
5662 START_OF_INSTR();
5663 FETCH_DECODE_MODRM(mod, rh, rl);
5664 #ifdef DEBUG
5665 if (DEBUG_DECODE()) {
5666 /* XXX DECODE_PRINTF may be changed to something more
5667 general, so that it is important to leave the strings
5668 in the same format, even though the result is that the
5669 above test is done twice. */
5670 switch (rh) {
5671 case 0:
5672 DECODE_PRINTF("ADD\t");
5673 break;
5674 case 1:
5675 DECODE_PRINTF("OR\t");
5676 break;
5677 case 2:
5678 DECODE_PRINTF("ADC\t");
5679 break;
5680 case 3:
5681 DECODE_PRINTF("SBB\t");
5682 break;
5683 case 4:
5684 DECODE_PRINTF("AND\t");
5685 break;
5686 case 5:
5687 DECODE_PRINTF("SUB\t");
5688 break;
5689 case 6:
5690 DECODE_PRINTF("XOR\t");
5691 break;
5692 case 7:
5693 DECODE_PRINTF("CMP\t");
5694 break;
5697 #endif
5698 /* know operation, decode the mod byte to find the addressing
5699 mode. */
5700 switch (mod) {
5701 case 0:
5702 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5703 u32 destval,imm;
5705 DECODE_PRINTF("DWORD PTR ");
5706 destoffset = decode_rm00_address(rl);
5707 destval = fetch_data_long(destoffset);
5708 imm = (s8) fetch_byte_imm();
5709 DECODE_PRINTF2(",%x\n", imm);
5710 TRACE_AND_STEP();
5711 destval = (*opc83_long_operation[rh]) (destval, imm);
5712 if (rh != 7)
5713 store_data_long(destoffset, destval);
5714 } else {
5715 u16 destval,imm;
5717 DECODE_PRINTF("WORD PTR ");
5718 destoffset = decode_rm00_address(rl);
5719 destval = fetch_data_word(destoffset);
5720 imm = (s8) fetch_byte_imm();
5721 DECODE_PRINTF2(",%x\n", imm);
5722 TRACE_AND_STEP();
5723 destval = (*opc83_word_operation[rh]) (destval, imm);
5724 if (rh != 7)
5725 store_data_word(destoffset, destval);
5727 break;
5728 case 1:
5729 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5730 u32 destval,imm;
5732 DECODE_PRINTF("DWORD PTR ");
5733 destoffset = decode_rm01_address(rl);
5734 destval = fetch_data_long(destoffset);
5735 imm = (s8) fetch_byte_imm();
5736 DECODE_PRINTF2(",%x\n", imm);
5737 TRACE_AND_STEP();
5738 destval = (*opc83_long_operation[rh]) (destval, imm);
5739 if (rh != 7)
5740 store_data_long(destoffset, destval);
5741 } else {
5742 u16 destval,imm;
5744 DECODE_PRINTF("WORD PTR ");
5745 destoffset = decode_rm01_address(rl);
5746 destval = fetch_data_word(destoffset);
5747 imm = (s8) fetch_byte_imm();
5748 DECODE_PRINTF2(",%x\n", imm);
5749 TRACE_AND_STEP();
5750 destval = (*opc83_word_operation[rh]) (destval, imm);
5751 if (rh != 7)
5752 store_data_word(destoffset, destval);
5754 break;
5755 case 2:
5756 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5757 u32 destval,imm;
5759 DECODE_PRINTF("DWORD PTR ");
5760 destoffset = decode_rm10_address(rl);
5761 destval = fetch_data_long(destoffset);
5762 imm = (s8) fetch_byte_imm();
5763 DECODE_PRINTF2(",%x\n", imm);
5764 TRACE_AND_STEP();
5765 destval = (*opc83_long_operation[rh]) (destval, imm);
5766 if (rh != 7)
5767 store_data_long(destoffset, destval);
5768 } else {
5769 u16 destval,imm;
5771 DECODE_PRINTF("WORD PTR ");
5772 destoffset = decode_rm10_address(rl);
5773 destval = fetch_data_word(destoffset);
5774 imm = (s8) fetch_byte_imm();
5775 DECODE_PRINTF2(",%x\n", imm);
5776 TRACE_AND_STEP();
5777 destval = (*opc83_word_operation[rh]) (destval, imm);
5778 if (rh != 7)
5779 store_data_word(destoffset, destval);
5781 break;
5782 case 3: /* register to register */
5783 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5784 u32 *destreg;
5785 u32 destval,imm;
5787 destreg = DECODE_RM_LONG_REGISTER(rl);
5788 imm = (s8) fetch_byte_imm();
5789 DECODE_PRINTF2(",%x\n", imm);
5790 TRACE_AND_STEP();
5791 destval = (*opc83_long_operation[rh]) (*destreg, imm);
5792 if (rh != 7)
5793 *destreg = destval;
5794 } else {
5795 u16 *destreg;
5796 u16 destval,imm;
5798 destreg = DECODE_RM_WORD_REGISTER(rl);
5799 imm = (s8) fetch_byte_imm();
5800 DECODE_PRINTF2(",%x\n", imm);
5801 TRACE_AND_STEP();
5802 destval = (*opc83_word_operation[rh]) (*destreg, imm);
5803 if (rh != 7)
5804 *destreg = destval;
5806 break;
5808 DECODE_CLEAR_SEGOVR();
5809 END_OF_INSTR();
5812 /****************************************************************************
5813 REMARKS:
5814 Handles opcode 0x84
5815 ****************************************************************************/
5816 static void x86emuOp_test_byte_RM_R(u8 X86EMU_UNUSED(op1))
5818 int mod, rl, rh;
5819 u8 *destreg, *srcreg;
5820 uint destoffset;
5821 u8 destval;
5823 START_OF_INSTR();
5824 DECODE_PRINTF("TEST\t");
5825 FETCH_DECODE_MODRM(mod, rh, rl);
5826 switch (mod) {
5827 case 0:
5828 destoffset = decode_rm00_address(rl);
5829 DECODE_PRINTF(",");
5830 destval = fetch_data_byte(destoffset);
5831 srcreg = DECODE_RM_BYTE_REGISTER(rh);
5832 DECODE_PRINTF("\n");
5833 TRACE_AND_STEP();
5834 test_byte(destval, *srcreg);
5835 break;
5836 case 1:
5837 destoffset = decode_rm01_address(rl);
5838 DECODE_PRINTF(",");
5839 destval = fetch_data_byte(destoffset);
5840 srcreg = DECODE_RM_BYTE_REGISTER(rh);
5841 DECODE_PRINTF("\n");
5842 TRACE_AND_STEP();
5843 test_byte(destval, *srcreg);
5844 break;
5845 case 2:
5846 destoffset = decode_rm10_address(rl);
5847 DECODE_PRINTF(",");
5848 destval = fetch_data_byte(destoffset);
5849 srcreg = DECODE_RM_BYTE_REGISTER(rh);
5850 DECODE_PRINTF("\n");
5851 TRACE_AND_STEP();
5852 test_byte(destval, *srcreg);
5853 break;
5854 case 3: /* register to register */
5855 destreg = DECODE_RM_BYTE_REGISTER(rl);
5856 DECODE_PRINTF(",");
5857 srcreg = DECODE_RM_BYTE_REGISTER(rh);
5858 DECODE_PRINTF("\n");
5859 TRACE_AND_STEP();
5860 test_byte(*destreg, *srcreg);
5861 break;
5863 DECODE_CLEAR_SEGOVR();
5864 END_OF_INSTR();
5867 /****************************************************************************
5868 REMARKS:
5869 Handles opcode 0x85
5870 ****************************************************************************/
5871 static void x86emuOp_test_word_RM_R(u8 X86EMU_UNUSED(op1))
5873 int mod, rl, rh;
5874 uint destoffset;
5876 START_OF_INSTR();
5877 DECODE_PRINTF("TEST\t");
5878 FETCH_DECODE_MODRM(mod, rh, rl);
5879 switch (mod) {
5880 case 0:
5881 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5882 u32 destval;
5883 u32 *srcreg;
5885 destoffset = decode_rm00_address(rl);
5886 DECODE_PRINTF(",");
5887 destval = fetch_data_long(destoffset);
5888 srcreg = DECODE_RM_LONG_REGISTER(rh);
5889 DECODE_PRINTF("\n");
5890 TRACE_AND_STEP();
5891 test_long(destval, *srcreg);
5892 } else {
5893 u16 destval;
5894 u16 *srcreg;
5896 destoffset = decode_rm00_address(rl);
5897 DECODE_PRINTF(",");
5898 destval = fetch_data_word(destoffset);
5899 srcreg = DECODE_RM_WORD_REGISTER(rh);
5900 DECODE_PRINTF("\n");
5901 TRACE_AND_STEP();
5902 test_word(destval, *srcreg);
5904 break;
5905 case 1:
5906 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5907 u32 destval;
5908 u32 *srcreg;
5910 destoffset = decode_rm01_address(rl);
5911 DECODE_PRINTF(",");
5912 destval = fetch_data_long(destoffset);
5913 srcreg = DECODE_RM_LONG_REGISTER(rh);
5914 DECODE_PRINTF("\n");
5915 TRACE_AND_STEP();
5916 test_long(destval, *srcreg);
5917 } else {
5918 u16 destval;
5919 u16 *srcreg;
5921 destoffset = decode_rm01_address(rl);
5922 DECODE_PRINTF(",");
5923 destval = fetch_data_word(destoffset);
5924 srcreg = DECODE_RM_WORD_REGISTER(rh);
5925 DECODE_PRINTF("\n");
5926 TRACE_AND_STEP();
5927 test_word(destval, *srcreg);
5929 break;
5930 case 2:
5931 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5932 u32 destval;
5933 u32 *srcreg;
5935 destoffset = decode_rm10_address(rl);
5936 DECODE_PRINTF(",");
5937 destval = fetch_data_long(destoffset);
5938 srcreg = DECODE_RM_LONG_REGISTER(rh);
5939 DECODE_PRINTF("\n");
5940 TRACE_AND_STEP();
5941 test_long(destval, *srcreg);
5942 } else {
5943 u16 destval;
5944 u16 *srcreg;
5946 destoffset = decode_rm10_address(rl);
5947 DECODE_PRINTF(",");
5948 destval = fetch_data_word(destoffset);
5949 srcreg = DECODE_RM_WORD_REGISTER(rh);
5950 DECODE_PRINTF("\n");
5951 TRACE_AND_STEP();
5952 test_word(destval, *srcreg);
5954 break;
5955 case 3: /* register to register */
5956 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5957 u32 *destreg,*srcreg;
5959 destreg = DECODE_RM_LONG_REGISTER(rl);
5960 DECODE_PRINTF(",");
5961 srcreg = DECODE_RM_LONG_REGISTER(rh);
5962 DECODE_PRINTF("\n");
5963 TRACE_AND_STEP();
5964 test_long(*destreg, *srcreg);
5965 } else {
5966 u16 *destreg,*srcreg;
5968 destreg = DECODE_RM_WORD_REGISTER(rl);
5969 DECODE_PRINTF(",");
5970 srcreg = DECODE_RM_WORD_REGISTER(rh);
5971 DECODE_PRINTF("\n");
5972 TRACE_AND_STEP();
5973 test_word(*destreg, *srcreg);
5975 break;
5977 DECODE_CLEAR_SEGOVR();
5978 END_OF_INSTR();
5981 /****************************************************************************
5982 REMARKS:
5983 Handles opcode 0x86
5984 ****************************************************************************/
5985 static void x86emuOp_xchg_byte_RM_R(u8 X86EMU_UNUSED(op1))
5987 int mod, rl, rh;
5988 u8 *destreg, *srcreg;
5989 uint destoffset;
5990 u8 destval;
5991 u8 tmp;
5993 START_OF_INSTR();
5994 DECODE_PRINTF("XCHG\t");
5995 FETCH_DECODE_MODRM(mod, rh, rl);
5996 switch (mod) {
5997 case 0:
5998 destoffset = decode_rm00_address(rl);
5999 DECODE_PRINTF(",");
6000 destval = fetch_data_byte(destoffset);
6001 srcreg = DECODE_RM_BYTE_REGISTER(rh);
6002 DECODE_PRINTF("\n");
6003 TRACE_AND_STEP();
6004 tmp = *srcreg;
6005 *srcreg = destval;
6006 destval = tmp;
6007 store_data_byte(destoffset, destval);
6008 break;
6009 case 1:
6010 destoffset = decode_rm01_address(rl);
6011 DECODE_PRINTF(",");
6012 destval = fetch_data_byte(destoffset);
6013 srcreg = DECODE_RM_BYTE_REGISTER(rh);
6014 DECODE_PRINTF("\n");
6015 TRACE_AND_STEP();
6016 tmp = *srcreg;
6017 *srcreg = destval;
6018 destval = tmp;
6019 store_data_byte(destoffset, destval);
6020 break;
6021 case 2:
6022 destoffset = decode_rm10_address(rl);
6023 DECODE_PRINTF(",");
6024 destval = fetch_data_byte(destoffset);
6025 srcreg = DECODE_RM_BYTE_REGISTER(rh);
6026 DECODE_PRINTF("\n");
6027 TRACE_AND_STEP();
6028 tmp = *srcreg;
6029 *srcreg = destval;
6030 destval = tmp;
6031 store_data_byte(destoffset, destval);
6032 break;
6033 case 3: /* register to register */
6034 destreg = DECODE_RM_BYTE_REGISTER(rl);
6035 DECODE_PRINTF(",");
6036 srcreg = DECODE_RM_BYTE_REGISTER(rh);
6037 DECODE_PRINTF("\n");
6038 TRACE_AND_STEP();
6039 tmp = *srcreg;
6040 *srcreg = *destreg;
6041 *destreg = tmp;
6042 break;
6044 DECODE_CLEAR_SEGOVR();
6045 END_OF_INSTR();
6048 /****************************************************************************
6049 REMARKS:
6050 Handles opcode 0x87
6051 ****************************************************************************/
6052 static void x86emuOp_xchg_word_RM_R(u8 X86EMU_UNUSED(op1))
6054 int mod, rl, rh;
6055 uint destoffset;
6057 START_OF_INSTR();
6058 DECODE_PRINTF("XCHG\t");
6059 FETCH_DECODE_MODRM(mod, rh, rl);
6060 switch (mod) {
6061 case 0:
6062 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6063 u32 *srcreg;
6064 u32 destval,tmp;
6066 destoffset = decode_rm00_address(rl);
6067 DECODE_PRINTF(",");
6068 destval = fetch_data_long(destoffset);
6069 srcreg = DECODE_RM_LONG_REGISTER(rh);
6070 DECODE_PRINTF("\n");
6071 TRACE_AND_STEP();
6072 tmp = *srcreg;
6073 *srcreg = destval;
6074 destval = tmp;
6075 store_data_long(destoffset, destval);
6076 } else {
6077 u16 *srcreg;
6078 u16 destval,tmp;
6080 destoffset = decode_rm00_address(rl);
6081 DECODE_PRINTF(",");
6082 destval = fetch_data_word(destoffset);
6083 srcreg = DECODE_RM_WORD_REGISTER(rh);
6084 DECODE_PRINTF("\n");
6085 TRACE_AND_STEP();
6086 tmp = *srcreg;
6087 *srcreg = destval;
6088 destval = tmp;
6089 store_data_word(destoffset, destval);
6091 break;
6092 case 1:
6093 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6094 u32 *srcreg;
6095 u32 destval,tmp;
6097 destoffset = decode_rm01_address(rl);
6098 DECODE_PRINTF(",");
6099 destval = fetch_data_long(destoffset);
6100 srcreg = DECODE_RM_LONG_REGISTER(rh);
6101 DECODE_PRINTF("\n");
6102 TRACE_AND_STEP();
6103 tmp = *srcreg;
6104 *srcreg = destval;
6105 destval = tmp;
6106 store_data_long(destoffset, destval);
6107 } else {
6108 u16 *srcreg;
6109 u16 destval,tmp;
6111 destoffset = decode_rm01_address(rl);
6112 DECODE_PRINTF(",");
6113 destval = fetch_data_word(destoffset);
6114 srcreg = DECODE_RM_WORD_REGISTER(rh);
6115 DECODE_PRINTF("\n");
6116 TRACE_AND_STEP();
6117 tmp = *srcreg;
6118 *srcreg = destval;
6119 destval = tmp;
6120 store_data_word(destoffset, destval);
6122 break;
6123 case 2:
6124 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6125 u32 *srcreg;
6126 u32 destval,tmp;
6128 destoffset = decode_rm10_address(rl);
6129 DECODE_PRINTF(",");
6130 destval = fetch_data_long(destoffset);
6131 srcreg = DECODE_RM_LONG_REGISTER(rh);
6132 DECODE_PRINTF("\n");
6133 TRACE_AND_STEP();
6134 tmp = *srcreg;
6135 *srcreg = destval;
6136 destval = tmp;
6137 store_data_long(destoffset, destval);
6138 } else {
6139 u16 *srcreg;
6140 u16 destval,tmp;
6142 destoffset = decode_rm10_address(rl);
6143 DECODE_PRINTF(",");
6144 destval = fetch_data_word(destoffset);
6145 srcreg = DECODE_RM_WORD_REGISTER(rh);
6146 DECODE_PRINTF("\n");
6147 TRACE_AND_STEP();
6148 tmp = *srcreg;
6149 *srcreg = destval;
6150 destval = tmp;
6151 store_data_word(destoffset, destval);
6153 break;
6154 case 3: /* register to register */
6155 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6156 u32 *destreg,*srcreg;
6157 u32 tmp;
6159 destreg = DECODE_RM_LONG_REGISTER(rl);
6160 DECODE_PRINTF(",");
6161 srcreg = DECODE_RM_LONG_REGISTER(rh);
6162 DECODE_PRINTF("\n");
6163 TRACE_AND_STEP();
6164 tmp = *srcreg;
6165 *srcreg = *destreg;
6166 *destreg = tmp;
6167 } else {
6168 u16 *destreg,*srcreg;
6169 u16 tmp;
6171 destreg = DECODE_RM_WORD_REGISTER(rl);
6172 DECODE_PRINTF(",");
6173 srcreg = DECODE_RM_WORD_REGISTER(rh);
6174 DECODE_PRINTF("\n");
6175 TRACE_AND_STEP();
6176 tmp = *srcreg;
6177 *srcreg = *destreg;
6178 *destreg = tmp;
6180 break;
6182 DECODE_CLEAR_SEGOVR();
6183 END_OF_INSTR();
6186 /****************************************************************************
6187 REMARKS:
6188 Handles opcode 0x88
6189 ****************************************************************************/
6190 static void x86emuOp_mov_byte_RM_R(u8 X86EMU_UNUSED(op1))
6192 int mod, rl, rh;
6193 u8 *destreg, *srcreg;
6194 uint destoffset;
6196 START_OF_INSTR();
6197 DECODE_PRINTF("MOV\t");
6198 FETCH_DECODE_MODRM(mod, rh, rl);
6199 switch (mod) {
6200 case 0:
6201 destoffset = decode_rm00_address(rl);
6202 DECODE_PRINTF(",");
6203 srcreg = DECODE_RM_BYTE_REGISTER(rh);
6204 DECODE_PRINTF("\n");
6205 TRACE_AND_STEP();
6206 store_data_byte(destoffset, *srcreg);
6207 break;
6208 case 1:
6209 destoffset = decode_rm01_address(rl);
6210 DECODE_PRINTF(",");
6211 srcreg = DECODE_RM_BYTE_REGISTER(rh);
6212 DECODE_PRINTF("\n");
6213 TRACE_AND_STEP();
6214 store_data_byte(destoffset, *srcreg);
6215 break;
6216 case 2:
6217 destoffset = decode_rm10_address(rl);
6218 DECODE_PRINTF(",");
6219 srcreg = DECODE_RM_BYTE_REGISTER(rh);
6220 DECODE_PRINTF("\n");
6221 TRACE_AND_STEP();
6222 store_data_byte(destoffset, *srcreg);
6223 break;
6224 case 3: /* register to register */
6225 destreg = DECODE_RM_BYTE_REGISTER(rl);
6226 DECODE_PRINTF(",");
6227 srcreg = DECODE_RM_BYTE_REGISTER(rh);
6228 DECODE_PRINTF("\n");
6229 TRACE_AND_STEP();
6230 *destreg = *srcreg;
6231 break;
6233 DECODE_CLEAR_SEGOVR();
6234 END_OF_INSTR();
6237 /****************************************************************************
6238 REMARKS:
6239 Handles opcode 0x89
6240 ****************************************************************************/
6241 static void x86emuOp_mov_word_RM_R(u8 X86EMU_UNUSED(op1))
6243 int mod, rl, rh;
6244 u32 destoffset;
6246 START_OF_INSTR();
6247 DECODE_PRINTF("MOV\t");
6248 FETCH_DECODE_MODRM(mod, rh, rl);
6249 switch (mod) {
6250 case 0:
6251 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6252 u32 *srcreg;
6254 destoffset = decode_rm00_address(rl);
6255 DECODE_PRINTF(",");
6256 srcreg = DECODE_RM_LONG_REGISTER(rh);
6257 DECODE_PRINTF("\n");
6258 TRACE_AND_STEP();
6259 store_data_long(destoffset, *srcreg);
6260 } else {
6261 u16 *srcreg;
6263 destoffset = decode_rm00_address(rl);
6264 DECODE_PRINTF(",");
6265 srcreg = DECODE_RM_WORD_REGISTER(rh);
6266 DECODE_PRINTF("\n");
6267 TRACE_AND_STEP();
6268 store_data_word(destoffset, *srcreg);
6270 break;
6271 case 1:
6272 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6273 u32 *srcreg;
6275 destoffset = decode_rm01_address(rl);
6276 DECODE_PRINTF(",");
6277 srcreg = DECODE_RM_LONG_REGISTER(rh);
6278 DECODE_PRINTF("\n");
6279 TRACE_AND_STEP();
6280 store_data_long(destoffset, *srcreg);
6281 } else {
6282 u16 *srcreg;
6284 destoffset = decode_rm01_address(rl);
6285 DECODE_PRINTF(",");
6286 srcreg = DECODE_RM_WORD_REGISTER(rh);
6287 DECODE_PRINTF("\n");
6288 TRACE_AND_STEP();
6289 store_data_word(destoffset, *srcreg);
6291 break;
6292 case 2:
6293 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6294 u32 *srcreg;
6296 destoffset = decode_rm10_address(rl);
6297 DECODE_PRINTF(",");
6298 srcreg = DECODE_RM_LONG_REGISTER(rh);
6299 DECODE_PRINTF("\n");
6300 TRACE_AND_STEP();
6301 store_data_long(destoffset, *srcreg);
6302 } else {
6303 u16 *srcreg;
6305 destoffset = decode_rm10_address(rl);
6306 DECODE_PRINTF(",");
6307 srcreg = DECODE_RM_WORD_REGISTER(rh);
6308 DECODE_PRINTF("\n");
6309 TRACE_AND_STEP();
6310 store_data_word(destoffset, *srcreg);
6312 break;
6313 case 3: /* register to register */
6314 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6315 u32 *destreg,*srcreg;
6317 destreg = DECODE_RM_LONG_REGISTER(rl);
6318 DECODE_PRINTF(",");
6319 srcreg = DECODE_RM_LONG_REGISTER(rh);
6320 DECODE_PRINTF("\n");
6321 TRACE_AND_STEP();
6322 *destreg = *srcreg;
6323 } else {
6324 u16 *destreg,*srcreg;
6326 destreg = DECODE_RM_WORD_REGISTER(rl);
6327 DECODE_PRINTF(",");
6328 srcreg = DECODE_RM_WORD_REGISTER(rh);
6329 DECODE_PRINTF("\n");
6330 TRACE_AND_STEP();
6331 *destreg = *srcreg;
6333 break;
6335 DECODE_CLEAR_SEGOVR();
6336 END_OF_INSTR();
6339 /****************************************************************************
6340 REMARKS:
6341 Handles opcode 0x8a
6342 ****************************************************************************/
6343 static void x86emuOp_mov_byte_R_RM(u8 X86EMU_UNUSED(op1))
6345 int mod, rl, rh;
6346 u8 *destreg, *srcreg;
6347 uint srcoffset;
6348 u8 srcval;
6350 START_OF_INSTR();
6351 DECODE_PRINTF("MOV\t");
6352 FETCH_DECODE_MODRM(mod, rh, rl);
6353 switch (mod) {
6354 case 0:
6355 destreg = DECODE_RM_BYTE_REGISTER(rh);
6356 DECODE_PRINTF(",");
6357 srcoffset = decode_rm00_address(rl);
6358 srcval = fetch_data_byte(srcoffset);
6359 DECODE_PRINTF("\n");
6360 TRACE_AND_STEP();
6361 *destreg = srcval;
6362 break;
6363 case 1:
6364 destreg = DECODE_RM_BYTE_REGISTER(rh);
6365 DECODE_PRINTF(",");
6366 srcoffset = decode_rm01_address(rl);
6367 srcval = fetch_data_byte(srcoffset);
6368 DECODE_PRINTF("\n");
6369 TRACE_AND_STEP();
6370 *destreg = srcval;
6371 break;
6372 case 2:
6373 destreg = DECODE_RM_BYTE_REGISTER(rh);
6374 DECODE_PRINTF(",");
6375 srcoffset = decode_rm10_address(rl);
6376 srcval = fetch_data_byte(srcoffset);
6377 DECODE_PRINTF("\n");
6378 TRACE_AND_STEP();
6379 *destreg = srcval;
6380 break;
6381 case 3: /* register to register */
6382 destreg = DECODE_RM_BYTE_REGISTER(rh);
6383 DECODE_PRINTF(",");
6384 srcreg = DECODE_RM_BYTE_REGISTER(rl);
6385 DECODE_PRINTF("\n");
6386 TRACE_AND_STEP();
6387 *destreg = *srcreg;
6388 break;
6390 DECODE_CLEAR_SEGOVR();
6391 END_OF_INSTR();
6394 /****************************************************************************
6395 REMARKS:
6396 Handles opcode 0x8b
6397 ****************************************************************************/
6398 static void x86emuOp_mov_word_R_RM(u8 X86EMU_UNUSED(op1))
6400 int mod, rl, rh;
6401 uint srcoffset;
6403 START_OF_INSTR();
6404 DECODE_PRINTF("MOV\t");
6405 FETCH_DECODE_MODRM(mod, rh, rl);
6406 switch (mod) {
6407 case 0:
6408 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6409 u32 *destreg;
6410 u32 srcval;
6412 destreg = DECODE_RM_LONG_REGISTER(rh);
6413 DECODE_PRINTF(",");
6414 srcoffset = decode_rm00_address(rl);
6415 srcval = fetch_data_long(srcoffset);
6416 DECODE_PRINTF("\n");
6417 TRACE_AND_STEP();
6418 *destreg = srcval;
6419 } else {
6420 u16 *destreg;
6421 u16 srcval;
6423 destreg = DECODE_RM_WORD_REGISTER(rh);
6424 DECODE_PRINTF(",");
6425 srcoffset = decode_rm00_address(rl);
6426 srcval = fetch_data_word(srcoffset);
6427 DECODE_PRINTF("\n");
6428 TRACE_AND_STEP();
6429 *destreg = srcval;
6431 break;
6432 case 1:
6433 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6434 u32 *destreg;
6435 u32 srcval;
6437 destreg = DECODE_RM_LONG_REGISTER(rh);
6438 DECODE_PRINTF(",");
6439 srcoffset = decode_rm01_address(rl);
6440 srcval = fetch_data_long(srcoffset);
6441 DECODE_PRINTF("\n");
6442 TRACE_AND_STEP();
6443 *destreg = srcval;
6444 } else {
6445 u16 *destreg;
6446 u16 srcval;
6448 destreg = DECODE_RM_WORD_REGISTER(rh);
6449 DECODE_PRINTF(",");
6450 srcoffset = decode_rm01_address(rl);
6451 srcval = fetch_data_word(srcoffset);
6452 DECODE_PRINTF("\n");
6453 TRACE_AND_STEP();
6454 *destreg = srcval;
6456 break;
6457 case 2:
6458 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6459 u32 *destreg;
6460 u32 srcval;
6462 destreg = DECODE_RM_LONG_REGISTER(rh);
6463 DECODE_PRINTF(",");
6464 srcoffset = decode_rm10_address(rl);
6465 srcval = fetch_data_long(srcoffset);
6466 DECODE_PRINTF("\n");
6467 TRACE_AND_STEP();
6468 *destreg = srcval;
6469 } else {
6470 u16 *destreg;
6471 u16 srcval;
6473 destreg = DECODE_RM_WORD_REGISTER(rh);
6474 DECODE_PRINTF(",");
6475 srcoffset = decode_rm10_address(rl);
6476 srcval = fetch_data_word(srcoffset);
6477 DECODE_PRINTF("\n");
6478 TRACE_AND_STEP();
6479 *destreg = srcval;
6481 break;
6482 case 3: /* register to register */
6483 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6484 u32 *destreg, *srcreg;
6486 destreg = DECODE_RM_LONG_REGISTER(rh);
6487 DECODE_PRINTF(",");
6488 srcreg = DECODE_RM_LONG_REGISTER(rl);
6489 DECODE_PRINTF("\n");
6490 TRACE_AND_STEP();
6491 *destreg = *srcreg;
6492 } else {
6493 u16 *destreg, *srcreg;
6495 destreg = DECODE_RM_WORD_REGISTER(rh);
6496 DECODE_PRINTF(",");
6497 srcreg = DECODE_RM_WORD_REGISTER(rl);
6498 DECODE_PRINTF("\n");
6499 TRACE_AND_STEP();
6500 *destreg = *srcreg;
6502 break;
6504 DECODE_CLEAR_SEGOVR();
6505 END_OF_INSTR();
6508 /****************************************************************************
6509 REMARKS:
6510 Handles opcode 0x8c
6511 ****************************************************************************/
6512 static void x86emuOp_mov_word_RM_SR(u8 X86EMU_UNUSED(op1))
6514 int mod, rl, rh;
6515 u16 *destreg, *srcreg;
6516 uint destoffset;
6517 u16 destval;
6519 START_OF_INSTR();
6520 DECODE_PRINTF("MOV\t");
6521 FETCH_DECODE_MODRM(mod, rh, rl);
6522 switch (mod) {
6523 case 0:
6524 destoffset = decode_rm00_address(rl);
6525 DECODE_PRINTF(",");
6526 srcreg = decode_rm_seg_register(rh);
6527 DECODE_PRINTF("\n");
6528 TRACE_AND_STEP();
6529 destval = *srcreg;
6530 store_data_word(destoffset, destval);
6531 break;
6532 case 1:
6533 destoffset = decode_rm01_address(rl);
6534 DECODE_PRINTF(",");
6535 srcreg = decode_rm_seg_register(rh);
6536 DECODE_PRINTF("\n");
6537 TRACE_AND_STEP();
6538 destval = *srcreg;
6539 store_data_word(destoffset, destval);
6540 break;
6541 case 2:
6542 destoffset = decode_rm10_address(rl);
6543 DECODE_PRINTF(",");
6544 srcreg = decode_rm_seg_register(rh);
6545 DECODE_PRINTF("\n");
6546 TRACE_AND_STEP();
6547 destval = *srcreg;
6548 store_data_word(destoffset, destval);
6549 break;
6550 case 3: /* register to register */
6551 destreg = DECODE_RM_WORD_REGISTER(rl);
6552 DECODE_PRINTF(",");
6553 srcreg = decode_rm_seg_register(rh);
6554 DECODE_PRINTF("\n");
6555 TRACE_AND_STEP();
6556 *destreg = *srcreg;
6557 break;
6559 DECODE_CLEAR_SEGOVR();
6560 END_OF_INSTR();
6563 /****************************************************************************
6564 REMARKS:
6565 Handles opcode 0x8d
6566 ****************************************************************************/
6567 static void x86emuOp_lea_word_R_M(u8 X86EMU_UNUSED(op1))
6569 int mod, rl, rh;
6570 u16 *srcreg;
6571 uint destoffset;
6574 * TODO: Need to handle address size prefix!
6576 * lea eax,[eax+ebx*2] ??
6579 START_OF_INSTR();
6580 DECODE_PRINTF("LEA\t");
6581 FETCH_DECODE_MODRM(mod, rh, rl);
6582 switch (mod) {
6583 case 0:
6584 srcreg = DECODE_RM_WORD_REGISTER(rh);
6585 DECODE_PRINTF(",");
6586 destoffset = decode_rm00_address(rl);
6587 DECODE_PRINTF("\n");
6588 TRACE_AND_STEP();
6589 *srcreg = (u16)destoffset;
6590 break;
6591 case 1:
6592 srcreg = DECODE_RM_WORD_REGISTER(rh);
6593 DECODE_PRINTF(",");
6594 destoffset = decode_rm01_address(rl);
6595 DECODE_PRINTF("\n");
6596 TRACE_AND_STEP();
6597 *srcreg = (u16)destoffset;
6598 break;
6599 case 2:
6600 srcreg = DECODE_RM_WORD_REGISTER(rh);
6601 DECODE_PRINTF(",");
6602 destoffset = decode_rm10_address(rl);
6603 DECODE_PRINTF("\n");
6604 TRACE_AND_STEP();
6605 *srcreg = (u16)destoffset;
6606 break;
6607 case 3: /* register to register */
6608 /* undefined. Do nothing. */
6609 break;
6611 DECODE_CLEAR_SEGOVR();
6612 END_OF_INSTR();
6615 /****************************************************************************
6616 REMARKS:
6617 Handles opcode 0x8e
6618 ****************************************************************************/
6619 static void x86emuOp_mov_word_SR_RM(u8 X86EMU_UNUSED(op1))
6621 int mod, rl, rh;
6622 u16 *destreg, *srcreg;
6623 uint srcoffset;
6624 u16 srcval;
6626 START_OF_INSTR();
6627 DECODE_PRINTF("MOV\t");
6628 FETCH_DECODE_MODRM(mod, rh, rl);
6629 switch (mod) {
6630 case 0:
6631 destreg = decode_rm_seg_register(rh);
6632 DECODE_PRINTF(",");
6633 srcoffset = decode_rm00_address(rl);
6634 srcval = fetch_data_word(srcoffset);
6635 DECODE_PRINTF("\n");
6636 TRACE_AND_STEP();
6637 *destreg = srcval;
6638 break;
6639 case 1:
6640 destreg = decode_rm_seg_register(rh);
6641 DECODE_PRINTF(",");
6642 srcoffset = decode_rm01_address(rl);
6643 srcval = fetch_data_word(srcoffset);
6644 DECODE_PRINTF("\n");
6645 TRACE_AND_STEP();
6646 *destreg = srcval;
6647 break;
6648 case 2:
6649 destreg = decode_rm_seg_register(rh);
6650 DECODE_PRINTF(",");
6651 srcoffset = decode_rm10_address(rl);
6652 srcval = fetch_data_word(srcoffset);
6653 DECODE_PRINTF("\n");
6654 TRACE_AND_STEP();
6655 *destreg = srcval;
6656 break;
6657 case 3: /* register to register */
6658 destreg = decode_rm_seg_register(rh);
6659 DECODE_PRINTF(",");
6660 srcreg = DECODE_RM_WORD_REGISTER(rl);
6661 DECODE_PRINTF("\n");
6662 TRACE_AND_STEP();
6663 *destreg = *srcreg;
6664 break;
6667 * Clean up, and reset all the R_xSP pointers to the correct
6668 * locations. This is about 3x too much overhead (doing all the
6669 * segreg ptrs when only one is needed, but this instruction
6670 * *cannot* be that common, and this isn't too much work anyway.
6672 DECODE_CLEAR_SEGOVR();
6673 END_OF_INSTR();
6676 /****************************************************************************
6677 REMARKS:
6678 Handles opcode 0x8f
6679 ****************************************************************************/
6680 static void x86emuOp_pop_RM(u8 X86EMU_UNUSED(op1))
6682 int mod, rl, rh;
6683 uint destoffset;
6685 START_OF_INSTR();
6686 DECODE_PRINTF("POP\t");
6687 FETCH_DECODE_MODRM(mod, rh, rl);
6688 if (rh != 0) {
6689 DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n");
6690 HALT_SYS();
6692 switch (mod) {
6693 case 0:
6694 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6695 u32 destval;
6697 destoffset = decode_rm00_address(rl);
6698 DECODE_PRINTF("\n");
6699 TRACE_AND_STEP();
6700 destval = pop_long();
6701 store_data_long(destoffset, destval);
6702 } else {
6703 u16 destval;
6705 destoffset = decode_rm00_address(rl);
6706 DECODE_PRINTF("\n");
6707 TRACE_AND_STEP();
6708 destval = pop_word();
6709 store_data_word(destoffset, destval);
6711 break;
6712 case 1:
6713 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6714 u32 destval;
6716 destoffset = decode_rm01_address(rl);
6717 DECODE_PRINTF("\n");
6718 TRACE_AND_STEP();
6719 destval = pop_long();
6720 store_data_long(destoffset, destval);
6721 } else {
6722 u16 destval;
6724 destoffset = decode_rm01_address(rl);
6725 DECODE_PRINTF("\n");
6726 TRACE_AND_STEP();
6727 destval = pop_word();
6728 store_data_word(destoffset, destval);
6730 break;
6731 case 2:
6732 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6733 u32 destval;
6735 destoffset = decode_rm10_address(rl);
6736 DECODE_PRINTF("\n");
6737 TRACE_AND_STEP();
6738 destval = pop_long();
6739 store_data_long(destoffset, destval);
6740 } else {
6741 u16 destval;
6743 destoffset = decode_rm10_address(rl);
6744 DECODE_PRINTF("\n");
6745 TRACE_AND_STEP();
6746 destval = pop_word();
6747 store_data_word(destoffset, destval);
6749 break;
6750 case 3: /* register to register */
6751 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6752 u32 *destreg;
6754 destreg = DECODE_RM_LONG_REGISTER(rl);
6755 DECODE_PRINTF("\n");
6756 TRACE_AND_STEP();
6757 *destreg = pop_long();
6758 } else {
6759 u16 *destreg;
6761 destreg = DECODE_RM_WORD_REGISTER(rl);
6762 DECODE_PRINTF("\n");
6763 TRACE_AND_STEP();
6764 *destreg = pop_word();
6766 break;
6768 DECODE_CLEAR_SEGOVR();
6769 END_OF_INSTR();
6772 /****************************************************************************
6773 REMARKS:
6774 Handles opcode 0x90
6775 ****************************************************************************/
6776 static void x86emuOp_nop(u8 X86EMU_UNUSED(op1))
6778 START_OF_INSTR();
6779 DECODE_PRINTF("NOP\n");
6780 TRACE_AND_STEP();
6781 DECODE_CLEAR_SEGOVR();
6782 END_OF_INSTR();
6785 /****************************************************************************
6786 REMARKS:
6787 Handles opcode 0x91
6788 ****************************************************************************/
6789 static void x86emuOp_xchg_word_AX_CX(u8 X86EMU_UNUSED(op1))
6791 u32 tmp;
6793 START_OF_INSTR();
6794 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6795 DECODE_PRINTF("XCHG\tEAX,ECX\n");
6796 } else {
6797 DECODE_PRINTF("XCHG\tAX,CX\n");
6799 TRACE_AND_STEP();
6800 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6801 tmp = M.x86.R_EAX;
6802 M.x86.R_EAX = M.x86.R_ECX;
6803 M.x86.R_ECX = tmp;
6804 } else {
6805 tmp = M.x86.R_AX;
6806 M.x86.R_AX = M.x86.R_CX;
6807 M.x86.R_CX = (u16)tmp;
6809 DECODE_CLEAR_SEGOVR();
6810 END_OF_INSTR();
6813 /****************************************************************************
6814 REMARKS:
6815 Handles opcode 0x92
6816 ****************************************************************************/
6817 static void x86emuOp_xchg_word_AX_DX(u8 X86EMU_UNUSED(op1))
6819 u32 tmp;
6821 START_OF_INSTR();
6822 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6823 DECODE_PRINTF("XCHG\tEAX,EDX\n");
6824 } else {
6825 DECODE_PRINTF("XCHG\tAX,DX\n");
6827 TRACE_AND_STEP();
6828 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6829 tmp = M.x86.R_EAX;
6830 M.x86.R_EAX = M.x86.R_EDX;
6831 M.x86.R_EDX = tmp;
6832 } else {
6833 tmp = M.x86.R_AX;
6834 M.x86.R_AX = M.x86.R_DX;
6835 M.x86.R_DX = (u16)tmp;
6837 DECODE_CLEAR_SEGOVR();
6838 END_OF_INSTR();
6841 /****************************************************************************
6842 REMARKS:
6843 Handles opcode 0x93
6844 ****************************************************************************/
6845 static void x86emuOp_xchg_word_AX_BX(u8 X86EMU_UNUSED(op1))
6847 u32 tmp;
6849 START_OF_INSTR();
6850 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6851 DECODE_PRINTF("XCHG\tEAX,EBX\n");
6852 } else {
6853 DECODE_PRINTF("XCHG\tAX,BX\n");
6855 TRACE_AND_STEP();
6856 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6857 tmp = M.x86.R_EAX;
6858 M.x86.R_EAX = M.x86.R_EBX;
6859 M.x86.R_EBX = tmp;
6860 } else {
6861 tmp = M.x86.R_AX;
6862 M.x86.R_AX = M.x86.R_BX;
6863 M.x86.R_BX = (u16)tmp;
6865 DECODE_CLEAR_SEGOVR();
6866 END_OF_INSTR();
6869 /****************************************************************************
6870 REMARKS:
6871 Handles opcode 0x94
6872 ****************************************************************************/
6873 static void x86emuOp_xchg_word_AX_SP(u8 X86EMU_UNUSED(op1))
6875 u32 tmp;
6877 START_OF_INSTR();
6878 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6879 DECODE_PRINTF("XCHG\tEAX,ESP\n");
6880 } else {
6881 DECODE_PRINTF("XCHG\tAX,SP\n");
6883 TRACE_AND_STEP();
6884 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6885 tmp = M.x86.R_EAX;
6886 M.x86.R_EAX = M.x86.R_ESP;
6887 M.x86.R_ESP = tmp;
6888 } else {
6889 tmp = M.x86.R_AX;
6890 M.x86.R_AX = M.x86.R_SP;
6891 M.x86.R_SP = (u16)tmp;
6893 DECODE_CLEAR_SEGOVR();
6894 END_OF_INSTR();
6897 /****************************************************************************
6898 REMARKS:
6899 Handles opcode 0x95
6900 ****************************************************************************/
6901 static void x86emuOp_xchg_word_AX_BP(u8 X86EMU_UNUSED(op1))
6903 u32 tmp;
6905 START_OF_INSTR();
6906 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6907 DECODE_PRINTF("XCHG\tEAX,EBP\n");
6908 } else {
6909 DECODE_PRINTF("XCHG\tAX,BP\n");
6911 TRACE_AND_STEP();
6912 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6913 tmp = M.x86.R_EAX;
6914 M.x86.R_EAX = M.x86.R_EBP;
6915 M.x86.R_EBP = tmp;
6916 } else {
6917 tmp = M.x86.R_AX;
6918 M.x86.R_AX = M.x86.R_BP;
6919 M.x86.R_BP = (u16)tmp;
6921 DECODE_CLEAR_SEGOVR();
6922 END_OF_INSTR();
6925 /****************************************************************************
6926 REMARKS:
6927 Handles opcode 0x96
6928 ****************************************************************************/
6929 static void x86emuOp_xchg_word_AX_SI(u8 X86EMU_UNUSED(op1))
6931 u32 tmp;
6933 START_OF_INSTR();
6934 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6935 DECODE_PRINTF("XCHG\tEAX,ESI\n");
6936 } else {
6937 DECODE_PRINTF("XCHG\tAX,SI\n");
6939 TRACE_AND_STEP();
6940 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6941 tmp = M.x86.R_EAX;
6942 M.x86.R_EAX = M.x86.R_ESI;
6943 M.x86.R_ESI = tmp;
6944 } else {
6945 tmp = M.x86.R_AX;
6946 M.x86.R_AX = M.x86.R_SI;
6947 M.x86.R_SI = (u16)tmp;
6949 DECODE_CLEAR_SEGOVR();
6950 END_OF_INSTR();
6953 /****************************************************************************
6954 REMARKS:
6955 Handles opcode 0x97
6956 ****************************************************************************/
6957 static void x86emuOp_xchg_word_AX_DI(u8 X86EMU_UNUSED(op1))
6959 u32 tmp;
6961 START_OF_INSTR();
6962 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6963 DECODE_PRINTF("XCHG\tEAX,EDI\n");
6964 } else {
6965 DECODE_PRINTF("XCHG\tAX,DI\n");
6967 TRACE_AND_STEP();
6968 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6969 tmp = M.x86.R_EAX;
6970 M.x86.R_EAX = M.x86.R_EDI;
6971 M.x86.R_EDI = tmp;
6972 } else {
6973 tmp = M.x86.R_AX;
6974 M.x86.R_AX = M.x86.R_DI;
6975 M.x86.R_DI = (u16)tmp;
6977 DECODE_CLEAR_SEGOVR();
6978 END_OF_INSTR();
6981 /****************************************************************************
6982 REMARKS:
6983 Handles opcode 0x98
6984 ****************************************************************************/
6985 static void x86emuOp_cbw(u8 X86EMU_UNUSED(op1))
6987 START_OF_INSTR();
6988 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6989 DECODE_PRINTF("CWDE\n");
6990 } else {
6991 DECODE_PRINTF("CBW\n");
6993 TRACE_AND_STEP();
6994 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6995 if (M.x86.R_AX & 0x8000) {
6996 M.x86.R_EAX |= 0xffff0000;
6997 } else {
6998 M.x86.R_EAX &= 0x0000ffff;
7000 } else {
7001 if (M.x86.R_AL & 0x80) {
7002 M.x86.R_AH = 0xff;
7003 } else {
7004 M.x86.R_AH = 0x0;
7007 DECODE_CLEAR_SEGOVR();
7008 END_OF_INSTR();
7011 /****************************************************************************
7012 REMARKS:
7013 Handles opcode 0x99
7014 ****************************************************************************/
7015 static void x86emuOp_cwd(u8 X86EMU_UNUSED(op1))
7017 START_OF_INSTR();
7018 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7019 DECODE_PRINTF("CDQ\n");
7020 } else {
7021 DECODE_PRINTF("CWD\n");
7023 DECODE_PRINTF("CWD\n");
7024 TRACE_AND_STEP();
7025 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7026 if (M.x86.R_EAX & 0x80000000) {
7027 M.x86.R_EDX = 0xffffffff;
7028 } else {
7029 M.x86.R_EDX = 0x0;
7031 } else {
7032 if (M.x86.R_AX & 0x8000) {
7033 M.x86.R_DX = 0xffff;
7034 } else {
7035 M.x86.R_DX = 0x0;
7038 DECODE_CLEAR_SEGOVR();
7039 END_OF_INSTR();
7042 /****************************************************************************
7043 REMARKS:
7044 Handles opcode 0x9a
7045 ****************************************************************************/
7046 static void x86emuOp_call_far_IMM(u8 X86EMU_UNUSED(op1))
7048 u16 farseg, faroff;
7050 START_OF_INSTR();
7051 DECODE_PRINTF("CALL\t");
7052 faroff = fetch_word_imm();
7053 farseg = fetch_word_imm();
7054 DECODE_PRINTF2("%04x:", farseg);
7055 DECODE_PRINTF2("%04x\n", faroff);
7056 CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, farseg, faroff, "FAR ");
7058 /* XXX
7060 * Hooked interrupt vectors calling into our "BIOS" will cause
7061 * problems unless all intersegment stuff is checked for BIOS
7062 * access. Check needed here. For moment, let it alone.
7064 TRACE_AND_STEP();
7065 push_word(M.x86.R_CS);
7066 M.x86.R_CS = farseg;
7067 push_word(M.x86.R_IP);
7068 M.x86.R_IP = faroff;
7069 DECODE_CLEAR_SEGOVR();
7070 END_OF_INSTR();
7073 /****************************************************************************
7074 REMARKS:
7075 Handles opcode 0x9b
7076 ****************************************************************************/
7077 static void x86emuOp_wait(u8 X86EMU_UNUSED(op1))
7079 START_OF_INSTR();
7080 DECODE_PRINTF("WAIT");
7081 TRACE_AND_STEP();
7082 /* NADA. */
7083 DECODE_CLEAR_SEGOVR();
7084 END_OF_INSTR();
7087 /****************************************************************************
7088 REMARKS:
7089 Handles opcode 0x9c
7090 ****************************************************************************/
7091 static void x86emuOp_pushf_word(u8 X86EMU_UNUSED(op1))
7093 u32 flags;
7095 START_OF_INSTR();
7096 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7097 DECODE_PRINTF("PUSHFD\n");
7098 } else {
7099 DECODE_PRINTF("PUSHF\n");
7101 TRACE_AND_STEP();
7103 /* clear out *all* bits not representing flags, and turn on real bits */
7104 flags = (M.x86.R_EFLG & F_MSK) | F_ALWAYS_ON;
7105 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7106 push_long(flags);
7107 } else {
7108 push_word((u16)flags);
7110 DECODE_CLEAR_SEGOVR();
7111 END_OF_INSTR();
7114 /****************************************************************************
7115 REMARKS:
7116 Handles opcode 0x9d
7117 ****************************************************************************/
7118 static void x86emuOp_popf_word(u8 X86EMU_UNUSED(op1))
7120 START_OF_INSTR();
7121 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7122 DECODE_PRINTF("POPFD\n");
7123 } else {
7124 DECODE_PRINTF("POPF\n");
7126 TRACE_AND_STEP();
7127 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7128 M.x86.R_EFLG = pop_long();
7129 } else {
7130 M.x86.R_FLG = pop_word();
7132 DECODE_CLEAR_SEGOVR();
7133 END_OF_INSTR();
7136 /****************************************************************************
7137 REMARKS:
7138 Handles opcode 0x9e
7139 ****************************************************************************/
7140 static void x86emuOp_sahf(u8 X86EMU_UNUSED(op1))
7142 START_OF_INSTR();
7143 DECODE_PRINTF("SAHF\n");
7144 TRACE_AND_STEP();
7145 /* clear the lower bits of the flag register */
7146 M.x86.R_FLG &= 0xffffff00;
7147 /* or in the AH register into the flags register */
7148 M.x86.R_FLG |= M.x86.R_AH;
7149 DECODE_CLEAR_SEGOVR();
7150 END_OF_INSTR();
7153 /****************************************************************************
7154 REMARKS:
7155 Handles opcode 0x9f
7156 ****************************************************************************/
7157 static void x86emuOp_lahf(u8 X86EMU_UNUSED(op1))
7159 START_OF_INSTR();
7160 DECODE_PRINTF("LAHF\n");
7161 TRACE_AND_STEP();
7162 M.x86.R_AH = (u8)(M.x86.R_FLG & 0xff);
7163 /*undocumented TC++ behavior??? Nope. It's documented, but
7164 you have too look real hard to notice it. */
7165 M.x86.R_AH |= 0x2;
7166 DECODE_CLEAR_SEGOVR();
7167 END_OF_INSTR();
7170 /****************************************************************************
7171 REMARKS:
7172 Handles opcode 0xa0
7173 ****************************************************************************/
7174 static void x86emuOp_mov_AL_M_IMM(u8 X86EMU_UNUSED(op1))
7176 u16 offset;
7178 START_OF_INSTR();
7179 DECODE_PRINTF("MOV\tAL,");
7180 offset = fetch_word_imm();
7181 DECODE_PRINTF2("[%04x]\n", offset);
7182 TRACE_AND_STEP();
7183 M.x86.R_AL = fetch_data_byte(offset);
7184 DECODE_CLEAR_SEGOVR();
7185 END_OF_INSTR();
7188 /****************************************************************************
7189 REMARKS:
7190 Handles opcode 0xa1
7191 ****************************************************************************/
7192 static void x86emuOp_mov_AX_M_IMM(u8 X86EMU_UNUSED(op1))
7194 u16 offset;
7196 START_OF_INSTR();
7197 offset = fetch_word_imm();
7198 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7199 DECODE_PRINTF2("MOV\tEAX,[%04x]\n", offset);
7200 } else {
7201 DECODE_PRINTF2("MOV\tAX,[%04x]\n", offset);
7203 TRACE_AND_STEP();
7204 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7205 M.x86.R_EAX = fetch_data_long(offset);
7206 } else {
7207 M.x86.R_AX = fetch_data_word(offset);
7209 DECODE_CLEAR_SEGOVR();
7210 END_OF_INSTR();
7213 /****************************************************************************
7214 REMARKS:
7215 Handles opcode 0xa2
7216 ****************************************************************************/
7217 static void x86emuOp_mov_M_AL_IMM(u8 X86EMU_UNUSED(op1))
7219 u16 offset;
7221 START_OF_INSTR();
7222 DECODE_PRINTF("MOV\t");
7223 offset = fetch_word_imm();
7224 DECODE_PRINTF2("[%04x],AL\n", offset);
7225 TRACE_AND_STEP();
7226 store_data_byte(offset, M.x86.R_AL);
7227 DECODE_CLEAR_SEGOVR();
7228 END_OF_INSTR();
7231 /****************************************************************************
7232 REMARKS:
7233 Handles opcode 0xa3
7234 ****************************************************************************/
7235 static void x86emuOp_mov_M_AX_IMM(u8 X86EMU_UNUSED(op1))
7237 u16 offset;
7239 START_OF_INSTR();
7240 offset = fetch_word_imm();
7241 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7242 DECODE_PRINTF2("MOV\t[%04x],EAX\n", offset);
7243 } else {
7244 DECODE_PRINTF2("MOV\t[%04x],AX\n", offset);
7246 TRACE_AND_STEP();
7247 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7248 store_data_long(offset, M.x86.R_EAX);
7249 } else {
7250 store_data_word(offset, M.x86.R_AX);
7252 DECODE_CLEAR_SEGOVR();
7253 END_OF_INSTR();
7256 /****************************************************************************
7257 REMARKS:
7258 Handles opcode 0xa4
7259 ****************************************************************************/
7260 static void x86emuOp_movs_byte(u8 X86EMU_UNUSED(op1))
7262 u8 val;
7263 u32 count;
7264 int inc;
7266 START_OF_INSTR();
7267 DECODE_PRINTF("MOVS\tBYTE\n");
7268 if (ACCESS_FLAG(F_DF)) /* down */
7269 inc = -1;
7270 else
7271 inc = 1;
7272 TRACE_AND_STEP();
7273 count = 1;
7274 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7275 /* dont care whether REPE or REPNE */
7276 /* move them until CX is ZERO. */
7277 count = M.x86.R_CX;
7278 M.x86.R_CX = 0;
7279 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7281 while (count--) {
7282 val = fetch_data_byte(M.x86.R_SI);
7283 store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, val);
7284 M.x86.R_SI += inc;
7285 M.x86.R_DI += inc;
7287 DECODE_CLEAR_SEGOVR();
7288 END_OF_INSTR();
7291 /****************************************************************************
7292 REMARKS:
7293 Handles opcode 0xa5
7294 ****************************************************************************/
7295 static void x86emuOp_movs_word(u8 X86EMU_UNUSED(op1))
7297 u32 val;
7298 int inc;
7299 u32 count;
7301 START_OF_INSTR();
7302 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7303 DECODE_PRINTF("MOVS\tDWORD\n");
7304 if (ACCESS_FLAG(F_DF)) /* down */
7305 inc = -4;
7306 else
7307 inc = 4;
7308 } else {
7309 DECODE_PRINTF("MOVS\tWORD\n");
7310 if (ACCESS_FLAG(F_DF)) /* down */
7311 inc = -2;
7312 else
7313 inc = 2;
7315 TRACE_AND_STEP();
7316 count = 1;
7317 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7318 /* dont care whether REPE or REPNE */
7319 /* move them until CX is ZERO. */
7320 count = M.x86.R_CX;
7321 M.x86.R_CX = 0;
7322 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7324 while (count--) {
7325 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7326 val = fetch_data_long(M.x86.R_SI);
7327 store_data_long_abs(M.x86.R_ES, M.x86.R_DI, val);
7328 } else {
7329 val = fetch_data_word(M.x86.R_SI);
7330 store_data_word_abs(M.x86.R_ES, M.x86.R_DI, (u16)val);
7332 M.x86.R_SI += inc;
7333 M.x86.R_DI += inc;
7335 DECODE_CLEAR_SEGOVR();
7336 END_OF_INSTR();
7339 /****************************************************************************
7340 REMARKS:
7341 Handles opcode 0xa6
7342 ****************************************************************************/
7343 static void x86emuOp_cmps_byte(u8 X86EMU_UNUSED(op1))
7345 s8 val1, val2;
7346 int inc;
7348 START_OF_INSTR();
7349 DECODE_PRINTF("CMPS\tBYTE\n");
7350 TRACE_AND_STEP();
7351 if (ACCESS_FLAG(F_DF)) /* down */
7352 inc = -1;
7353 else
7354 inc = 1;
7356 if (M.x86.mode & SYSMODE_PREFIX_REPE) {
7357 /* REPE */
7358 /* move them until CX is ZERO. */
7359 while (M.x86.R_CX != 0) {
7360 val1 = fetch_data_byte(M.x86.R_SI);
7361 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7362 cmp_byte(val1, val2);
7363 M.x86.R_CX -= 1;
7364 M.x86.R_SI += inc;
7365 M.x86.R_DI += inc;
7366 if (ACCESS_FLAG(F_ZF) == 0)
7367 break;
7369 M.x86.mode &= ~SYSMODE_PREFIX_REPE;
7370 } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
7371 /* REPNE */
7372 /* move them until CX is ZERO. */
7373 while (M.x86.R_CX != 0) {
7374 val1 = fetch_data_byte(M.x86.R_SI);
7375 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7376 cmp_byte(val1, val2);
7377 M.x86.R_CX -= 1;
7378 M.x86.R_SI += inc;
7379 M.x86.R_DI += inc;
7380 if (ACCESS_FLAG(F_ZF))
7381 break; /* zero flag set means equal */
7383 M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
7384 } else {
7385 val1 = fetch_data_byte(M.x86.R_SI);
7386 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7387 cmp_byte(val1, val2);
7388 M.x86.R_SI += inc;
7389 M.x86.R_DI += inc;
7391 DECODE_CLEAR_SEGOVR();
7392 END_OF_INSTR();
7395 /****************************************************************************
7396 REMARKS:
7397 Handles opcode 0xa7
7398 ****************************************************************************/
7399 static void x86emuOp_cmps_word(u8 X86EMU_UNUSED(op1))
7401 u32 val1,val2;
7402 int inc;
7404 START_OF_INSTR();
7405 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7406 DECODE_PRINTF("CMPS\tDWORD\n");
7407 if (ACCESS_FLAG(F_DF)) /* down */
7408 inc = -4;
7409 else
7410 inc = 4;
7411 } else {
7412 DECODE_PRINTF("CMPS\tWORD\n");
7413 if (ACCESS_FLAG(F_DF)) /* down */
7414 inc = -2;
7415 else
7416 inc = 2;
7418 TRACE_AND_STEP();
7419 if (M.x86.mode & SYSMODE_PREFIX_REPE) {
7420 /* REPE */
7421 /* move them until CX is ZERO. */
7422 while (M.x86.R_CX != 0) {
7423 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7424 val1 = fetch_data_long(M.x86.R_SI);
7425 val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7426 cmp_long(val1, val2);
7427 } else {
7428 val1 = fetch_data_word(M.x86.R_SI);
7429 val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7430 cmp_word((u16)val1, (u16)val2);
7432 M.x86.R_CX -= 1;
7433 M.x86.R_SI += inc;
7434 M.x86.R_DI += inc;
7435 if (ACCESS_FLAG(F_ZF) == 0)
7436 break;
7438 M.x86.mode &= ~SYSMODE_PREFIX_REPE;
7439 } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
7440 /* REPNE */
7441 /* move them until CX is ZERO. */
7442 while (M.x86.R_CX != 0) {
7443 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7444 val1 = fetch_data_long(M.x86.R_SI);
7445 val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7446 cmp_long(val1, val2);
7447 } else {
7448 val1 = fetch_data_word(M.x86.R_SI);
7449 val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7450 cmp_word((u16)val1, (u16)val2);
7452 M.x86.R_CX -= 1;
7453 M.x86.R_SI += inc;
7454 M.x86.R_DI += inc;
7455 if (ACCESS_FLAG(F_ZF))
7456 break; /* zero flag set means equal */
7458 M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
7459 } else {
7460 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7461 val1 = fetch_data_long(M.x86.R_SI);
7462 val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7463 cmp_long(val1, val2);
7464 } else {
7465 val1 = fetch_data_word(M.x86.R_SI);
7466 val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7467 cmp_word((u16)val1, (u16)val2);
7469 M.x86.R_SI += inc;
7470 M.x86.R_DI += inc;
7472 DECODE_CLEAR_SEGOVR();
7473 END_OF_INSTR();
7476 /****************************************************************************
7477 REMARKS:
7478 Handles opcode 0xa8
7479 ****************************************************************************/
7480 static void x86emuOp_test_AL_IMM(u8 X86EMU_UNUSED(op1))
7482 int imm;
7484 START_OF_INSTR();
7485 DECODE_PRINTF("TEST\tAL,");
7486 imm = fetch_byte_imm();
7487 DECODE_PRINTF2("%04x\n", imm);
7488 TRACE_AND_STEP();
7489 test_byte(M.x86.R_AL, (u8)imm);
7490 DECODE_CLEAR_SEGOVR();
7491 END_OF_INSTR();
7494 /****************************************************************************
7495 REMARKS:
7496 Handles opcode 0xa9
7497 ****************************************************************************/
7498 static void x86emuOp_test_AX_IMM(u8 X86EMU_UNUSED(op1))
7500 u32 srcval;
7502 START_OF_INSTR();
7503 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7504 DECODE_PRINTF("TEST\tEAX,");
7505 srcval = fetch_long_imm();
7506 } else {
7507 DECODE_PRINTF("TEST\tAX,");
7508 srcval = fetch_word_imm();
7510 DECODE_PRINTF2("%x\n", srcval);
7511 TRACE_AND_STEP();
7512 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7513 test_long(M.x86.R_EAX, srcval);
7514 } else {
7515 test_word(M.x86.R_AX, (u16)srcval);
7517 DECODE_CLEAR_SEGOVR();
7518 END_OF_INSTR();
7521 /****************************************************************************
7522 REMARKS:
7523 Handles opcode 0xaa
7524 ****************************************************************************/
7525 static void x86emuOp_stos_byte(u8 X86EMU_UNUSED(op1))
7527 int inc;
7529 START_OF_INSTR();
7530 DECODE_PRINTF("STOS\tBYTE\n");
7531 if (ACCESS_FLAG(F_DF)) /* down */
7532 inc = -1;
7533 else
7534 inc = 1;
7535 TRACE_AND_STEP();
7536 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7537 /* dont care whether REPE or REPNE */
7538 /* move them until CX is ZERO. */
7539 while (M.x86.R_CX != 0) {
7540 store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL);
7541 M.x86.R_CX -= 1;
7542 M.x86.R_DI += inc;
7544 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7545 } else {
7546 store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL);
7547 M.x86.R_DI += inc;
7549 DECODE_CLEAR_SEGOVR();
7550 END_OF_INSTR();
7553 /****************************************************************************
7554 REMARKS:
7555 Handles opcode 0xab
7556 ****************************************************************************/
7557 static void x86emuOp_stos_word(u8 X86EMU_UNUSED(op1))
7559 int inc;
7560 u32 count;
7562 START_OF_INSTR();
7563 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7564 DECODE_PRINTF("STOS\tDWORD\n");
7565 if (ACCESS_FLAG(F_DF)) /* down */
7566 inc = -4;
7567 else
7568 inc = 4;
7569 } else {
7570 DECODE_PRINTF("STOS\tWORD\n");
7571 if (ACCESS_FLAG(F_DF)) /* down */
7572 inc = -2;
7573 else
7574 inc = 2;
7576 TRACE_AND_STEP();
7577 count = 1;
7578 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7579 /* dont care whether REPE or REPNE */
7580 /* move them until CX is ZERO. */
7581 count = M.x86.R_CX;
7582 M.x86.R_CX = 0;
7583 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7585 while (count--) {
7586 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7587 store_data_long_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_EAX);
7588 } else {
7589 store_data_word_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AX);
7591 M.x86.R_DI += inc;
7593 DECODE_CLEAR_SEGOVR();
7594 END_OF_INSTR();
7597 /****************************************************************************
7598 REMARKS:
7599 Handles opcode 0xac
7600 ****************************************************************************/
7601 static void x86emuOp_lods_byte(u8 X86EMU_UNUSED(op1))
7603 int inc;
7605 START_OF_INSTR();
7606 DECODE_PRINTF("LODS\tBYTE\n");
7607 TRACE_AND_STEP();
7608 if (ACCESS_FLAG(F_DF)) /* down */
7609 inc = -1;
7610 else
7611 inc = 1;
7612 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7613 /* dont care whether REPE or REPNE */
7614 /* move them until CX is ZERO. */
7615 while (M.x86.R_CX != 0) {
7616 M.x86.R_AL = fetch_data_byte(M.x86.R_SI);
7617 M.x86.R_CX -= 1;
7618 M.x86.R_SI += inc;
7620 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7621 } else {
7622 M.x86.R_AL = fetch_data_byte(M.x86.R_SI);
7623 M.x86.R_SI += inc;
7625 DECODE_CLEAR_SEGOVR();
7626 END_OF_INSTR();
7629 /****************************************************************************
7630 REMARKS:
7631 Handles opcode 0xad
7632 ****************************************************************************/
7633 static void x86emuOp_lods_word(u8 X86EMU_UNUSED(op1))
7635 int inc;
7636 u32 count;
7638 START_OF_INSTR();
7639 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7640 DECODE_PRINTF("LODS\tDWORD\n");
7641 if (ACCESS_FLAG(F_DF)) /* down */
7642 inc = -4;
7643 else
7644 inc = 4;
7645 } else {
7646 DECODE_PRINTF("LODS\tWORD\n");
7647 if (ACCESS_FLAG(F_DF)) /* down */
7648 inc = -2;
7649 else
7650 inc = 2;
7652 TRACE_AND_STEP();
7653 count = 1;
7654 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7655 /* dont care whether REPE or REPNE */
7656 /* move them until CX is ZERO. */
7657 count = M.x86.R_CX;
7658 M.x86.R_CX = 0;
7659 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7661 while (count--) {
7662 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7663 M.x86.R_EAX = fetch_data_long(M.x86.R_SI);
7664 } else {
7665 M.x86.R_AX = fetch_data_word(M.x86.R_SI);
7667 M.x86.R_SI += inc;
7669 DECODE_CLEAR_SEGOVR();
7670 END_OF_INSTR();
7673 /****************************************************************************
7674 REMARKS:
7675 Handles opcode 0xae
7676 ****************************************************************************/
7677 static void x86emuOp_scas_byte(u8 X86EMU_UNUSED(op1))
7679 s8 val2;
7680 int inc;
7682 START_OF_INSTR();
7683 DECODE_PRINTF("SCAS\tBYTE\n");
7684 TRACE_AND_STEP();
7685 if (ACCESS_FLAG(F_DF)) /* down */
7686 inc = -1;
7687 else
7688 inc = 1;
7689 if (M.x86.mode & SYSMODE_PREFIX_REPE) {
7690 /* REPE */
7691 /* move them until CX is ZERO. */
7692 while (M.x86.R_CX != 0) {
7693 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7694 cmp_byte(M.x86.R_AL, val2);
7695 M.x86.R_CX -= 1;
7696 M.x86.R_DI += inc;
7697 if (ACCESS_FLAG(F_ZF) == 0)
7698 break;
7700 M.x86.mode &= ~SYSMODE_PREFIX_REPE;
7701 } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
7702 /* REPNE */
7703 /* move them until CX is ZERO. */
7704 while (M.x86.R_CX != 0) {
7705 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7706 cmp_byte(M.x86.R_AL, val2);
7707 M.x86.R_CX -= 1;
7708 M.x86.R_DI += inc;
7709 if (ACCESS_FLAG(F_ZF))
7710 break; /* zero flag set means equal */
7712 M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
7713 } else {
7714 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7715 cmp_byte(M.x86.R_AL, val2);
7716 M.x86.R_DI += inc;
7718 DECODE_CLEAR_SEGOVR();
7719 END_OF_INSTR();
7722 /****************************************************************************
7723 REMARKS:
7724 Handles opcode 0xaf
7725 ****************************************************************************/
7726 static void x86emuOp_scas_word(u8 X86EMU_UNUSED(op1))
7728 int inc;
7729 u32 val;
7731 START_OF_INSTR();
7732 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7733 DECODE_PRINTF("SCAS\tDWORD\n");
7734 if (ACCESS_FLAG(F_DF)) /* down */
7735 inc = -4;
7736 else
7737 inc = 4;
7738 } else {
7739 DECODE_PRINTF("SCAS\tWORD\n");
7740 if (ACCESS_FLAG(F_DF)) /* down */
7741 inc = -2;
7742 else
7743 inc = 2;
7745 TRACE_AND_STEP();
7746 if (M.x86.mode & SYSMODE_PREFIX_REPE) {
7747 /* REPE */
7748 /* move them until CX is ZERO. */
7749 while (M.x86.R_CX != 0) {
7750 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7751 val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7752 cmp_long(M.x86.R_EAX, val);
7753 } else {
7754 val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7755 cmp_word(M.x86.R_AX, (u16)val);
7757 M.x86.R_CX -= 1;
7758 M.x86.R_DI += inc;
7759 if (ACCESS_FLAG(F_ZF) == 0)
7760 break;
7762 M.x86.mode &= ~SYSMODE_PREFIX_REPE;
7763 } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
7764 /* REPNE */
7765 /* move them until CX is ZERO. */
7766 while (M.x86.R_CX != 0) {
7767 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7768 val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7769 cmp_long(M.x86.R_EAX, val);
7770 } else {
7771 val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7772 cmp_word(M.x86.R_AX, (u16)val);
7774 M.x86.R_CX -= 1;
7775 M.x86.R_DI += inc;
7776 if (ACCESS_FLAG(F_ZF))
7777 break; /* zero flag set means equal */
7779 M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
7780 } else {
7781 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7782 val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7783 cmp_long(M.x86.R_EAX, val);
7784 } else {
7785 val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7786 cmp_word(M.x86.R_AX, (u16)val);
7788 M.x86.R_DI += inc;
7790 DECODE_CLEAR_SEGOVR();
7791 END_OF_INSTR();
7794 /****************************************************************************
7795 REMARKS:
7796 Handles opcode 0xb0
7797 ****************************************************************************/
7798 static void x86emuOp_mov_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
7800 u8 imm;
7802 START_OF_INSTR();
7803 DECODE_PRINTF("MOV\tAL,");
7804 imm = fetch_byte_imm();
7805 DECODE_PRINTF2("%x\n", imm);
7806 TRACE_AND_STEP();
7807 M.x86.R_AL = imm;
7808 DECODE_CLEAR_SEGOVR();
7809 END_OF_INSTR();
7812 /****************************************************************************
7813 REMARKS:
7814 Handles opcode 0xb1
7815 ****************************************************************************/
7816 static void x86emuOp_mov_byte_CL_IMM(u8 X86EMU_UNUSED(op1))
7818 u8 imm;
7820 START_OF_INSTR();
7821 DECODE_PRINTF("MOV\tCL,");
7822 imm = fetch_byte_imm();
7823 DECODE_PRINTF2("%x\n", imm);
7824 TRACE_AND_STEP();
7825 M.x86.R_CL = imm;
7826 DECODE_CLEAR_SEGOVR();
7827 END_OF_INSTR();
7830 /****************************************************************************
7831 REMARKS:
7832 Handles opcode 0xb2
7833 ****************************************************************************/
7834 static void x86emuOp_mov_byte_DL_IMM(u8 X86EMU_UNUSED(op1))
7836 u8 imm;
7838 START_OF_INSTR();
7839 DECODE_PRINTF("MOV\tDL,");
7840 imm = fetch_byte_imm();
7841 DECODE_PRINTF2("%x\n", imm);
7842 TRACE_AND_STEP();
7843 M.x86.R_DL = imm;
7844 DECODE_CLEAR_SEGOVR();
7845 END_OF_INSTR();
7848 /****************************************************************************
7849 REMARKS:
7850 Handles opcode 0xb3
7851 ****************************************************************************/
7852 static void x86emuOp_mov_byte_BL_IMM(u8 X86EMU_UNUSED(op1))
7854 u8 imm;
7856 START_OF_INSTR();
7857 DECODE_PRINTF("MOV\tBL,");
7858 imm = fetch_byte_imm();
7859 DECODE_PRINTF2("%x\n", imm);
7860 TRACE_AND_STEP();
7861 M.x86.R_BL = imm;
7862 DECODE_CLEAR_SEGOVR();
7863 END_OF_INSTR();
7866 /****************************************************************************
7867 REMARKS:
7868 Handles opcode 0xb4
7869 ****************************************************************************/
7870 static void x86emuOp_mov_byte_AH_IMM(u8 X86EMU_UNUSED(op1))
7872 u8 imm;
7874 START_OF_INSTR();
7875 DECODE_PRINTF("MOV\tAH,");
7876 imm = fetch_byte_imm();
7877 DECODE_PRINTF2("%x\n", imm);
7878 TRACE_AND_STEP();
7879 M.x86.R_AH = imm;
7880 DECODE_CLEAR_SEGOVR();
7881 END_OF_INSTR();
7884 /****************************************************************************
7885 REMARKS:
7886 Handles opcode 0xb5
7887 ****************************************************************************/
7888 static void x86emuOp_mov_byte_CH_IMM(u8 X86EMU_UNUSED(op1))
7890 u8 imm;
7892 START_OF_INSTR();
7893 DECODE_PRINTF("MOV\tCH,");
7894 imm = fetch_byte_imm();
7895 DECODE_PRINTF2("%x\n", imm);
7896 TRACE_AND_STEP();
7897 M.x86.R_CH = imm;
7898 DECODE_CLEAR_SEGOVR();
7899 END_OF_INSTR();
7902 /****************************************************************************
7903 REMARKS:
7904 Handles opcode 0xb6
7905 ****************************************************************************/
7906 static void x86emuOp_mov_byte_DH_IMM(u8 X86EMU_UNUSED(op1))
7908 u8 imm;
7910 START_OF_INSTR();
7911 DECODE_PRINTF("MOV\tDH,");
7912 imm = fetch_byte_imm();
7913 DECODE_PRINTF2("%x\n", imm);
7914 TRACE_AND_STEP();
7915 M.x86.R_DH = imm;
7916 DECODE_CLEAR_SEGOVR();
7917 END_OF_INSTR();
7920 /****************************************************************************
7921 REMARKS:
7922 Handles opcode 0xb7
7923 ****************************************************************************/
7924 static void x86emuOp_mov_byte_BH_IMM(u8 X86EMU_UNUSED(op1))
7926 u8 imm;
7928 START_OF_INSTR();
7929 DECODE_PRINTF("MOV\tBH,");
7930 imm = fetch_byte_imm();
7931 DECODE_PRINTF2("%x\n", imm);
7932 TRACE_AND_STEP();
7933 M.x86.R_BH = imm;
7934 DECODE_CLEAR_SEGOVR();
7935 END_OF_INSTR();
7938 /****************************************************************************
7939 REMARKS:
7940 Handles opcode 0xb8
7941 ****************************************************************************/
7942 static void x86emuOp_mov_word_AX_IMM(u8 X86EMU_UNUSED(op1))
7944 u32 srcval;
7946 START_OF_INSTR();
7947 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7948 DECODE_PRINTF("MOV\tEAX,");
7949 srcval = fetch_long_imm();
7950 } else {
7951 DECODE_PRINTF("MOV\tAX,");
7952 srcval = fetch_word_imm();
7954 DECODE_PRINTF2("%x\n", srcval);
7955 TRACE_AND_STEP();
7956 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7957 M.x86.R_EAX = srcval;
7958 } else {
7959 M.x86.R_AX = (u16)srcval;
7961 DECODE_CLEAR_SEGOVR();
7962 END_OF_INSTR();
7965 /****************************************************************************
7966 REMARKS:
7967 Handles opcode 0xb9
7968 ****************************************************************************/
7969 static void x86emuOp_mov_word_CX_IMM(u8 X86EMU_UNUSED(op1))
7971 u32 srcval;
7973 START_OF_INSTR();
7974 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7975 DECODE_PRINTF("MOV\tECX,");
7976 srcval = fetch_long_imm();
7977 } else {
7978 DECODE_PRINTF("MOV\tCX,");
7979 srcval = fetch_word_imm();
7981 DECODE_PRINTF2("%x\n", srcval);
7982 TRACE_AND_STEP();
7983 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7984 M.x86.R_ECX = srcval;
7985 } else {
7986 M.x86.R_CX = (u16)srcval;
7988 DECODE_CLEAR_SEGOVR();
7989 END_OF_INSTR();
7992 /****************************************************************************
7993 REMARKS:
7994 Handles opcode 0xba
7995 ****************************************************************************/
7996 static void x86emuOp_mov_word_DX_IMM(u8 X86EMU_UNUSED(op1))
7998 u32 srcval;
8000 START_OF_INSTR();
8001 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8002 DECODE_PRINTF("MOV\tEDX,");
8003 srcval = fetch_long_imm();
8004 } else {
8005 DECODE_PRINTF("MOV\tDX,");
8006 srcval = fetch_word_imm();
8008 DECODE_PRINTF2("%x\n", srcval);
8009 TRACE_AND_STEP();
8010 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8011 M.x86.R_EDX = srcval;
8012 } else {
8013 M.x86.R_DX = (u16)srcval;
8015 DECODE_CLEAR_SEGOVR();
8016 END_OF_INSTR();
8019 /****************************************************************************
8020 REMARKS:
8021 Handles opcode 0xbb
8022 ****************************************************************************/
8023 static void x86emuOp_mov_word_BX_IMM(u8 X86EMU_UNUSED(op1))
8025 u32 srcval;
8027 START_OF_INSTR();
8028 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8029 DECODE_PRINTF("MOV\tEBX,");
8030 srcval = fetch_long_imm();
8031 } else {
8032 DECODE_PRINTF("MOV\tBX,");
8033 srcval = fetch_word_imm();
8035 DECODE_PRINTF2("%x\n", srcval);
8036 TRACE_AND_STEP();
8037 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8038 M.x86.R_EBX = srcval;
8039 } else {
8040 M.x86.R_BX = (u16)srcval;
8042 DECODE_CLEAR_SEGOVR();
8043 END_OF_INSTR();
8046 /****************************************************************************
8047 REMARKS:
8048 Handles opcode 0xbc
8049 ****************************************************************************/
8050 static void x86emuOp_mov_word_SP_IMM(u8 X86EMU_UNUSED(op1))
8052 u32 srcval;
8054 START_OF_INSTR();
8055 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8056 DECODE_PRINTF("MOV\tESP,");
8057 srcval = fetch_long_imm();
8058 } else {
8059 DECODE_PRINTF("MOV\tSP,");
8060 srcval = fetch_word_imm();
8062 DECODE_PRINTF2("%x\n", srcval);
8063 TRACE_AND_STEP();
8064 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8065 M.x86.R_ESP = srcval;
8066 } else {
8067 M.x86.R_SP = (u16)srcval;
8069 DECODE_CLEAR_SEGOVR();
8070 END_OF_INSTR();
8073 /****************************************************************************
8074 REMARKS:
8075 Handles opcode 0xbd
8076 ****************************************************************************/
8077 static void x86emuOp_mov_word_BP_IMM(u8 X86EMU_UNUSED(op1))
8079 u32 srcval;
8081 START_OF_INSTR();
8082 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8083 DECODE_PRINTF("MOV\tEBP,");
8084 srcval = fetch_long_imm();
8085 } else {
8086 DECODE_PRINTF("MOV\tBP,");
8087 srcval = fetch_word_imm();
8089 DECODE_PRINTF2("%x\n", srcval);
8090 TRACE_AND_STEP();
8091 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8092 M.x86.R_EBP = srcval;
8093 } else {
8094 M.x86.R_BP = (u16)srcval;
8096 DECODE_CLEAR_SEGOVR();
8097 END_OF_INSTR();
8100 /****************************************************************************
8101 REMARKS:
8102 Handles opcode 0xbe
8103 ****************************************************************************/
8104 static void x86emuOp_mov_word_SI_IMM(u8 X86EMU_UNUSED(op1))
8106 u32 srcval;
8108 START_OF_INSTR();
8109 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8110 DECODE_PRINTF("MOV\tESI,");
8111 srcval = fetch_long_imm();
8112 } else {
8113 DECODE_PRINTF("MOV\tSI,");
8114 srcval = fetch_word_imm();
8116 DECODE_PRINTF2("%x\n", srcval);
8117 TRACE_AND_STEP();
8118 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8119 M.x86.R_ESI = srcval;
8120 } else {
8121 M.x86.R_SI = (u16)srcval;
8123 DECODE_CLEAR_SEGOVR();
8124 END_OF_INSTR();
8127 /****************************************************************************
8128 REMARKS:
8129 Handles opcode 0xbf
8130 ****************************************************************************/
8131 static void x86emuOp_mov_word_DI_IMM(u8 X86EMU_UNUSED(op1))
8133 u32 srcval;
8135 START_OF_INSTR();
8136 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8137 DECODE_PRINTF("MOV\tEDI,");
8138 srcval = fetch_long_imm();
8139 } else {
8140 DECODE_PRINTF("MOV\tDI,");
8141 srcval = fetch_word_imm();
8143 DECODE_PRINTF2("%x\n", srcval);
8144 TRACE_AND_STEP();
8145 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8146 M.x86.R_EDI = srcval;
8147 } else {
8148 M.x86.R_DI = (u16)srcval;
8150 DECODE_CLEAR_SEGOVR();
8151 END_OF_INSTR();
8154 /* used by opcodes c0, d0, and d2. */
8155 static u8(*opcD0_byte_operation[])(u8 d, u8 s) =
8157 rol_byte,
8158 ror_byte,
8159 rcl_byte,
8160 rcr_byte,
8161 shl_byte,
8162 shr_byte,
8163 shl_byte, /* sal_byte === shl_byte by definition */
8164 sar_byte,
8167 /****************************************************************************
8168 REMARKS:
8169 Handles opcode 0xc0
8170 ****************************************************************************/
8171 static void x86emuOp_opcC0_byte_RM_MEM(u8 X86EMU_UNUSED(op1))
8173 int mod, rl, rh;
8174 u8 *destreg;
8175 uint destoffset;
8176 u8 destval;
8177 u8 amt;
8180 * Yet another weirdo special case instruction format. Part of
8181 * the opcode held below in "RH". Doubly nested case would
8182 * result, except that the decoded instruction
8184 START_OF_INSTR();
8185 FETCH_DECODE_MODRM(mod, rh, rl);
8186 #ifdef DEBUG
8187 if (DEBUG_DECODE()) {
8188 /* XXX DECODE_PRINTF may be changed to something more
8189 general, so that it is important to leave the strings
8190 in the same format, even though the result is that the
8191 above test is done twice. */
8193 switch (rh) {
8194 case 0:
8195 DECODE_PRINTF("ROL\t");
8196 break;
8197 case 1:
8198 DECODE_PRINTF("ROR\t");
8199 break;
8200 case 2:
8201 DECODE_PRINTF("RCL\t");
8202 break;
8203 case 3:
8204 DECODE_PRINTF("RCR\t");
8205 break;
8206 case 4:
8207 DECODE_PRINTF("SHL\t");
8208 break;
8209 case 5:
8210 DECODE_PRINTF("SHR\t");
8211 break;
8212 case 6:
8213 DECODE_PRINTF("SAL\t");
8214 break;
8215 case 7:
8216 DECODE_PRINTF("SAR\t");
8217 break;
8220 #endif
8221 /* know operation, decode the mod byte to find the addressing
8222 mode. */
8223 switch (mod) {
8224 case 0:
8225 DECODE_PRINTF("BYTE PTR ");
8226 destoffset = decode_rm00_address(rl);
8227 amt = fetch_byte_imm();
8228 DECODE_PRINTF2(",%x\n", amt);
8229 destval = fetch_data_byte(destoffset);
8230 TRACE_AND_STEP();
8231 destval = (*opcD0_byte_operation[rh]) (destval, amt);
8232 store_data_byte(destoffset, destval);
8233 break;
8234 case 1:
8235 DECODE_PRINTF("BYTE PTR ");
8236 destoffset = decode_rm01_address(rl);
8237 amt = fetch_byte_imm();
8238 DECODE_PRINTF2(",%x\n", amt);
8239 destval = fetch_data_byte(destoffset);
8240 TRACE_AND_STEP();
8241 destval = (*opcD0_byte_operation[rh]) (destval, amt);
8242 store_data_byte(destoffset, destval);
8243 break;
8244 case 2:
8245 DECODE_PRINTF("BYTE PTR ");
8246 destoffset = decode_rm10_address(rl);
8247 amt = fetch_byte_imm();
8248 DECODE_PRINTF2(",%x\n", amt);
8249 destval = fetch_data_byte(destoffset);
8250 TRACE_AND_STEP();
8251 destval = (*opcD0_byte_operation[rh]) (destval, amt);
8252 store_data_byte(destoffset, destval);
8253 break;
8254 case 3: /* register to register */
8255 destreg = DECODE_RM_BYTE_REGISTER(rl);
8256 amt = fetch_byte_imm();
8257 DECODE_PRINTF2(",%x\n", amt);
8258 TRACE_AND_STEP();
8259 destval = (*opcD0_byte_operation[rh]) (*destreg, amt);
8260 *destreg = destval;
8261 break;
8263 DECODE_CLEAR_SEGOVR();
8264 END_OF_INSTR();
8267 /* used by opcodes c1, d1, and d3. */
8268 static u16(*opcD1_word_operation[])(u16 s, u8 d) =
8270 rol_word,
8271 ror_word,
8272 rcl_word,
8273 rcr_word,
8274 shl_word,
8275 shr_word,
8276 shl_word, /* sal_byte === shl_byte by definition */
8277 sar_word,
8280 /* used by opcodes c1, d1, and d3. */
8281 static u32 (*opcD1_long_operation[])(u32 s, u8 d) =
8283 rol_long,
8284 ror_long,
8285 rcl_long,
8286 rcr_long,
8287 shl_long,
8288 shr_long,
8289 shl_long, /* sal_byte === shl_byte by definition */
8290 sar_long,
8293 /****************************************************************************
8294 REMARKS:
8295 Handles opcode 0xc1
8296 ****************************************************************************/
8297 static void x86emuOp_opcC1_word_RM_MEM(u8 X86EMU_UNUSED(op1))
8299 int mod, rl, rh;
8300 uint destoffset;
8301 u8 amt;
8304 * Yet another weirdo special case instruction format. Part of
8305 * the opcode held below in "RH". Doubly nested case would
8306 * result, except that the decoded instruction
8308 START_OF_INSTR();
8309 FETCH_DECODE_MODRM(mod, rh, rl);
8310 #ifdef DEBUG
8311 if (DEBUG_DECODE()) {
8312 /* XXX DECODE_PRINTF may be changed to something more
8313 general, so that it is important to leave the strings
8314 in the same format, even though the result is that the
8315 above test is done twice. */
8317 switch (rh) {
8318 case 0:
8319 DECODE_PRINTF("ROL\t");
8320 break;
8321 case 1:
8322 DECODE_PRINTF("ROR\t");
8323 break;
8324 case 2:
8325 DECODE_PRINTF("RCL\t");
8326 break;
8327 case 3:
8328 DECODE_PRINTF("RCR\t");
8329 break;
8330 case 4:
8331 DECODE_PRINTF("SHL\t");
8332 break;
8333 case 5:
8334 DECODE_PRINTF("SHR\t");
8335 break;
8336 case 6:
8337 DECODE_PRINTF("SAL\t");
8338 break;
8339 case 7:
8340 DECODE_PRINTF("SAR\t");
8341 break;
8344 #endif
8345 /* know operation, decode the mod byte to find the addressing
8346 mode. */
8347 switch (mod) {
8348 case 0:
8349 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8350 u32 destval;
8352 DECODE_PRINTF("DWORD PTR ");
8353 destoffset = decode_rm00_address(rl);
8354 amt = fetch_byte_imm();
8355 DECODE_PRINTF2(",%x\n", amt);
8356 destval = fetch_data_long(destoffset);
8357 TRACE_AND_STEP();
8358 destval = (*opcD1_long_operation[rh]) (destval, amt);
8359 store_data_long(destoffset, destval);
8360 } else {
8361 u16 destval;
8363 DECODE_PRINTF("WORD PTR ");
8364 destoffset = decode_rm00_address(rl);
8365 amt = fetch_byte_imm();
8366 DECODE_PRINTF2(",%x\n", amt);
8367 destval = fetch_data_word(destoffset);
8368 TRACE_AND_STEP();
8369 destval = (*opcD1_word_operation[rh]) (destval, amt);
8370 store_data_word(destoffset, destval);
8372 break;
8373 case 1:
8374 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8375 u32 destval;
8377 DECODE_PRINTF("DWORD PTR ");
8378 destoffset = decode_rm01_address(rl);
8379 amt = fetch_byte_imm();
8380 DECODE_PRINTF2(",%x\n", amt);
8381 destval = fetch_data_long(destoffset);
8382 TRACE_AND_STEP();
8383 destval = (*opcD1_long_operation[rh]) (destval, amt);
8384 store_data_long(destoffset, destval);
8385 } else {
8386 u16 destval;
8388 DECODE_PRINTF("WORD PTR ");
8389 destoffset = decode_rm01_address(rl);
8390 amt = fetch_byte_imm();
8391 DECODE_PRINTF2(",%x\n", amt);
8392 destval = fetch_data_word(destoffset);
8393 TRACE_AND_STEP();
8394 destval = (*opcD1_word_operation[rh]) (destval, amt);
8395 store_data_word(destoffset, destval);
8397 break;
8398 case 2:
8399 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8400 u32 destval;
8402 DECODE_PRINTF("DWORD PTR ");
8403 destoffset = decode_rm10_address(rl);
8404 amt = fetch_byte_imm();
8405 DECODE_PRINTF2(",%x\n", amt);
8406 destval = fetch_data_long(destoffset);
8407 TRACE_AND_STEP();
8408 destval = (*opcD1_long_operation[rh]) (destval, amt);
8409 store_data_long(destoffset, destval);
8410 } else {
8411 u16 destval;
8413 DECODE_PRINTF("WORD PTR ");
8414 destoffset = decode_rm10_address(rl);
8415 amt = fetch_byte_imm();
8416 DECODE_PRINTF2(",%x\n", amt);
8417 destval = fetch_data_word(destoffset);
8418 TRACE_AND_STEP();
8419 destval = (*opcD1_word_operation[rh]) (destval, amt);
8420 store_data_word(destoffset, destval);
8422 break;
8423 case 3: /* register to register */
8424 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8425 u32 *destreg;
8427 destreg = DECODE_RM_LONG_REGISTER(rl);
8428 amt = fetch_byte_imm();
8429 DECODE_PRINTF2(",%x\n", amt);
8430 TRACE_AND_STEP();
8431 *destreg = (*opcD1_long_operation[rh]) (*destreg, amt);
8432 } else {
8433 u16 *destreg;
8435 destreg = DECODE_RM_WORD_REGISTER(rl);
8436 amt = fetch_byte_imm();
8437 DECODE_PRINTF2(",%x\n", amt);
8438 TRACE_AND_STEP();
8439 *destreg = (*opcD1_word_operation[rh]) (*destreg, amt);
8441 break;
8443 DECODE_CLEAR_SEGOVR();
8444 END_OF_INSTR();
8447 /****************************************************************************
8448 REMARKS:
8449 Handles opcode 0xc2
8450 ****************************************************************************/
8451 static void x86emuOp_ret_near_IMM(u8 X86EMU_UNUSED(op1))
8453 u16 imm;
8455 START_OF_INSTR();
8456 DECODE_PRINTF("RET\t");
8457 imm = fetch_word_imm();
8458 DECODE_PRINTF2("%x\n", imm);
8459 RETURN_TRACE("RET",M.x86.saved_cs,M.x86.saved_ip);
8460 TRACE_AND_STEP();
8461 M.x86.R_IP = pop_word();
8462 M.x86.R_SP += imm;
8463 DECODE_CLEAR_SEGOVR();
8464 END_OF_INSTR();
8467 /****************************************************************************
8468 REMARKS:
8469 Handles opcode 0xc3
8470 ****************************************************************************/
8471 static void x86emuOp_ret_near(u8 X86EMU_UNUSED(op1))
8473 START_OF_INSTR();
8474 DECODE_PRINTF("RET\n");
8475 RETURN_TRACE("RET",M.x86.saved_cs,M.x86.saved_ip);
8476 TRACE_AND_STEP();
8477 M.x86.R_IP = pop_word();
8478 DECODE_CLEAR_SEGOVR();
8479 END_OF_INSTR();
8482 /****************************************************************************
8483 REMARKS:
8484 Handles opcode 0xc4
8485 ****************************************************************************/
8486 static void x86emuOp_les_R_IMM(u8 X86EMU_UNUSED(op1))
8488 int mod, rh, rl;
8489 u16 *dstreg;
8490 uint srcoffset;
8492 START_OF_INSTR();
8493 DECODE_PRINTF("LES\t");
8494 FETCH_DECODE_MODRM(mod, rh, rl);
8495 switch (mod) {
8496 case 0:
8497 dstreg = DECODE_RM_WORD_REGISTER(rh);
8498 DECODE_PRINTF(",");
8499 srcoffset = decode_rm00_address(rl);
8500 DECODE_PRINTF("\n");
8501 TRACE_AND_STEP();
8502 *dstreg = fetch_data_word(srcoffset);
8503 M.x86.R_ES = fetch_data_word(srcoffset + 2);
8504 break;
8505 case 1:
8506 dstreg = DECODE_RM_WORD_REGISTER(rh);
8507 DECODE_PRINTF(",");
8508 srcoffset = decode_rm01_address(rl);
8509 DECODE_PRINTF("\n");
8510 TRACE_AND_STEP();
8511 *dstreg = fetch_data_word(srcoffset);
8512 M.x86.R_ES = fetch_data_word(srcoffset + 2);
8513 break;
8514 case 2:
8515 dstreg = DECODE_RM_WORD_REGISTER(rh);
8516 DECODE_PRINTF(",");
8517 srcoffset = decode_rm10_address(rl);
8518 DECODE_PRINTF("\n");
8519 TRACE_AND_STEP();
8520 *dstreg = fetch_data_word(srcoffset);
8521 M.x86.R_ES = fetch_data_word(srcoffset + 2);
8522 break;
8523 case 3: /* register to register */
8524 /* UNDEFINED! */
8525 TRACE_AND_STEP();
8527 DECODE_CLEAR_SEGOVR();
8528 END_OF_INSTR();
8531 /****************************************************************************
8532 REMARKS:
8533 Handles opcode 0xc5
8534 ****************************************************************************/
8535 static void x86emuOp_lds_R_IMM(u8 X86EMU_UNUSED(op1))
8537 int mod, rh, rl;
8538 u16 *dstreg;
8539 uint srcoffset;
8541 START_OF_INSTR();
8542 DECODE_PRINTF("LDS\t");
8543 FETCH_DECODE_MODRM(mod, rh, rl);
8544 switch (mod) {
8545 case 0:
8546 dstreg = DECODE_RM_WORD_REGISTER(rh);
8547 DECODE_PRINTF(",");
8548 srcoffset = decode_rm00_address(rl);
8549 DECODE_PRINTF("\n");
8550 TRACE_AND_STEP();
8551 *dstreg = fetch_data_word(srcoffset);
8552 M.x86.R_DS = fetch_data_word(srcoffset + 2);
8553 break;
8554 case 1:
8555 dstreg = DECODE_RM_WORD_REGISTER(rh);
8556 DECODE_PRINTF(",");
8557 srcoffset = decode_rm01_address(rl);
8558 DECODE_PRINTF("\n");
8559 TRACE_AND_STEP();
8560 *dstreg = fetch_data_word(srcoffset);
8561 M.x86.R_DS = fetch_data_word(srcoffset + 2);
8562 break;
8563 case 2:
8564 dstreg = DECODE_RM_WORD_REGISTER(rh);
8565 DECODE_PRINTF(",");
8566 srcoffset = decode_rm10_address(rl);
8567 DECODE_PRINTF("\n");
8568 TRACE_AND_STEP();
8569 *dstreg = fetch_data_word(srcoffset);
8570 M.x86.R_DS = fetch_data_word(srcoffset + 2);
8571 break;
8572 case 3: /* register to register */
8573 /* UNDEFINED! */
8574 TRACE_AND_STEP();
8576 DECODE_CLEAR_SEGOVR();
8577 END_OF_INSTR();
8580 /****************************************************************************
8581 REMARKS:
8582 Handles opcode 0xc6
8583 ****************************************************************************/
8584 static void x86emuOp_mov_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
8586 int mod, rl, rh;
8587 u8 *destreg;
8588 uint destoffset;
8589 u8 imm;
8591 START_OF_INSTR();
8592 DECODE_PRINTF("MOV\t");
8593 FETCH_DECODE_MODRM(mod, rh, rl);
8594 if (rh != 0) {
8595 DECODE_PRINTF("ILLEGAL DECODE OF OPCODE c6\n");
8596 HALT_SYS();
8598 switch (mod) {
8599 case 0:
8600 DECODE_PRINTF("BYTE PTR ");
8601 destoffset = decode_rm00_address(rl);
8602 imm = fetch_byte_imm();
8603 DECODE_PRINTF2(",%2x\n", imm);
8604 TRACE_AND_STEP();
8605 store_data_byte(destoffset, imm);
8606 break;
8607 case 1:
8608 DECODE_PRINTF("BYTE PTR ");
8609 destoffset = decode_rm01_address(rl);
8610 imm = fetch_byte_imm();
8611 DECODE_PRINTF2(",%2x\n", imm);
8612 TRACE_AND_STEP();
8613 store_data_byte(destoffset, imm);
8614 break;
8615 case 2:
8616 DECODE_PRINTF("BYTE PTR ");
8617 destoffset = decode_rm10_address(rl);
8618 imm = fetch_byte_imm();
8619 DECODE_PRINTF2(",%2x\n", imm);
8620 TRACE_AND_STEP();
8621 store_data_byte(destoffset, imm);
8622 break;
8623 case 3: /* register to register */
8624 destreg = DECODE_RM_BYTE_REGISTER(rl);
8625 imm = fetch_byte_imm();
8626 DECODE_PRINTF2(",%2x\n", imm);
8627 TRACE_AND_STEP();
8628 *destreg = imm;
8629 break;
8631 DECODE_CLEAR_SEGOVR();
8632 END_OF_INSTR();
8635 /****************************************************************************
8636 REMARKS:
8637 Handles opcode 0xc7
8638 ****************************************************************************/
8639 static void x86emuOp_mov_word_RM_IMM(u8 X86EMU_UNUSED(op1))
8641 int mod, rl, rh;
8642 uint destoffset;
8644 START_OF_INSTR();
8645 DECODE_PRINTF("MOV\t");
8646 FETCH_DECODE_MODRM(mod, rh, rl);
8647 if (rh != 0) {
8648 DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n");
8649 HALT_SYS();
8651 switch (mod) {
8652 case 0:
8653 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8654 u32 imm;
8656 DECODE_PRINTF("DWORD PTR ");
8657 destoffset = decode_rm00_address(rl);
8658 imm = fetch_long_imm();
8659 DECODE_PRINTF2(",%x\n", imm);
8660 TRACE_AND_STEP();
8661 store_data_long(destoffset, imm);
8662 } else {
8663 u16 imm;
8665 DECODE_PRINTF("WORD PTR ");
8666 destoffset = decode_rm00_address(rl);
8667 imm = fetch_word_imm();
8668 DECODE_PRINTF2(",%x\n", imm);
8669 TRACE_AND_STEP();
8670 store_data_word(destoffset, imm);
8672 break;
8673 case 1:
8674 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8675 u32 imm;
8677 DECODE_PRINTF("DWORD PTR ");
8678 destoffset = decode_rm01_address(rl);
8679 imm = fetch_long_imm();
8680 DECODE_PRINTF2(",%x\n", imm);
8681 TRACE_AND_STEP();
8682 store_data_long(destoffset, imm);
8683 } else {
8684 u16 imm;
8686 DECODE_PRINTF("WORD PTR ");
8687 destoffset = decode_rm01_address(rl);
8688 imm = fetch_word_imm();
8689 DECODE_PRINTF2(",%x\n", imm);
8690 TRACE_AND_STEP();
8691 store_data_word(destoffset, imm);
8693 break;
8694 case 2:
8695 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8696 u32 imm;
8698 DECODE_PRINTF("DWORD PTR ");
8699 destoffset = decode_rm10_address(rl);
8700 imm = fetch_long_imm();
8701 DECODE_PRINTF2(",%x\n", imm);
8702 TRACE_AND_STEP();
8703 store_data_long(destoffset, imm);
8704 } else {
8705 u16 imm;
8707 DECODE_PRINTF("WORD PTR ");
8708 destoffset = decode_rm10_address(rl);
8709 imm = fetch_word_imm();
8710 DECODE_PRINTF2(",%x\n", imm);
8711 TRACE_AND_STEP();
8712 store_data_word(destoffset, imm);
8714 break;
8715 case 3: /* register to register */
8716 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8717 u32 *destreg;
8718 u32 imm;
8720 destreg = DECODE_RM_LONG_REGISTER(rl);
8721 imm = fetch_long_imm();
8722 DECODE_PRINTF2(",%x\n", imm);
8723 TRACE_AND_STEP();
8724 *destreg = imm;
8725 } else {
8726 u16 *destreg;
8727 u16 imm;
8729 destreg = DECODE_RM_WORD_REGISTER(rl);
8730 imm = fetch_word_imm();
8731 DECODE_PRINTF2(",%x\n", imm);
8732 TRACE_AND_STEP();
8733 *destreg = imm;
8735 break;
8737 DECODE_CLEAR_SEGOVR();
8738 END_OF_INSTR();
8741 /****************************************************************************
8742 REMARKS:
8743 Handles opcode 0xc8
8744 ****************************************************************************/
8745 static void x86emuOp_enter(u8 X86EMU_UNUSED(op1))
8747 u16 local,frame_pointer;
8748 u8 nesting;
8749 int i;
8751 START_OF_INSTR();
8752 local = fetch_word_imm();
8753 nesting = fetch_byte_imm();
8754 DECODE_PRINTF2("ENTER %x\n", local);
8755 DECODE_PRINTF2(",%x\n", nesting);
8756 TRACE_AND_STEP();
8757 push_word(M.x86.R_BP);
8758 frame_pointer = M.x86.R_SP;
8759 if (nesting > 0) {
8760 for (i = 1; i < nesting; i++) {
8761 M.x86.R_BP -= 2;
8762 push_word(fetch_data_word_abs(M.x86.R_SS, M.x86.R_BP));
8764 push_word(frame_pointer);
8766 M.x86.R_BP = frame_pointer;
8767 M.x86.R_SP = (u16)(M.x86.R_SP - local);
8768 DECODE_CLEAR_SEGOVR();
8769 END_OF_INSTR();
8772 /****************************************************************************
8773 REMARKS:
8774 Handles opcode 0xc9
8775 ****************************************************************************/
8776 static void x86emuOp_leave(u8 X86EMU_UNUSED(op1))
8778 START_OF_INSTR();
8779 DECODE_PRINTF("LEAVE\n");
8780 TRACE_AND_STEP();
8781 M.x86.R_SP = M.x86.R_BP;
8782 M.x86.R_BP = pop_word();
8783 DECODE_CLEAR_SEGOVR();
8784 END_OF_INSTR();
8787 /****************************************************************************
8788 REMARKS:
8789 Handles opcode 0xca
8790 ****************************************************************************/
8791 static void x86emuOp_ret_far_IMM(u8 X86EMU_UNUSED(op1))
8793 u16 imm;
8795 START_OF_INSTR();
8796 DECODE_PRINTF("RETF\t");
8797 imm = fetch_word_imm();
8798 DECODE_PRINTF2("%x\n", imm);
8799 RETURN_TRACE("RETF",M.x86.saved_cs,M.x86.saved_ip);
8800 TRACE_AND_STEP();
8801 M.x86.R_IP = pop_word();
8802 M.x86.R_CS = pop_word();
8803 M.x86.R_SP += imm;
8804 DECODE_CLEAR_SEGOVR();
8805 END_OF_INSTR();
8808 /****************************************************************************
8809 REMARKS:
8810 Handles opcode 0xcb
8811 ****************************************************************************/
8812 static void x86emuOp_ret_far(u8 X86EMU_UNUSED(op1))
8814 START_OF_INSTR();
8815 DECODE_PRINTF("RETF\n");
8816 RETURN_TRACE("RETF",M.x86.saved_cs,M.x86.saved_ip);
8817 TRACE_AND_STEP();
8818 M.x86.R_IP = pop_word();
8819 M.x86.R_CS = pop_word();
8820 DECODE_CLEAR_SEGOVR();
8821 END_OF_INSTR();
8824 /****************************************************************************
8825 REMARKS:
8826 Handles opcode 0xcc
8827 ****************************************************************************/
8828 static void x86emuOp_int3(u8 X86EMU_UNUSED(op1))
8830 START_OF_INSTR();
8831 DECODE_PRINTF("INT 3\n");
8832 TRACE_AND_STEP();
8833 if (_X86EMU_intrTab[3]) {
8834 (*_X86EMU_intrTab[3])(3);
8835 } else {
8836 push_word((u16)M.x86.R_FLG);
8837 CLEAR_FLAG(F_IF);
8838 CLEAR_FLAG(F_TF);
8839 push_word(M.x86.R_CS);
8840 M.x86.R_CS = mem_access_word(3 * 4 + 2);
8841 push_word(M.x86.R_IP);
8842 M.x86.R_IP = mem_access_word(3 * 4);
8844 DECODE_CLEAR_SEGOVR();
8845 END_OF_INSTR();
8848 /****************************************************************************
8849 REMARKS:
8850 Handles opcode 0xcd
8851 ****************************************************************************/
8852 static void x86emuOp_int_IMM(u8 X86EMU_UNUSED(op1))
8854 u8 intnum;
8856 START_OF_INSTR();
8857 DECODE_PRINTF("INT\t");
8858 intnum = fetch_byte_imm();
8859 DECODE_PRINTF2("%x\n", intnum);
8860 TRACE_AND_STEP();
8861 if (_X86EMU_intrTab[intnum]) {
8862 (*_X86EMU_intrTab[intnum])(intnum);
8863 } else {
8864 push_word((u16)M.x86.R_FLG);
8865 CLEAR_FLAG(F_IF);
8866 CLEAR_FLAG(F_TF);
8867 push_word(M.x86.R_CS);
8868 M.x86.R_CS = mem_access_word(intnum * 4 + 2);
8869 push_word(M.x86.R_IP);
8870 M.x86.R_IP = mem_access_word(intnum * 4);
8872 DECODE_CLEAR_SEGOVR();
8873 END_OF_INSTR();
8876 /****************************************************************************
8877 REMARKS:
8878 Handles opcode 0xce
8879 ****************************************************************************/
8880 static void x86emuOp_into(u8 X86EMU_UNUSED(op1))
8882 START_OF_INSTR();
8883 DECODE_PRINTF("INTO\n");
8884 TRACE_AND_STEP();
8885 if (ACCESS_FLAG(F_OF)) {
8886 if (_X86EMU_intrTab[4]) {
8887 (*_X86EMU_intrTab[4])(4);
8888 } else {
8889 push_word((u16)M.x86.R_FLG);
8890 CLEAR_FLAG(F_IF);
8891 CLEAR_FLAG(F_TF);
8892 push_word(M.x86.R_CS);
8893 M.x86.R_CS = mem_access_word(4 * 4 + 2);
8894 push_word(M.x86.R_IP);
8895 M.x86.R_IP = mem_access_word(4 * 4);
8898 DECODE_CLEAR_SEGOVR();
8899 END_OF_INSTR();
8902 /****************************************************************************
8903 REMARKS:
8904 Handles opcode 0xcf
8905 ****************************************************************************/
8906 static void x86emuOp_iret(u8 X86EMU_UNUSED(op1))
8908 START_OF_INSTR();
8909 DECODE_PRINTF("IRET\n");
8911 TRACE_AND_STEP();
8913 M.x86.R_IP = pop_word();
8914 M.x86.R_CS = pop_word();
8915 M.x86.R_FLG = pop_word();
8916 DECODE_CLEAR_SEGOVR();
8917 END_OF_INSTR();
8920 /****************************************************************************
8921 REMARKS:
8922 Handles opcode 0xd0
8923 ****************************************************************************/
8924 static void x86emuOp_opcD0_byte_RM_1(u8 X86EMU_UNUSED(op1))
8926 int mod, rl, rh;
8927 u8 *destreg;
8928 uint destoffset;
8929 u8 destval;
8932 * Yet another weirdo special case instruction format. Part of
8933 * the opcode held below in "RH". Doubly nested case would
8934 * result, except that the decoded instruction
8936 START_OF_INSTR();
8937 FETCH_DECODE_MODRM(mod, rh, rl);
8938 #ifdef DEBUG
8939 if (DEBUG_DECODE()) {
8940 /* XXX DECODE_PRINTF may be changed to something more
8941 general, so that it is important to leave the strings
8942 in the same format, even though the result is that the
8943 above test is done twice. */
8944 switch (rh) {
8945 case 0:
8946 DECODE_PRINTF("ROL\t");
8947 break;
8948 case 1:
8949 DECODE_PRINTF("ROR\t");
8950 break;
8951 case 2:
8952 DECODE_PRINTF("RCL\t");
8953 break;
8954 case 3:
8955 DECODE_PRINTF("RCR\t");
8956 break;
8957 case 4:
8958 DECODE_PRINTF("SHL\t");
8959 break;
8960 case 5:
8961 DECODE_PRINTF("SHR\t");
8962 break;
8963 case 6:
8964 DECODE_PRINTF("SAL\t");
8965 break;
8966 case 7:
8967 DECODE_PRINTF("SAR\t");
8968 break;
8971 #endif
8972 /* know operation, decode the mod byte to find the addressing
8973 mode. */
8974 switch (mod) {
8975 case 0:
8976 DECODE_PRINTF("BYTE PTR ");
8977 destoffset = decode_rm00_address(rl);
8978 DECODE_PRINTF(",1\n");
8979 destval = fetch_data_byte(destoffset);
8980 TRACE_AND_STEP();
8981 destval = (*opcD0_byte_operation[rh]) (destval, 1);
8982 store_data_byte(destoffset, destval);
8983 break;
8984 case 1:
8985 DECODE_PRINTF("BYTE PTR ");
8986 destoffset = decode_rm01_address(rl);
8987 DECODE_PRINTF(",1\n");
8988 destval = fetch_data_byte(destoffset);
8989 TRACE_AND_STEP();
8990 destval = (*opcD0_byte_operation[rh]) (destval, 1);
8991 store_data_byte(destoffset, destval);
8992 break;
8993 case 2:
8994 DECODE_PRINTF("BYTE PTR ");
8995 destoffset = decode_rm10_address(rl);
8996 DECODE_PRINTF(",1\n");
8997 destval = fetch_data_byte(destoffset);
8998 TRACE_AND_STEP();
8999 destval = (*opcD0_byte_operation[rh]) (destval, 1);
9000 store_data_byte(destoffset, destval);
9001 break;
9002 case 3: /* register to register */
9003 destreg = DECODE_RM_BYTE_REGISTER(rl);
9004 DECODE_PRINTF(",1\n");
9005 TRACE_AND_STEP();
9006 destval = (*opcD0_byte_operation[rh]) (*destreg, 1);
9007 *destreg = destval;
9008 break;
9010 DECODE_CLEAR_SEGOVR();
9011 END_OF_INSTR();
9014 /****************************************************************************
9015 REMARKS:
9016 Handles opcode 0xd1
9017 ****************************************************************************/
9018 static void x86emuOp_opcD1_word_RM_1(u8 X86EMU_UNUSED(op1))
9020 int mod, rl, rh;
9021 uint destoffset;
9024 * Yet another weirdo special case instruction format. Part of
9025 * the opcode held below in "RH". Doubly nested case would
9026 * result, except that the decoded instruction
9028 START_OF_INSTR();
9029 FETCH_DECODE_MODRM(mod, rh, rl);
9030 #ifdef DEBUG
9031 if (DEBUG_DECODE()) {
9032 /* XXX DECODE_PRINTF may be changed to something more
9033 general, so that it is important to leave the strings
9034 in the same format, even though the result is that the
9035 above test is done twice. */
9036 switch (rh) {
9037 case 0:
9038 DECODE_PRINTF("ROL\t");
9039 break;
9040 case 1:
9041 DECODE_PRINTF("ROR\t");
9042 break;
9043 case 2:
9044 DECODE_PRINTF("RCL\t");
9045 break;
9046 case 3:
9047 DECODE_PRINTF("RCR\t");
9048 break;
9049 case 4:
9050 DECODE_PRINTF("SHL\t");
9051 break;
9052 case 5:
9053 DECODE_PRINTF("SHR\t");
9054 break;
9055 case 6:
9056 DECODE_PRINTF("SAL\t");
9057 break;
9058 case 7:
9059 DECODE_PRINTF("SAR\t");
9060 break;
9063 #endif
9064 /* know operation, decode the mod byte to find the addressing
9065 mode. */
9066 switch (mod) {
9067 case 0:
9068 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9069 u32 destval;
9071 DECODE_PRINTF("DWORD PTR ");
9072 destoffset = decode_rm00_address(rl);
9073 DECODE_PRINTF(",1\n");
9074 destval = fetch_data_long(destoffset);
9075 TRACE_AND_STEP();
9076 destval = (*opcD1_long_operation[rh]) (destval, 1);
9077 store_data_long(destoffset, destval);
9078 } else {
9079 u16 destval;
9081 DECODE_PRINTF("WORD PTR ");
9082 destoffset = decode_rm00_address(rl);
9083 DECODE_PRINTF(",1\n");
9084 destval = fetch_data_word(destoffset);
9085 TRACE_AND_STEP();
9086 destval = (*opcD1_word_operation[rh]) (destval, 1);
9087 store_data_word(destoffset, destval);
9089 break;
9090 case 1:
9091 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9092 u32 destval;
9094 DECODE_PRINTF("DWORD PTR ");
9095 destoffset = decode_rm01_address(rl);
9096 DECODE_PRINTF(",1\n");
9097 destval = fetch_data_long(destoffset);
9098 TRACE_AND_STEP();
9099 destval = (*opcD1_long_operation[rh]) (destval, 1);
9100 store_data_long(destoffset, destval);
9101 } else {
9102 u16 destval;
9104 DECODE_PRINTF("WORD PTR ");
9105 destoffset = decode_rm01_address(rl);
9106 DECODE_PRINTF(",1\n");
9107 destval = fetch_data_word(destoffset);
9108 TRACE_AND_STEP();
9109 destval = (*opcD1_word_operation[rh]) (destval, 1);
9110 store_data_word(destoffset, destval);
9112 break;
9113 case 2:
9114 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9115 u32 destval;
9117 DECODE_PRINTF("DWORD PTR ");
9118 destoffset = decode_rm10_address(rl);
9119 DECODE_PRINTF(",1\n");
9120 destval = fetch_data_long(destoffset);
9121 TRACE_AND_STEP();
9122 destval = (*opcD1_long_operation[rh]) (destval, 1);
9123 store_data_long(destoffset, destval);
9124 } else {
9125 u16 destval;
9127 DECODE_PRINTF("BYTE PTR ");
9128 destoffset = decode_rm10_address(rl);
9129 DECODE_PRINTF(",1\n");
9130 destval = fetch_data_word(destoffset);
9131 TRACE_AND_STEP();
9132 destval = (*opcD1_word_operation[rh]) (destval, 1);
9133 store_data_word(destoffset, destval);
9135 break;
9136 case 3: /* register to register */
9137 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9138 u32 destval;
9139 u32 *destreg;
9141 destreg = DECODE_RM_LONG_REGISTER(rl);
9142 DECODE_PRINTF(",1\n");
9143 TRACE_AND_STEP();
9144 destval = (*opcD1_long_operation[rh]) (*destreg, 1);
9145 *destreg = destval;
9146 } else {
9147 u16 destval;
9148 u16 *destreg;
9150 destreg = DECODE_RM_WORD_REGISTER(rl);
9151 DECODE_PRINTF(",1\n");
9152 TRACE_AND_STEP();
9153 destval = (*opcD1_word_operation[rh]) (*destreg, 1);
9154 *destreg = destval;
9156 break;
9158 DECODE_CLEAR_SEGOVR();
9159 END_OF_INSTR();
9162 /****************************************************************************
9163 REMARKS:
9164 Handles opcode 0xd2
9165 ****************************************************************************/
9166 static void x86emuOp_opcD2_byte_RM_CL(u8 X86EMU_UNUSED(op1))
9168 int mod, rl, rh;
9169 u8 *destreg;
9170 uint destoffset;
9171 u8 destval;
9172 u8 amt;
9175 * Yet another weirdo special case instruction format. Part of
9176 * the opcode held below in "RH". Doubly nested case would
9177 * result, except that the decoded instruction
9179 START_OF_INSTR();
9180 FETCH_DECODE_MODRM(mod, rh, rl);
9181 #ifdef DEBUG
9182 if (DEBUG_DECODE()) {
9183 /* XXX DECODE_PRINTF may be changed to something more
9184 general, so that it is important to leave the strings
9185 in the same format, even though the result is that the
9186 above test is done twice. */
9187 switch (rh) {
9188 case 0:
9189 DECODE_PRINTF("ROL\t");
9190 break;
9191 case 1:
9192 DECODE_PRINTF("ROR\t");
9193 break;
9194 case 2:
9195 DECODE_PRINTF("RCL\t");
9196 break;
9197 case 3:
9198 DECODE_PRINTF("RCR\t");
9199 break;
9200 case 4:
9201 DECODE_PRINTF("SHL\t");
9202 break;
9203 case 5:
9204 DECODE_PRINTF("SHR\t");
9205 break;
9206 case 6:
9207 DECODE_PRINTF("SAL\t");
9208 break;
9209 case 7:
9210 DECODE_PRINTF("SAR\t");
9211 break;
9214 #endif
9215 /* know operation, decode the mod byte to find the addressing
9216 mode. */
9217 amt = M.x86.R_CL;
9218 switch (mod) {
9219 case 0:
9220 DECODE_PRINTF("BYTE PTR ");
9221 destoffset = decode_rm00_address(rl);
9222 DECODE_PRINTF(",CL\n");
9223 destval = fetch_data_byte(destoffset);
9224 TRACE_AND_STEP();
9225 destval = (*opcD0_byte_operation[rh]) (destval, amt);
9226 store_data_byte(destoffset, destval);
9227 break;
9228 case 1:
9229 DECODE_PRINTF("BYTE PTR ");
9230 destoffset = decode_rm01_address(rl);
9231 DECODE_PRINTF(",CL\n");
9232 destval = fetch_data_byte(destoffset);
9233 TRACE_AND_STEP();
9234 destval = (*opcD0_byte_operation[rh]) (destval, amt);
9235 store_data_byte(destoffset, destval);
9236 break;
9237 case 2:
9238 DECODE_PRINTF("BYTE PTR ");
9239 destoffset = decode_rm10_address(rl);
9240 DECODE_PRINTF(",CL\n");
9241 destval = fetch_data_byte(destoffset);
9242 TRACE_AND_STEP();
9243 destval = (*opcD0_byte_operation[rh]) (destval, amt);
9244 store_data_byte(destoffset, destval);
9245 break;
9246 case 3: /* register to register */
9247 destreg = DECODE_RM_BYTE_REGISTER(rl);
9248 DECODE_PRINTF(",CL\n");
9249 TRACE_AND_STEP();
9250 destval = (*opcD0_byte_operation[rh]) (*destreg, amt);
9251 *destreg = destval;
9252 break;
9254 DECODE_CLEAR_SEGOVR();
9255 END_OF_INSTR();
9258 /****************************************************************************
9259 REMARKS:
9260 Handles opcode 0xd3
9261 ****************************************************************************/
9262 static void x86emuOp_opcD3_word_RM_CL(u8 X86EMU_UNUSED(op1))
9264 int mod, rl, rh;
9265 uint destoffset;
9266 u8 amt;
9269 * Yet another weirdo special case instruction format. Part of
9270 * the opcode held below in "RH". Doubly nested case would
9271 * result, except that the decoded instruction
9273 START_OF_INSTR();
9274 FETCH_DECODE_MODRM(mod, rh, rl);
9275 #ifdef DEBUG
9276 if (DEBUG_DECODE()) {
9277 /* XXX DECODE_PRINTF may be changed to something more
9278 general, so that it is important to leave the strings
9279 in the same format, even though the result is that the
9280 above test is done twice. */
9281 switch (rh) {
9282 case 0:
9283 DECODE_PRINTF("ROL\t");
9284 break;
9285 case 1:
9286 DECODE_PRINTF("ROR\t");
9287 break;
9288 case 2:
9289 DECODE_PRINTF("RCL\t");
9290 break;
9291 case 3:
9292 DECODE_PRINTF("RCR\t");
9293 break;
9294 case 4:
9295 DECODE_PRINTF("SHL\t");
9296 break;
9297 case 5:
9298 DECODE_PRINTF("SHR\t");
9299 break;
9300 case 6:
9301 DECODE_PRINTF("SAL\t");
9302 break;
9303 case 7:
9304 DECODE_PRINTF("SAR\t");
9305 break;
9308 #endif
9309 /* know operation, decode the mod byte to find the addressing
9310 mode. */
9311 amt = M.x86.R_CL;
9312 switch (mod) {
9313 case 0:
9314 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9315 u32 destval;
9317 DECODE_PRINTF("DWORD PTR ");
9318 destoffset = decode_rm00_address(rl);
9319 DECODE_PRINTF(",CL\n");
9320 destval = fetch_data_long(destoffset);
9321 TRACE_AND_STEP();
9322 destval = (*opcD1_long_operation[rh]) (destval, amt);
9323 store_data_long(destoffset, destval);
9324 } else {
9325 u16 destval;
9327 DECODE_PRINTF("WORD PTR ");
9328 destoffset = decode_rm00_address(rl);
9329 DECODE_PRINTF(",CL\n");
9330 destval = fetch_data_word(destoffset);
9331 TRACE_AND_STEP();
9332 destval = (*opcD1_word_operation[rh]) (destval, amt);
9333 store_data_word(destoffset, destval);
9335 break;
9336 case 1:
9337 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9338 u32 destval;
9340 DECODE_PRINTF("DWORD PTR ");
9341 destoffset = decode_rm01_address(rl);
9342 DECODE_PRINTF(",CL\n");
9343 destval = fetch_data_long(destoffset);
9344 TRACE_AND_STEP();
9345 destval = (*opcD1_long_operation[rh]) (destval, amt);
9346 store_data_long(destoffset, destval);
9347 } else {
9348 u16 destval;
9350 DECODE_PRINTF("WORD PTR ");
9351 destoffset = decode_rm01_address(rl);
9352 DECODE_PRINTF(",CL\n");
9353 destval = fetch_data_word(destoffset);
9354 TRACE_AND_STEP();
9355 destval = (*opcD1_word_operation[rh]) (destval, amt);
9356 store_data_word(destoffset, destval);
9358 break;
9359 case 2:
9360 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9361 u32 destval;
9363 DECODE_PRINTF("DWORD PTR ");
9364 destoffset = decode_rm10_address(rl);
9365 DECODE_PRINTF(",CL\n");
9366 destval = fetch_data_long(destoffset);
9367 TRACE_AND_STEP();
9368 destval = (*opcD1_long_operation[rh]) (destval, amt);
9369 store_data_long(destoffset, destval);
9370 } else {
9371 u16 destval;
9373 DECODE_PRINTF("WORD PTR ");
9374 destoffset = decode_rm10_address(rl);
9375 DECODE_PRINTF(",CL\n");
9376 destval = fetch_data_word(destoffset);
9377 TRACE_AND_STEP();
9378 destval = (*opcD1_word_operation[rh]) (destval, amt);
9379 store_data_word(destoffset, destval);
9381 break;
9382 case 3: /* register to register */
9383 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9384 u32 *destreg;
9386 destreg = DECODE_RM_LONG_REGISTER(rl);
9387 DECODE_PRINTF(",CL\n");
9388 TRACE_AND_STEP();
9389 *destreg = (*opcD1_long_operation[rh]) (*destreg, amt);
9390 } else {
9391 u16 *destreg;
9393 destreg = DECODE_RM_WORD_REGISTER(rl);
9394 DECODE_PRINTF(",CL\n");
9395 TRACE_AND_STEP();
9396 *destreg = (*opcD1_word_operation[rh]) (*destreg, amt);
9398 break;
9400 DECODE_CLEAR_SEGOVR();
9401 END_OF_INSTR();
9404 /****************************************************************************
9405 REMARKS:
9406 Handles opcode 0xd4
9407 ****************************************************************************/
9408 static void x86emuOp_aam(u8 X86EMU_UNUSED(op1))
9410 u8 a;
9412 START_OF_INSTR();
9413 DECODE_PRINTF("AAM\n");
9414 a = fetch_byte_imm(); /* this is a stupid encoding. */
9415 if (a != 10) {
9416 /* fix: add base decoding
9417 aam_word(u8 val, int base a) */
9418 DECODE_PRINTF("ERROR DECODING AAM\n");
9419 TRACE_REGS();
9420 HALT_SYS();
9422 TRACE_AND_STEP();
9423 /* note the type change here --- returning AL and AH in AX. */
9424 M.x86.R_AX = aam_word(M.x86.R_AL);
9425 DECODE_CLEAR_SEGOVR();
9426 END_OF_INSTR();
9429 /****************************************************************************
9430 REMARKS:
9431 Handles opcode 0xd5
9432 ****************************************************************************/
9433 static void x86emuOp_aad(u8 X86EMU_UNUSED(op1))
9435 u8 a;
9437 START_OF_INSTR();
9438 DECODE_PRINTF("AAD\n");
9439 a = fetch_byte_imm();
9440 if (a != 10) {
9441 /* fix: add base decoding
9442 aad_word(u16 val, int base a) */
9443 DECODE_PRINTF("ERROR DECODING AAM\n");
9444 TRACE_REGS();
9445 HALT_SYS();
9447 TRACE_AND_STEP();
9448 M.x86.R_AX = aad_word(M.x86.R_AX);
9449 DECODE_CLEAR_SEGOVR();
9450 END_OF_INSTR();
9453 /* opcode 0xd6 ILLEGAL OPCODE */
9455 /****************************************************************************
9456 REMARKS:
9457 Handles opcode 0xd7
9458 ****************************************************************************/
9459 static void x86emuOp_xlat(u8 X86EMU_UNUSED(op1))
9461 u16 addr;
9463 START_OF_INSTR();
9464 DECODE_PRINTF("XLAT\n");
9465 TRACE_AND_STEP();
9466 addr = (u16)(M.x86.R_BX + (u8)M.x86.R_AL);
9467 M.x86.R_AL = fetch_data_byte(addr);
9468 DECODE_CLEAR_SEGOVR();
9469 END_OF_INSTR();
9472 /* instuctions D8 .. DF are in i87_ops.c */
9474 /****************************************************************************
9475 REMARKS:
9476 Handles opcode 0xe0
9477 ****************************************************************************/
9478 static void x86emuOp_loopne(u8 X86EMU_UNUSED(op1))
9480 s16 ip;
9482 START_OF_INSTR();
9483 DECODE_PRINTF("LOOPNE\t");
9484 ip = (s8) fetch_byte_imm();
9485 ip += (s16) M.x86.R_IP;
9486 DECODE_PRINTF2("%04x\n", ip);
9487 TRACE_AND_STEP();
9488 M.x86.R_CX -= 1;
9489 if (M.x86.R_CX != 0 && !ACCESS_FLAG(F_ZF)) /* CX != 0 and !ZF */
9490 M.x86.R_IP = ip;
9491 DECODE_CLEAR_SEGOVR();
9492 END_OF_INSTR();
9495 /****************************************************************************
9496 REMARKS:
9497 Handles opcode 0xe1
9498 ****************************************************************************/
9499 static void x86emuOp_loope(u8 X86EMU_UNUSED(op1))
9501 s16 ip;
9503 START_OF_INSTR();
9504 DECODE_PRINTF("LOOPE\t");
9505 ip = (s8) fetch_byte_imm();
9506 ip += (s16) M.x86.R_IP;
9507 DECODE_PRINTF2("%04x\n", ip);
9508 TRACE_AND_STEP();
9509 M.x86.R_CX -= 1;
9510 if (M.x86.R_CX != 0 && ACCESS_FLAG(F_ZF)) /* CX != 0 and ZF */
9511 M.x86.R_IP = ip;
9512 DECODE_CLEAR_SEGOVR();
9513 END_OF_INSTR();
9516 /****************************************************************************
9517 REMARKS:
9518 Handles opcode 0xe2
9519 ****************************************************************************/
9520 static void x86emuOp_loop(u8 X86EMU_UNUSED(op1))
9522 s16 ip;
9524 START_OF_INSTR();
9525 DECODE_PRINTF("LOOP\t");
9526 ip = (s8) fetch_byte_imm();
9527 ip += (s16) M.x86.R_IP;
9528 DECODE_PRINTF2("%04x\n", ip);
9529 TRACE_AND_STEP();
9530 M.x86.R_CX -= 1;
9531 if (M.x86.R_CX != 0)
9532 M.x86.R_IP = ip;
9533 DECODE_CLEAR_SEGOVR();
9534 END_OF_INSTR();
9537 /****************************************************************************
9538 REMARKS:
9539 Handles opcode 0xe3
9540 ****************************************************************************/
9541 static void x86emuOp_jcxz(u8 X86EMU_UNUSED(op1))
9543 u16 target;
9544 s8 offset;
9546 /* jump to byte offset if overflow flag is set */
9547 START_OF_INSTR();
9548 DECODE_PRINTF("JCXZ\t");
9549 offset = (s8)fetch_byte_imm();
9550 target = (u16)(M.x86.R_IP + offset);
9551 DECODE_PRINTF2("%x\n", target);
9552 TRACE_AND_STEP();
9553 if (M.x86.R_CX == 0)
9554 M.x86.R_IP = target;
9555 DECODE_CLEAR_SEGOVR();
9556 END_OF_INSTR();
9559 /****************************************************************************
9560 REMARKS:
9561 Handles opcode 0xe4
9562 ****************************************************************************/
9563 static void x86emuOp_in_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
9565 u8 port;
9567 START_OF_INSTR();
9568 DECODE_PRINTF("IN\t");
9569 port = (u8) fetch_byte_imm();
9570 DECODE_PRINTF2("%x,AL\n", port);
9571 TRACE_AND_STEP();
9572 M.x86.R_AL = (*sys_inb)(port);
9573 DECODE_CLEAR_SEGOVR();
9574 END_OF_INSTR();
9577 /****************************************************************************
9578 REMARKS:
9579 Handles opcode 0xe5
9580 ****************************************************************************/
9581 static void x86emuOp_in_word_AX_IMM(u8 X86EMU_UNUSED(op1))
9583 u8 port;
9585 START_OF_INSTR();
9586 DECODE_PRINTF("IN\t");
9587 port = (u8) fetch_byte_imm();
9588 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9589 DECODE_PRINTF2("EAX,%x\n", port);
9590 } else {
9591 DECODE_PRINTF2("AX,%x\n", port);
9593 TRACE_AND_STEP();
9594 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9595 M.x86.R_EAX = (*sys_inl)(port);
9596 } else {
9597 M.x86.R_AX = (*sys_inw)(port);
9599 DECODE_CLEAR_SEGOVR();
9600 END_OF_INSTR();
9603 /****************************************************************************
9604 REMARKS:
9605 Handles opcode 0xe6
9606 ****************************************************************************/
9607 static void x86emuOp_out_byte_IMM_AL(u8 X86EMU_UNUSED(op1))
9609 u8 port;
9611 START_OF_INSTR();
9612 DECODE_PRINTF("OUT\t");
9613 port = (u8) fetch_byte_imm();
9614 DECODE_PRINTF2("%x,AL\n", port);
9615 TRACE_AND_STEP();
9616 (*sys_outb)(port, M.x86.R_AL);
9617 DECODE_CLEAR_SEGOVR();
9618 END_OF_INSTR();
9621 /****************************************************************************
9622 REMARKS:
9623 Handles opcode 0xe7
9624 ****************************************************************************/
9625 static void x86emuOp_out_word_IMM_AX(u8 X86EMU_UNUSED(op1))
9627 u8 port;
9629 START_OF_INSTR();
9630 DECODE_PRINTF("OUT\t");
9631 port = (u8) fetch_byte_imm();
9632 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9633 DECODE_PRINTF2("%x,EAX\n", port);
9634 } else {
9635 DECODE_PRINTF2("%x,AX\n", port);
9637 TRACE_AND_STEP();
9638 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9639 (*sys_outl)(port, M.x86.R_EAX);
9640 } else {
9641 (*sys_outw)(port, M.x86.R_AX);
9643 DECODE_CLEAR_SEGOVR();
9644 END_OF_INSTR();
9647 /****************************************************************************
9648 REMARKS:
9649 Handles opcode 0xe8
9650 ****************************************************************************/
9651 static void x86emuOp_call_near_IMM(u8 X86EMU_UNUSED(op1))
9653 s16 ip;
9655 START_OF_INSTR();
9656 DECODE_PRINTF("CALL\t");
9657 ip = (s16) fetch_word_imm();
9658 ip += (s16) M.x86.R_IP; /* CHECK SIGN */
9659 DECODE_PRINTF2("%04x\n", (u16)ip);
9660 CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, M.x86.R_CS, ip, "");
9661 TRACE_AND_STEP();
9662 push_word(M.x86.R_IP);
9663 M.x86.R_IP = ip;
9664 DECODE_CLEAR_SEGOVR();
9665 END_OF_INSTR();
9668 /****************************************************************************
9669 REMARKS:
9670 Handles opcode 0xe9
9671 ****************************************************************************/
9672 static void x86emuOp_jump_near_IMM(u8 X86EMU_UNUSED(op1))
9674 int ip;
9676 START_OF_INSTR();
9677 DECODE_PRINTF("JMP\t");
9678 ip = (s16)fetch_word_imm();
9679 ip += (s16)M.x86.R_IP;
9680 DECODE_PRINTF2("%04x\n", (u16)ip);
9681 TRACE_AND_STEP();
9682 M.x86.R_IP = (u16)ip;
9683 DECODE_CLEAR_SEGOVR();
9684 END_OF_INSTR();
9687 /****************************************************************************
9688 REMARKS:
9689 Handles opcode 0xea
9690 ****************************************************************************/
9691 static void x86emuOp_jump_far_IMM(u8 X86EMU_UNUSED(op1))
9693 u16 cs, ip;
9695 START_OF_INSTR();
9696 DECODE_PRINTF("JMP\tFAR ");
9697 ip = fetch_word_imm();
9698 cs = fetch_word_imm();
9699 DECODE_PRINTF2("%04x:", cs);
9700 DECODE_PRINTF2("%04x\n", ip);
9701 TRACE_AND_STEP();
9702 M.x86.R_IP = ip;
9703 M.x86.R_CS = cs;
9704 DECODE_CLEAR_SEGOVR();
9705 END_OF_INSTR();
9708 /****************************************************************************
9709 REMARKS:
9710 Handles opcode 0xeb
9711 ****************************************************************************/
9712 static void x86emuOp_jump_byte_IMM(u8 X86EMU_UNUSED(op1))
9714 u16 target;
9715 s8 offset;
9717 START_OF_INSTR();
9718 DECODE_PRINTF("JMP\t");
9719 offset = (s8)fetch_byte_imm();
9720 target = (u16)(M.x86.R_IP + offset);
9721 DECODE_PRINTF2("%x\n", target);
9722 TRACE_AND_STEP();
9723 M.x86.R_IP = target;
9724 DECODE_CLEAR_SEGOVR();
9725 END_OF_INSTR();
9728 /****************************************************************************
9729 REMARKS:
9730 Handles opcode 0xec
9731 ****************************************************************************/
9732 static void x86emuOp_in_byte_AL_DX(u8 X86EMU_UNUSED(op1))
9734 START_OF_INSTR();
9735 DECODE_PRINTF("IN\tAL,DX\n");
9736 TRACE_AND_STEP();
9737 M.x86.R_AL = (*sys_inb)(M.x86.R_DX);
9738 DECODE_CLEAR_SEGOVR();
9739 END_OF_INSTR();
9742 /****************************************************************************
9743 REMARKS:
9744 Handles opcode 0xed
9745 ****************************************************************************/
9746 static void x86emuOp_in_word_AX_DX(u8 X86EMU_UNUSED(op1))
9748 START_OF_INSTR();
9749 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9750 DECODE_PRINTF("IN\tEAX,DX\n");
9751 } else {
9752 DECODE_PRINTF("IN\tAX,DX\n");
9754 TRACE_AND_STEP();
9755 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9756 M.x86.R_EAX = (*sys_inl)(M.x86.R_DX);
9757 } else {
9758 M.x86.R_AX = (*sys_inw)(M.x86.R_DX);
9760 DECODE_CLEAR_SEGOVR();
9761 END_OF_INSTR();
9764 /****************************************************************************
9765 REMARKS:
9766 Handles opcode 0xee
9767 ****************************************************************************/
9768 static void x86emuOp_out_byte_DX_AL(u8 X86EMU_UNUSED(op1))
9770 START_OF_INSTR();
9771 DECODE_PRINTF("OUT\tDX,AL\n");
9772 TRACE_AND_STEP();
9773 (*sys_outb)(M.x86.R_DX, M.x86.R_AL);
9774 DECODE_CLEAR_SEGOVR();
9775 END_OF_INSTR();
9778 /****************************************************************************
9779 REMARKS:
9780 Handles opcode 0xef
9781 ****************************************************************************/
9782 static void x86emuOp_out_word_DX_AX(u8 X86EMU_UNUSED(op1))
9784 START_OF_INSTR();
9785 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9786 DECODE_PRINTF("OUT\tDX,EAX\n");
9787 } else {
9788 DECODE_PRINTF("OUT\tDX,AX\n");
9790 TRACE_AND_STEP();
9791 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9792 (*sys_outl)(M.x86.R_DX, M.x86.R_EAX);
9793 } else {
9794 (*sys_outw)(M.x86.R_DX, M.x86.R_AX);
9796 DECODE_CLEAR_SEGOVR();
9797 END_OF_INSTR();
9800 /****************************************************************************
9801 REMARKS:
9802 Handles opcode 0xf0
9803 ****************************************************************************/
9804 static void x86emuOp_lock(u8 X86EMU_UNUSED(op1))
9806 START_OF_INSTR();
9807 DECODE_PRINTF("LOCK:\n");
9808 TRACE_AND_STEP();
9809 DECODE_CLEAR_SEGOVR();
9810 END_OF_INSTR();
9813 /*opcode 0xf1 ILLEGAL OPERATION */
9815 /****************************************************************************
9816 REMARKS:
9817 Handles opcode 0xf2
9818 ****************************************************************************/
9819 static void x86emuOp_repne(u8 X86EMU_UNUSED(op1))
9821 START_OF_INSTR();
9822 DECODE_PRINTF("REPNE\n");
9823 TRACE_AND_STEP();
9824 M.x86.mode |= SYSMODE_PREFIX_REPNE;
9825 DECODE_CLEAR_SEGOVR();
9826 END_OF_INSTR();
9829 /****************************************************************************
9830 REMARKS:
9831 Handles opcode 0xf3
9832 ****************************************************************************/
9833 static void x86emuOp_repe(u8 X86EMU_UNUSED(op1))
9835 START_OF_INSTR();
9836 DECODE_PRINTF("REPE\n");
9837 TRACE_AND_STEP();
9838 M.x86.mode |= SYSMODE_PREFIX_REPE;
9839 DECODE_CLEAR_SEGOVR();
9840 END_OF_INSTR();
9843 /****************************************************************************
9844 REMARKS:
9845 Handles opcode 0xf4
9846 ****************************************************************************/
9847 static void x86emuOp_halt(u8 X86EMU_UNUSED(op1))
9849 START_OF_INSTR();
9850 DECODE_PRINTF("HALT\n");
9851 TRACE_AND_STEP();
9852 HALT_SYS();
9853 DECODE_CLEAR_SEGOVR();
9854 END_OF_INSTR();
9857 /****************************************************************************
9858 REMARKS:
9859 Handles opcode 0xf5
9860 ****************************************************************************/
9861 static void x86emuOp_cmc(u8 X86EMU_UNUSED(op1))
9863 /* complement the carry flag. */
9864 START_OF_INSTR();
9865 DECODE_PRINTF("CMC\n");
9866 TRACE_AND_STEP();
9867 TOGGLE_FLAG(F_CF);
9868 DECODE_CLEAR_SEGOVR();
9869 END_OF_INSTR();
9872 /****************************************************************************
9873 REMARKS:
9874 Handles opcode 0xf6
9875 ****************************************************************************/
9876 static void x86emuOp_opcF6_byte_RM(u8 X86EMU_UNUSED(op1))
9878 int mod, rl, rh;
9879 u8 *destreg;
9880 uint destoffset;
9881 u8 destval, srcval;
9883 /* long, drawn out code follows. Double switch for a total
9884 of 32 cases. */
9885 START_OF_INSTR();
9886 FETCH_DECODE_MODRM(mod, rh, rl);
9887 switch (mod) {
9888 case 0: /* mod=00 */
9889 switch (rh) {
9890 case 0: /* test byte imm */
9891 DECODE_PRINTF("TEST\tBYTE PTR ");
9892 destoffset = decode_rm00_address(rl);
9893 DECODE_PRINTF(",");
9894 srcval = fetch_byte_imm();
9895 DECODE_PRINTF2("%02x\n", srcval);
9896 destval = fetch_data_byte(destoffset);
9897 TRACE_AND_STEP();
9898 test_byte(destval, srcval);
9899 break;
9900 case 1:
9901 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
9902 HALT_SYS();
9903 break;
9904 case 2:
9905 DECODE_PRINTF("NOT\tBYTE PTR ");
9906 destoffset = decode_rm00_address(rl);
9907 DECODE_PRINTF("\n");
9908 destval = fetch_data_byte(destoffset);
9909 TRACE_AND_STEP();
9910 destval = not_byte(destval);
9911 store_data_byte(destoffset, destval);
9912 break;
9913 case 3:
9914 DECODE_PRINTF("NEG\tBYTE PTR ");
9915 destoffset = decode_rm00_address(rl);
9916 DECODE_PRINTF("\n");
9917 destval = fetch_data_byte(destoffset);
9918 TRACE_AND_STEP();
9919 destval = neg_byte(destval);
9920 store_data_byte(destoffset, destval);
9921 break;
9922 case 4:
9923 DECODE_PRINTF("MUL\tBYTE PTR ");
9924 destoffset = decode_rm00_address(rl);
9925 DECODE_PRINTF("\n");
9926 destval = fetch_data_byte(destoffset);
9927 TRACE_AND_STEP();
9928 mul_byte(destval);
9929 break;
9930 case 5:
9931 DECODE_PRINTF("IMUL\tBYTE PTR ");
9932 destoffset = decode_rm00_address(rl);
9933 DECODE_PRINTF("\n");
9934 destval = fetch_data_byte(destoffset);
9935 TRACE_AND_STEP();
9936 imul_byte(destval);
9937 break;
9938 case 6:
9939 DECODE_PRINTF("DIV\tBYTE PTR ");
9940 destoffset = decode_rm00_address(rl);
9941 DECODE_PRINTF("\n");
9942 destval = fetch_data_byte(destoffset);
9943 TRACE_AND_STEP();
9944 div_byte(destval);
9945 break;
9946 case 7:
9947 DECODE_PRINTF("IDIV\tBYTE PTR ");
9948 destoffset = decode_rm00_address(rl);
9949 DECODE_PRINTF("\n");
9950 destval = fetch_data_byte(destoffset);
9951 TRACE_AND_STEP();
9952 idiv_byte(destval);
9953 break;
9955 break; /* end mod==00 */
9956 case 1: /* mod=01 */
9957 switch (rh) {
9958 case 0: /* test byte imm */
9959 DECODE_PRINTF("TEST\tBYTE PTR ");
9960 destoffset = decode_rm01_address(rl);
9961 DECODE_PRINTF(",");
9962 srcval = fetch_byte_imm();
9963 DECODE_PRINTF2("%02x\n", srcval);
9964 destval = fetch_data_byte(destoffset);
9965 TRACE_AND_STEP();
9966 test_byte(destval, srcval);
9967 break;
9968 case 1:
9969 DECODE_PRINTF("ILLEGAL OP MOD=01 RH=01 OP=F6\n");
9970 HALT_SYS();
9971 break;
9972 case 2:
9973 DECODE_PRINTF("NOT\tBYTE PTR ");
9974 destoffset = decode_rm01_address(rl);
9975 DECODE_PRINTF("\n");
9976 destval = fetch_data_byte(destoffset);
9977 TRACE_AND_STEP();
9978 destval = not_byte(destval);
9979 store_data_byte(destoffset, destval);
9980 break;
9981 case 3:
9982 DECODE_PRINTF("NEG\tBYTE PTR ");
9983 destoffset = decode_rm01_address(rl);
9984 DECODE_PRINTF("\n");
9985 destval = fetch_data_byte(destoffset);
9986 TRACE_AND_STEP();
9987 destval = neg_byte(destval);
9988 store_data_byte(destoffset, destval);
9989 break;
9990 case 4:
9991 DECODE_PRINTF("MUL\tBYTE PTR ");
9992 destoffset = decode_rm01_address(rl);
9993 DECODE_PRINTF("\n");
9994 destval = fetch_data_byte(destoffset);
9995 TRACE_AND_STEP();
9996 mul_byte(destval);
9997 break;
9998 case 5:
9999 DECODE_PRINTF("IMUL\tBYTE PTR ");
10000 destoffset = decode_rm01_address(rl);
10001 DECODE_PRINTF("\n");
10002 destval = fetch_data_byte(destoffset);
10003 TRACE_AND_STEP();
10004 imul_byte(destval);
10005 break;
10006 case 6:
10007 DECODE_PRINTF("DIV\tBYTE PTR ");
10008 destoffset = decode_rm01_address(rl);
10009 DECODE_PRINTF("\n");
10010 destval = fetch_data_byte(destoffset);
10011 TRACE_AND_STEP();
10012 div_byte(destval);
10013 break;
10014 case 7:
10015 DECODE_PRINTF("IDIV\tBYTE PTR ");
10016 destoffset = decode_rm01_address(rl);
10017 DECODE_PRINTF("\n");
10018 destval = fetch_data_byte(destoffset);
10019 TRACE_AND_STEP();
10020 idiv_byte(destval);
10021 break;
10023 break; /* end mod==01 */
10024 case 2: /* mod=10 */
10025 switch (rh) {
10026 case 0: /* test byte imm */
10027 DECODE_PRINTF("TEST\tBYTE PTR ");
10028 destoffset = decode_rm10_address(rl);
10029 DECODE_PRINTF(",");
10030 srcval = fetch_byte_imm();
10031 DECODE_PRINTF2("%02x\n", srcval);
10032 destval = fetch_data_byte(destoffset);
10033 TRACE_AND_STEP();
10034 test_byte(destval, srcval);
10035 break;
10036 case 1:
10037 DECODE_PRINTF("ILLEGAL OP MOD=10 RH=01 OP=F6\n");
10038 HALT_SYS();
10039 break;
10040 case 2:
10041 DECODE_PRINTF("NOT\tBYTE PTR ");
10042 destoffset = decode_rm10_address(rl);
10043 DECODE_PRINTF("\n");
10044 destval = fetch_data_byte(destoffset);
10045 TRACE_AND_STEP();
10046 destval = not_byte(destval);
10047 store_data_byte(destoffset, destval);
10048 break;
10049 case 3:
10050 DECODE_PRINTF("NEG\tBYTE PTR ");
10051 destoffset = decode_rm10_address(rl);
10052 DECODE_PRINTF("\n");
10053 destval = fetch_data_byte(destoffset);
10054 TRACE_AND_STEP();
10055 destval = neg_byte(destval);
10056 store_data_byte(destoffset, destval);
10057 break;
10058 case 4:
10059 DECODE_PRINTF("MUL\tBYTE PTR ");
10060 destoffset = decode_rm10_address(rl);
10061 DECODE_PRINTF("\n");
10062 destval = fetch_data_byte(destoffset);
10063 TRACE_AND_STEP();
10064 mul_byte(destval);
10065 break;
10066 case 5:
10067 DECODE_PRINTF("IMUL\tBYTE PTR ");
10068 destoffset = decode_rm10_address(rl);
10069 DECODE_PRINTF("\n");
10070 destval = fetch_data_byte(destoffset);
10071 TRACE_AND_STEP();
10072 imul_byte(destval);
10073 break;
10074 case 6:
10075 DECODE_PRINTF("DIV\tBYTE PTR ");
10076 destoffset = decode_rm10_address(rl);
10077 DECODE_PRINTF("\n");
10078 destval = fetch_data_byte(destoffset);
10079 TRACE_AND_STEP();
10080 div_byte(destval);
10081 break;
10082 case 7:
10083 DECODE_PRINTF("IDIV\tBYTE PTR ");
10084 destoffset = decode_rm10_address(rl);
10085 DECODE_PRINTF("\n");
10086 destval = fetch_data_byte(destoffset);
10087 TRACE_AND_STEP();
10088 idiv_byte(destval);
10089 break;
10091 break; /* end mod==10 */
10092 case 3: /* mod=11 */
10093 switch (rh) {
10094 case 0: /* test byte imm */
10095 DECODE_PRINTF("TEST\t");
10096 destreg = DECODE_RM_BYTE_REGISTER(rl);
10097 DECODE_PRINTF(",");
10098 srcval = fetch_byte_imm();
10099 DECODE_PRINTF2("%02x\n", srcval);
10100 TRACE_AND_STEP();
10101 test_byte(*destreg, srcval);
10102 break;
10103 case 1:
10104 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
10105 HALT_SYS();
10106 break;
10107 case 2:
10108 DECODE_PRINTF("NOT\t");
10109 destreg = DECODE_RM_BYTE_REGISTER(rl);
10110 DECODE_PRINTF("\n");
10111 TRACE_AND_STEP();
10112 *destreg = not_byte(*destreg);
10113 break;
10114 case 3:
10115 DECODE_PRINTF("NEG\t");
10116 destreg = DECODE_RM_BYTE_REGISTER(rl);
10117 DECODE_PRINTF("\n");
10118 TRACE_AND_STEP();
10119 *destreg = neg_byte(*destreg);
10120 break;
10121 case 4:
10122 DECODE_PRINTF("MUL\t");
10123 destreg = DECODE_RM_BYTE_REGISTER(rl);
10124 DECODE_PRINTF("\n");
10125 TRACE_AND_STEP();
10126 mul_byte(*destreg); /*!!! */
10127 break;
10128 case 5:
10129 DECODE_PRINTF("IMUL\t");
10130 destreg = DECODE_RM_BYTE_REGISTER(rl);
10131 DECODE_PRINTF("\n");
10132 TRACE_AND_STEP();
10133 imul_byte(*destreg);
10134 break;
10135 case 6:
10136 DECODE_PRINTF("DIV\t");
10137 destreg = DECODE_RM_BYTE_REGISTER(rl);
10138 DECODE_PRINTF("\n");
10139 TRACE_AND_STEP();
10140 div_byte(*destreg);
10141 break;
10142 case 7:
10143 DECODE_PRINTF("IDIV\t");
10144 destreg = DECODE_RM_BYTE_REGISTER(rl);
10145 DECODE_PRINTF("\n");
10146 TRACE_AND_STEP();
10147 idiv_byte(*destreg);
10148 break;
10150 break; /* end mod==11 */
10152 DECODE_CLEAR_SEGOVR();
10153 END_OF_INSTR();
10156 /****************************************************************************
10157 REMARKS:
10158 Handles opcode 0xf7
10159 ****************************************************************************/
10160 static void x86emuOp_opcF7_word_RM(u8 X86EMU_UNUSED(op1))
10162 int mod, rl, rh;
10163 uint destoffset;
10165 /* long, drawn out code follows. Double switch for a total
10166 of 32 cases. */
10167 START_OF_INSTR();
10168 FETCH_DECODE_MODRM(mod, rh, rl);
10169 switch (mod) {
10170 case 0: /* mod=00 */
10171 switch (rh) {
10172 case 0: /* test word imm */
10173 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10174 u32 destval,srcval;
10176 DECODE_PRINTF("TEST\tDWORD PTR ");
10177 destoffset = decode_rm00_address(rl);
10178 DECODE_PRINTF(",");
10179 srcval = fetch_long_imm();
10180 DECODE_PRINTF2("%x\n", srcval);
10181 destval = fetch_data_long(destoffset);
10182 TRACE_AND_STEP();
10183 test_long(destval, srcval);
10184 } else {
10185 u16 destval,srcval;
10187 DECODE_PRINTF("TEST\tWORD PTR ");
10188 destoffset = decode_rm00_address(rl);
10189 DECODE_PRINTF(",");
10190 srcval = fetch_word_imm();
10191 DECODE_PRINTF2("%x\n", srcval);
10192 destval = fetch_data_word(destoffset);
10193 TRACE_AND_STEP();
10194 test_word(destval, srcval);
10196 break;
10197 case 1:
10198 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F7\n");
10199 HALT_SYS();
10200 break;
10201 case 2:
10202 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10203 u32 destval;
10205 DECODE_PRINTF("NOT\tDWORD PTR ");
10206 destoffset = decode_rm00_address(rl);
10207 DECODE_PRINTF("\n");
10208 destval = fetch_data_long(destoffset);
10209 TRACE_AND_STEP();
10210 destval = not_long(destval);
10211 store_data_long(destoffset, destval);
10212 } else {
10213 u16 destval;
10215 DECODE_PRINTF("NOT\tWORD PTR ");
10216 destoffset = decode_rm00_address(rl);
10217 DECODE_PRINTF("\n");
10218 destval = fetch_data_word(destoffset);
10219 TRACE_AND_STEP();
10220 destval = not_word(destval);
10221 store_data_word(destoffset, destval);
10223 break;
10224 case 3:
10225 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10226 u32 destval;
10228 DECODE_PRINTF("NEG\tDWORD PTR ");
10229 destoffset = decode_rm00_address(rl);
10230 DECODE_PRINTF("\n");
10231 destval = fetch_data_long(destoffset);
10232 TRACE_AND_STEP();
10233 destval = neg_long(destval);
10234 store_data_long(destoffset, destval);
10235 } else {
10236 u16 destval;
10238 DECODE_PRINTF("NEG\tWORD PTR ");
10239 destoffset = decode_rm00_address(rl);
10240 DECODE_PRINTF("\n");
10241 destval = fetch_data_word(destoffset);
10242 TRACE_AND_STEP();
10243 destval = neg_word(destval);
10244 store_data_word(destoffset, destval);
10246 break;
10247 case 4:
10248 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10249 u32 destval;
10251 DECODE_PRINTF("MUL\tDWORD PTR ");
10252 destoffset = decode_rm00_address(rl);
10253 DECODE_PRINTF("\n");
10254 destval = fetch_data_long(destoffset);
10255 TRACE_AND_STEP();
10256 mul_long(destval);
10257 } else {
10258 u16 destval;
10260 DECODE_PRINTF("MUL\tWORD PTR ");
10261 destoffset = decode_rm00_address(rl);
10262 DECODE_PRINTF("\n");
10263 destval = fetch_data_word(destoffset);
10264 TRACE_AND_STEP();
10265 mul_word(destval);
10267 break;
10268 case 5:
10269 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10270 u32 destval;
10272 DECODE_PRINTF("IMUL\tDWORD PTR ");
10273 destoffset = decode_rm00_address(rl);
10274 DECODE_PRINTF("\n");
10275 destval = fetch_data_long(destoffset);
10276 TRACE_AND_STEP();
10277 imul_long(destval);
10278 } else {
10279 u16 destval;
10281 DECODE_PRINTF("IMUL\tWORD PTR ");
10282 destoffset = decode_rm00_address(rl);
10283 DECODE_PRINTF("\n");
10284 destval = fetch_data_word(destoffset);
10285 TRACE_AND_STEP();
10286 imul_word(destval);
10288 break;
10289 case 6:
10290 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10291 u32 destval;
10293 DECODE_PRINTF("DIV\tDWORD PTR ");
10294 destoffset = decode_rm00_address(rl);
10295 DECODE_PRINTF("\n");
10296 destval = fetch_data_long(destoffset);
10297 TRACE_AND_STEP();
10298 div_long(destval);
10299 } else {
10300 u16 destval;
10302 DECODE_PRINTF("DIV\tWORD PTR ");
10303 destoffset = decode_rm00_address(rl);
10304 DECODE_PRINTF("\n");
10305 destval = fetch_data_word(destoffset);
10306 TRACE_AND_STEP();
10307 div_word(destval);
10309 break;
10310 case 7:
10311 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10312 u32 destval;
10314 DECODE_PRINTF("IDIV\tDWORD PTR ");
10315 destoffset = decode_rm00_address(rl);
10316 DECODE_PRINTF("\n");
10317 destval = fetch_data_long(destoffset);
10318 TRACE_AND_STEP();
10319 idiv_long(destval);
10320 } else {
10321 u16 destval;
10323 DECODE_PRINTF("IDIV\tWORD PTR ");
10324 destoffset = decode_rm00_address(rl);
10325 DECODE_PRINTF("\n");
10326 destval = fetch_data_word(destoffset);
10327 TRACE_AND_STEP();
10328 idiv_word(destval);
10330 break;
10332 break; /* end mod==00 */
10333 case 1: /* mod=01 */
10334 switch (rh) {
10335 case 0: /* test word imm */
10336 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10337 u32 destval,srcval;
10339 DECODE_PRINTF("TEST\tDWORD PTR ");
10340 destoffset = decode_rm01_address(rl);
10341 DECODE_PRINTF(",");
10342 srcval = fetch_long_imm();
10343 DECODE_PRINTF2("%x\n", srcval);
10344 destval = fetch_data_long(destoffset);
10345 TRACE_AND_STEP();
10346 test_long(destval, srcval);
10347 } else {
10348 u16 destval,srcval;
10350 DECODE_PRINTF("TEST\tWORD PTR ");
10351 destoffset = decode_rm01_address(rl);
10352 DECODE_PRINTF(",");
10353 srcval = fetch_word_imm();
10354 DECODE_PRINTF2("%x\n", srcval);
10355 destval = fetch_data_word(destoffset);
10356 TRACE_AND_STEP();
10357 test_word(destval, srcval);
10359 break;
10360 case 1:
10361 DECODE_PRINTF("ILLEGAL OP MOD=01 RH=01 OP=F6\n");
10362 HALT_SYS();
10363 break;
10364 case 2:
10365 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10366 u32 destval;
10368 DECODE_PRINTF("NOT\tDWORD PTR ");
10369 destoffset = decode_rm01_address(rl);
10370 DECODE_PRINTF("\n");
10371 destval = fetch_data_long(destoffset);
10372 TRACE_AND_STEP();
10373 destval = not_long(destval);
10374 store_data_long(destoffset, destval);
10375 } else {
10376 u16 destval;
10378 DECODE_PRINTF("NOT\tWORD PTR ");
10379 destoffset = decode_rm01_address(rl);
10380 DECODE_PRINTF("\n");
10381 destval = fetch_data_word(destoffset);
10382 TRACE_AND_STEP();
10383 destval = not_word(destval);
10384 store_data_word(destoffset, destval);
10386 break;
10387 case 3:
10388 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10389 u32 destval;
10391 DECODE_PRINTF("NEG\tDWORD PTR ");
10392 destoffset = decode_rm01_address(rl);
10393 DECODE_PRINTF("\n");
10394 destval = fetch_data_long(destoffset);
10395 TRACE_AND_STEP();
10396 destval = neg_long(destval);
10397 store_data_long(destoffset, destval);
10398 } else {
10399 u16 destval;
10401 DECODE_PRINTF("NEG\tWORD PTR ");
10402 destoffset = decode_rm01_address(rl);
10403 DECODE_PRINTF("\n");
10404 destval = fetch_data_word(destoffset);
10405 TRACE_AND_STEP();
10406 destval = neg_word(destval);
10407 store_data_word(destoffset, destval);
10409 break;
10410 case 4:
10411 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10412 u32 destval;
10414 DECODE_PRINTF("MUL\tDWORD PTR ");
10415 destoffset = decode_rm01_address(rl);
10416 DECODE_PRINTF("\n");
10417 destval = fetch_data_long(destoffset);
10418 TRACE_AND_STEP();
10419 mul_long(destval);
10420 } else {
10421 u16 destval;
10423 DECODE_PRINTF("MUL\tWORD PTR ");
10424 destoffset = decode_rm01_address(rl);
10425 DECODE_PRINTF("\n");
10426 destval = fetch_data_word(destoffset);
10427 TRACE_AND_STEP();
10428 mul_word(destval);
10430 break;
10431 case 5:
10432 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10433 u32 destval;
10435 DECODE_PRINTF("IMUL\tDWORD PTR ");
10436 destoffset = decode_rm01_address(rl);
10437 DECODE_PRINTF("\n");
10438 destval = fetch_data_long(destoffset);
10439 TRACE_AND_STEP();
10440 imul_long(destval);
10441 } else {
10442 u16 destval;
10444 DECODE_PRINTF("IMUL\tWORD PTR ");
10445 destoffset = decode_rm01_address(rl);
10446 DECODE_PRINTF("\n");
10447 destval = fetch_data_word(destoffset);
10448 TRACE_AND_STEP();
10449 imul_word(destval);
10451 break;
10452 case 6:
10453 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10454 u32 destval;
10456 DECODE_PRINTF("DIV\tDWORD PTR ");
10457 destoffset = decode_rm01_address(rl);
10458 DECODE_PRINTF("\n");
10459 destval = fetch_data_long(destoffset);
10460 TRACE_AND_STEP();
10461 div_long(destval);
10462 } else {
10463 u16 destval;
10465 DECODE_PRINTF("DIV\tWORD PTR ");
10466 destoffset = decode_rm01_address(rl);
10467 DECODE_PRINTF("\n");
10468 destval = fetch_data_word(destoffset);
10469 TRACE_AND_STEP();
10470 div_word(destval);
10472 break;
10473 case 7:
10474 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10475 u32 destval;
10477 DECODE_PRINTF("IDIV\tDWORD PTR ");
10478 destoffset = decode_rm01_address(rl);
10479 DECODE_PRINTF("\n");
10480 destval = fetch_data_long(destoffset);
10481 TRACE_AND_STEP();
10482 idiv_long(destval);
10483 } else {
10484 u16 destval;
10486 DECODE_PRINTF("IDIV\tWORD PTR ");
10487 destoffset = decode_rm01_address(rl);
10488 DECODE_PRINTF("\n");
10489 destval = fetch_data_word(destoffset);
10490 TRACE_AND_STEP();
10491 idiv_word(destval);
10493 break;
10495 break; /* end mod==01 */
10496 case 2: /* mod=10 */
10497 switch (rh) {
10498 case 0: /* test word imm */
10499 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10500 u32 destval,srcval;
10502 DECODE_PRINTF("TEST\tDWORD PTR ");
10503 destoffset = decode_rm10_address(rl);
10504 DECODE_PRINTF(",");
10505 srcval = fetch_long_imm();
10506 DECODE_PRINTF2("%x\n", srcval);
10507 destval = fetch_data_long(destoffset);
10508 TRACE_AND_STEP();
10509 test_long(destval, srcval);
10510 } else {
10511 u16 destval,srcval;
10513 DECODE_PRINTF("TEST\tWORD PTR ");
10514 destoffset = decode_rm10_address(rl);
10515 DECODE_PRINTF(",");
10516 srcval = fetch_word_imm();
10517 DECODE_PRINTF2("%x\n", srcval);
10518 destval = fetch_data_word(destoffset);
10519 TRACE_AND_STEP();
10520 test_word(destval, srcval);
10522 break;
10523 case 1:
10524 DECODE_PRINTF("ILLEGAL OP MOD=10 RH=01 OP=F6\n");
10525 HALT_SYS();
10526 break;
10527 case 2:
10528 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10529 u32 destval;
10531 DECODE_PRINTF("NOT\tDWORD PTR ");
10532 destoffset = decode_rm10_address(rl);
10533 DECODE_PRINTF("\n");
10534 destval = fetch_data_long(destoffset);
10535 TRACE_AND_STEP();
10536 destval = not_long(destval);
10537 store_data_long(destoffset, destval);
10538 } else {
10539 u16 destval;
10541 DECODE_PRINTF("NOT\tWORD PTR ");
10542 destoffset = decode_rm10_address(rl);
10543 DECODE_PRINTF("\n");
10544 destval = fetch_data_word(destoffset);
10545 TRACE_AND_STEP();
10546 destval = not_word(destval);
10547 store_data_word(destoffset, destval);
10549 break;
10550 case 3:
10551 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10552 u32 destval;
10554 DECODE_PRINTF("NEG\tDWORD PTR ");
10555 destoffset = decode_rm10_address(rl);
10556 DECODE_PRINTF("\n");
10557 destval = fetch_data_long(destoffset);
10558 TRACE_AND_STEP();
10559 destval = neg_long(destval);
10560 store_data_long(destoffset, destval);
10561 } else {
10562 u16 destval;
10564 DECODE_PRINTF("NEG\tWORD PTR ");
10565 destoffset = decode_rm10_address(rl);
10566 DECODE_PRINTF("\n");
10567 destval = fetch_data_word(destoffset);
10568 TRACE_AND_STEP();
10569 destval = neg_word(destval);
10570 store_data_word(destoffset, destval);
10572 break;
10573 case 4:
10574 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10575 u32 destval;
10577 DECODE_PRINTF("MUL\tDWORD PTR ");
10578 destoffset = decode_rm10_address(rl);
10579 DECODE_PRINTF("\n");
10580 destval = fetch_data_long(destoffset);
10581 TRACE_AND_STEP();
10582 mul_long(destval);
10583 } else {
10584 u16 destval;
10586 DECODE_PRINTF("MUL\tWORD PTR ");
10587 destoffset = decode_rm10_address(rl);
10588 DECODE_PRINTF("\n");
10589 destval = fetch_data_word(destoffset);
10590 TRACE_AND_STEP();
10591 mul_word(destval);
10593 break;
10594 case 5:
10595 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10596 u32 destval;
10598 DECODE_PRINTF("IMUL\tDWORD PTR ");
10599 destoffset = decode_rm10_address(rl);
10600 DECODE_PRINTF("\n");
10601 destval = fetch_data_long(destoffset);
10602 TRACE_AND_STEP();
10603 imul_long(destval);
10604 } else {
10605 u16 destval;
10607 DECODE_PRINTF("IMUL\tWORD PTR ");
10608 destoffset = decode_rm10_address(rl);
10609 DECODE_PRINTF("\n");
10610 destval = fetch_data_word(destoffset);
10611 TRACE_AND_STEP();
10612 imul_word(destval);
10614 break;
10615 case 6:
10616 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10617 u32 destval;
10619 DECODE_PRINTF("DIV\tDWORD PTR ");
10620 destoffset = decode_rm10_address(rl);
10621 DECODE_PRINTF("\n");
10622 destval = fetch_data_long(destoffset);
10623 TRACE_AND_STEP();
10624 div_long(destval);
10625 } else {
10626 u16 destval;
10628 DECODE_PRINTF("DIV\tWORD PTR ");
10629 destoffset = decode_rm10_address(rl);
10630 DECODE_PRINTF("\n");
10631 destval = fetch_data_word(destoffset);
10632 TRACE_AND_STEP();
10633 div_word(destval);
10635 break;
10636 case 7:
10637 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10638 u32 destval;
10640 DECODE_PRINTF("IDIV\tDWORD PTR ");
10641 destoffset = decode_rm10_address(rl);
10642 DECODE_PRINTF("\n");
10643 destval = fetch_data_long(destoffset);
10644 TRACE_AND_STEP();
10645 idiv_long(destval);
10646 } else {
10647 u16 destval;
10649 DECODE_PRINTF("IDIV\tWORD PTR ");
10650 destoffset = decode_rm10_address(rl);
10651 DECODE_PRINTF("\n");
10652 destval = fetch_data_word(destoffset);
10653 TRACE_AND_STEP();
10654 idiv_word(destval);
10656 break;
10658 break; /* end mod==10 */
10659 case 3: /* mod=11 */
10660 switch (rh) {
10661 case 0: /* test word imm */
10662 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10663 u32 *destreg;
10664 u32 srcval;
10666 DECODE_PRINTF("TEST\t");
10667 destreg = DECODE_RM_LONG_REGISTER(rl);
10668 DECODE_PRINTF(",");
10669 srcval = fetch_long_imm();
10670 DECODE_PRINTF2("%x\n", srcval);
10671 TRACE_AND_STEP();
10672 test_long(*destreg, srcval);
10673 } else {
10674 u16 *destreg;
10675 u16 srcval;
10677 DECODE_PRINTF("TEST\t");
10678 destreg = DECODE_RM_WORD_REGISTER(rl);
10679 DECODE_PRINTF(",");
10680 srcval = fetch_word_imm();
10681 DECODE_PRINTF2("%x\n", srcval);
10682 TRACE_AND_STEP();
10683 test_word(*destreg, srcval);
10685 break;
10686 case 1:
10687 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
10688 HALT_SYS();
10689 break;
10690 case 2:
10691 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10692 u32 *destreg;
10694 DECODE_PRINTF("NOT\t");
10695 destreg = DECODE_RM_LONG_REGISTER(rl);
10696 DECODE_PRINTF("\n");
10697 TRACE_AND_STEP();
10698 *destreg = not_long(*destreg);
10699 } else {
10700 u16 *destreg;
10702 DECODE_PRINTF("NOT\t");
10703 destreg = DECODE_RM_WORD_REGISTER(rl);
10704 DECODE_PRINTF("\n");
10705 TRACE_AND_STEP();
10706 *destreg = not_word(*destreg);
10708 break;
10709 case 3:
10710 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10711 u32 *destreg;
10713 DECODE_PRINTF("NEG\t");
10714 destreg = DECODE_RM_LONG_REGISTER(rl);
10715 DECODE_PRINTF("\n");
10716 TRACE_AND_STEP();
10717 *destreg = neg_long(*destreg);
10718 } else {
10719 u16 *destreg;
10721 DECODE_PRINTF("NEG\t");
10722 destreg = DECODE_RM_WORD_REGISTER(rl);
10723 DECODE_PRINTF("\n");
10724 TRACE_AND_STEP();
10725 *destreg = neg_word(*destreg);
10727 break;
10728 case 4:
10729 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10730 u32 *destreg;
10732 DECODE_PRINTF("MUL\t");
10733 destreg = DECODE_RM_LONG_REGISTER(rl);
10734 DECODE_PRINTF("\n");
10735 TRACE_AND_STEP();
10736 mul_long(*destreg); /*!!! */
10737 } else {
10738 u16 *destreg;
10740 DECODE_PRINTF("MUL\t");
10741 destreg = DECODE_RM_WORD_REGISTER(rl);
10742 DECODE_PRINTF("\n");
10743 TRACE_AND_STEP();
10744 mul_word(*destreg); /*!!! */
10746 break;
10747 case 5:
10748 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10749 u32 *destreg;
10751 DECODE_PRINTF("IMUL\t");
10752 destreg = DECODE_RM_LONG_REGISTER(rl);
10753 DECODE_PRINTF("\n");
10754 TRACE_AND_STEP();
10755 imul_long(*destreg);
10756 } else {
10757 u16 *destreg;
10759 DECODE_PRINTF("IMUL\t");
10760 destreg = DECODE_RM_WORD_REGISTER(rl);
10761 DECODE_PRINTF("\n");
10762 TRACE_AND_STEP();
10763 imul_word(*destreg);
10765 break;
10766 case 6:
10767 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10768 u32 *destreg;
10770 DECODE_PRINTF("DIV\t");
10771 destreg = DECODE_RM_LONG_REGISTER(rl);
10772 DECODE_PRINTF("\n");
10773 TRACE_AND_STEP();
10774 div_long(*destreg);
10775 } else {
10776 u16 *destreg;
10778 DECODE_PRINTF("DIV\t");
10779 destreg = DECODE_RM_WORD_REGISTER(rl);
10780 DECODE_PRINTF("\n");
10781 TRACE_AND_STEP();
10782 div_word(*destreg);
10784 break;
10785 case 7:
10786 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10787 u32 *destreg;
10789 DECODE_PRINTF("IDIV\t");
10790 destreg = DECODE_RM_LONG_REGISTER(rl);
10791 DECODE_PRINTF("\n");
10792 TRACE_AND_STEP();
10793 idiv_long(*destreg);
10794 } else {
10795 u16 *destreg;
10797 DECODE_PRINTF("IDIV\t");
10798 destreg = DECODE_RM_WORD_REGISTER(rl);
10799 DECODE_PRINTF("\n");
10800 TRACE_AND_STEP();
10801 idiv_word(*destreg);
10803 break;
10805 break; /* end mod==11 */
10807 DECODE_CLEAR_SEGOVR();
10808 END_OF_INSTR();
10811 /****************************************************************************
10812 REMARKS:
10813 Handles opcode 0xf8
10814 ****************************************************************************/
10815 static void x86emuOp_clc(u8 X86EMU_UNUSED(op1))
10817 /* clear the carry flag. */
10818 START_OF_INSTR();
10819 DECODE_PRINTF("CLC\n");
10820 TRACE_AND_STEP();
10821 CLEAR_FLAG(F_CF);
10822 DECODE_CLEAR_SEGOVR();
10823 END_OF_INSTR();
10826 /****************************************************************************
10827 REMARKS:
10828 Handles opcode 0xf9
10829 ****************************************************************************/
10830 static void x86emuOp_stc(u8 X86EMU_UNUSED(op1))
10832 /* set the carry flag. */
10833 START_OF_INSTR();
10834 DECODE_PRINTF("STC\n");
10835 TRACE_AND_STEP();
10836 SET_FLAG(F_CF);
10837 DECODE_CLEAR_SEGOVR();
10838 END_OF_INSTR();
10841 /****************************************************************************
10842 REMARKS:
10843 Handles opcode 0xfa
10844 ****************************************************************************/
10845 static void x86emuOp_cli(u8 X86EMU_UNUSED(op1))
10847 /* clear interrupts. */
10848 START_OF_INSTR();
10849 DECODE_PRINTF("CLI\n");
10850 TRACE_AND_STEP();
10851 CLEAR_FLAG(F_IF);
10852 DECODE_CLEAR_SEGOVR();
10853 END_OF_INSTR();
10856 /****************************************************************************
10857 REMARKS:
10858 Handles opcode 0xfb
10859 ****************************************************************************/
10860 static void x86emuOp_sti(u8 X86EMU_UNUSED(op1))
10862 /* enable interrupts. */
10863 START_OF_INSTR();
10864 DECODE_PRINTF("STI\n");
10865 TRACE_AND_STEP();
10866 SET_FLAG(F_IF);
10867 DECODE_CLEAR_SEGOVR();
10868 END_OF_INSTR();
10871 /****************************************************************************
10872 REMARKS:
10873 Handles opcode 0xfc
10874 ****************************************************************************/
10875 static void x86emuOp_cld(u8 X86EMU_UNUSED(op1))
10877 /* clear interrupts. */
10878 START_OF_INSTR();
10879 DECODE_PRINTF("CLD\n");
10880 TRACE_AND_STEP();
10881 CLEAR_FLAG(F_DF);
10882 DECODE_CLEAR_SEGOVR();
10883 END_OF_INSTR();
10886 /****************************************************************************
10887 REMARKS:
10888 Handles opcode 0xfd
10889 ****************************************************************************/
10890 static void x86emuOp_std(u8 X86EMU_UNUSED(op1))
10892 /* clear interrupts. */
10893 START_OF_INSTR();
10894 DECODE_PRINTF("STD\n");
10895 TRACE_AND_STEP();
10896 SET_FLAG(F_DF);
10897 DECODE_CLEAR_SEGOVR();
10898 END_OF_INSTR();
10901 /****************************************************************************
10902 REMARKS:
10903 Handles opcode 0xfe
10904 ****************************************************************************/
10905 static void x86emuOp_opcFE_byte_RM(u8 X86EMU_UNUSED(op1))
10907 int mod, rh, rl;
10908 u8 destval;
10909 uint destoffset;
10910 u8 *destreg;
10912 /* Yet another special case instruction. */
10913 START_OF_INSTR();
10914 FETCH_DECODE_MODRM(mod, rh, rl);
10915 #ifdef DEBUG
10916 if (DEBUG_DECODE()) {
10917 /* XXX DECODE_PRINTF may be changed to something more
10918 general, so that it is important to leave the strings
10919 in the same format, even though the result is that the
10920 above test is done twice. */
10922 switch (rh) {
10923 case 0:
10924 DECODE_PRINTF("INC\t");
10925 break;
10926 case 1:
10927 DECODE_PRINTF("DEC\t");
10928 break;
10929 case 2:
10930 case 3:
10931 case 4:
10932 case 5:
10933 case 6:
10934 case 7:
10935 DECODE_PRINTF2("ILLEGAL OP MAJOR OP 0xFE MINOR OP %x \n", mod);
10936 HALT_SYS();
10937 break;
10940 #endif
10941 switch (mod) {
10942 case 0:
10943 DECODE_PRINTF("BYTE PTR ");
10944 destoffset = decode_rm00_address(rl);
10945 DECODE_PRINTF("\n");
10946 switch (rh) {
10947 case 0: /* inc word ptr ... */
10948 destval = fetch_data_byte(destoffset);
10949 TRACE_AND_STEP();
10950 destval = inc_byte(destval);
10951 store_data_byte(destoffset, destval);
10952 break;
10953 case 1: /* dec word ptr ... */
10954 destval = fetch_data_byte(destoffset);
10955 TRACE_AND_STEP();
10956 destval = dec_byte(destval);
10957 store_data_byte(destoffset, destval);
10958 break;
10960 break;
10961 case 1:
10962 DECODE_PRINTF("BYTE PTR ");
10963 destoffset = decode_rm01_address(rl);
10964 DECODE_PRINTF("\n");
10965 switch (rh) {
10966 case 0:
10967 destval = fetch_data_byte(destoffset);
10968 TRACE_AND_STEP();
10969 destval = inc_byte(destval);
10970 store_data_byte(destoffset, destval);
10971 break;
10972 case 1:
10973 destval = fetch_data_byte(destoffset);
10974 TRACE_AND_STEP();
10975 destval = dec_byte(destval);
10976 store_data_byte(destoffset, destval);
10977 break;
10979 break;
10980 case 2:
10981 DECODE_PRINTF("BYTE PTR ");
10982 destoffset = decode_rm10_address(rl);
10983 DECODE_PRINTF("\n");
10984 switch (rh) {
10985 case 0:
10986 destval = fetch_data_byte(destoffset);
10987 TRACE_AND_STEP();
10988 destval = inc_byte(destval);
10989 store_data_byte(destoffset, destval);
10990 break;
10991 case 1:
10992 destval = fetch_data_byte(destoffset);
10993 TRACE_AND_STEP();
10994 destval = dec_byte(destval);
10995 store_data_byte(destoffset, destval);
10996 break;
10998 break;
10999 case 3:
11000 destreg = DECODE_RM_BYTE_REGISTER(rl);
11001 DECODE_PRINTF("\n");
11002 switch (rh) {
11003 case 0:
11004 TRACE_AND_STEP();
11005 *destreg = inc_byte(*destreg);
11006 break;
11007 case 1:
11008 TRACE_AND_STEP();
11009 *destreg = dec_byte(*destreg);
11010 break;
11012 break;
11014 DECODE_CLEAR_SEGOVR();
11015 END_OF_INSTR();
11018 /****************************************************************************
11019 REMARKS:
11020 Handles opcode 0xff
11021 ****************************************************************************/
11022 static void x86emuOp_opcFF_word_RM(u8 X86EMU_UNUSED(op1))
11024 int mod, rh, rl;
11025 uint destoffset = 0;
11026 u16 *destreg;
11027 u16 destval,destval2;
11029 /* Yet another special case instruction. */
11030 START_OF_INSTR();
11031 FETCH_DECODE_MODRM(mod, rh, rl);
11032 #ifdef DEBUG
11033 if (DEBUG_DECODE()) {
11034 /* XXX DECODE_PRINTF may be changed to something more
11035 general, so that it is important to leave the strings
11036 in the same format, even though the result is that the
11037 above test is done twice. */
11039 switch (rh) {
11040 case 0:
11041 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11042 DECODE_PRINTF("INC\tDWORD PTR ");
11043 } else {
11044 DECODE_PRINTF("INC\tWORD PTR ");
11046 break;
11047 case 1:
11048 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11049 DECODE_PRINTF("DEC\tDWORD PTR ");
11050 } else {
11051 DECODE_PRINTF("DEC\tWORD PTR ");
11053 break;
11054 case 2:
11055 DECODE_PRINTF("CALL\t");
11056 break;
11057 case 3:
11058 DECODE_PRINTF("CALL\tFAR ");
11059 break;
11060 case 4:
11061 DECODE_PRINTF("JMP\t");
11062 break;
11063 case 5:
11064 DECODE_PRINTF("JMP\tFAR ");
11065 break;
11066 case 6:
11067 DECODE_PRINTF("PUSH\t");
11068 break;
11069 case 7:
11070 DECODE_PRINTF("ILLEGAL DECODING OF OPCODE FF\t");
11071 HALT_SYS();
11072 break;
11075 #endif
11076 switch (mod) {
11077 case 0:
11078 destoffset = decode_rm00_address(rl);
11079 DECODE_PRINTF("\n");
11080 switch (rh) {
11081 case 0: /* inc word ptr ... */
11082 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11083 u32 destval;
11085 destval = fetch_data_long(destoffset);
11086 TRACE_AND_STEP();
11087 destval = inc_long(destval);
11088 store_data_long(destoffset, destval);
11089 } else {
11090 u16 destval;
11092 destval = fetch_data_word(destoffset);
11093 TRACE_AND_STEP();
11094 destval = inc_word(destval);
11095 store_data_word(destoffset, destval);
11097 break;
11098 case 1: /* dec word ptr ... */
11099 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11100 u32 destval;
11102 destval = fetch_data_long(destoffset);
11103 TRACE_AND_STEP();
11104 destval = dec_long(destval);
11105 store_data_long(destoffset, destval);
11106 } else {
11107 u16 destval;
11109 destval = fetch_data_word(destoffset);
11110 TRACE_AND_STEP();
11111 destval = dec_word(destval);
11112 store_data_word(destoffset, destval);
11114 break;
11115 case 2: /* call word ptr ... */
11116 destval = fetch_data_word(destoffset);
11117 TRACE_AND_STEP();
11118 push_word(M.x86.R_IP);
11119 M.x86.R_IP = destval;
11120 break;
11121 case 3: /* call far ptr ... */
11122 destval = fetch_data_word(destoffset);
11123 destval2 = fetch_data_word(destoffset + 2);
11124 TRACE_AND_STEP();
11125 push_word(M.x86.R_CS);
11126 M.x86.R_CS = destval2;
11127 push_word(M.x86.R_IP);
11128 M.x86.R_IP = destval;
11129 break;
11130 case 4: /* jmp word ptr ... */
11131 destval = fetch_data_word(destoffset);
11132 TRACE_AND_STEP();
11133 M.x86.R_IP = destval;
11134 break;
11135 case 5: /* jmp far ptr ... */
11136 destval = fetch_data_word(destoffset);
11137 destval2 = fetch_data_word(destoffset + 2);
11138 TRACE_AND_STEP();
11139 M.x86.R_IP = destval;
11140 M.x86.R_CS = destval2;
11141 break;
11142 case 6: /* push word ptr ... */
11143 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11144 u32 destval;
11146 destval = fetch_data_long(destoffset);
11147 TRACE_AND_STEP();
11148 push_long(destval);
11149 } else {
11150 u16 destval;
11152 destval = fetch_data_word(destoffset);
11153 TRACE_AND_STEP();
11154 push_word(destval);
11156 break;
11158 break;
11159 case 1:
11160 destoffset = decode_rm01_address(rl);
11161 DECODE_PRINTF("\n");
11162 switch (rh) {
11163 case 0:
11164 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11165 u32 destval;
11167 destval = fetch_data_long(destoffset);
11168 TRACE_AND_STEP();
11169 destval = inc_long(destval);
11170 store_data_long(destoffset, destval);
11171 } else {
11172 u16 destval;
11174 destval = fetch_data_word(destoffset);
11175 TRACE_AND_STEP();
11176 destval = inc_word(destval);
11177 store_data_word(destoffset, destval);
11179 break;
11180 case 1:
11181 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11182 u32 destval;
11184 destval = fetch_data_long(destoffset);
11185 TRACE_AND_STEP();
11186 destval = dec_long(destval);
11187 store_data_long(destoffset, destval);
11188 } else {
11189 u16 destval;
11191 destval = fetch_data_word(destoffset);
11192 TRACE_AND_STEP();
11193 destval = dec_word(destval);
11194 store_data_word(destoffset, destval);
11196 break;
11197 case 2: /* call word ptr ... */
11198 destval = fetch_data_word(destoffset);
11199 TRACE_AND_STEP();
11200 push_word(M.x86.R_IP);
11201 M.x86.R_IP = destval;
11202 break;
11203 case 3: /* call far ptr ... */
11204 destval = fetch_data_word(destoffset);
11205 destval2 = fetch_data_word(destoffset + 2);
11206 TRACE_AND_STEP();
11207 push_word(M.x86.R_CS);
11208 M.x86.R_CS = destval2;
11209 push_word(M.x86.R_IP);
11210 M.x86.R_IP = destval;
11211 break;
11212 case 4: /* jmp word ptr ... */
11213 destval = fetch_data_word(destoffset);
11214 TRACE_AND_STEP();
11215 M.x86.R_IP = destval;
11216 break;
11217 case 5: /* jmp far ptr ... */
11218 destval = fetch_data_word(destoffset);
11219 destval2 = fetch_data_word(destoffset + 2);
11220 TRACE_AND_STEP();
11221 M.x86.R_IP = destval;
11222 M.x86.R_CS = destval2;
11223 break;
11224 case 6: /* push word ptr ... */
11225 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11226 u32 destval;
11228 destval = fetch_data_long(destoffset);
11229 TRACE_AND_STEP();
11230 push_long(destval);
11231 } else {
11232 u16 destval;
11234 destval = fetch_data_word(destoffset);
11235 TRACE_AND_STEP();
11236 push_word(destval);
11238 break;
11240 break;
11241 case 2:
11242 destoffset = decode_rm10_address(rl);
11243 DECODE_PRINTF("\n");
11244 switch (rh) {
11245 case 0:
11246 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11247 u32 destval;
11249 destval = fetch_data_long(destoffset);
11250 TRACE_AND_STEP();
11251 destval = inc_long(destval);
11252 store_data_long(destoffset, destval);
11253 } else {
11254 u16 destval;
11256 destval = fetch_data_word(destoffset);
11257 TRACE_AND_STEP();
11258 destval = inc_word(destval);
11259 store_data_word(destoffset, destval);
11261 break;
11262 case 1:
11263 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11264 u32 destval;
11266 destval = fetch_data_long(destoffset);
11267 TRACE_AND_STEP();
11268 destval = dec_long(destval);
11269 store_data_long(destoffset, destval);
11270 } else {
11271 u16 destval;
11273 destval = fetch_data_word(destoffset);
11274 TRACE_AND_STEP();
11275 destval = dec_word(destval);
11276 store_data_word(destoffset, destval);
11278 break;
11279 case 2: /* call word ptr ... */
11280 destval = fetch_data_word(destoffset);
11281 TRACE_AND_STEP();
11282 push_word(M.x86.R_IP);
11283 M.x86.R_IP = destval;
11284 break;
11285 case 3: /* call far ptr ... */
11286 destval = fetch_data_word(destoffset);
11287 destval2 = fetch_data_word(destoffset + 2);
11288 TRACE_AND_STEP();
11289 push_word(M.x86.R_CS);
11290 M.x86.R_CS = destval2;
11291 push_word(M.x86.R_IP);
11292 M.x86.R_IP = destval;
11293 break;
11294 case 4: /* jmp word ptr ... */
11295 destval = fetch_data_word(destoffset);
11296 TRACE_AND_STEP();
11297 M.x86.R_IP = destval;
11298 break;
11299 case 5: /* jmp far ptr ... */
11300 destval = fetch_data_word(destoffset);
11301 destval2 = fetch_data_word(destoffset + 2);
11302 TRACE_AND_STEP();
11303 M.x86.R_IP = destval;
11304 M.x86.R_CS = destval2;
11305 break;
11306 case 6: /* push word ptr ... */
11307 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11308 u32 destval;
11310 destval = fetch_data_long(destoffset);
11311 TRACE_AND_STEP();
11312 push_long(destval);
11313 } else {
11314 u16 destval;
11316 destval = fetch_data_word(destoffset);
11317 TRACE_AND_STEP();
11318 push_word(destval);
11320 break;
11322 break;
11323 case 3:
11324 switch (rh) {
11325 case 0:
11326 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11327 u32 *destreg;
11329 destreg = DECODE_RM_LONG_REGISTER(rl);
11330 DECODE_PRINTF("\n");
11331 TRACE_AND_STEP();
11332 *destreg = inc_long(*destreg);
11333 } else {
11334 u16 *destreg;
11336 destreg = DECODE_RM_WORD_REGISTER(rl);
11337 DECODE_PRINTF("\n");
11338 TRACE_AND_STEP();
11339 *destreg = inc_word(*destreg);
11341 break;
11342 case 1:
11343 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11344 u32 *destreg;
11346 destreg = DECODE_RM_LONG_REGISTER(rl);
11347 DECODE_PRINTF("\n");
11348 TRACE_AND_STEP();
11349 *destreg = dec_long(*destreg);
11350 } else {
11351 u16 *destreg;
11353 destreg = DECODE_RM_WORD_REGISTER(rl);
11354 DECODE_PRINTF("\n");
11355 TRACE_AND_STEP();
11356 *destreg = dec_word(*destreg);
11358 break;
11359 case 2: /* call word ptr ... */
11360 destreg = DECODE_RM_WORD_REGISTER(rl);
11361 DECODE_PRINTF("\n");
11362 TRACE_AND_STEP();
11363 push_word(M.x86.R_IP);
11364 M.x86.R_IP = *destreg;
11365 break;
11366 case 3: /* jmp far ptr ... */
11367 DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n");
11368 TRACE_AND_STEP();
11369 HALT_SYS();
11370 break;
11372 case 4: /* jmp ... */
11373 destreg = DECODE_RM_WORD_REGISTER(rl);
11374 DECODE_PRINTF("\n");
11375 TRACE_AND_STEP();
11376 M.x86.R_IP = (u16) (*destreg);
11377 break;
11378 case 5: /* jmp far ptr ... */
11379 DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n");
11380 TRACE_AND_STEP();
11381 HALT_SYS();
11382 break;
11383 case 6:
11384 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11385 u32 *destreg;
11387 destreg = DECODE_RM_LONG_REGISTER(rl);
11388 DECODE_PRINTF("\n");
11389 TRACE_AND_STEP();
11390 push_long(*destreg);
11391 } else {
11392 u16 *destreg;
11394 destreg = DECODE_RM_WORD_REGISTER(rl);
11395 DECODE_PRINTF("\n");
11396 TRACE_AND_STEP();
11397 push_word(*destreg);
11399 break;
11401 break;
11403 DECODE_CLEAR_SEGOVR();
11404 END_OF_INSTR();
11407 /***************************************************************************
11408 * Single byte operation code table:
11409 **************************************************************************/
11410 void (*x86emu_optab[256])(u8) =
11412 /* 0x00 */ x86emuOp_add_byte_RM_R,
11413 /* 0x01 */ x86emuOp_add_word_RM_R,
11414 /* 0x02 */ x86emuOp_add_byte_R_RM,
11415 /* 0x03 */ x86emuOp_add_word_R_RM,
11416 /* 0x04 */ x86emuOp_add_byte_AL_IMM,
11417 /* 0x05 */ x86emuOp_add_word_AX_IMM,
11418 /* 0x06 */ x86emuOp_push_ES,
11419 /* 0x07 */ x86emuOp_pop_ES,
11421 /* 0x08 */ x86emuOp_or_byte_RM_R,
11422 /* 0x09 */ x86emuOp_or_word_RM_R,
11423 /* 0x0a */ x86emuOp_or_byte_R_RM,
11424 /* 0x0b */ x86emuOp_or_word_R_RM,
11425 /* 0x0c */ x86emuOp_or_byte_AL_IMM,
11426 /* 0x0d */ x86emuOp_or_word_AX_IMM,
11427 /* 0x0e */ x86emuOp_push_CS,
11428 /* 0x0f */ x86emuOp_two_byte,
11430 /* 0x10 */ x86emuOp_adc_byte_RM_R,
11431 /* 0x11 */ x86emuOp_adc_word_RM_R,
11432 /* 0x12 */ x86emuOp_adc_byte_R_RM,
11433 /* 0x13 */ x86emuOp_adc_word_R_RM,
11434 /* 0x14 */ x86emuOp_adc_byte_AL_IMM,
11435 /* 0x15 */ x86emuOp_adc_word_AX_IMM,
11436 /* 0x16 */ x86emuOp_push_SS,
11437 /* 0x17 */ x86emuOp_pop_SS,
11439 /* 0x18 */ x86emuOp_sbb_byte_RM_R,
11440 /* 0x19 */ x86emuOp_sbb_word_RM_R,
11441 /* 0x1a */ x86emuOp_sbb_byte_R_RM,
11442 /* 0x1b */ x86emuOp_sbb_word_R_RM,
11443 /* 0x1c */ x86emuOp_sbb_byte_AL_IMM,
11444 /* 0x1d */ x86emuOp_sbb_word_AX_IMM,
11445 /* 0x1e */ x86emuOp_push_DS,
11446 /* 0x1f */ x86emuOp_pop_DS,
11448 /* 0x20 */ x86emuOp_and_byte_RM_R,
11449 /* 0x21 */ x86emuOp_and_word_RM_R,
11450 /* 0x22 */ x86emuOp_and_byte_R_RM,
11451 /* 0x23 */ x86emuOp_and_word_R_RM,
11452 /* 0x24 */ x86emuOp_and_byte_AL_IMM,
11453 /* 0x25 */ x86emuOp_and_word_AX_IMM,
11454 /* 0x26 */ x86emuOp_segovr_ES,
11455 /* 0x27 */ x86emuOp_daa,
11457 /* 0x28 */ x86emuOp_sub_byte_RM_R,
11458 /* 0x29 */ x86emuOp_sub_word_RM_R,
11459 /* 0x2a */ x86emuOp_sub_byte_R_RM,
11460 /* 0x2b */ x86emuOp_sub_word_R_RM,
11461 /* 0x2c */ x86emuOp_sub_byte_AL_IMM,
11462 /* 0x2d */ x86emuOp_sub_word_AX_IMM,
11463 /* 0x2e */ x86emuOp_segovr_CS,
11464 /* 0x2f */ x86emuOp_das,
11466 /* 0x30 */ x86emuOp_xor_byte_RM_R,
11467 /* 0x31 */ x86emuOp_xor_word_RM_R,
11468 /* 0x32 */ x86emuOp_xor_byte_R_RM,
11469 /* 0x33 */ x86emuOp_xor_word_R_RM,
11470 /* 0x34 */ x86emuOp_xor_byte_AL_IMM,
11471 /* 0x35 */ x86emuOp_xor_word_AX_IMM,
11472 /* 0x36 */ x86emuOp_segovr_SS,
11473 /* 0x37 */ x86emuOp_aaa,
11475 /* 0x38 */ x86emuOp_cmp_byte_RM_R,
11476 /* 0x39 */ x86emuOp_cmp_word_RM_R,
11477 /* 0x3a */ x86emuOp_cmp_byte_R_RM,
11478 /* 0x3b */ x86emuOp_cmp_word_R_RM,
11479 /* 0x3c */ x86emuOp_cmp_byte_AL_IMM,
11480 /* 0x3d */ x86emuOp_cmp_word_AX_IMM,
11481 /* 0x3e */ x86emuOp_segovr_DS,
11482 /* 0x3f */ x86emuOp_aas,
11484 /* 0x40 */ x86emuOp_inc_AX,
11485 /* 0x41 */ x86emuOp_inc_CX,
11486 /* 0x42 */ x86emuOp_inc_DX,
11487 /* 0x43 */ x86emuOp_inc_BX,
11488 /* 0x44 */ x86emuOp_inc_SP,
11489 /* 0x45 */ x86emuOp_inc_BP,
11490 /* 0x46 */ x86emuOp_inc_SI,
11491 /* 0x47 */ x86emuOp_inc_DI,
11493 /* 0x48 */ x86emuOp_dec_AX,
11494 /* 0x49 */ x86emuOp_dec_CX,
11495 /* 0x4a */ x86emuOp_dec_DX,
11496 /* 0x4b */ x86emuOp_dec_BX,
11497 /* 0x4c */ x86emuOp_dec_SP,
11498 /* 0x4d */ x86emuOp_dec_BP,
11499 /* 0x4e */ x86emuOp_dec_SI,
11500 /* 0x4f */ x86emuOp_dec_DI,
11502 /* 0x50 */ x86emuOp_push_AX,
11503 /* 0x51 */ x86emuOp_push_CX,
11504 /* 0x52 */ x86emuOp_push_DX,
11505 /* 0x53 */ x86emuOp_push_BX,
11506 /* 0x54 */ x86emuOp_push_SP,
11507 /* 0x55 */ x86emuOp_push_BP,
11508 /* 0x56 */ x86emuOp_push_SI,
11509 /* 0x57 */ x86emuOp_push_DI,
11511 /* 0x58 */ x86emuOp_pop_AX,
11512 /* 0x59 */ x86emuOp_pop_CX,
11513 /* 0x5a */ x86emuOp_pop_DX,
11514 /* 0x5b */ x86emuOp_pop_BX,
11515 /* 0x5c */ x86emuOp_pop_SP,
11516 /* 0x5d */ x86emuOp_pop_BP,
11517 /* 0x5e */ x86emuOp_pop_SI,
11518 /* 0x5f */ x86emuOp_pop_DI,
11520 /* 0x60 */ x86emuOp_push_all,
11521 /* 0x61 */ x86emuOp_pop_all,
11522 /* 0x62 */ x86emuOp_illegal_op, /* bound */
11523 /* 0x63 */ x86emuOp_illegal_op, /* arpl */
11524 /* 0x64 */ x86emuOp_segovr_FS,
11525 /* 0x65 */ x86emuOp_segovr_GS,
11526 /* 0x66 */ x86emuOp_prefix_data,
11527 /* 0x67 */ x86emuOp_prefix_addr,
11529 /* 0x68 */ x86emuOp_push_word_IMM,
11530 /* 0x69 */ x86emuOp_imul_word_IMM,
11531 /* 0x6a */ x86emuOp_push_byte_IMM,
11532 /* 0x6b */ x86emuOp_imul_byte_IMM,
11533 /* 0x6c */ x86emuOp_ins_byte,
11534 /* 0x6d */ x86emuOp_ins_word,
11535 /* 0x6e */ x86emuOp_outs_byte,
11536 /* 0x6f */ x86emuOp_outs_word,
11538 /* 0x70 */ x86emuOp_jump_near_O,
11539 /* 0x71 */ x86emuOp_jump_near_NO,
11540 /* 0x72 */ x86emuOp_jump_near_B,
11541 /* 0x73 */ x86emuOp_jump_near_NB,
11542 /* 0x74 */ x86emuOp_jump_near_Z,
11543 /* 0x75 */ x86emuOp_jump_near_NZ,
11544 /* 0x76 */ x86emuOp_jump_near_BE,
11545 /* 0x77 */ x86emuOp_jump_near_NBE,
11547 /* 0x78 */ x86emuOp_jump_near_S,
11548 /* 0x79 */ x86emuOp_jump_near_NS,
11549 /* 0x7a */ x86emuOp_jump_near_P,
11550 /* 0x7b */ x86emuOp_jump_near_NP,
11551 /* 0x7c */ x86emuOp_jump_near_L,
11552 /* 0x7d */ x86emuOp_jump_near_NL,
11553 /* 0x7e */ x86emuOp_jump_near_LE,
11554 /* 0x7f */ x86emuOp_jump_near_NLE,
11556 /* 0x80 */ x86emuOp_opc80_byte_RM_IMM,
11557 /* 0x81 */ x86emuOp_opc81_word_RM_IMM,
11558 /* 0x82 */ x86emuOp_opc82_byte_RM_IMM,
11559 /* 0x83 */ x86emuOp_opc83_word_RM_IMM,
11560 /* 0x84 */ x86emuOp_test_byte_RM_R,
11561 /* 0x85 */ x86emuOp_test_word_RM_R,
11562 /* 0x86 */ x86emuOp_xchg_byte_RM_R,
11563 /* 0x87 */ x86emuOp_xchg_word_RM_R,
11565 /* 0x88 */ x86emuOp_mov_byte_RM_R,
11566 /* 0x89 */ x86emuOp_mov_word_RM_R,
11567 /* 0x8a */ x86emuOp_mov_byte_R_RM,
11568 /* 0x8b */ x86emuOp_mov_word_R_RM,
11569 /* 0x8c */ x86emuOp_mov_word_RM_SR,
11570 /* 0x8d */ x86emuOp_lea_word_R_M,
11571 /* 0x8e */ x86emuOp_mov_word_SR_RM,
11572 /* 0x8f */ x86emuOp_pop_RM,
11574 /* 0x90 */ x86emuOp_nop,
11575 /* 0x91 */ x86emuOp_xchg_word_AX_CX,
11576 /* 0x92 */ x86emuOp_xchg_word_AX_DX,
11577 /* 0x93 */ x86emuOp_xchg_word_AX_BX,
11578 /* 0x94 */ x86emuOp_xchg_word_AX_SP,
11579 /* 0x95 */ x86emuOp_xchg_word_AX_BP,
11580 /* 0x96 */ x86emuOp_xchg_word_AX_SI,
11581 /* 0x97 */ x86emuOp_xchg_word_AX_DI,
11583 /* 0x98 */ x86emuOp_cbw,
11584 /* 0x99 */ x86emuOp_cwd,
11585 /* 0x9a */ x86emuOp_call_far_IMM,
11586 /* 0x9b */ x86emuOp_wait,
11587 /* 0x9c */ x86emuOp_pushf_word,
11588 /* 0x9d */ x86emuOp_popf_word,
11589 /* 0x9e */ x86emuOp_sahf,
11590 /* 0x9f */ x86emuOp_lahf,
11592 /* 0xa0 */ x86emuOp_mov_AL_M_IMM,
11593 /* 0xa1 */ x86emuOp_mov_AX_M_IMM,
11594 /* 0xa2 */ x86emuOp_mov_M_AL_IMM,
11595 /* 0xa3 */ x86emuOp_mov_M_AX_IMM,
11596 /* 0xa4 */ x86emuOp_movs_byte,
11597 /* 0xa5 */ x86emuOp_movs_word,
11598 /* 0xa6 */ x86emuOp_cmps_byte,
11599 /* 0xa7 */ x86emuOp_cmps_word,
11600 /* 0xa8 */ x86emuOp_test_AL_IMM,
11601 /* 0xa9 */ x86emuOp_test_AX_IMM,
11602 /* 0xaa */ x86emuOp_stos_byte,
11603 /* 0xab */ x86emuOp_stos_word,
11604 /* 0xac */ x86emuOp_lods_byte,
11605 /* 0xad */ x86emuOp_lods_word,
11606 /* 0xac */ x86emuOp_scas_byte,
11607 /* 0xad */ x86emuOp_scas_word,
11610 /* 0xb0 */ x86emuOp_mov_byte_AL_IMM,
11611 /* 0xb1 */ x86emuOp_mov_byte_CL_IMM,
11612 /* 0xb2 */ x86emuOp_mov_byte_DL_IMM,
11613 /* 0xb3 */ x86emuOp_mov_byte_BL_IMM,
11614 /* 0xb4 */ x86emuOp_mov_byte_AH_IMM,
11615 /* 0xb5 */ x86emuOp_mov_byte_CH_IMM,
11616 /* 0xb6 */ x86emuOp_mov_byte_DH_IMM,
11617 /* 0xb7 */ x86emuOp_mov_byte_BH_IMM,
11619 /* 0xb8 */ x86emuOp_mov_word_AX_IMM,
11620 /* 0xb9 */ x86emuOp_mov_word_CX_IMM,
11621 /* 0xba */ x86emuOp_mov_word_DX_IMM,
11622 /* 0xbb */ x86emuOp_mov_word_BX_IMM,
11623 /* 0xbc */ x86emuOp_mov_word_SP_IMM,
11624 /* 0xbd */ x86emuOp_mov_word_BP_IMM,
11625 /* 0xbe */ x86emuOp_mov_word_SI_IMM,
11626 /* 0xbf */ x86emuOp_mov_word_DI_IMM,
11628 /* 0xc0 */ x86emuOp_opcC0_byte_RM_MEM,
11629 /* 0xc1 */ x86emuOp_opcC1_word_RM_MEM,
11630 /* 0xc2 */ x86emuOp_ret_near_IMM,
11631 /* 0xc3 */ x86emuOp_ret_near,
11632 /* 0xc4 */ x86emuOp_les_R_IMM,
11633 /* 0xc5 */ x86emuOp_lds_R_IMM,
11634 /* 0xc6 */ x86emuOp_mov_byte_RM_IMM,
11635 /* 0xc7 */ x86emuOp_mov_word_RM_IMM,
11636 /* 0xc8 */ x86emuOp_enter,
11637 /* 0xc9 */ x86emuOp_leave,
11638 /* 0xca */ x86emuOp_ret_far_IMM,
11639 /* 0xcb */ x86emuOp_ret_far,
11640 /* 0xcc */ x86emuOp_int3,
11641 /* 0xcd */ x86emuOp_int_IMM,
11642 /* 0xce */ x86emuOp_into,
11643 /* 0xcf */ x86emuOp_iret,
11645 /* 0xd0 */ x86emuOp_opcD0_byte_RM_1,
11646 /* 0xd1 */ x86emuOp_opcD1_word_RM_1,
11647 /* 0xd2 */ x86emuOp_opcD2_byte_RM_CL,
11648 /* 0xd3 */ x86emuOp_opcD3_word_RM_CL,
11649 /* 0xd4 */ x86emuOp_aam,
11650 /* 0xd5 */ x86emuOp_aad,
11651 /* 0xd6 */ x86emuOp_illegal_op, /* Undocumented SETALC instruction */
11652 /* 0xd7 */ x86emuOp_xlat,
11653 /* 0xd8 */ x86emuOp_esc_coprocess_d8,
11654 /* 0xd9 */ x86emuOp_esc_coprocess_d9,
11655 /* 0xda */ x86emuOp_esc_coprocess_da,
11656 /* 0xdb */ x86emuOp_esc_coprocess_db,
11657 /* 0xdc */ x86emuOp_esc_coprocess_dc,
11658 /* 0xdd */ x86emuOp_esc_coprocess_dd,
11659 /* 0xde */ x86emuOp_esc_coprocess_de,
11660 /* 0xdf */ x86emuOp_esc_coprocess_df,
11662 /* 0xe0 */ x86emuOp_loopne,
11663 /* 0xe1 */ x86emuOp_loope,
11664 /* 0xe2 */ x86emuOp_loop,
11665 /* 0xe3 */ x86emuOp_jcxz,
11666 /* 0xe4 */ x86emuOp_in_byte_AL_IMM,
11667 /* 0xe5 */ x86emuOp_in_word_AX_IMM,
11668 /* 0xe6 */ x86emuOp_out_byte_IMM_AL,
11669 /* 0xe7 */ x86emuOp_out_word_IMM_AX,
11671 /* 0xe8 */ x86emuOp_call_near_IMM,
11672 /* 0xe9 */ x86emuOp_jump_near_IMM,
11673 /* 0xea */ x86emuOp_jump_far_IMM,
11674 /* 0xeb */ x86emuOp_jump_byte_IMM,
11675 /* 0xec */ x86emuOp_in_byte_AL_DX,
11676 /* 0xed */ x86emuOp_in_word_AX_DX,
11677 /* 0xee */ x86emuOp_out_byte_DX_AL,
11678 /* 0xef */ x86emuOp_out_word_DX_AX,
11680 /* 0xf0 */ x86emuOp_lock,
11681 /* 0xf1 */ x86emuOp_illegal_op,
11682 /* 0xf2 */ x86emuOp_repne,
11683 /* 0xf3 */ x86emuOp_repe,
11684 /* 0xf4 */ x86emuOp_halt,
11685 /* 0xf5 */ x86emuOp_cmc,
11686 /* 0xf6 */ x86emuOp_opcF6_byte_RM,
11687 /* 0xf7 */ x86emuOp_opcF7_word_RM,
11689 /* 0xf8 */ x86emuOp_clc,
11690 /* 0xf9 */ x86emuOp_stc,
11691 /* 0xfa */ x86emuOp_cli,
11692 /* 0xfb */ x86emuOp_sti,
11693 /* 0xfc */ x86emuOp_cld,
11694 /* 0xfd */ x86emuOp_std,
11695 /* 0xfe */ x86emuOp_opcFE_byte_RM,
11696 /* 0xff */ x86emuOp_opcFF_word_RM,