GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / cfe / cfe / x86emu / ops.c
blob38b9b5ae9695242f5e62aec0a745ebb9bbb384d2
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 /* $XFree86: xc/extras/x86emu/src/x86emu/ops.c,v 1.4 2000/04/17 16:29:45 eich Exp $ */
75 #include "x86emu/x86emui.h"
76 #include "x86emu/ops_protos.h"
77 #include "lib_printf.h"
79 /*----------------------------- Implementation ----------------------------*/
81 /****************************************************************************
82 PARAMETERS:
83 op1 - Instruction op code
85 REMARKS:
86 Handles illegal opcodes.
87 ****************************************************************************/
88 void x86emuOp_illegal_op(
89 u8 op1)
91 START_OF_INSTR();
92 DECODE_PRINTF("ILLEGAL X86 OPCODE\n");
93 TRACE_REGS();
94 printk("%04x:%04x: %02X ILLEGAL X86 OPCODE!\n",
95 M.x86.R_CS, M.x86.R_IP-1,op1);
96 HALT_SYS();
97 END_OF_INSTR();
100 /****************************************************************************
101 REMARKS:
102 Handles opcode 0x00
103 ****************************************************************************/
104 void x86emuOp_add_byte_RM_R(u8 X86EMU_UNUSED(op1))
106 int mod, rl, rh;
107 uint destoffset;
108 u8 *destreg, *srcreg;
109 u8 destval;
111 START_OF_INSTR();
112 DECODE_PRINTF("ADD\t");
113 FETCH_DECODE_MODRM(mod, rh, rl);
114 switch (mod) {
115 case 0:
116 destoffset = decode_rm00_address(rl);
117 DECODE_PRINTF(",");
118 destval = fetch_data_byte(destoffset);
119 srcreg = DECODE_RM_BYTE_REGISTER(rh);
120 DECODE_PRINTF("\n");
121 TRACE_AND_STEP();
122 destval = add_byte(destval, *srcreg);
123 store_data_byte(destoffset, destval);
124 break;
125 case 1:
126 destoffset = decode_rm01_address(rl);
127 DECODE_PRINTF(",");
128 destval = fetch_data_byte(destoffset);
129 srcreg = DECODE_RM_BYTE_REGISTER(rh);
130 DECODE_PRINTF("\n");
131 TRACE_AND_STEP();
132 destval = add_byte(destval, *srcreg);
133 store_data_byte(destoffset, destval);
134 break;
135 case 2:
136 destoffset = decode_rm10_address(rl);
137 DECODE_PRINTF(",");
138 destval = fetch_data_byte(destoffset);
139 srcreg = DECODE_RM_BYTE_REGISTER(rh);
140 DECODE_PRINTF("\n");
141 TRACE_AND_STEP();
142 destval = add_byte(destval, *srcreg);
143 store_data_byte(destoffset, destval);
144 break;
145 case 3: /* register to register */
146 destreg = DECODE_RM_BYTE_REGISTER(rl);
147 DECODE_PRINTF(",");
148 srcreg = DECODE_RM_BYTE_REGISTER(rh);
149 DECODE_PRINTF("\n");
150 TRACE_AND_STEP();
151 *destreg = add_byte(*destreg, *srcreg);
152 break;
154 DECODE_CLEAR_SEGOVR();
155 END_OF_INSTR();
158 /****************************************************************************
159 REMARKS:
160 Handles opcode 0x01
161 ****************************************************************************/
162 void x86emuOp_add_word_RM_R(u8 X86EMU_UNUSED(op1))
164 int mod, rl, rh;
165 uint destoffset;
167 START_OF_INSTR();
168 DECODE_PRINTF("ADD\t");
169 FETCH_DECODE_MODRM(mod, rh, rl);
170 switch (mod) {
171 case 0:
172 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
173 u32 destval;
174 u32 *srcreg;
176 destoffset = decode_rm00_address(rl);
177 DECODE_PRINTF(",");
178 destval = fetch_data_long(destoffset);
179 srcreg = DECODE_RM_LONG_REGISTER(rh);
180 DECODE_PRINTF("\n");
181 TRACE_AND_STEP();
182 destval = add_long(destval, *srcreg);
183 store_data_long(destoffset, destval);
184 } else {
185 u16 destval;
186 u16 *srcreg;
188 destoffset = decode_rm00_address(rl);
189 DECODE_PRINTF(",");
190 destval = fetch_data_word(destoffset);
191 srcreg = DECODE_RM_WORD_REGISTER(rh);
192 DECODE_PRINTF("\n");
193 TRACE_AND_STEP();
194 destval = add_word(destval, *srcreg);
195 store_data_word(destoffset, destval);
197 break;
198 case 1:
199 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
200 u32 destval;
201 u32 *srcreg;
203 destoffset = decode_rm01_address(rl);
204 DECODE_PRINTF(",");
205 destval = fetch_data_long(destoffset);
206 srcreg = DECODE_RM_LONG_REGISTER(rh);
207 DECODE_PRINTF("\n");
208 TRACE_AND_STEP();
209 destval = add_long(destval, *srcreg);
210 store_data_long(destoffset, destval);
211 } else {
212 u16 destval;
213 u16 *srcreg;
215 destoffset = decode_rm01_address(rl);
216 DECODE_PRINTF(",");
217 destval = fetch_data_word(destoffset);
218 srcreg = DECODE_RM_WORD_REGISTER(rh);
219 DECODE_PRINTF("\n");
220 TRACE_AND_STEP();
221 destval = add_word(destval, *srcreg);
222 store_data_word(destoffset, destval);
224 break;
225 case 2:
226 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
227 u32 destval;
228 u32 *srcreg;
230 destoffset = decode_rm10_address(rl);
231 DECODE_PRINTF(",");
232 destval = fetch_data_long(destoffset);
233 srcreg = DECODE_RM_LONG_REGISTER(rh);
234 DECODE_PRINTF("\n");
235 TRACE_AND_STEP();
236 destval = add_long(destval, *srcreg);
237 store_data_long(destoffset, destval);
238 } else {
239 u16 destval;
240 u16 *srcreg;
242 destoffset = decode_rm10_address(rl);
243 DECODE_PRINTF(",");
244 destval = fetch_data_word(destoffset);
245 srcreg = DECODE_RM_WORD_REGISTER(rh);
246 DECODE_PRINTF("\n");
247 TRACE_AND_STEP();
248 destval = add_word(destval, *srcreg);
249 store_data_word(destoffset, destval);
251 break;
252 case 3: /* register to register */
253 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
254 u32 *destreg,*srcreg;
256 destreg = DECODE_RM_LONG_REGISTER(rl);
257 DECODE_PRINTF(",");
258 srcreg = DECODE_RM_LONG_REGISTER(rh);
259 DECODE_PRINTF("\n");
260 TRACE_AND_STEP();
261 *destreg = add_long(*destreg, *srcreg);
262 } else {
263 u16 *destreg,*srcreg;
265 destreg = DECODE_RM_WORD_REGISTER(rl);
266 DECODE_PRINTF(",");
267 srcreg = DECODE_RM_WORD_REGISTER(rh);
268 DECODE_PRINTF("\n");
269 TRACE_AND_STEP();
270 *destreg = add_word(*destreg, *srcreg);
272 break;
274 DECODE_CLEAR_SEGOVR();
275 END_OF_INSTR();
278 /****************************************************************************
279 REMARKS:
280 Handles opcode 0x02
281 ****************************************************************************/
282 void x86emuOp_add_byte_R_RM(u8 X86EMU_UNUSED(op1))
284 int mod, rl, rh;
285 u8 *destreg, *srcreg;
286 uint srcoffset;
287 u8 srcval;
289 START_OF_INSTR();
290 DECODE_PRINTF("ADD\t");
291 FETCH_DECODE_MODRM(mod, rh, rl);
292 switch (mod) {
293 case 0:
294 destreg = DECODE_RM_BYTE_REGISTER(rh);
295 DECODE_PRINTF(",");
296 srcoffset = decode_rm00_address(rl);
297 srcval = fetch_data_byte(srcoffset);
298 DECODE_PRINTF("\n");
299 TRACE_AND_STEP();
300 *destreg = add_byte(*destreg, srcval);
301 break;
302 case 1:
303 destreg = DECODE_RM_BYTE_REGISTER(rh);
304 DECODE_PRINTF(",");
305 srcoffset = decode_rm01_address(rl);
306 srcval = fetch_data_byte(srcoffset);
307 DECODE_PRINTF("\n");
308 TRACE_AND_STEP();
309 *destreg = add_byte(*destreg, srcval);
310 break;
311 case 2:
312 destreg = DECODE_RM_BYTE_REGISTER(rh);
313 DECODE_PRINTF(",");
314 srcoffset = decode_rm10_address(rl);
315 srcval = fetch_data_byte(srcoffset);
316 DECODE_PRINTF("\n");
317 TRACE_AND_STEP();
318 *destreg = add_byte(*destreg, srcval);
319 break;
320 case 3: /* register to register */
321 destreg = DECODE_RM_BYTE_REGISTER(rh);
322 DECODE_PRINTF(",");
323 srcreg = DECODE_RM_BYTE_REGISTER(rl);
324 DECODE_PRINTF("\n");
325 TRACE_AND_STEP();
326 *destreg = add_byte(*destreg, *srcreg);
327 break;
329 DECODE_CLEAR_SEGOVR();
330 END_OF_INSTR();
333 /****************************************************************************
334 REMARKS:
335 Handles opcode 0x03
336 ****************************************************************************/
337 void x86emuOp_add_word_R_RM(u8 X86EMU_UNUSED(op1))
339 int mod, rl, rh;
340 uint srcoffset;
342 START_OF_INSTR();
343 DECODE_PRINTF("ADD\t");
344 FETCH_DECODE_MODRM(mod, rh, rl);
345 switch (mod) {
346 case 0:
347 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
348 u32 *destreg;
349 u32 srcval;
351 destreg = DECODE_RM_LONG_REGISTER(rh);
352 DECODE_PRINTF(",");
353 srcoffset = decode_rm00_address(rl);
354 srcval = fetch_data_long(srcoffset);
355 DECODE_PRINTF("\n");
356 TRACE_AND_STEP();
357 *destreg = add_long(*destreg, srcval);
358 } else {
359 u16 *destreg;
360 u16 srcval;
362 destreg = DECODE_RM_WORD_REGISTER(rh);
363 DECODE_PRINTF(",");
364 srcoffset = decode_rm00_address(rl);
365 srcval = fetch_data_word(srcoffset);
366 DECODE_PRINTF("\n");
367 TRACE_AND_STEP();
368 *destreg = add_word(*destreg, srcval);
370 break;
371 case 1:
372 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
373 u32 *destreg;
374 u32 srcval;
376 destreg = DECODE_RM_LONG_REGISTER(rh);
377 DECODE_PRINTF(",");
378 srcoffset = decode_rm01_address(rl);
379 srcval = fetch_data_long(srcoffset);
380 DECODE_PRINTF("\n");
381 TRACE_AND_STEP();
382 *destreg = add_long(*destreg, srcval);
383 } else {
384 u16 *destreg;
385 u16 srcval;
387 destreg = DECODE_RM_WORD_REGISTER(rh);
388 DECODE_PRINTF(",");
389 srcoffset = decode_rm01_address(rl);
390 srcval = fetch_data_word(srcoffset);
391 DECODE_PRINTF("\n");
392 TRACE_AND_STEP();
393 *destreg = add_word(*destreg, srcval);
395 break;
396 case 2:
397 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
398 u32 *destreg;
399 u32 srcval;
401 destreg = DECODE_RM_LONG_REGISTER(rh);
402 DECODE_PRINTF(",");
403 srcoffset = decode_rm10_address(rl);
404 srcval = fetch_data_long(srcoffset);
405 DECODE_PRINTF("\n");
406 TRACE_AND_STEP();
407 *destreg = add_long(*destreg, srcval);
408 } else {
409 u16 *destreg;
410 u16 srcval;
412 destreg = DECODE_RM_WORD_REGISTER(rh);
413 DECODE_PRINTF(",");
414 srcoffset = decode_rm10_address(rl);
415 srcval = fetch_data_word(srcoffset);
416 DECODE_PRINTF("\n");
417 TRACE_AND_STEP();
418 *destreg = add_word(*destreg, srcval);
420 break;
421 case 3: /* register to register */
422 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
423 u32 *destreg,*srcreg;
425 destreg = DECODE_RM_LONG_REGISTER(rh);
426 DECODE_PRINTF(",");
427 srcreg = DECODE_RM_LONG_REGISTER(rl);
428 DECODE_PRINTF("\n");
429 TRACE_AND_STEP();
430 *destreg = add_long(*destreg, *srcreg);
431 } else {
432 u16 *destreg,*srcreg;
434 destreg = DECODE_RM_WORD_REGISTER(rh);
435 DECODE_PRINTF(",");
436 srcreg = DECODE_RM_WORD_REGISTER(rl);
437 DECODE_PRINTF("\n");
438 TRACE_AND_STEP();
439 *destreg = add_word(*destreg, *srcreg);
441 break;
443 DECODE_CLEAR_SEGOVR();
444 END_OF_INSTR();
447 /****************************************************************************
448 REMARKS:
449 Handles opcode 0x04
450 ****************************************************************************/
451 void x86emuOp_add_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
453 u8 srcval;
455 START_OF_INSTR();
456 DECODE_PRINTF("ADD\tAL,");
457 srcval = fetch_byte_imm();
458 DECODE_PRINTF2("%x\n", srcval);
459 TRACE_AND_STEP();
460 M.x86.R_AL = add_byte(M.x86.R_AL, srcval);
461 DECODE_CLEAR_SEGOVR();
462 END_OF_INSTR();
465 /****************************************************************************
466 REMARKS:
467 Handles opcode 0x05
468 ****************************************************************************/
469 void x86emuOp_add_word_AX_IMM(u8 X86EMU_UNUSED(op1))
471 u32 srcval;
473 START_OF_INSTR();
474 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
475 DECODE_PRINTF("ADD\tEAX,");
476 srcval = fetch_long_imm();
477 } else {
478 DECODE_PRINTF("ADD\tAX,");
479 srcval = fetch_word_imm();
481 DECODE_PRINTF2("%x\n", srcval);
482 TRACE_AND_STEP();
483 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
484 M.x86.R_EAX = add_long(M.x86.R_EAX, srcval);
485 } else {
486 M.x86.R_AX = add_word(M.x86.R_AX, (u16)srcval);
488 DECODE_CLEAR_SEGOVR();
489 END_OF_INSTR();
492 /****************************************************************************
493 REMARKS:
494 Handles opcode 0x06
495 ****************************************************************************/
496 void x86emuOp_push_ES(u8 X86EMU_UNUSED(op1))
498 START_OF_INSTR();
499 DECODE_PRINTF("PUSH\tES\n");
500 TRACE_AND_STEP();
501 push_word(M.x86.R_ES);
502 DECODE_CLEAR_SEGOVR();
503 END_OF_INSTR();
506 /****************************************************************************
507 REMARKS:
508 Handles opcode 0x07
509 ****************************************************************************/
510 void x86emuOp_pop_ES(u8 X86EMU_UNUSED(op1))
512 START_OF_INSTR();
513 DECODE_PRINTF("POP\tES\n");
514 TRACE_AND_STEP();
515 M.x86.R_ES = pop_word();
516 DECODE_CLEAR_SEGOVR();
517 END_OF_INSTR();
520 /****************************************************************************
521 REMARKS:
522 Handles opcode 0x08
523 ****************************************************************************/
524 void x86emuOp_or_byte_RM_R(u8 X86EMU_UNUSED(op1))
526 int mod, rl, rh;
527 u8 *destreg, *srcreg;
528 uint destoffset;
529 u8 destval;
531 START_OF_INSTR();
532 DECODE_PRINTF("OR\t");
533 FETCH_DECODE_MODRM(mod, rh, rl);
534 switch (mod) {
535 case 0:
536 destoffset = decode_rm00_address(rl);
537 DECODE_PRINTF(",");
538 destval = fetch_data_byte(destoffset);
539 srcreg = DECODE_RM_BYTE_REGISTER(rh);
540 DECODE_PRINTF("\n");
541 TRACE_AND_STEP();
542 destval = or_byte(destval, *srcreg);
543 store_data_byte(destoffset, destval);
544 break;
545 case 1:
546 destoffset = decode_rm01_address(rl);
547 DECODE_PRINTF(",");
548 destval = fetch_data_byte(destoffset);
549 srcreg = DECODE_RM_BYTE_REGISTER(rh);
550 DECODE_PRINTF("\n");
551 TRACE_AND_STEP();
552 destval = or_byte(destval, *srcreg);
553 store_data_byte(destoffset, destval);
554 break;
555 case 2:
556 destoffset = decode_rm10_address(rl);
557 DECODE_PRINTF(",");
558 destval = fetch_data_byte(destoffset);
559 srcreg = DECODE_RM_BYTE_REGISTER(rh);
560 DECODE_PRINTF("\n");
561 TRACE_AND_STEP();
562 destval = or_byte(destval, *srcreg);
563 store_data_byte(destoffset, destval);
564 break;
565 case 3: /* register to register */
566 destreg = DECODE_RM_BYTE_REGISTER(rl);
567 DECODE_PRINTF(",");
568 srcreg = DECODE_RM_BYTE_REGISTER(rh);
569 DECODE_PRINTF("\n");
570 TRACE_AND_STEP();
571 *destreg = or_byte(*destreg, *srcreg);
572 break;
574 DECODE_CLEAR_SEGOVR();
575 END_OF_INSTR();
578 /****************************************************************************
579 REMARKS:
580 Handles opcode 0x09
581 ****************************************************************************/
582 void x86emuOp_or_word_RM_R(u8 X86EMU_UNUSED(op1))
584 int mod, rl, rh;
585 uint destoffset;
587 START_OF_INSTR();
588 DECODE_PRINTF("OR\t");
589 FETCH_DECODE_MODRM(mod, rh, rl);
590 switch (mod) {
591 case 0:
592 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
593 u32 destval;
594 u32 *srcreg;
596 destoffset = decode_rm00_address(rl);
597 DECODE_PRINTF(",");
598 destval = fetch_data_long(destoffset);
599 srcreg = DECODE_RM_LONG_REGISTER(rh);
600 DECODE_PRINTF("\n");
601 TRACE_AND_STEP();
602 destval = or_long(destval, *srcreg);
603 store_data_long(destoffset, destval);
604 } else {
605 u16 destval;
606 u16 *srcreg;
608 destoffset = decode_rm00_address(rl);
609 DECODE_PRINTF(",");
610 destval = fetch_data_word(destoffset);
611 srcreg = DECODE_RM_WORD_REGISTER(rh);
612 DECODE_PRINTF("\n");
613 TRACE_AND_STEP();
614 destval = or_word(destval, *srcreg);
615 store_data_word(destoffset, destval);
617 break;
618 case 1:
619 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
620 u32 destval;
621 u32 *srcreg;
623 destoffset = decode_rm01_address(rl);
624 DECODE_PRINTF(",");
625 destval = fetch_data_long(destoffset);
626 srcreg = DECODE_RM_LONG_REGISTER(rh);
627 DECODE_PRINTF("\n");
628 TRACE_AND_STEP();
629 destval = or_long(destval, *srcreg);
630 store_data_long(destoffset, destval);
631 } else {
632 u16 destval;
633 u16 *srcreg;
635 destoffset = decode_rm01_address(rl);
636 DECODE_PRINTF(",");
637 destval = fetch_data_word(destoffset);
638 srcreg = DECODE_RM_WORD_REGISTER(rh);
639 DECODE_PRINTF("\n");
640 TRACE_AND_STEP();
641 destval = or_word(destval, *srcreg);
642 store_data_word(destoffset, destval);
644 break;
645 case 2:
646 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
647 u32 destval;
648 u32 *srcreg;
650 destoffset = decode_rm10_address(rl);
651 DECODE_PRINTF(",");
652 destval = fetch_data_long(destoffset);
653 srcreg = DECODE_RM_LONG_REGISTER(rh);
654 DECODE_PRINTF("\n");
655 TRACE_AND_STEP();
656 destval = or_long(destval, *srcreg);
657 store_data_long(destoffset, destval);
658 } else {
659 u16 destval;
660 u16 *srcreg;
662 destoffset = decode_rm10_address(rl);
663 DECODE_PRINTF(",");
664 destval = fetch_data_word(destoffset);
665 srcreg = DECODE_RM_WORD_REGISTER(rh);
666 DECODE_PRINTF("\n");
667 TRACE_AND_STEP();
668 destval = or_word(destval, *srcreg);
669 store_data_word(destoffset, destval);
671 break;
672 case 3: /* register to register */
673 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
674 u32 *destreg,*srcreg;
676 destreg = DECODE_RM_LONG_REGISTER(rl);
677 DECODE_PRINTF(",");
678 srcreg = DECODE_RM_LONG_REGISTER(rh);
679 DECODE_PRINTF("\n");
680 TRACE_AND_STEP();
681 *destreg = or_long(*destreg, *srcreg);
682 } else {
683 u16 *destreg,*srcreg;
685 destreg = DECODE_RM_WORD_REGISTER(rl);
686 DECODE_PRINTF(",");
687 srcreg = DECODE_RM_WORD_REGISTER(rh);
688 DECODE_PRINTF("\n");
689 TRACE_AND_STEP();
690 *destreg = or_word(*destreg, *srcreg);
692 break;
694 DECODE_CLEAR_SEGOVR();
695 END_OF_INSTR();
698 /****************************************************************************
699 REMARKS:
700 Handles opcode 0x0a
701 ****************************************************************************/
702 void x86emuOp_or_byte_R_RM(u8 X86EMU_UNUSED(op1))
704 int mod, rl, rh;
705 u8 *destreg, *srcreg;
706 uint srcoffset;
707 u8 srcval;
709 START_OF_INSTR();
710 DECODE_PRINTF("OR\t");
711 FETCH_DECODE_MODRM(mod, rh, rl);
712 switch (mod) {
713 case 0:
714 destreg = DECODE_RM_BYTE_REGISTER(rh);
715 DECODE_PRINTF(",");
716 srcoffset = decode_rm00_address(rl);
717 srcval = fetch_data_byte(srcoffset);
718 DECODE_PRINTF("\n");
719 TRACE_AND_STEP();
720 *destreg = or_byte(*destreg, srcval);
721 break;
722 case 1:
723 destreg = DECODE_RM_BYTE_REGISTER(rh);
724 DECODE_PRINTF(",");
725 srcoffset = decode_rm01_address(rl);
726 srcval = fetch_data_byte(srcoffset);
727 DECODE_PRINTF("\n");
728 TRACE_AND_STEP();
729 *destreg = or_byte(*destreg, srcval);
730 break;
731 case 2:
732 destreg = DECODE_RM_BYTE_REGISTER(rh);
733 DECODE_PRINTF(",");
734 srcoffset = decode_rm10_address(rl);
735 srcval = fetch_data_byte(srcoffset);
736 DECODE_PRINTF("\n");
737 TRACE_AND_STEP();
738 *destreg = or_byte(*destreg, srcval);
739 break;
740 case 3: /* register to register */
741 destreg = DECODE_RM_BYTE_REGISTER(rh);
742 DECODE_PRINTF(",");
743 srcreg = DECODE_RM_BYTE_REGISTER(rl);
744 DECODE_PRINTF("\n");
745 TRACE_AND_STEP();
746 *destreg = or_byte(*destreg, *srcreg);
747 break;
749 DECODE_CLEAR_SEGOVR();
750 END_OF_INSTR();
753 /****************************************************************************
754 REMARKS:
755 Handles opcode 0x0b
756 ****************************************************************************/
757 void x86emuOp_or_word_R_RM(u8 X86EMU_UNUSED(op1))
759 int mod, rl, rh;
760 uint srcoffset;
762 START_OF_INSTR();
763 DECODE_PRINTF("OR\t");
764 FETCH_DECODE_MODRM(mod, rh, rl);
765 switch (mod) {
766 case 0:
767 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
768 u32 *destreg;
769 u32 srcval;
771 destreg = DECODE_RM_LONG_REGISTER(rh);
772 DECODE_PRINTF(",");
773 srcoffset = decode_rm00_address(rl);
774 srcval = fetch_data_long(srcoffset);
775 DECODE_PRINTF("\n");
776 TRACE_AND_STEP();
777 *destreg = or_long(*destreg, srcval);
778 } else {
779 u16 *destreg;
780 u16 srcval;
782 destreg = DECODE_RM_WORD_REGISTER(rh);
783 DECODE_PRINTF(",");
784 srcoffset = decode_rm00_address(rl);
785 srcval = fetch_data_word(srcoffset);
786 DECODE_PRINTF("\n");
787 TRACE_AND_STEP();
788 *destreg = or_word(*destreg, srcval);
790 break;
791 case 1:
792 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
793 u32 *destreg;
794 u32 srcval;
796 destreg = DECODE_RM_LONG_REGISTER(rh);
797 DECODE_PRINTF(",");
798 srcoffset = decode_rm01_address(rl);
799 srcval = fetch_data_long(srcoffset);
800 DECODE_PRINTF("\n");
801 TRACE_AND_STEP();
802 *destreg = or_long(*destreg, srcval);
803 } else {
804 u16 *destreg;
805 u16 srcval;
807 destreg = DECODE_RM_WORD_REGISTER(rh);
808 DECODE_PRINTF(",");
809 srcoffset = decode_rm01_address(rl);
810 srcval = fetch_data_word(srcoffset);
811 DECODE_PRINTF("\n");
812 TRACE_AND_STEP();
813 *destreg = or_word(*destreg, srcval);
815 break;
816 case 2:
817 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
818 u32 *destreg;
819 u32 srcval;
821 destreg = DECODE_RM_LONG_REGISTER(rh);
822 DECODE_PRINTF(",");
823 srcoffset = decode_rm10_address(rl);
824 srcval = fetch_data_long(srcoffset);
825 DECODE_PRINTF("\n");
826 TRACE_AND_STEP();
827 *destreg = or_long(*destreg, srcval);
828 } else {
829 u16 *destreg;
830 u16 srcval;
832 destreg = DECODE_RM_WORD_REGISTER(rh);
833 DECODE_PRINTF(",");
834 srcoffset = decode_rm10_address(rl);
835 srcval = fetch_data_word(srcoffset);
836 DECODE_PRINTF("\n");
837 TRACE_AND_STEP();
838 *destreg = or_word(*destreg, srcval);
840 break;
841 case 3: /* register to register */
842 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
843 u32 *destreg,*srcreg;
845 destreg = DECODE_RM_LONG_REGISTER(rh);
846 DECODE_PRINTF(",");
847 srcreg = DECODE_RM_LONG_REGISTER(rl);
848 DECODE_PRINTF("\n");
849 TRACE_AND_STEP();
850 *destreg = or_long(*destreg, *srcreg);
851 } else {
852 u16 *destreg,*srcreg;
854 destreg = DECODE_RM_WORD_REGISTER(rh);
855 DECODE_PRINTF(",");
856 srcreg = DECODE_RM_WORD_REGISTER(rl);
857 DECODE_PRINTF("\n");
858 TRACE_AND_STEP();
859 *destreg = or_word(*destreg, *srcreg);
861 break;
863 DECODE_CLEAR_SEGOVR();
864 END_OF_INSTR();
867 /****************************************************************************
868 REMARKS:
869 Handles opcode 0x0c
870 ****************************************************************************/
871 void x86emuOp_or_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
873 u8 srcval;
875 START_OF_INSTR();
876 DECODE_PRINTF("OR\tAL,");
877 srcval = fetch_byte_imm();
878 DECODE_PRINTF2("%x\n", srcval);
879 TRACE_AND_STEP();
880 M.x86.R_AL = or_byte(M.x86.R_AL, srcval);
881 DECODE_CLEAR_SEGOVR();
882 END_OF_INSTR();
885 /****************************************************************************
886 REMARKS:
887 Handles opcode 0x0d
888 ****************************************************************************/
889 void x86emuOp_or_word_AX_IMM(u8 X86EMU_UNUSED(op1))
891 u32 srcval;
893 START_OF_INSTR();
894 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
895 DECODE_PRINTF("OR\tEAX,");
896 srcval = fetch_long_imm();
897 } else {
898 DECODE_PRINTF("OR\tAX,");
899 srcval = fetch_word_imm();
901 DECODE_PRINTF2("%x\n", srcval);
902 TRACE_AND_STEP();
903 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
904 M.x86.R_EAX = or_long(M.x86.R_EAX, srcval);
905 } else {
906 M.x86.R_AX = or_word(M.x86.R_AX, (u16)srcval);
908 DECODE_CLEAR_SEGOVR();
909 END_OF_INSTR();
912 /****************************************************************************
913 REMARKS:
914 Handles opcode 0x0e
915 ****************************************************************************/
916 void x86emuOp_push_CS(u8 X86EMU_UNUSED(op1))
918 START_OF_INSTR();
919 DECODE_PRINTF("PUSH\tCS\n");
920 TRACE_AND_STEP();
921 push_word(M.x86.R_CS);
922 DECODE_CLEAR_SEGOVR();
923 END_OF_INSTR();
926 /****************************************************************************
927 REMARKS:
928 Handles opcode 0x0f. Escape for two-byte opcode (286 or better)
929 ****************************************************************************/
930 void x86emuOp_two_byte(u8 X86EMU_UNUSED(op1))
932 u8 op2 = (*sys_rdb)(((u32)M.x86.R_CS << 4) + (M.x86.R_IP++));
933 INC_DECODED_INST_LEN(1);
934 (*x86emu_optab2[op2])(op2);
937 /****************************************************************************
938 REMARKS:
939 Handles opcode 0x10
940 ****************************************************************************/
941 void x86emuOp_adc_byte_RM_R(u8 X86EMU_UNUSED(op1))
943 int mod, rl, rh;
944 u8 *destreg, *srcreg;
945 uint destoffset;
946 u8 destval;
948 START_OF_INSTR();
949 DECODE_PRINTF("ADC\t");
950 FETCH_DECODE_MODRM(mod, rh, rl);
951 switch (mod) {
952 case 0:
953 destoffset = decode_rm00_address(rl);
954 DECODE_PRINTF(",");
955 destval = fetch_data_byte(destoffset);
956 srcreg = DECODE_RM_BYTE_REGISTER(rh);
957 DECODE_PRINTF("\n");
958 TRACE_AND_STEP();
959 destval = adc_byte(destval, *srcreg);
960 store_data_byte(destoffset, destval);
961 break;
962 case 1:
963 destoffset = decode_rm01_address(rl);
964 DECODE_PRINTF(",");
965 destval = fetch_data_byte(destoffset);
966 srcreg = DECODE_RM_BYTE_REGISTER(rh);
967 DECODE_PRINTF("\n");
968 TRACE_AND_STEP();
969 destval = adc_byte(destval, *srcreg);
970 store_data_byte(destoffset, destval);
971 break;
972 case 2:
973 destoffset = decode_rm10_address(rl);
974 DECODE_PRINTF(",");
975 destval = fetch_data_byte(destoffset);
976 srcreg = DECODE_RM_BYTE_REGISTER(rh);
977 DECODE_PRINTF("\n");
978 TRACE_AND_STEP();
979 destval = adc_byte(destval, *srcreg);
980 store_data_byte(destoffset, destval);
981 break;
982 case 3: /* register to register */
983 destreg = DECODE_RM_BYTE_REGISTER(rl);
984 DECODE_PRINTF(",");
985 srcreg = DECODE_RM_BYTE_REGISTER(rh);
986 DECODE_PRINTF("\n");
987 TRACE_AND_STEP();
988 *destreg = adc_byte(*destreg, *srcreg);
989 break;
991 DECODE_CLEAR_SEGOVR();
992 END_OF_INSTR();
995 /****************************************************************************
996 REMARKS:
997 Handles opcode 0x11
998 ****************************************************************************/
999 void x86emuOp_adc_word_RM_R(u8 X86EMU_UNUSED(op1))
1001 int mod, rl, rh;
1002 uint destoffset;
1004 START_OF_INSTR();
1005 DECODE_PRINTF("ADC\t");
1006 FETCH_DECODE_MODRM(mod, rh, rl);
1007 switch (mod) {
1008 case 0:
1009 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1010 u32 destval;
1011 u32 *srcreg;
1013 destoffset = decode_rm00_address(rl);
1014 DECODE_PRINTF(",");
1015 destval = fetch_data_long(destoffset);
1016 srcreg = DECODE_RM_LONG_REGISTER(rh);
1017 DECODE_PRINTF("\n");
1018 TRACE_AND_STEP();
1019 destval = adc_long(destval, *srcreg);
1020 store_data_long(destoffset, destval);
1021 } else {
1022 u16 destval;
1023 u16 *srcreg;
1025 destoffset = decode_rm00_address(rl);
1026 DECODE_PRINTF(",");
1027 destval = fetch_data_word(destoffset);
1028 srcreg = DECODE_RM_WORD_REGISTER(rh);
1029 DECODE_PRINTF("\n");
1030 TRACE_AND_STEP();
1031 destval = adc_word(destval, *srcreg);
1032 store_data_word(destoffset, destval);
1034 break;
1035 case 1:
1036 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1037 u32 destval;
1038 u32 *srcreg;
1040 destoffset = decode_rm01_address(rl);
1041 DECODE_PRINTF(",");
1042 destval = fetch_data_long(destoffset);
1043 srcreg = DECODE_RM_LONG_REGISTER(rh);
1044 DECODE_PRINTF("\n");
1045 TRACE_AND_STEP();
1046 destval = adc_long(destval, *srcreg);
1047 store_data_long(destoffset, destval);
1048 } else {
1049 u16 destval;
1050 u16 *srcreg;
1052 destoffset = decode_rm01_address(rl);
1053 DECODE_PRINTF(",");
1054 destval = fetch_data_word(destoffset);
1055 srcreg = DECODE_RM_WORD_REGISTER(rh);
1056 DECODE_PRINTF("\n");
1057 TRACE_AND_STEP();
1058 destval = adc_word(destval, *srcreg);
1059 store_data_word(destoffset, destval);
1061 break;
1062 case 2:
1063 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1064 u32 destval;
1065 u32 *srcreg;
1067 destoffset = decode_rm10_address(rl);
1068 DECODE_PRINTF(",");
1069 destval = fetch_data_long(destoffset);
1070 srcreg = DECODE_RM_LONG_REGISTER(rh);
1071 DECODE_PRINTF("\n");
1072 TRACE_AND_STEP();
1073 destval = adc_long(destval, *srcreg);
1074 store_data_long(destoffset, destval);
1075 } else {
1076 u16 destval;
1077 u16 *srcreg;
1079 destoffset = decode_rm10_address(rl);
1080 DECODE_PRINTF(",");
1081 destval = fetch_data_word(destoffset);
1082 srcreg = DECODE_RM_WORD_REGISTER(rh);
1083 DECODE_PRINTF("\n");
1084 TRACE_AND_STEP();
1085 destval = adc_word(destval, *srcreg);
1086 store_data_word(destoffset, destval);
1088 break;
1089 case 3: /* register to register */
1090 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1091 u32 *destreg,*srcreg;
1093 destreg = DECODE_RM_LONG_REGISTER(rl);
1094 DECODE_PRINTF(",");
1095 srcreg = DECODE_RM_LONG_REGISTER(rh);
1096 DECODE_PRINTF("\n");
1097 TRACE_AND_STEP();
1098 *destreg = adc_long(*destreg, *srcreg);
1099 } else {
1100 u16 *destreg,*srcreg;
1102 destreg = DECODE_RM_WORD_REGISTER(rl);
1103 DECODE_PRINTF(",");
1104 srcreg = DECODE_RM_WORD_REGISTER(rh);
1105 DECODE_PRINTF("\n");
1106 TRACE_AND_STEP();
1107 *destreg = adc_word(*destreg, *srcreg);
1109 break;
1111 DECODE_CLEAR_SEGOVR();
1112 END_OF_INSTR();
1115 /****************************************************************************
1116 REMARKS:
1117 Handles opcode 0x12
1118 ****************************************************************************/
1119 void x86emuOp_adc_byte_R_RM(u8 X86EMU_UNUSED(op1))
1121 int mod, rl, rh;
1122 u8 *destreg, *srcreg;
1123 uint srcoffset;
1124 u8 srcval;
1126 START_OF_INSTR();
1127 DECODE_PRINTF("ADC\t");
1128 FETCH_DECODE_MODRM(mod, rh, rl);
1129 switch (mod) {
1130 case 0:
1131 destreg = DECODE_RM_BYTE_REGISTER(rh);
1132 DECODE_PRINTF(",");
1133 srcoffset = decode_rm00_address(rl);
1134 srcval = fetch_data_byte(srcoffset);
1135 DECODE_PRINTF("\n");
1136 TRACE_AND_STEP();
1137 *destreg = adc_byte(*destreg, srcval);
1138 break;
1139 case 1:
1140 destreg = DECODE_RM_BYTE_REGISTER(rh);
1141 DECODE_PRINTF(",");
1142 srcoffset = decode_rm01_address(rl);
1143 srcval = fetch_data_byte(srcoffset);
1144 DECODE_PRINTF("\n");
1145 TRACE_AND_STEP();
1146 *destreg = adc_byte(*destreg, srcval);
1147 break;
1148 case 2:
1149 destreg = DECODE_RM_BYTE_REGISTER(rh);
1150 DECODE_PRINTF(",");
1151 srcoffset = decode_rm10_address(rl);
1152 srcval = fetch_data_byte(srcoffset);
1153 DECODE_PRINTF("\n");
1154 TRACE_AND_STEP();
1155 *destreg = adc_byte(*destreg, srcval);
1156 break;
1157 case 3: /* register to register */
1158 destreg = DECODE_RM_BYTE_REGISTER(rh);
1159 DECODE_PRINTF(",");
1160 srcreg = DECODE_RM_BYTE_REGISTER(rl);
1161 DECODE_PRINTF("\n");
1162 TRACE_AND_STEP();
1163 *destreg = adc_byte(*destreg, *srcreg);
1164 break;
1166 DECODE_CLEAR_SEGOVR();
1167 END_OF_INSTR();
1170 /****************************************************************************
1171 REMARKS:
1172 Handles opcode 0x13
1173 ****************************************************************************/
1174 void x86emuOp_adc_word_R_RM(u8 X86EMU_UNUSED(op1))
1176 int mod, rl, rh;
1177 uint srcoffset;
1179 START_OF_INSTR();
1180 DECODE_PRINTF("ADC\t");
1181 FETCH_DECODE_MODRM(mod, rh, rl);
1182 switch (mod) {
1183 case 0:
1184 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1185 u32 *destreg;
1186 u32 srcval;
1188 destreg = DECODE_RM_LONG_REGISTER(rh);
1189 DECODE_PRINTF(",");
1190 srcoffset = decode_rm00_address(rl);
1191 srcval = fetch_data_long(srcoffset);
1192 DECODE_PRINTF("\n");
1193 TRACE_AND_STEP();
1194 *destreg = adc_long(*destreg, srcval);
1195 } else {
1196 u16 *destreg;
1197 u16 srcval;
1199 destreg = DECODE_RM_WORD_REGISTER(rh);
1200 DECODE_PRINTF(",");
1201 srcoffset = decode_rm00_address(rl);
1202 srcval = fetch_data_word(srcoffset);
1203 DECODE_PRINTF("\n");
1204 TRACE_AND_STEP();
1205 *destreg = adc_word(*destreg, srcval);
1207 break;
1208 case 1:
1209 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1210 u32 *destreg;
1211 u32 srcval;
1213 destreg = DECODE_RM_LONG_REGISTER(rh);
1214 DECODE_PRINTF(",");
1215 srcoffset = decode_rm01_address(rl);
1216 srcval = fetch_data_long(srcoffset);
1217 DECODE_PRINTF("\n");
1218 TRACE_AND_STEP();
1219 *destreg = adc_long(*destreg, srcval);
1220 } else {
1221 u16 *destreg;
1222 u16 srcval;
1224 destreg = DECODE_RM_WORD_REGISTER(rh);
1225 DECODE_PRINTF(",");
1226 srcoffset = decode_rm01_address(rl);
1227 srcval = fetch_data_word(srcoffset);
1228 DECODE_PRINTF("\n");
1229 TRACE_AND_STEP();
1230 *destreg = adc_word(*destreg, srcval);
1232 break;
1233 case 2:
1234 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1235 u32 *destreg;
1236 u32 srcval;
1238 destreg = DECODE_RM_LONG_REGISTER(rh);
1239 DECODE_PRINTF(",");
1240 srcoffset = decode_rm10_address(rl);
1241 srcval = fetch_data_long(srcoffset);
1242 DECODE_PRINTF("\n");
1243 TRACE_AND_STEP();
1244 *destreg = adc_long(*destreg, srcval);
1245 } else {
1246 u16 *destreg;
1247 u16 srcval;
1249 destreg = DECODE_RM_WORD_REGISTER(rh);
1250 DECODE_PRINTF(",");
1251 srcoffset = decode_rm10_address(rl);
1252 srcval = fetch_data_word(srcoffset);
1253 DECODE_PRINTF("\n");
1254 TRACE_AND_STEP();
1255 *destreg = adc_word(*destreg, srcval);
1257 break;
1258 case 3: /* register to register */
1259 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1260 u32 *destreg,*srcreg;
1262 destreg = DECODE_RM_LONG_REGISTER(rh);
1263 DECODE_PRINTF(",");
1264 srcreg = DECODE_RM_LONG_REGISTER(rl);
1265 DECODE_PRINTF("\n");
1266 TRACE_AND_STEP();
1267 *destreg = adc_long(*destreg, *srcreg);
1268 } else {
1269 u16 *destreg,*srcreg;
1271 destreg = DECODE_RM_WORD_REGISTER(rh);
1272 DECODE_PRINTF(",");
1273 srcreg = DECODE_RM_WORD_REGISTER(rl);
1274 DECODE_PRINTF("\n");
1275 TRACE_AND_STEP();
1276 *destreg = adc_word(*destreg, *srcreg);
1278 break;
1280 DECODE_CLEAR_SEGOVR();
1281 END_OF_INSTR();
1284 /****************************************************************************
1285 REMARKS:
1286 Handles opcode 0x14
1287 ****************************************************************************/
1288 void x86emuOp_adc_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
1290 u8 srcval;
1292 START_OF_INSTR();
1293 DECODE_PRINTF("ADC\tAL,");
1294 srcval = fetch_byte_imm();
1295 DECODE_PRINTF2("%x\n", srcval);
1296 TRACE_AND_STEP();
1297 M.x86.R_AL = adc_byte(M.x86.R_AL, srcval);
1298 DECODE_CLEAR_SEGOVR();
1299 END_OF_INSTR();
1302 /****************************************************************************
1303 REMARKS:
1304 Handles opcode 0x15
1305 ****************************************************************************/
1306 void x86emuOp_adc_word_AX_IMM(u8 X86EMU_UNUSED(op1))
1308 u32 srcval;
1310 START_OF_INSTR();
1311 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1312 DECODE_PRINTF("ADC\tEAX,");
1313 srcval = fetch_long_imm();
1314 } else {
1315 DECODE_PRINTF("ADC\tAX,");
1316 srcval = fetch_word_imm();
1318 DECODE_PRINTF2("%x\n", srcval);
1319 TRACE_AND_STEP();
1320 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1321 M.x86.R_EAX = adc_long(M.x86.R_EAX, srcval);
1322 } else {
1323 M.x86.R_AX = adc_word(M.x86.R_AX, (u16)srcval);
1325 DECODE_CLEAR_SEGOVR();
1326 END_OF_INSTR();
1329 /****************************************************************************
1330 REMARKS:
1331 Handles opcode 0x16
1332 ****************************************************************************/
1333 void x86emuOp_push_SS(u8 X86EMU_UNUSED(op1))
1335 START_OF_INSTR();
1336 DECODE_PRINTF("PUSH\tSS\n");
1337 TRACE_AND_STEP();
1338 push_word(M.x86.R_SS);
1339 DECODE_CLEAR_SEGOVR();
1340 END_OF_INSTR();
1343 /****************************************************************************
1344 REMARKS:
1345 Handles opcode 0x17
1346 ****************************************************************************/
1347 void x86emuOp_pop_SS(u8 X86EMU_UNUSED(op1))
1349 START_OF_INSTR();
1350 DECODE_PRINTF("POP\tSS\n");
1351 TRACE_AND_STEP();
1352 M.x86.R_SS = pop_word();
1353 DECODE_CLEAR_SEGOVR();
1354 END_OF_INSTR();
1357 /****************************************************************************
1358 REMARKS:
1359 Handles opcode 0x18
1360 ****************************************************************************/
1361 void x86emuOp_sbb_byte_RM_R(u8 X86EMU_UNUSED(op1))
1363 int mod, rl, rh;
1364 u8 *destreg, *srcreg;
1365 uint destoffset;
1366 u8 destval;
1368 START_OF_INSTR();
1369 DECODE_PRINTF("SBB\t");
1370 FETCH_DECODE_MODRM(mod, rh, rl);
1371 switch (mod) {
1372 case 0:
1373 destoffset = decode_rm00_address(rl);
1374 DECODE_PRINTF(",");
1375 destval = fetch_data_byte(destoffset);
1376 srcreg = DECODE_RM_BYTE_REGISTER(rh);
1377 DECODE_PRINTF("\n");
1378 TRACE_AND_STEP();
1379 destval = sbb_byte(destval, *srcreg);
1380 store_data_byte(destoffset, destval);
1381 break;
1382 case 1:
1383 destoffset = decode_rm01_address(rl);
1384 DECODE_PRINTF(",");
1385 destval = fetch_data_byte(destoffset);
1386 srcreg = DECODE_RM_BYTE_REGISTER(rh);
1387 DECODE_PRINTF("\n");
1388 TRACE_AND_STEP();
1389 destval = sbb_byte(destval, *srcreg);
1390 store_data_byte(destoffset, destval);
1391 break;
1392 case 2:
1393 destoffset = decode_rm10_address(rl);
1394 DECODE_PRINTF(",");
1395 destval = fetch_data_byte(destoffset);
1396 srcreg = DECODE_RM_BYTE_REGISTER(rh);
1397 DECODE_PRINTF("\n");
1398 TRACE_AND_STEP();
1399 destval = sbb_byte(destval, *srcreg);
1400 store_data_byte(destoffset, destval);
1401 break;
1402 case 3: /* register to register */
1403 destreg = DECODE_RM_BYTE_REGISTER(rl);
1404 DECODE_PRINTF(",");
1405 srcreg = DECODE_RM_BYTE_REGISTER(rh);
1406 DECODE_PRINTF("\n");
1407 TRACE_AND_STEP();
1408 *destreg = sbb_byte(*destreg, *srcreg);
1409 break;
1411 DECODE_CLEAR_SEGOVR();
1412 END_OF_INSTR();
1415 /****************************************************************************
1416 REMARKS:
1417 Handles opcode 0x19
1418 ****************************************************************************/
1419 void x86emuOp_sbb_word_RM_R(u8 X86EMU_UNUSED(op1))
1421 int mod, rl, rh;
1422 uint destoffset;
1424 START_OF_INSTR();
1425 DECODE_PRINTF("SBB\t");
1426 FETCH_DECODE_MODRM(mod, rh, rl);
1427 switch (mod) {
1428 case 0:
1429 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1430 u32 destval;
1431 u32 *srcreg;
1433 destoffset = decode_rm00_address(rl);
1434 DECODE_PRINTF(",");
1435 destval = fetch_data_long(destoffset);
1436 srcreg = DECODE_RM_LONG_REGISTER(rh);
1437 DECODE_PRINTF("\n");
1438 TRACE_AND_STEP();
1439 destval = sbb_long(destval, *srcreg);
1440 store_data_long(destoffset, destval);
1441 } else {
1442 u16 destval;
1443 u16 *srcreg;
1445 destoffset = decode_rm00_address(rl);
1446 DECODE_PRINTF(",");
1447 destval = fetch_data_word(destoffset);
1448 srcreg = DECODE_RM_WORD_REGISTER(rh);
1449 DECODE_PRINTF("\n");
1450 TRACE_AND_STEP();
1451 destval = sbb_word(destval, *srcreg);
1452 store_data_word(destoffset, destval);
1454 break;
1455 case 1:
1456 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1457 u32 destval;
1458 u32 *srcreg;
1460 destoffset = decode_rm01_address(rl);
1461 DECODE_PRINTF(",");
1462 destval = fetch_data_long(destoffset);
1463 srcreg = DECODE_RM_LONG_REGISTER(rh);
1464 DECODE_PRINTF("\n");
1465 TRACE_AND_STEP();
1466 destval = sbb_long(destval, *srcreg);
1467 store_data_long(destoffset, destval);
1468 } else {
1469 u16 destval;
1470 u16 *srcreg;
1472 destoffset = decode_rm01_address(rl);
1473 DECODE_PRINTF(",");
1474 destval = fetch_data_word(destoffset);
1475 srcreg = DECODE_RM_WORD_REGISTER(rh);
1476 DECODE_PRINTF("\n");
1477 TRACE_AND_STEP();
1478 destval = sbb_word(destval, *srcreg);
1479 store_data_word(destoffset, destval);
1481 break;
1482 case 2:
1483 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1484 u32 destval;
1485 u32 *srcreg;
1487 destoffset = decode_rm10_address(rl);
1488 DECODE_PRINTF(",");
1489 destval = fetch_data_long(destoffset);
1490 srcreg = DECODE_RM_LONG_REGISTER(rh);
1491 DECODE_PRINTF("\n");
1492 TRACE_AND_STEP();
1493 destval = sbb_long(destval, *srcreg);
1494 store_data_long(destoffset, destval);
1495 } else {
1496 u16 destval;
1497 u16 *srcreg;
1499 destoffset = decode_rm10_address(rl);
1500 DECODE_PRINTF(",");
1501 destval = fetch_data_word(destoffset);
1502 srcreg = DECODE_RM_WORD_REGISTER(rh);
1503 DECODE_PRINTF("\n");
1504 TRACE_AND_STEP();
1505 destval = sbb_word(destval, *srcreg);
1506 store_data_word(destoffset, destval);
1508 break;
1509 case 3: /* register to register */
1510 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1511 u32 *destreg,*srcreg;
1513 destreg = DECODE_RM_LONG_REGISTER(rl);
1514 DECODE_PRINTF(",");
1515 srcreg = DECODE_RM_LONG_REGISTER(rh);
1516 DECODE_PRINTF("\n");
1517 TRACE_AND_STEP();
1518 *destreg = sbb_long(*destreg, *srcreg);
1519 } else {
1520 u16 *destreg,*srcreg;
1522 destreg = DECODE_RM_WORD_REGISTER(rl);
1523 DECODE_PRINTF(",");
1524 srcreg = DECODE_RM_WORD_REGISTER(rh);
1525 DECODE_PRINTF("\n");
1526 TRACE_AND_STEP();
1527 *destreg = sbb_word(*destreg, *srcreg);
1529 break;
1531 DECODE_CLEAR_SEGOVR();
1532 END_OF_INSTR();
1535 /****************************************************************************
1536 REMARKS:
1537 Handles opcode 0x1a
1538 ****************************************************************************/
1539 void x86emuOp_sbb_byte_R_RM(u8 X86EMU_UNUSED(op1))
1541 int mod, rl, rh;
1542 u8 *destreg, *srcreg;
1543 uint srcoffset;
1544 u8 srcval;
1546 START_OF_INSTR();
1547 DECODE_PRINTF("SBB\t");
1548 FETCH_DECODE_MODRM(mod, rh, rl);
1549 switch (mod) {
1550 case 0:
1551 destreg = DECODE_RM_BYTE_REGISTER(rh);
1552 DECODE_PRINTF(",");
1553 srcoffset = decode_rm00_address(rl);
1554 srcval = fetch_data_byte(srcoffset);
1555 DECODE_PRINTF("\n");
1556 TRACE_AND_STEP();
1557 *destreg = sbb_byte(*destreg, srcval);
1558 break;
1559 case 1:
1560 destreg = DECODE_RM_BYTE_REGISTER(rh);
1561 DECODE_PRINTF(",");
1562 srcoffset = decode_rm01_address(rl);
1563 srcval = fetch_data_byte(srcoffset);
1564 DECODE_PRINTF("\n");
1565 TRACE_AND_STEP();
1566 *destreg = sbb_byte(*destreg, srcval);
1567 break;
1568 case 2:
1569 destreg = DECODE_RM_BYTE_REGISTER(rh);
1570 DECODE_PRINTF(",");
1571 srcoffset = decode_rm10_address(rl);
1572 srcval = fetch_data_byte(srcoffset);
1573 DECODE_PRINTF("\n");
1574 TRACE_AND_STEP();
1575 *destreg = sbb_byte(*destreg, srcval);
1576 break;
1577 case 3: /* register to register */
1578 destreg = DECODE_RM_BYTE_REGISTER(rh);
1579 DECODE_PRINTF(",");
1580 srcreg = DECODE_RM_BYTE_REGISTER(rl);
1581 DECODE_PRINTF("\n");
1582 TRACE_AND_STEP();
1583 *destreg = sbb_byte(*destreg, *srcreg);
1584 break;
1586 DECODE_CLEAR_SEGOVR();
1587 END_OF_INSTR();
1590 /****************************************************************************
1591 REMARKS:
1592 Handles opcode 0x1b
1593 ****************************************************************************/
1594 void x86emuOp_sbb_word_R_RM(u8 X86EMU_UNUSED(op1))
1596 int mod, rl, rh;
1597 uint srcoffset;
1599 START_OF_INSTR();
1600 DECODE_PRINTF("SBB\t");
1601 FETCH_DECODE_MODRM(mod, rh, rl);
1602 switch (mod) {
1603 case 0:
1604 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1605 u32 *destreg;
1606 u32 srcval;
1608 destreg = DECODE_RM_LONG_REGISTER(rh);
1609 DECODE_PRINTF(",");
1610 srcoffset = decode_rm00_address(rl);
1611 srcval = fetch_data_long(srcoffset);
1612 DECODE_PRINTF("\n");
1613 TRACE_AND_STEP();
1614 *destreg = sbb_long(*destreg, srcval);
1615 } else {
1616 u16 *destreg;
1617 u16 srcval;
1619 destreg = DECODE_RM_WORD_REGISTER(rh);
1620 DECODE_PRINTF(",");
1621 srcoffset = decode_rm00_address(rl);
1622 srcval = fetch_data_word(srcoffset);
1623 DECODE_PRINTF("\n");
1624 TRACE_AND_STEP();
1625 *destreg = sbb_word(*destreg, srcval);
1627 break;
1628 case 1:
1629 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1630 u32 *destreg;
1631 u32 srcval;
1633 destreg = DECODE_RM_LONG_REGISTER(rh);
1634 DECODE_PRINTF(",");
1635 srcoffset = decode_rm01_address(rl);
1636 srcval = fetch_data_long(srcoffset);
1637 DECODE_PRINTF("\n");
1638 TRACE_AND_STEP();
1639 *destreg = sbb_long(*destreg, srcval);
1640 } else {
1641 u16 *destreg;
1642 u16 srcval;
1644 destreg = DECODE_RM_WORD_REGISTER(rh);
1645 DECODE_PRINTF(",");
1646 srcoffset = decode_rm01_address(rl);
1647 srcval = fetch_data_word(srcoffset);
1648 DECODE_PRINTF("\n");
1649 TRACE_AND_STEP();
1650 *destreg = sbb_word(*destreg, srcval);
1652 break;
1653 case 2:
1654 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1655 u32 *destreg;
1656 u32 srcval;
1658 destreg = DECODE_RM_LONG_REGISTER(rh);
1659 DECODE_PRINTF(",");
1660 srcoffset = decode_rm10_address(rl);
1661 srcval = fetch_data_long(srcoffset);
1662 DECODE_PRINTF("\n");
1663 TRACE_AND_STEP();
1664 *destreg = sbb_long(*destreg, srcval);
1665 } else {
1666 u16 *destreg;
1667 u16 srcval;
1669 destreg = DECODE_RM_WORD_REGISTER(rh);
1670 DECODE_PRINTF(",");
1671 srcoffset = decode_rm10_address(rl);
1672 srcval = fetch_data_word(srcoffset);
1673 DECODE_PRINTF("\n");
1674 TRACE_AND_STEP();
1675 *destreg = sbb_word(*destreg, srcval);
1677 break;
1678 case 3: /* register to register */
1679 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1680 u32 *destreg,*srcreg;
1682 destreg = DECODE_RM_LONG_REGISTER(rh);
1683 DECODE_PRINTF(",");
1684 srcreg = DECODE_RM_LONG_REGISTER(rl);
1685 DECODE_PRINTF("\n");
1686 TRACE_AND_STEP();
1687 *destreg = sbb_long(*destreg, *srcreg);
1688 } else {
1689 u16 *destreg,*srcreg;
1691 destreg = DECODE_RM_WORD_REGISTER(rh);
1692 DECODE_PRINTF(",");
1693 srcreg = DECODE_RM_WORD_REGISTER(rl);
1694 DECODE_PRINTF("\n");
1695 TRACE_AND_STEP();
1696 *destreg = sbb_word(*destreg, *srcreg);
1698 break;
1700 DECODE_CLEAR_SEGOVR();
1701 END_OF_INSTR();
1704 /****************************************************************************
1705 REMARKS:
1706 Handles opcode 0x1c
1707 ****************************************************************************/
1708 void x86emuOp_sbb_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
1710 u8 srcval;
1712 START_OF_INSTR();
1713 DECODE_PRINTF("SBB\tAL,");
1714 srcval = fetch_byte_imm();
1715 DECODE_PRINTF2("%x\n", srcval);
1716 TRACE_AND_STEP();
1717 M.x86.R_AL = sbb_byte(M.x86.R_AL, srcval);
1718 DECODE_CLEAR_SEGOVR();
1719 END_OF_INSTR();
1722 /****************************************************************************
1723 REMARKS:
1724 Handles opcode 0x1d
1725 ****************************************************************************/
1726 void x86emuOp_sbb_word_AX_IMM(u8 X86EMU_UNUSED(op1))
1728 u32 srcval;
1730 START_OF_INSTR();
1731 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1732 DECODE_PRINTF("SBB\tEAX,");
1733 srcval = fetch_long_imm();
1734 } else {
1735 DECODE_PRINTF("SBB\tAX,");
1736 srcval = fetch_word_imm();
1738 DECODE_PRINTF2("%x\n", srcval);
1739 TRACE_AND_STEP();
1740 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1741 M.x86.R_EAX = sbb_long(M.x86.R_EAX, srcval);
1742 } else {
1743 M.x86.R_AX = sbb_word(M.x86.R_AX, (u16)srcval);
1745 DECODE_CLEAR_SEGOVR();
1746 END_OF_INSTR();
1749 /****************************************************************************
1750 REMARKS:
1751 Handles opcode 0x1e
1752 ****************************************************************************/
1753 void x86emuOp_push_DS(u8 X86EMU_UNUSED(op1))
1755 START_OF_INSTR();
1756 DECODE_PRINTF("PUSH\tDS\n");
1757 TRACE_AND_STEP();
1758 push_word(M.x86.R_DS);
1759 DECODE_CLEAR_SEGOVR();
1760 END_OF_INSTR();
1763 /****************************************************************************
1764 REMARKS:
1765 Handles opcode 0x1f
1766 ****************************************************************************/
1767 void x86emuOp_pop_DS(u8 X86EMU_UNUSED(op1))
1769 START_OF_INSTR();
1770 DECODE_PRINTF("POP\tDS\n");
1771 TRACE_AND_STEP();
1772 M.x86.R_DS = pop_word();
1773 DECODE_CLEAR_SEGOVR();
1774 END_OF_INSTR();
1777 /****************************************************************************
1778 REMARKS:
1779 Handles opcode 0x20
1780 ****************************************************************************/
1781 void x86emuOp_and_byte_RM_R(u8 X86EMU_UNUSED(op1))
1783 int mod, rl, rh;
1784 u8 *destreg, *srcreg;
1785 uint destoffset;
1786 u8 destval;
1788 START_OF_INSTR();
1789 DECODE_PRINTF("AND\t");
1790 FETCH_DECODE_MODRM(mod, rh, rl);
1792 switch (mod) {
1793 case 0:
1794 destoffset = decode_rm00_address(rl);
1795 DECODE_PRINTF(",");
1796 destval = fetch_data_byte(destoffset);
1797 srcreg = DECODE_RM_BYTE_REGISTER(rh);
1798 DECODE_PRINTF("\n");
1799 TRACE_AND_STEP();
1800 destval = and_byte(destval, *srcreg);
1801 store_data_byte(destoffset, destval);
1802 break;
1804 case 1:
1805 destoffset = decode_rm01_address(rl);
1806 DECODE_PRINTF(",");
1807 destval = fetch_data_byte(destoffset);
1808 srcreg = DECODE_RM_BYTE_REGISTER(rh);
1809 DECODE_PRINTF("\n");
1810 TRACE_AND_STEP();
1811 destval = and_byte(destval, *srcreg);
1812 store_data_byte(destoffset, destval);
1813 break;
1815 case 2:
1816 destoffset = decode_rm10_address(rl);
1817 DECODE_PRINTF(",");
1818 destval = fetch_data_byte(destoffset);
1819 srcreg = DECODE_RM_BYTE_REGISTER(rh);
1820 DECODE_PRINTF("\n");
1821 TRACE_AND_STEP();
1822 destval = and_byte(destval, *srcreg);
1823 store_data_byte(destoffset, destval);
1824 break;
1826 case 3: /* register to register */
1827 destreg = DECODE_RM_BYTE_REGISTER(rl);
1828 DECODE_PRINTF(",");
1829 srcreg = DECODE_RM_BYTE_REGISTER(rh);
1830 DECODE_PRINTF("\n");
1831 TRACE_AND_STEP();
1832 *destreg = and_byte(*destreg, *srcreg);
1833 break;
1835 DECODE_CLEAR_SEGOVR();
1836 END_OF_INSTR();
1839 /****************************************************************************
1840 REMARKS:
1841 Handles opcode 0x21
1842 ****************************************************************************/
1843 void x86emuOp_and_word_RM_R(u8 X86EMU_UNUSED(op1))
1845 int mod, rl, rh;
1846 uint destoffset;
1848 START_OF_INSTR();
1849 DECODE_PRINTF("AND\t");
1850 FETCH_DECODE_MODRM(mod, rh, rl);
1851 switch (mod) {
1852 case 0:
1853 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1854 u32 destval;
1855 u32 *srcreg;
1857 destoffset = decode_rm00_address(rl);
1858 DECODE_PRINTF(",");
1859 destval = fetch_data_long(destoffset);
1860 srcreg = DECODE_RM_LONG_REGISTER(rh);
1861 DECODE_PRINTF("\n");
1862 TRACE_AND_STEP();
1863 destval = and_long(destval, *srcreg);
1864 store_data_long(destoffset, destval);
1865 } else {
1866 u16 destval;
1867 u16 *srcreg;
1869 destoffset = decode_rm00_address(rl);
1870 DECODE_PRINTF(",");
1871 destval = fetch_data_word(destoffset);
1872 srcreg = DECODE_RM_WORD_REGISTER(rh);
1873 DECODE_PRINTF("\n");
1874 TRACE_AND_STEP();
1875 destval = and_word(destval, *srcreg);
1876 store_data_word(destoffset, destval);
1878 break;
1879 case 1:
1880 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1881 u32 destval;
1882 u32 *srcreg;
1884 destoffset = decode_rm01_address(rl);
1885 DECODE_PRINTF(",");
1886 destval = fetch_data_long(destoffset);
1887 srcreg = DECODE_RM_LONG_REGISTER(rh);
1888 DECODE_PRINTF("\n");
1889 TRACE_AND_STEP();
1890 destval = and_long(destval, *srcreg);
1891 store_data_long(destoffset, destval);
1892 } else {
1893 u16 destval;
1894 u16 *srcreg;
1896 destoffset = decode_rm01_address(rl);
1897 DECODE_PRINTF(",");
1898 destval = fetch_data_word(destoffset);
1899 srcreg = DECODE_RM_WORD_REGISTER(rh);
1900 DECODE_PRINTF("\n");
1901 TRACE_AND_STEP();
1902 destval = and_word(destval, *srcreg);
1903 store_data_word(destoffset, destval);
1905 break;
1906 case 2:
1907 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1908 u32 destval;
1909 u32 *srcreg;
1911 destoffset = decode_rm10_address(rl);
1912 DECODE_PRINTF(",");
1913 destval = fetch_data_long(destoffset);
1914 srcreg = DECODE_RM_LONG_REGISTER(rh);
1915 DECODE_PRINTF("\n");
1916 TRACE_AND_STEP();
1917 destval = and_long(destval, *srcreg);
1918 store_data_long(destoffset, destval);
1919 } else {
1920 u16 destval;
1921 u16 *srcreg;
1923 destoffset = decode_rm10_address(rl);
1924 DECODE_PRINTF(",");
1925 destval = fetch_data_word(destoffset);
1926 srcreg = DECODE_RM_WORD_REGISTER(rh);
1927 DECODE_PRINTF("\n");
1928 TRACE_AND_STEP();
1929 destval = and_word(destval, *srcreg);
1930 store_data_word(destoffset, destval);
1932 break;
1933 case 3: /* register to register */
1934 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1935 u32 *destreg,*srcreg;
1937 destreg = DECODE_RM_LONG_REGISTER(rl);
1938 DECODE_PRINTF(",");
1939 srcreg = DECODE_RM_LONG_REGISTER(rh);
1940 DECODE_PRINTF("\n");
1941 TRACE_AND_STEP();
1942 *destreg = and_long(*destreg, *srcreg);
1943 } else {
1944 u16 *destreg,*srcreg;
1946 destreg = DECODE_RM_WORD_REGISTER(rl);
1947 DECODE_PRINTF(",");
1948 srcreg = DECODE_RM_WORD_REGISTER(rh);
1949 DECODE_PRINTF("\n");
1950 TRACE_AND_STEP();
1951 *destreg = and_word(*destreg, *srcreg);
1953 break;
1955 DECODE_CLEAR_SEGOVR();
1956 END_OF_INSTR();
1959 /****************************************************************************
1960 REMARKS:
1961 Handles opcode 0x22
1962 ****************************************************************************/
1963 void x86emuOp_and_byte_R_RM(u8 X86EMU_UNUSED(op1))
1965 int mod, rl, rh;
1966 u8 *destreg, *srcreg;
1967 uint srcoffset;
1968 u8 srcval;
1970 START_OF_INSTR();
1971 DECODE_PRINTF("AND\t");
1972 FETCH_DECODE_MODRM(mod, rh, rl);
1973 switch (mod) {
1974 case 0:
1975 destreg = DECODE_RM_BYTE_REGISTER(rh);
1976 DECODE_PRINTF(",");
1977 srcoffset = decode_rm00_address(rl);
1978 srcval = fetch_data_byte(srcoffset);
1979 DECODE_PRINTF("\n");
1980 TRACE_AND_STEP();
1981 *destreg = and_byte(*destreg, srcval);
1982 break;
1983 case 1:
1984 destreg = DECODE_RM_BYTE_REGISTER(rh);
1985 DECODE_PRINTF(",");
1986 srcoffset = decode_rm01_address(rl);
1987 srcval = fetch_data_byte(srcoffset);
1988 DECODE_PRINTF("\n");
1989 TRACE_AND_STEP();
1990 *destreg = and_byte(*destreg, srcval);
1991 break;
1992 case 2:
1993 destreg = DECODE_RM_BYTE_REGISTER(rh);
1994 DECODE_PRINTF(",");
1995 srcoffset = decode_rm10_address(rl);
1996 srcval = fetch_data_byte(srcoffset);
1997 DECODE_PRINTF("\n");
1998 TRACE_AND_STEP();
1999 *destreg = and_byte(*destreg, srcval);
2000 break;
2001 case 3: /* register to register */
2002 destreg = DECODE_RM_BYTE_REGISTER(rh);
2003 DECODE_PRINTF(",");
2004 srcreg = DECODE_RM_BYTE_REGISTER(rl);
2005 DECODE_PRINTF("\n");
2006 TRACE_AND_STEP();
2007 *destreg = and_byte(*destreg, *srcreg);
2008 break;
2010 DECODE_CLEAR_SEGOVR();
2011 END_OF_INSTR();
2014 /****************************************************************************
2015 REMARKS:
2016 Handles opcode 0x23
2017 ****************************************************************************/
2018 void x86emuOp_and_word_R_RM(u8 X86EMU_UNUSED(op1))
2020 int mod, rl, rh;
2021 uint srcoffset;
2023 START_OF_INSTR();
2024 DECODE_PRINTF("AND\t");
2025 FETCH_DECODE_MODRM(mod, rh, rl);
2026 switch (mod) {
2027 case 0:
2028 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2029 u32 *destreg;
2030 u32 srcval;
2032 destreg = DECODE_RM_LONG_REGISTER(rh);
2033 DECODE_PRINTF(",");
2034 srcoffset = decode_rm00_address(rl);
2035 srcval = fetch_data_long(srcoffset);
2036 DECODE_PRINTF("\n");
2037 TRACE_AND_STEP();
2038 *destreg = and_long(*destreg, srcval);
2039 } else {
2040 u16 *destreg;
2041 u16 srcval;
2043 destreg = DECODE_RM_WORD_REGISTER(rh);
2044 DECODE_PRINTF(",");
2045 srcoffset = decode_rm00_address(rl);
2046 srcval = fetch_data_word(srcoffset);
2047 DECODE_PRINTF("\n");
2048 TRACE_AND_STEP();
2049 *destreg = and_word(*destreg, srcval);
2051 break;
2052 case 1:
2053 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2054 u32 *destreg;
2055 u32 srcval;
2057 destreg = DECODE_RM_LONG_REGISTER(rh);
2058 DECODE_PRINTF(",");
2059 srcoffset = decode_rm01_address(rl);
2060 srcval = fetch_data_long(srcoffset);
2061 DECODE_PRINTF("\n");
2062 TRACE_AND_STEP();
2063 *destreg = and_long(*destreg, srcval);
2064 break;
2065 } else {
2066 u16 *destreg;
2067 u16 srcval;
2069 destreg = DECODE_RM_WORD_REGISTER(rh);
2070 DECODE_PRINTF(",");
2071 srcoffset = decode_rm01_address(rl);
2072 srcval = fetch_data_word(srcoffset);
2073 DECODE_PRINTF("\n");
2074 TRACE_AND_STEP();
2075 *destreg = and_word(*destreg, srcval);
2076 break;
2078 case 2:
2079 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2080 u32 *destreg;
2081 u32 srcval;
2083 destreg = DECODE_RM_LONG_REGISTER(rh);
2084 DECODE_PRINTF(",");
2085 srcoffset = decode_rm10_address(rl);
2086 srcval = fetch_data_long(srcoffset);
2087 DECODE_PRINTF("\n");
2088 TRACE_AND_STEP();
2089 *destreg = and_long(*destreg, srcval);
2090 } else {
2091 u16 *destreg;
2092 u16 srcval;
2094 destreg = DECODE_RM_WORD_REGISTER(rh);
2095 DECODE_PRINTF(",");
2096 srcoffset = decode_rm10_address(rl);
2097 srcval = fetch_data_word(srcoffset);
2098 DECODE_PRINTF("\n");
2099 TRACE_AND_STEP();
2100 *destreg = and_word(*destreg, srcval);
2102 break;
2103 case 3: /* register to register */
2104 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2105 u32 *destreg,*srcreg;
2107 destreg = DECODE_RM_LONG_REGISTER(rh);
2108 DECODE_PRINTF(",");
2109 srcreg = DECODE_RM_LONG_REGISTER(rl);
2110 DECODE_PRINTF("\n");
2111 TRACE_AND_STEP();
2112 *destreg = and_long(*destreg, *srcreg);
2113 } else {
2114 u16 *destreg,*srcreg;
2116 destreg = DECODE_RM_WORD_REGISTER(rh);
2117 DECODE_PRINTF(",");
2118 srcreg = DECODE_RM_WORD_REGISTER(rl);
2119 DECODE_PRINTF("\n");
2120 TRACE_AND_STEP();
2121 *destreg = and_word(*destreg, *srcreg);
2123 break;
2125 DECODE_CLEAR_SEGOVR();
2126 END_OF_INSTR();
2129 /****************************************************************************
2130 REMARKS:
2131 Handles opcode 0x24
2132 ****************************************************************************/
2133 void x86emuOp_and_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
2135 u8 srcval;
2137 START_OF_INSTR();
2138 DECODE_PRINTF("AND\tAL,");
2139 srcval = fetch_byte_imm();
2140 DECODE_PRINTF2("%x\n", srcval);
2141 TRACE_AND_STEP();
2142 M.x86.R_AL = and_byte(M.x86.R_AL, srcval);
2143 DECODE_CLEAR_SEGOVR();
2144 END_OF_INSTR();
2147 /****************************************************************************
2148 REMARKS:
2149 Handles opcode 0x25
2150 ****************************************************************************/
2151 void x86emuOp_and_word_AX_IMM(u8 X86EMU_UNUSED(op1))
2153 u32 srcval;
2155 START_OF_INSTR();
2156 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2157 DECODE_PRINTF("AND\tEAX,");
2158 srcval = fetch_long_imm();
2159 } else {
2160 DECODE_PRINTF("AND\tAX,");
2161 srcval = fetch_word_imm();
2163 DECODE_PRINTF2("%x\n", srcval);
2164 TRACE_AND_STEP();
2165 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2166 M.x86.R_EAX = and_long(M.x86.R_EAX, srcval);
2167 } else {
2168 M.x86.R_AX = and_word(M.x86.R_AX, (u16)srcval);
2170 DECODE_CLEAR_SEGOVR();
2171 END_OF_INSTR();
2174 /****************************************************************************
2175 REMARKS:
2176 Handles opcode 0x26
2177 ****************************************************************************/
2178 void x86emuOp_segovr_ES(u8 X86EMU_UNUSED(op1))
2180 START_OF_INSTR();
2181 DECODE_PRINTF("ES:\n");
2182 TRACE_AND_STEP();
2183 M.x86.mode |= SYSMODE_SEGOVR_ES;
2185 * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
2186 * opcode subroutines we do not want to do this.
2188 END_OF_INSTR();
2191 /****************************************************************************
2192 REMARKS:
2193 Handles opcode 0x27
2194 ****************************************************************************/
2195 void x86emuOp_daa(u8 X86EMU_UNUSED(op1))
2197 START_OF_INSTR();
2198 DECODE_PRINTF("DAA\n");
2199 TRACE_AND_STEP();
2200 M.x86.R_AL = daa_byte(M.x86.R_AL);
2201 DECODE_CLEAR_SEGOVR();
2202 END_OF_INSTR();
2205 /****************************************************************************
2206 REMARKS:
2207 Handles opcode 0x28
2208 ****************************************************************************/
2209 void x86emuOp_sub_byte_RM_R(u8 X86EMU_UNUSED(op1))
2211 int mod, rl, rh;
2212 u8 *destreg, *srcreg;
2213 uint destoffset;
2214 u8 destval;
2216 START_OF_INSTR();
2217 DECODE_PRINTF("SUB\t");
2218 FETCH_DECODE_MODRM(mod, rh, rl);
2219 switch (mod) {
2220 case 0:
2221 destoffset = decode_rm00_address(rl);
2222 DECODE_PRINTF(",");
2223 destval = fetch_data_byte(destoffset);
2224 srcreg = DECODE_RM_BYTE_REGISTER(rh);
2225 DECODE_PRINTF("\n");
2226 TRACE_AND_STEP();
2227 destval = sub_byte(destval, *srcreg);
2228 store_data_byte(destoffset, destval);
2229 break;
2230 case 1:
2231 destoffset = decode_rm01_address(rl);
2232 DECODE_PRINTF(",");
2233 destval = fetch_data_byte(destoffset);
2234 srcreg = DECODE_RM_BYTE_REGISTER(rh);
2235 DECODE_PRINTF("\n");
2236 TRACE_AND_STEP();
2237 destval = sub_byte(destval, *srcreg);
2238 store_data_byte(destoffset, destval);
2239 break;
2240 case 2:
2241 destoffset = decode_rm10_address(rl);
2242 DECODE_PRINTF(",");
2243 destval = fetch_data_byte(destoffset);
2244 srcreg = DECODE_RM_BYTE_REGISTER(rh);
2245 DECODE_PRINTF("\n");
2246 TRACE_AND_STEP();
2247 destval = sub_byte(destval, *srcreg);
2248 store_data_byte(destoffset, destval);
2249 break;
2250 case 3: /* register to register */
2251 destreg = DECODE_RM_BYTE_REGISTER(rl);
2252 DECODE_PRINTF(",");
2253 srcreg = DECODE_RM_BYTE_REGISTER(rh);
2254 DECODE_PRINTF("\n");
2255 TRACE_AND_STEP();
2256 *destreg = sub_byte(*destreg, *srcreg);
2257 break;
2259 DECODE_CLEAR_SEGOVR();
2260 END_OF_INSTR();
2263 /****************************************************************************
2264 REMARKS:
2265 Handles opcode 0x29
2266 ****************************************************************************/
2267 void x86emuOp_sub_word_RM_R(u8 X86EMU_UNUSED(op1))
2269 int mod, rl, rh;
2270 uint destoffset;
2272 START_OF_INSTR();
2273 DECODE_PRINTF("SUB\t");
2274 FETCH_DECODE_MODRM(mod, rh, rl);
2275 switch (mod) {
2276 case 0:
2277 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2278 u32 destval;
2279 u32 *srcreg;
2281 destoffset = decode_rm00_address(rl);
2282 DECODE_PRINTF(",");
2283 destval = fetch_data_long(destoffset);
2284 srcreg = DECODE_RM_LONG_REGISTER(rh);
2285 DECODE_PRINTF("\n");
2286 TRACE_AND_STEP();
2287 destval = sub_long(destval, *srcreg);
2288 store_data_long(destoffset, destval);
2289 } else {
2290 u16 destval;
2291 u16 *srcreg;
2293 destoffset = decode_rm00_address(rl);
2294 DECODE_PRINTF(",");
2295 destval = fetch_data_word(destoffset);
2296 srcreg = DECODE_RM_WORD_REGISTER(rh);
2297 DECODE_PRINTF("\n");
2298 TRACE_AND_STEP();
2299 destval = sub_word(destval, *srcreg);
2300 store_data_word(destoffset, destval);
2302 break;
2303 case 1:
2304 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2305 u32 destval;
2306 u32 *srcreg;
2308 destoffset = decode_rm01_address(rl);
2309 DECODE_PRINTF(",");
2310 destval = fetch_data_long(destoffset);
2311 srcreg = DECODE_RM_LONG_REGISTER(rh);
2312 DECODE_PRINTF("\n");
2313 TRACE_AND_STEP();
2314 destval = sub_long(destval, *srcreg);
2315 store_data_long(destoffset, destval);
2316 } else {
2317 u16 destval;
2318 u16 *srcreg;
2320 destoffset = decode_rm01_address(rl);
2321 DECODE_PRINTF(",");
2322 destval = fetch_data_word(destoffset);
2323 srcreg = DECODE_RM_WORD_REGISTER(rh);
2324 DECODE_PRINTF("\n");
2325 TRACE_AND_STEP();
2326 destval = sub_word(destval, *srcreg);
2327 store_data_word(destoffset, destval);
2329 break;
2330 case 2:
2331 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2332 u32 destval;
2333 u32 *srcreg;
2335 destoffset = decode_rm10_address(rl);
2336 DECODE_PRINTF(",");
2337 destval = fetch_data_long(destoffset);
2338 srcreg = DECODE_RM_LONG_REGISTER(rh);
2339 DECODE_PRINTF("\n");
2340 TRACE_AND_STEP();
2341 destval = sub_long(destval, *srcreg);
2342 store_data_long(destoffset, destval);
2343 } else {
2344 u16 destval;
2345 u16 *srcreg;
2347 destoffset = decode_rm10_address(rl);
2348 DECODE_PRINTF(",");
2349 destval = fetch_data_word(destoffset);
2350 srcreg = DECODE_RM_WORD_REGISTER(rh);
2351 DECODE_PRINTF("\n");
2352 TRACE_AND_STEP();
2353 destval = sub_word(destval, *srcreg);
2354 store_data_word(destoffset, destval);
2356 break;
2357 case 3: /* register to register */
2358 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2359 u32 *destreg,*srcreg;
2361 destreg = DECODE_RM_LONG_REGISTER(rl);
2362 DECODE_PRINTF(",");
2363 srcreg = DECODE_RM_LONG_REGISTER(rh);
2364 DECODE_PRINTF("\n");
2365 TRACE_AND_STEP();
2366 *destreg = sub_long(*destreg, *srcreg);
2367 } else {
2368 u16 *destreg,*srcreg;
2370 destreg = DECODE_RM_WORD_REGISTER(rl);
2371 DECODE_PRINTF(",");
2372 srcreg = DECODE_RM_WORD_REGISTER(rh);
2373 DECODE_PRINTF("\n");
2374 TRACE_AND_STEP();
2375 *destreg = sub_word(*destreg, *srcreg);
2377 break;
2379 DECODE_CLEAR_SEGOVR();
2380 END_OF_INSTR();
2383 /****************************************************************************
2384 REMARKS:
2385 Handles opcode 0x2a
2386 ****************************************************************************/
2387 void x86emuOp_sub_byte_R_RM(u8 X86EMU_UNUSED(op1))
2389 int mod, rl, rh;
2390 u8 *destreg, *srcreg;
2391 uint srcoffset;
2392 u8 srcval;
2394 START_OF_INSTR();
2395 DECODE_PRINTF("SUB\t");
2396 FETCH_DECODE_MODRM(mod, rh, rl);
2397 switch (mod) {
2398 case 0:
2399 destreg = DECODE_RM_BYTE_REGISTER(rh);
2400 DECODE_PRINTF(",");
2401 srcoffset = decode_rm00_address(rl);
2402 srcval = fetch_data_byte(srcoffset);
2403 DECODE_PRINTF("\n");
2404 TRACE_AND_STEP();
2405 *destreg = sub_byte(*destreg, srcval);
2406 break;
2407 case 1:
2408 destreg = DECODE_RM_BYTE_REGISTER(rh);
2409 DECODE_PRINTF(",");
2410 srcoffset = decode_rm01_address(rl);
2411 srcval = fetch_data_byte(srcoffset);
2412 DECODE_PRINTF("\n");
2413 TRACE_AND_STEP();
2414 *destreg = sub_byte(*destreg, srcval);
2415 break;
2416 case 2:
2417 destreg = DECODE_RM_BYTE_REGISTER(rh);
2418 DECODE_PRINTF(",");
2419 srcoffset = decode_rm10_address(rl);
2420 srcval = fetch_data_byte(srcoffset);
2421 DECODE_PRINTF("\n");
2422 TRACE_AND_STEP();
2423 *destreg = sub_byte(*destreg, srcval);
2424 break;
2425 case 3: /* register to register */
2426 destreg = DECODE_RM_BYTE_REGISTER(rh);
2427 DECODE_PRINTF(",");
2428 srcreg = DECODE_RM_BYTE_REGISTER(rl);
2429 DECODE_PRINTF("\n");
2430 TRACE_AND_STEP();
2431 *destreg = sub_byte(*destreg, *srcreg);
2432 break;
2434 DECODE_CLEAR_SEGOVR();
2435 END_OF_INSTR();
2438 /****************************************************************************
2439 REMARKS:
2440 Handles opcode 0x2b
2441 ****************************************************************************/
2442 void x86emuOp_sub_word_R_RM(u8 X86EMU_UNUSED(op1))
2444 int mod, rl, rh;
2445 uint srcoffset;
2447 START_OF_INSTR();
2448 DECODE_PRINTF("SUB\t");
2449 FETCH_DECODE_MODRM(mod, rh, rl);
2450 switch (mod) {
2451 case 0:
2452 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2453 u32 *destreg;
2454 u32 srcval;
2456 destreg = DECODE_RM_LONG_REGISTER(rh);
2457 DECODE_PRINTF(",");
2458 srcoffset = decode_rm00_address(rl);
2459 srcval = fetch_data_long(srcoffset);
2460 DECODE_PRINTF("\n");
2461 TRACE_AND_STEP();
2462 *destreg = sub_long(*destreg, srcval);
2463 } else {
2464 u16 *destreg;
2465 u16 srcval;
2467 destreg = DECODE_RM_WORD_REGISTER(rh);
2468 DECODE_PRINTF(",");
2469 srcoffset = decode_rm00_address(rl);
2470 srcval = fetch_data_word(srcoffset);
2471 DECODE_PRINTF("\n");
2472 TRACE_AND_STEP();
2473 *destreg = sub_word(*destreg, srcval);
2475 break;
2476 case 1:
2477 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2478 u32 *destreg;
2479 u32 srcval;
2481 destreg = DECODE_RM_LONG_REGISTER(rh);
2482 DECODE_PRINTF(",");
2483 srcoffset = decode_rm01_address(rl);
2484 srcval = fetch_data_long(srcoffset);
2485 DECODE_PRINTF("\n");
2486 TRACE_AND_STEP();
2487 *destreg = sub_long(*destreg, srcval);
2488 } else {
2489 u16 *destreg;
2490 u16 srcval;
2492 destreg = DECODE_RM_WORD_REGISTER(rh);
2493 DECODE_PRINTF(",");
2494 srcoffset = decode_rm01_address(rl);
2495 srcval = fetch_data_word(srcoffset);
2496 DECODE_PRINTF("\n");
2497 TRACE_AND_STEP();
2498 *destreg = sub_word(*destreg, srcval);
2500 break;
2501 case 2:
2502 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2503 u32 *destreg;
2504 u32 srcval;
2506 destreg = DECODE_RM_LONG_REGISTER(rh);
2507 DECODE_PRINTF(",");
2508 srcoffset = decode_rm10_address(rl);
2509 srcval = fetch_data_long(srcoffset);
2510 DECODE_PRINTF("\n");
2511 TRACE_AND_STEP();
2512 *destreg = sub_long(*destreg, srcval);
2513 } else {
2514 u16 *destreg;
2515 u16 srcval;
2517 destreg = DECODE_RM_WORD_REGISTER(rh);
2518 DECODE_PRINTF(",");
2519 srcoffset = decode_rm10_address(rl);
2520 srcval = fetch_data_word(srcoffset);
2521 DECODE_PRINTF("\n");
2522 TRACE_AND_STEP();
2523 *destreg = sub_word(*destreg, srcval);
2525 break;
2526 case 3: /* register to register */
2527 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2528 u32 *destreg,*srcreg;
2530 destreg = DECODE_RM_LONG_REGISTER(rh);
2531 DECODE_PRINTF(",");
2532 srcreg = DECODE_RM_LONG_REGISTER(rl);
2533 DECODE_PRINTF("\n");
2534 TRACE_AND_STEP();
2535 *destreg = sub_long(*destreg, *srcreg);
2536 } else {
2537 u16 *destreg,*srcreg;
2539 destreg = DECODE_RM_WORD_REGISTER(rh);
2540 DECODE_PRINTF(",");
2541 srcreg = DECODE_RM_WORD_REGISTER(rl);
2542 DECODE_PRINTF("\n");
2543 TRACE_AND_STEP();
2544 *destreg = sub_word(*destreg, *srcreg);
2546 break;
2548 DECODE_CLEAR_SEGOVR();
2549 END_OF_INSTR();
2552 /****************************************************************************
2553 REMARKS:
2554 Handles opcode 0x2c
2555 ****************************************************************************/
2556 void x86emuOp_sub_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
2558 u8 srcval;
2560 START_OF_INSTR();
2561 DECODE_PRINTF("SUB\tAL,");
2562 srcval = fetch_byte_imm();
2563 DECODE_PRINTF2("%x\n", srcval);
2564 TRACE_AND_STEP();
2565 M.x86.R_AL = sub_byte(M.x86.R_AL, srcval);
2566 DECODE_CLEAR_SEGOVR();
2567 END_OF_INSTR();
2570 /****************************************************************************
2571 REMARKS:
2572 Handles opcode 0x2d
2573 ****************************************************************************/
2574 void x86emuOp_sub_word_AX_IMM(u8 X86EMU_UNUSED(op1))
2576 u32 srcval;
2578 START_OF_INSTR();
2579 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2580 DECODE_PRINTF("SUB\tEAX,");
2581 srcval = fetch_long_imm();
2582 } else {
2583 DECODE_PRINTF("SUB\tAX,");
2584 srcval = fetch_word_imm();
2586 DECODE_PRINTF2("%x\n", srcval);
2587 TRACE_AND_STEP();
2588 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2589 M.x86.R_EAX = sub_long(M.x86.R_EAX, srcval);
2590 } else {
2591 M.x86.R_AX = sub_word(M.x86.R_AX, (u16)srcval);
2593 DECODE_CLEAR_SEGOVR();
2594 END_OF_INSTR();
2597 /****************************************************************************
2598 REMARKS:
2599 Handles opcode 0x2e
2600 ****************************************************************************/
2601 void x86emuOp_segovr_CS(u8 X86EMU_UNUSED(op1))
2603 START_OF_INSTR();
2604 DECODE_PRINTF("CS:\n");
2605 TRACE_AND_STEP();
2606 M.x86.mode |= SYSMODE_SEGOVR_CS;
2607 /* note no DECODE_CLEAR_SEGOVR here. */
2608 END_OF_INSTR();
2611 /****************************************************************************
2612 REMARKS:
2613 Handles opcode 0x2f
2614 ****************************************************************************/
2615 void x86emuOp_das(u8 X86EMU_UNUSED(op1))
2617 START_OF_INSTR();
2618 DECODE_PRINTF("DAS\n");
2619 TRACE_AND_STEP();
2620 M.x86.R_AL = das_byte(M.x86.R_AL);
2621 DECODE_CLEAR_SEGOVR();
2622 END_OF_INSTR();
2625 /****************************************************************************
2626 REMARKS:
2627 Handles opcode 0x30
2628 ****************************************************************************/
2629 void x86emuOp_xor_byte_RM_R(u8 X86EMU_UNUSED(op1))
2631 int mod, rl, rh;
2632 u8 *destreg, *srcreg;
2633 uint destoffset;
2634 u8 destval;
2636 START_OF_INSTR();
2637 DECODE_PRINTF("XOR\t");
2638 FETCH_DECODE_MODRM(mod, rh, rl);
2639 switch (mod) {
2640 case 0:
2641 destoffset = decode_rm00_address(rl);
2642 DECODE_PRINTF(",");
2643 destval = fetch_data_byte(destoffset);
2644 srcreg = DECODE_RM_BYTE_REGISTER(rh);
2645 DECODE_PRINTF("\n");
2646 TRACE_AND_STEP();
2647 destval = xor_byte(destval, *srcreg);
2648 store_data_byte(destoffset, destval);
2649 break;
2650 case 1:
2651 destoffset = decode_rm01_address(rl);
2652 DECODE_PRINTF(",");
2653 destval = fetch_data_byte(destoffset);
2654 srcreg = DECODE_RM_BYTE_REGISTER(rh);
2655 DECODE_PRINTF("\n");
2656 TRACE_AND_STEP();
2657 destval = xor_byte(destval, *srcreg);
2658 store_data_byte(destoffset, destval);
2659 break;
2660 case 2:
2661 destoffset = decode_rm10_address(rl);
2662 DECODE_PRINTF(",");
2663 destval = fetch_data_byte(destoffset);
2664 srcreg = DECODE_RM_BYTE_REGISTER(rh);
2665 DECODE_PRINTF("\n");
2666 TRACE_AND_STEP();
2667 destval = xor_byte(destval, *srcreg);
2668 store_data_byte(destoffset, destval);
2669 break;
2670 case 3: /* register to register */
2671 destreg = DECODE_RM_BYTE_REGISTER(rl);
2672 DECODE_PRINTF(",");
2673 srcreg = DECODE_RM_BYTE_REGISTER(rh);
2674 DECODE_PRINTF("\n");
2675 TRACE_AND_STEP();
2676 *destreg = xor_byte(*destreg, *srcreg);
2677 break;
2679 DECODE_CLEAR_SEGOVR();
2680 END_OF_INSTR();
2683 /****************************************************************************
2684 REMARKS:
2685 Handles opcode 0x31
2686 ****************************************************************************/
2687 void x86emuOp_xor_word_RM_R(u8 X86EMU_UNUSED(op1))
2689 int mod, rl, rh;
2690 uint destoffset;
2692 START_OF_INSTR();
2693 DECODE_PRINTF("XOR\t");
2694 FETCH_DECODE_MODRM(mod, rh, rl);
2695 switch (mod) {
2696 case 0:
2697 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2698 u32 destval;
2699 u32 *srcreg;
2701 destoffset = decode_rm00_address(rl);
2702 DECODE_PRINTF(",");
2703 destval = fetch_data_long(destoffset);
2704 srcreg = DECODE_RM_LONG_REGISTER(rh);
2705 DECODE_PRINTF("\n");
2706 TRACE_AND_STEP();
2707 destval = xor_long(destval, *srcreg);
2708 store_data_long(destoffset, destval);
2709 } else {
2710 u16 destval;
2711 u16 *srcreg;
2713 destoffset = decode_rm00_address(rl);
2714 DECODE_PRINTF(",");
2715 destval = fetch_data_word(destoffset);
2716 srcreg = DECODE_RM_WORD_REGISTER(rh);
2717 DECODE_PRINTF("\n");
2718 TRACE_AND_STEP();
2719 destval = xor_word(destval, *srcreg);
2720 store_data_word(destoffset, destval);
2722 break;
2723 case 1:
2724 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2725 u32 destval;
2726 u32 *srcreg;
2728 destoffset = decode_rm01_address(rl);
2729 DECODE_PRINTF(",");
2730 destval = fetch_data_long(destoffset);
2731 srcreg = DECODE_RM_LONG_REGISTER(rh);
2732 DECODE_PRINTF("\n");
2733 TRACE_AND_STEP();
2734 destval = xor_long(destval, *srcreg);
2735 store_data_long(destoffset, destval);
2736 } else {
2737 u16 destval;
2738 u16 *srcreg;
2740 destoffset = decode_rm01_address(rl);
2741 DECODE_PRINTF(",");
2742 destval = fetch_data_word(destoffset);
2743 srcreg = DECODE_RM_WORD_REGISTER(rh);
2744 DECODE_PRINTF("\n");
2745 TRACE_AND_STEP();
2746 destval = xor_word(destval, *srcreg);
2747 store_data_word(destoffset, destval);
2749 break;
2750 case 2:
2751 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2752 u32 destval;
2753 u32 *srcreg;
2755 destoffset = decode_rm10_address(rl);
2756 DECODE_PRINTF(",");
2757 destval = fetch_data_long(destoffset);
2758 srcreg = DECODE_RM_LONG_REGISTER(rh);
2759 DECODE_PRINTF("\n");
2760 TRACE_AND_STEP();
2761 destval = xor_long(destval, *srcreg);
2762 store_data_long(destoffset, destval);
2763 } else {
2764 u16 destval;
2765 u16 *srcreg;
2767 destoffset = decode_rm10_address(rl);
2768 DECODE_PRINTF(",");
2769 destval = fetch_data_word(destoffset);
2770 srcreg = DECODE_RM_WORD_REGISTER(rh);
2771 DECODE_PRINTF("\n");
2772 TRACE_AND_STEP();
2773 destval = xor_word(destval, *srcreg);
2774 store_data_word(destoffset, destval);
2776 break;
2777 case 3: /* register to register */
2778 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2779 u32 *destreg,*srcreg;
2781 destreg = DECODE_RM_LONG_REGISTER(rl);
2782 DECODE_PRINTF(",");
2783 srcreg = DECODE_RM_LONG_REGISTER(rh);
2784 DECODE_PRINTF("\n");
2785 TRACE_AND_STEP();
2786 *destreg = xor_long(*destreg, *srcreg);
2787 } else {
2788 u16 *destreg,*srcreg;
2790 destreg = DECODE_RM_WORD_REGISTER(rl);
2791 DECODE_PRINTF(",");
2792 srcreg = DECODE_RM_WORD_REGISTER(rh);
2793 DECODE_PRINTF("\n");
2794 TRACE_AND_STEP();
2795 *destreg = xor_word(*destreg, *srcreg);
2797 break;
2799 DECODE_CLEAR_SEGOVR();
2800 END_OF_INSTR();
2803 /****************************************************************************
2804 REMARKS:
2805 Handles opcode 0x32
2806 ****************************************************************************/
2807 void x86emuOp_xor_byte_R_RM(u8 X86EMU_UNUSED(op1))
2809 int mod, rl, rh;
2810 u8 *destreg, *srcreg;
2811 uint srcoffset;
2812 u8 srcval;
2814 START_OF_INSTR();
2815 DECODE_PRINTF("XOR\t");
2816 FETCH_DECODE_MODRM(mod, rh, rl);
2817 switch (mod) {
2818 case 0:
2819 destreg = DECODE_RM_BYTE_REGISTER(rh);
2820 DECODE_PRINTF(",");
2821 srcoffset = decode_rm00_address(rl);
2822 srcval = fetch_data_byte(srcoffset);
2823 DECODE_PRINTF("\n");
2824 TRACE_AND_STEP();
2825 *destreg = xor_byte(*destreg, srcval);
2826 break;
2827 case 1:
2828 destreg = DECODE_RM_BYTE_REGISTER(rh);
2829 DECODE_PRINTF(",");
2830 srcoffset = decode_rm01_address(rl);
2831 srcval = fetch_data_byte(srcoffset);
2832 DECODE_PRINTF("\n");
2833 TRACE_AND_STEP();
2834 *destreg = xor_byte(*destreg, srcval);
2835 break;
2836 case 2:
2837 destreg = DECODE_RM_BYTE_REGISTER(rh);
2838 DECODE_PRINTF(",");
2839 srcoffset = decode_rm10_address(rl);
2840 srcval = fetch_data_byte(srcoffset);
2841 DECODE_PRINTF("\n");
2842 TRACE_AND_STEP();
2843 *destreg = xor_byte(*destreg, srcval);
2844 break;
2845 case 3: /* register to register */
2846 destreg = DECODE_RM_BYTE_REGISTER(rh);
2847 DECODE_PRINTF(",");
2848 srcreg = DECODE_RM_BYTE_REGISTER(rl);
2849 DECODE_PRINTF("\n");
2850 TRACE_AND_STEP();
2851 *destreg = xor_byte(*destreg, *srcreg);
2852 break;
2854 DECODE_CLEAR_SEGOVR();
2855 END_OF_INSTR();
2858 /****************************************************************************
2859 REMARKS:
2860 Handles opcode 0x33
2861 ****************************************************************************/
2862 void x86emuOp_xor_word_R_RM(u8 X86EMU_UNUSED(op1))
2864 int mod, rl, rh;
2865 uint srcoffset;
2867 START_OF_INSTR();
2868 DECODE_PRINTF("XOR\t");
2869 FETCH_DECODE_MODRM(mod, rh, rl);
2870 switch (mod) {
2871 case 0:
2872 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2873 u32 *destreg;
2874 u32 srcval;
2876 destreg = DECODE_RM_LONG_REGISTER(rh);
2877 DECODE_PRINTF(",");
2878 srcoffset = decode_rm00_address(rl);
2879 srcval = fetch_data_long(srcoffset);
2880 DECODE_PRINTF("\n");
2881 TRACE_AND_STEP();
2882 *destreg = xor_long(*destreg, srcval);
2883 } else {
2884 u16 *destreg;
2885 u16 srcval;
2887 destreg = DECODE_RM_WORD_REGISTER(rh);
2888 DECODE_PRINTF(",");
2889 srcoffset = decode_rm00_address(rl);
2890 srcval = fetch_data_word(srcoffset);
2891 DECODE_PRINTF("\n");
2892 TRACE_AND_STEP();
2893 *destreg = xor_word(*destreg, srcval);
2895 break;
2896 case 1:
2897 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2898 u32 *destreg;
2899 u32 srcval;
2901 destreg = DECODE_RM_LONG_REGISTER(rh);
2902 DECODE_PRINTF(",");
2903 srcoffset = decode_rm01_address(rl);
2904 srcval = fetch_data_long(srcoffset);
2905 DECODE_PRINTF("\n");
2906 TRACE_AND_STEP();
2907 *destreg = xor_long(*destreg, srcval);
2908 } else {
2909 u16 *destreg;
2910 u16 srcval;
2912 destreg = DECODE_RM_WORD_REGISTER(rh);
2913 DECODE_PRINTF(",");
2914 srcoffset = decode_rm01_address(rl);
2915 srcval = fetch_data_word(srcoffset);
2916 DECODE_PRINTF("\n");
2917 TRACE_AND_STEP();
2918 *destreg = xor_word(*destreg, srcval);
2920 break;
2921 case 2:
2922 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2923 u32 *destreg;
2924 u32 srcval;
2926 destreg = DECODE_RM_LONG_REGISTER(rh);
2927 DECODE_PRINTF(",");
2928 srcoffset = decode_rm10_address(rl);
2929 srcval = fetch_data_long(srcoffset);
2930 DECODE_PRINTF("\n");
2931 TRACE_AND_STEP();
2932 *destreg = xor_long(*destreg, srcval);
2933 } else {
2934 u16 *destreg;
2935 u16 srcval;
2937 destreg = DECODE_RM_WORD_REGISTER(rh);
2938 DECODE_PRINTF(",");
2939 srcoffset = decode_rm10_address(rl);
2940 srcval = fetch_data_word(srcoffset);
2941 DECODE_PRINTF("\n");
2942 TRACE_AND_STEP();
2943 *destreg = xor_word(*destreg, srcval);
2945 break;
2946 case 3: /* register to register */
2947 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2948 u32 *destreg,*srcreg;
2950 destreg = DECODE_RM_LONG_REGISTER(rh);
2951 DECODE_PRINTF(",");
2952 srcreg = DECODE_RM_LONG_REGISTER(rl);
2953 DECODE_PRINTF("\n");
2954 TRACE_AND_STEP();
2955 *destreg = xor_long(*destreg, *srcreg);
2956 } else {
2957 u16 *destreg,*srcreg;
2959 destreg = DECODE_RM_WORD_REGISTER(rh);
2960 DECODE_PRINTF(",");
2961 srcreg = DECODE_RM_WORD_REGISTER(rl);
2962 DECODE_PRINTF("\n");
2963 TRACE_AND_STEP();
2964 *destreg = xor_word(*destreg, *srcreg);
2966 break;
2968 DECODE_CLEAR_SEGOVR();
2969 END_OF_INSTR();
2972 /****************************************************************************
2973 REMARKS:
2974 Handles opcode 0x34
2975 ****************************************************************************/
2976 void x86emuOp_xor_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
2978 u8 srcval;
2980 START_OF_INSTR();
2981 DECODE_PRINTF("XOR\tAL,");
2982 srcval = fetch_byte_imm();
2983 DECODE_PRINTF2("%x\n", srcval);
2984 TRACE_AND_STEP();
2985 M.x86.R_AL = xor_byte(M.x86.R_AL, srcval);
2986 DECODE_CLEAR_SEGOVR();
2987 END_OF_INSTR();
2990 /****************************************************************************
2991 REMARKS:
2992 Handles opcode 0x35
2993 ****************************************************************************/
2994 void x86emuOp_xor_word_AX_IMM(u8 X86EMU_UNUSED(op1))
2996 u32 srcval;
2998 START_OF_INSTR();
2999 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3000 DECODE_PRINTF("XOR\tEAX,");
3001 srcval = fetch_long_imm();
3002 } else {
3003 DECODE_PRINTF("XOR\tAX,");
3004 srcval = fetch_word_imm();
3006 DECODE_PRINTF2("%x\n", srcval);
3007 TRACE_AND_STEP();
3008 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3009 M.x86.R_EAX = xor_long(M.x86.R_EAX, srcval);
3010 } else {
3011 M.x86.R_AX = xor_word(M.x86.R_AX, (u16)srcval);
3013 DECODE_CLEAR_SEGOVR();
3014 END_OF_INSTR();
3017 /****************************************************************************
3018 REMARKS:
3019 Handles opcode 0x36
3020 ****************************************************************************/
3021 void x86emuOp_segovr_SS(u8 X86EMU_UNUSED(op1))
3023 START_OF_INSTR();
3024 DECODE_PRINTF("SS:\n");
3025 TRACE_AND_STEP();
3026 M.x86.mode |= SYSMODE_SEGOVR_SS;
3027 /* no DECODE_CLEAR_SEGOVR ! */
3028 END_OF_INSTR();
3031 /****************************************************************************
3032 REMARKS:
3033 Handles opcode 0x37
3034 ****************************************************************************/
3035 void x86emuOp_aaa(u8 X86EMU_UNUSED(op1))
3037 START_OF_INSTR();
3038 DECODE_PRINTF("AAA\n");
3039 TRACE_AND_STEP();
3040 M.x86.R_AX = aaa_word(M.x86.R_AX);
3041 DECODE_CLEAR_SEGOVR();
3042 END_OF_INSTR();
3045 /****************************************************************************
3046 REMARKS:
3047 Handles opcode 0x38
3048 ****************************************************************************/
3049 void x86emuOp_cmp_byte_RM_R(u8 X86EMU_UNUSED(op1))
3051 int mod, rl, rh;
3052 uint destoffset;
3053 u8 *destreg, *srcreg;
3054 u8 destval;
3056 START_OF_INSTR();
3057 DECODE_PRINTF("CMP\t");
3058 FETCH_DECODE_MODRM(mod, rh, rl);
3059 switch (mod) {
3060 case 0:
3061 destoffset = decode_rm00_address(rl);
3062 DECODE_PRINTF(",");
3063 destval = fetch_data_byte(destoffset);
3064 srcreg = DECODE_RM_BYTE_REGISTER(rh);
3065 DECODE_PRINTF("\n");
3066 TRACE_AND_STEP();
3067 cmp_byte(destval, *srcreg);
3068 break;
3069 case 1:
3070 destoffset = decode_rm01_address(rl);
3071 DECODE_PRINTF(",");
3072 destval = fetch_data_byte(destoffset);
3073 srcreg = DECODE_RM_BYTE_REGISTER(rh);
3074 DECODE_PRINTF("\n");
3075 TRACE_AND_STEP();
3076 cmp_byte(destval, *srcreg);
3077 break;
3078 case 2:
3079 destoffset = decode_rm10_address(rl);
3080 DECODE_PRINTF(",");
3081 destval = fetch_data_byte(destoffset);
3082 srcreg = DECODE_RM_BYTE_REGISTER(rh);
3083 DECODE_PRINTF("\n");
3084 TRACE_AND_STEP();
3085 cmp_byte(destval, *srcreg);
3086 break;
3087 case 3: /* register to register */
3088 destreg = DECODE_RM_BYTE_REGISTER(rl);
3089 DECODE_PRINTF(",");
3090 srcreg = DECODE_RM_BYTE_REGISTER(rh);
3091 DECODE_PRINTF("\n");
3092 TRACE_AND_STEP();
3093 cmp_byte(*destreg, *srcreg);
3094 break;
3096 DECODE_CLEAR_SEGOVR();
3097 END_OF_INSTR();
3100 /****************************************************************************
3101 REMARKS:
3102 Handles opcode 0x39
3103 ****************************************************************************/
3104 void x86emuOp_cmp_word_RM_R(u8 X86EMU_UNUSED(op1))
3106 int mod, rl, rh;
3107 uint destoffset;
3109 START_OF_INSTR();
3110 DECODE_PRINTF("CMP\t");
3111 FETCH_DECODE_MODRM(mod, rh, rl);
3112 switch (mod) {
3113 case 0:
3114 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3115 u32 destval;
3116 u32 *srcreg;
3118 destoffset = decode_rm00_address(rl);
3119 DECODE_PRINTF(",");
3120 destval = fetch_data_long(destoffset);
3121 srcreg = DECODE_RM_LONG_REGISTER(rh);
3122 DECODE_PRINTF("\n");
3123 TRACE_AND_STEP();
3124 cmp_long(destval, *srcreg);
3125 } else {
3126 u16 destval;
3127 u16 *srcreg;
3129 destoffset = decode_rm00_address(rl);
3130 DECODE_PRINTF(",");
3131 destval = fetch_data_word(destoffset);
3132 srcreg = DECODE_RM_WORD_REGISTER(rh);
3133 DECODE_PRINTF("\n");
3134 TRACE_AND_STEP();
3135 cmp_word(destval, *srcreg);
3137 break;
3138 case 1:
3139 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3140 u32 destval;
3141 u32 *srcreg;
3143 destoffset = decode_rm01_address(rl);
3144 DECODE_PRINTF(",");
3145 destval = fetch_data_long(destoffset);
3146 srcreg = DECODE_RM_LONG_REGISTER(rh);
3147 DECODE_PRINTF("\n");
3148 TRACE_AND_STEP();
3149 cmp_long(destval, *srcreg);
3150 } else {
3151 u16 destval;
3152 u16 *srcreg;
3154 destoffset = decode_rm01_address(rl);
3155 DECODE_PRINTF(",");
3156 destval = fetch_data_word(destoffset);
3157 srcreg = DECODE_RM_WORD_REGISTER(rh);
3158 DECODE_PRINTF("\n");
3159 TRACE_AND_STEP();
3160 cmp_word(destval, *srcreg);
3162 break;
3163 case 2:
3164 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3165 u32 destval;
3166 u32 *srcreg;
3168 destoffset = decode_rm10_address(rl);
3169 DECODE_PRINTF(",");
3170 destval = fetch_data_long(destoffset);
3171 srcreg = DECODE_RM_LONG_REGISTER(rh);
3172 DECODE_PRINTF("\n");
3173 TRACE_AND_STEP();
3174 cmp_long(destval, *srcreg);
3175 } else {
3176 u16 destval;
3177 u16 *srcreg;
3179 destoffset = decode_rm10_address(rl);
3180 DECODE_PRINTF(",");
3181 destval = fetch_data_word(destoffset);
3182 srcreg = DECODE_RM_WORD_REGISTER(rh);
3183 DECODE_PRINTF("\n");
3184 TRACE_AND_STEP();
3185 cmp_word(destval, *srcreg);
3187 break;
3188 case 3: /* register to register */
3189 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3190 u32 *destreg,*srcreg;
3192 destreg = DECODE_RM_LONG_REGISTER(rl);
3193 DECODE_PRINTF(",");
3194 srcreg = DECODE_RM_LONG_REGISTER(rh);
3195 DECODE_PRINTF("\n");
3196 TRACE_AND_STEP();
3197 cmp_long(*destreg, *srcreg);
3198 } else {
3199 u16 *destreg,*srcreg;
3201 destreg = DECODE_RM_WORD_REGISTER(rl);
3202 DECODE_PRINTF(",");
3203 srcreg = DECODE_RM_WORD_REGISTER(rh);
3204 DECODE_PRINTF("\n");
3205 TRACE_AND_STEP();
3206 cmp_word(*destreg, *srcreg);
3208 break;
3210 DECODE_CLEAR_SEGOVR();
3211 END_OF_INSTR();
3214 /****************************************************************************
3215 REMARKS:
3216 Handles opcode 0x3a
3217 ****************************************************************************/
3218 void x86emuOp_cmp_byte_R_RM(u8 X86EMU_UNUSED(op1))
3220 int mod, rl, rh;
3221 u8 *destreg, *srcreg;
3222 uint srcoffset;
3223 u8 srcval;
3225 START_OF_INSTR();
3226 DECODE_PRINTF("CMP\t");
3227 FETCH_DECODE_MODRM(mod, rh, rl);
3228 switch (mod) {
3229 case 0:
3230 destreg = DECODE_RM_BYTE_REGISTER(rh);
3231 DECODE_PRINTF(",");
3232 srcoffset = decode_rm00_address(rl);
3233 srcval = fetch_data_byte(srcoffset);
3234 DECODE_PRINTF("\n");
3235 TRACE_AND_STEP();
3236 cmp_byte(*destreg, srcval);
3237 break;
3238 case 1:
3239 destreg = DECODE_RM_BYTE_REGISTER(rh);
3240 DECODE_PRINTF(",");
3241 srcoffset = decode_rm01_address(rl);
3242 srcval = fetch_data_byte(srcoffset);
3243 DECODE_PRINTF("\n");
3244 TRACE_AND_STEP();
3245 cmp_byte(*destreg, srcval);
3246 break;
3247 case 2:
3248 destreg = DECODE_RM_BYTE_REGISTER(rh);
3249 DECODE_PRINTF(",");
3250 srcoffset = decode_rm10_address(rl);
3251 srcval = fetch_data_byte(srcoffset);
3252 DECODE_PRINTF("\n");
3253 TRACE_AND_STEP();
3254 cmp_byte(*destreg, srcval);
3255 break;
3256 case 3: /* register to register */
3257 destreg = DECODE_RM_BYTE_REGISTER(rh);
3258 DECODE_PRINTF(",");
3259 srcreg = DECODE_RM_BYTE_REGISTER(rl);
3260 DECODE_PRINTF("\n");
3261 TRACE_AND_STEP();
3262 cmp_byte(*destreg, *srcreg);
3263 break;
3265 DECODE_CLEAR_SEGOVR();
3266 END_OF_INSTR();
3269 /****************************************************************************
3270 REMARKS:
3271 Handles opcode 0x3b
3272 ****************************************************************************/
3273 void x86emuOp_cmp_word_R_RM(u8 X86EMU_UNUSED(op1))
3275 int mod, rl, rh;
3276 uint srcoffset;
3278 START_OF_INSTR();
3279 DECODE_PRINTF("CMP\t");
3280 FETCH_DECODE_MODRM(mod, rh, rl);
3281 switch (mod) {
3282 case 0:
3283 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3284 u32 *destreg;
3285 u32 srcval;
3287 destreg = DECODE_RM_LONG_REGISTER(rh);
3288 DECODE_PRINTF(",");
3289 srcoffset = decode_rm00_address(rl);
3290 srcval = fetch_data_long(srcoffset);
3291 DECODE_PRINTF("\n");
3292 TRACE_AND_STEP();
3293 cmp_long(*destreg, srcval);
3294 } else {
3295 u16 *destreg;
3296 u16 srcval;
3298 destreg = DECODE_RM_WORD_REGISTER(rh);
3299 DECODE_PRINTF(",");
3300 srcoffset = decode_rm00_address(rl);
3301 srcval = fetch_data_word(srcoffset);
3302 DECODE_PRINTF("\n");
3303 TRACE_AND_STEP();
3304 cmp_word(*destreg, srcval);
3306 break;
3307 case 1:
3308 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3309 u32 *destreg;
3310 u32 srcval;
3312 destreg = DECODE_RM_LONG_REGISTER(rh);
3313 DECODE_PRINTF(",");
3314 srcoffset = decode_rm01_address(rl);
3315 srcval = fetch_data_long(srcoffset);
3316 DECODE_PRINTF("\n");
3317 TRACE_AND_STEP();
3318 cmp_long(*destreg, srcval);
3319 } else {
3320 u16 *destreg;
3321 u16 srcval;
3323 destreg = DECODE_RM_WORD_REGISTER(rh);
3324 DECODE_PRINTF(",");
3325 srcoffset = decode_rm01_address(rl);
3326 srcval = fetch_data_word(srcoffset);
3327 DECODE_PRINTF("\n");
3328 TRACE_AND_STEP();
3329 cmp_word(*destreg, srcval);
3331 break;
3332 case 2:
3333 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3334 u32 *destreg;
3335 u32 srcval;
3337 destreg = DECODE_RM_LONG_REGISTER(rh);
3338 DECODE_PRINTF(",");
3339 srcoffset = decode_rm10_address(rl);
3340 srcval = fetch_data_long(srcoffset);
3341 DECODE_PRINTF("\n");
3342 TRACE_AND_STEP();
3343 cmp_long(*destreg, srcval);
3344 } else {
3345 u16 *destreg;
3346 u16 srcval;
3348 destreg = DECODE_RM_WORD_REGISTER(rh);
3349 DECODE_PRINTF(",");
3350 srcoffset = decode_rm10_address(rl);
3351 srcval = fetch_data_word(srcoffset);
3352 DECODE_PRINTF("\n");
3353 TRACE_AND_STEP();
3354 cmp_word(*destreg, srcval);
3356 break;
3357 case 3: /* register to register */
3358 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3359 u32 *destreg,*srcreg;
3361 destreg = DECODE_RM_LONG_REGISTER(rh);
3362 DECODE_PRINTF(",");
3363 srcreg = DECODE_RM_LONG_REGISTER(rl);
3364 DECODE_PRINTF("\n");
3365 TRACE_AND_STEP();
3366 cmp_long(*destreg, *srcreg);
3367 } else {
3368 u16 *destreg,*srcreg;
3370 destreg = DECODE_RM_WORD_REGISTER(rh);
3371 DECODE_PRINTF(",");
3372 srcreg = DECODE_RM_WORD_REGISTER(rl);
3373 DECODE_PRINTF("\n");
3374 TRACE_AND_STEP();
3375 cmp_word(*destreg, *srcreg);
3377 break;
3379 DECODE_CLEAR_SEGOVR();
3380 END_OF_INSTR();
3383 /****************************************************************************
3384 REMARKS:
3385 Handles opcode 0x3c
3386 ****************************************************************************/
3387 void x86emuOp_cmp_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
3389 u8 srcval;
3391 START_OF_INSTR();
3392 DECODE_PRINTF("CMP\tAL,");
3393 srcval = fetch_byte_imm();
3394 DECODE_PRINTF2("%x\n", srcval);
3395 TRACE_AND_STEP();
3396 cmp_byte(M.x86.R_AL, srcval);
3397 DECODE_CLEAR_SEGOVR();
3398 END_OF_INSTR();
3401 /****************************************************************************
3402 REMARKS:
3403 Handles opcode 0x3d
3404 ****************************************************************************/
3405 void x86emuOp_cmp_word_AX_IMM(u8 X86EMU_UNUSED(op1))
3407 u32 srcval;
3409 START_OF_INSTR();
3410 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3411 DECODE_PRINTF("CMP\tEAX,");
3412 srcval = fetch_long_imm();
3413 } else {
3414 DECODE_PRINTF("CMP\tAX,");
3415 srcval = fetch_word_imm();
3417 DECODE_PRINTF2("%x\n", srcval);
3418 TRACE_AND_STEP();
3419 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3420 cmp_long(M.x86.R_EAX, srcval);
3421 } else {
3422 cmp_word(M.x86.R_AX, (u16)srcval);
3424 DECODE_CLEAR_SEGOVR();
3425 END_OF_INSTR();
3428 /****************************************************************************
3429 REMARKS:
3430 Handles opcode 0x3e
3431 ****************************************************************************/
3432 void x86emuOp_segovr_DS(u8 X86EMU_UNUSED(op1))
3434 START_OF_INSTR();
3435 DECODE_PRINTF("DS:\n");
3436 TRACE_AND_STEP();
3437 M.x86.mode |= SYSMODE_SEGOVR_DS;
3438 /* NO DECODE_CLEAR_SEGOVR! */
3439 END_OF_INSTR();
3442 /****************************************************************************
3443 REMARKS:
3444 Handles opcode 0x3f
3445 ****************************************************************************/
3446 void x86emuOp_aas(u8 X86EMU_UNUSED(op1))
3448 START_OF_INSTR();
3449 DECODE_PRINTF("AAS\n");
3450 TRACE_AND_STEP();
3451 M.x86.R_AX = aas_word(M.x86.R_AX);
3452 DECODE_CLEAR_SEGOVR();
3453 END_OF_INSTR();
3456 /****************************************************************************
3457 REMARKS:
3458 Handles opcode 0x40
3459 ****************************************************************************/
3460 void x86emuOp_inc_AX(u8 X86EMU_UNUSED(op1))
3462 START_OF_INSTR();
3463 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3464 DECODE_PRINTF("INC\tEAX\n");
3465 } else {
3466 DECODE_PRINTF("INC\tAX\n");
3468 TRACE_AND_STEP();
3469 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3470 M.x86.R_EAX = inc_long(M.x86.R_EAX);
3471 } else {
3472 M.x86.R_AX = inc_word(M.x86.R_AX);
3474 DECODE_CLEAR_SEGOVR();
3475 END_OF_INSTR();
3478 /****************************************************************************
3479 REMARKS:
3480 Handles opcode 0x41
3481 ****************************************************************************/
3482 void x86emuOp_inc_CX(u8 X86EMU_UNUSED(op1))
3484 START_OF_INSTR();
3485 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3486 DECODE_PRINTF("INC\tECX\n");
3487 } else {
3488 DECODE_PRINTF("INC\tCX\n");
3490 TRACE_AND_STEP();
3491 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3492 M.x86.R_ECX = inc_long(M.x86.R_ECX);
3493 } else {
3494 M.x86.R_CX = inc_word(M.x86.R_CX);
3496 DECODE_CLEAR_SEGOVR();
3497 END_OF_INSTR();
3500 /****************************************************************************
3501 REMARKS:
3502 Handles opcode 0x42
3503 ****************************************************************************/
3504 void x86emuOp_inc_DX(u8 X86EMU_UNUSED(op1))
3506 START_OF_INSTR();
3507 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3508 DECODE_PRINTF("INC\tEDX\n");
3509 } else {
3510 DECODE_PRINTF("INC\tDX\n");
3512 TRACE_AND_STEP();
3513 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3514 M.x86.R_EDX = inc_long(M.x86.R_EDX);
3515 } else {
3516 M.x86.R_DX = inc_word(M.x86.R_DX);
3518 DECODE_CLEAR_SEGOVR();
3519 END_OF_INSTR();
3522 /****************************************************************************
3523 REMARKS:
3524 Handles opcode 0x43
3525 ****************************************************************************/
3526 void x86emuOp_inc_BX(u8 X86EMU_UNUSED(op1))
3528 START_OF_INSTR();
3529 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3530 DECODE_PRINTF("INC\tEBX\n");
3531 } else {
3532 DECODE_PRINTF("INC\tBX\n");
3534 TRACE_AND_STEP();
3535 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3536 M.x86.R_EBX = inc_long(M.x86.R_EBX);
3537 } else {
3538 M.x86.R_BX = inc_word(M.x86.R_BX);
3540 DECODE_CLEAR_SEGOVR();
3541 END_OF_INSTR();
3544 /****************************************************************************
3545 REMARKS:
3546 Handles opcode 0x44
3547 ****************************************************************************/
3548 void x86emuOp_inc_SP(u8 X86EMU_UNUSED(op1))
3550 START_OF_INSTR();
3551 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3552 DECODE_PRINTF("INC\tESP\n");
3553 } else {
3554 DECODE_PRINTF("INC\tSP\n");
3556 TRACE_AND_STEP();
3557 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3558 M.x86.R_ESP = inc_long(M.x86.R_ESP);
3559 } else {
3560 M.x86.R_SP = inc_word(M.x86.R_SP);
3562 DECODE_CLEAR_SEGOVR();
3563 END_OF_INSTR();
3566 /****************************************************************************
3567 REMARKS:
3568 Handles opcode 0x45
3569 ****************************************************************************/
3570 void x86emuOp_inc_BP(u8 X86EMU_UNUSED(op1))
3572 START_OF_INSTR();
3573 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3574 DECODE_PRINTF("INC\tEBP\n");
3575 } else {
3576 DECODE_PRINTF("INC\tBP\n");
3578 TRACE_AND_STEP();
3579 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3580 M.x86.R_EBP = inc_long(M.x86.R_EBP);
3581 } else {
3582 M.x86.R_BP = inc_word(M.x86.R_BP);
3584 DECODE_CLEAR_SEGOVR();
3585 END_OF_INSTR();
3588 /****************************************************************************
3589 REMARKS:
3590 Handles opcode 0x46
3591 ****************************************************************************/
3592 void x86emuOp_inc_SI(u8 X86EMU_UNUSED(op1))
3594 START_OF_INSTR();
3595 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3596 DECODE_PRINTF("INC\tESI\n");
3597 } else {
3598 DECODE_PRINTF("INC\tSI\n");
3600 TRACE_AND_STEP();
3601 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3602 M.x86.R_ESI = inc_long(M.x86.R_ESI);
3603 } else {
3604 M.x86.R_SI = inc_word(M.x86.R_SI);
3606 DECODE_CLEAR_SEGOVR();
3607 END_OF_INSTR();
3610 /****************************************************************************
3611 REMARKS:
3612 Handles opcode 0x47
3613 ****************************************************************************/
3614 void x86emuOp_inc_DI(u8 X86EMU_UNUSED(op1))
3616 START_OF_INSTR();
3617 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3618 DECODE_PRINTF("INC\tEDI\n");
3619 } else {
3620 DECODE_PRINTF("INC\tDI\n");
3622 TRACE_AND_STEP();
3623 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3624 M.x86.R_EDI = inc_long(M.x86.R_EDI);
3625 } else {
3626 M.x86.R_DI = inc_word(M.x86.R_DI);
3628 DECODE_CLEAR_SEGOVR();
3629 END_OF_INSTR();
3632 /****************************************************************************
3633 REMARKS:
3634 Handles opcode 0x48
3635 ****************************************************************************/
3636 void x86emuOp_dec_AX(u8 X86EMU_UNUSED(op1))
3638 START_OF_INSTR();
3639 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3640 DECODE_PRINTF("DEC\tEAX\n");
3641 } else {
3642 DECODE_PRINTF("DEC\tAX\n");
3644 TRACE_AND_STEP();
3645 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3646 M.x86.R_EAX = dec_long(M.x86.R_EAX);
3647 } else {
3648 M.x86.R_AX = dec_word(M.x86.R_AX);
3650 DECODE_CLEAR_SEGOVR();
3651 END_OF_INSTR();
3654 /****************************************************************************
3655 REMARKS:
3656 Handles opcode 0x49
3657 ****************************************************************************/
3658 void x86emuOp_dec_CX(u8 X86EMU_UNUSED(op1))
3660 START_OF_INSTR();
3661 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3662 DECODE_PRINTF("DEC\tECX\n");
3663 } else {
3664 DECODE_PRINTF("DEC\tCX\n");
3666 TRACE_AND_STEP();
3667 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3668 M.x86.R_ECX = dec_long(M.x86.R_ECX);
3669 } else {
3670 M.x86.R_CX = dec_word(M.x86.R_CX);
3672 DECODE_CLEAR_SEGOVR();
3673 END_OF_INSTR();
3676 /****************************************************************************
3677 REMARKS:
3678 Handles opcode 0x4a
3679 ****************************************************************************/
3680 void x86emuOp_dec_DX(u8 X86EMU_UNUSED(op1))
3682 START_OF_INSTR();
3683 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3684 DECODE_PRINTF("DEC\tEDX\n");
3685 } else {
3686 DECODE_PRINTF("DEC\tDX\n");
3688 TRACE_AND_STEP();
3689 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3690 M.x86.R_EDX = dec_long(M.x86.R_EDX);
3691 } else {
3692 M.x86.R_DX = dec_word(M.x86.R_DX);
3694 DECODE_CLEAR_SEGOVR();
3695 END_OF_INSTR();
3698 /****************************************************************************
3699 REMARKS:
3700 Handles opcode 0x4b
3701 ****************************************************************************/
3702 void x86emuOp_dec_BX(u8 X86EMU_UNUSED(op1))
3704 START_OF_INSTR();
3705 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3706 DECODE_PRINTF("DEC\tEBX\n");
3707 } else {
3708 DECODE_PRINTF("DEC\tBX\n");
3710 TRACE_AND_STEP();
3711 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3712 M.x86.R_EBX = dec_long(M.x86.R_EBX);
3713 } else {
3714 M.x86.R_BX = dec_word(M.x86.R_BX);
3716 DECODE_CLEAR_SEGOVR();
3717 END_OF_INSTR();
3720 /****************************************************************************
3721 REMARKS:
3722 Handles opcode 0x4c
3723 ****************************************************************************/
3724 void x86emuOp_dec_SP(u8 X86EMU_UNUSED(op1))
3726 START_OF_INSTR();
3727 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3728 DECODE_PRINTF("DEC\tESP\n");
3729 } else {
3730 DECODE_PRINTF("DEC\tSP\n");
3732 TRACE_AND_STEP();
3733 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3734 M.x86.R_ESP = dec_long(M.x86.R_ESP);
3735 } else {
3736 M.x86.R_SP = dec_word(M.x86.R_SP);
3738 DECODE_CLEAR_SEGOVR();
3739 END_OF_INSTR();
3742 /****************************************************************************
3743 REMARKS:
3744 Handles opcode 0x4d
3745 ****************************************************************************/
3746 void x86emuOp_dec_BP(u8 X86EMU_UNUSED(op1))
3748 START_OF_INSTR();
3749 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3750 DECODE_PRINTF("DEC\tEBP\n");
3751 } else {
3752 DECODE_PRINTF("DEC\tBP\n");
3754 TRACE_AND_STEP();
3755 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3756 M.x86.R_EBP = dec_long(M.x86.R_EBP);
3757 } else {
3758 M.x86.R_BP = dec_word(M.x86.R_BP);
3760 DECODE_CLEAR_SEGOVR();
3761 END_OF_INSTR();
3764 /****************************************************************************
3765 REMARKS:
3766 Handles opcode 0x4e
3767 ****************************************************************************/
3768 void x86emuOp_dec_SI(u8 X86EMU_UNUSED(op1))
3770 START_OF_INSTR();
3771 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3772 DECODE_PRINTF("DEC\tESI\n");
3773 } else {
3774 DECODE_PRINTF("DEC\tSI\n");
3776 TRACE_AND_STEP();
3777 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3778 M.x86.R_ESI = dec_long(M.x86.R_ESI);
3779 } else {
3780 M.x86.R_SI = dec_word(M.x86.R_SI);
3782 DECODE_CLEAR_SEGOVR();
3783 END_OF_INSTR();
3786 /****************************************************************************
3787 REMARKS:
3788 Handles opcode 0x4f
3789 ****************************************************************************/
3790 void x86emuOp_dec_DI(u8 X86EMU_UNUSED(op1))
3792 START_OF_INSTR();
3793 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3794 DECODE_PRINTF("DEC\tEDI\n");
3795 } else {
3796 DECODE_PRINTF("DEC\tDI\n");
3798 TRACE_AND_STEP();
3799 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3800 M.x86.R_EDI = dec_long(M.x86.R_EDI);
3801 } else {
3802 M.x86.R_DI = dec_word(M.x86.R_DI);
3804 DECODE_CLEAR_SEGOVR();
3805 END_OF_INSTR();
3808 /****************************************************************************
3809 REMARKS:
3810 Handles opcode 0x50
3811 ****************************************************************************/
3812 void x86emuOp_push_AX(u8 X86EMU_UNUSED(op1))
3814 START_OF_INSTR();
3815 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3816 DECODE_PRINTF("PUSH\tEAX\n");
3817 } else {
3818 DECODE_PRINTF("PUSH\tAX\n");
3820 TRACE_AND_STEP();
3821 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3822 push_long(M.x86.R_EAX);
3823 } else {
3824 push_word(M.x86.R_AX);
3826 DECODE_CLEAR_SEGOVR();
3827 END_OF_INSTR();
3830 /****************************************************************************
3831 REMARKS:
3832 Handles opcode 0x51
3833 ****************************************************************************/
3834 void x86emuOp_push_CX(u8 X86EMU_UNUSED(op1))
3836 START_OF_INSTR();
3837 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3838 DECODE_PRINTF("PUSH\tECX\n");
3839 } else {
3840 DECODE_PRINTF("PUSH\tCX\n");
3842 TRACE_AND_STEP();
3843 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3844 push_long(M.x86.R_ECX);
3845 } else {
3846 push_word(M.x86.R_CX);
3848 DECODE_CLEAR_SEGOVR();
3849 END_OF_INSTR();
3852 /****************************************************************************
3853 REMARKS:
3854 Handles opcode 0x52
3855 ****************************************************************************/
3856 void x86emuOp_push_DX(u8 X86EMU_UNUSED(op1))
3858 START_OF_INSTR();
3859 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3860 DECODE_PRINTF("PUSH\tEDX\n");
3861 } else {
3862 DECODE_PRINTF("PUSH\tDX\n");
3864 TRACE_AND_STEP();
3865 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3866 push_long(M.x86.R_EDX);
3867 } else {
3868 push_word(M.x86.R_DX);
3870 DECODE_CLEAR_SEGOVR();
3871 END_OF_INSTR();
3874 /****************************************************************************
3875 REMARKS:
3876 Handles opcode 0x53
3877 ****************************************************************************/
3878 void x86emuOp_push_BX(u8 X86EMU_UNUSED(op1))
3880 START_OF_INSTR();
3881 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3882 DECODE_PRINTF("PUSH\tEBX\n");
3883 } else {
3884 DECODE_PRINTF("PUSH\tBX\n");
3886 TRACE_AND_STEP();
3887 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3888 push_long(M.x86.R_EBX);
3889 } else {
3890 push_word(M.x86.R_BX);
3892 DECODE_CLEAR_SEGOVR();
3893 END_OF_INSTR();
3896 /****************************************************************************
3897 REMARKS:
3898 Handles opcode 0x54
3899 ****************************************************************************/
3900 void x86emuOp_push_SP(u8 X86EMU_UNUSED(op1))
3902 START_OF_INSTR();
3903 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3904 DECODE_PRINTF("PUSH\tESP\n");
3905 } else {
3906 DECODE_PRINTF("PUSH\tSP\n");
3908 TRACE_AND_STEP();
3909 /* Always push (E)SP, since we are emulating an i386 and above
3910 * processor. This is necessary as some BIOS'es use this to check
3911 * what type of processor is in the system.
3913 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3914 push_long(M.x86.R_ESP);
3915 } else {
3916 push_word((u16)(M.x86.R_SP));
3918 DECODE_CLEAR_SEGOVR();
3919 END_OF_INSTR();
3922 /****************************************************************************
3923 REMARKS:
3924 Handles opcode 0x55
3925 ****************************************************************************/
3926 void x86emuOp_push_BP(u8 X86EMU_UNUSED(op1))
3928 START_OF_INSTR();
3929 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3930 DECODE_PRINTF("PUSH\tEBP\n");
3931 } else {
3932 DECODE_PRINTF("PUSH\tBP\n");
3934 TRACE_AND_STEP();
3935 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3936 push_long(M.x86.R_EBP);
3937 } else {
3938 push_word(M.x86.R_BP);
3940 DECODE_CLEAR_SEGOVR();
3941 END_OF_INSTR();
3944 /****************************************************************************
3945 REMARKS:
3946 Handles opcode 0x56
3947 ****************************************************************************/
3948 void x86emuOp_push_SI(u8 X86EMU_UNUSED(op1))
3950 START_OF_INSTR();
3951 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3952 DECODE_PRINTF("PUSH\tESI\n");
3953 } else {
3954 DECODE_PRINTF("PUSH\tSI\n");
3956 TRACE_AND_STEP();
3957 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3958 push_long(M.x86.R_ESI);
3959 } else {
3960 push_word(M.x86.R_SI);
3962 DECODE_CLEAR_SEGOVR();
3963 END_OF_INSTR();
3966 /****************************************************************************
3967 REMARKS:
3968 Handles opcode 0x57
3969 ****************************************************************************/
3970 void x86emuOp_push_DI(u8 X86EMU_UNUSED(op1))
3972 START_OF_INSTR();
3973 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3974 DECODE_PRINTF("PUSH\tEDI\n");
3975 } else {
3976 DECODE_PRINTF("PUSH\tDI\n");
3978 TRACE_AND_STEP();
3979 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3980 push_long(M.x86.R_EDI);
3981 } else {
3982 push_word(M.x86.R_DI);
3984 DECODE_CLEAR_SEGOVR();
3985 END_OF_INSTR();
3988 /****************************************************************************
3989 REMARKS:
3990 Handles opcode 0x58
3991 ****************************************************************************/
3992 void x86emuOp_pop_AX(u8 X86EMU_UNUSED(op1))
3994 START_OF_INSTR();
3995 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3996 DECODE_PRINTF("POP\tEAX\n");
3997 } else {
3998 DECODE_PRINTF("POP\tAX\n");
4000 TRACE_AND_STEP();
4001 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4002 M.x86.R_EAX = pop_long();
4003 } else {
4004 M.x86.R_AX = pop_word();
4006 DECODE_CLEAR_SEGOVR();
4007 END_OF_INSTR();
4010 /****************************************************************************
4011 REMARKS:
4012 Handles opcode 0x59
4013 ****************************************************************************/
4014 void x86emuOp_pop_CX(u8 X86EMU_UNUSED(op1))
4016 START_OF_INSTR();
4017 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4018 DECODE_PRINTF("POP\tECX\n");
4019 } else {
4020 DECODE_PRINTF("POP\tCX\n");
4022 TRACE_AND_STEP();
4023 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4024 M.x86.R_ECX = pop_long();
4025 } else {
4026 M.x86.R_CX = pop_word();
4028 DECODE_CLEAR_SEGOVR();
4029 END_OF_INSTR();
4032 /****************************************************************************
4033 REMARKS:
4034 Handles opcode 0x5a
4035 ****************************************************************************/
4036 void x86emuOp_pop_DX(u8 X86EMU_UNUSED(op1))
4038 START_OF_INSTR();
4039 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4040 DECODE_PRINTF("POP\tEDX\n");
4041 } else {
4042 DECODE_PRINTF("POP\tDX\n");
4044 TRACE_AND_STEP();
4045 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4046 M.x86.R_EDX = pop_long();
4047 } else {
4048 M.x86.R_DX = pop_word();
4050 DECODE_CLEAR_SEGOVR();
4051 END_OF_INSTR();
4054 /****************************************************************************
4055 REMARKS:
4056 Handles opcode 0x5b
4057 ****************************************************************************/
4058 void x86emuOp_pop_BX(u8 X86EMU_UNUSED(op1))
4060 START_OF_INSTR();
4061 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4062 DECODE_PRINTF("POP\tEBX\n");
4063 } else {
4064 DECODE_PRINTF("POP\tBX\n");
4066 TRACE_AND_STEP();
4067 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4068 M.x86.R_EBX = pop_long();
4069 } else {
4070 M.x86.R_BX = pop_word();
4072 DECODE_CLEAR_SEGOVR();
4073 END_OF_INSTR();
4076 /****************************************************************************
4077 REMARKS:
4078 Handles opcode 0x5c
4079 ****************************************************************************/
4080 void x86emuOp_pop_SP(u8 X86EMU_UNUSED(op1))
4082 START_OF_INSTR();
4083 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4084 DECODE_PRINTF("POP\tESP\n");
4085 } else {
4086 DECODE_PRINTF("POP\tSP\n");
4088 TRACE_AND_STEP();
4089 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4090 M.x86.R_ESP = pop_long();
4091 } else {
4092 M.x86.R_SP = pop_word();
4094 DECODE_CLEAR_SEGOVR();
4095 END_OF_INSTR();
4098 /****************************************************************************
4099 REMARKS:
4100 Handles opcode 0x5d
4101 ****************************************************************************/
4102 void x86emuOp_pop_BP(u8 X86EMU_UNUSED(op1))
4104 START_OF_INSTR();
4105 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4106 DECODE_PRINTF("POP\tEBP\n");
4107 } else {
4108 DECODE_PRINTF("POP\tBP\n");
4110 TRACE_AND_STEP();
4111 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4112 M.x86.R_EBP = pop_long();
4113 } else {
4114 M.x86.R_BP = pop_word();
4116 DECODE_CLEAR_SEGOVR();
4117 END_OF_INSTR();
4120 /****************************************************************************
4121 REMARKS:
4122 Handles opcode 0x5e
4123 ****************************************************************************/
4124 void x86emuOp_pop_SI(u8 X86EMU_UNUSED(op1))
4126 START_OF_INSTR();
4127 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4128 DECODE_PRINTF("POP\tESI\n");
4129 } else {
4130 DECODE_PRINTF("POP\tSI\n");
4132 TRACE_AND_STEP();
4133 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4134 M.x86.R_ESI = pop_long();
4135 } else {
4136 M.x86.R_SI = pop_word();
4138 DECODE_CLEAR_SEGOVR();
4139 END_OF_INSTR();
4142 /****************************************************************************
4143 REMARKS:
4144 Handles opcode 0x5f
4145 ****************************************************************************/
4146 void x86emuOp_pop_DI(u8 X86EMU_UNUSED(op1))
4148 START_OF_INSTR();
4149 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4150 DECODE_PRINTF("POP\tEDI\n");
4151 } else {
4152 DECODE_PRINTF("POP\tDI\n");
4154 TRACE_AND_STEP();
4155 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4156 M.x86.R_EDI = pop_long();
4157 } else {
4158 M.x86.R_DI = pop_word();
4160 DECODE_CLEAR_SEGOVR();
4161 END_OF_INSTR();
4164 /****************************************************************************
4165 REMARKS:
4166 Handles opcode 0x60
4167 ****************************************************************************/
4168 void x86emuOp_push_all(u8 X86EMU_UNUSED(op1))
4170 START_OF_INSTR();
4171 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4172 DECODE_PRINTF("PUSHAD\n");
4173 } else {
4174 DECODE_PRINTF("PUSHA\n");
4176 TRACE_AND_STEP();
4177 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4178 u32 old_sp = M.x86.R_ESP;
4180 push_long(M.x86.R_EAX);
4181 push_long(M.x86.R_ECX);
4182 push_long(M.x86.R_EDX);
4183 push_long(M.x86.R_EBX);
4184 push_long(old_sp);
4185 push_long(M.x86.R_EBP);
4186 push_long(M.x86.R_ESI);
4187 push_long(M.x86.R_EDI);
4188 } else {
4189 u16 old_sp = M.x86.R_SP;
4191 push_word(M.x86.R_AX);
4192 push_word(M.x86.R_CX);
4193 push_word(M.x86.R_DX);
4194 push_word(M.x86.R_BX);
4195 push_word(old_sp);
4196 push_word(M.x86.R_BP);
4197 push_word(M.x86.R_SI);
4198 push_word(M.x86.R_DI);
4200 DECODE_CLEAR_SEGOVR();
4201 END_OF_INSTR();
4204 /****************************************************************************
4205 REMARKS:
4206 Handles opcode 0x61
4207 ****************************************************************************/
4208 void x86emuOp_pop_all(u8 X86EMU_UNUSED(op1))
4210 START_OF_INSTR();
4211 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4212 DECODE_PRINTF("POPAD\n");
4213 } else {
4214 DECODE_PRINTF("POPA\n");
4216 TRACE_AND_STEP();
4217 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4218 M.x86.R_EDI = pop_long();
4219 M.x86.R_ESI = pop_long();
4220 M.x86.R_EBP = pop_long();
4221 M.x86.R_ESP += 4; /* skip ESP */
4222 M.x86.R_EBX = pop_long();
4223 M.x86.R_EDX = pop_long();
4224 M.x86.R_ECX = pop_long();
4225 M.x86.R_EAX = pop_long();
4226 } else {
4227 M.x86.R_DI = pop_word();
4228 M.x86.R_SI = pop_word();
4229 M.x86.R_BP = pop_word();
4230 M.x86.R_SP += 2; /* skip SP */
4231 M.x86.R_BX = pop_word();
4232 M.x86.R_DX = pop_word();
4233 M.x86.R_CX = pop_word();
4234 M.x86.R_AX = pop_word();
4236 DECODE_CLEAR_SEGOVR();
4237 END_OF_INSTR();
4240 /*opcode 0x62 ILLEGAL OP, calls x86emuOp_illegal_op() */
4241 /*opcode 0x63 ILLEGAL OP, calls x86emuOp_illegal_op() */
4243 /****************************************************************************
4244 REMARKS:
4245 Handles opcode 0x64
4246 ****************************************************************************/
4247 void x86emuOp_segovr_FS(u8 X86EMU_UNUSED(op1))
4249 START_OF_INSTR();
4250 DECODE_PRINTF("FS:\n");
4251 TRACE_AND_STEP();
4252 M.x86.mode |= SYSMODE_SEGOVR_FS;
4254 * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
4255 * opcode subroutines we do not want to do this.
4257 END_OF_INSTR();
4260 /****************************************************************************
4261 REMARKS:
4262 Handles opcode 0x65
4263 ****************************************************************************/
4264 void x86emuOp_segovr_GS(u8 X86EMU_UNUSED(op1))
4266 START_OF_INSTR();
4267 DECODE_PRINTF("GS:\n");
4268 TRACE_AND_STEP();
4269 M.x86.mode |= SYSMODE_SEGOVR_GS;
4271 * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
4272 * opcode subroutines we do not want to do this.
4274 END_OF_INSTR();
4277 /****************************************************************************
4278 REMARKS:
4279 Handles opcode 0x66 - prefix for 32-bit register
4280 ****************************************************************************/
4281 void x86emuOp_prefix_data(u8 X86EMU_UNUSED(op1))
4283 START_OF_INSTR();
4284 DECODE_PRINTF("DATA:\n");
4285 TRACE_AND_STEP();
4286 M.x86.mode |= SYSMODE_PREFIX_DATA;
4287 /* note no DECODE_CLEAR_SEGOVR here. */
4288 END_OF_INSTR();
4291 /****************************************************************************
4292 REMARKS:
4293 Handles opcode 0x67 - prefix for 32-bit address
4294 ****************************************************************************/
4295 void x86emuOp_prefix_addr(u8 X86EMU_UNUSED(op1))
4297 START_OF_INSTR();
4298 DECODE_PRINTF("ADDR:\n");
4299 TRACE_AND_STEP();
4300 M.x86.mode |= SYSMODE_PREFIX_ADDR;
4301 /* note no DECODE_CLEAR_SEGOVR here. */
4302 END_OF_INSTR();
4305 /****************************************************************************
4306 REMARKS:
4307 Handles opcode 0x68
4308 ****************************************************************************/
4309 void x86emuOp_push_word_IMM(u8 X86EMU_UNUSED(op1))
4311 u32 imm;
4313 START_OF_INSTR();
4314 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4315 imm = fetch_long_imm();
4316 } else {
4317 imm = fetch_word_imm();
4319 DECODE_PRINTF2("PUSH\t%x\n", imm);
4320 TRACE_AND_STEP();
4321 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4322 push_long(imm);
4323 } else {
4324 push_word((u16)imm);
4326 DECODE_CLEAR_SEGOVR();
4327 END_OF_INSTR();
4330 /****************************************************************************
4331 REMARKS:
4332 Handles opcode 0x69
4333 ****************************************************************************/
4334 void x86emuOp_imul_word_IMM(u8 X86EMU_UNUSED(op1))
4336 int mod, rl, rh;
4337 uint srcoffset;
4339 START_OF_INSTR();
4340 DECODE_PRINTF("IMUL\t");
4341 FETCH_DECODE_MODRM(mod, rh, rl);
4342 switch (mod) {
4343 case 0:
4344 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4345 u32 *destreg;
4346 u32 srcval;
4347 u32 res_lo,res_hi;
4348 s32 imm;
4350 destreg = DECODE_RM_LONG_REGISTER(rh);
4351 DECODE_PRINTF(",");
4352 srcoffset = decode_rm00_address(rl);
4353 srcval = fetch_data_long(srcoffset);
4354 imm = fetch_long_imm();
4355 DECODE_PRINTF2(",%d\n", (s32)imm);
4356 TRACE_AND_STEP();
4357 imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
4358 if (res_hi != 0) {
4359 SET_FLAG(F_CF);
4360 SET_FLAG(F_OF);
4361 } else {
4362 CLEAR_FLAG(F_CF);
4363 CLEAR_FLAG(F_OF);
4365 *destreg = (u32)res_lo;
4366 } else {
4367 u16 *destreg;
4368 u16 srcval;
4369 u32 res;
4370 s16 imm;
4372 destreg = DECODE_RM_WORD_REGISTER(rh);
4373 DECODE_PRINTF(",");
4374 srcoffset = decode_rm00_address(rl);
4375 srcval = fetch_data_word(srcoffset);
4376 imm = fetch_word_imm();
4377 DECODE_PRINTF2(",%d\n", (s32)imm);
4378 TRACE_AND_STEP();
4379 res = (s16)srcval * (s16)imm;
4380 if (res > 0xFFFF) {
4381 SET_FLAG(F_CF);
4382 SET_FLAG(F_OF);
4383 } else {
4384 CLEAR_FLAG(F_CF);
4385 CLEAR_FLAG(F_OF);
4387 *destreg = (u16)res;
4389 break;
4390 case 1:
4391 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4392 u32 *destreg;
4393 u32 srcval;
4394 u32 res_lo,res_hi;
4395 s32 imm;
4397 destreg = DECODE_RM_LONG_REGISTER(rh);
4398 DECODE_PRINTF(",");
4399 srcoffset = decode_rm01_address(rl);
4400 srcval = fetch_data_long(srcoffset);
4401 imm = fetch_long_imm();
4402 DECODE_PRINTF2(",%d\n", (s32)imm);
4403 TRACE_AND_STEP();
4404 imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
4405 if (res_hi != 0) {
4406 SET_FLAG(F_CF);
4407 SET_FLAG(F_OF);
4408 } else {
4409 CLEAR_FLAG(F_CF);
4410 CLEAR_FLAG(F_OF);
4412 *destreg = (u32)res_lo;
4413 } else {
4414 u16 *destreg;
4415 u16 srcval;
4416 u32 res;
4417 s16 imm;
4419 destreg = DECODE_RM_WORD_REGISTER(rh);
4420 DECODE_PRINTF(",");
4421 srcoffset = decode_rm01_address(rl);
4422 srcval = fetch_data_word(srcoffset);
4423 imm = fetch_word_imm();
4424 DECODE_PRINTF2(",%d\n", (s32)imm);
4425 TRACE_AND_STEP();
4426 res = (s16)srcval * (s16)imm;
4427 if (res > 0xFFFF) {
4428 SET_FLAG(F_CF);
4429 SET_FLAG(F_OF);
4430 } else {
4431 CLEAR_FLAG(F_CF);
4432 CLEAR_FLAG(F_OF);
4434 *destreg = (u16)res;
4436 break;
4437 case 2:
4438 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4439 u32 *destreg;
4440 u32 srcval;
4441 u32 res_lo,res_hi;
4442 s32 imm;
4444 destreg = DECODE_RM_LONG_REGISTER(rh);
4445 DECODE_PRINTF(",");
4446 srcoffset = decode_rm10_address(rl);
4447 srcval = fetch_data_long(srcoffset);
4448 imm = fetch_long_imm();
4449 DECODE_PRINTF2(",%d\n", (s32)imm);
4450 TRACE_AND_STEP();
4451 imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
4452 if (res_hi != 0) {
4453 SET_FLAG(F_CF);
4454 SET_FLAG(F_OF);
4455 } else {
4456 CLEAR_FLAG(F_CF);
4457 CLEAR_FLAG(F_OF);
4459 *destreg = (u32)res_lo;
4460 } else {
4461 u16 *destreg;
4462 u16 srcval;
4463 u32 res;
4464 s16 imm;
4466 destreg = DECODE_RM_WORD_REGISTER(rh);
4467 DECODE_PRINTF(",");
4468 srcoffset = decode_rm10_address(rl);
4469 srcval = fetch_data_word(srcoffset);
4470 imm = fetch_word_imm();
4471 DECODE_PRINTF2(",%d\n", (s32)imm);
4472 TRACE_AND_STEP();
4473 res = (s16)srcval * (s16)imm;
4474 if (res > 0xFFFF) {
4475 SET_FLAG(F_CF);
4476 SET_FLAG(F_OF);
4477 } else {
4478 CLEAR_FLAG(F_CF);
4479 CLEAR_FLAG(F_OF);
4481 *destreg = (u16)res;
4483 break;
4484 case 3: /* register to register */
4485 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4486 u32 *destreg,*srcreg;
4487 u32 res_lo,res_hi;
4488 s32 imm;
4490 destreg = DECODE_RM_LONG_REGISTER(rh);
4491 DECODE_PRINTF(",");
4492 srcreg = DECODE_RM_LONG_REGISTER(rl);
4493 imm = fetch_long_imm();
4494 DECODE_PRINTF2(",%d\n", (s32)imm);
4495 TRACE_AND_STEP();
4496 imul_long_direct(&res_lo,&res_hi,(s32)*srcreg,(s32)imm);
4497 if (res_hi != 0) {
4498 SET_FLAG(F_CF);
4499 SET_FLAG(F_OF);
4500 } else {
4501 CLEAR_FLAG(F_CF);
4502 CLEAR_FLAG(F_OF);
4504 *destreg = (u32)res_lo;
4505 } else {
4506 u16 *destreg,*srcreg;
4507 u32 res;
4508 s16 imm;
4510 destreg = DECODE_RM_WORD_REGISTER(rh);
4511 DECODE_PRINTF(",");
4512 srcreg = DECODE_RM_WORD_REGISTER(rl);
4513 imm = fetch_word_imm();
4514 DECODE_PRINTF2(",%d\n", (s32)imm);
4515 res = (s16)*srcreg * (s16)imm;
4516 if (res > 0xFFFF) {
4517 SET_FLAG(F_CF);
4518 SET_FLAG(F_OF);
4519 } else {
4520 CLEAR_FLAG(F_CF);
4521 CLEAR_FLAG(F_OF);
4523 *destreg = (u16)res;
4525 break;
4527 DECODE_CLEAR_SEGOVR();
4528 END_OF_INSTR();
4531 /****************************************************************************
4532 REMARKS:
4533 Handles opcode 0x6a
4534 ****************************************************************************/
4535 void x86emuOp_push_byte_IMM(u8 X86EMU_UNUSED(op1))
4537 s16 imm;
4539 START_OF_INSTR();
4540 imm = (s8)fetch_byte_imm();
4541 DECODE_PRINTF2("PUSH\t%d\n", imm);
4542 TRACE_AND_STEP();
4543 push_word(imm);
4544 DECODE_CLEAR_SEGOVR();
4545 END_OF_INSTR();
4548 /****************************************************************************
4549 REMARKS:
4550 Handles opcode 0x6b
4551 ****************************************************************************/
4552 void x86emuOp_imul_byte_IMM(u8 X86EMU_UNUSED(op1))
4554 int mod, rl, rh;
4555 uint srcoffset;
4556 s8 imm;
4558 START_OF_INSTR();
4559 DECODE_PRINTF("IMUL\t");
4560 FETCH_DECODE_MODRM(mod, rh, rl);
4561 switch (mod) {
4562 case 0:
4563 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4564 u32 *destreg;
4565 u32 srcval;
4566 u32 res_lo,res_hi;
4568 destreg = DECODE_RM_LONG_REGISTER(rh);
4569 DECODE_PRINTF(",");
4570 srcoffset = decode_rm00_address(rl);
4571 srcval = fetch_data_long(srcoffset);
4572 imm = fetch_byte_imm();
4573 DECODE_PRINTF2(",%d\n", (s32)imm);
4574 TRACE_AND_STEP();
4575 imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
4576 if (res_hi != 0) {
4577 SET_FLAG(F_CF);
4578 SET_FLAG(F_OF);
4579 } else {
4580 CLEAR_FLAG(F_CF);
4581 CLEAR_FLAG(F_OF);
4583 *destreg = (u32)res_lo;
4584 } else {
4585 u16 *destreg;
4586 u16 srcval;
4587 u32 res;
4589 destreg = DECODE_RM_WORD_REGISTER(rh);
4590 DECODE_PRINTF(",");
4591 srcoffset = decode_rm00_address(rl);
4592 srcval = fetch_data_word(srcoffset);
4593 imm = fetch_byte_imm();
4594 DECODE_PRINTF2(",%d\n", (s32)imm);
4595 TRACE_AND_STEP();
4596 res = (s16)srcval * (s16)imm;
4597 if (res > 0xFFFF) {
4598 SET_FLAG(F_CF);
4599 SET_FLAG(F_OF);
4600 } else {
4601 CLEAR_FLAG(F_CF);
4602 CLEAR_FLAG(F_OF);
4604 *destreg = (u16)res;
4606 break;
4607 case 1:
4608 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4609 u32 *destreg;
4610 u32 srcval;
4611 u32 res_lo,res_hi;
4613 destreg = DECODE_RM_LONG_REGISTER(rh);
4614 DECODE_PRINTF(",");
4615 srcoffset = decode_rm01_address(rl);
4616 srcval = fetch_data_long(srcoffset);
4617 imm = fetch_byte_imm();
4618 DECODE_PRINTF2(",%d\n", (s32)imm);
4619 TRACE_AND_STEP();
4620 imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
4621 if (res_hi != 0) {
4622 SET_FLAG(F_CF);
4623 SET_FLAG(F_OF);
4624 } else {
4625 CLEAR_FLAG(F_CF);
4626 CLEAR_FLAG(F_OF);
4628 *destreg = (u32)res_lo;
4629 } else {
4630 u16 *destreg;
4631 u16 srcval;
4632 u32 res;
4634 destreg = DECODE_RM_WORD_REGISTER(rh);
4635 DECODE_PRINTF(",");
4636 srcoffset = decode_rm01_address(rl);
4637 srcval = fetch_data_word(srcoffset);
4638 imm = fetch_byte_imm();
4639 DECODE_PRINTF2(",%d\n", (s32)imm);
4640 TRACE_AND_STEP();
4641 res = (s16)srcval * (s16)imm;
4642 if (res > 0xFFFF) {
4643 SET_FLAG(F_CF);
4644 SET_FLAG(F_OF);
4645 } else {
4646 CLEAR_FLAG(F_CF);
4647 CLEAR_FLAG(F_OF);
4649 *destreg = (u16)res;
4651 break;
4652 case 2:
4653 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4654 u32 *destreg;
4655 u32 srcval;
4656 u32 res_lo,res_hi;
4658 destreg = DECODE_RM_LONG_REGISTER(rh);
4659 DECODE_PRINTF(",");
4660 srcoffset = decode_rm10_address(rl);
4661 srcval = fetch_data_long(srcoffset);
4662 imm = fetch_byte_imm();
4663 DECODE_PRINTF2(",%d\n", (s32)imm);
4664 TRACE_AND_STEP();
4665 imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
4666 if (res_hi != 0) {
4667 SET_FLAG(F_CF);
4668 SET_FLAG(F_OF);
4669 } else {
4670 CLEAR_FLAG(F_CF);
4671 CLEAR_FLAG(F_OF);
4673 *destreg = (u32)res_lo;
4674 } else {
4675 u16 *destreg;
4676 u16 srcval;
4677 u32 res;
4679 destreg = DECODE_RM_WORD_REGISTER(rh);
4680 DECODE_PRINTF(",");
4681 srcoffset = decode_rm10_address(rl);
4682 srcval = fetch_data_word(srcoffset);
4683 imm = fetch_byte_imm();
4684 DECODE_PRINTF2(",%d\n", (s32)imm);
4685 TRACE_AND_STEP();
4686 res = (s16)srcval * (s16)imm;
4687 if (res > 0xFFFF) {
4688 SET_FLAG(F_CF);
4689 SET_FLAG(F_OF);
4690 } else {
4691 CLEAR_FLAG(F_CF);
4692 CLEAR_FLAG(F_OF);
4694 *destreg = (u16)res;
4696 break;
4697 case 3: /* register to register */
4698 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4699 u32 *destreg,*srcreg;
4700 u32 res_lo,res_hi;
4702 destreg = DECODE_RM_LONG_REGISTER(rh);
4703 DECODE_PRINTF(",");
4704 srcreg = DECODE_RM_LONG_REGISTER(rl);
4705 imm = fetch_byte_imm();
4706 DECODE_PRINTF2(",%d\n", (s32)imm);
4707 TRACE_AND_STEP();
4708 imul_long_direct(&res_lo,&res_hi,(s32)*srcreg,(s32)imm);
4709 if (res_hi != 0) {
4710 SET_FLAG(F_CF);
4711 SET_FLAG(F_OF);
4712 } else {
4713 CLEAR_FLAG(F_CF);
4714 CLEAR_FLAG(F_OF);
4716 *destreg = (u32)res_lo;
4717 } else {
4718 u16 *destreg,*srcreg;
4719 u32 res;
4721 destreg = DECODE_RM_WORD_REGISTER(rh);
4722 DECODE_PRINTF(",");
4723 srcreg = DECODE_RM_WORD_REGISTER(rl);
4724 imm = fetch_byte_imm();
4725 DECODE_PRINTF2(",%d\n", (s32)imm);
4726 res = (s16)*srcreg * (s16)imm;
4727 if (res > 0xFFFF) {
4728 SET_FLAG(F_CF);
4729 SET_FLAG(F_OF);
4730 } else {
4731 CLEAR_FLAG(F_CF);
4732 CLEAR_FLAG(F_OF);
4734 *destreg = (u16)res;
4736 break;
4738 DECODE_CLEAR_SEGOVR();
4739 END_OF_INSTR();
4742 /****************************************************************************
4743 REMARKS:
4744 Handles opcode 0x6c
4745 ****************************************************************************/
4746 void x86emuOp_ins_byte(u8 X86EMU_UNUSED(op1))
4748 START_OF_INSTR();
4749 DECODE_PRINTF("INSB\n");
4750 ins(1);
4751 TRACE_AND_STEP();
4752 DECODE_CLEAR_SEGOVR();
4753 END_OF_INSTR();
4756 /****************************************************************************
4757 REMARKS:
4758 Handles opcode 0x6d
4759 ****************************************************************************/
4760 void x86emuOp_ins_word(u8 X86EMU_UNUSED(op1))
4762 START_OF_INSTR();
4763 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4764 DECODE_PRINTF("INSD\n");
4765 ins(4);
4766 } else {
4767 DECODE_PRINTF("INSW\n");
4768 ins(2);
4770 TRACE_AND_STEP();
4771 DECODE_CLEAR_SEGOVR();
4772 END_OF_INSTR();
4775 /****************************************************************************
4776 REMARKS:
4777 Handles opcode 0x6e
4778 ****************************************************************************/
4779 void x86emuOp_outs_byte(u8 X86EMU_UNUSED(op1))
4781 START_OF_INSTR();
4782 DECODE_PRINTF("OUTSB\n");
4783 outs(1);
4784 TRACE_AND_STEP();
4785 DECODE_CLEAR_SEGOVR();
4786 END_OF_INSTR();
4789 /****************************************************************************
4790 REMARKS:
4791 Handles opcode 0x6f
4792 ****************************************************************************/
4793 void x86emuOp_outs_word(u8 X86EMU_UNUSED(op1))
4795 START_OF_INSTR();
4796 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4797 DECODE_PRINTF("OUTSD\n");
4798 outs(4);
4799 } else {
4800 DECODE_PRINTF("OUTSW\n");
4801 outs(2);
4803 TRACE_AND_STEP();
4804 DECODE_CLEAR_SEGOVR();
4805 END_OF_INSTR();
4808 /****************************************************************************
4809 REMARKS:
4810 Handles opcode 0x70
4811 ****************************************************************************/
4812 void x86emuOp_jump_near_O(u8 X86EMU_UNUSED(op1))
4814 s8 offset;
4815 u16 target;
4817 /* jump to byte offset if overflow flag is set */
4818 START_OF_INSTR();
4819 DECODE_PRINTF("JO\t");
4820 offset = (s8)fetch_byte_imm();
4821 target = (u16)(M.x86.R_IP + (s16)offset);
4822 DECODE_PRINTF2("%x\n", target);
4823 TRACE_AND_STEP();
4824 if (ACCESS_FLAG(F_OF))
4825 M.x86.R_IP = target;
4826 DECODE_CLEAR_SEGOVR();
4827 END_OF_INSTR();
4830 /****************************************************************************
4831 REMARKS:
4832 Handles opcode 0x71
4833 ****************************************************************************/
4834 void x86emuOp_jump_near_NO(u8 X86EMU_UNUSED(op1))
4836 s8 offset;
4837 u16 target;
4839 /* jump to byte offset if overflow is not set */
4840 START_OF_INSTR();
4841 DECODE_PRINTF("JNO\t");
4842 offset = (s8)fetch_byte_imm();
4843 target = (u16)(M.x86.R_IP + (s16)offset);
4844 DECODE_PRINTF2("%x\n", target);
4845 TRACE_AND_STEP();
4846 if (!ACCESS_FLAG(F_OF))
4847 M.x86.R_IP = target;
4848 DECODE_CLEAR_SEGOVR();
4849 END_OF_INSTR();
4852 /****************************************************************************
4853 REMARKS:
4854 Handles opcode 0x72
4855 ****************************************************************************/
4856 void x86emuOp_jump_near_B(u8 X86EMU_UNUSED(op1))
4858 s8 offset;
4859 u16 target;
4861 /* jump to byte offset if carry flag is set. */
4862 START_OF_INSTR();
4863 DECODE_PRINTF("JB\t");
4864 offset = (s8)fetch_byte_imm();
4865 target = (u16)(M.x86.R_IP + (s16)offset);
4866 DECODE_PRINTF2("%x\n", target);
4867 TRACE_AND_STEP();
4868 if (ACCESS_FLAG(F_CF))
4869 M.x86.R_IP = target;
4870 DECODE_CLEAR_SEGOVR();
4871 END_OF_INSTR();
4874 /****************************************************************************
4875 REMARKS:
4876 Handles opcode 0x73
4877 ****************************************************************************/
4878 void x86emuOp_jump_near_NB(u8 X86EMU_UNUSED(op1))
4880 s8 offset;
4881 u16 target;
4883 /* jump to byte offset if carry flag is clear. */
4884 START_OF_INSTR();
4885 DECODE_PRINTF("JNB\t");
4886 offset = (s8)fetch_byte_imm();
4887 target = (u16)(M.x86.R_IP + (s16)offset);
4888 DECODE_PRINTF2("%x\n", target);
4889 TRACE_AND_STEP();
4890 if (!ACCESS_FLAG(F_CF))
4891 M.x86.R_IP = target;
4892 DECODE_CLEAR_SEGOVR();
4893 END_OF_INSTR();
4896 /****************************************************************************
4897 REMARKS:
4898 Handles opcode 0x74
4899 ****************************************************************************/
4900 void x86emuOp_jump_near_Z(u8 X86EMU_UNUSED(op1))
4902 s8 offset;
4903 u16 target;
4905 /* jump to byte offset if zero flag is set. */
4906 START_OF_INSTR();
4907 DECODE_PRINTF("JZ\t");
4908 offset = (s8)fetch_byte_imm();
4909 target = (u16)(M.x86.R_IP + (s16)offset);
4910 DECODE_PRINTF2("%x\n", target);
4911 TRACE_AND_STEP();
4912 if (ACCESS_FLAG(F_ZF))
4913 M.x86.R_IP = target;
4914 DECODE_CLEAR_SEGOVR();
4915 END_OF_INSTR();
4918 /****************************************************************************
4919 REMARKS:
4920 Handles opcode 0x75
4921 ****************************************************************************/
4922 void x86emuOp_jump_near_NZ(u8 X86EMU_UNUSED(op1))
4924 s8 offset;
4925 u16 target;
4927 /* jump to byte offset if zero flag is clear. */
4928 START_OF_INSTR();
4929 DECODE_PRINTF("JNZ\t");
4930 offset = (s8)fetch_byte_imm();
4931 target = (u16)(M.x86.R_IP + (s16)offset);
4932 DECODE_PRINTF2("%x\n", target);
4933 TRACE_AND_STEP();
4934 if (!ACCESS_FLAG(F_ZF))
4935 M.x86.R_IP = target;
4936 DECODE_CLEAR_SEGOVR();
4937 END_OF_INSTR();
4940 /****************************************************************************
4941 REMARKS:
4942 Handles opcode 0x76
4943 ****************************************************************************/
4944 void x86emuOp_jump_near_BE(u8 X86EMU_UNUSED(op1))
4946 s8 offset;
4947 u16 target;
4949 /* jump to byte offset if carry flag is set or if the zero
4950 flag is set. */
4951 START_OF_INSTR();
4952 DECODE_PRINTF("JBE\t");
4953 offset = (s8)fetch_byte_imm();
4954 target = (u16)(M.x86.R_IP + (s16)offset);
4955 DECODE_PRINTF2("%x\n", target);
4956 TRACE_AND_STEP();
4957 if (ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF))
4958 M.x86.R_IP = target;
4959 DECODE_CLEAR_SEGOVR();
4960 END_OF_INSTR();
4963 /****************************************************************************
4964 REMARKS:
4965 Handles opcode 0x77
4966 ****************************************************************************/
4967 void x86emuOp_jump_near_NBE(u8 X86EMU_UNUSED(op1))
4969 s8 offset;
4970 u16 target;
4972 /* jump to byte offset if carry flag is clear and if the zero
4973 flag is clear */
4974 START_OF_INSTR();
4975 DECODE_PRINTF("JNBE\t");
4976 offset = (s8)fetch_byte_imm();
4977 target = (u16)(M.x86.R_IP + (s16)offset);
4978 DECODE_PRINTF2("%x\n", target);
4979 TRACE_AND_STEP();
4980 if (!(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF)))
4981 M.x86.R_IP = target;
4982 DECODE_CLEAR_SEGOVR();
4983 END_OF_INSTR();
4986 /****************************************************************************
4987 REMARKS:
4988 Handles opcode 0x78
4989 ****************************************************************************/
4990 void x86emuOp_jump_near_S(u8 X86EMU_UNUSED(op1))
4992 s8 offset;
4993 u16 target;
4995 /* jump to byte offset if sign flag is set */
4996 START_OF_INSTR();
4997 DECODE_PRINTF("JS\t");
4998 offset = (s8)fetch_byte_imm();
4999 target = (u16)(M.x86.R_IP + (s16)offset);
5000 DECODE_PRINTF2("%x\n", target);
5001 TRACE_AND_STEP();
5002 if (ACCESS_FLAG(F_SF))
5003 M.x86.R_IP = target;
5004 DECODE_CLEAR_SEGOVR();
5005 END_OF_INSTR();
5008 /****************************************************************************
5009 REMARKS:
5010 Handles opcode 0x79
5011 ****************************************************************************/
5012 void x86emuOp_jump_near_NS(u8 X86EMU_UNUSED(op1))
5014 s8 offset;
5015 u16 target;
5017 /* jump to byte offset if sign flag is clear */
5018 START_OF_INSTR();
5019 DECODE_PRINTF("JNS\t");
5020 offset = (s8)fetch_byte_imm();
5021 target = (u16)(M.x86.R_IP + (s16)offset);
5022 DECODE_PRINTF2("%x\n", target);
5023 TRACE_AND_STEP();
5024 if (!ACCESS_FLAG(F_SF))
5025 M.x86.R_IP = target;
5026 DECODE_CLEAR_SEGOVR();
5027 END_OF_INSTR();
5030 /****************************************************************************
5031 REMARKS:
5032 Handles opcode 0x7a
5033 ****************************************************************************/
5034 void x86emuOp_jump_near_P(u8 X86EMU_UNUSED(op1))
5036 s8 offset;
5037 u16 target;
5039 /* jump to byte offset if parity flag is set (even parity) */
5040 START_OF_INSTR();
5041 DECODE_PRINTF("JP\t");
5042 offset = (s8)fetch_byte_imm();
5043 target = (u16)(M.x86.R_IP + (s16)offset);
5044 DECODE_PRINTF2("%x\n", target);
5045 TRACE_AND_STEP();
5046 if (ACCESS_FLAG(F_PF))
5047 M.x86.R_IP = target;
5048 DECODE_CLEAR_SEGOVR();
5049 END_OF_INSTR();
5052 /****************************************************************************
5053 REMARKS:
5054 Handles opcode 0x7b
5055 ****************************************************************************/
5056 void x86emuOp_jump_near_NP(u8 X86EMU_UNUSED(op1))
5058 s8 offset;
5059 u16 target;
5061 /* jump to byte offset if parity flag is clear (odd parity) */
5062 START_OF_INSTR();
5063 DECODE_PRINTF("JNP\t");
5064 offset = (s8)fetch_byte_imm();
5065 target = (u16)(M.x86.R_IP + (s16)offset);
5066 DECODE_PRINTF2("%x\n", target);
5067 TRACE_AND_STEP();
5068 if (!ACCESS_FLAG(F_PF))
5069 M.x86.R_IP = target;
5070 DECODE_CLEAR_SEGOVR();
5071 END_OF_INSTR();
5074 /****************************************************************************
5075 REMARKS:
5076 Handles opcode 0x7c
5077 ****************************************************************************/
5078 void x86emuOp_jump_near_L(u8 X86EMU_UNUSED(op1))
5080 s8 offset;
5081 u16 target;
5082 int sf, of;
5084 /* jump to byte offset if sign flag not equal to overflow flag. */
5085 START_OF_INSTR();
5086 DECODE_PRINTF("JL\t");
5087 offset = (s8)fetch_byte_imm();
5088 target = (u16)(M.x86.R_IP + (s16)offset);
5089 DECODE_PRINTF2("%x\n", target);
5090 TRACE_AND_STEP();
5091 sf = ACCESS_FLAG(F_SF) != 0;
5092 of = ACCESS_FLAG(F_OF) != 0;
5093 if (sf ^ of)
5094 M.x86.R_IP = target;
5095 DECODE_CLEAR_SEGOVR();
5096 END_OF_INSTR();
5099 /****************************************************************************
5100 REMARKS:
5101 Handles opcode 0x7d
5102 ****************************************************************************/
5103 void x86emuOp_jump_near_NL(u8 X86EMU_UNUSED(op1))
5105 s8 offset;
5106 u16 target;
5107 int sf, of;
5109 /* jump to byte offset if sign flag not equal to overflow flag. */
5110 START_OF_INSTR();
5111 DECODE_PRINTF("JNL\t");
5112 offset = (s8)fetch_byte_imm();
5113 target = (u16)(M.x86.R_IP + (s16)offset);
5114 DECODE_PRINTF2("%x\n", target);
5115 TRACE_AND_STEP();
5116 sf = ACCESS_FLAG(F_SF) != 0;
5117 of = ACCESS_FLAG(F_OF) != 0;
5118 /* note: inverse of above, but using == instead of xor. */
5119 if (sf == of)
5120 M.x86.R_IP = target;
5121 DECODE_CLEAR_SEGOVR();
5122 END_OF_INSTR();
5125 /****************************************************************************
5126 REMARKS:
5127 Handles opcode 0x7e
5128 ****************************************************************************/
5129 void x86emuOp_jump_near_LE(u8 X86EMU_UNUSED(op1))
5131 s8 offset;
5132 u16 target;
5133 int sf, of;
5135 /* jump to byte offset if sign flag not equal to overflow flag
5136 or the zero flag is set */
5137 START_OF_INSTR();
5138 DECODE_PRINTF("JLE\t");
5139 offset = (s8)fetch_byte_imm();
5140 target = (u16)(M.x86.R_IP + (s16)offset);
5141 DECODE_PRINTF2("%x\n", target);
5142 TRACE_AND_STEP();
5143 sf = ACCESS_FLAG(F_SF) != 0;
5144 of = ACCESS_FLAG(F_OF) != 0;
5145 if ((sf ^ of) || ACCESS_FLAG(F_ZF))
5146 M.x86.R_IP = target;
5147 DECODE_CLEAR_SEGOVR();
5148 END_OF_INSTR();
5151 /****************************************************************************
5152 REMARKS:
5153 Handles opcode 0x7f
5154 ****************************************************************************/
5155 void x86emuOp_jump_near_NLE(u8 X86EMU_UNUSED(op1))
5157 s8 offset;
5158 u16 target;
5159 int sf, of;
5161 /* jump to byte offset if sign flag equal to overflow flag.
5162 and the zero flag is clear */
5163 START_OF_INSTR();
5164 DECODE_PRINTF("JNLE\t");
5165 offset = (s8)fetch_byte_imm();
5166 target = (u16)(M.x86.R_IP + (s16)offset);
5167 DECODE_PRINTF2("%x\n", target);
5168 TRACE_AND_STEP();
5169 sf = ACCESS_FLAG(F_SF) != 0;
5170 of = ACCESS_FLAG(F_OF) != 0;
5171 if ((sf == of) && !ACCESS_FLAG(F_ZF))
5172 M.x86.R_IP = target;
5173 DECODE_CLEAR_SEGOVR();
5174 END_OF_INSTR();
5177 static u8 (*opc80_byte_operation[])(u8 d, u8 s) =
5179 add_byte, /* 00 */
5180 or_byte, /* 01 */
5181 adc_byte, /* 02 */
5182 sbb_byte, /* 03 */
5183 and_byte, /* 04 */
5184 sub_byte, /* 05 */
5185 xor_byte, /* 06 */
5186 cmp_byte, /* 07 */
5189 /****************************************************************************
5190 REMARKS:
5191 Handles opcode 0x80
5192 ****************************************************************************/
5193 void x86emuOp_opc80_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
5195 int mod, rl, rh;
5196 u8 *destreg;
5197 uint destoffset;
5198 u8 imm;
5199 u8 destval;
5202 * Weirdo special case instruction format. Part of the opcode
5203 * held below in "RH". Doubly nested case would result, except
5204 * that the decoded instruction
5206 START_OF_INSTR();
5207 FETCH_DECODE_MODRM(mod, rh, rl);
5208 #ifdef DEBUG
5209 if (DEBUG_DECODE()) {
5211 switch (rh) {
5212 case 0:
5213 DECODE_PRINTF("ADD\t");
5214 break;
5215 case 1:
5216 DECODE_PRINTF("OR\t");
5217 break;
5218 case 2:
5219 DECODE_PRINTF("ADC\t");
5220 break;
5221 case 3:
5222 DECODE_PRINTF("SBB\t");
5223 break;
5224 case 4:
5225 DECODE_PRINTF("AND\t");
5226 break;
5227 case 5:
5228 DECODE_PRINTF("SUB\t");
5229 break;
5230 case 6:
5231 DECODE_PRINTF("XOR\t");
5232 break;
5233 case 7:
5234 DECODE_PRINTF("CMP\t");
5235 break;
5238 #endif
5239 /* know operation, decode the mod byte to find the addressing
5240 mode. */
5241 switch (mod) {
5242 case 0:
5243 DECODE_PRINTF("BYTE PTR ");
5244 destoffset = decode_rm00_address(rl);
5245 DECODE_PRINTF(",");
5246 destval = fetch_data_byte(destoffset);
5247 imm = fetch_byte_imm();
5248 DECODE_PRINTF2("%x\n", imm);
5249 TRACE_AND_STEP();
5250 destval = (*opc80_byte_operation[rh]) (destval, imm);
5251 if (rh != 7)
5252 store_data_byte(destoffset, destval);
5253 break;
5254 case 1:
5255 DECODE_PRINTF("BYTE PTR ");
5256 destoffset = decode_rm01_address(rl);
5257 DECODE_PRINTF(",");
5258 destval = fetch_data_byte(destoffset);
5259 imm = fetch_byte_imm();
5260 DECODE_PRINTF2("%x\n", imm);
5261 TRACE_AND_STEP();
5262 destval = (*opc80_byte_operation[rh]) (destval, imm);
5263 if (rh != 7)
5264 store_data_byte(destoffset, destval);
5265 break;
5266 case 2:
5267 DECODE_PRINTF("BYTE PTR ");
5268 destoffset = decode_rm10_address(rl);
5269 DECODE_PRINTF(",");
5270 destval = fetch_data_byte(destoffset);
5271 imm = fetch_byte_imm();
5272 DECODE_PRINTF2("%x\n", imm);
5273 TRACE_AND_STEP();
5274 destval = (*opc80_byte_operation[rh]) (destval, imm);
5275 if (rh != 7)
5276 store_data_byte(destoffset, destval);
5277 break;
5278 case 3: /* register to register */
5279 destreg = DECODE_RM_BYTE_REGISTER(rl);
5280 DECODE_PRINTF(",");
5281 imm = fetch_byte_imm();
5282 DECODE_PRINTF2("%x\n", imm);
5283 TRACE_AND_STEP();
5284 destval = (*opc80_byte_operation[rh]) (*destreg, imm);
5285 if (rh != 7)
5286 *destreg = destval;
5287 break;
5289 DECODE_CLEAR_SEGOVR();
5290 END_OF_INSTR();
5293 static u16 (*opc81_word_operation[])(u16 d, u16 s) =
5295 add_word, /*00 */
5296 or_word, /*01 */
5297 adc_word, /*02 */
5298 sbb_word, /*03 */
5299 and_word, /*04 */
5300 sub_word, /*05 */
5301 xor_word, /*06 */
5302 cmp_word, /*07 */
5305 static u32 (*opc81_long_operation[])(u32 d, u32 s) =
5307 add_long, /*00 */
5308 or_long, /*01 */
5309 adc_long, /*02 */
5310 sbb_long, /*03 */
5311 and_long, /*04 */
5312 sub_long, /*05 */
5313 xor_long, /*06 */
5314 cmp_long, /*07 */
5317 /****************************************************************************
5318 REMARKS:
5319 Handles opcode 0x81
5320 ****************************************************************************/
5321 void x86emuOp_opc81_word_RM_IMM(u8 X86EMU_UNUSED(op1))
5323 int mod, rl, rh;
5324 uint destoffset;
5327 * Weirdo special case instruction format. Part of the opcode
5328 * held below in "RH". Doubly nested case would result, except
5329 * that the decoded instruction
5331 START_OF_INSTR();
5332 FETCH_DECODE_MODRM(mod, rh, rl);
5333 #ifdef DEBUG
5334 if (DEBUG_DECODE()) {
5336 switch (rh) {
5337 case 0:
5338 DECODE_PRINTF("ADD\t");
5339 break;
5340 case 1:
5341 DECODE_PRINTF("OR\t");
5342 break;
5343 case 2:
5344 DECODE_PRINTF("ADC\t");
5345 break;
5346 case 3:
5347 DECODE_PRINTF("SBB\t");
5348 break;
5349 case 4:
5350 DECODE_PRINTF("AND\t");
5351 break;
5352 case 5:
5353 DECODE_PRINTF("SUB\t");
5354 break;
5355 case 6:
5356 DECODE_PRINTF("XOR\t");
5357 break;
5358 case 7:
5359 DECODE_PRINTF("CMP\t");
5360 break;
5363 #endif
5365 * Know operation, decode the mod byte to find the addressing
5366 * mode.
5368 switch (mod) {
5369 case 0:
5370 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5371 u32 destval,imm;
5373 DECODE_PRINTF("DWORD PTR ");
5374 destoffset = decode_rm00_address(rl);
5375 DECODE_PRINTF(",");
5376 destval = fetch_data_long(destoffset);
5377 imm = fetch_long_imm();
5378 DECODE_PRINTF2("%x\n", imm);
5379 TRACE_AND_STEP();
5380 destval = (*opc81_long_operation[rh]) (destval, imm);
5381 if (rh != 7)
5382 store_data_long(destoffset, destval);
5383 } else {
5384 u16 destval,imm;
5386 DECODE_PRINTF("WORD PTR ");
5387 destoffset = decode_rm00_address(rl);
5388 DECODE_PRINTF(",");
5389 destval = fetch_data_word(destoffset);
5390 imm = fetch_word_imm();
5391 DECODE_PRINTF2("%x\n", imm);
5392 TRACE_AND_STEP();
5393 destval = (*opc81_word_operation[rh]) (destval, imm);
5394 if (rh != 7)
5395 store_data_word(destoffset, destval);
5397 break;
5398 case 1:
5399 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5400 u32 destval,imm;
5402 DECODE_PRINTF("DWORD PTR ");
5403 destoffset = decode_rm01_address(rl);
5404 DECODE_PRINTF(",");
5405 destval = fetch_data_long(destoffset);
5406 imm = fetch_long_imm();
5407 DECODE_PRINTF2("%x\n", imm);
5408 TRACE_AND_STEP();
5409 destval = (*opc81_long_operation[rh]) (destval, imm);
5410 if (rh != 7)
5411 store_data_long(destoffset, destval);
5412 } else {
5413 u16 destval,imm;
5415 DECODE_PRINTF("WORD PTR ");
5416 destoffset = decode_rm01_address(rl);
5417 DECODE_PRINTF(",");
5418 destval = fetch_data_word(destoffset);
5419 imm = fetch_word_imm();
5420 DECODE_PRINTF2("%x\n", imm);
5421 TRACE_AND_STEP();
5422 destval = (*opc81_word_operation[rh]) (destval, imm);
5423 if (rh != 7)
5424 store_data_word(destoffset, destval);
5426 break;
5427 case 2:
5428 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5429 u32 destval,imm;
5431 DECODE_PRINTF("DWORD PTR ");
5432 destoffset = decode_rm10_address(rl);
5433 DECODE_PRINTF(",");
5434 destval = fetch_data_long(destoffset);
5435 imm = fetch_long_imm();
5436 DECODE_PRINTF2("%x\n", imm);
5437 TRACE_AND_STEP();
5438 destval = (*opc81_long_operation[rh]) (destval, imm);
5439 if (rh != 7)
5440 store_data_long(destoffset, destval);
5441 } else {
5442 u16 destval,imm;
5444 DECODE_PRINTF("WORD PTR ");
5445 destoffset = decode_rm10_address(rl);
5446 DECODE_PRINTF(",");
5447 destval = fetch_data_word(destoffset);
5448 imm = fetch_word_imm();
5449 DECODE_PRINTF2("%x\n", imm);
5450 TRACE_AND_STEP();
5451 destval = (*opc81_word_operation[rh]) (destval, imm);
5452 if (rh != 7)
5453 store_data_word(destoffset, destval);
5455 break;
5456 case 3: /* register to register */
5457 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5458 u32 *destreg;
5459 u32 destval,imm;
5461 destreg = DECODE_RM_LONG_REGISTER(rl);
5462 DECODE_PRINTF(",");
5463 imm = fetch_long_imm();
5464 DECODE_PRINTF2("%x\n", imm);
5465 TRACE_AND_STEP();
5466 destval = (*opc81_long_operation[rh]) (*destreg, imm);
5467 if (rh != 7)
5468 *destreg = destval;
5469 } else {
5470 u16 *destreg;
5471 u16 destval,imm;
5473 destreg = DECODE_RM_WORD_REGISTER(rl);
5474 DECODE_PRINTF(",");
5475 imm = fetch_word_imm();
5476 DECODE_PRINTF2("%x\n", imm);
5477 TRACE_AND_STEP();
5478 destval = (*opc81_word_operation[rh]) (*destreg, imm);
5479 if (rh != 7)
5480 *destreg = destval;
5482 break;
5484 DECODE_CLEAR_SEGOVR();
5485 END_OF_INSTR();
5488 static u8 (*opc82_byte_operation[])(u8 s, u8 d) =
5490 add_byte, /*00 */
5491 or_byte, /*01 *//*YYY UNUSED ???? */
5492 adc_byte, /*02 */
5493 sbb_byte, /*03 */
5494 and_byte, /*04 *//*YYY UNUSED ???? */
5495 sub_byte, /*05 */
5496 xor_byte, /*06 *//*YYY UNUSED ???? */
5497 cmp_byte, /*07 */
5500 /****************************************************************************
5501 REMARKS:
5502 Handles opcode 0x82
5503 ****************************************************************************/
5504 void x86emuOp_opc82_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
5506 int mod, rl, rh;
5507 u8 *destreg;
5508 uint destoffset;
5509 u8 imm;
5510 u8 destval;
5513 * Weirdo special case instruction format. Part of the opcode
5514 * held below in "RH". Doubly nested case would result, except
5515 * that the decoded instruction Similar to opcode 81, except that
5516 * the immediate byte is sign extended to a word length.
5518 START_OF_INSTR();
5519 FETCH_DECODE_MODRM(mod, rh, rl);
5520 #ifdef DEBUG
5521 if (DEBUG_DECODE()) {
5522 switch (rh) {
5523 case 0:
5524 DECODE_PRINTF("ADD\t");
5525 break;
5526 case 1:
5527 DECODE_PRINTF("OR\t");
5528 break;
5529 case 2:
5530 DECODE_PRINTF("ADC\t");
5531 break;
5532 case 3:
5533 DECODE_PRINTF("SBB\t");
5534 break;
5535 case 4:
5536 DECODE_PRINTF("AND\t");
5537 break;
5538 case 5:
5539 DECODE_PRINTF("SUB\t");
5540 break;
5541 case 6:
5542 DECODE_PRINTF("XOR\t");
5543 break;
5544 case 7:
5545 DECODE_PRINTF("CMP\t");
5546 break;
5549 #endif
5550 /* know operation, decode the mod byte to find the addressing
5551 mode. */
5552 switch (mod) {
5553 case 0:
5554 DECODE_PRINTF("BYTE PTR ");
5555 destoffset = decode_rm00_address(rl);
5556 destval = fetch_data_byte(destoffset);
5557 imm = fetch_byte_imm();
5558 DECODE_PRINTF2(",%x\n", imm);
5559 TRACE_AND_STEP();
5560 destval = (*opc82_byte_operation[rh]) (destval, imm);
5561 if (rh != 7)
5562 store_data_byte(destoffset, destval);
5563 break;
5564 case 1:
5565 DECODE_PRINTF("BYTE PTR ");
5566 destoffset = decode_rm01_address(rl);
5567 destval = fetch_data_byte(destoffset);
5568 imm = fetch_byte_imm();
5569 DECODE_PRINTF2(",%x\n", imm);
5570 TRACE_AND_STEP();
5571 destval = (*opc82_byte_operation[rh]) (destval, imm);
5572 if (rh != 7)
5573 store_data_byte(destoffset, destval);
5574 break;
5575 case 2:
5576 DECODE_PRINTF("BYTE PTR ");
5577 destoffset = decode_rm10_address(rl);
5578 destval = fetch_data_byte(destoffset);
5579 imm = fetch_byte_imm();
5580 DECODE_PRINTF2(",%x\n", imm);
5581 TRACE_AND_STEP();
5582 destval = (*opc82_byte_operation[rh]) (destval, imm);
5583 if (rh != 7)
5584 store_data_byte(destoffset, destval);
5585 break;
5586 case 3: /* register to register */
5587 destreg = DECODE_RM_BYTE_REGISTER(rl);
5588 imm = fetch_byte_imm();
5589 DECODE_PRINTF2(",%x\n", imm);
5590 TRACE_AND_STEP();
5591 destval = (*opc82_byte_operation[rh]) (*destreg, imm);
5592 if (rh != 7)
5593 *destreg = destval;
5594 break;
5596 DECODE_CLEAR_SEGOVR();
5597 END_OF_INSTR();
5600 static u16 (*opc83_word_operation[])(u16 s, u16 d) =
5602 add_word, /*00 */
5603 or_word, /*01 *//*YYY UNUSED ???? */
5604 adc_word, /*02 */
5605 sbb_word, /*03 */
5606 and_word, /*04 *//*YYY UNUSED ???? */
5607 sub_word, /*05 */
5608 xor_word, /*06 *//*YYY UNUSED ???? */
5609 cmp_word, /*07 */
5612 static u32 (*opc83_long_operation[])(u32 s, u32 d) =
5614 add_long, /*00 */
5615 or_long, /*01 *//*YYY UNUSED ???? */
5616 adc_long, /*02 */
5617 sbb_long, /*03 */
5618 and_long, /*04 *//*YYY UNUSED ???? */
5619 sub_long, /*05 */
5620 xor_long, /*06 *//*YYY UNUSED ???? */
5621 cmp_long, /*07 */
5624 /****************************************************************************
5625 REMARKS:
5626 Handles opcode 0x83
5627 ****************************************************************************/
5628 void x86emuOp_opc83_word_RM_IMM(u8 X86EMU_UNUSED(op1))
5630 int mod, rl, rh;
5631 uint destoffset;
5634 * Weirdo special case instruction format. Part of the opcode
5635 * held below in "RH". Doubly nested case would result, except
5636 * that the decoded instruction Similar to opcode 81, except that
5637 * the immediate byte is sign extended to a word length.
5639 START_OF_INSTR();
5640 FETCH_DECODE_MODRM(mod, rh, rl);
5641 #ifdef DEBUG
5642 if (DEBUG_DECODE()) {
5643 switch (rh) {
5644 case 0:
5645 DECODE_PRINTF("ADD\t");
5646 break;
5647 case 1:
5648 DECODE_PRINTF("OR\t");
5649 break;
5650 case 2:
5651 DECODE_PRINTF("ADC\t");
5652 break;
5653 case 3:
5654 DECODE_PRINTF("SBB\t");
5655 break;
5656 case 4:
5657 DECODE_PRINTF("AND\t");
5658 break;
5659 case 5:
5660 DECODE_PRINTF("SUB\t");
5661 break;
5662 case 6:
5663 DECODE_PRINTF("XOR\t");
5664 break;
5665 case 7:
5666 DECODE_PRINTF("CMP\t");
5667 break;
5670 #endif
5671 /* know operation, decode the mod byte to find the addressing
5672 mode. */
5673 switch (mod) {
5674 case 0:
5675 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5676 u32 destval,imm;
5678 DECODE_PRINTF("DWORD PTR ");
5679 destoffset = decode_rm00_address(rl);
5680 destval = fetch_data_long(destoffset);
5681 imm = (s8) fetch_byte_imm();
5682 DECODE_PRINTF2(",%x\n", imm);
5683 TRACE_AND_STEP();
5684 destval = (*opc83_long_operation[rh]) (destval, imm);
5685 if (rh != 7)
5686 store_data_long(destoffset, destval);
5687 } else {
5688 u16 destval,imm;
5690 DECODE_PRINTF("WORD PTR ");
5691 destoffset = decode_rm00_address(rl);
5692 destval = fetch_data_word(destoffset);
5693 imm = (s8) fetch_byte_imm();
5694 DECODE_PRINTF2(",%x\n", imm);
5695 TRACE_AND_STEP();
5696 destval = (*opc83_word_operation[rh]) (destval, imm);
5697 if (rh != 7)
5698 store_data_word(destoffset, destval);
5700 break;
5701 case 1:
5702 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5703 u32 destval,imm;
5705 DECODE_PRINTF("DWORD PTR ");
5706 destoffset = decode_rm01_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_rm01_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 2:
5729 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5730 u32 destval,imm;
5732 DECODE_PRINTF("DWORD PTR ");
5733 destoffset = decode_rm10_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_rm10_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 3: /* register to register */
5756 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5757 u32 *destreg;
5758 u32 destval,imm;
5760 destreg = DECODE_RM_LONG_REGISTER(rl);
5761 imm = (s8) fetch_byte_imm();
5762 DECODE_PRINTF2(",%x\n", imm);
5763 TRACE_AND_STEP();
5764 destval = (*opc83_long_operation[rh]) (*destreg, imm);
5765 if (rh != 7)
5766 *destreg = destval;
5767 } else {
5768 u16 *destreg;
5769 u16 destval,imm;
5771 destreg = DECODE_RM_WORD_REGISTER(rl);
5772 imm = (s8) fetch_byte_imm();
5773 DECODE_PRINTF2(",%x\n", imm);
5774 TRACE_AND_STEP();
5775 destval = (*opc83_word_operation[rh]) (*destreg, imm);
5776 if (rh != 7)
5777 *destreg = destval;
5779 break;
5781 DECODE_CLEAR_SEGOVR();
5782 END_OF_INSTR();
5785 /****************************************************************************
5786 REMARKS:
5787 Handles opcode 0x84
5788 ****************************************************************************/
5789 void x86emuOp_test_byte_RM_R(u8 X86EMU_UNUSED(op1))
5791 int mod, rl, rh;
5792 u8 *destreg, *srcreg;
5793 uint destoffset;
5794 u8 destval;
5796 START_OF_INSTR();
5797 DECODE_PRINTF("TEST\t");
5798 FETCH_DECODE_MODRM(mod, rh, rl);
5799 switch (mod) {
5800 case 0:
5801 destoffset = decode_rm00_address(rl);
5802 DECODE_PRINTF(",");
5803 destval = fetch_data_byte(destoffset);
5804 srcreg = DECODE_RM_BYTE_REGISTER(rh);
5805 DECODE_PRINTF("\n");
5806 TRACE_AND_STEP();
5807 test_byte(destval, *srcreg);
5808 break;
5809 case 1:
5810 destoffset = decode_rm01_address(rl);
5811 DECODE_PRINTF(",");
5812 destval = fetch_data_byte(destoffset);
5813 srcreg = DECODE_RM_BYTE_REGISTER(rh);
5814 DECODE_PRINTF("\n");
5815 TRACE_AND_STEP();
5816 test_byte(destval, *srcreg);
5817 break;
5818 case 2:
5819 destoffset = decode_rm10_address(rl);
5820 DECODE_PRINTF(",");
5821 destval = fetch_data_byte(destoffset);
5822 srcreg = DECODE_RM_BYTE_REGISTER(rh);
5823 DECODE_PRINTF("\n");
5824 TRACE_AND_STEP();
5825 test_byte(destval, *srcreg);
5826 break;
5827 case 3: /* register to register */
5828 destreg = DECODE_RM_BYTE_REGISTER(rl);
5829 DECODE_PRINTF(",");
5830 srcreg = DECODE_RM_BYTE_REGISTER(rh);
5831 DECODE_PRINTF("\n");
5832 TRACE_AND_STEP();
5833 test_byte(*destreg, *srcreg);
5834 break;
5836 DECODE_CLEAR_SEGOVR();
5837 END_OF_INSTR();
5840 /****************************************************************************
5841 REMARKS:
5842 Handles opcode 0x85
5843 ****************************************************************************/
5844 void x86emuOp_test_word_RM_R(u8 X86EMU_UNUSED(op1))
5846 int mod, rl, rh;
5847 uint destoffset;
5849 START_OF_INSTR();
5850 DECODE_PRINTF("TEST\t");
5851 FETCH_DECODE_MODRM(mod, rh, rl);
5852 switch (mod) {
5853 case 0:
5854 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5855 u32 destval;
5856 u32 *srcreg;
5858 destoffset = decode_rm00_address(rl);
5859 DECODE_PRINTF(",");
5860 destval = fetch_data_long(destoffset);
5861 srcreg = DECODE_RM_LONG_REGISTER(rh);
5862 DECODE_PRINTF("\n");
5863 TRACE_AND_STEP();
5864 test_long(destval, *srcreg);
5865 } else {
5866 u16 destval;
5867 u16 *srcreg;
5869 destoffset = decode_rm00_address(rl);
5870 DECODE_PRINTF(",");
5871 destval = fetch_data_word(destoffset);
5872 srcreg = DECODE_RM_WORD_REGISTER(rh);
5873 DECODE_PRINTF("\n");
5874 TRACE_AND_STEP();
5875 test_word(destval, *srcreg);
5877 break;
5878 case 1:
5879 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5880 u32 destval;
5881 u32 *srcreg;
5883 destoffset = decode_rm01_address(rl);
5884 DECODE_PRINTF(",");
5885 destval = fetch_data_long(destoffset);
5886 srcreg = DECODE_RM_LONG_REGISTER(rh);
5887 DECODE_PRINTF("\n");
5888 TRACE_AND_STEP();
5889 test_long(destval, *srcreg);
5890 } else {
5891 u16 destval;
5892 u16 *srcreg;
5894 destoffset = decode_rm01_address(rl);
5895 DECODE_PRINTF(",");
5896 destval = fetch_data_word(destoffset);
5897 srcreg = DECODE_RM_WORD_REGISTER(rh);
5898 DECODE_PRINTF("\n");
5899 TRACE_AND_STEP();
5900 test_word(destval, *srcreg);
5902 break;
5903 case 2:
5904 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5905 u32 destval;
5906 u32 *srcreg;
5908 destoffset = decode_rm10_address(rl);
5909 DECODE_PRINTF(",");
5910 destval = fetch_data_long(destoffset);
5911 srcreg = DECODE_RM_LONG_REGISTER(rh);
5912 DECODE_PRINTF("\n");
5913 TRACE_AND_STEP();
5914 test_long(destval, *srcreg);
5915 } else {
5916 u16 destval;
5917 u16 *srcreg;
5919 destoffset = decode_rm10_address(rl);
5920 DECODE_PRINTF(",");
5921 destval = fetch_data_word(destoffset);
5922 srcreg = DECODE_RM_WORD_REGISTER(rh);
5923 DECODE_PRINTF("\n");
5924 TRACE_AND_STEP();
5925 test_word(destval, *srcreg);
5927 break;
5928 case 3: /* register to register */
5929 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5930 u32 *destreg,*srcreg;
5932 destreg = DECODE_RM_LONG_REGISTER(rl);
5933 DECODE_PRINTF(",");
5934 srcreg = DECODE_RM_LONG_REGISTER(rh);
5935 DECODE_PRINTF("\n");
5936 TRACE_AND_STEP();
5937 test_long(*destreg, *srcreg);
5938 } else {
5939 u16 *destreg,*srcreg;
5941 destreg = DECODE_RM_WORD_REGISTER(rl);
5942 DECODE_PRINTF(",");
5943 srcreg = DECODE_RM_WORD_REGISTER(rh);
5944 DECODE_PRINTF("\n");
5945 TRACE_AND_STEP();
5946 test_word(*destreg, *srcreg);
5948 break;
5950 DECODE_CLEAR_SEGOVR();
5951 END_OF_INSTR();
5954 /****************************************************************************
5955 REMARKS:
5956 Handles opcode 0x86
5957 ****************************************************************************/
5958 void x86emuOp_xchg_byte_RM_R(u8 X86EMU_UNUSED(op1))
5960 int mod, rl, rh;
5961 u8 *destreg, *srcreg;
5962 uint destoffset;
5963 u8 destval;
5964 u8 tmp;
5966 START_OF_INSTR();
5967 DECODE_PRINTF("XCHG\t");
5968 FETCH_DECODE_MODRM(mod, rh, rl);
5969 switch (mod) {
5970 case 0:
5971 destoffset = decode_rm00_address(rl);
5972 DECODE_PRINTF(",");
5973 destval = fetch_data_byte(destoffset);
5974 srcreg = DECODE_RM_BYTE_REGISTER(rh);
5975 DECODE_PRINTF("\n");
5976 TRACE_AND_STEP();
5977 tmp = *srcreg;
5978 *srcreg = destval;
5979 destval = tmp;
5980 store_data_byte(destoffset, destval);
5981 break;
5982 case 1:
5983 destoffset = decode_rm01_address(rl);
5984 DECODE_PRINTF(",");
5985 destval = fetch_data_byte(destoffset);
5986 srcreg = DECODE_RM_BYTE_REGISTER(rh);
5987 DECODE_PRINTF("\n");
5988 TRACE_AND_STEP();
5989 tmp = *srcreg;
5990 *srcreg = destval;
5991 destval = tmp;
5992 store_data_byte(destoffset, destval);
5993 break;
5994 case 2:
5995 destoffset = decode_rm10_address(rl);
5996 DECODE_PRINTF(",");
5997 destval = fetch_data_byte(destoffset);
5998 srcreg = DECODE_RM_BYTE_REGISTER(rh);
5999 DECODE_PRINTF("\n");
6000 TRACE_AND_STEP();
6001 tmp = *srcreg;
6002 *srcreg = destval;
6003 destval = tmp;
6004 store_data_byte(destoffset, destval);
6005 break;
6006 case 3: /* register to register */
6007 destreg = DECODE_RM_BYTE_REGISTER(rl);
6008 DECODE_PRINTF(",");
6009 srcreg = DECODE_RM_BYTE_REGISTER(rh);
6010 DECODE_PRINTF("\n");
6011 TRACE_AND_STEP();
6012 tmp = *srcreg;
6013 *srcreg = *destreg;
6014 *destreg = tmp;
6015 break;
6017 DECODE_CLEAR_SEGOVR();
6018 END_OF_INSTR();
6021 /****************************************************************************
6022 REMARKS:
6023 Handles opcode 0x87
6024 ****************************************************************************/
6025 void x86emuOp_xchg_word_RM_R(u8 X86EMU_UNUSED(op1))
6027 int mod, rl, rh;
6028 uint destoffset;
6030 START_OF_INSTR();
6031 DECODE_PRINTF("XCHG\t");
6032 FETCH_DECODE_MODRM(mod, rh, rl);
6033 switch (mod) {
6034 case 0:
6035 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6036 u32 *srcreg;
6037 u32 destval,tmp;
6039 destoffset = decode_rm00_address(rl);
6040 DECODE_PRINTF(",");
6041 destval = fetch_data_long(destoffset);
6042 srcreg = DECODE_RM_LONG_REGISTER(rh);
6043 DECODE_PRINTF("\n");
6044 TRACE_AND_STEP();
6045 tmp = *srcreg;
6046 *srcreg = destval;
6047 destval = tmp;
6048 store_data_long(destoffset, destval);
6049 } else {
6050 u16 *srcreg;
6051 u16 destval,tmp;
6053 destoffset = decode_rm00_address(rl);
6054 DECODE_PRINTF(",");
6055 destval = fetch_data_word(destoffset);
6056 srcreg = DECODE_RM_WORD_REGISTER(rh);
6057 DECODE_PRINTF("\n");
6058 TRACE_AND_STEP();
6059 tmp = *srcreg;
6060 *srcreg = destval;
6061 destval = tmp;
6062 store_data_word(destoffset, destval);
6064 break;
6065 case 1:
6066 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6067 u32 *srcreg;
6068 u32 destval,tmp;
6070 destoffset = decode_rm01_address(rl);
6071 DECODE_PRINTF(",");
6072 destval = fetch_data_long(destoffset);
6073 srcreg = DECODE_RM_LONG_REGISTER(rh);
6074 DECODE_PRINTF("\n");
6075 TRACE_AND_STEP();
6076 tmp = *srcreg;
6077 *srcreg = destval;
6078 destval = tmp;
6079 store_data_long(destoffset, destval);
6080 } else {
6081 u16 *srcreg;
6082 u16 destval,tmp;
6084 destoffset = decode_rm01_address(rl);
6085 DECODE_PRINTF(",");
6086 destval = fetch_data_word(destoffset);
6087 srcreg = DECODE_RM_WORD_REGISTER(rh);
6088 DECODE_PRINTF("\n");
6089 TRACE_AND_STEP();
6090 tmp = *srcreg;
6091 *srcreg = destval;
6092 destval = tmp;
6093 store_data_word(destoffset, destval);
6095 break;
6096 case 2:
6097 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6098 u32 *srcreg;
6099 u32 destval,tmp;
6101 destoffset = decode_rm10_address(rl);
6102 DECODE_PRINTF(",");
6103 destval = fetch_data_long(destoffset);
6104 srcreg = DECODE_RM_LONG_REGISTER(rh);
6105 DECODE_PRINTF("\n");
6106 TRACE_AND_STEP();
6107 tmp = *srcreg;
6108 *srcreg = destval;
6109 destval = tmp;
6110 store_data_long(destoffset, destval);
6111 } else {
6112 u16 *srcreg;
6113 u16 destval,tmp;
6115 destoffset = decode_rm10_address(rl);
6116 DECODE_PRINTF(",");
6117 destval = fetch_data_word(destoffset);
6118 srcreg = DECODE_RM_WORD_REGISTER(rh);
6119 DECODE_PRINTF("\n");
6120 TRACE_AND_STEP();
6121 tmp = *srcreg;
6122 *srcreg = destval;
6123 destval = tmp;
6124 store_data_word(destoffset, destval);
6126 break;
6127 case 3: /* register to register */
6128 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6129 u32 *destreg,*srcreg;
6130 u32 tmp;
6132 destreg = DECODE_RM_LONG_REGISTER(rl);
6133 DECODE_PRINTF(",");
6134 srcreg = DECODE_RM_LONG_REGISTER(rh);
6135 DECODE_PRINTF("\n");
6136 TRACE_AND_STEP();
6137 tmp = *srcreg;
6138 *srcreg = *destreg;
6139 *destreg = tmp;
6140 } else {
6141 u16 *destreg,*srcreg;
6142 u16 tmp;
6144 destreg = DECODE_RM_WORD_REGISTER(rl);
6145 DECODE_PRINTF(",");
6146 srcreg = DECODE_RM_WORD_REGISTER(rh);
6147 DECODE_PRINTF("\n");
6148 TRACE_AND_STEP();
6149 tmp = *srcreg;
6150 *srcreg = *destreg;
6151 *destreg = tmp;
6153 break;
6155 DECODE_CLEAR_SEGOVR();
6156 END_OF_INSTR();
6159 /****************************************************************************
6160 REMARKS:
6161 Handles opcode 0x88
6162 ****************************************************************************/
6163 void x86emuOp_mov_byte_RM_R(u8 X86EMU_UNUSED(op1))
6165 int mod, rl, rh;
6166 u8 *destreg, *srcreg;
6167 uint destoffset;
6169 START_OF_INSTR();
6170 DECODE_PRINTF("MOV\t");
6171 FETCH_DECODE_MODRM(mod, rh, rl);
6172 switch (mod) {
6173 case 0:
6174 destoffset = decode_rm00_address(rl);
6175 DECODE_PRINTF(",");
6176 srcreg = DECODE_RM_BYTE_REGISTER(rh);
6177 DECODE_PRINTF("\n");
6178 TRACE_AND_STEP();
6179 store_data_byte(destoffset, *srcreg);
6180 break;
6181 case 1:
6182 destoffset = decode_rm01_address(rl);
6183 DECODE_PRINTF(",");
6184 srcreg = DECODE_RM_BYTE_REGISTER(rh);
6185 DECODE_PRINTF("\n");
6186 TRACE_AND_STEP();
6187 store_data_byte(destoffset, *srcreg);
6188 break;
6189 case 2:
6190 destoffset = decode_rm10_address(rl);
6191 DECODE_PRINTF(",");
6192 srcreg = DECODE_RM_BYTE_REGISTER(rh);
6193 DECODE_PRINTF("\n");
6194 TRACE_AND_STEP();
6195 store_data_byte(destoffset, *srcreg);
6196 break;
6197 case 3: /* register to register */
6198 destreg = DECODE_RM_BYTE_REGISTER(rl);
6199 DECODE_PRINTF(",");
6200 srcreg = DECODE_RM_BYTE_REGISTER(rh);
6201 DECODE_PRINTF("\n");
6202 TRACE_AND_STEP();
6203 *destreg = *srcreg;
6204 break;
6206 DECODE_CLEAR_SEGOVR();
6207 END_OF_INSTR();
6210 /****************************************************************************
6211 REMARKS:
6212 Handles opcode 0x89
6213 ****************************************************************************/
6214 void x86emuOp_mov_word_RM_R(u8 X86EMU_UNUSED(op1))
6216 int mod, rl, rh;
6217 uint destoffset;
6219 START_OF_INSTR();
6220 DECODE_PRINTF("MOV\t");
6221 FETCH_DECODE_MODRM(mod, rh, rl);
6222 switch (mod) {
6223 case 0:
6224 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6225 u32 *srcreg;
6227 destoffset = decode_rm00_address(rl);
6228 DECODE_PRINTF(",");
6229 srcreg = DECODE_RM_LONG_REGISTER(rh);
6230 DECODE_PRINTF("\n");
6231 TRACE_AND_STEP();
6232 store_data_long(destoffset, *srcreg);
6233 } else {
6234 u16 *srcreg;
6236 destoffset = decode_rm00_address(rl);
6237 DECODE_PRINTF(",");
6238 srcreg = DECODE_RM_WORD_REGISTER(rh);
6239 DECODE_PRINTF("\n");
6240 TRACE_AND_STEP();
6241 store_data_word(destoffset, *srcreg);
6243 break;
6244 case 1:
6245 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6246 u32 *srcreg;
6248 destoffset = decode_rm01_address(rl);
6249 DECODE_PRINTF(",");
6250 srcreg = DECODE_RM_LONG_REGISTER(rh);
6251 DECODE_PRINTF("\n");
6252 TRACE_AND_STEP();
6253 store_data_long(destoffset, *srcreg);
6254 } else {
6255 u16 *srcreg;
6257 destoffset = decode_rm01_address(rl);
6258 DECODE_PRINTF(",");
6259 srcreg = DECODE_RM_WORD_REGISTER(rh);
6260 DECODE_PRINTF("\n");
6261 TRACE_AND_STEP();
6262 store_data_word(destoffset, *srcreg);
6264 break;
6265 case 2:
6266 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6267 u32 *srcreg;
6269 destoffset = decode_rm10_address(rl);
6270 DECODE_PRINTF(",");
6271 srcreg = DECODE_RM_LONG_REGISTER(rh);
6272 DECODE_PRINTF("\n");
6273 TRACE_AND_STEP();
6274 store_data_long(destoffset, *srcreg);
6275 } else {
6276 u16 *srcreg;
6278 destoffset = decode_rm10_address(rl);
6279 DECODE_PRINTF(",");
6280 srcreg = DECODE_RM_WORD_REGISTER(rh);
6281 DECODE_PRINTF("\n");
6282 TRACE_AND_STEP();
6283 store_data_word(destoffset, *srcreg);
6285 break;
6286 case 3: /* register to register */
6287 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6288 u32 *destreg,*srcreg;
6290 destreg = DECODE_RM_LONG_REGISTER(rl);
6291 DECODE_PRINTF(",");
6292 srcreg = DECODE_RM_LONG_REGISTER(rh);
6293 DECODE_PRINTF("\n");
6294 TRACE_AND_STEP();
6295 *destreg = *srcreg;
6296 } else {
6297 u16 *destreg,*srcreg;
6299 destreg = DECODE_RM_WORD_REGISTER(rl);
6300 DECODE_PRINTF(",");
6301 srcreg = DECODE_RM_WORD_REGISTER(rh);
6302 DECODE_PRINTF("\n");
6303 TRACE_AND_STEP();
6304 *destreg = *srcreg;
6306 break;
6308 DECODE_CLEAR_SEGOVR();
6309 END_OF_INSTR();
6312 /****************************************************************************
6313 REMARKS:
6314 Handles opcode 0x8a
6315 ****************************************************************************/
6316 void x86emuOp_mov_byte_R_RM(u8 X86EMU_UNUSED(op1))
6318 int mod, rl, rh;
6319 u8 *destreg, *srcreg;
6320 uint srcoffset;
6321 u8 srcval;
6323 START_OF_INSTR();
6324 DECODE_PRINTF("MOV\t");
6325 FETCH_DECODE_MODRM(mod, rh, rl);
6326 switch (mod) {
6327 case 0:
6328 destreg = DECODE_RM_BYTE_REGISTER(rh);
6329 DECODE_PRINTF(",");
6330 srcoffset = decode_rm00_address(rl);
6331 srcval = fetch_data_byte(srcoffset);
6332 DECODE_PRINTF("\n");
6333 TRACE_AND_STEP();
6334 *destreg = srcval;
6335 break;
6336 case 1:
6337 destreg = DECODE_RM_BYTE_REGISTER(rh);
6338 DECODE_PRINTF(",");
6339 srcoffset = decode_rm01_address(rl);
6340 srcval = fetch_data_byte(srcoffset);
6341 DECODE_PRINTF("\n");
6342 TRACE_AND_STEP();
6343 *destreg = srcval;
6344 break;
6345 case 2:
6346 destreg = DECODE_RM_BYTE_REGISTER(rh);
6347 DECODE_PRINTF(",");
6348 srcoffset = decode_rm10_address(rl);
6349 srcval = fetch_data_byte(srcoffset);
6350 DECODE_PRINTF("\n");
6351 TRACE_AND_STEP();
6352 *destreg = srcval;
6353 break;
6354 case 3: /* register to register */
6355 destreg = DECODE_RM_BYTE_REGISTER(rh);
6356 DECODE_PRINTF(",");
6357 srcreg = DECODE_RM_BYTE_REGISTER(rl);
6358 DECODE_PRINTF("\n");
6359 TRACE_AND_STEP();
6360 *destreg = *srcreg;
6361 break;
6363 DECODE_CLEAR_SEGOVR();
6364 END_OF_INSTR();
6367 /****************************************************************************
6368 REMARKS:
6369 Handles opcode 0x8b
6370 ****************************************************************************/
6371 void x86emuOp_mov_word_R_RM(u8 X86EMU_UNUSED(op1))
6373 int mod, rl, rh;
6374 uint srcoffset;
6376 START_OF_INSTR();
6377 DECODE_PRINTF("MOV\t");
6378 FETCH_DECODE_MODRM(mod, rh, rl);
6379 switch (mod) {
6380 case 0:
6381 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6382 u32 *destreg;
6383 u32 srcval;
6385 destreg = DECODE_RM_LONG_REGISTER(rh);
6386 DECODE_PRINTF(",");
6387 srcoffset = decode_rm00_address(rl);
6388 srcval = fetch_data_long(srcoffset);
6389 DECODE_PRINTF("\n");
6390 TRACE_AND_STEP();
6391 *destreg = srcval;
6392 } else {
6393 u16 *destreg;
6394 u16 srcval;
6396 destreg = DECODE_RM_WORD_REGISTER(rh);
6397 DECODE_PRINTF(",");
6398 srcoffset = decode_rm00_address(rl);
6399 srcval = fetch_data_word(srcoffset);
6400 DECODE_PRINTF("\n");
6401 TRACE_AND_STEP();
6402 *destreg = srcval;
6404 break;
6405 case 1:
6406 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6407 u32 *destreg;
6408 u32 srcval;
6410 destreg = DECODE_RM_LONG_REGISTER(rh);
6411 DECODE_PRINTF(",");
6412 srcoffset = decode_rm01_address(rl);
6413 srcval = fetch_data_long(srcoffset);
6414 DECODE_PRINTF("\n");
6415 TRACE_AND_STEP();
6416 *destreg = srcval;
6417 } else {
6418 u16 *destreg;
6419 u16 srcval;
6421 destreg = DECODE_RM_WORD_REGISTER(rh);
6422 DECODE_PRINTF(",");
6423 srcoffset = decode_rm01_address(rl);
6424 srcval = fetch_data_word(srcoffset);
6425 DECODE_PRINTF("\n");
6426 TRACE_AND_STEP();
6427 *destreg = srcval;
6429 break;
6430 case 2:
6431 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6432 u32 *destreg;
6433 u32 srcval;
6435 destreg = DECODE_RM_LONG_REGISTER(rh);
6436 DECODE_PRINTF(",");
6437 srcoffset = decode_rm10_address(rl);
6438 srcval = fetch_data_long(srcoffset);
6439 DECODE_PRINTF("\n");
6440 TRACE_AND_STEP();
6441 *destreg = srcval;
6442 } else {
6443 u16 *destreg;
6444 u16 srcval;
6446 destreg = DECODE_RM_WORD_REGISTER(rh);
6447 DECODE_PRINTF(",");
6448 srcoffset = decode_rm10_address(rl);
6449 srcval = fetch_data_word(srcoffset);
6450 DECODE_PRINTF("\n");
6451 TRACE_AND_STEP();
6452 *destreg = srcval;
6454 break;
6455 case 3: /* register to register */
6456 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6457 u32 *destreg, *srcreg;
6459 destreg = DECODE_RM_LONG_REGISTER(rh);
6460 DECODE_PRINTF(",");
6461 srcreg = DECODE_RM_LONG_REGISTER(rl);
6462 DECODE_PRINTF("\n");
6463 TRACE_AND_STEP();
6464 *destreg = *srcreg;
6465 } else {
6466 u16 *destreg, *srcreg;
6468 destreg = DECODE_RM_WORD_REGISTER(rh);
6469 DECODE_PRINTF(",");
6470 srcreg = DECODE_RM_WORD_REGISTER(rl);
6471 DECODE_PRINTF("\n");
6472 TRACE_AND_STEP();
6473 *destreg = *srcreg;
6475 break;
6477 DECODE_CLEAR_SEGOVR();
6478 END_OF_INSTR();
6481 /****************************************************************************
6482 REMARKS:
6483 Handles opcode 0x8c
6484 ****************************************************************************/
6485 void x86emuOp_mov_word_RM_SR(u8 X86EMU_UNUSED(op1))
6487 int mod, rl, rh;
6488 u16 *destreg, *srcreg;
6489 uint destoffset;
6490 u16 destval;
6492 START_OF_INSTR();
6493 DECODE_PRINTF("MOV\t");
6494 FETCH_DECODE_MODRM(mod, rh, rl);
6495 switch (mod) {
6496 case 0:
6497 destoffset = decode_rm00_address(rl);
6498 DECODE_PRINTF(",");
6499 srcreg = decode_rm_seg_register(rh);
6500 DECODE_PRINTF("\n");
6501 TRACE_AND_STEP();
6502 destval = *srcreg;
6503 store_data_word(destoffset, destval);
6504 break;
6505 case 1:
6506 destoffset = decode_rm01_address(rl);
6507 DECODE_PRINTF(",");
6508 srcreg = decode_rm_seg_register(rh);
6509 DECODE_PRINTF("\n");
6510 TRACE_AND_STEP();
6511 destval = *srcreg;
6512 store_data_word(destoffset, destval);
6513 break;
6514 case 2:
6515 destoffset = decode_rm10_address(rl);
6516 DECODE_PRINTF(",");
6517 srcreg = decode_rm_seg_register(rh);
6518 DECODE_PRINTF("\n");
6519 TRACE_AND_STEP();
6520 destval = *srcreg;
6521 store_data_word(destoffset, destval);
6522 break;
6523 case 3: /* register to register */
6524 destreg = DECODE_RM_WORD_REGISTER(rl);
6525 DECODE_PRINTF(",");
6526 srcreg = decode_rm_seg_register(rh);
6527 DECODE_PRINTF("\n");
6528 TRACE_AND_STEP();
6529 *destreg = *srcreg;
6530 break;
6532 DECODE_CLEAR_SEGOVR();
6533 END_OF_INSTR();
6536 /****************************************************************************
6537 REMARKS:
6538 Handles opcode 0x8d
6539 ****************************************************************************/
6540 void x86emuOp_lea_word_R_M(u8 X86EMU_UNUSED(op1))
6542 int mod, rl, rh;
6543 u16 *srcreg;
6544 uint destoffset;
6547 * TODO: Need to handle address size prefix!
6549 * lea eax,[eax+ebx*2] ??
6552 START_OF_INSTR();
6553 DECODE_PRINTF("LEA\t");
6554 FETCH_DECODE_MODRM(mod, rh, rl);
6555 switch (mod) {
6556 case 0:
6557 srcreg = DECODE_RM_WORD_REGISTER(rh);
6558 DECODE_PRINTF(",");
6559 destoffset = decode_rm00_address(rl);
6560 DECODE_PRINTF("\n");
6561 TRACE_AND_STEP();
6562 *srcreg = (u16)destoffset;
6563 break;
6564 case 1:
6565 srcreg = DECODE_RM_WORD_REGISTER(rh);
6566 DECODE_PRINTF(",");
6567 destoffset = decode_rm01_address(rl);
6568 DECODE_PRINTF("\n");
6569 TRACE_AND_STEP();
6570 *srcreg = (u16)destoffset;
6571 break;
6572 case 2:
6573 srcreg = DECODE_RM_WORD_REGISTER(rh);
6574 DECODE_PRINTF(",");
6575 destoffset = decode_rm10_address(rl);
6576 DECODE_PRINTF("\n");
6577 TRACE_AND_STEP();
6578 *srcreg = (u16)destoffset;
6579 break;
6580 case 3: /* register to register */
6581 /* undefined. Do nothing. */
6582 break;
6584 DECODE_CLEAR_SEGOVR();
6585 END_OF_INSTR();
6588 /****************************************************************************
6589 REMARKS:
6590 Handles opcode 0x8e
6591 ****************************************************************************/
6592 void x86emuOp_mov_word_SR_RM(u8 X86EMU_UNUSED(op1))
6594 int mod, rl, rh;
6595 u16 *destreg, *srcreg;
6596 uint srcoffset;
6597 u16 srcval;
6599 START_OF_INSTR();
6600 DECODE_PRINTF("MOV\t");
6601 FETCH_DECODE_MODRM(mod, rh, rl);
6602 switch (mod) {
6603 case 0:
6604 destreg = decode_rm_seg_register(rh);
6605 DECODE_PRINTF(",");
6606 srcoffset = decode_rm00_address(rl);
6607 srcval = fetch_data_word(srcoffset);
6608 DECODE_PRINTF("\n");
6609 TRACE_AND_STEP();
6610 *destreg = srcval;
6611 break;
6612 case 1:
6613 destreg = decode_rm_seg_register(rh);
6614 DECODE_PRINTF(",");
6615 srcoffset = decode_rm01_address(rl);
6616 srcval = fetch_data_word(srcoffset);
6617 DECODE_PRINTF("\n");
6618 TRACE_AND_STEP();
6619 *destreg = srcval;
6620 break;
6621 case 2:
6622 destreg = decode_rm_seg_register(rh);
6623 DECODE_PRINTF(",");
6624 srcoffset = decode_rm10_address(rl);
6625 srcval = fetch_data_word(srcoffset);
6626 DECODE_PRINTF("\n");
6627 TRACE_AND_STEP();
6628 *destreg = srcval;
6629 break;
6630 case 3: /* register to register */
6631 destreg = decode_rm_seg_register(rh);
6632 DECODE_PRINTF(",");
6633 srcreg = DECODE_RM_WORD_REGISTER(rl);
6634 DECODE_PRINTF("\n");
6635 TRACE_AND_STEP();
6636 *destreg = *srcreg;
6637 break;
6640 * Clean up, and reset all the R_xSP pointers to the correct
6641 * locations. This is about 3x too much overhead (doing all the
6642 * segreg ptrs when only one is needed, but this instruction
6643 * *cannot* be that common, and this isn't too much work anyway.
6645 DECODE_CLEAR_SEGOVR();
6646 END_OF_INSTR();
6649 /****************************************************************************
6650 REMARKS:
6651 Handles opcode 0x8f
6652 ****************************************************************************/
6653 void x86emuOp_pop_RM(u8 X86EMU_UNUSED(op1))
6655 int mod, rl, rh;
6656 uint destoffset;
6658 START_OF_INSTR();
6659 DECODE_PRINTF("POP\t");
6660 FETCH_DECODE_MODRM(mod, rh, rl);
6661 if (rh != 0) {
6662 DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n");
6663 HALT_SYS();
6665 switch (mod) {
6666 case 0:
6667 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6668 u32 destval;
6670 destoffset = decode_rm00_address(rl);
6671 DECODE_PRINTF("\n");
6672 TRACE_AND_STEP();
6673 destval = pop_long();
6674 store_data_long(destoffset, destval);
6675 } else {
6676 u16 destval;
6678 destoffset = decode_rm00_address(rl);
6679 DECODE_PRINTF("\n");
6680 TRACE_AND_STEP();
6681 destval = pop_word();
6682 store_data_word(destoffset, destval);
6684 break;
6685 case 1:
6686 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6687 u32 destval;
6689 destoffset = decode_rm01_address(rl);
6690 DECODE_PRINTF("\n");
6691 TRACE_AND_STEP();
6692 destval = pop_long();
6693 store_data_long(destoffset, destval);
6694 } else {
6695 u16 destval;
6697 destoffset = decode_rm01_address(rl);
6698 DECODE_PRINTF("\n");
6699 TRACE_AND_STEP();
6700 destval = pop_word();
6701 store_data_word(destoffset, destval);
6703 break;
6704 case 2:
6705 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6706 u32 destval;
6708 destoffset = decode_rm10_address(rl);
6709 DECODE_PRINTF("\n");
6710 TRACE_AND_STEP();
6711 destval = pop_long();
6712 store_data_long(destoffset, destval);
6713 } else {
6714 u16 destval;
6716 destoffset = decode_rm10_address(rl);
6717 DECODE_PRINTF("\n");
6718 TRACE_AND_STEP();
6719 destval = pop_word();
6720 store_data_word(destoffset, destval);
6722 break;
6723 case 3: /* register to register */
6724 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6725 u32 *destreg;
6727 destreg = DECODE_RM_LONG_REGISTER(rl);
6728 DECODE_PRINTF("\n");
6729 TRACE_AND_STEP();
6730 *destreg = pop_long();
6731 } else {
6732 u16 *destreg;
6734 destreg = DECODE_RM_WORD_REGISTER(rl);
6735 DECODE_PRINTF("\n");
6736 TRACE_AND_STEP();
6737 *destreg = pop_word();
6739 break;
6741 DECODE_CLEAR_SEGOVR();
6742 END_OF_INSTR();
6745 /****************************************************************************
6746 REMARKS:
6747 Handles opcode 0x90
6748 ****************************************************************************/
6749 void x86emuOp_nop(u8 X86EMU_UNUSED(op1))
6751 START_OF_INSTR();
6752 DECODE_PRINTF("NOP\n");
6753 TRACE_AND_STEP();
6754 DECODE_CLEAR_SEGOVR();
6755 END_OF_INSTR();
6758 /****************************************************************************
6759 REMARKS:
6760 Handles opcode 0x91
6761 ****************************************************************************/
6762 void x86emuOp_xchg_word_AX_CX(u8 X86EMU_UNUSED(op1))
6764 u32 tmp;
6766 START_OF_INSTR();
6767 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6768 DECODE_PRINTF("XCHG\tEAX,ECX\n");
6769 } else {
6770 DECODE_PRINTF("XCHG\tAX,CX\n");
6772 TRACE_AND_STEP();
6773 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6774 tmp = M.x86.R_EAX;
6775 M.x86.R_EAX = M.x86.R_ECX;
6776 M.x86.R_ECX = tmp;
6777 } else {
6778 tmp = M.x86.R_AX;
6779 M.x86.R_AX = M.x86.R_CX;
6780 M.x86.R_CX = (u16)tmp;
6782 DECODE_CLEAR_SEGOVR();
6783 END_OF_INSTR();
6786 /****************************************************************************
6787 REMARKS:
6788 Handles opcode 0x92
6789 ****************************************************************************/
6790 void x86emuOp_xchg_word_AX_DX(u8 X86EMU_UNUSED(op1))
6792 u32 tmp;
6794 START_OF_INSTR();
6795 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6796 DECODE_PRINTF("XCHG\tEAX,EDX\n");
6797 } else {
6798 DECODE_PRINTF("XCHG\tAX,DX\n");
6800 TRACE_AND_STEP();
6801 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6802 tmp = M.x86.R_EAX;
6803 M.x86.R_EAX = M.x86.R_EDX;
6804 M.x86.R_EDX = tmp;
6805 } else {
6806 tmp = M.x86.R_AX;
6807 M.x86.R_AX = M.x86.R_DX;
6808 M.x86.R_DX = (u16)tmp;
6810 DECODE_CLEAR_SEGOVR();
6811 END_OF_INSTR();
6814 /****************************************************************************
6815 REMARKS:
6816 Handles opcode 0x93
6817 ****************************************************************************/
6818 void x86emuOp_xchg_word_AX_BX(u8 X86EMU_UNUSED(op1))
6820 u32 tmp;
6822 START_OF_INSTR();
6823 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6824 DECODE_PRINTF("XCHG\tEAX,EBX\n");
6825 } else {
6826 DECODE_PRINTF("XCHG\tAX,BX\n");
6828 TRACE_AND_STEP();
6829 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6830 tmp = M.x86.R_EAX;
6831 M.x86.R_EAX = M.x86.R_EBX;
6832 M.x86.R_EBX = tmp;
6833 } else {
6834 tmp = M.x86.R_AX;
6835 M.x86.R_AX = M.x86.R_BX;
6836 M.x86.R_BX = (u16)tmp;
6838 DECODE_CLEAR_SEGOVR();
6839 END_OF_INSTR();
6842 /****************************************************************************
6843 REMARKS:
6844 Handles opcode 0x94
6845 ****************************************************************************/
6846 void x86emuOp_xchg_word_AX_SP(u8 X86EMU_UNUSED(op1))
6848 u32 tmp;
6850 START_OF_INSTR();
6851 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6852 DECODE_PRINTF("XCHG\tEAX,ESP\n");
6853 } else {
6854 DECODE_PRINTF("XCHG\tAX,SP\n");
6856 TRACE_AND_STEP();
6857 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6858 tmp = M.x86.R_EAX;
6859 M.x86.R_EAX = M.x86.R_ESP;
6860 M.x86.R_ESP = tmp;
6861 } else {
6862 tmp = M.x86.R_AX;
6863 M.x86.R_AX = M.x86.R_SP;
6864 M.x86.R_SP = (u16)tmp;
6866 DECODE_CLEAR_SEGOVR();
6867 END_OF_INSTR();
6870 /****************************************************************************
6871 REMARKS:
6872 Handles opcode 0x95
6873 ****************************************************************************/
6874 void x86emuOp_xchg_word_AX_BP(u8 X86EMU_UNUSED(op1))
6876 u32 tmp;
6878 START_OF_INSTR();
6879 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6880 DECODE_PRINTF("XCHG\tEAX,EBP\n");
6881 } else {
6882 DECODE_PRINTF("XCHG\tAX,BP\n");
6884 TRACE_AND_STEP();
6885 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6886 tmp = M.x86.R_EAX;
6887 M.x86.R_EAX = M.x86.R_EBP;
6888 M.x86.R_EBP = tmp;
6889 } else {
6890 tmp = M.x86.R_AX;
6891 M.x86.R_AX = M.x86.R_BP;
6892 M.x86.R_BP = (u16)tmp;
6894 DECODE_CLEAR_SEGOVR();
6895 END_OF_INSTR();
6898 /****************************************************************************
6899 REMARKS:
6900 Handles opcode 0x96
6901 ****************************************************************************/
6902 void x86emuOp_xchg_word_AX_SI(u8 X86EMU_UNUSED(op1))
6904 u32 tmp;
6906 START_OF_INSTR();
6907 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6908 DECODE_PRINTF("XCHG\tEAX,ESI\n");
6909 } else {
6910 DECODE_PRINTF("XCHG\tAX,SI\n");
6912 TRACE_AND_STEP();
6913 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6914 tmp = M.x86.R_EAX;
6915 M.x86.R_EAX = M.x86.R_ESI;
6916 M.x86.R_ESI = tmp;
6917 } else {
6918 tmp = M.x86.R_AX;
6919 M.x86.R_AX = M.x86.R_SI;
6920 M.x86.R_SI = (u16)tmp;
6922 DECODE_CLEAR_SEGOVR();
6923 END_OF_INSTR();
6926 /****************************************************************************
6927 REMARKS:
6928 Handles opcode 0x97
6929 ****************************************************************************/
6930 void x86emuOp_xchg_word_AX_DI(u8 X86EMU_UNUSED(op1))
6932 u32 tmp;
6934 START_OF_INSTR();
6935 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6936 DECODE_PRINTF("XCHG\tEAX,EDI\n");
6937 } else {
6938 DECODE_PRINTF("XCHG\tAX,DI\n");
6940 TRACE_AND_STEP();
6941 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6942 tmp = M.x86.R_EAX;
6943 M.x86.R_EAX = M.x86.R_EDI;
6944 M.x86.R_EDI = tmp;
6945 } else {
6946 tmp = M.x86.R_AX;
6947 M.x86.R_AX = M.x86.R_DI;
6948 M.x86.R_DI = (u16)tmp;
6950 DECODE_CLEAR_SEGOVR();
6951 END_OF_INSTR();
6954 /****************************************************************************
6955 REMARKS:
6956 Handles opcode 0x98
6957 ****************************************************************************/
6958 void x86emuOp_cbw(u8 X86EMU_UNUSED(op1))
6960 START_OF_INSTR();
6961 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6962 DECODE_PRINTF("CWDE\n");
6963 } else {
6964 DECODE_PRINTF("CBW\n");
6966 TRACE_AND_STEP();
6967 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6968 if (M.x86.R_AX & 0x8000) {
6969 M.x86.R_EAX |= 0xffff0000;
6970 } else {
6971 M.x86.R_EAX &= 0x0000ffff;
6973 } else {
6974 if (M.x86.R_AL & 0x80) {
6975 M.x86.R_AH = 0xff;
6976 } else {
6977 M.x86.R_AH = 0x0;
6980 DECODE_CLEAR_SEGOVR();
6981 END_OF_INSTR();
6984 /****************************************************************************
6985 REMARKS:
6986 Handles opcode 0x99
6987 ****************************************************************************/
6988 void x86emuOp_cwd(u8 X86EMU_UNUSED(op1))
6990 START_OF_INSTR();
6991 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6992 DECODE_PRINTF("CDQ\n");
6993 } else {
6994 DECODE_PRINTF("CWD\n");
6996 DECODE_PRINTF("CWD\n");
6997 TRACE_AND_STEP();
6998 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6999 if (M.x86.R_EAX & 0x80000000) {
7000 M.x86.R_EDX = 0xffffffff;
7001 } else {
7002 M.x86.R_EDX = 0x0;
7004 } else {
7005 if (M.x86.R_AX & 0x8000) {
7006 M.x86.R_DX = 0xffff;
7007 } else {
7008 M.x86.R_DX = 0x0;
7011 DECODE_CLEAR_SEGOVR();
7012 END_OF_INSTR();
7015 /****************************************************************************
7016 REMARKS:
7017 Handles opcode 0x9a
7018 ****************************************************************************/
7019 void x86emuOp_call_far_IMM(u8 X86EMU_UNUSED(op1))
7021 u16 farseg, faroff;
7023 START_OF_INSTR();
7024 DECODE_PRINTF("CALL\t");
7025 faroff = fetch_word_imm();
7026 farseg = fetch_word_imm();
7027 DECODE_PRINTF2("%04x:", farseg);
7028 DECODE_PRINTF2("%04x\n", faroff);
7029 CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, farseg, faroff, "FAR ");
7031 TRACE_AND_STEP();
7032 push_word(M.x86.R_CS);
7033 M.x86.R_CS = farseg;
7034 push_word(M.x86.R_IP);
7035 M.x86.R_IP = faroff;
7036 DECODE_CLEAR_SEGOVR();
7037 END_OF_INSTR();
7040 /****************************************************************************
7041 REMARKS:
7042 Handles opcode 0x9b
7043 ****************************************************************************/
7044 void x86emuOp_wait(u8 X86EMU_UNUSED(op1))
7046 START_OF_INSTR();
7047 DECODE_PRINTF("WAIT");
7048 TRACE_AND_STEP();
7049 /* NADA. */
7050 DECODE_CLEAR_SEGOVR();
7051 END_OF_INSTR();
7054 /****************************************************************************
7055 REMARKS:
7056 Handles opcode 0x9c
7057 ****************************************************************************/
7058 void x86emuOp_pushf_word(u8 X86EMU_UNUSED(op1))
7060 u32 flags;
7062 START_OF_INSTR();
7063 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7064 DECODE_PRINTF("PUSHFD\n");
7065 } else {
7066 DECODE_PRINTF("PUSHF\n");
7068 TRACE_AND_STEP();
7070 /* clear out *all* bits not representing flags, and turn on real bits */
7071 flags = (M.x86.R_EFLG & F_MSK) | F_ALWAYS_ON;
7072 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7073 push_long(flags);
7074 } else {
7075 push_word((u16)flags);
7077 DECODE_CLEAR_SEGOVR();
7078 END_OF_INSTR();
7081 /****************************************************************************
7082 REMARKS:
7083 Handles opcode 0x9d
7084 ****************************************************************************/
7085 void x86emuOp_popf_word(u8 X86EMU_UNUSED(op1))
7087 START_OF_INSTR();
7088 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7089 DECODE_PRINTF("POPFD\n");
7090 } else {
7091 DECODE_PRINTF("POPF\n");
7093 TRACE_AND_STEP();
7094 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7095 M.x86.R_EFLG = pop_long();
7096 } else {
7097 M.x86.R_FLG = pop_word();
7099 DECODE_CLEAR_SEGOVR();
7100 END_OF_INSTR();
7103 /****************************************************************************
7104 REMARKS:
7105 Handles opcode 0x9e
7106 ****************************************************************************/
7107 void x86emuOp_sahf(u8 X86EMU_UNUSED(op1))
7109 START_OF_INSTR();
7110 DECODE_PRINTF("SAHF\n");
7111 TRACE_AND_STEP();
7112 /* clear the lower bits of the flag register */
7113 M.x86.R_FLG &= 0xffffff00;
7114 /* or in the AH register into the flags register */
7115 M.x86.R_FLG |= M.x86.R_AH;
7116 DECODE_CLEAR_SEGOVR();
7117 END_OF_INSTR();
7120 /****************************************************************************
7121 REMARKS:
7122 Handles opcode 0x9f
7123 ****************************************************************************/
7124 void x86emuOp_lahf(u8 X86EMU_UNUSED(op1))
7126 START_OF_INSTR();
7127 DECODE_PRINTF("LAHF\n");
7128 TRACE_AND_STEP();
7129 M.x86.R_AH = (u8)(M.x86.R_FLG & 0xff);
7130 /*undocumented TC++ behavior??? Nope. It's documented, but
7131 you have too look real hard to notice it. */
7132 M.x86.R_AH |= 0x2;
7133 DECODE_CLEAR_SEGOVR();
7134 END_OF_INSTR();
7137 /****************************************************************************
7138 REMARKS:
7139 Handles opcode 0xa0
7140 ****************************************************************************/
7141 void x86emuOp_mov_AL_M_IMM(u8 X86EMU_UNUSED(op1))
7143 u16 offset;
7145 START_OF_INSTR();
7146 DECODE_PRINTF("MOV\tAL,");
7147 offset = fetch_word_imm();
7148 DECODE_PRINTF2("[%04x]\n", offset);
7149 TRACE_AND_STEP();
7150 M.x86.R_AL = fetch_data_byte(offset);
7151 DECODE_CLEAR_SEGOVR();
7152 END_OF_INSTR();
7155 /****************************************************************************
7156 REMARKS:
7157 Handles opcode 0xa1
7158 ****************************************************************************/
7159 void x86emuOp_mov_AX_M_IMM(u8 X86EMU_UNUSED(op1))
7161 u16 offset;
7163 START_OF_INSTR();
7164 offset = fetch_word_imm();
7165 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7166 DECODE_PRINTF2("MOV\tEAX,[%04x]\n", offset);
7167 } else {
7168 DECODE_PRINTF2("MOV\tAX,[%04x]\n", offset);
7170 TRACE_AND_STEP();
7171 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7172 M.x86.R_EAX = fetch_data_long(offset);
7173 } else {
7174 M.x86.R_AX = fetch_data_word(offset);
7176 DECODE_CLEAR_SEGOVR();
7177 END_OF_INSTR();
7180 /****************************************************************************
7181 REMARKS:
7182 Handles opcode 0xa2
7183 ****************************************************************************/
7184 void x86emuOp_mov_M_AL_IMM(u8 X86EMU_UNUSED(op1))
7186 u16 offset;
7188 START_OF_INSTR();
7189 DECODE_PRINTF("MOV\t");
7190 offset = fetch_word_imm();
7191 DECODE_PRINTF2("[%04x],AL\n", offset);
7192 TRACE_AND_STEP();
7193 store_data_byte(offset, M.x86.R_AL);
7194 DECODE_CLEAR_SEGOVR();
7195 END_OF_INSTR();
7198 /****************************************************************************
7199 REMARKS:
7200 Handles opcode 0xa3
7201 ****************************************************************************/
7202 void x86emuOp_mov_M_AX_IMM(u8 X86EMU_UNUSED(op1))
7204 u16 offset;
7206 START_OF_INSTR();
7207 offset = fetch_word_imm();
7208 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7209 DECODE_PRINTF2("MOV\t[%04x],EAX\n", offset);
7210 } else {
7211 DECODE_PRINTF2("MOV\t[%04x],AX\n", offset);
7213 TRACE_AND_STEP();
7214 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7215 store_data_long(offset, M.x86.R_EAX);
7216 } else {
7217 store_data_word(offset, M.x86.R_AX);
7219 DECODE_CLEAR_SEGOVR();
7220 END_OF_INSTR();
7223 /****************************************************************************
7224 REMARKS:
7225 Handles opcode 0xa4
7226 ****************************************************************************/
7227 void x86emuOp_movs_byte(u8 X86EMU_UNUSED(op1))
7229 u8 val;
7230 u32 count;
7231 int inc;
7233 START_OF_INSTR();
7234 DECODE_PRINTF("MOVS\tBYTE\n");
7235 if (ACCESS_FLAG(F_DF)) /* down */
7236 inc = -1;
7237 else
7238 inc = 1;
7239 TRACE_AND_STEP();
7240 count = 1;
7241 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7242 /* dont care whether REPE or REPNE */
7243 /* move them until CX is ZERO. */
7244 count = M.x86.R_CX;
7245 M.x86.R_CX = 0;
7246 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7248 while (count--) {
7249 val = fetch_data_byte(M.x86.R_SI);
7250 store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, val);
7251 M.x86.R_SI += inc;
7252 M.x86.R_DI += inc;
7254 DECODE_CLEAR_SEGOVR();
7255 END_OF_INSTR();
7258 /****************************************************************************
7259 REMARKS:
7260 Handles opcode 0xa5
7261 ****************************************************************************/
7262 void x86emuOp_movs_word(u8 X86EMU_UNUSED(op1))
7264 u32 val;
7265 int inc;
7266 u32 count;
7268 START_OF_INSTR();
7269 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7270 DECODE_PRINTF("MOVS\tDWORD\n");
7271 if (ACCESS_FLAG(F_DF)) /* down */
7272 inc = -4;
7273 else
7274 inc = 4;
7275 } else {
7276 DECODE_PRINTF("MOVS\tWORD\n");
7277 if (ACCESS_FLAG(F_DF)) /* down */
7278 inc = -2;
7279 else
7280 inc = 2;
7282 TRACE_AND_STEP();
7283 count = 1;
7284 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7285 /* dont care whether REPE or REPNE */
7286 /* move them until CX is ZERO. */
7287 count = M.x86.R_CX;
7288 M.x86.R_CX = 0;
7289 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7291 while (count--) {
7292 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7293 val = fetch_data_long(M.x86.R_SI);
7294 store_data_long_abs(M.x86.R_ES, M.x86.R_DI, val);
7295 } else {
7296 val = fetch_data_word(M.x86.R_SI);
7297 store_data_word_abs(M.x86.R_ES, M.x86.R_DI, (u16)val);
7299 M.x86.R_SI += inc;
7300 M.x86.R_DI += inc;
7302 DECODE_CLEAR_SEGOVR();
7303 END_OF_INSTR();
7306 /****************************************************************************
7307 REMARKS:
7308 Handles opcode 0xa6
7309 ****************************************************************************/
7310 void x86emuOp_cmps_byte(u8 X86EMU_UNUSED(op1))
7312 s8 val1, val2;
7313 int inc;
7315 START_OF_INSTR();
7316 DECODE_PRINTF("CMPS\tBYTE\n");
7317 TRACE_AND_STEP();
7318 if (ACCESS_FLAG(F_DF)) /* down */
7319 inc = -1;
7320 else
7321 inc = 1;
7323 if (M.x86.mode & SYSMODE_PREFIX_REPE) {
7324 /* REPE */
7325 /* move them until CX is ZERO. */
7326 while (M.x86.R_CX != 0) {
7327 val1 = fetch_data_byte(M.x86.R_SI);
7328 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7329 cmp_byte(val1, val2);
7330 M.x86.R_CX -= 1;
7331 M.x86.R_SI += inc;
7332 M.x86.R_DI += inc;
7333 if (ACCESS_FLAG(F_ZF) == 0)
7334 break;
7336 M.x86.mode &= ~SYSMODE_PREFIX_REPE;
7337 } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
7338 /* REPNE */
7339 /* move them until CX is ZERO. */
7340 while (M.x86.R_CX != 0) {
7341 val1 = fetch_data_byte(M.x86.R_SI);
7342 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7343 cmp_byte(val1, val2);
7344 M.x86.R_CX -= 1;
7345 M.x86.R_SI += inc;
7346 M.x86.R_DI += inc;
7347 if (ACCESS_FLAG(F_ZF))
7348 break; /* zero flag set means equal */
7350 M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
7351 } else {
7352 val1 = fetch_data_byte(M.x86.R_SI);
7353 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7354 cmp_byte(val1, val2);
7355 M.x86.R_SI += inc;
7356 M.x86.R_DI += inc;
7358 DECODE_CLEAR_SEGOVR();
7359 END_OF_INSTR();
7362 /****************************************************************************
7363 REMARKS:
7364 Handles opcode 0xa7
7365 ****************************************************************************/
7366 void x86emuOp_cmps_word(u8 X86EMU_UNUSED(op1))
7368 u32 val1,val2;
7369 int inc;
7371 START_OF_INSTR();
7372 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7373 DECODE_PRINTF("CMPS\tDWORD\n");
7374 if (ACCESS_FLAG(F_DF)) /* down */
7375 inc = -4;
7376 else
7377 inc = 4;
7378 } else {
7379 DECODE_PRINTF("CMPS\tWORD\n");
7380 if (ACCESS_FLAG(F_DF)) /* down */
7381 inc = -2;
7382 else
7383 inc = 2;
7385 TRACE_AND_STEP();
7386 if (M.x86.mode & SYSMODE_PREFIX_REPE) {
7387 /* REPE */
7388 /* move them until CX is ZERO. */
7389 while (M.x86.R_CX != 0) {
7390 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7391 val1 = fetch_data_long(M.x86.R_SI);
7392 val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7393 cmp_long(val1, val2);
7394 } else {
7395 val1 = fetch_data_word(M.x86.R_SI);
7396 val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7397 cmp_word((u16)val1, (u16)val2);
7399 M.x86.R_CX -= 1;
7400 M.x86.R_SI += inc;
7401 M.x86.R_DI += inc;
7402 if (ACCESS_FLAG(F_ZF) == 0)
7403 break;
7405 M.x86.mode &= ~SYSMODE_PREFIX_REPE;
7406 } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
7407 /* REPNE */
7408 /* move them until CX is ZERO. */
7409 while (M.x86.R_CX != 0) {
7410 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7411 val1 = fetch_data_long(M.x86.R_SI);
7412 val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7413 cmp_long(val1, val2);
7414 } else {
7415 val1 = fetch_data_word(M.x86.R_SI);
7416 val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7417 cmp_word((u16)val1, (u16)val2);
7419 M.x86.R_CX -= 1;
7420 M.x86.R_SI += inc;
7421 M.x86.R_DI += inc;
7422 if (ACCESS_FLAG(F_ZF))
7423 break; /* zero flag set means equal */
7425 M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
7426 } else {
7427 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7428 val1 = fetch_data_long(M.x86.R_SI);
7429 val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7430 cmp_long(val1, val2);
7431 } else {
7432 val1 = fetch_data_word(M.x86.R_SI);
7433 val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7434 cmp_word((u16)val1, (u16)val2);
7436 M.x86.R_SI += inc;
7437 M.x86.R_DI += inc;
7439 DECODE_CLEAR_SEGOVR();
7440 END_OF_INSTR();
7443 /****************************************************************************
7444 REMARKS:
7445 Handles opcode 0xa8
7446 ****************************************************************************/
7447 void x86emuOp_test_AL_IMM(u8 X86EMU_UNUSED(op1))
7449 int imm;
7451 START_OF_INSTR();
7452 DECODE_PRINTF("TEST\tAL,");
7453 imm = fetch_byte_imm();
7454 DECODE_PRINTF2("%04x\n", imm);
7455 TRACE_AND_STEP();
7456 test_byte(M.x86.R_AL, (u8)imm);
7457 DECODE_CLEAR_SEGOVR();
7458 END_OF_INSTR();
7461 /****************************************************************************
7462 REMARKS:
7463 Handles opcode 0xa9
7464 ****************************************************************************/
7465 void x86emuOp_test_AX_IMM(u8 X86EMU_UNUSED(op1))
7467 u32 srcval;
7469 START_OF_INSTR();
7470 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7471 DECODE_PRINTF("TEST\tEAX,");
7472 srcval = fetch_long_imm();
7473 } else {
7474 DECODE_PRINTF("TEST\tAX,");
7475 srcval = fetch_word_imm();
7477 DECODE_PRINTF2("%x\n", srcval);
7478 TRACE_AND_STEP();
7479 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7480 test_long(M.x86.R_EAX, srcval);
7481 } else {
7482 test_word(M.x86.R_AX, (u16)srcval);
7484 DECODE_CLEAR_SEGOVR();
7485 END_OF_INSTR();
7488 /****************************************************************************
7489 REMARKS:
7490 Handles opcode 0xaa
7491 ****************************************************************************/
7492 void x86emuOp_stos_byte(u8 X86EMU_UNUSED(op1))
7494 int inc;
7496 START_OF_INSTR();
7497 DECODE_PRINTF("STOS\tBYTE\n");
7498 if (ACCESS_FLAG(F_DF)) /* down */
7499 inc = -1;
7500 else
7501 inc = 1;
7502 TRACE_AND_STEP();
7503 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7504 /* dont care whether REPE or REPNE */
7505 /* move them until CX is ZERO. */
7506 while (M.x86.R_CX != 0) {
7507 store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL);
7508 M.x86.R_CX -= 1;
7509 M.x86.R_DI += inc;
7511 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7512 } else {
7513 store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL);
7514 M.x86.R_DI += inc;
7516 DECODE_CLEAR_SEGOVR();
7517 END_OF_INSTR();
7520 /****************************************************************************
7521 REMARKS:
7522 Handles opcode 0xab
7523 ****************************************************************************/
7524 void x86emuOp_stos_word(u8 X86EMU_UNUSED(op1))
7526 int inc;
7527 u32 count;
7529 START_OF_INSTR();
7530 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7531 DECODE_PRINTF("STOS\tDWORD\n");
7532 if (ACCESS_FLAG(F_DF)) /* down */
7533 inc = -4;
7534 else
7535 inc = 4;
7536 } else {
7537 DECODE_PRINTF("STOS\tWORD\n");
7538 if (ACCESS_FLAG(F_DF)) /* down */
7539 inc = -2;
7540 else
7541 inc = 2;
7543 TRACE_AND_STEP();
7544 count = 1;
7545 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7546 /* dont care whether REPE or REPNE */
7547 /* move them until CX is ZERO. */
7548 count = M.x86.R_CX;
7549 M.x86.R_CX = 0;
7550 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7552 while (count--) {
7553 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7554 store_data_long_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_EAX);
7555 } else {
7556 store_data_word_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AX);
7558 M.x86.R_DI += inc;
7560 DECODE_CLEAR_SEGOVR();
7561 END_OF_INSTR();
7564 /****************************************************************************
7565 REMARKS:
7566 Handles opcode 0xac
7567 ****************************************************************************/
7568 void x86emuOp_lods_byte(u8 X86EMU_UNUSED(op1))
7570 int inc;
7572 START_OF_INSTR();
7573 DECODE_PRINTF("LODS\tBYTE\n");
7574 TRACE_AND_STEP();
7575 if (ACCESS_FLAG(F_DF)) /* down */
7576 inc = -1;
7577 else
7578 inc = 1;
7579 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7580 /* dont care whether REPE or REPNE */
7581 /* move them until CX is ZERO. */
7582 while (M.x86.R_CX != 0) {
7583 M.x86.R_AL = fetch_data_byte(M.x86.R_SI);
7584 M.x86.R_CX -= 1;
7585 M.x86.R_SI += inc;
7587 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7588 } else {
7589 M.x86.R_AL = fetch_data_byte(M.x86.R_SI);
7590 M.x86.R_SI += inc;
7592 DECODE_CLEAR_SEGOVR();
7593 END_OF_INSTR();
7596 /****************************************************************************
7597 REMARKS:
7598 Handles opcode 0xad
7599 ****************************************************************************/
7600 void x86emuOp_lods_word(u8 X86EMU_UNUSED(op1))
7602 int inc;
7603 u32 count;
7605 START_OF_INSTR();
7606 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7607 DECODE_PRINTF("LODS\tDWORD\n");
7608 if (ACCESS_FLAG(F_DF)) /* down */
7609 inc = -4;
7610 else
7611 inc = 4;
7612 } else {
7613 DECODE_PRINTF("LODS\tWORD\n");
7614 if (ACCESS_FLAG(F_DF)) /* down */
7615 inc = -2;
7616 else
7617 inc = 2;
7619 TRACE_AND_STEP();
7620 count = 1;
7621 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7622 /* dont care whether REPE or REPNE */
7623 /* move them until CX is ZERO. */
7624 count = M.x86.R_CX;
7625 M.x86.R_CX = 0;
7626 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7628 while (count--) {
7629 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7630 M.x86.R_EAX = fetch_data_long(M.x86.R_SI);
7631 } else {
7632 M.x86.R_AX = fetch_data_word(M.x86.R_SI);
7634 M.x86.R_SI += inc;
7636 DECODE_CLEAR_SEGOVR();
7637 END_OF_INSTR();
7640 /****************************************************************************
7641 REMARKS:
7642 Handles opcode 0xae
7643 ****************************************************************************/
7644 void x86emuOp_scas_byte(u8 X86EMU_UNUSED(op1))
7646 s8 val2;
7647 int inc;
7649 START_OF_INSTR();
7650 DECODE_PRINTF("SCAS\tBYTE\n");
7651 TRACE_AND_STEP();
7652 if (ACCESS_FLAG(F_DF)) /* down */
7653 inc = -1;
7654 else
7655 inc = 1;
7656 if (M.x86.mode & SYSMODE_PREFIX_REPE) {
7657 /* REPE */
7658 /* move them until CX is ZERO. */
7659 while (M.x86.R_CX != 0) {
7660 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7661 cmp_byte(M.x86.R_AL, val2);
7662 M.x86.R_CX -= 1;
7663 M.x86.R_DI += inc;
7664 if (ACCESS_FLAG(F_ZF) == 0)
7665 break;
7667 M.x86.mode &= ~SYSMODE_PREFIX_REPE;
7668 } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
7669 /* REPNE */
7670 /* move them until CX is ZERO. */
7671 while (M.x86.R_CX != 0) {
7672 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7673 cmp_byte(M.x86.R_AL, val2);
7674 M.x86.R_CX -= 1;
7675 M.x86.R_DI += inc;
7676 if (ACCESS_FLAG(F_ZF))
7677 break; /* zero flag set means equal */
7679 M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
7680 } else {
7681 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7682 cmp_byte(M.x86.R_AL, val2);
7683 M.x86.R_DI += inc;
7685 DECODE_CLEAR_SEGOVR();
7686 END_OF_INSTR();
7689 /****************************************************************************
7690 REMARKS:
7691 Handles opcode 0xaf
7692 ****************************************************************************/
7693 void x86emuOp_scas_word(u8 X86EMU_UNUSED(op1))
7695 int inc;
7696 u32 val;
7698 START_OF_INSTR();
7699 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7700 DECODE_PRINTF("SCAS\tDWORD\n");
7701 if (ACCESS_FLAG(F_DF)) /* down */
7702 inc = -4;
7703 else
7704 inc = 4;
7705 } else {
7706 DECODE_PRINTF("SCAS\tWORD\n");
7707 if (ACCESS_FLAG(F_DF)) /* down */
7708 inc = -2;
7709 else
7710 inc = 2;
7712 TRACE_AND_STEP();
7713 if (M.x86.mode & SYSMODE_PREFIX_REPE) {
7714 /* REPE */
7715 /* move them until CX is ZERO. */
7716 while (M.x86.R_CX != 0) {
7717 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7718 val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7719 cmp_long(M.x86.R_EAX, val);
7720 } else {
7721 val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7722 cmp_word(M.x86.R_AX, (u16)val);
7724 M.x86.R_CX -= 1;
7725 M.x86.R_DI += inc;
7726 if (ACCESS_FLAG(F_ZF) == 0)
7727 break;
7729 M.x86.mode &= ~SYSMODE_PREFIX_REPE;
7730 } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
7731 /* REPNE */
7732 /* move them until CX is ZERO. */
7733 while (M.x86.R_CX != 0) {
7734 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7735 val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7736 cmp_long(M.x86.R_EAX, val);
7737 } else {
7738 val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7739 cmp_word(M.x86.R_AX, (u16)val);
7741 M.x86.R_CX -= 1;
7742 M.x86.R_DI += inc;
7743 if (ACCESS_FLAG(F_ZF))
7744 break; /* zero flag set means equal */
7746 M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
7747 } else {
7748 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7749 val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7750 cmp_long(M.x86.R_EAX, val);
7751 } else {
7752 val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7753 cmp_word(M.x86.R_AX, (u16)val);
7755 M.x86.R_DI += inc;
7757 DECODE_CLEAR_SEGOVR();
7758 END_OF_INSTR();
7761 /****************************************************************************
7762 REMARKS:
7763 Handles opcode 0xb0
7764 ****************************************************************************/
7765 void x86emuOp_mov_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
7767 u8 imm;
7769 START_OF_INSTR();
7770 DECODE_PRINTF("MOV\tAL,");
7771 imm = fetch_byte_imm();
7772 DECODE_PRINTF2("%x\n", imm);
7773 TRACE_AND_STEP();
7774 M.x86.R_AL = imm;
7775 DECODE_CLEAR_SEGOVR();
7776 END_OF_INSTR();
7779 /****************************************************************************
7780 REMARKS:
7781 Handles opcode 0xb1
7782 ****************************************************************************/
7783 void x86emuOp_mov_byte_CL_IMM(u8 X86EMU_UNUSED(op1))
7785 u8 imm;
7787 START_OF_INSTR();
7788 DECODE_PRINTF("MOV\tCL,");
7789 imm = fetch_byte_imm();
7790 DECODE_PRINTF2("%x\n", imm);
7791 TRACE_AND_STEP();
7792 M.x86.R_CL = imm;
7793 DECODE_CLEAR_SEGOVR();
7794 END_OF_INSTR();
7797 /****************************************************************************
7798 REMARKS:
7799 Handles opcode 0xb2
7800 ****************************************************************************/
7801 void x86emuOp_mov_byte_DL_IMM(u8 X86EMU_UNUSED(op1))
7803 u8 imm;
7805 START_OF_INSTR();
7806 DECODE_PRINTF("MOV\tDL,");
7807 imm = fetch_byte_imm();
7808 DECODE_PRINTF2("%x\n", imm);
7809 TRACE_AND_STEP();
7810 M.x86.R_DL = imm;
7811 DECODE_CLEAR_SEGOVR();
7812 END_OF_INSTR();
7815 /****************************************************************************
7816 REMARKS:
7817 Handles opcode 0xb3
7818 ****************************************************************************/
7819 void x86emuOp_mov_byte_BL_IMM(u8 X86EMU_UNUSED(op1))
7821 u8 imm;
7823 START_OF_INSTR();
7824 DECODE_PRINTF("MOV\tBL,");
7825 imm = fetch_byte_imm();
7826 DECODE_PRINTF2("%x\n", imm);
7827 TRACE_AND_STEP();
7828 M.x86.R_BL = imm;
7829 DECODE_CLEAR_SEGOVR();
7830 END_OF_INSTR();
7833 /****************************************************************************
7834 REMARKS:
7835 Handles opcode 0xb4
7836 ****************************************************************************/
7837 void x86emuOp_mov_byte_AH_IMM(u8 X86EMU_UNUSED(op1))
7839 u8 imm;
7841 START_OF_INSTR();
7842 DECODE_PRINTF("MOV\tAH,");
7843 imm = fetch_byte_imm();
7844 DECODE_PRINTF2("%x\n", imm);
7845 TRACE_AND_STEP();
7846 M.x86.R_AH = imm;
7847 DECODE_CLEAR_SEGOVR();
7848 END_OF_INSTR();
7851 /****************************************************************************
7852 REMARKS:
7853 Handles opcode 0xb5
7854 ****************************************************************************/
7855 void x86emuOp_mov_byte_CH_IMM(u8 X86EMU_UNUSED(op1))
7857 u8 imm;
7859 START_OF_INSTR();
7860 DECODE_PRINTF("MOV\tCH,");
7861 imm = fetch_byte_imm();
7862 DECODE_PRINTF2("%x\n", imm);
7863 TRACE_AND_STEP();
7864 M.x86.R_CH = imm;
7865 DECODE_CLEAR_SEGOVR();
7866 END_OF_INSTR();
7869 /****************************************************************************
7870 REMARKS:
7871 Handles opcode 0xb6
7872 ****************************************************************************/
7873 void x86emuOp_mov_byte_DH_IMM(u8 X86EMU_UNUSED(op1))
7875 u8 imm;
7877 START_OF_INSTR();
7878 DECODE_PRINTF("MOV\tDH,");
7879 imm = fetch_byte_imm();
7880 DECODE_PRINTF2("%x\n", imm);
7881 TRACE_AND_STEP();
7882 M.x86.R_DH = imm;
7883 DECODE_CLEAR_SEGOVR();
7884 END_OF_INSTR();
7887 /****************************************************************************
7888 REMARKS:
7889 Handles opcode 0xb7
7890 ****************************************************************************/
7891 void x86emuOp_mov_byte_BH_IMM(u8 X86EMU_UNUSED(op1))
7893 u8 imm;
7895 START_OF_INSTR();
7896 DECODE_PRINTF("MOV\tBH,");
7897 imm = fetch_byte_imm();
7898 DECODE_PRINTF2("%x\n", imm);
7899 TRACE_AND_STEP();
7900 M.x86.R_BH = imm;
7901 DECODE_CLEAR_SEGOVR();
7902 END_OF_INSTR();
7905 /****************************************************************************
7906 REMARKS:
7907 Handles opcode 0xb8
7908 ****************************************************************************/
7909 void x86emuOp_mov_word_AX_IMM(u8 X86EMU_UNUSED(op1))
7911 u32 srcval;
7913 START_OF_INSTR();
7914 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7915 DECODE_PRINTF("MOV\tEAX,");
7916 srcval = fetch_long_imm();
7917 } else {
7918 DECODE_PRINTF("MOV\tAX,");
7919 srcval = fetch_word_imm();
7921 DECODE_PRINTF2("%x\n", srcval);
7922 TRACE_AND_STEP();
7923 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7924 M.x86.R_EAX = srcval;
7925 } else {
7926 M.x86.R_AX = (u16)srcval;
7928 DECODE_CLEAR_SEGOVR();
7929 END_OF_INSTR();
7932 /****************************************************************************
7933 REMARKS:
7934 Handles opcode 0xb9
7935 ****************************************************************************/
7936 void x86emuOp_mov_word_CX_IMM(u8 X86EMU_UNUSED(op1))
7938 u32 srcval;
7940 START_OF_INSTR();
7941 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7942 DECODE_PRINTF("MOV\tECX,");
7943 srcval = fetch_long_imm();
7944 } else {
7945 DECODE_PRINTF("MOV\tCX,");
7946 srcval = fetch_word_imm();
7948 DECODE_PRINTF2("%x\n", srcval);
7949 TRACE_AND_STEP();
7950 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7951 M.x86.R_ECX = srcval;
7952 } else {
7953 M.x86.R_CX = (u16)srcval;
7955 DECODE_CLEAR_SEGOVR();
7956 END_OF_INSTR();
7959 /****************************************************************************
7960 REMARKS:
7961 Handles opcode 0xba
7962 ****************************************************************************/
7963 void x86emuOp_mov_word_DX_IMM(u8 X86EMU_UNUSED(op1))
7965 u32 srcval;
7967 START_OF_INSTR();
7968 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7969 DECODE_PRINTF("MOV\tEDX,");
7970 srcval = fetch_long_imm();
7971 } else {
7972 DECODE_PRINTF("MOV\tDX,");
7973 srcval = fetch_word_imm();
7975 DECODE_PRINTF2("%x\n", srcval);
7976 TRACE_AND_STEP();
7977 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7978 M.x86.R_EDX = srcval;
7979 } else {
7980 M.x86.R_DX = (u16)srcval;
7982 DECODE_CLEAR_SEGOVR();
7983 END_OF_INSTR();
7986 /****************************************************************************
7987 REMARKS:
7988 Handles opcode 0xbb
7989 ****************************************************************************/
7990 void x86emuOp_mov_word_BX_IMM(u8 X86EMU_UNUSED(op1))
7992 u32 srcval;
7994 START_OF_INSTR();
7995 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7996 DECODE_PRINTF("MOV\tEBX,");
7997 srcval = fetch_long_imm();
7998 } else {
7999 DECODE_PRINTF("MOV\tBX,");
8000 srcval = fetch_word_imm();
8002 DECODE_PRINTF2("%x\n", srcval);
8003 TRACE_AND_STEP();
8004 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8005 M.x86.R_EBX = srcval;
8006 } else {
8007 M.x86.R_BX = (u16)srcval;
8009 DECODE_CLEAR_SEGOVR();
8010 END_OF_INSTR();
8013 /****************************************************************************
8014 REMARKS:
8015 Handles opcode 0xbc
8016 ****************************************************************************/
8017 void x86emuOp_mov_word_SP_IMM(u8 X86EMU_UNUSED(op1))
8019 u32 srcval;
8021 START_OF_INSTR();
8022 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8023 DECODE_PRINTF("MOV\tESP,");
8024 srcval = fetch_long_imm();
8025 } else {
8026 DECODE_PRINTF("MOV\tSP,");
8027 srcval = fetch_word_imm();
8029 DECODE_PRINTF2("%x\n", srcval);
8030 TRACE_AND_STEP();
8031 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8032 M.x86.R_ESP = srcval;
8033 } else {
8034 M.x86.R_SP = (u16)srcval;
8036 DECODE_CLEAR_SEGOVR();
8037 END_OF_INSTR();
8040 /****************************************************************************
8041 REMARKS:
8042 Handles opcode 0xbd
8043 ****************************************************************************/
8044 void x86emuOp_mov_word_BP_IMM(u8 X86EMU_UNUSED(op1))
8046 u32 srcval;
8048 START_OF_INSTR();
8049 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8050 DECODE_PRINTF("MOV\tEBP,");
8051 srcval = fetch_long_imm();
8052 } else {
8053 DECODE_PRINTF("MOV\tBP,");
8054 srcval = fetch_word_imm();
8056 DECODE_PRINTF2("%x\n", srcval);
8057 TRACE_AND_STEP();
8058 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8059 M.x86.R_EBP = srcval;
8060 } else {
8061 M.x86.R_BP = (u16)srcval;
8063 DECODE_CLEAR_SEGOVR();
8064 END_OF_INSTR();
8067 /****************************************************************************
8068 REMARKS:
8069 Handles opcode 0xbe
8070 ****************************************************************************/
8071 void x86emuOp_mov_word_SI_IMM(u8 X86EMU_UNUSED(op1))
8073 u32 srcval;
8075 START_OF_INSTR();
8076 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8077 DECODE_PRINTF("MOV\tESI,");
8078 srcval = fetch_long_imm();
8079 } else {
8080 DECODE_PRINTF("MOV\tSI,");
8081 srcval = fetch_word_imm();
8083 DECODE_PRINTF2("%x\n", srcval);
8084 TRACE_AND_STEP();
8085 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8086 M.x86.R_ESI = srcval;
8087 } else {
8088 M.x86.R_SI = (u16)srcval;
8090 DECODE_CLEAR_SEGOVR();
8091 END_OF_INSTR();
8094 /****************************************************************************
8095 REMARKS:
8096 Handles opcode 0xbf
8097 ****************************************************************************/
8098 void x86emuOp_mov_word_DI_IMM(u8 X86EMU_UNUSED(op1))
8100 u32 srcval;
8102 START_OF_INSTR();
8103 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8104 DECODE_PRINTF("MOV\tEDI,");
8105 srcval = fetch_long_imm();
8106 } else {
8107 DECODE_PRINTF("MOV\tDI,");
8108 srcval = fetch_word_imm();
8110 DECODE_PRINTF2("%x\n", srcval);
8111 TRACE_AND_STEP();
8112 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8113 M.x86.R_EDI = srcval;
8114 } else {
8115 M.x86.R_DI = (u16)srcval;
8117 DECODE_CLEAR_SEGOVR();
8118 END_OF_INSTR();
8121 /* used by opcodes c0, d0, and d2. */
8122 static u8(*opcD0_byte_operation[])(u8 d, u8 s) =
8124 rol_byte,
8125 ror_byte,
8126 rcl_byte,
8127 rcr_byte,
8128 shl_byte,
8129 shr_byte,
8130 shl_byte, /* sal_byte === shl_byte by definition */
8131 sar_byte,
8134 /****************************************************************************
8135 REMARKS:
8136 Handles opcode 0xc0
8137 ****************************************************************************/
8138 void x86emuOp_opcC0_byte_RM_MEM(u8 X86EMU_UNUSED(op1))
8140 int mod, rl, rh;
8141 u8 *destreg;
8142 uint destoffset;
8143 u8 destval;
8144 u8 amt;
8147 * Yet another weirdo special case instruction format. Part of
8148 * the opcode held below in "RH". Doubly nested case would
8149 * result, except that the decoded instruction
8151 START_OF_INSTR();
8152 FETCH_DECODE_MODRM(mod, rh, rl);
8153 #ifdef DEBUG
8154 if (DEBUG_DECODE()) {
8156 switch (rh) {
8157 case 0:
8158 DECODE_PRINTF("ROL\t");
8159 break;
8160 case 1:
8161 DECODE_PRINTF("ROR\t");
8162 break;
8163 case 2:
8164 DECODE_PRINTF("RCL\t");
8165 break;
8166 case 3:
8167 DECODE_PRINTF("RCR\t");
8168 break;
8169 case 4:
8170 DECODE_PRINTF("SHL\t");
8171 break;
8172 case 5:
8173 DECODE_PRINTF("SHR\t");
8174 break;
8175 case 6:
8176 DECODE_PRINTF("SAL\t");
8177 break;
8178 case 7:
8179 DECODE_PRINTF("SAR\t");
8180 break;
8183 #endif
8184 /* know operation, decode the mod byte to find the addressing
8185 mode. */
8186 switch (mod) {
8187 case 0:
8188 DECODE_PRINTF("BYTE PTR ");
8189 destoffset = decode_rm00_address(rl);
8190 amt = fetch_byte_imm();
8191 DECODE_PRINTF2(",%x\n", amt);
8192 destval = fetch_data_byte(destoffset);
8193 TRACE_AND_STEP();
8194 destval = (*opcD0_byte_operation[rh]) (destval, amt);
8195 store_data_byte(destoffset, destval);
8196 break;
8197 case 1:
8198 DECODE_PRINTF("BYTE PTR ");
8199 destoffset = decode_rm01_address(rl);
8200 amt = fetch_byte_imm();
8201 DECODE_PRINTF2(",%x\n", amt);
8202 destval = fetch_data_byte(destoffset);
8203 TRACE_AND_STEP();
8204 destval = (*opcD0_byte_operation[rh]) (destval, amt);
8205 store_data_byte(destoffset, destval);
8206 break;
8207 case 2:
8208 DECODE_PRINTF("BYTE PTR ");
8209 destoffset = decode_rm10_address(rl);
8210 amt = fetch_byte_imm();
8211 DECODE_PRINTF2(",%x\n", amt);
8212 destval = fetch_data_byte(destoffset);
8213 TRACE_AND_STEP();
8214 destval = (*opcD0_byte_operation[rh]) (destval, amt);
8215 store_data_byte(destoffset, destval);
8216 break;
8217 case 3: /* register to register */
8218 destreg = DECODE_RM_BYTE_REGISTER(rl);
8219 amt = fetch_byte_imm();
8220 DECODE_PRINTF2(",%x\n", amt);
8221 TRACE_AND_STEP();
8222 destval = (*opcD0_byte_operation[rh]) (*destreg, amt);
8223 *destreg = destval;
8224 break;
8226 DECODE_CLEAR_SEGOVR();
8227 END_OF_INSTR();
8230 /* used by opcodes c1, d1, and d3. */
8231 static u16(*opcD1_word_operation[])(u16 s, u8 d) =
8233 rol_word,
8234 ror_word,
8235 rcl_word,
8236 rcr_word,
8237 shl_word,
8238 shr_word,
8239 shl_word, /* sal_byte === shl_byte by definition */
8240 sar_word,
8243 /* used by opcodes c1, d1, and d3. */
8244 static u32 (*opcD1_long_operation[])(u32 s, u8 d) =
8246 rol_long,
8247 ror_long,
8248 rcl_long,
8249 rcr_long,
8250 shl_long,
8251 shr_long,
8252 shl_long, /* sal_byte === shl_byte by definition */
8253 sar_long,
8256 /****************************************************************************
8257 REMARKS:
8258 Handles opcode 0xc1
8259 ****************************************************************************/
8260 void x86emuOp_opcC1_word_RM_MEM(u8 X86EMU_UNUSED(op1))
8262 int mod, rl, rh;
8263 uint destoffset;
8264 u8 amt;
8267 * Yet another weirdo special case instruction format. Part of
8268 * the opcode held below in "RH". Doubly nested case would
8269 * result, except that the decoded instruction
8271 START_OF_INSTR();
8272 FETCH_DECODE_MODRM(mod, rh, rl);
8273 #ifdef DEBUG
8274 if (DEBUG_DECODE()) {
8276 switch (rh) {
8277 case 0:
8278 DECODE_PRINTF("ROL\t");
8279 break;
8280 case 1:
8281 DECODE_PRINTF("ROR\t");
8282 break;
8283 case 2:
8284 DECODE_PRINTF("RCL\t");
8285 break;
8286 case 3:
8287 DECODE_PRINTF("RCR\t");
8288 break;
8289 case 4:
8290 DECODE_PRINTF("SHL\t");
8291 break;
8292 case 5:
8293 DECODE_PRINTF("SHR\t");
8294 break;
8295 case 6:
8296 DECODE_PRINTF("SAL\t");
8297 break;
8298 case 7:
8299 DECODE_PRINTF("SAR\t");
8300 break;
8303 #endif
8304 /* know operation, decode the mod byte to find the addressing
8305 mode. */
8306 switch (mod) {
8307 case 0:
8308 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8309 u32 destval;
8311 DECODE_PRINTF("DWORD PTR ");
8312 destoffset = decode_rm00_address(rl);
8313 amt = fetch_byte_imm();
8314 DECODE_PRINTF2(",%x\n", amt);
8315 destval = fetch_data_long(destoffset);
8316 TRACE_AND_STEP();
8317 destval = (*opcD1_long_operation[rh]) (destval, amt);
8318 store_data_long(destoffset, destval);
8319 } else {
8320 u16 destval;
8322 DECODE_PRINTF("WORD PTR ");
8323 destoffset = decode_rm00_address(rl);
8324 amt = fetch_byte_imm();
8325 DECODE_PRINTF2(",%x\n", amt);
8326 destval = fetch_data_word(destoffset);
8327 TRACE_AND_STEP();
8328 destval = (*opcD1_word_operation[rh]) (destval, amt);
8329 store_data_word(destoffset, destval);
8331 break;
8332 case 1:
8333 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8334 u32 destval;
8336 DECODE_PRINTF("DWORD PTR ");
8337 destoffset = decode_rm01_address(rl);
8338 amt = fetch_byte_imm();
8339 DECODE_PRINTF2(",%x\n", amt);
8340 destval = fetch_data_long(destoffset);
8341 TRACE_AND_STEP();
8342 destval = (*opcD1_long_operation[rh]) (destval, amt);
8343 store_data_long(destoffset, destval);
8344 } else {
8345 u16 destval;
8347 DECODE_PRINTF("WORD PTR ");
8348 destoffset = decode_rm01_address(rl);
8349 amt = fetch_byte_imm();
8350 DECODE_PRINTF2(",%x\n", amt);
8351 destval = fetch_data_word(destoffset);
8352 TRACE_AND_STEP();
8353 destval = (*opcD1_word_operation[rh]) (destval, amt);
8354 store_data_word(destoffset, destval);
8356 break;
8357 case 2:
8358 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8359 u32 destval;
8361 DECODE_PRINTF("DWORD PTR ");
8362 destoffset = decode_rm10_address(rl);
8363 amt = fetch_byte_imm();
8364 DECODE_PRINTF2(",%x\n", amt);
8365 destval = fetch_data_long(destoffset);
8366 TRACE_AND_STEP();
8367 destval = (*opcD1_long_operation[rh]) (destval, amt);
8368 store_data_long(destoffset, destval);
8369 } else {
8370 u16 destval;
8372 DECODE_PRINTF("WORD PTR ");
8373 destoffset = decode_rm10_address(rl);
8374 amt = fetch_byte_imm();
8375 DECODE_PRINTF2(",%x\n", amt);
8376 destval = fetch_data_word(destoffset);
8377 TRACE_AND_STEP();
8378 destval = (*opcD1_word_operation[rh]) (destval, amt);
8379 store_data_word(destoffset, destval);
8381 break;
8382 case 3: /* register to register */
8383 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8384 u32 *destreg;
8386 destreg = DECODE_RM_LONG_REGISTER(rl);
8387 amt = fetch_byte_imm();
8388 DECODE_PRINTF2(",%x\n", amt);
8389 TRACE_AND_STEP();
8390 *destreg = (*opcD1_long_operation[rh]) (*destreg, amt);
8391 } else {
8392 u16 *destreg;
8394 destreg = DECODE_RM_WORD_REGISTER(rl);
8395 amt = fetch_byte_imm();
8396 DECODE_PRINTF2(",%x\n", amt);
8397 TRACE_AND_STEP();
8398 *destreg = (*opcD1_word_operation[rh]) (*destreg, amt);
8400 break;
8402 DECODE_CLEAR_SEGOVR();
8403 END_OF_INSTR();
8406 /****************************************************************************
8407 REMARKS:
8408 Handles opcode 0xc2
8409 ****************************************************************************/
8410 void x86emuOp_ret_near_IMM(u8 X86EMU_UNUSED(op1))
8412 u16 imm;
8414 START_OF_INSTR();
8415 DECODE_PRINTF("RET\t");
8416 imm = fetch_word_imm();
8417 DECODE_PRINTF2("%x\n", imm);
8418 RETURN_TRACE("RET",M.x86.saved_cs,M.x86.saved_ip);
8419 TRACE_AND_STEP();
8420 M.x86.R_IP = pop_word();
8421 M.x86.R_SP += imm;
8422 DECODE_CLEAR_SEGOVR();
8423 END_OF_INSTR();
8426 /****************************************************************************
8427 REMARKS:
8428 Handles opcode 0xc3
8429 ****************************************************************************/
8430 void x86emuOp_ret_near(u8 X86EMU_UNUSED(op1))
8432 START_OF_INSTR();
8433 DECODE_PRINTF("RET\n");
8434 RETURN_TRACE("RET",M.x86.saved_cs,M.x86.saved_ip);
8435 TRACE_AND_STEP();
8436 M.x86.R_IP = pop_word();
8437 DECODE_CLEAR_SEGOVR();
8438 END_OF_INSTR();
8441 /****************************************************************************
8442 REMARKS:
8443 Handles opcode 0xc4
8444 ****************************************************************************/
8445 void x86emuOp_les_R_IMM(u8 X86EMU_UNUSED(op1))
8447 int mod, rh, rl;
8448 u16 *dstreg;
8449 uint srcoffset;
8451 START_OF_INSTR();
8452 DECODE_PRINTF("LES\t");
8453 FETCH_DECODE_MODRM(mod, rh, rl);
8454 switch (mod) {
8455 case 0:
8456 dstreg = DECODE_RM_WORD_REGISTER(rh);
8457 DECODE_PRINTF(",");
8458 srcoffset = decode_rm00_address(rl);
8459 DECODE_PRINTF("\n");
8460 TRACE_AND_STEP();
8461 *dstreg = fetch_data_word(srcoffset);
8462 M.x86.R_ES = fetch_data_word(srcoffset + 2);
8463 break;
8464 case 1:
8465 dstreg = DECODE_RM_WORD_REGISTER(rh);
8466 DECODE_PRINTF(",");
8467 srcoffset = decode_rm01_address(rl);
8468 DECODE_PRINTF("\n");
8469 TRACE_AND_STEP();
8470 *dstreg = fetch_data_word(srcoffset);
8471 M.x86.R_ES = fetch_data_word(srcoffset + 2);
8472 break;
8473 case 2:
8474 dstreg = DECODE_RM_WORD_REGISTER(rh);
8475 DECODE_PRINTF(",");
8476 srcoffset = decode_rm10_address(rl);
8477 DECODE_PRINTF("\n");
8478 TRACE_AND_STEP();
8479 *dstreg = fetch_data_word(srcoffset);
8480 M.x86.R_ES = fetch_data_word(srcoffset + 2);
8481 break;
8482 case 3: /* register to register */
8483 /* UNDEFINED! */
8484 TRACE_AND_STEP();
8486 DECODE_CLEAR_SEGOVR();
8487 END_OF_INSTR();
8490 /****************************************************************************
8491 REMARKS:
8492 Handles opcode 0xc5
8493 ****************************************************************************/
8494 void x86emuOp_lds_R_IMM(u8 X86EMU_UNUSED(op1))
8496 int mod, rh, rl;
8497 u16 *dstreg;
8498 uint srcoffset;
8500 START_OF_INSTR();
8501 DECODE_PRINTF("LDS\t");
8502 FETCH_DECODE_MODRM(mod, rh, rl);
8503 switch (mod) {
8504 case 0:
8505 dstreg = DECODE_RM_WORD_REGISTER(rh);
8506 DECODE_PRINTF(",");
8507 srcoffset = decode_rm00_address(rl);
8508 DECODE_PRINTF("\n");
8509 TRACE_AND_STEP();
8510 *dstreg = fetch_data_word(srcoffset);
8511 M.x86.R_DS = fetch_data_word(srcoffset + 2);
8512 break;
8513 case 1:
8514 dstreg = DECODE_RM_WORD_REGISTER(rh);
8515 DECODE_PRINTF(",");
8516 srcoffset = decode_rm01_address(rl);
8517 DECODE_PRINTF("\n");
8518 TRACE_AND_STEP();
8519 *dstreg = fetch_data_word(srcoffset);
8520 M.x86.R_DS = fetch_data_word(srcoffset + 2);
8521 break;
8522 case 2:
8523 dstreg = DECODE_RM_WORD_REGISTER(rh);
8524 DECODE_PRINTF(",");
8525 srcoffset = decode_rm10_address(rl);
8526 DECODE_PRINTF("\n");
8527 TRACE_AND_STEP();
8528 *dstreg = fetch_data_word(srcoffset);
8529 M.x86.R_DS = fetch_data_word(srcoffset + 2);
8530 break;
8531 case 3: /* register to register */
8532 /* UNDEFINED! */
8533 TRACE_AND_STEP();
8535 DECODE_CLEAR_SEGOVR();
8536 END_OF_INSTR();
8539 /****************************************************************************
8540 REMARKS:
8541 Handles opcode 0xc6
8542 ****************************************************************************/
8543 void x86emuOp_mov_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
8545 int mod, rl, rh;
8546 u8 *destreg;
8547 uint destoffset;
8548 u8 imm;
8550 START_OF_INSTR();
8551 DECODE_PRINTF("MOV\t");
8552 FETCH_DECODE_MODRM(mod, rh, rl);
8553 if (rh != 0) {
8554 DECODE_PRINTF("ILLEGAL DECODE OF OPCODE c6\n");
8555 HALT_SYS();
8557 switch (mod) {
8558 case 0:
8559 DECODE_PRINTF("BYTE PTR ");
8560 destoffset = decode_rm00_address(rl);
8561 imm = fetch_byte_imm();
8562 DECODE_PRINTF2(",%2x\n", imm);
8563 TRACE_AND_STEP();
8564 store_data_byte(destoffset, imm);
8565 break;
8566 case 1:
8567 DECODE_PRINTF("BYTE PTR ");
8568 destoffset = decode_rm01_address(rl);
8569 imm = fetch_byte_imm();
8570 DECODE_PRINTF2(",%2x\n", imm);
8571 TRACE_AND_STEP();
8572 store_data_byte(destoffset, imm);
8573 break;
8574 case 2:
8575 DECODE_PRINTF("BYTE PTR ");
8576 destoffset = decode_rm10_address(rl);
8577 imm = fetch_byte_imm();
8578 DECODE_PRINTF2(",%2x\n", imm);
8579 TRACE_AND_STEP();
8580 store_data_byte(destoffset, imm);
8581 break;
8582 case 3: /* register to register */
8583 destreg = DECODE_RM_BYTE_REGISTER(rl);
8584 imm = fetch_byte_imm();
8585 DECODE_PRINTF2(",%2x\n", imm);
8586 TRACE_AND_STEP();
8587 *destreg = imm;
8588 break;
8590 DECODE_CLEAR_SEGOVR();
8591 END_OF_INSTR();
8594 /****************************************************************************
8595 REMARKS:
8596 Handles opcode 0xc7
8597 ****************************************************************************/
8598 void x86emuOp_mov_word_RM_IMM(u8 X86EMU_UNUSED(op1))
8600 int mod, rl, rh;
8601 uint destoffset;
8603 START_OF_INSTR();
8604 DECODE_PRINTF("MOV\t");
8605 FETCH_DECODE_MODRM(mod, rh, rl);
8606 if (rh != 0) {
8607 DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n");
8608 HALT_SYS();
8610 switch (mod) {
8611 case 0:
8612 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8613 u32 imm;
8615 DECODE_PRINTF("DWORD PTR ");
8616 destoffset = decode_rm00_address(rl);
8617 imm = fetch_long_imm();
8618 DECODE_PRINTF2(",%x\n", imm);
8619 TRACE_AND_STEP();
8620 store_data_long(destoffset, imm);
8621 } else {
8622 u16 imm;
8624 DECODE_PRINTF("WORD PTR ");
8625 destoffset = decode_rm00_address(rl);
8626 imm = fetch_word_imm();
8627 DECODE_PRINTF2(",%x\n", imm);
8628 TRACE_AND_STEP();
8629 store_data_word(destoffset, imm);
8631 break;
8632 case 1:
8633 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8634 u32 imm;
8636 DECODE_PRINTF("DWORD PTR ");
8637 destoffset = decode_rm01_address(rl);
8638 imm = fetch_long_imm();
8639 DECODE_PRINTF2(",%x\n", imm);
8640 TRACE_AND_STEP();
8641 store_data_long(destoffset, imm);
8642 } else {
8643 u16 imm;
8645 DECODE_PRINTF("WORD PTR ");
8646 destoffset = decode_rm01_address(rl);
8647 imm = fetch_word_imm();
8648 DECODE_PRINTF2(",%x\n", imm);
8649 TRACE_AND_STEP();
8650 store_data_word(destoffset, imm);
8652 break;
8653 case 2:
8654 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8655 u32 imm;
8657 DECODE_PRINTF("DWORD PTR ");
8658 destoffset = decode_rm10_address(rl);
8659 imm = fetch_long_imm();
8660 DECODE_PRINTF2(",%x\n", imm);
8661 TRACE_AND_STEP();
8662 store_data_long(destoffset, imm);
8663 } else {
8664 u16 imm;
8666 DECODE_PRINTF("WORD PTR ");
8667 destoffset = decode_rm10_address(rl);
8668 imm = fetch_word_imm();
8669 DECODE_PRINTF2(",%x\n", imm);
8670 TRACE_AND_STEP();
8671 store_data_word(destoffset, imm);
8673 break;
8674 case 3: /* register to register */
8675 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8676 u32 *destreg;
8677 u32 imm;
8679 destreg = DECODE_RM_LONG_REGISTER(rl);
8680 imm = fetch_long_imm();
8681 DECODE_PRINTF2(",%x\n", imm);
8682 TRACE_AND_STEP();
8683 *destreg = imm;
8684 } else {
8685 u16 *destreg;
8686 u16 imm;
8688 destreg = DECODE_RM_WORD_REGISTER(rl);
8689 imm = fetch_word_imm();
8690 DECODE_PRINTF2(",%x\n", imm);
8691 TRACE_AND_STEP();
8692 *destreg = imm;
8694 break;
8696 DECODE_CLEAR_SEGOVR();
8697 END_OF_INSTR();
8700 /****************************************************************************
8701 REMARKS:
8702 Handles opcode 0xc8
8703 ****************************************************************************/
8704 void x86emuOp_enter(u8 X86EMU_UNUSED(op1))
8706 u16 local,frame_pointer;
8707 u8 nesting;
8708 int i;
8710 START_OF_INSTR();
8711 local = fetch_word_imm();
8712 nesting = fetch_byte_imm();
8713 DECODE_PRINTF2("ENTER %x\n", local);
8714 DECODE_PRINTF2(",%x\n", nesting);
8715 TRACE_AND_STEP();
8716 push_word(M.x86.R_BP);
8717 frame_pointer = M.x86.R_SP;
8718 if (nesting > 0) {
8719 for (i = 1; i < nesting; i++) {
8720 M.x86.R_BP -= 2;
8721 push_word(fetch_data_word_abs(M.x86.R_SS, M.x86.R_BP));
8723 push_word(frame_pointer);
8725 M.x86.R_BP = frame_pointer;
8726 M.x86.R_SP = (u16)(M.x86.R_SP - local);
8727 DECODE_CLEAR_SEGOVR();
8728 END_OF_INSTR();
8731 /****************************************************************************
8732 REMARKS:
8733 Handles opcode 0xc9
8734 ****************************************************************************/
8735 void x86emuOp_leave(u8 X86EMU_UNUSED(op1))
8737 START_OF_INSTR();
8738 DECODE_PRINTF("LEAVE\n");
8739 TRACE_AND_STEP();
8740 M.x86.R_SP = M.x86.R_BP;
8741 M.x86.R_BP = pop_word();
8742 DECODE_CLEAR_SEGOVR();
8743 END_OF_INSTR();
8746 /****************************************************************************
8747 REMARKS:
8748 Handles opcode 0xca
8749 ****************************************************************************/
8750 void x86emuOp_ret_far_IMM(u8 X86EMU_UNUSED(op1))
8752 u16 imm;
8754 START_OF_INSTR();
8755 DECODE_PRINTF("RETF\t");
8756 imm = fetch_word_imm();
8757 DECODE_PRINTF2("%x\n", imm);
8758 RETURN_TRACE("RETF",M.x86.saved_cs,M.x86.saved_ip);
8759 TRACE_AND_STEP();
8760 M.x86.R_IP = pop_word();
8761 M.x86.R_CS = pop_word();
8762 M.x86.R_SP += imm;
8763 DECODE_CLEAR_SEGOVR();
8764 END_OF_INSTR();
8767 /****************************************************************************
8768 REMARKS:
8769 Handles opcode 0xcb
8770 ****************************************************************************/
8771 void x86emuOp_ret_far(u8 X86EMU_UNUSED(op1))
8773 START_OF_INSTR();
8774 DECODE_PRINTF("RETF\n");
8775 RETURN_TRACE("RETF",M.x86.saved_cs,M.x86.saved_ip);
8776 TRACE_AND_STEP();
8777 M.x86.R_IP = pop_word();
8778 M.x86.R_CS = pop_word();
8779 DECODE_CLEAR_SEGOVR();
8780 END_OF_INSTR();
8783 /****************************************************************************
8784 REMARKS:
8785 Handles opcode 0xcc
8786 ****************************************************************************/
8787 void x86emuOp_int3(u8 X86EMU_UNUSED(op1))
8789 u16 tmp;
8791 START_OF_INSTR();
8792 DECODE_PRINTF("INT 3\n");
8793 tmp = (u16) mem_access_word(3 * 4 + 2);
8794 /* access the segment register */
8795 TRACE_AND_STEP();
8796 if (_X86EMU_intrTab[3]) {
8797 (*_X86EMU_intrTab[3])(3);
8798 } else {
8799 push_word((u16)M.x86.R_FLG);
8800 CLEAR_FLAG(F_IF);
8801 CLEAR_FLAG(F_TF);
8802 push_word(M.x86.R_CS);
8803 M.x86.R_CS = mem_access_word(3 * 4 + 2);
8804 push_word(M.x86.R_IP);
8805 M.x86.R_IP = mem_access_word(3 * 4);
8807 DECODE_CLEAR_SEGOVR();
8808 END_OF_INSTR();
8811 /****************************************************************************
8812 REMARKS:
8813 Handles opcode 0xcd
8814 ****************************************************************************/
8815 void x86emuOp_int_IMM(u8 X86EMU_UNUSED(op1))
8817 u16 tmp;
8818 u8 intnum;
8820 START_OF_INSTR();
8821 DECODE_PRINTF("INT\t");
8822 intnum = fetch_byte_imm();
8823 DECODE_PRINTF2("%x\n", intnum);
8824 tmp = mem_access_word(intnum * 4 + 2);
8825 TRACE_AND_STEP();
8826 if (_X86EMU_intrTab[intnum]) {
8827 (*_X86EMU_intrTab[intnum])(intnum);
8828 } else {
8829 push_word((u16)M.x86.R_FLG);
8830 CLEAR_FLAG(F_IF);
8831 CLEAR_FLAG(F_TF);
8832 push_word(M.x86.R_CS);
8833 M.x86.R_CS = mem_access_word(intnum * 4 + 2);
8834 push_word(M.x86.R_IP);
8835 M.x86.R_IP = mem_access_word(intnum * 4);
8837 DECODE_CLEAR_SEGOVR();
8838 END_OF_INSTR();
8841 /****************************************************************************
8842 REMARKS:
8843 Handles opcode 0xce
8844 ****************************************************************************/
8845 void x86emuOp_into(u8 X86EMU_UNUSED(op1))
8847 u16 tmp;
8849 START_OF_INSTR();
8850 DECODE_PRINTF("INTO\n");
8851 TRACE_AND_STEP();
8852 if (ACCESS_FLAG(F_OF)) {
8853 tmp = mem_access_word(4 * 4 + 2);
8854 if (_X86EMU_intrTab[4]) {
8855 (*_X86EMU_intrTab[4])(4);
8856 } else {
8857 push_word((u16)M.x86.R_FLG);
8858 CLEAR_FLAG(F_IF);
8859 CLEAR_FLAG(F_TF);
8860 push_word(M.x86.R_CS);
8861 M.x86.R_CS = mem_access_word(4 * 4 + 2);
8862 push_word(M.x86.R_IP);
8863 M.x86.R_IP = mem_access_word(4 * 4);
8866 DECODE_CLEAR_SEGOVR();
8867 END_OF_INSTR();
8870 /****************************************************************************
8871 REMARKS:
8872 Handles opcode 0xcf
8873 ****************************************************************************/
8874 void x86emuOp_iret(u8 X86EMU_UNUSED(op1))
8876 START_OF_INSTR();
8877 DECODE_PRINTF("IRET\n");
8879 TRACE_AND_STEP();
8881 M.x86.R_IP = pop_word();
8882 M.x86.R_CS = pop_word();
8883 M.x86.R_FLG = pop_word();
8884 DECODE_CLEAR_SEGOVR();
8885 END_OF_INSTR();
8888 /****************************************************************************
8889 REMARKS:
8890 Handles opcode 0xd0
8891 ****************************************************************************/
8892 void x86emuOp_opcD0_byte_RM_1(u8 X86EMU_UNUSED(op1))
8894 int mod, rl, rh;
8895 u8 *destreg;
8896 uint destoffset;
8897 u8 destval;
8900 * Yet another weirdo special case instruction format. Part of
8901 * the opcode held below in "RH". Doubly nested case would
8902 * result, except that the decoded instruction
8904 START_OF_INSTR();
8905 FETCH_DECODE_MODRM(mod, rh, rl);
8906 #ifdef DEBUG
8907 if (DEBUG_DECODE()) {
8908 switch (rh) {
8909 case 0:
8910 DECODE_PRINTF("ROL\t");
8911 break;
8912 case 1:
8913 DECODE_PRINTF("ROR\t");
8914 break;
8915 case 2:
8916 DECODE_PRINTF("RCL\t");
8917 break;
8918 case 3:
8919 DECODE_PRINTF("RCR\t");
8920 break;
8921 case 4:
8922 DECODE_PRINTF("SHL\t");
8923 break;
8924 case 5:
8925 DECODE_PRINTF("SHR\t");
8926 break;
8927 case 6:
8928 DECODE_PRINTF("SAL\t");
8929 break;
8930 case 7:
8931 DECODE_PRINTF("SAR\t");
8932 break;
8935 #endif
8936 /* know operation, decode the mod byte to find the addressing
8937 mode. */
8938 switch (mod) {
8939 case 0:
8940 DECODE_PRINTF("BYTE PTR ");
8941 destoffset = decode_rm00_address(rl);
8942 DECODE_PRINTF(",1\n");
8943 destval = fetch_data_byte(destoffset);
8944 TRACE_AND_STEP();
8945 destval = (*opcD0_byte_operation[rh]) (destval, 1);
8946 store_data_byte(destoffset, destval);
8947 break;
8948 case 1:
8949 DECODE_PRINTF("BYTE PTR ");
8950 destoffset = decode_rm01_address(rl);
8951 DECODE_PRINTF(",1\n");
8952 destval = fetch_data_byte(destoffset);
8953 TRACE_AND_STEP();
8954 destval = (*opcD0_byte_operation[rh]) (destval, 1);
8955 store_data_byte(destoffset, destval);
8956 break;
8957 case 2:
8958 DECODE_PRINTF("BYTE PTR ");
8959 destoffset = decode_rm10_address(rl);
8960 DECODE_PRINTF(",1\n");
8961 destval = fetch_data_byte(destoffset);
8962 TRACE_AND_STEP();
8963 destval = (*opcD0_byte_operation[rh]) (destval, 1);
8964 store_data_byte(destoffset, destval);
8965 break;
8966 case 3: /* register to register */
8967 destreg = DECODE_RM_BYTE_REGISTER(rl);
8968 DECODE_PRINTF(",1\n");
8969 TRACE_AND_STEP();
8970 destval = (*opcD0_byte_operation[rh]) (*destreg, 1);
8971 *destreg = destval;
8972 break;
8974 DECODE_CLEAR_SEGOVR();
8975 END_OF_INSTR();
8978 /****************************************************************************
8979 REMARKS:
8980 Handles opcode 0xd1
8981 ****************************************************************************/
8982 void x86emuOp_opcD1_word_RM_1(u8 X86EMU_UNUSED(op1))
8984 int mod, rl, rh;
8985 uint destoffset;
8988 * Yet another weirdo special case instruction format. Part of
8989 * the opcode held below in "RH". Doubly nested case would
8990 * result, except that the decoded instruction
8992 START_OF_INSTR();
8993 FETCH_DECODE_MODRM(mod, rh, rl);
8994 #ifdef DEBUG
8995 if (DEBUG_DECODE()) {
8996 switch (rh) {
8997 case 0:
8998 DECODE_PRINTF("ROL\t");
8999 break;
9000 case 1:
9001 DECODE_PRINTF("ROR\t");
9002 break;
9003 case 2:
9004 DECODE_PRINTF("RCL\t");
9005 break;
9006 case 3:
9007 DECODE_PRINTF("RCR\t");
9008 break;
9009 case 4:
9010 DECODE_PRINTF("SHL\t");
9011 break;
9012 case 5:
9013 DECODE_PRINTF("SHR\t");
9014 break;
9015 case 6:
9016 DECODE_PRINTF("SAL\t");
9017 break;
9018 case 7:
9019 DECODE_PRINTF("SAR\t");
9020 break;
9023 #endif
9024 /* know operation, decode the mod byte to find the addressing
9025 mode. */
9026 switch (mod) {
9027 case 0:
9028 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9029 u32 destval;
9031 DECODE_PRINTF("DWORD PTR ");
9032 destoffset = decode_rm00_address(rl);
9033 DECODE_PRINTF(",1\n");
9034 destval = fetch_data_long(destoffset);
9035 TRACE_AND_STEP();
9036 destval = (*opcD1_long_operation[rh]) (destval, 1);
9037 store_data_long(destoffset, destval);
9038 } else {
9039 u16 destval;
9041 DECODE_PRINTF("WORD PTR ");
9042 destoffset = decode_rm00_address(rl);
9043 DECODE_PRINTF(",1\n");
9044 destval = fetch_data_word(destoffset);
9045 TRACE_AND_STEP();
9046 destval = (*opcD1_word_operation[rh]) (destval, 1);
9047 store_data_word(destoffset, destval);
9049 break;
9050 case 1:
9051 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9052 u32 destval;
9054 DECODE_PRINTF("DWORD PTR ");
9055 destoffset = decode_rm01_address(rl);
9056 DECODE_PRINTF(",1\n");
9057 destval = fetch_data_long(destoffset);
9058 TRACE_AND_STEP();
9059 destval = (*opcD1_long_operation[rh]) (destval, 1);
9060 store_data_long(destoffset, destval);
9061 } else {
9062 u16 destval;
9064 DECODE_PRINTF("WORD PTR ");
9065 destoffset = decode_rm01_address(rl);
9066 DECODE_PRINTF(",1\n");
9067 destval = fetch_data_word(destoffset);
9068 TRACE_AND_STEP();
9069 destval = (*opcD1_word_operation[rh]) (destval, 1);
9070 store_data_word(destoffset, destval);
9072 break;
9073 case 2:
9074 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9075 u32 destval;
9077 DECODE_PRINTF("DWORD PTR ");
9078 destoffset = decode_rm10_address(rl);
9079 DECODE_PRINTF(",1\n");
9080 destval = fetch_data_long(destoffset);
9081 TRACE_AND_STEP();
9082 destval = (*opcD1_long_operation[rh]) (destval, 1);
9083 store_data_long(destoffset, destval);
9084 } else {
9085 u16 destval;
9087 DECODE_PRINTF("BYTE PTR ");
9088 destoffset = decode_rm10_address(rl);
9089 DECODE_PRINTF(",1\n");
9090 destval = fetch_data_word(destoffset);
9091 TRACE_AND_STEP();
9092 destval = (*opcD1_word_operation[rh]) (destval, 1);
9093 store_data_word(destoffset, destval);
9095 break;
9096 case 3: /* register to register */
9097 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9098 u32 destval;
9099 u32 *destreg;
9101 destreg = DECODE_RM_LONG_REGISTER(rl);
9102 DECODE_PRINTF(",1\n");
9103 TRACE_AND_STEP();
9104 destval = (*opcD1_long_operation[rh]) (*destreg, 1);
9105 *destreg = destval;
9106 } else {
9107 u16 destval;
9108 u16 *destreg;
9110 destreg = DECODE_RM_WORD_REGISTER(rl);
9111 DECODE_PRINTF(",1\n");
9112 TRACE_AND_STEP();
9113 destval = (*opcD1_word_operation[rh]) (*destreg, 1);
9114 *destreg = destval;
9116 break;
9118 DECODE_CLEAR_SEGOVR();
9119 END_OF_INSTR();
9122 /****************************************************************************
9123 REMARKS:
9124 Handles opcode 0xd2
9125 ****************************************************************************/
9126 void x86emuOp_opcD2_byte_RM_CL(u8 X86EMU_UNUSED(op1))
9128 int mod, rl, rh;
9129 u8 *destreg;
9130 uint destoffset;
9131 u8 destval;
9132 u8 amt;
9135 * Yet another weirdo special case instruction format. Part of
9136 * the opcode held below in "RH". Doubly nested case would
9137 * result, except that the decoded instruction
9139 START_OF_INSTR();
9140 FETCH_DECODE_MODRM(mod, rh, rl);
9141 #ifdef DEBUG
9142 if (DEBUG_DECODE()) {
9143 switch (rh) {
9144 case 0:
9145 DECODE_PRINTF("ROL\t");
9146 break;
9147 case 1:
9148 DECODE_PRINTF("ROR\t");
9149 break;
9150 case 2:
9151 DECODE_PRINTF("RCL\t");
9152 break;
9153 case 3:
9154 DECODE_PRINTF("RCR\t");
9155 break;
9156 case 4:
9157 DECODE_PRINTF("SHL\t");
9158 break;
9159 case 5:
9160 DECODE_PRINTF("SHR\t");
9161 break;
9162 case 6:
9163 DECODE_PRINTF("SAL\t");
9164 break;
9165 case 7:
9166 DECODE_PRINTF("SAR\t");
9167 break;
9170 #endif
9171 /* know operation, decode the mod byte to find the addressing
9172 mode. */
9173 amt = M.x86.R_CL;
9174 switch (mod) {
9175 case 0:
9176 DECODE_PRINTF("BYTE PTR ");
9177 destoffset = decode_rm00_address(rl);
9178 DECODE_PRINTF(",CL\n");
9179 destval = fetch_data_byte(destoffset);
9180 TRACE_AND_STEP();
9181 destval = (*opcD0_byte_operation[rh]) (destval, amt);
9182 store_data_byte(destoffset, destval);
9183 break;
9184 case 1:
9185 DECODE_PRINTF("BYTE PTR ");
9186 destoffset = decode_rm01_address(rl);
9187 DECODE_PRINTF(",CL\n");
9188 destval = fetch_data_byte(destoffset);
9189 TRACE_AND_STEP();
9190 destval = (*opcD0_byte_operation[rh]) (destval, amt);
9191 store_data_byte(destoffset, destval);
9192 break;
9193 case 2:
9194 DECODE_PRINTF("BYTE PTR ");
9195 destoffset = decode_rm10_address(rl);
9196 DECODE_PRINTF(",CL\n");
9197 destval = fetch_data_byte(destoffset);
9198 TRACE_AND_STEP();
9199 destval = (*opcD0_byte_operation[rh]) (destval, amt);
9200 store_data_byte(destoffset, destval);
9201 break;
9202 case 3: /* register to register */
9203 destreg = DECODE_RM_BYTE_REGISTER(rl);
9204 DECODE_PRINTF(",CL\n");
9205 TRACE_AND_STEP();
9206 destval = (*opcD0_byte_operation[rh]) (*destreg, amt);
9207 *destreg = destval;
9208 break;
9210 DECODE_CLEAR_SEGOVR();
9211 END_OF_INSTR();
9214 /****************************************************************************
9215 REMARKS:
9216 Handles opcode 0xd3
9217 ****************************************************************************/
9218 void x86emuOp_opcD3_word_RM_CL(u8 X86EMU_UNUSED(op1))
9220 int mod, rl, rh;
9221 uint destoffset;
9222 u8 amt;
9225 * Yet another weirdo special case instruction format. Part of
9226 * the opcode held below in "RH". Doubly nested case would
9227 * result, except that the decoded instruction
9229 START_OF_INSTR();
9230 FETCH_DECODE_MODRM(mod, rh, rl);
9231 #ifdef DEBUG
9232 if (DEBUG_DECODE()) {
9233 switch (rh) {
9234 case 0:
9235 DECODE_PRINTF("ROL\t");
9236 break;
9237 case 1:
9238 DECODE_PRINTF("ROR\t");
9239 break;
9240 case 2:
9241 DECODE_PRINTF("RCL\t");
9242 break;
9243 case 3:
9244 DECODE_PRINTF("RCR\t");
9245 break;
9246 case 4:
9247 DECODE_PRINTF("SHL\t");
9248 break;
9249 case 5:
9250 DECODE_PRINTF("SHR\t");
9251 break;
9252 case 6:
9253 DECODE_PRINTF("SAL\t");
9254 break;
9255 case 7:
9256 DECODE_PRINTF("SAR\t");
9257 break;
9260 #endif
9261 /* know operation, decode the mod byte to find the addressing
9262 mode. */
9263 amt = M.x86.R_CL;
9264 switch (mod) {
9265 case 0:
9266 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9267 u32 destval;
9269 DECODE_PRINTF("DWORD PTR ");
9270 destoffset = decode_rm00_address(rl);
9271 DECODE_PRINTF(",CL\n");
9272 destval = fetch_data_long(destoffset);
9273 TRACE_AND_STEP();
9274 destval = (*opcD1_long_operation[rh]) (destval, amt);
9275 store_data_long(destoffset, destval);
9276 } else {
9277 u16 destval;
9279 DECODE_PRINTF("WORD PTR ");
9280 destoffset = decode_rm00_address(rl);
9281 DECODE_PRINTF(",CL\n");
9282 destval = fetch_data_word(destoffset);
9283 TRACE_AND_STEP();
9284 destval = (*opcD1_word_operation[rh]) (destval, amt);
9285 store_data_word(destoffset, destval);
9287 break;
9288 case 1:
9289 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9290 u32 destval;
9292 DECODE_PRINTF("DWORD PTR ");
9293 destoffset = decode_rm01_address(rl);
9294 DECODE_PRINTF(",CL\n");
9295 destval = fetch_data_long(destoffset);
9296 TRACE_AND_STEP();
9297 destval = (*opcD1_long_operation[rh]) (destval, amt);
9298 store_data_long(destoffset, destval);
9299 } else {
9300 u16 destval;
9302 DECODE_PRINTF("WORD PTR ");
9303 destoffset = decode_rm01_address(rl);
9304 DECODE_PRINTF(",CL\n");
9305 destval = fetch_data_word(destoffset);
9306 TRACE_AND_STEP();
9307 destval = (*opcD1_word_operation[rh]) (destval, amt);
9308 store_data_word(destoffset, destval);
9310 break;
9311 case 2:
9312 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9313 u32 destval;
9315 DECODE_PRINTF("DWORD PTR ");
9316 destoffset = decode_rm10_address(rl);
9317 DECODE_PRINTF(",CL\n");
9318 destval = fetch_data_long(destoffset);
9319 TRACE_AND_STEP();
9320 destval = (*opcD1_long_operation[rh]) (destval, amt);
9321 store_data_long(destoffset, destval);
9322 } else {
9323 u16 destval;
9325 DECODE_PRINTF("WORD PTR ");
9326 destoffset = decode_rm10_address(rl);
9327 DECODE_PRINTF(",CL\n");
9328 destval = fetch_data_word(destoffset);
9329 TRACE_AND_STEP();
9330 destval = (*opcD1_word_operation[rh]) (destval, amt);
9331 store_data_word(destoffset, destval);
9333 break;
9334 case 3: /* register to register */
9335 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9336 u32 *destreg;
9338 destreg = DECODE_RM_LONG_REGISTER(rl);
9339 DECODE_PRINTF(",CL\n");
9340 TRACE_AND_STEP();
9341 *destreg = (*opcD1_long_operation[rh]) (*destreg, amt);
9342 } else {
9343 u16 *destreg;
9345 destreg = DECODE_RM_WORD_REGISTER(rl);
9346 DECODE_PRINTF(",CL\n");
9347 TRACE_AND_STEP();
9348 *destreg = (*opcD1_word_operation[rh]) (*destreg, amt);
9350 break;
9352 DECODE_CLEAR_SEGOVR();
9353 END_OF_INSTR();
9356 /****************************************************************************
9357 REMARKS:
9358 Handles opcode 0xd4
9359 ****************************************************************************/
9360 void x86emuOp_aam(u8 X86EMU_UNUSED(op1))
9362 u8 a;
9364 START_OF_INSTR();
9365 DECODE_PRINTF("AAM\n");
9366 a = fetch_byte_imm(); /* this is a stupid encoding. */
9367 if (a != 10) {
9368 DECODE_PRINTF("ERROR DECODING AAM\n");
9369 TRACE_REGS();
9370 HALT_SYS();
9372 TRACE_AND_STEP();
9373 /* note the type change here --- returning AL and AH in AX. */
9374 M.x86.R_AX = aam_word(M.x86.R_AL);
9375 DECODE_CLEAR_SEGOVR();
9376 END_OF_INSTR();
9379 /****************************************************************************
9380 REMARKS:
9381 Handles opcode 0xd5
9382 ****************************************************************************/
9383 void x86emuOp_aad(u8 X86EMU_UNUSED(op1))
9385 u8 a;
9387 START_OF_INSTR();
9388 DECODE_PRINTF("AAD\n");
9389 a = fetch_byte_imm();
9390 TRACE_AND_STEP();
9391 M.x86.R_AX = aad_word(M.x86.R_AX);
9392 DECODE_CLEAR_SEGOVR();
9393 END_OF_INSTR();
9396 /* opcode 0xd6 ILLEGAL OPCODE */
9398 /****************************************************************************
9399 REMARKS:
9400 Handles opcode 0xd7
9401 ****************************************************************************/
9402 void x86emuOp_xlat(u8 X86EMU_UNUSED(op1))
9404 u16 addr;
9406 START_OF_INSTR();
9407 DECODE_PRINTF("XLAT\n");
9408 TRACE_AND_STEP();
9409 addr = (u16)(M.x86.R_BX + (u8)M.x86.R_AL);
9410 M.x86.R_AL = fetch_data_byte(addr);
9411 DECODE_CLEAR_SEGOVR();
9412 END_OF_INSTR();
9415 /* instuctions D8 .. DF are in i87_ops.c */
9417 /****************************************************************************
9418 REMARKS:
9419 Handles opcode 0xe0
9420 ****************************************************************************/
9421 void x86emuOp_loopne(u8 X86EMU_UNUSED(op1))
9423 s16 ip;
9425 START_OF_INSTR();
9426 DECODE_PRINTF("LOOPNE\t");
9427 ip = (s8) fetch_byte_imm();
9428 ip += (s16) M.x86.R_IP;
9429 DECODE_PRINTF2("%04x\n", ip);
9430 TRACE_AND_STEP();
9431 M.x86.R_CX -= 1;
9432 if (M.x86.R_CX != 0 && !ACCESS_FLAG(F_ZF)) /* CX != 0 and !ZF */
9433 M.x86.R_IP = ip;
9434 DECODE_CLEAR_SEGOVR();
9435 END_OF_INSTR();
9438 /****************************************************************************
9439 REMARKS:
9440 Handles opcode 0xe1
9441 ****************************************************************************/
9442 void x86emuOp_loope(u8 X86EMU_UNUSED(op1))
9444 s16 ip;
9446 START_OF_INSTR();
9447 DECODE_PRINTF("LOOPE\t");
9448 ip = (s8) fetch_byte_imm();
9449 ip += (s16) M.x86.R_IP;
9450 DECODE_PRINTF2("%04x\n", ip);
9451 TRACE_AND_STEP();
9452 M.x86.R_CX -= 1;
9453 if (M.x86.R_CX != 0 && ACCESS_FLAG(F_ZF)) /* CX != 0 and ZF */
9454 M.x86.R_IP = ip;
9455 DECODE_CLEAR_SEGOVR();
9456 END_OF_INSTR();
9459 /****************************************************************************
9460 REMARKS:
9461 Handles opcode 0xe2
9462 ****************************************************************************/
9463 void x86emuOp_loop(u8 X86EMU_UNUSED(op1))
9465 s16 ip;
9467 START_OF_INSTR();
9468 DECODE_PRINTF("LOOP\t");
9469 ip = (s8) fetch_byte_imm();
9470 ip += (s16) M.x86.R_IP;
9471 DECODE_PRINTF2("%04x\n", ip);
9472 TRACE_AND_STEP();
9473 M.x86.R_CX -= 1;
9474 if (M.x86.R_CX != 0)
9475 M.x86.R_IP = ip;
9476 DECODE_CLEAR_SEGOVR();
9477 END_OF_INSTR();
9480 /****************************************************************************
9481 REMARKS:
9482 Handles opcode 0xe3
9483 ****************************************************************************/
9484 void x86emuOp_jcxz(u8 X86EMU_UNUSED(op1))
9486 u16 target;
9487 s8 offset;
9489 /* jump to byte offset if overflow flag is set */
9490 START_OF_INSTR();
9491 DECODE_PRINTF("JCXZ\t");
9492 offset = (s8)fetch_byte_imm();
9493 target = (u16)(M.x86.R_IP + offset);
9494 DECODE_PRINTF2("%x\n", target);
9495 TRACE_AND_STEP();
9496 if (M.x86.R_CX == 0)
9497 M.x86.R_IP = target;
9498 DECODE_CLEAR_SEGOVR();
9499 END_OF_INSTR();
9502 /****************************************************************************
9503 REMARKS:
9504 Handles opcode 0xe4
9505 ****************************************************************************/
9506 void x86emuOp_in_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
9508 u8 port;
9510 START_OF_INSTR();
9511 DECODE_PRINTF("IN\t");
9512 port = (u8) fetch_byte_imm();
9513 DECODE_PRINTF2("%x,AL\n", port);
9514 TRACE_AND_STEP();
9515 M.x86.R_AL = (*sys_inb)(port);
9516 DECODE_CLEAR_SEGOVR();
9517 END_OF_INSTR();
9520 /****************************************************************************
9521 REMARKS:
9522 Handles opcode 0xe5
9523 ****************************************************************************/
9524 void x86emuOp_in_word_AX_IMM(u8 X86EMU_UNUSED(op1))
9526 u8 port;
9528 START_OF_INSTR();
9529 DECODE_PRINTF("IN\t");
9530 port = (u8) fetch_byte_imm();
9531 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9532 DECODE_PRINTF2("EAX,%x\n", port);
9533 } else {
9534 DECODE_PRINTF2("AX,%x\n", port);
9536 TRACE_AND_STEP();
9537 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9538 M.x86.R_EAX = (*sys_inl)(port);
9539 } else {
9540 M.x86.R_AX = (*sys_inw)(port);
9542 DECODE_CLEAR_SEGOVR();
9543 END_OF_INSTR();
9546 /****************************************************************************
9547 REMARKS:
9548 Handles opcode 0xe6
9549 ****************************************************************************/
9550 void x86emuOp_out_byte_IMM_AL(u8 X86EMU_UNUSED(op1))
9552 u8 port;
9554 START_OF_INSTR();
9555 DECODE_PRINTF("OUT\t");
9556 port = (u8) fetch_byte_imm();
9557 DECODE_PRINTF2("%x,AL\n", port);
9558 TRACE_AND_STEP();
9559 (*sys_outb)(port, M.x86.R_AL);
9560 DECODE_CLEAR_SEGOVR();
9561 END_OF_INSTR();
9564 /****************************************************************************
9565 REMARKS:
9566 Handles opcode 0xe7
9567 ****************************************************************************/
9568 void x86emuOp_out_word_IMM_AX(u8 X86EMU_UNUSED(op1))
9570 u8 port;
9572 START_OF_INSTR();
9573 DECODE_PRINTF("OUT\t");
9574 port = (u8) fetch_byte_imm();
9575 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9576 DECODE_PRINTF2("%x,EAX\n", port);
9577 } else {
9578 DECODE_PRINTF2("%x,AX\n", port);
9580 TRACE_AND_STEP();
9581 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9582 (*sys_outl)(port, M.x86.R_EAX);
9583 } else {
9584 (*sys_outw)(port, M.x86.R_AX);
9586 DECODE_CLEAR_SEGOVR();
9587 END_OF_INSTR();
9590 /****************************************************************************
9591 REMARKS:
9592 Handles opcode 0xe8
9593 ****************************************************************************/
9594 void x86emuOp_call_near_IMM(u8 X86EMU_UNUSED(op1))
9596 s16 ip;
9598 START_OF_INSTR();
9599 DECODE_PRINTF("CALL\t");
9600 ip = (s16) fetch_word_imm();
9601 ip += (s16) M.x86.R_IP; /* CHECK SIGN */
9602 DECODE_PRINTF2("%04x\n", ip);
9603 CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, M.x86.R_CS, ip, "");
9604 TRACE_AND_STEP();
9605 push_word(M.x86.R_IP);
9606 M.x86.R_IP = ip;
9607 DECODE_CLEAR_SEGOVR();
9608 END_OF_INSTR();
9611 /****************************************************************************
9612 REMARKS:
9613 Handles opcode 0xe9
9614 ****************************************************************************/
9615 void x86emuOp_jump_near_IMM(u8 X86EMU_UNUSED(op1))
9617 int ip;
9619 START_OF_INSTR();
9620 DECODE_PRINTF("JMP\t");
9621 ip = (s16)fetch_word_imm();
9622 ip += (s16)M.x86.R_IP;
9623 DECODE_PRINTF2("%04x\n", ip);
9624 TRACE_AND_STEP();
9625 M.x86.R_IP = (u16)ip;
9626 DECODE_CLEAR_SEGOVR();
9627 END_OF_INSTR();
9630 /****************************************************************************
9631 REMARKS:
9632 Handles opcode 0xea
9633 ****************************************************************************/
9634 void x86emuOp_jump_far_IMM(u8 X86EMU_UNUSED(op1))
9636 u16 cs, ip;
9638 START_OF_INSTR();
9639 DECODE_PRINTF("JMP\tFAR ");
9640 ip = fetch_word_imm();
9641 cs = fetch_word_imm();
9642 DECODE_PRINTF2("%04x:", cs);
9643 DECODE_PRINTF2("%04x\n", ip);
9644 TRACE_AND_STEP();
9645 M.x86.R_IP = ip;
9646 M.x86.R_CS = cs;
9647 DECODE_CLEAR_SEGOVR();
9648 END_OF_INSTR();
9651 /****************************************************************************
9652 REMARKS:
9653 Handles opcode 0xeb
9654 ****************************************************************************/
9655 void x86emuOp_jump_byte_IMM(u8 X86EMU_UNUSED(op1))
9657 u16 target;
9658 s8 offset;
9660 START_OF_INSTR();
9661 DECODE_PRINTF("JMP\t");
9662 offset = (s8)fetch_byte_imm();
9663 target = (u16)(M.x86.R_IP + offset);
9664 DECODE_PRINTF2("%x\n", target);
9665 TRACE_AND_STEP();
9666 M.x86.R_IP = target;
9667 DECODE_CLEAR_SEGOVR();
9668 END_OF_INSTR();
9671 /****************************************************************************
9672 REMARKS:
9673 Handles opcode 0xec
9674 ****************************************************************************/
9675 void x86emuOp_in_byte_AL_DX(u8 X86EMU_UNUSED(op1))
9677 START_OF_INSTR();
9678 DECODE_PRINTF("IN\tAL,DX\n");
9679 TRACE_AND_STEP();
9680 M.x86.R_AL = (*sys_inb)(M.x86.R_DX);
9681 DECODE_CLEAR_SEGOVR();
9682 END_OF_INSTR();
9685 /****************************************************************************
9686 REMARKS:
9687 Handles opcode 0xed
9688 ****************************************************************************/
9689 void x86emuOp_in_word_AX_DX(u8 X86EMU_UNUSED(op1))
9691 START_OF_INSTR();
9692 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9693 DECODE_PRINTF("IN\tEAX,DX\n");
9694 } else {
9695 DECODE_PRINTF("IN\tAX,DX\n");
9697 TRACE_AND_STEP();
9698 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9699 M.x86.R_EAX = (*sys_inl)(M.x86.R_DX);
9700 } else {
9701 M.x86.R_AX = (*sys_inw)(M.x86.R_DX);
9703 DECODE_CLEAR_SEGOVR();
9704 END_OF_INSTR();
9707 /****************************************************************************
9708 REMARKS:
9709 Handles opcode 0xee
9710 ****************************************************************************/
9711 void x86emuOp_out_byte_DX_AL(u8 X86EMU_UNUSED(op1))
9713 START_OF_INSTR();
9714 DECODE_PRINTF("OUT\tDX,AL\n");
9715 TRACE_AND_STEP();
9716 (*sys_outb)(M.x86.R_DX, M.x86.R_AL);
9717 DECODE_CLEAR_SEGOVR();
9718 END_OF_INSTR();
9721 /****************************************************************************
9722 REMARKS:
9723 Handles opcode 0xef
9724 ****************************************************************************/
9725 void x86emuOp_out_word_DX_AX(u8 X86EMU_UNUSED(op1))
9727 START_OF_INSTR();
9728 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9729 DECODE_PRINTF("OUT\tDX,EAX\n");
9730 } else {
9731 DECODE_PRINTF("OUT\tDX,AX\n");
9733 TRACE_AND_STEP();
9734 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9735 (*sys_outl)(M.x86.R_DX, M.x86.R_EAX);
9736 } else {
9737 (*sys_outw)(M.x86.R_DX, M.x86.R_AX);
9739 DECODE_CLEAR_SEGOVR();
9740 END_OF_INSTR();
9743 /****************************************************************************
9744 REMARKS:
9745 Handles opcode 0xf0
9746 ****************************************************************************/
9747 void x86emuOp_lock(u8 X86EMU_UNUSED(op1))
9749 START_OF_INSTR();
9750 DECODE_PRINTF("LOCK:\n");
9751 TRACE_AND_STEP();
9752 DECODE_CLEAR_SEGOVR();
9753 END_OF_INSTR();
9756 /*opcode 0xf1 ILLEGAL OPERATION */
9758 /****************************************************************************
9759 REMARKS:
9760 Handles opcode 0xf2
9761 ****************************************************************************/
9762 void x86emuOp_repne(u8 X86EMU_UNUSED(op1))
9764 START_OF_INSTR();
9765 DECODE_PRINTF("REPNE\n");
9766 TRACE_AND_STEP();
9767 M.x86.mode |= SYSMODE_PREFIX_REPNE;
9768 DECODE_CLEAR_SEGOVR();
9769 END_OF_INSTR();
9772 /****************************************************************************
9773 REMARKS:
9774 Handles opcode 0xf3
9775 ****************************************************************************/
9776 void x86emuOp_repe(u8 X86EMU_UNUSED(op1))
9778 START_OF_INSTR();
9779 DECODE_PRINTF("REPE\n");
9780 TRACE_AND_STEP();
9781 M.x86.mode |= SYSMODE_PREFIX_REPE;
9782 DECODE_CLEAR_SEGOVR();
9783 END_OF_INSTR();
9786 /****************************************************************************
9787 REMARKS:
9788 Handles opcode 0xf4
9789 ****************************************************************************/
9790 void x86emuOp_halt(u8 X86EMU_UNUSED(op1))
9792 START_OF_INSTR();
9793 DECODE_PRINTF("HALT\n");
9794 TRACE_AND_STEP();
9795 HALT_SYS();
9796 DECODE_CLEAR_SEGOVR();
9797 END_OF_INSTR();
9800 /****************************************************************************
9801 REMARKS:
9802 Handles opcode 0xf5
9803 ****************************************************************************/
9804 void x86emuOp_cmc(u8 X86EMU_UNUSED(op1))
9806 /* complement the carry flag. */
9807 START_OF_INSTR();
9808 DECODE_PRINTF("CMC\n");
9809 TRACE_AND_STEP();
9810 TOGGLE_FLAG(F_CF);
9811 DECODE_CLEAR_SEGOVR();
9812 END_OF_INSTR();
9815 /****************************************************************************
9816 REMARKS:
9817 Handles opcode 0xf6
9818 ****************************************************************************/
9819 void x86emuOp_opcF6_byte_RM(u8 X86EMU_UNUSED(op1))
9821 int mod, rl, rh;
9822 u8 *destreg;
9823 uint destoffset;
9824 u8 destval, srcval;
9826 /* long, drawn out code follows. Double switch for a total
9827 of 32 cases. */
9828 START_OF_INSTR();
9829 FETCH_DECODE_MODRM(mod, rh, rl);
9830 switch (mod) {
9831 case 0: /* mod=00 */
9832 switch (rh) {
9833 case 0: /* test byte imm */
9834 DECODE_PRINTF("TEST\tBYTE PTR ");
9835 destoffset = decode_rm00_address(rl);
9836 DECODE_PRINTF(",");
9837 srcval = fetch_byte_imm();
9838 DECODE_PRINTF2("%02x\n", srcval);
9839 destval = fetch_data_byte(destoffset);
9840 TRACE_AND_STEP();
9841 test_byte(destval, srcval);
9842 break;
9843 case 1:
9844 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
9845 HALT_SYS();
9846 break;
9847 case 2:
9848 DECODE_PRINTF("NOT\tBYTE PTR ");
9849 destoffset = decode_rm00_address(rl);
9850 DECODE_PRINTF("\n");
9851 destval = fetch_data_byte(destoffset);
9852 TRACE_AND_STEP();
9853 destval = not_byte(destval);
9854 store_data_byte(destoffset, destval);
9855 break;
9856 case 3:
9857 DECODE_PRINTF("NEG\tBYTE PTR ");
9858 destoffset = decode_rm00_address(rl);
9859 DECODE_PRINTF("\n");
9860 destval = fetch_data_byte(destoffset);
9861 TRACE_AND_STEP();
9862 destval = neg_byte(destval);
9863 store_data_byte(destoffset, destval);
9864 break;
9865 case 4:
9866 DECODE_PRINTF("MUL\tBYTE PTR ");
9867 destoffset = decode_rm00_address(rl);
9868 DECODE_PRINTF("\n");
9869 destval = fetch_data_byte(destoffset);
9870 TRACE_AND_STEP();
9871 mul_byte(destval);
9872 break;
9873 case 5:
9874 DECODE_PRINTF("IMUL\tBYTE PTR ");
9875 destoffset = decode_rm00_address(rl);
9876 DECODE_PRINTF("\n");
9877 destval = fetch_data_byte(destoffset);
9878 TRACE_AND_STEP();
9879 imul_byte(destval);
9880 break;
9881 case 6:
9882 DECODE_PRINTF("DIV\tBYTE PTR ");
9883 destoffset = decode_rm00_address(rl);
9884 DECODE_PRINTF("\n");
9885 destval = fetch_data_byte(destoffset);
9886 TRACE_AND_STEP();
9887 div_byte(destval);
9888 break;
9889 case 7:
9890 DECODE_PRINTF("IDIV\tBYTE PTR ");
9891 destoffset = decode_rm00_address(rl);
9892 DECODE_PRINTF("\n");
9893 destval = fetch_data_byte(destoffset);
9894 TRACE_AND_STEP();
9895 idiv_byte(destval);
9896 break;
9898 break; /* end mod==00 */
9899 case 1: /* mod=01 */
9900 switch (rh) {
9901 case 0: /* test byte imm */
9902 DECODE_PRINTF("TEST\tBYTE PTR ");
9903 destoffset = decode_rm01_address(rl);
9904 DECODE_PRINTF(",");
9905 srcval = fetch_byte_imm();
9906 DECODE_PRINTF2("%02x\n", srcval);
9907 destval = fetch_data_byte(destoffset);
9908 TRACE_AND_STEP();
9909 test_byte(destval, srcval);
9910 break;
9911 case 1:
9912 DECODE_PRINTF("ILLEGAL OP MOD=01 RH=01 OP=F6\n");
9913 HALT_SYS();
9914 break;
9915 case 2:
9916 DECODE_PRINTF("NOT\tBYTE PTR ");
9917 destoffset = decode_rm01_address(rl);
9918 DECODE_PRINTF("\n");
9919 destval = fetch_data_byte(destoffset);
9920 TRACE_AND_STEP();
9921 destval = not_byte(destval);
9922 store_data_byte(destoffset, destval);
9923 break;
9924 case 3:
9925 DECODE_PRINTF("NEG\tBYTE PTR ");
9926 destoffset = decode_rm01_address(rl);
9927 DECODE_PRINTF("\n");
9928 destval = fetch_data_byte(destoffset);
9929 TRACE_AND_STEP();
9930 destval = neg_byte(destval);
9931 store_data_byte(destoffset, destval);
9932 break;
9933 case 4:
9934 DECODE_PRINTF("MUL\tBYTE PTR ");
9935 destoffset = decode_rm01_address(rl);
9936 DECODE_PRINTF("\n");
9937 destval = fetch_data_byte(destoffset);
9938 TRACE_AND_STEP();
9939 mul_byte(destval);
9940 break;
9941 case 5:
9942 DECODE_PRINTF("IMUL\tBYTE PTR ");
9943 destoffset = decode_rm01_address(rl);
9944 DECODE_PRINTF("\n");
9945 destval = fetch_data_byte(destoffset);
9946 TRACE_AND_STEP();
9947 imul_byte(destval);
9948 break;
9949 case 6:
9950 DECODE_PRINTF("DIV\tBYTE PTR ");
9951 destoffset = decode_rm01_address(rl);
9952 DECODE_PRINTF("\n");
9953 destval = fetch_data_byte(destoffset);
9954 TRACE_AND_STEP();
9955 div_byte(destval);
9956 break;
9957 case 7:
9958 DECODE_PRINTF("IDIV\tBYTE PTR ");
9959 destoffset = decode_rm01_address(rl);
9960 DECODE_PRINTF("\n");
9961 destval = fetch_data_byte(destoffset);
9962 TRACE_AND_STEP();
9963 idiv_byte(destval);
9964 break;
9966 break; /* end mod==01 */
9967 case 2: /* mod=10 */
9968 switch (rh) {
9969 case 0: /* test byte imm */
9970 DECODE_PRINTF("TEST\tBYTE PTR ");
9971 destoffset = decode_rm10_address(rl);
9972 DECODE_PRINTF(",");
9973 srcval = fetch_byte_imm();
9974 DECODE_PRINTF2("%02x\n", srcval);
9975 destval = fetch_data_byte(destoffset);
9976 TRACE_AND_STEP();
9977 test_byte(destval, srcval);
9978 break;
9979 case 1:
9980 DECODE_PRINTF("ILLEGAL OP MOD=10 RH=01 OP=F6\n");
9981 HALT_SYS();
9982 break;
9983 case 2:
9984 DECODE_PRINTF("NOT\tBYTE PTR ");
9985 destoffset = decode_rm10_address(rl);
9986 DECODE_PRINTF("\n");
9987 destval = fetch_data_byte(destoffset);
9988 TRACE_AND_STEP();
9989 destval = not_byte(destval);
9990 store_data_byte(destoffset, destval);
9991 break;
9992 case 3:
9993 DECODE_PRINTF("NEG\tBYTE PTR ");
9994 destoffset = decode_rm10_address(rl);
9995 DECODE_PRINTF("\n");
9996 destval = fetch_data_byte(destoffset);
9997 TRACE_AND_STEP();
9998 destval = neg_byte(destval);
9999 store_data_byte(destoffset, destval);
10000 break;
10001 case 4:
10002 DECODE_PRINTF("MUL\tBYTE PTR ");
10003 destoffset = decode_rm10_address(rl);
10004 DECODE_PRINTF("\n");
10005 destval = fetch_data_byte(destoffset);
10006 TRACE_AND_STEP();
10007 mul_byte(destval);
10008 break;
10009 case 5:
10010 DECODE_PRINTF("IMUL\tBYTE PTR ");
10011 destoffset = decode_rm10_address(rl);
10012 DECODE_PRINTF("\n");
10013 destval = fetch_data_byte(destoffset);
10014 TRACE_AND_STEP();
10015 imul_byte(destval);
10016 break;
10017 case 6:
10018 DECODE_PRINTF("DIV\tBYTE PTR ");
10019 destoffset = decode_rm10_address(rl);
10020 DECODE_PRINTF("\n");
10021 destval = fetch_data_byte(destoffset);
10022 TRACE_AND_STEP();
10023 div_byte(destval);
10024 break;
10025 case 7:
10026 DECODE_PRINTF("IDIV\tBYTE PTR ");
10027 destoffset = decode_rm10_address(rl);
10028 DECODE_PRINTF("\n");
10029 destval = fetch_data_byte(destoffset);
10030 TRACE_AND_STEP();
10031 idiv_byte(destval);
10032 break;
10034 break; /* end mod==10 */
10035 case 3: /* mod=11 */
10036 switch (rh) {
10037 case 0: /* test byte imm */
10038 DECODE_PRINTF("TEST\t");
10039 destreg = DECODE_RM_BYTE_REGISTER(rl);
10040 DECODE_PRINTF(",");
10041 srcval = fetch_byte_imm();
10042 DECODE_PRINTF2("%02x\n", srcval);
10043 TRACE_AND_STEP();
10044 test_byte(*destreg, srcval);
10045 break;
10046 case 1:
10047 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
10048 HALT_SYS();
10049 break;
10050 case 2:
10051 DECODE_PRINTF("NOT\t");
10052 destreg = DECODE_RM_BYTE_REGISTER(rl);
10053 DECODE_PRINTF("\n");
10054 TRACE_AND_STEP();
10055 *destreg = not_byte(*destreg);
10056 break;
10057 case 3:
10058 DECODE_PRINTF("NEG\t");
10059 destreg = DECODE_RM_BYTE_REGISTER(rl);
10060 DECODE_PRINTF("\n");
10061 TRACE_AND_STEP();
10062 *destreg = neg_byte(*destreg);
10063 break;
10064 case 4:
10065 DECODE_PRINTF("MUL\t");
10066 destreg = DECODE_RM_BYTE_REGISTER(rl);
10067 DECODE_PRINTF("\n");
10068 TRACE_AND_STEP();
10069 mul_byte(*destreg); /*!!! */
10070 break;
10071 case 5:
10072 DECODE_PRINTF("IMUL\t");
10073 destreg = DECODE_RM_BYTE_REGISTER(rl);
10074 DECODE_PRINTF("\n");
10075 TRACE_AND_STEP();
10076 imul_byte(*destreg);
10077 break;
10078 case 6:
10079 DECODE_PRINTF("DIV\t");
10080 destreg = DECODE_RM_BYTE_REGISTER(rl);
10081 DECODE_PRINTF("\n");
10082 TRACE_AND_STEP();
10083 div_byte(*destreg);
10084 break;
10085 case 7:
10086 DECODE_PRINTF("IDIV\t");
10087 destreg = DECODE_RM_BYTE_REGISTER(rl);
10088 DECODE_PRINTF("\n");
10089 TRACE_AND_STEP();
10090 idiv_byte(*destreg);
10091 break;
10093 break; /* end mod==11 */
10095 DECODE_CLEAR_SEGOVR();
10096 END_OF_INSTR();
10099 /****************************************************************************
10100 REMARKS:
10101 Handles opcode 0xf7
10102 ****************************************************************************/
10103 void x86emuOp_opcF7_word_RM(u8 X86EMU_UNUSED(op1))
10105 int mod, rl, rh;
10106 uint destoffset;
10108 /* long, drawn out code follows. Double switch for a total
10109 of 32 cases. */
10110 START_OF_INSTR();
10111 FETCH_DECODE_MODRM(mod, rh, rl);
10112 switch (mod) {
10113 case 0: /* mod=00 */
10114 switch (rh) {
10115 case 0: /* test word imm */
10116 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10117 u32 destval,srcval;
10119 DECODE_PRINTF("TEST\tDWORD PTR ");
10120 destoffset = decode_rm00_address(rl);
10121 DECODE_PRINTF(",");
10122 srcval = fetch_long_imm();
10123 DECODE_PRINTF2("%x\n", srcval);
10124 destval = fetch_data_long(destoffset);
10125 TRACE_AND_STEP();
10126 test_long(destval, srcval);
10127 } else {
10128 u16 destval,srcval;
10130 DECODE_PRINTF("TEST\tWORD PTR ");
10131 destoffset = decode_rm00_address(rl);
10132 DECODE_PRINTF(",");
10133 srcval = fetch_word_imm();
10134 DECODE_PRINTF2("%x\n", srcval);
10135 destval = fetch_data_word(destoffset);
10136 TRACE_AND_STEP();
10137 test_word(destval, srcval);
10139 break;
10140 case 1:
10141 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F7\n");
10142 HALT_SYS();
10143 break;
10144 case 2:
10145 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10146 u32 destval;
10148 DECODE_PRINTF("NOT\tDWORD PTR ");
10149 destoffset = decode_rm00_address(rl);
10150 DECODE_PRINTF("\n");
10151 destval = fetch_data_long(destoffset);
10152 TRACE_AND_STEP();
10153 destval = not_long(destval);
10154 store_data_long(destoffset, destval);
10155 } else {
10156 u16 destval;
10158 DECODE_PRINTF("NOT\tWORD PTR ");
10159 destoffset = decode_rm00_address(rl);
10160 DECODE_PRINTF("\n");
10161 destval = fetch_data_word(destoffset);
10162 TRACE_AND_STEP();
10163 destval = not_word(destval);
10164 store_data_word(destoffset, destval);
10166 break;
10167 case 3:
10168 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10169 u32 destval;
10171 DECODE_PRINTF("NEG\tDWORD PTR ");
10172 destoffset = decode_rm00_address(rl);
10173 DECODE_PRINTF("\n");
10174 destval = fetch_data_long(destoffset);
10175 TRACE_AND_STEP();
10176 destval = neg_long(destval);
10177 store_data_long(destoffset, destval);
10178 } else {
10179 u16 destval;
10181 DECODE_PRINTF("NEG\tWORD PTR ");
10182 destoffset = decode_rm00_address(rl);
10183 DECODE_PRINTF("\n");
10184 destval = fetch_data_word(destoffset);
10185 TRACE_AND_STEP();
10186 destval = neg_word(destval);
10187 store_data_word(destoffset, destval);
10189 break;
10190 case 4:
10191 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10192 u32 destval;
10194 DECODE_PRINTF("MUL\tDWORD PTR ");
10195 destoffset = decode_rm00_address(rl);
10196 DECODE_PRINTF("\n");
10197 destval = fetch_data_long(destoffset);
10198 TRACE_AND_STEP();
10199 mul_long(destval);
10200 } else {
10201 u16 destval;
10203 DECODE_PRINTF("MUL\tWORD PTR ");
10204 destoffset = decode_rm00_address(rl);
10205 DECODE_PRINTF("\n");
10206 destval = fetch_data_word(destoffset);
10207 TRACE_AND_STEP();
10208 mul_word(destval);
10210 break;
10211 case 5:
10212 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10213 u32 destval;
10215 DECODE_PRINTF("IMUL\tDWORD PTR ");
10216 destoffset = decode_rm00_address(rl);
10217 DECODE_PRINTF("\n");
10218 destval = fetch_data_long(destoffset);
10219 TRACE_AND_STEP();
10220 imul_long(destval);
10221 } else {
10222 u16 destval;
10224 DECODE_PRINTF("IMUL\tWORD PTR ");
10225 destoffset = decode_rm00_address(rl);
10226 DECODE_PRINTF("\n");
10227 destval = fetch_data_word(destoffset);
10228 TRACE_AND_STEP();
10229 imul_word(destval);
10231 break;
10232 case 6:
10233 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10234 u32 destval;
10236 DECODE_PRINTF("DIV\tDWORD PTR ");
10237 destoffset = decode_rm00_address(rl);
10238 DECODE_PRINTF("\n");
10239 destval = fetch_data_long(destoffset);
10240 TRACE_AND_STEP();
10241 div_long(destval);
10242 } else {
10243 u16 destval;
10245 DECODE_PRINTF("DIV\tWORD PTR ");
10246 destoffset = decode_rm00_address(rl);
10247 DECODE_PRINTF("\n");
10248 destval = fetch_data_word(destoffset);
10249 TRACE_AND_STEP();
10250 div_word(destval);
10252 break;
10253 case 7:
10254 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10255 u32 destval;
10257 DECODE_PRINTF("IDIV\tDWORD PTR ");
10258 destoffset = decode_rm00_address(rl);
10259 DECODE_PRINTF("\n");
10260 destval = fetch_data_long(destoffset);
10261 TRACE_AND_STEP();
10262 idiv_long(destval);
10263 } else {
10264 u16 destval;
10266 DECODE_PRINTF("IDIV\tWORD PTR ");
10267 destoffset = decode_rm00_address(rl);
10268 DECODE_PRINTF("\n");
10269 destval = fetch_data_word(destoffset);
10270 TRACE_AND_STEP();
10271 idiv_word(destval);
10273 break;
10275 break; /* end mod==00 */
10276 case 1: /* mod=01 */
10277 switch (rh) {
10278 case 0: /* test word imm */
10279 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10280 u32 destval,srcval;
10282 DECODE_PRINTF("TEST\tDWORD PTR ");
10283 destoffset = decode_rm01_address(rl);
10284 DECODE_PRINTF(",");
10285 srcval = fetch_long_imm();
10286 DECODE_PRINTF2("%x\n", srcval);
10287 destval = fetch_data_long(destoffset);
10288 TRACE_AND_STEP();
10289 test_long(destval, srcval);
10290 } else {
10291 u16 destval,srcval;
10293 DECODE_PRINTF("TEST\tWORD PTR ");
10294 destoffset = decode_rm01_address(rl);
10295 DECODE_PRINTF(",");
10296 srcval = fetch_word_imm();
10297 DECODE_PRINTF2("%x\n", srcval);
10298 destval = fetch_data_word(destoffset);
10299 TRACE_AND_STEP();
10300 test_word(destval, srcval);
10302 break;
10303 case 1:
10304 DECODE_PRINTF("ILLEGAL OP MOD=01 RH=01 OP=F6\n");
10305 HALT_SYS();
10306 break;
10307 case 2:
10308 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10309 u32 destval;
10311 DECODE_PRINTF("NOT\tDWORD PTR ");
10312 destoffset = decode_rm01_address(rl);
10313 DECODE_PRINTF("\n");
10314 destval = fetch_data_long(destoffset);
10315 TRACE_AND_STEP();
10316 destval = not_long(destval);
10317 store_data_long(destoffset, destval);
10318 } else {
10319 u16 destval;
10321 DECODE_PRINTF("NOT\tWORD PTR ");
10322 destoffset = decode_rm01_address(rl);
10323 DECODE_PRINTF("\n");
10324 destval = fetch_data_word(destoffset);
10325 TRACE_AND_STEP();
10326 destval = not_word(destval);
10327 store_data_word(destoffset, destval);
10329 break;
10330 case 3:
10331 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10332 u32 destval;
10334 DECODE_PRINTF("NEG\tDWORD PTR ");
10335 destoffset = decode_rm01_address(rl);
10336 DECODE_PRINTF("\n");
10337 destval = fetch_data_long(destoffset);
10338 TRACE_AND_STEP();
10339 destval = neg_long(destval);
10340 store_data_long(destoffset, destval);
10341 } else {
10342 u16 destval;
10344 DECODE_PRINTF("NEG\tWORD PTR ");
10345 destoffset = decode_rm01_address(rl);
10346 DECODE_PRINTF("\n");
10347 destval = fetch_data_word(destoffset);
10348 TRACE_AND_STEP();
10349 destval = neg_word(destval);
10350 store_data_word(destoffset, destval);
10352 break;
10353 case 4:
10354 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10355 u32 destval;
10357 DECODE_PRINTF("MUL\tDWORD PTR ");
10358 destoffset = decode_rm01_address(rl);
10359 DECODE_PRINTF("\n");
10360 destval = fetch_data_long(destoffset);
10361 TRACE_AND_STEP();
10362 mul_long(destval);
10363 } else {
10364 u16 destval;
10366 DECODE_PRINTF("MUL\tWORD PTR ");
10367 destoffset = decode_rm01_address(rl);
10368 DECODE_PRINTF("\n");
10369 destval = fetch_data_word(destoffset);
10370 TRACE_AND_STEP();
10371 mul_word(destval);
10373 break;
10374 case 5:
10375 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10376 u32 destval;
10378 DECODE_PRINTF("IMUL\tDWORD PTR ");
10379 destoffset = decode_rm01_address(rl);
10380 DECODE_PRINTF("\n");
10381 destval = fetch_data_long(destoffset);
10382 TRACE_AND_STEP();
10383 imul_long(destval);
10384 } else {
10385 u16 destval;
10387 DECODE_PRINTF("IMUL\tWORD PTR ");
10388 destoffset = decode_rm01_address(rl);
10389 DECODE_PRINTF("\n");
10390 destval = fetch_data_word(destoffset);
10391 TRACE_AND_STEP();
10392 imul_word(destval);
10394 break;
10395 case 6:
10396 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10397 u32 destval;
10399 DECODE_PRINTF("DIV\tDWORD PTR ");
10400 destoffset = decode_rm01_address(rl);
10401 DECODE_PRINTF("\n");
10402 destval = fetch_data_long(destoffset);
10403 TRACE_AND_STEP();
10404 div_long(destval);
10405 } else {
10406 u16 destval;
10408 DECODE_PRINTF("DIV\tWORD PTR ");
10409 destoffset = decode_rm01_address(rl);
10410 DECODE_PRINTF("\n");
10411 destval = fetch_data_word(destoffset);
10412 TRACE_AND_STEP();
10413 div_word(destval);
10415 break;
10416 case 7:
10417 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10418 u32 destval;
10420 DECODE_PRINTF("IDIV\tDWORD PTR ");
10421 destoffset = decode_rm01_address(rl);
10422 DECODE_PRINTF("\n");
10423 destval = fetch_data_long(destoffset);
10424 TRACE_AND_STEP();
10425 idiv_long(destval);
10426 } else {
10427 u16 destval;
10429 DECODE_PRINTF("IDIV\tWORD PTR ");
10430 destoffset = decode_rm01_address(rl);
10431 DECODE_PRINTF("\n");
10432 destval = fetch_data_word(destoffset);
10433 TRACE_AND_STEP();
10434 idiv_word(destval);
10436 break;
10438 break; /* end mod==01 */
10439 case 2: /* mod=10 */
10440 switch (rh) {
10441 case 0: /* test word imm */
10442 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10443 u32 destval,srcval;
10445 DECODE_PRINTF("TEST\tDWORD PTR ");
10446 destoffset = decode_rm10_address(rl);
10447 DECODE_PRINTF(",");
10448 srcval = fetch_long_imm();
10449 DECODE_PRINTF2("%x\n", srcval);
10450 destval = fetch_data_long(destoffset);
10451 TRACE_AND_STEP();
10452 test_long(destval, srcval);
10453 } else {
10454 u16 destval,srcval;
10456 DECODE_PRINTF("TEST\tWORD PTR ");
10457 destoffset = decode_rm10_address(rl);
10458 DECODE_PRINTF(",");
10459 srcval = fetch_word_imm();
10460 DECODE_PRINTF2("%x\n", srcval);
10461 destval = fetch_data_word(destoffset);
10462 TRACE_AND_STEP();
10463 test_word(destval, srcval);
10465 break;
10466 case 1:
10467 DECODE_PRINTF("ILLEGAL OP MOD=10 RH=01 OP=F6\n");
10468 HALT_SYS();
10469 break;
10470 case 2:
10471 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10472 u32 destval;
10474 DECODE_PRINTF("NOT\tDWORD PTR ");
10475 destoffset = decode_rm10_address(rl);
10476 DECODE_PRINTF("\n");
10477 destval = fetch_data_long(destoffset);
10478 TRACE_AND_STEP();
10479 destval = not_long(destval);
10480 store_data_long(destoffset, destval);
10481 } else {
10482 u16 destval;
10484 DECODE_PRINTF("NOT\tWORD PTR ");
10485 destoffset = decode_rm10_address(rl);
10486 DECODE_PRINTF("\n");
10487 destval = fetch_data_word(destoffset);
10488 TRACE_AND_STEP();
10489 destval = not_word(destval);
10490 store_data_word(destoffset, destval);
10492 break;
10493 case 3:
10494 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10495 u32 destval;
10497 DECODE_PRINTF("NEG\tDWORD PTR ");
10498 destoffset = decode_rm10_address(rl);
10499 DECODE_PRINTF("\n");
10500 destval = fetch_data_long(destoffset);
10501 TRACE_AND_STEP();
10502 destval = neg_long(destval);
10503 store_data_long(destoffset, destval);
10504 } else {
10505 u16 destval;
10507 DECODE_PRINTF("NEG\tWORD PTR ");
10508 destoffset = decode_rm10_address(rl);
10509 DECODE_PRINTF("\n");
10510 destval = fetch_data_word(destoffset);
10511 TRACE_AND_STEP();
10512 destval = neg_word(destval);
10513 store_data_word(destoffset, destval);
10515 break;
10516 case 4:
10517 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10518 u32 destval;
10520 DECODE_PRINTF("MUL\tDWORD PTR ");
10521 destoffset = decode_rm10_address(rl);
10522 DECODE_PRINTF("\n");
10523 destval = fetch_data_long(destoffset);
10524 TRACE_AND_STEP();
10525 mul_long(destval);
10526 } else {
10527 u16 destval;
10529 DECODE_PRINTF("MUL\tWORD PTR ");
10530 destoffset = decode_rm10_address(rl);
10531 DECODE_PRINTF("\n");
10532 destval = fetch_data_word(destoffset);
10533 TRACE_AND_STEP();
10534 mul_word(destval);
10536 break;
10537 case 5:
10538 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10539 u32 destval;
10541 DECODE_PRINTF("IMUL\tDWORD PTR ");
10542 destoffset = decode_rm10_address(rl);
10543 DECODE_PRINTF("\n");
10544 destval = fetch_data_long(destoffset);
10545 TRACE_AND_STEP();
10546 imul_long(destval);
10547 } else {
10548 u16 destval;
10550 DECODE_PRINTF("IMUL\tWORD PTR ");
10551 destoffset = decode_rm10_address(rl);
10552 DECODE_PRINTF("\n");
10553 destval = fetch_data_word(destoffset);
10554 TRACE_AND_STEP();
10555 imul_word(destval);
10557 break;
10558 case 6:
10559 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10560 u32 destval;
10562 DECODE_PRINTF("DIV\tDWORD PTR ");
10563 destoffset = decode_rm10_address(rl);
10564 DECODE_PRINTF("\n");
10565 destval = fetch_data_long(destoffset);
10566 TRACE_AND_STEP();
10567 div_long(destval);
10568 } else {
10569 u16 destval;
10571 DECODE_PRINTF("DIV\tWORD PTR ");
10572 destoffset = decode_rm10_address(rl);
10573 DECODE_PRINTF("\n");
10574 destval = fetch_data_word(destoffset);
10575 TRACE_AND_STEP();
10576 div_word(destval);
10578 break;
10579 case 7:
10580 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10581 u32 destval;
10583 DECODE_PRINTF("IDIV\tDWORD PTR ");
10584 destoffset = decode_rm10_address(rl);
10585 DECODE_PRINTF("\n");
10586 destval = fetch_data_long(destoffset);
10587 TRACE_AND_STEP();
10588 idiv_long(destval);
10589 } else {
10590 u16 destval;
10592 DECODE_PRINTF("IDIV\tWORD PTR ");
10593 destoffset = decode_rm10_address(rl);
10594 DECODE_PRINTF("\n");
10595 destval = fetch_data_word(destoffset);
10596 TRACE_AND_STEP();
10597 idiv_word(destval);
10599 break;
10601 break; /* end mod==10 */
10602 case 3: /* mod=11 */
10603 switch (rh) {
10604 case 0: /* test word imm */
10605 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10606 u32 *destreg;
10607 u32 srcval;
10609 DECODE_PRINTF("TEST\t");
10610 destreg = DECODE_RM_LONG_REGISTER(rl);
10611 DECODE_PRINTF(",");
10612 srcval = fetch_long_imm();
10613 DECODE_PRINTF2("%x\n", srcval);
10614 TRACE_AND_STEP();
10615 test_long(*destreg, srcval);
10616 } else {
10617 u16 *destreg;
10618 u16 srcval;
10620 DECODE_PRINTF("TEST\t");
10621 destreg = DECODE_RM_WORD_REGISTER(rl);
10622 DECODE_PRINTF(",");
10623 srcval = fetch_word_imm();
10624 DECODE_PRINTF2("%x\n", srcval);
10625 TRACE_AND_STEP();
10626 test_word(*destreg, srcval);
10628 break;
10629 case 1:
10630 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
10631 HALT_SYS();
10632 break;
10633 case 2:
10634 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10635 u32 *destreg;
10637 DECODE_PRINTF("NOT\t");
10638 destreg = DECODE_RM_LONG_REGISTER(rl);
10639 DECODE_PRINTF("\n");
10640 TRACE_AND_STEP();
10641 *destreg = not_long(*destreg);
10642 } else {
10643 u16 *destreg;
10645 DECODE_PRINTF("NOT\t");
10646 destreg = DECODE_RM_WORD_REGISTER(rl);
10647 DECODE_PRINTF("\n");
10648 TRACE_AND_STEP();
10649 *destreg = not_word(*destreg);
10651 break;
10652 case 3:
10653 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10654 u32 *destreg;
10656 DECODE_PRINTF("NEG\t");
10657 destreg = DECODE_RM_LONG_REGISTER(rl);
10658 DECODE_PRINTF("\n");
10659 TRACE_AND_STEP();
10660 *destreg = neg_long(*destreg);
10661 } else {
10662 u16 *destreg;
10664 DECODE_PRINTF("NEG\t");
10665 destreg = DECODE_RM_WORD_REGISTER(rl);
10666 DECODE_PRINTF("\n");
10667 TRACE_AND_STEP();
10668 *destreg = neg_word(*destreg);
10670 break;
10671 case 4:
10672 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10673 u32 *destreg;
10675 DECODE_PRINTF("MUL\t");
10676 destreg = DECODE_RM_LONG_REGISTER(rl);
10677 DECODE_PRINTF("\n");
10678 TRACE_AND_STEP();
10679 mul_long(*destreg); /*!!! */
10680 } else {
10681 u16 *destreg;
10683 DECODE_PRINTF("MUL\t");
10684 destreg = DECODE_RM_WORD_REGISTER(rl);
10685 DECODE_PRINTF("\n");
10686 TRACE_AND_STEP();
10687 mul_word(*destreg); /*!!! */
10689 break;
10690 case 5:
10691 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10692 u32 *destreg;
10694 DECODE_PRINTF("IMUL\t");
10695 destreg = DECODE_RM_LONG_REGISTER(rl);
10696 DECODE_PRINTF("\n");
10697 TRACE_AND_STEP();
10698 imul_long(*destreg);
10699 } else {
10700 u16 *destreg;
10702 DECODE_PRINTF("IMUL\t");
10703 destreg = DECODE_RM_WORD_REGISTER(rl);
10704 DECODE_PRINTF("\n");
10705 TRACE_AND_STEP();
10706 imul_word(*destreg);
10708 break;
10709 case 6:
10710 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10711 u32 *destreg;
10713 DECODE_PRINTF("DIV\t");
10714 destreg = DECODE_RM_LONG_REGISTER(rl);
10715 DECODE_PRINTF("\n");
10716 TRACE_AND_STEP();
10717 div_long(*destreg);
10718 } else {
10719 u16 *destreg;
10721 DECODE_PRINTF("DIV\t");
10722 destreg = DECODE_RM_WORD_REGISTER(rl);
10723 DECODE_PRINTF("\n");
10724 TRACE_AND_STEP();
10725 div_word(*destreg);
10727 break;
10728 case 7:
10729 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10730 u32 *destreg;
10732 DECODE_PRINTF("IDIV\t");
10733 destreg = DECODE_RM_LONG_REGISTER(rl);
10734 DECODE_PRINTF("\n");
10735 TRACE_AND_STEP();
10736 idiv_long(*destreg);
10737 } else {
10738 u16 *destreg;
10740 DECODE_PRINTF("IDIV\t");
10741 destreg = DECODE_RM_WORD_REGISTER(rl);
10742 DECODE_PRINTF("\n");
10743 TRACE_AND_STEP();
10744 idiv_word(*destreg);
10746 break;
10748 break; /* end mod==11 */
10750 DECODE_CLEAR_SEGOVR();
10751 END_OF_INSTR();
10754 /****************************************************************************
10755 REMARKS:
10756 Handles opcode 0xf8
10757 ****************************************************************************/
10758 void x86emuOp_clc(u8 X86EMU_UNUSED(op1))
10760 /* clear the carry flag. */
10761 START_OF_INSTR();
10762 DECODE_PRINTF("CLC\n");
10763 TRACE_AND_STEP();
10764 CLEAR_FLAG(F_CF);
10765 DECODE_CLEAR_SEGOVR();
10766 END_OF_INSTR();
10769 /****************************************************************************
10770 REMARKS:
10771 Handles opcode 0xf9
10772 ****************************************************************************/
10773 void x86emuOp_stc(u8 X86EMU_UNUSED(op1))
10775 /* set the carry flag. */
10776 START_OF_INSTR();
10777 DECODE_PRINTF("STC\n");
10778 TRACE_AND_STEP();
10779 SET_FLAG(F_CF);
10780 DECODE_CLEAR_SEGOVR();
10781 END_OF_INSTR();
10784 /****************************************************************************
10785 REMARKS:
10786 Handles opcode 0xfa
10787 ****************************************************************************/
10788 void x86emuOp_cli(u8 X86EMU_UNUSED(op1))
10790 /* clear interrupts. */
10791 START_OF_INSTR();
10792 DECODE_PRINTF("CLI\n");
10793 TRACE_AND_STEP();
10794 CLEAR_FLAG(F_IF);
10795 DECODE_CLEAR_SEGOVR();
10796 END_OF_INSTR();
10799 /****************************************************************************
10800 REMARKS:
10801 Handles opcode 0xfb
10802 ****************************************************************************/
10803 void x86emuOp_sti(u8 X86EMU_UNUSED(op1))
10805 /* enable interrupts. */
10806 START_OF_INSTR();
10807 DECODE_PRINTF("STI\n");
10808 TRACE_AND_STEP();
10809 SET_FLAG(F_IF);
10810 DECODE_CLEAR_SEGOVR();
10811 END_OF_INSTR();
10814 /****************************************************************************
10815 REMARKS:
10816 Handles opcode 0xfc
10817 ****************************************************************************/
10818 void x86emuOp_cld(u8 X86EMU_UNUSED(op1))
10820 /* clear interrupts. */
10821 START_OF_INSTR();
10822 DECODE_PRINTF("CLD\n");
10823 TRACE_AND_STEP();
10824 CLEAR_FLAG(F_DF);
10825 DECODE_CLEAR_SEGOVR();
10826 END_OF_INSTR();
10829 /****************************************************************************
10830 REMARKS:
10831 Handles opcode 0xfd
10832 ****************************************************************************/
10833 void x86emuOp_std(u8 X86EMU_UNUSED(op1))
10835 /* clear interrupts. */
10836 START_OF_INSTR();
10837 DECODE_PRINTF("STD\n");
10838 TRACE_AND_STEP();
10839 SET_FLAG(F_DF);
10840 DECODE_CLEAR_SEGOVR();
10841 END_OF_INSTR();
10844 /****************************************************************************
10845 REMARKS:
10846 Handles opcode 0xfe
10847 ****************************************************************************/
10848 void x86emuOp_opcFE_byte_RM(u8 X86EMU_UNUSED(op1))
10850 int mod, rh, rl;
10851 u8 destval;
10852 uint destoffset;
10853 u8 *destreg;
10855 /* Yet another special case instruction. */
10856 START_OF_INSTR();
10857 FETCH_DECODE_MODRM(mod, rh, rl);
10858 #ifdef DEBUG
10859 if (DEBUG_DECODE()) {
10861 switch (rh) {
10862 case 0:
10863 DECODE_PRINTF("INC\t");
10864 break;
10865 case 1:
10866 DECODE_PRINTF("DEC\t");
10867 break;
10868 case 2:
10869 case 3:
10870 case 4:
10871 case 5:
10872 case 6:
10873 case 7:
10874 DECODE_PRINTF2("ILLEGAL OP MAJOR OP 0xFE MINOR OP %x \n", mod);
10875 HALT_SYS();
10876 break;
10879 #endif
10880 switch (mod) {
10881 case 0:
10882 DECODE_PRINTF("BYTE PTR ");
10883 destoffset = decode_rm00_address(rl);
10884 DECODE_PRINTF("\n");
10885 switch (rh) {
10886 case 0: /* inc word ptr ... */
10887 destval = fetch_data_byte(destoffset);
10888 TRACE_AND_STEP();
10889 destval = inc_byte(destval);
10890 store_data_byte(destoffset, destval);
10891 break;
10892 case 1: /* dec word ptr ... */
10893 destval = fetch_data_byte(destoffset);
10894 TRACE_AND_STEP();
10895 destval = dec_byte(destval);
10896 store_data_byte(destoffset, destval);
10897 break;
10899 break;
10900 case 1:
10901 DECODE_PRINTF("BYTE PTR ");
10902 destoffset = decode_rm01_address(rl);
10903 DECODE_PRINTF("\n");
10904 switch (rh) {
10905 case 0:
10906 destval = fetch_data_byte(destoffset);
10907 TRACE_AND_STEP();
10908 destval = inc_byte(destval);
10909 store_data_byte(destoffset, destval);
10910 break;
10911 case 1:
10912 destval = fetch_data_byte(destoffset);
10913 TRACE_AND_STEP();
10914 destval = dec_byte(destval);
10915 store_data_byte(destoffset, destval);
10916 break;
10918 break;
10919 case 2:
10920 DECODE_PRINTF("BYTE PTR ");
10921 destoffset = decode_rm10_address(rl);
10922 DECODE_PRINTF("\n");
10923 switch (rh) {
10924 case 0:
10925 destval = fetch_data_byte(destoffset);
10926 TRACE_AND_STEP();
10927 destval = inc_byte(destval);
10928 store_data_byte(destoffset, destval);
10929 break;
10930 case 1:
10931 destval = fetch_data_byte(destoffset);
10932 TRACE_AND_STEP();
10933 destval = dec_byte(destval);
10934 store_data_byte(destoffset, destval);
10935 break;
10937 break;
10938 case 3:
10939 destreg = DECODE_RM_BYTE_REGISTER(rl);
10940 DECODE_PRINTF("\n");
10941 switch (rh) {
10942 case 0:
10943 TRACE_AND_STEP();
10944 *destreg = inc_byte(*destreg);
10945 break;
10946 case 1:
10947 TRACE_AND_STEP();
10948 *destreg = dec_byte(*destreg);
10949 break;
10951 break;
10953 DECODE_CLEAR_SEGOVR();
10954 END_OF_INSTR();
10957 /****************************************************************************
10958 REMARKS:
10959 Handles opcode 0xff
10960 ****************************************************************************/
10961 void x86emuOp_opcFF_word_RM(u8 X86EMU_UNUSED(op1))
10963 int mod, rh, rl;
10964 uint destoffset = 0;
10965 u16 *destreg;
10966 u16 destval,destval2;
10968 /* Yet another special case instruction. */
10969 START_OF_INSTR();
10970 FETCH_DECODE_MODRM(mod, rh, rl);
10971 #ifdef DEBUG
10972 if (DEBUG_DECODE()) {
10974 switch (rh) {
10975 case 0:
10976 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10977 DECODE_PRINTF("INC\tDWORD PTR ");
10978 } else {
10979 DECODE_PRINTF("INC\tWORD PTR ");
10981 break;
10982 case 1:
10983 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10984 DECODE_PRINTF("DEC\tDWORD PTR ");
10985 } else {
10986 DECODE_PRINTF("DEC\tWORD PTR ");
10988 break;
10989 case 2:
10990 DECODE_PRINTF("CALL\t ");
10991 break;
10992 case 3:
10993 DECODE_PRINTF("CALL\tFAR ");
10994 break;
10995 case 4:
10996 DECODE_PRINTF("JMP\t");
10997 break;
10998 case 5:
10999 DECODE_PRINTF("JMP\tFAR ");
11000 break;
11001 case 6:
11002 DECODE_PRINTF("PUSH\t");
11003 break;
11004 case 7:
11005 DECODE_PRINTF("ILLEGAL DECODING OF OPCODE FF\t");
11006 HALT_SYS();
11007 break;
11010 #endif
11011 switch (mod) {
11012 case 0:
11013 destoffset = decode_rm00_address(rl);
11014 DECODE_PRINTF("\n");
11015 switch (rh) {
11016 case 0: /* inc word ptr ... */
11017 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11018 u32 destval;
11020 destval = fetch_data_long(destoffset);
11021 TRACE_AND_STEP();
11022 destval = inc_long(destval);
11023 store_data_long(destoffset, destval);
11024 } else {
11025 u16 destval;
11027 destval = fetch_data_word(destoffset);
11028 TRACE_AND_STEP();
11029 destval = inc_word(destval);
11030 store_data_word(destoffset, destval);
11032 break;
11033 case 1: /* dec word ptr ... */
11034 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11035 u32 destval;
11037 destval = fetch_data_long(destoffset);
11038 TRACE_AND_STEP();
11039 destval = dec_long(destval);
11040 store_data_long(destoffset, destval);
11041 } else {
11042 u16 destval;
11044 destval = fetch_data_word(destoffset);
11045 TRACE_AND_STEP();
11046 destval = dec_word(destval);
11047 store_data_word(destoffset, destval);
11049 break;
11050 case 2: /* call word ptr ... */
11051 destval = fetch_data_word(destoffset);
11052 TRACE_AND_STEP();
11053 push_word(M.x86.R_IP);
11054 M.x86.R_IP = destval;
11055 break;
11056 case 3: /* call far ptr ... */
11057 destval = fetch_data_word(destoffset);
11058 destval2 = fetch_data_word(destoffset + 2);
11059 TRACE_AND_STEP();
11060 push_word(M.x86.R_CS);
11061 M.x86.R_CS = destval2;
11062 push_word(M.x86.R_IP);
11063 M.x86.R_IP = destval;
11064 break;
11065 case 4: /* jmp word ptr ... */
11066 destval = fetch_data_word(destoffset);
11067 TRACE_AND_STEP();
11068 M.x86.R_IP = destval;
11069 break;
11070 case 5: /* jmp far ptr ... */
11071 destval = fetch_data_word(destoffset);
11072 destval2 = fetch_data_word(destoffset + 2);
11073 TRACE_AND_STEP();
11074 M.x86.R_IP = destval;
11075 M.x86.R_CS = destval2;
11076 break;
11077 case 6: /* push word ptr ... */
11078 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11079 u32 destval;
11081 destval = fetch_data_long(destoffset);
11082 TRACE_AND_STEP();
11083 push_long(destval);
11084 } else {
11085 u16 destval;
11087 destval = fetch_data_word(destoffset);
11088 TRACE_AND_STEP();
11089 push_word(destval);
11091 break;
11093 break;
11094 case 1:
11095 destoffset = decode_rm01_address(rl);
11096 DECODE_PRINTF("\n");
11097 switch (rh) {
11098 case 0:
11099 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11100 u32 destval;
11102 destval = fetch_data_long(destoffset);
11103 TRACE_AND_STEP();
11104 destval = inc_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 = inc_word(destval);
11112 store_data_word(destoffset, destval);
11114 break;
11115 case 1:
11116 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11117 u32 destval;
11119 destval = fetch_data_long(destoffset);
11120 TRACE_AND_STEP();
11121 destval = dec_long(destval);
11122 store_data_long(destoffset, destval);
11123 } else {
11124 u16 destval;
11126 destval = fetch_data_word(destoffset);
11127 TRACE_AND_STEP();
11128 destval = dec_word(destval);
11129 store_data_word(destoffset, destval);
11131 break;
11132 case 2: /* call word ptr ... */
11133 destval = fetch_data_word(destoffset);
11134 TRACE_AND_STEP();
11135 push_word(M.x86.R_IP);
11136 M.x86.R_IP = destval;
11137 break;
11138 case 3: /* call far ptr ... */
11139 destval = fetch_data_word(destoffset);
11140 destval2 = fetch_data_word(destoffset + 2);
11141 TRACE_AND_STEP();
11142 push_word(M.x86.R_CS);
11143 M.x86.R_CS = destval2;
11144 push_word(M.x86.R_IP);
11145 M.x86.R_IP = destval;
11146 break;
11147 case 4: /* jmp word ptr ... */
11148 destval = fetch_data_word(destoffset);
11149 TRACE_AND_STEP();
11150 M.x86.R_IP = destval;
11151 break;
11152 case 5: /* jmp far ptr ... */
11153 destval = fetch_data_word(destoffset);
11154 destval2 = fetch_data_word(destoffset + 2);
11155 TRACE_AND_STEP();
11156 M.x86.R_IP = destval;
11157 M.x86.R_CS = destval2;
11158 break;
11159 case 6: /* push word ptr ... */
11160 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11161 u32 destval;
11163 destval = fetch_data_long(destoffset);
11164 TRACE_AND_STEP();
11165 push_long(destval);
11166 } else {
11167 u16 destval;
11169 destval = fetch_data_word(destoffset);
11170 TRACE_AND_STEP();
11171 push_word(destval);
11173 break;
11175 break;
11176 case 2:
11177 destoffset = decode_rm10_address(rl);
11178 DECODE_PRINTF("\n");
11179 switch (rh) {
11180 case 0:
11181 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11182 u32 destval;
11184 destval = fetch_data_long(destoffset);
11185 TRACE_AND_STEP();
11186 destval = inc_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 = inc_word(destval);
11194 store_data_word(destoffset, destval);
11196 break;
11197 case 1:
11198 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11199 u32 destval;
11201 destval = fetch_data_long(destoffset);
11202 TRACE_AND_STEP();
11203 destval = dec_long(destval);
11204 store_data_long(destoffset, destval);
11205 } else {
11206 u16 destval;
11208 destval = fetch_data_word(destoffset);
11209 TRACE_AND_STEP();
11210 destval = dec_word(destval);
11211 store_data_word(destoffset, destval);
11213 break;
11214 case 2: /* call word ptr ... */
11215 destval = fetch_data_word(destoffset);
11216 TRACE_AND_STEP();
11217 push_word(M.x86.R_IP);
11218 M.x86.R_IP = destval;
11219 break;
11220 case 3: /* call far ptr ... */
11221 destval = fetch_data_word(destoffset);
11222 destval2 = fetch_data_word(destoffset + 2);
11223 TRACE_AND_STEP();
11224 push_word(M.x86.R_CS);
11225 M.x86.R_CS = destval2;
11226 push_word(M.x86.R_IP);
11227 M.x86.R_IP = destval;
11228 break;
11229 case 4: /* jmp word ptr ... */
11230 destval = fetch_data_word(destoffset);
11231 TRACE_AND_STEP();
11232 M.x86.R_IP = destval;
11233 break;
11234 case 5: /* jmp far ptr ... */
11235 destval = fetch_data_word(destoffset);
11236 destval2 = fetch_data_word(destoffset + 2);
11237 TRACE_AND_STEP();
11238 M.x86.R_IP = destval;
11239 M.x86.R_CS = destval2;
11240 break;
11241 case 6: /* push word ptr ... */
11242 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11243 u32 destval;
11245 destval = fetch_data_long(destoffset);
11246 TRACE_AND_STEP();
11247 push_long(destval);
11248 } else {
11249 u16 destval;
11251 destval = fetch_data_word(destoffset);
11252 TRACE_AND_STEP();
11253 push_word(destval);
11255 break;
11257 break;
11258 case 3:
11259 switch (rh) {
11260 case 0:
11261 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11262 u32 *destreg;
11264 destreg = DECODE_RM_LONG_REGISTER(rl);
11265 DECODE_PRINTF("\n");
11266 TRACE_AND_STEP();
11267 *destreg = inc_long(*destreg);
11268 } else {
11269 u16 *destreg;
11271 destreg = DECODE_RM_WORD_REGISTER(rl);
11272 DECODE_PRINTF("\n");
11273 TRACE_AND_STEP();
11274 *destreg = inc_word(*destreg);
11276 break;
11277 case 1:
11278 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11279 u32 *destreg;
11281 destreg = DECODE_RM_LONG_REGISTER(rl);
11282 DECODE_PRINTF("\n");
11283 TRACE_AND_STEP();
11284 *destreg = dec_long(*destreg);
11285 } else {
11286 u16 *destreg;
11288 destreg = DECODE_RM_WORD_REGISTER(rl);
11289 DECODE_PRINTF("\n");
11290 TRACE_AND_STEP();
11291 *destreg = dec_word(*destreg);
11293 break;
11294 case 2: /* call word ptr ... */
11295 destreg = DECODE_RM_WORD_REGISTER(rl);
11296 DECODE_PRINTF("\n");
11297 TRACE_AND_STEP();
11298 push_word(M.x86.R_IP);
11299 M.x86.R_IP = *destreg;
11300 break;
11301 case 3: /* jmp far ptr ... */
11302 DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n");
11303 TRACE_AND_STEP();
11304 HALT_SYS();
11305 break;
11307 case 4: /* jmp ... */
11308 destreg = DECODE_RM_WORD_REGISTER(rl);
11309 DECODE_PRINTF("\n");
11310 TRACE_AND_STEP();
11311 M.x86.R_IP = (u16) (*destreg);
11312 break;
11313 case 5: /* jmp far ptr ... */
11314 DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n");
11315 TRACE_AND_STEP();
11316 HALT_SYS();
11317 break;
11318 case 6:
11319 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11320 u32 *destreg;
11322 destreg = DECODE_RM_LONG_REGISTER(rl);
11323 DECODE_PRINTF("\n");
11324 TRACE_AND_STEP();
11325 push_long(*destreg);
11326 } else {
11327 u16 *destreg;
11329 destreg = DECODE_RM_WORD_REGISTER(rl);
11330 DECODE_PRINTF("\n");
11331 TRACE_AND_STEP();
11332 push_word(*destreg);
11334 break;
11336 break;
11338 DECODE_CLEAR_SEGOVR();
11339 END_OF_INSTR();
11342 /***************************************************************************
11343 * Single byte operation code table:
11344 **************************************************************************/
11345 void (*x86emu_optab[256])(u8) =
11347 /* 0x00 */ x86emuOp_add_byte_RM_R,
11348 /* 0x01 */ x86emuOp_add_word_RM_R,
11349 /* 0x02 */ x86emuOp_add_byte_R_RM,
11350 /* 0x03 */ x86emuOp_add_word_R_RM,
11351 /* 0x04 */ x86emuOp_add_byte_AL_IMM,
11352 /* 0x05 */ x86emuOp_add_word_AX_IMM,
11353 /* 0x06 */ x86emuOp_push_ES,
11354 /* 0x07 */ x86emuOp_pop_ES,
11356 /* 0x08 */ x86emuOp_or_byte_RM_R,
11357 /* 0x09 */ x86emuOp_or_word_RM_R,
11358 /* 0x0a */ x86emuOp_or_byte_R_RM,
11359 /* 0x0b */ x86emuOp_or_word_R_RM,
11360 /* 0x0c */ x86emuOp_or_byte_AL_IMM,
11361 /* 0x0d */ x86emuOp_or_word_AX_IMM,
11362 /* 0x0e */ x86emuOp_push_CS,
11363 /* 0x0f */ x86emuOp_two_byte,
11365 /* 0x10 */ x86emuOp_adc_byte_RM_R,
11366 /* 0x11 */ x86emuOp_adc_word_RM_R,
11367 /* 0x12 */ x86emuOp_adc_byte_R_RM,
11368 /* 0x13 */ x86emuOp_adc_word_R_RM,
11369 /* 0x14 */ x86emuOp_adc_byte_AL_IMM,
11370 /* 0x15 */ x86emuOp_adc_word_AX_IMM,
11371 /* 0x16 */ x86emuOp_push_SS,
11372 /* 0x17 */ x86emuOp_pop_SS,
11374 /* 0x18 */ x86emuOp_sbb_byte_RM_R,
11375 /* 0x19 */ x86emuOp_sbb_word_RM_R,
11376 /* 0x1a */ x86emuOp_sbb_byte_R_RM,
11377 /* 0x1b */ x86emuOp_sbb_word_R_RM,
11378 /* 0x1c */ x86emuOp_sbb_byte_AL_IMM,
11379 /* 0x1d */ x86emuOp_sbb_word_AX_IMM,
11380 /* 0x1e */ x86emuOp_push_DS,
11381 /* 0x1f */ x86emuOp_pop_DS,
11383 /* 0x20 */ x86emuOp_and_byte_RM_R,
11384 /* 0x21 */ x86emuOp_and_word_RM_R,
11385 /* 0x22 */ x86emuOp_and_byte_R_RM,
11386 /* 0x23 */ x86emuOp_and_word_R_RM,
11387 /* 0x24 */ x86emuOp_and_byte_AL_IMM,
11388 /* 0x25 */ x86emuOp_and_word_AX_IMM,
11389 /* 0x26 */ x86emuOp_segovr_ES,
11390 /* 0x27 */ x86emuOp_daa,
11392 /* 0x28 */ x86emuOp_sub_byte_RM_R,
11393 /* 0x29 */ x86emuOp_sub_word_RM_R,
11394 /* 0x2a */ x86emuOp_sub_byte_R_RM,
11395 /* 0x2b */ x86emuOp_sub_word_R_RM,
11396 /* 0x2c */ x86emuOp_sub_byte_AL_IMM,
11397 /* 0x2d */ x86emuOp_sub_word_AX_IMM,
11398 /* 0x2e */ x86emuOp_segovr_CS,
11399 /* 0x2f */ x86emuOp_das,
11401 /* 0x30 */ x86emuOp_xor_byte_RM_R,
11402 /* 0x31 */ x86emuOp_xor_word_RM_R,
11403 /* 0x32 */ x86emuOp_xor_byte_R_RM,
11404 /* 0x33 */ x86emuOp_xor_word_R_RM,
11405 /* 0x34 */ x86emuOp_xor_byte_AL_IMM,
11406 /* 0x35 */ x86emuOp_xor_word_AX_IMM,
11407 /* 0x36 */ x86emuOp_segovr_SS,
11408 /* 0x37 */ x86emuOp_aaa,
11410 /* 0x38 */ x86emuOp_cmp_byte_RM_R,
11411 /* 0x39 */ x86emuOp_cmp_word_RM_R,
11412 /* 0x3a */ x86emuOp_cmp_byte_R_RM,
11413 /* 0x3b */ x86emuOp_cmp_word_R_RM,
11414 /* 0x3c */ x86emuOp_cmp_byte_AL_IMM,
11415 /* 0x3d */ x86emuOp_cmp_word_AX_IMM,
11416 /* 0x3e */ x86emuOp_segovr_DS,
11417 /* 0x3f */ x86emuOp_aas,
11419 /* 0x40 */ x86emuOp_inc_AX,
11420 /* 0x41 */ x86emuOp_inc_CX,
11421 /* 0x42 */ x86emuOp_inc_DX,
11422 /* 0x43 */ x86emuOp_inc_BX,
11423 /* 0x44 */ x86emuOp_inc_SP,
11424 /* 0x45 */ x86emuOp_inc_BP,
11425 /* 0x46 */ x86emuOp_inc_SI,
11426 /* 0x47 */ x86emuOp_inc_DI,
11428 /* 0x48 */ x86emuOp_dec_AX,
11429 /* 0x49 */ x86emuOp_dec_CX,
11430 /* 0x4a */ x86emuOp_dec_DX,
11431 /* 0x4b */ x86emuOp_dec_BX,
11432 /* 0x4c */ x86emuOp_dec_SP,
11433 /* 0x4d */ x86emuOp_dec_BP,
11434 /* 0x4e */ x86emuOp_dec_SI,
11435 /* 0x4f */ x86emuOp_dec_DI,
11437 /* 0x50 */ x86emuOp_push_AX,
11438 /* 0x51 */ x86emuOp_push_CX,
11439 /* 0x52 */ x86emuOp_push_DX,
11440 /* 0x53 */ x86emuOp_push_BX,
11441 /* 0x54 */ x86emuOp_push_SP,
11442 /* 0x55 */ x86emuOp_push_BP,
11443 /* 0x56 */ x86emuOp_push_SI,
11444 /* 0x57 */ x86emuOp_push_DI,
11446 /* 0x58 */ x86emuOp_pop_AX,
11447 /* 0x59 */ x86emuOp_pop_CX,
11448 /* 0x5a */ x86emuOp_pop_DX,
11449 /* 0x5b */ x86emuOp_pop_BX,
11450 /* 0x5c */ x86emuOp_pop_SP,
11451 /* 0x5d */ x86emuOp_pop_BP,
11452 /* 0x5e */ x86emuOp_pop_SI,
11453 /* 0x5f */ x86emuOp_pop_DI,
11455 /* 0x60 */ x86emuOp_push_all,
11456 /* 0x61 */ x86emuOp_pop_all,
11457 /* 0x62 */ x86emuOp_illegal_op, /* bound */
11458 /* 0x63 */ x86emuOp_illegal_op, /* arpl */
11459 /* 0x64 */ x86emuOp_segovr_FS,
11460 /* 0x65 */ x86emuOp_segovr_GS,
11461 /* 0x66 */ x86emuOp_prefix_data,
11462 /* 0x67 */ x86emuOp_prefix_addr,
11464 /* 0x68 */ x86emuOp_push_word_IMM,
11465 /* 0x69 */ x86emuOp_imul_word_IMM,
11466 /* 0x6a */ x86emuOp_push_byte_IMM,
11467 /* 0x6b */ x86emuOp_imul_byte_IMM,
11468 /* 0x6c */ x86emuOp_ins_byte,
11469 /* 0x6d */ x86emuOp_ins_word,
11470 /* 0x6e */ x86emuOp_outs_byte,
11471 /* 0x6f */ x86emuOp_outs_word,
11473 /* 0x70 */ x86emuOp_jump_near_O,
11474 /* 0x71 */ x86emuOp_jump_near_NO,
11475 /* 0x72 */ x86emuOp_jump_near_B,
11476 /* 0x73 */ x86emuOp_jump_near_NB,
11477 /* 0x74 */ x86emuOp_jump_near_Z,
11478 /* 0x75 */ x86emuOp_jump_near_NZ,
11479 /* 0x76 */ x86emuOp_jump_near_BE,
11480 /* 0x77 */ x86emuOp_jump_near_NBE,
11482 /* 0x78 */ x86emuOp_jump_near_S,
11483 /* 0x79 */ x86emuOp_jump_near_NS,
11484 /* 0x7a */ x86emuOp_jump_near_P,
11485 /* 0x7b */ x86emuOp_jump_near_NP,
11486 /* 0x7c */ x86emuOp_jump_near_L,
11487 /* 0x7d */ x86emuOp_jump_near_NL,
11488 /* 0x7e */ x86emuOp_jump_near_LE,
11489 /* 0x7f */ x86emuOp_jump_near_NLE,
11491 /* 0x80 */ x86emuOp_opc80_byte_RM_IMM,
11492 /* 0x81 */ x86emuOp_opc81_word_RM_IMM,
11493 /* 0x82 */ x86emuOp_opc82_byte_RM_IMM,
11494 /* 0x83 */ x86emuOp_opc83_word_RM_IMM,
11495 /* 0x84 */ x86emuOp_test_byte_RM_R,
11496 /* 0x85 */ x86emuOp_test_word_RM_R,
11497 /* 0x86 */ x86emuOp_xchg_byte_RM_R,
11498 /* 0x87 */ x86emuOp_xchg_word_RM_R,
11500 /* 0x88 */ x86emuOp_mov_byte_RM_R,
11501 /* 0x89 */ x86emuOp_mov_word_RM_R,
11502 /* 0x8a */ x86emuOp_mov_byte_R_RM,
11503 /* 0x8b */ x86emuOp_mov_word_R_RM,
11504 /* 0x8c */ x86emuOp_mov_word_RM_SR,
11505 /* 0x8d */ x86emuOp_lea_word_R_M,
11506 /* 0x8e */ x86emuOp_mov_word_SR_RM,
11507 /* 0x8f */ x86emuOp_pop_RM,
11509 /* 0x90 */ x86emuOp_nop,
11510 /* 0x91 */ x86emuOp_xchg_word_AX_CX,
11511 /* 0x92 */ x86emuOp_xchg_word_AX_DX,
11512 /* 0x93 */ x86emuOp_xchg_word_AX_BX,
11513 /* 0x94 */ x86emuOp_xchg_word_AX_SP,
11514 /* 0x95 */ x86emuOp_xchg_word_AX_BP,
11515 /* 0x96 */ x86emuOp_xchg_word_AX_SI,
11516 /* 0x97 */ x86emuOp_xchg_word_AX_DI,
11518 /* 0x98 */ x86emuOp_cbw,
11519 /* 0x99 */ x86emuOp_cwd,
11520 /* 0x9a */ x86emuOp_call_far_IMM,
11521 /* 0x9b */ x86emuOp_wait,
11522 /* 0x9c */ x86emuOp_pushf_word,
11523 /* 0x9d */ x86emuOp_popf_word,
11524 /* 0x9e */ x86emuOp_sahf,
11525 /* 0x9f */ x86emuOp_lahf,
11527 /* 0xa0 */ x86emuOp_mov_AL_M_IMM,
11528 /* 0xa1 */ x86emuOp_mov_AX_M_IMM,
11529 /* 0xa2 */ x86emuOp_mov_M_AL_IMM,
11530 /* 0xa3 */ x86emuOp_mov_M_AX_IMM,
11531 /* 0xa4 */ x86emuOp_movs_byte,
11532 /* 0xa5 */ x86emuOp_movs_word,
11533 /* 0xa6 */ x86emuOp_cmps_byte,
11534 /* 0xa7 */ x86emuOp_cmps_word,
11535 /* 0xa8 */ x86emuOp_test_AL_IMM,
11536 /* 0xa9 */ x86emuOp_test_AX_IMM,
11537 /* 0xaa */ x86emuOp_stos_byte,
11538 /* 0xab */ x86emuOp_stos_word,
11539 /* 0xac */ x86emuOp_lods_byte,
11540 /* 0xad */ x86emuOp_lods_word,
11541 /* 0xac */ x86emuOp_scas_byte,
11542 /* 0xad */ x86emuOp_scas_word,
11545 /* 0xb0 */ x86emuOp_mov_byte_AL_IMM,
11546 /* 0xb1 */ x86emuOp_mov_byte_CL_IMM,
11547 /* 0xb2 */ x86emuOp_mov_byte_DL_IMM,
11548 /* 0xb3 */ x86emuOp_mov_byte_BL_IMM,
11549 /* 0xb4 */ x86emuOp_mov_byte_AH_IMM,
11550 /* 0xb5 */ x86emuOp_mov_byte_CH_IMM,
11551 /* 0xb6 */ x86emuOp_mov_byte_DH_IMM,
11552 /* 0xb7 */ x86emuOp_mov_byte_BH_IMM,
11554 /* 0xb8 */ x86emuOp_mov_word_AX_IMM,
11555 /* 0xb9 */ x86emuOp_mov_word_CX_IMM,
11556 /* 0xba */ x86emuOp_mov_word_DX_IMM,
11557 /* 0xbb */ x86emuOp_mov_word_BX_IMM,
11558 /* 0xbc */ x86emuOp_mov_word_SP_IMM,
11559 /* 0xbd */ x86emuOp_mov_word_BP_IMM,
11560 /* 0xbe */ x86emuOp_mov_word_SI_IMM,
11561 /* 0xbf */ x86emuOp_mov_word_DI_IMM,
11563 /* 0xc0 */ x86emuOp_opcC0_byte_RM_MEM,
11564 /* 0xc1 */ x86emuOp_opcC1_word_RM_MEM,
11565 /* 0xc2 */ x86emuOp_ret_near_IMM,
11566 /* 0xc3 */ x86emuOp_ret_near,
11567 /* 0xc4 */ x86emuOp_les_R_IMM,
11568 /* 0xc5 */ x86emuOp_lds_R_IMM,
11569 /* 0xc6 */ x86emuOp_mov_byte_RM_IMM,
11570 /* 0xc7 */ x86emuOp_mov_word_RM_IMM,
11571 /* 0xc8 */ x86emuOp_enter,
11572 /* 0xc9 */ x86emuOp_leave,
11573 /* 0xca */ x86emuOp_ret_far_IMM,
11574 /* 0xcb */ x86emuOp_ret_far,
11575 /* 0xcc */ x86emuOp_int3,
11576 /* 0xcd */ x86emuOp_int_IMM,
11577 /* 0xce */ x86emuOp_into,
11578 /* 0xcf */ x86emuOp_iret,
11580 /* 0xd0 */ x86emuOp_opcD0_byte_RM_1,
11581 /* 0xd1 */ x86emuOp_opcD1_word_RM_1,
11582 /* 0xd2 */ x86emuOp_opcD2_byte_RM_CL,
11583 /* 0xd3 */ x86emuOp_opcD3_word_RM_CL,
11584 /* 0xd4 */ x86emuOp_aam,
11585 /* 0xd5 */ x86emuOp_aad,
11586 /* 0xd6 */ x86emuOp_illegal_op, /* Undocumented SETALC instruction */
11587 /* 0xd7 */ x86emuOp_xlat,
11588 /* 0xd8 */ x86emuOp_esc_coprocess_d8,
11589 /* 0xd9 */ x86emuOp_esc_coprocess_d9,
11590 /* 0xda */ x86emuOp_esc_coprocess_da,
11591 /* 0xdb */ x86emuOp_esc_coprocess_db,
11592 /* 0xdc */ x86emuOp_esc_coprocess_dc,
11593 /* 0xdd */ x86emuOp_esc_coprocess_dd,
11594 /* 0xde */ x86emuOp_esc_coprocess_de,
11595 /* 0xdf */ x86emuOp_esc_coprocess_df,
11597 /* 0xe0 */ x86emuOp_loopne,
11598 /* 0xe1 */ x86emuOp_loope,
11599 /* 0xe2 */ x86emuOp_loop,
11600 /* 0xe3 */ x86emuOp_jcxz,
11601 /* 0xe4 */ x86emuOp_in_byte_AL_IMM,
11602 /* 0xe5 */ x86emuOp_in_word_AX_IMM,
11603 /* 0xe6 */ x86emuOp_out_byte_IMM_AL,
11604 /* 0xe7 */ x86emuOp_out_word_IMM_AX,
11606 /* 0xe8 */ x86emuOp_call_near_IMM,
11607 /* 0xe9 */ x86emuOp_jump_near_IMM,
11608 /* 0xea */ x86emuOp_jump_far_IMM,
11609 /* 0xeb */ x86emuOp_jump_byte_IMM,
11610 /* 0xec */ x86emuOp_in_byte_AL_DX,
11611 /* 0xed */ x86emuOp_in_word_AX_DX,
11612 /* 0xee */ x86emuOp_out_byte_DX_AL,
11613 /* 0xef */ x86emuOp_out_word_DX_AX,
11615 /* 0xf0 */ x86emuOp_lock,
11616 /* 0xf1 */ x86emuOp_illegal_op,
11617 /* 0xf2 */ x86emuOp_repne,
11618 /* 0xf3 */ x86emuOp_repe,
11619 /* 0xf4 */ x86emuOp_halt,
11620 /* 0xf5 */ x86emuOp_cmc,
11621 /* 0xf6 */ x86emuOp_opcF6_byte_RM,
11622 /* 0xf7 */ x86emuOp_opcF7_word_RM,
11624 /* 0xf8 */ x86emuOp_clc,
11625 /* 0xf9 */ x86emuOp_stc,
11626 /* 0xfa */ x86emuOp_cli,
11627 /* 0xfb */ x86emuOp_sti,
11628 /* 0xfc */ x86emuOp_cld,
11629 /* 0xfd */ x86emuOp_std,
11630 /* 0xfe */ x86emuOp_opcFE_byte_RM,
11631 /* 0xff */ x86emuOp_opcFF_word_RM,