]> git.ipfire.org Git - people/teissler/ipfire-2.x.git/blob - src/hwinfo/src/x86emu/ops.c
Kleiner netter neuer Versuch.
[people/teissler/ipfire-2.x.git] / src / hwinfo / src / x86emu / ops.c
1 /****************************************************************************
2 *
3 * Realmode X86 Emulator Library
4 *
5 * Copyright (C) 1996-1999 SciTech Software, Inc.
6 * Copyright (C) David Mosberger-Tang
7 * Copyright (C) 1999 Egbert Eich
8 *
9 * ========================================================================
10 *
11 * Permission to use, copy, modify, distribute, and sell this software and
12 * its documentation for any purpose is hereby granted without fee,
13 * provided that the above copyright notice appear in all copies and that
14 * both that copyright notice and this permission notice appear in
15 * supporting documentation, and that the name of the authors not be used
16 * in advertising or publicity pertaining to distribution of the software
17 * without specific, written prior permission. The authors makes no
18 * representations about the suitability of this software for any purpose.
19 * It is provided "as is" without express or implied warranty.
20 *
21 * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
22 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
23 * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
24 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
25 * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
26 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
27 * PERFORMANCE OF THIS SOFTWARE.
28 *
29 * ========================================================================
30 *
31 * Language: ANSI C
32 * Environment: Any
33 * Developer: Kendall Bennett
34 *
35 * Description: This file includes subroutines to implement the decoding
36 * and emulation of all the x86 processor instructions.
37 *
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].
41 *
42 * Each opcode proc has a comment preceeding it which gives it's table
43 * address. Several opcodes are missing (undefined) in the table.
44 *
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).
48 *
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.
70 *
71 ****************************************************************************/
72
73 /* $XFree86: xc/extras/x86emu/src/x86emu/ops.c,v 1.8tsi Exp $ */
74
75 #include "x86emu/x86emui.h"
76
77 /*----------------------------- Implementation ----------------------------*/
78
79 /****************************************************************************
80 PARAMETERS:
81 op1 - Instruction op code
82
83 REMARKS:
84 Handles illegal opcodes.
85 ****************************************************************************/
86 static void x86emuOp_illegal_op(
87 u8 op1)
88 {
89 START_OF_INSTR();
90 if (M.x86.R_SP != 0) {
91 DECODE_PRINTF("ILLEGAL X86 OPCODE\n");
92 TRACE_REGS();
93 printk("%04x:%04x: %02X ILLEGAL X86 OPCODE!\n",
94 M.x86.R_CS, M.x86.R_IP-1,op1);
95 HALT_SYS();
96 }
97 else {
98 /* If we get here, it means the stack pointer is back to zero
99 * so we are just returning from an emulator service call
100 * so therte is no need to display an error message. We trap
101 * the emulator with an 0xF1 opcode to finish the service
102 * call.
103 */
104 X86EMU_halt_sys();
105 }
106 END_OF_INSTR();
107 }
108
109 /****************************************************************************
110 REMARKS:
111 Handles opcode 0x00
112 ****************************************************************************/
113 static void x86emuOp_add_byte_RM_R(u8 X86EMU_UNUSED(op1))
114 {
115 int mod, rl, rh;
116 uint destoffset;
117 u8 *destreg, *srcreg;
118 u8 destval;
119
120 START_OF_INSTR();
121 DECODE_PRINTF("ADD\t");
122 FETCH_DECODE_MODRM(mod, rh, rl);
123 switch (mod) {
124 case 0:
125 destoffset = decode_rm00_address(rl);
126 DECODE_PRINTF(",");
127 destval = fetch_data_byte(destoffset);
128 srcreg = DECODE_RM_BYTE_REGISTER(rh);
129 DECODE_PRINTF("\n");
130 TRACE_AND_STEP();
131 destval = add_byte(destval, *srcreg);
132 store_data_byte(destoffset, destval);
133 break;
134 case 1:
135 destoffset = decode_rm01_address(rl);
136 DECODE_PRINTF(",");
137 destval = fetch_data_byte(destoffset);
138 srcreg = DECODE_RM_BYTE_REGISTER(rh);
139 DECODE_PRINTF("\n");
140 TRACE_AND_STEP();
141 destval = add_byte(destval, *srcreg);
142 store_data_byte(destoffset, destval);
143 break;
144 case 2:
145 destoffset = decode_rm10_address(rl);
146 DECODE_PRINTF(",");
147 destval = fetch_data_byte(destoffset);
148 srcreg = DECODE_RM_BYTE_REGISTER(rh);
149 DECODE_PRINTF("\n");
150 TRACE_AND_STEP();
151 destval = add_byte(destval, *srcreg);
152 store_data_byte(destoffset, destval);
153 break;
154 case 3: /* register to register */
155 destreg = DECODE_RM_BYTE_REGISTER(rl);
156 DECODE_PRINTF(",");
157 srcreg = DECODE_RM_BYTE_REGISTER(rh);
158 DECODE_PRINTF("\n");
159 TRACE_AND_STEP();
160 *destreg = add_byte(*destreg, *srcreg);
161 break;
162 }
163 DECODE_CLEAR_SEGOVR();
164 END_OF_INSTR();
165 }
166
167 /****************************************************************************
168 REMARKS:
169 Handles opcode 0x01
170 ****************************************************************************/
171 static void x86emuOp_add_word_RM_R(u8 X86EMU_UNUSED(op1))
172 {
173 int mod, rl, rh;
174 uint destoffset;
175
176 START_OF_INSTR();
177 DECODE_PRINTF("ADD\t");
178 FETCH_DECODE_MODRM(mod, rh, rl);
179 switch (mod) {
180 case 0:
181 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
182 u32 destval;
183 u32 *srcreg;
184
185 destoffset = decode_rm00_address(rl);
186 DECODE_PRINTF(",");
187 destval = fetch_data_long(destoffset);
188 srcreg = DECODE_RM_LONG_REGISTER(rh);
189 DECODE_PRINTF("\n");
190 TRACE_AND_STEP();
191 destval = add_long(destval, *srcreg);
192 store_data_long(destoffset, destval);
193 } else {
194 u16 destval;
195 u16 *srcreg;
196
197 destoffset = decode_rm00_address(rl);
198 DECODE_PRINTF(",");
199 destval = fetch_data_word(destoffset);
200 srcreg = DECODE_RM_WORD_REGISTER(rh);
201 DECODE_PRINTF("\n");
202 TRACE_AND_STEP();
203 destval = add_word(destval, *srcreg);
204 store_data_word(destoffset, destval);
205 }
206 break;
207 case 1:
208 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
209 u32 destval;
210 u32 *srcreg;
211
212 destoffset = decode_rm01_address(rl);
213 DECODE_PRINTF(",");
214 destval = fetch_data_long(destoffset);
215 srcreg = DECODE_RM_LONG_REGISTER(rh);
216 DECODE_PRINTF("\n");
217 TRACE_AND_STEP();
218 destval = add_long(destval, *srcreg);
219 store_data_long(destoffset, destval);
220 } else {
221 u16 destval;
222 u16 *srcreg;
223
224 destoffset = decode_rm01_address(rl);
225 DECODE_PRINTF(",");
226 destval = fetch_data_word(destoffset);
227 srcreg = DECODE_RM_WORD_REGISTER(rh);
228 DECODE_PRINTF("\n");
229 TRACE_AND_STEP();
230 destval = add_word(destval, *srcreg);
231 store_data_word(destoffset, destval);
232 }
233 break;
234 case 2:
235 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
236 u32 destval;
237 u32 *srcreg;
238
239 destoffset = decode_rm10_address(rl);
240 DECODE_PRINTF(",");
241 destval = fetch_data_long(destoffset);
242 srcreg = DECODE_RM_LONG_REGISTER(rh);
243 DECODE_PRINTF("\n");
244 TRACE_AND_STEP();
245 destval = add_long(destval, *srcreg);
246 store_data_long(destoffset, destval);
247 } else {
248 u16 destval;
249 u16 *srcreg;
250
251 destoffset = decode_rm10_address(rl);
252 DECODE_PRINTF(",");
253 destval = fetch_data_word(destoffset);
254 srcreg = DECODE_RM_WORD_REGISTER(rh);
255 DECODE_PRINTF("\n");
256 TRACE_AND_STEP();
257 destval = add_word(destval, *srcreg);
258 store_data_word(destoffset, destval);
259 }
260 break;
261 case 3: /* register to register */
262 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
263 u32 *destreg,*srcreg;
264
265 destreg = DECODE_RM_LONG_REGISTER(rl);
266 DECODE_PRINTF(",");
267 srcreg = DECODE_RM_LONG_REGISTER(rh);
268 DECODE_PRINTF("\n");
269 TRACE_AND_STEP();
270 *destreg = add_long(*destreg, *srcreg);
271 } else {
272 u16 *destreg,*srcreg;
273
274 destreg = DECODE_RM_WORD_REGISTER(rl);
275 DECODE_PRINTF(",");
276 srcreg = DECODE_RM_WORD_REGISTER(rh);
277 DECODE_PRINTF("\n");
278 TRACE_AND_STEP();
279 *destreg = add_word(*destreg, *srcreg);
280 }
281 break;
282 }
283 DECODE_CLEAR_SEGOVR();
284 END_OF_INSTR();
285 }
286
287 /****************************************************************************
288 REMARKS:
289 Handles opcode 0x02
290 ****************************************************************************/
291 static void x86emuOp_add_byte_R_RM(u8 X86EMU_UNUSED(op1))
292 {
293 int mod, rl, rh;
294 u8 *destreg, *srcreg;
295 uint srcoffset;
296 u8 srcval;
297
298 START_OF_INSTR();
299 DECODE_PRINTF("ADD\t");
300 FETCH_DECODE_MODRM(mod, rh, rl);
301 switch (mod) {
302 case 0:
303 destreg = DECODE_RM_BYTE_REGISTER(rh);
304 DECODE_PRINTF(",");
305 srcoffset = decode_rm00_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 1:
312 destreg = DECODE_RM_BYTE_REGISTER(rh);
313 DECODE_PRINTF(",");
314 srcoffset = decode_rm01_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 2:
321 destreg = DECODE_RM_BYTE_REGISTER(rh);
322 DECODE_PRINTF(",");
323 srcoffset = decode_rm10_address(rl);
324 srcval = fetch_data_byte(srcoffset);
325 DECODE_PRINTF("\n");
326 TRACE_AND_STEP();
327 *destreg = add_byte(*destreg, srcval);
328 break;
329 case 3: /* register to register */
330 destreg = DECODE_RM_BYTE_REGISTER(rh);
331 DECODE_PRINTF(",");
332 srcreg = DECODE_RM_BYTE_REGISTER(rl);
333 DECODE_PRINTF("\n");
334 TRACE_AND_STEP();
335 *destreg = add_byte(*destreg, *srcreg);
336 break;
337 }
338 DECODE_CLEAR_SEGOVR();
339 END_OF_INSTR();
340 }
341
342 /****************************************************************************
343 REMARKS:
344 Handles opcode 0x03
345 ****************************************************************************/
346 static void x86emuOp_add_word_R_RM(u8 X86EMU_UNUSED(op1))
347 {
348 int mod, rl, rh;
349 uint srcoffset;
350
351 START_OF_INSTR();
352 DECODE_PRINTF("ADD\t");
353 FETCH_DECODE_MODRM(mod, rh, rl);
354 switch (mod) {
355 case 0:
356 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
357 u32 *destreg;
358 u32 srcval;
359
360 destreg = DECODE_RM_LONG_REGISTER(rh);
361 DECODE_PRINTF(",");
362 srcoffset = decode_rm00_address(rl);
363 srcval = fetch_data_long(srcoffset);
364 DECODE_PRINTF("\n");
365 TRACE_AND_STEP();
366 *destreg = add_long(*destreg, srcval);
367 } else {
368 u16 *destreg;
369 u16 srcval;
370
371 destreg = DECODE_RM_WORD_REGISTER(rh);
372 DECODE_PRINTF(",");
373 srcoffset = decode_rm00_address(rl);
374 srcval = fetch_data_word(srcoffset);
375 DECODE_PRINTF("\n");
376 TRACE_AND_STEP();
377 *destreg = add_word(*destreg, srcval);
378 }
379 break;
380 case 1:
381 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
382 u32 *destreg;
383 u32 srcval;
384
385 destreg = DECODE_RM_LONG_REGISTER(rh);
386 DECODE_PRINTF(",");
387 srcoffset = decode_rm01_address(rl);
388 srcval = fetch_data_long(srcoffset);
389 DECODE_PRINTF("\n");
390 TRACE_AND_STEP();
391 *destreg = add_long(*destreg, srcval);
392 } else {
393 u16 *destreg;
394 u16 srcval;
395
396 destreg = DECODE_RM_WORD_REGISTER(rh);
397 DECODE_PRINTF(",");
398 srcoffset = decode_rm01_address(rl);
399 srcval = fetch_data_word(srcoffset);
400 DECODE_PRINTF("\n");
401 TRACE_AND_STEP();
402 *destreg = add_word(*destreg, srcval);
403 }
404 break;
405 case 2:
406 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
407 u32 *destreg;
408 u32 srcval;
409
410 destreg = DECODE_RM_LONG_REGISTER(rh);
411 DECODE_PRINTF(",");
412 srcoffset = decode_rm10_address(rl);
413 srcval = fetch_data_long(srcoffset);
414 DECODE_PRINTF("\n");
415 TRACE_AND_STEP();
416 *destreg = add_long(*destreg, srcval);
417 } else {
418 u16 *destreg;
419 u16 srcval;
420
421 destreg = DECODE_RM_WORD_REGISTER(rh);
422 DECODE_PRINTF(",");
423 srcoffset = decode_rm10_address(rl);
424 srcval = fetch_data_word(srcoffset);
425 DECODE_PRINTF("\n");
426 TRACE_AND_STEP();
427 *destreg = add_word(*destreg, srcval);
428 }
429 break;
430 case 3: /* register to register */
431 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
432 u32 *destreg,*srcreg;
433
434 destreg = DECODE_RM_LONG_REGISTER(rh);
435 DECODE_PRINTF(",");
436 srcreg = DECODE_RM_LONG_REGISTER(rl);
437 DECODE_PRINTF("\n");
438 TRACE_AND_STEP();
439 *destreg = add_long(*destreg, *srcreg);
440 } else {
441 u16 *destreg,*srcreg;
442
443 destreg = DECODE_RM_WORD_REGISTER(rh);
444 DECODE_PRINTF(",");
445 srcreg = DECODE_RM_WORD_REGISTER(rl);
446 DECODE_PRINTF("\n");
447 TRACE_AND_STEP();
448 *destreg = add_word(*destreg, *srcreg);
449 }
450 break;
451 }
452 DECODE_CLEAR_SEGOVR();
453 END_OF_INSTR();
454 }
455
456 /****************************************************************************
457 REMARKS:
458 Handles opcode 0x04
459 ****************************************************************************/
460 static void x86emuOp_add_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
461 {
462 u8 srcval;
463
464 START_OF_INSTR();
465 DECODE_PRINTF("ADD\tAL,");
466 srcval = fetch_byte_imm();
467 DECODE_PRINTF2("%x\n", srcval);
468 TRACE_AND_STEP();
469 M.x86.R_AL = add_byte(M.x86.R_AL, srcval);
470 DECODE_CLEAR_SEGOVR();
471 END_OF_INSTR();
472 }
473
474 /****************************************************************************
475 REMARKS:
476 Handles opcode 0x05
477 ****************************************************************************/
478 static void x86emuOp_add_word_AX_IMM(u8 X86EMU_UNUSED(op1))
479 {
480 u32 srcval;
481
482 START_OF_INSTR();
483 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
484 DECODE_PRINTF("ADD\tEAX,");
485 srcval = fetch_long_imm();
486 } else {
487 DECODE_PRINTF("ADD\tAX,");
488 srcval = fetch_word_imm();
489 }
490 DECODE_PRINTF2("%x\n", srcval);
491 TRACE_AND_STEP();
492 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
493 M.x86.R_EAX = add_long(M.x86.R_EAX, srcval);
494 } else {
495 M.x86.R_AX = add_word(M.x86.R_AX, (u16)srcval);
496 }
497 DECODE_CLEAR_SEGOVR();
498 END_OF_INSTR();
499 }
500
501 /****************************************************************************
502 REMARKS:
503 Handles opcode 0x06
504 ****************************************************************************/
505 static void x86emuOp_push_ES(u8 X86EMU_UNUSED(op1))
506 {
507 START_OF_INSTR();
508 DECODE_PRINTF("PUSH\tES\n");
509 TRACE_AND_STEP();
510 push_word(M.x86.R_ES);
511 DECODE_CLEAR_SEGOVR();
512 END_OF_INSTR();
513 }
514
515 /****************************************************************************
516 REMARKS:
517 Handles opcode 0x07
518 ****************************************************************************/
519 static void x86emuOp_pop_ES(u8 X86EMU_UNUSED(op1))
520 {
521 START_OF_INSTR();
522 DECODE_PRINTF("POP\tES\n");
523 TRACE_AND_STEP();
524 M.x86.R_ES = pop_word();
525 DECODE_CLEAR_SEGOVR();
526 END_OF_INSTR();
527 }
528
529 /****************************************************************************
530 REMARKS:
531 Handles opcode 0x08
532 ****************************************************************************/
533 static void x86emuOp_or_byte_RM_R(u8 X86EMU_UNUSED(op1))
534 {
535 int mod, rl, rh;
536 u8 *destreg, *srcreg;
537 uint destoffset;
538 u8 destval;
539
540 START_OF_INSTR();
541 DECODE_PRINTF("OR\t");
542 FETCH_DECODE_MODRM(mod, rh, rl);
543 switch (mod) {
544 case 0:
545 destoffset = decode_rm00_address(rl);
546 DECODE_PRINTF(",");
547 destval = fetch_data_byte(destoffset);
548 srcreg = DECODE_RM_BYTE_REGISTER(rh);
549 DECODE_PRINTF("\n");
550 TRACE_AND_STEP();
551 destval = or_byte(destval, *srcreg);
552 store_data_byte(destoffset, destval);
553 break;
554 case 1:
555 destoffset = decode_rm01_address(rl);
556 DECODE_PRINTF(",");
557 destval = fetch_data_byte(destoffset);
558 srcreg = DECODE_RM_BYTE_REGISTER(rh);
559 DECODE_PRINTF("\n");
560 TRACE_AND_STEP();
561 destval = or_byte(destval, *srcreg);
562 store_data_byte(destoffset, destval);
563 break;
564 case 2:
565 destoffset = decode_rm10_address(rl);
566 DECODE_PRINTF(",");
567 destval = fetch_data_byte(destoffset);
568 srcreg = DECODE_RM_BYTE_REGISTER(rh);
569 DECODE_PRINTF("\n");
570 TRACE_AND_STEP();
571 destval = or_byte(destval, *srcreg);
572 store_data_byte(destoffset, destval);
573 break;
574 case 3: /* register to register */
575 destreg = DECODE_RM_BYTE_REGISTER(rl);
576 DECODE_PRINTF(",");
577 srcreg = DECODE_RM_BYTE_REGISTER(rh);
578 DECODE_PRINTF("\n");
579 TRACE_AND_STEP();
580 *destreg = or_byte(*destreg, *srcreg);
581 break;
582 }
583 DECODE_CLEAR_SEGOVR();
584 END_OF_INSTR();
585 }
586
587 /****************************************************************************
588 REMARKS:
589 Handles opcode 0x09
590 ****************************************************************************/
591 static void x86emuOp_or_word_RM_R(u8 X86EMU_UNUSED(op1))
592 {
593 int mod, rl, rh;
594 uint destoffset;
595
596 START_OF_INSTR();
597 DECODE_PRINTF("OR\t");
598 FETCH_DECODE_MODRM(mod, rh, rl);
599 switch (mod) {
600 case 0:
601 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
602 u32 destval;
603 u32 *srcreg;
604
605 destoffset = decode_rm00_address(rl);
606 DECODE_PRINTF(",");
607 destval = fetch_data_long(destoffset);
608 srcreg = DECODE_RM_LONG_REGISTER(rh);
609 DECODE_PRINTF("\n");
610 TRACE_AND_STEP();
611 destval = or_long(destval, *srcreg);
612 store_data_long(destoffset, destval);
613 } else {
614 u16 destval;
615 u16 *srcreg;
616
617 destoffset = decode_rm00_address(rl);
618 DECODE_PRINTF(",");
619 destval = fetch_data_word(destoffset);
620 srcreg = DECODE_RM_WORD_REGISTER(rh);
621 DECODE_PRINTF("\n");
622 TRACE_AND_STEP();
623 destval = or_word(destval, *srcreg);
624 store_data_word(destoffset, destval);
625 }
626 break;
627 case 1:
628 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
629 u32 destval;
630 u32 *srcreg;
631
632 destoffset = decode_rm01_address(rl);
633 DECODE_PRINTF(",");
634 destval = fetch_data_long(destoffset);
635 srcreg = DECODE_RM_LONG_REGISTER(rh);
636 DECODE_PRINTF("\n");
637 TRACE_AND_STEP();
638 destval = or_long(destval, *srcreg);
639 store_data_long(destoffset, destval);
640 } else {
641 u16 destval;
642 u16 *srcreg;
643
644 destoffset = decode_rm01_address(rl);
645 DECODE_PRINTF(",");
646 destval = fetch_data_word(destoffset);
647 srcreg = DECODE_RM_WORD_REGISTER(rh);
648 DECODE_PRINTF("\n");
649 TRACE_AND_STEP();
650 destval = or_word(destval, *srcreg);
651 store_data_word(destoffset, destval);
652 }
653 break;
654 case 2:
655 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
656 u32 destval;
657 u32 *srcreg;
658
659 destoffset = decode_rm10_address(rl);
660 DECODE_PRINTF(",");
661 destval = fetch_data_long(destoffset);
662 srcreg = DECODE_RM_LONG_REGISTER(rh);
663 DECODE_PRINTF("\n");
664 TRACE_AND_STEP();
665 destval = or_long(destval, *srcreg);
666 store_data_long(destoffset, destval);
667 } else {
668 u16 destval;
669 u16 *srcreg;
670
671 destoffset = decode_rm10_address(rl);
672 DECODE_PRINTF(",");
673 destval = fetch_data_word(destoffset);
674 srcreg = DECODE_RM_WORD_REGISTER(rh);
675 DECODE_PRINTF("\n");
676 TRACE_AND_STEP();
677 destval = or_word(destval, *srcreg);
678 store_data_word(destoffset, destval);
679 }
680 break;
681 case 3: /* register to register */
682 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
683 u32 *destreg,*srcreg;
684
685 destreg = DECODE_RM_LONG_REGISTER(rl);
686 DECODE_PRINTF(",");
687 srcreg = DECODE_RM_LONG_REGISTER(rh);
688 DECODE_PRINTF("\n");
689 TRACE_AND_STEP();
690 *destreg = or_long(*destreg, *srcreg);
691 } else {
692 u16 *destreg,*srcreg;
693
694 destreg = DECODE_RM_WORD_REGISTER(rl);
695 DECODE_PRINTF(",");
696 srcreg = DECODE_RM_WORD_REGISTER(rh);
697 DECODE_PRINTF("\n");
698 TRACE_AND_STEP();
699 *destreg = or_word(*destreg, *srcreg);
700 }
701 break;
702 }
703 DECODE_CLEAR_SEGOVR();
704 END_OF_INSTR();
705 }
706
707 /****************************************************************************
708 REMARKS:
709 Handles opcode 0x0a
710 ****************************************************************************/
711 static void x86emuOp_or_byte_R_RM(u8 X86EMU_UNUSED(op1))
712 {
713 int mod, rl, rh;
714 u8 *destreg, *srcreg;
715 uint srcoffset;
716 u8 srcval;
717
718 START_OF_INSTR();
719 DECODE_PRINTF("OR\t");
720 FETCH_DECODE_MODRM(mod, rh, rl);
721 switch (mod) {
722 case 0:
723 destreg = DECODE_RM_BYTE_REGISTER(rh);
724 DECODE_PRINTF(",");
725 srcoffset = decode_rm00_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 1:
732 destreg = DECODE_RM_BYTE_REGISTER(rh);
733 DECODE_PRINTF(",");
734 srcoffset = decode_rm01_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 2:
741 destreg = DECODE_RM_BYTE_REGISTER(rh);
742 DECODE_PRINTF(",");
743 srcoffset = decode_rm10_address(rl);
744 srcval = fetch_data_byte(srcoffset);
745 DECODE_PRINTF("\n");
746 TRACE_AND_STEP();
747 *destreg = or_byte(*destreg, srcval);
748 break;
749 case 3: /* register to register */
750 destreg = DECODE_RM_BYTE_REGISTER(rh);
751 DECODE_PRINTF(",");
752 srcreg = DECODE_RM_BYTE_REGISTER(rl);
753 DECODE_PRINTF("\n");
754 TRACE_AND_STEP();
755 *destreg = or_byte(*destreg, *srcreg);
756 break;
757 }
758 DECODE_CLEAR_SEGOVR();
759 END_OF_INSTR();
760 }
761
762 /****************************************************************************
763 REMARKS:
764 Handles opcode 0x0b
765 ****************************************************************************/
766 static void x86emuOp_or_word_R_RM(u8 X86EMU_UNUSED(op1))
767 {
768 int mod, rl, rh;
769 uint srcoffset;
770
771 START_OF_INSTR();
772 DECODE_PRINTF("OR\t");
773 FETCH_DECODE_MODRM(mod, rh, rl);
774 switch (mod) {
775 case 0:
776 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
777 u32 *destreg;
778 u32 srcval;
779
780 destreg = DECODE_RM_LONG_REGISTER(rh);
781 DECODE_PRINTF(",");
782 srcoffset = decode_rm00_address(rl);
783 srcval = fetch_data_long(srcoffset);
784 DECODE_PRINTF("\n");
785 TRACE_AND_STEP();
786 *destreg = or_long(*destreg, srcval);
787 } else {
788 u16 *destreg;
789 u16 srcval;
790
791 destreg = DECODE_RM_WORD_REGISTER(rh);
792 DECODE_PRINTF(",");
793 srcoffset = decode_rm00_address(rl);
794 srcval = fetch_data_word(srcoffset);
795 DECODE_PRINTF("\n");
796 TRACE_AND_STEP();
797 *destreg = or_word(*destreg, srcval);
798 }
799 break;
800 case 1:
801 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
802 u32 *destreg;
803 u32 srcval;
804
805 destreg = DECODE_RM_LONG_REGISTER(rh);
806 DECODE_PRINTF(",");
807 srcoffset = decode_rm01_address(rl);
808 srcval = fetch_data_long(srcoffset);
809 DECODE_PRINTF("\n");
810 TRACE_AND_STEP();
811 *destreg = or_long(*destreg, srcval);
812 } else {
813 u16 *destreg;
814 u16 srcval;
815
816 destreg = DECODE_RM_WORD_REGISTER(rh);
817 DECODE_PRINTF(",");
818 srcoffset = decode_rm01_address(rl);
819 srcval = fetch_data_word(srcoffset);
820 DECODE_PRINTF("\n");
821 TRACE_AND_STEP();
822 *destreg = or_word(*destreg, srcval);
823 }
824 break;
825 case 2:
826 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
827 u32 *destreg;
828 u32 srcval;
829
830 destreg = DECODE_RM_LONG_REGISTER(rh);
831 DECODE_PRINTF(",");
832 srcoffset = decode_rm10_address(rl);
833 srcval = fetch_data_long(srcoffset);
834 DECODE_PRINTF("\n");
835 TRACE_AND_STEP();
836 *destreg = or_long(*destreg, srcval);
837 } else {
838 u16 *destreg;
839 u16 srcval;
840
841 destreg = DECODE_RM_WORD_REGISTER(rh);
842 DECODE_PRINTF(",");
843 srcoffset = decode_rm10_address(rl);
844 srcval = fetch_data_word(srcoffset);
845 DECODE_PRINTF("\n");
846 TRACE_AND_STEP();
847 *destreg = or_word(*destreg, srcval);
848 }
849 break;
850 case 3: /* register to register */
851 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
852 u32 *destreg,*srcreg;
853
854 destreg = DECODE_RM_LONG_REGISTER(rh);
855 DECODE_PRINTF(",");
856 srcreg = DECODE_RM_LONG_REGISTER(rl);
857 DECODE_PRINTF("\n");
858 TRACE_AND_STEP();
859 *destreg = or_long(*destreg, *srcreg);
860 } else {
861 u16 *destreg,*srcreg;
862
863 destreg = DECODE_RM_WORD_REGISTER(rh);
864 DECODE_PRINTF(",");
865 srcreg = DECODE_RM_WORD_REGISTER(rl);
866 DECODE_PRINTF("\n");
867 TRACE_AND_STEP();
868 *destreg = or_word(*destreg, *srcreg);
869 }
870 break;
871 }
872 DECODE_CLEAR_SEGOVR();
873 END_OF_INSTR();
874 }
875
876 /****************************************************************************
877 REMARKS:
878 Handles opcode 0x0c
879 ****************************************************************************/
880 static void x86emuOp_or_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
881 {
882 u8 srcval;
883
884 START_OF_INSTR();
885 DECODE_PRINTF("OR\tAL,");
886 srcval = fetch_byte_imm();
887 DECODE_PRINTF2("%x\n", srcval);
888 TRACE_AND_STEP();
889 M.x86.R_AL = or_byte(M.x86.R_AL, srcval);
890 DECODE_CLEAR_SEGOVR();
891 END_OF_INSTR();
892 }
893
894 /****************************************************************************
895 REMARKS:
896 Handles opcode 0x0d
897 ****************************************************************************/
898 static void x86emuOp_or_word_AX_IMM(u8 X86EMU_UNUSED(op1))
899 {
900 u32 srcval;
901
902 START_OF_INSTR();
903 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
904 DECODE_PRINTF("OR\tEAX,");
905 srcval = fetch_long_imm();
906 } else {
907 DECODE_PRINTF("OR\tAX,");
908 srcval = fetch_word_imm();
909 }
910 DECODE_PRINTF2("%x\n", srcval);
911 TRACE_AND_STEP();
912 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
913 M.x86.R_EAX = or_long(M.x86.R_EAX, srcval);
914 } else {
915 M.x86.R_AX = or_word(M.x86.R_AX, (u16)srcval);
916 }
917 DECODE_CLEAR_SEGOVR();
918 END_OF_INSTR();
919 }
920
921 /****************************************************************************
922 REMARKS:
923 Handles opcode 0x0e
924 ****************************************************************************/
925 static void x86emuOp_push_CS(u8 X86EMU_UNUSED(op1))
926 {
927 START_OF_INSTR();
928 DECODE_PRINTF("PUSH\tCS\n");
929 TRACE_AND_STEP();
930 push_word(M.x86.R_CS);
931 DECODE_CLEAR_SEGOVR();
932 END_OF_INSTR();
933 }
934
935 /****************************************************************************
936 REMARKS:
937 Handles opcode 0x0f. Escape for two-byte opcode (286 or better)
938 ****************************************************************************/
939 static void x86emuOp_two_byte(u8 X86EMU_UNUSED(op1))
940 {
941 u8 op2 = (*sys_rdb)(((u32)M.x86.R_CS << 4) + (M.x86.R_IP++));
942 INC_DECODED_INST_LEN(1);
943 (*x86emu_optab2[op2])(op2);
944 }
945
946 /****************************************************************************
947 REMARKS:
948 Handles opcode 0x10
949 ****************************************************************************/
950 static void x86emuOp_adc_byte_RM_R(u8 X86EMU_UNUSED(op1))
951 {
952 int mod, rl, rh;
953 u8 *destreg, *srcreg;
954 uint destoffset;
955 u8 destval;
956
957 START_OF_INSTR();
958 DECODE_PRINTF("ADC\t");
959 FETCH_DECODE_MODRM(mod, rh, rl);
960 switch (mod) {
961 case 0:
962 destoffset = decode_rm00_address(rl);
963 DECODE_PRINTF(",");
964 destval = fetch_data_byte(destoffset);
965 srcreg = DECODE_RM_BYTE_REGISTER(rh);
966 DECODE_PRINTF("\n");
967 TRACE_AND_STEP();
968 destval = adc_byte(destval, *srcreg);
969 store_data_byte(destoffset, destval);
970 break;
971 case 1:
972 destoffset = decode_rm01_address(rl);
973 DECODE_PRINTF(",");
974 destval = fetch_data_byte(destoffset);
975 srcreg = DECODE_RM_BYTE_REGISTER(rh);
976 DECODE_PRINTF("\n");
977 TRACE_AND_STEP();
978 destval = adc_byte(destval, *srcreg);
979 store_data_byte(destoffset, destval);
980 break;
981 case 2:
982 destoffset = decode_rm10_address(rl);
983 DECODE_PRINTF(",");
984 destval = fetch_data_byte(destoffset);
985 srcreg = DECODE_RM_BYTE_REGISTER(rh);
986 DECODE_PRINTF("\n");
987 TRACE_AND_STEP();
988 destval = adc_byte(destval, *srcreg);
989 store_data_byte(destoffset, destval);
990 break;
991 case 3: /* register to register */
992 destreg = DECODE_RM_BYTE_REGISTER(rl);
993 DECODE_PRINTF(",");
994 srcreg = DECODE_RM_BYTE_REGISTER(rh);
995 DECODE_PRINTF("\n");
996 TRACE_AND_STEP();
997 *destreg = adc_byte(*destreg, *srcreg);
998 break;
999 }
1000 DECODE_CLEAR_SEGOVR();
1001 END_OF_INSTR();
1002 }
1003
1004 /****************************************************************************
1005 REMARKS:
1006 Handles opcode 0x11
1007 ****************************************************************************/
1008 static void x86emuOp_adc_word_RM_R(u8 X86EMU_UNUSED(op1))
1009 {
1010 int mod, rl, rh;
1011 uint destoffset;
1012
1013 START_OF_INSTR();
1014 DECODE_PRINTF("ADC\t");
1015 FETCH_DECODE_MODRM(mod, rh, rl);
1016 switch (mod) {
1017 case 0:
1018 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1019 u32 destval;
1020 u32 *srcreg;
1021
1022 destoffset = decode_rm00_address(rl);
1023 DECODE_PRINTF(",");
1024 destval = fetch_data_long(destoffset);
1025 srcreg = DECODE_RM_LONG_REGISTER(rh);
1026 DECODE_PRINTF("\n");
1027 TRACE_AND_STEP();
1028 destval = adc_long(destval, *srcreg);
1029 store_data_long(destoffset, destval);
1030 } else {
1031 u16 destval;
1032 u16 *srcreg;
1033
1034 destoffset = decode_rm00_address(rl);
1035 DECODE_PRINTF(",");
1036 destval = fetch_data_word(destoffset);
1037 srcreg = DECODE_RM_WORD_REGISTER(rh);
1038 DECODE_PRINTF("\n");
1039 TRACE_AND_STEP();
1040 destval = adc_word(destval, *srcreg);
1041 store_data_word(destoffset, destval);
1042 }
1043 break;
1044 case 1:
1045 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1046 u32 destval;
1047 u32 *srcreg;
1048
1049 destoffset = decode_rm01_address(rl);
1050 DECODE_PRINTF(",");
1051 destval = fetch_data_long(destoffset);
1052 srcreg = DECODE_RM_LONG_REGISTER(rh);
1053 DECODE_PRINTF("\n");
1054 TRACE_AND_STEP();
1055 destval = adc_long(destval, *srcreg);
1056 store_data_long(destoffset, destval);
1057 } else {
1058 u16 destval;
1059 u16 *srcreg;
1060
1061 destoffset = decode_rm01_address(rl);
1062 DECODE_PRINTF(",");
1063 destval = fetch_data_word(destoffset);
1064 srcreg = DECODE_RM_WORD_REGISTER(rh);
1065 DECODE_PRINTF("\n");
1066 TRACE_AND_STEP();
1067 destval = adc_word(destval, *srcreg);
1068 store_data_word(destoffset, destval);
1069 }
1070 break;
1071 case 2:
1072 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1073 u32 destval;
1074 u32 *srcreg;
1075
1076 destoffset = decode_rm10_address(rl);
1077 DECODE_PRINTF(",");
1078 destval = fetch_data_long(destoffset);
1079 srcreg = DECODE_RM_LONG_REGISTER(rh);
1080 DECODE_PRINTF("\n");
1081 TRACE_AND_STEP();
1082 destval = adc_long(destval, *srcreg);
1083 store_data_long(destoffset, destval);
1084 } else {
1085 u16 destval;
1086 u16 *srcreg;
1087
1088 destoffset = decode_rm10_address(rl);
1089 DECODE_PRINTF(",");
1090 destval = fetch_data_word(destoffset);
1091 srcreg = DECODE_RM_WORD_REGISTER(rh);
1092 DECODE_PRINTF("\n");
1093 TRACE_AND_STEP();
1094 destval = adc_word(destval, *srcreg);
1095 store_data_word(destoffset, destval);
1096 }
1097 break;
1098 case 3: /* register to register */
1099 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1100 u32 *destreg,*srcreg;
1101
1102 destreg = DECODE_RM_LONG_REGISTER(rl);
1103 DECODE_PRINTF(",");
1104 srcreg = DECODE_RM_LONG_REGISTER(rh);
1105 DECODE_PRINTF("\n");
1106 TRACE_AND_STEP();
1107 *destreg = adc_long(*destreg, *srcreg);
1108 } else {
1109 u16 *destreg,*srcreg;
1110
1111 destreg = DECODE_RM_WORD_REGISTER(rl);
1112 DECODE_PRINTF(",");
1113 srcreg = DECODE_RM_WORD_REGISTER(rh);
1114 DECODE_PRINTF("\n");
1115 TRACE_AND_STEP();
1116 *destreg = adc_word(*destreg, *srcreg);
1117 }
1118 break;
1119 }
1120 DECODE_CLEAR_SEGOVR();
1121 END_OF_INSTR();
1122 }
1123
1124 /****************************************************************************
1125 REMARKS:
1126 Handles opcode 0x12
1127 ****************************************************************************/
1128 static void x86emuOp_adc_byte_R_RM(u8 X86EMU_UNUSED(op1))
1129 {
1130 int mod, rl, rh;
1131 u8 *destreg, *srcreg;
1132 uint srcoffset;
1133 u8 srcval;
1134
1135 START_OF_INSTR();
1136 DECODE_PRINTF("ADC\t");
1137 FETCH_DECODE_MODRM(mod, rh, rl);
1138 switch (mod) {
1139 case 0:
1140 destreg = DECODE_RM_BYTE_REGISTER(rh);
1141 DECODE_PRINTF(",");
1142 srcoffset = decode_rm00_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 1:
1149 destreg = DECODE_RM_BYTE_REGISTER(rh);
1150 DECODE_PRINTF(",");
1151 srcoffset = decode_rm01_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 2:
1158 destreg = DECODE_RM_BYTE_REGISTER(rh);
1159 DECODE_PRINTF(",");
1160 srcoffset = decode_rm10_address(rl);
1161 srcval = fetch_data_byte(srcoffset);
1162 DECODE_PRINTF("\n");
1163 TRACE_AND_STEP();
1164 *destreg = adc_byte(*destreg, srcval);
1165 break;
1166 case 3: /* register to register */
1167 destreg = DECODE_RM_BYTE_REGISTER(rh);
1168 DECODE_PRINTF(",");
1169 srcreg = DECODE_RM_BYTE_REGISTER(rl);
1170 DECODE_PRINTF("\n");
1171 TRACE_AND_STEP();
1172 *destreg = adc_byte(*destreg, *srcreg);
1173 break;
1174 }
1175 DECODE_CLEAR_SEGOVR();
1176 END_OF_INSTR();
1177 }
1178
1179 /****************************************************************************
1180 REMARKS:
1181 Handles opcode 0x13
1182 ****************************************************************************/
1183 static void x86emuOp_adc_word_R_RM(u8 X86EMU_UNUSED(op1))
1184 {
1185 int mod, rl, rh;
1186 uint srcoffset;
1187
1188 START_OF_INSTR();
1189 DECODE_PRINTF("ADC\t");
1190 FETCH_DECODE_MODRM(mod, rh, rl);
1191 switch (mod) {
1192 case 0:
1193 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1194 u32 *destreg;
1195 u32 srcval;
1196
1197 destreg = DECODE_RM_LONG_REGISTER(rh);
1198 DECODE_PRINTF(",");
1199 srcoffset = decode_rm00_address(rl);
1200 srcval = fetch_data_long(srcoffset);
1201 DECODE_PRINTF("\n");
1202 TRACE_AND_STEP();
1203 *destreg = adc_long(*destreg, srcval);
1204 } else {
1205 u16 *destreg;
1206 u16 srcval;
1207
1208 destreg = DECODE_RM_WORD_REGISTER(rh);
1209 DECODE_PRINTF(",");
1210 srcoffset = decode_rm00_address(rl);
1211 srcval = fetch_data_word(srcoffset);
1212 DECODE_PRINTF("\n");
1213 TRACE_AND_STEP();
1214 *destreg = adc_word(*destreg, srcval);
1215 }
1216 break;
1217 case 1:
1218 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1219 u32 *destreg;
1220 u32 srcval;
1221
1222 destreg = DECODE_RM_LONG_REGISTER(rh);
1223 DECODE_PRINTF(",");
1224 srcoffset = decode_rm01_address(rl);
1225 srcval = fetch_data_long(srcoffset);
1226 DECODE_PRINTF("\n");
1227 TRACE_AND_STEP();
1228 *destreg = adc_long(*destreg, srcval);
1229 } else {
1230 u16 *destreg;
1231 u16 srcval;
1232
1233 destreg = DECODE_RM_WORD_REGISTER(rh);
1234 DECODE_PRINTF(",");
1235 srcoffset = decode_rm01_address(rl);
1236 srcval = fetch_data_word(srcoffset);
1237 DECODE_PRINTF("\n");
1238 TRACE_AND_STEP();
1239 *destreg = adc_word(*destreg, srcval);
1240 }
1241 break;
1242 case 2:
1243 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1244 u32 *destreg;
1245 u32 srcval;
1246
1247 destreg = DECODE_RM_LONG_REGISTER(rh);
1248 DECODE_PRINTF(",");
1249 srcoffset = decode_rm10_address(rl);
1250 srcval = fetch_data_long(srcoffset);
1251 DECODE_PRINTF("\n");
1252 TRACE_AND_STEP();
1253 *destreg = adc_long(*destreg, srcval);
1254 } else {
1255 u16 *destreg;
1256 u16 srcval;
1257
1258 destreg = DECODE_RM_WORD_REGISTER(rh);
1259 DECODE_PRINTF(",");
1260 srcoffset = decode_rm10_address(rl);
1261 srcval = fetch_data_word(srcoffset);
1262 DECODE_PRINTF("\n");
1263 TRACE_AND_STEP();
1264 *destreg = adc_word(*destreg, srcval);
1265 }
1266 break;
1267 case 3: /* register to register */
1268 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1269 u32 *destreg,*srcreg;
1270
1271 destreg = DECODE_RM_LONG_REGISTER(rh);
1272 DECODE_PRINTF(",");
1273 srcreg = DECODE_RM_LONG_REGISTER(rl);
1274 DECODE_PRINTF("\n");
1275 TRACE_AND_STEP();
1276 *destreg = adc_long(*destreg, *srcreg);
1277 } else {
1278 u16 *destreg,*srcreg;
1279
1280 destreg = DECODE_RM_WORD_REGISTER(rh);
1281 DECODE_PRINTF(",");
1282 srcreg = DECODE_RM_WORD_REGISTER(rl);
1283 DECODE_PRINTF("\n");
1284 TRACE_AND_STEP();
1285 *destreg = adc_word(*destreg, *srcreg);
1286 }
1287 break;
1288 }
1289 DECODE_CLEAR_SEGOVR();
1290 END_OF_INSTR();
1291 }
1292
1293 /****************************************************************************
1294 REMARKS:
1295 Handles opcode 0x14
1296 ****************************************************************************/
1297 static void x86emuOp_adc_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
1298 {
1299 u8 srcval;
1300
1301 START_OF_INSTR();
1302 DECODE_PRINTF("ADC\tAL,");
1303 srcval = fetch_byte_imm();
1304 DECODE_PRINTF2("%x\n", srcval);
1305 TRACE_AND_STEP();
1306 M.x86.R_AL = adc_byte(M.x86.R_AL, srcval);
1307 DECODE_CLEAR_SEGOVR();
1308 END_OF_INSTR();
1309 }
1310
1311 /****************************************************************************
1312 REMARKS:
1313 Handles opcode 0x15
1314 ****************************************************************************/
1315 static void x86emuOp_adc_word_AX_IMM(u8 X86EMU_UNUSED(op1))
1316 {
1317 u32 srcval;
1318
1319 START_OF_INSTR();
1320 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1321 DECODE_PRINTF("ADC\tEAX,");
1322 srcval = fetch_long_imm();
1323 } else {
1324 DECODE_PRINTF("ADC\tAX,");
1325 srcval = fetch_word_imm();
1326 }
1327 DECODE_PRINTF2("%x\n", srcval);
1328 TRACE_AND_STEP();
1329 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1330 M.x86.R_EAX = adc_long(M.x86.R_EAX, srcval);
1331 } else {
1332 M.x86.R_AX = adc_word(M.x86.R_AX, (u16)srcval);
1333 }
1334 DECODE_CLEAR_SEGOVR();
1335 END_OF_INSTR();
1336 }
1337
1338 /****************************************************************************
1339 REMARKS:
1340 Handles opcode 0x16
1341 ****************************************************************************/
1342 static void x86emuOp_push_SS(u8 X86EMU_UNUSED(op1))
1343 {
1344 START_OF_INSTR();
1345 DECODE_PRINTF("PUSH\tSS\n");
1346 TRACE_AND_STEP();
1347 push_word(M.x86.R_SS);
1348 DECODE_CLEAR_SEGOVR();
1349 END_OF_INSTR();
1350 }
1351
1352 /****************************************************************************
1353 REMARKS:
1354 Handles opcode 0x17
1355 ****************************************************************************/
1356 static void x86emuOp_pop_SS(u8 X86EMU_UNUSED(op1))
1357 {
1358 START_OF_INSTR();
1359 DECODE_PRINTF("POP\tSS\n");
1360 TRACE_AND_STEP();
1361 M.x86.R_SS = pop_word();
1362 DECODE_CLEAR_SEGOVR();
1363 END_OF_INSTR();
1364 }
1365
1366 /****************************************************************************
1367 REMARKS:
1368 Handles opcode 0x18
1369 ****************************************************************************/
1370 static void x86emuOp_sbb_byte_RM_R(u8 X86EMU_UNUSED(op1))
1371 {
1372 int mod, rl, rh;
1373 u8 *destreg, *srcreg;
1374 uint destoffset;
1375 u8 destval;
1376
1377 START_OF_INSTR();
1378 DECODE_PRINTF("SBB\t");
1379 FETCH_DECODE_MODRM(mod, rh, rl);
1380 switch (mod) {
1381 case 0:
1382 destoffset = decode_rm00_address(rl);
1383 DECODE_PRINTF(",");
1384 destval = fetch_data_byte(destoffset);
1385 srcreg = DECODE_RM_BYTE_REGISTER(rh);
1386 DECODE_PRINTF("\n");
1387 TRACE_AND_STEP();
1388 destval = sbb_byte(destval, *srcreg);
1389 store_data_byte(destoffset, destval);
1390 break;
1391 case 1:
1392 destoffset = decode_rm01_address(rl);
1393 DECODE_PRINTF(",");
1394 destval = fetch_data_byte(destoffset);
1395 srcreg = DECODE_RM_BYTE_REGISTER(rh);
1396 DECODE_PRINTF("\n");
1397 TRACE_AND_STEP();
1398 destval = sbb_byte(destval, *srcreg);
1399 store_data_byte(destoffset, destval);
1400 break;
1401 case 2:
1402 destoffset = decode_rm10_address(rl);
1403 DECODE_PRINTF(",");
1404 destval = fetch_data_byte(destoffset);
1405 srcreg = DECODE_RM_BYTE_REGISTER(rh);
1406 DECODE_PRINTF("\n");
1407 TRACE_AND_STEP();
1408 destval = sbb_byte(destval, *srcreg);
1409 store_data_byte(destoffset, destval);
1410 break;
1411 case 3: /* register to register */
1412 destreg = DECODE_RM_BYTE_REGISTER(rl);
1413 DECODE_PRINTF(",");
1414 srcreg = DECODE_RM_BYTE_REGISTER(rh);
1415 DECODE_PRINTF("\n");
1416 TRACE_AND_STEP();
1417 *destreg = sbb_byte(*destreg, *srcreg);
1418 break;
1419 }
1420 DECODE_CLEAR_SEGOVR();
1421 END_OF_INSTR();
1422 }
1423
1424 /****************************************************************************
1425 REMARKS:
1426 Handles opcode 0x19
1427 ****************************************************************************/
1428 static void x86emuOp_sbb_word_RM_R(u8 X86EMU_UNUSED(op1))
1429 {
1430 int mod, rl, rh;
1431 uint destoffset;
1432
1433 START_OF_INSTR();
1434 DECODE_PRINTF("SBB\t");
1435 FETCH_DECODE_MODRM(mod, rh, rl);
1436 switch (mod) {
1437 case 0:
1438 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1439 u32 destval;
1440 u32 *srcreg;
1441
1442 destoffset = decode_rm00_address(rl);
1443 DECODE_PRINTF(",");
1444 destval = fetch_data_long(destoffset);
1445 srcreg = DECODE_RM_LONG_REGISTER(rh);
1446 DECODE_PRINTF("\n");
1447 TRACE_AND_STEP();
1448 destval = sbb_long(destval, *srcreg);
1449 store_data_long(destoffset, destval);
1450 } else {
1451 u16 destval;
1452 u16 *srcreg;
1453
1454 destoffset = decode_rm00_address(rl);
1455 DECODE_PRINTF(",");
1456 destval = fetch_data_word(destoffset);
1457 srcreg = DECODE_RM_WORD_REGISTER(rh);
1458 DECODE_PRINTF("\n");
1459 TRACE_AND_STEP();
1460 destval = sbb_word(destval, *srcreg);
1461 store_data_word(destoffset, destval);
1462 }
1463 break;
1464 case 1:
1465 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1466 u32 destval;
1467 u32 *srcreg;
1468
1469 destoffset = decode_rm01_address(rl);
1470 DECODE_PRINTF(",");
1471 destval = fetch_data_long(destoffset);
1472 srcreg = DECODE_RM_LONG_REGISTER(rh);
1473 DECODE_PRINTF("\n");
1474 TRACE_AND_STEP();
1475 destval = sbb_long(destval, *srcreg);
1476 store_data_long(destoffset, destval);
1477 } else {
1478 u16 destval;
1479 u16 *srcreg;
1480
1481 destoffset = decode_rm01_address(rl);
1482 DECODE_PRINTF(",");
1483 destval = fetch_data_word(destoffset);
1484 srcreg = DECODE_RM_WORD_REGISTER(rh);
1485 DECODE_PRINTF("\n");
1486 TRACE_AND_STEP();
1487 destval = sbb_word(destval, *srcreg);
1488 store_data_word(destoffset, destval);
1489 }
1490 break;
1491 case 2:
1492 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1493 u32 destval;
1494 u32 *srcreg;
1495
1496 destoffset = decode_rm10_address(rl);
1497 DECODE_PRINTF(",");
1498 destval = fetch_data_long(destoffset);
1499 srcreg = DECODE_RM_LONG_REGISTER(rh);
1500 DECODE_PRINTF("\n");
1501 TRACE_AND_STEP();
1502 destval = sbb_long(destval, *srcreg);
1503 store_data_long(destoffset, destval);
1504 } else {
1505 u16 destval;
1506 u16 *srcreg;
1507
1508 destoffset = decode_rm10_address(rl);
1509 DECODE_PRINTF(",");
1510 destval = fetch_data_word(destoffset);
1511 srcreg = DECODE_RM_WORD_REGISTER(rh);
1512 DECODE_PRINTF("\n");
1513 TRACE_AND_STEP();
1514 destval = sbb_word(destval, *srcreg);
1515 store_data_word(destoffset, destval);
1516 }
1517 break;
1518 case 3: /* register to register */
1519 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1520 u32 *destreg,*srcreg;
1521
1522 destreg = DECODE_RM_LONG_REGISTER(rl);
1523 DECODE_PRINTF(",");
1524 srcreg = DECODE_RM_LONG_REGISTER(rh);
1525 DECODE_PRINTF("\n");
1526 TRACE_AND_STEP();
1527 *destreg = sbb_long(*destreg, *srcreg);
1528 } else {
1529 u16 *destreg,*srcreg;
1530
1531 destreg = DECODE_RM_WORD_REGISTER(rl);
1532 DECODE_PRINTF(",");
1533 srcreg = DECODE_RM_WORD_REGISTER(rh);
1534 DECODE_PRINTF("\n");
1535 TRACE_AND_STEP();
1536 *destreg = sbb_word(*destreg, *srcreg);
1537 }
1538 break;
1539 }
1540 DECODE_CLEAR_SEGOVR();
1541 END_OF_INSTR();
1542 }
1543
1544 /****************************************************************************
1545 REMARKS:
1546 Handles opcode 0x1a
1547 ****************************************************************************/
1548 static void x86emuOp_sbb_byte_R_RM(u8 X86EMU_UNUSED(op1))
1549 {
1550 int mod, rl, rh;
1551 u8 *destreg, *srcreg;
1552 uint srcoffset;
1553 u8 srcval;
1554
1555 START_OF_INSTR();
1556 DECODE_PRINTF("SBB\t");
1557 FETCH_DECODE_MODRM(mod, rh, rl);
1558 switch (mod) {
1559 case 0:
1560 destreg = DECODE_RM_BYTE_REGISTER(rh);
1561 DECODE_PRINTF(",");
1562 srcoffset = decode_rm00_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 1:
1569 destreg = DECODE_RM_BYTE_REGISTER(rh);
1570 DECODE_PRINTF(",");
1571 srcoffset = decode_rm01_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 2:
1578 destreg = DECODE_RM_BYTE_REGISTER(rh);
1579 DECODE_PRINTF(",");
1580 srcoffset = decode_rm10_address(rl);
1581 srcval = fetch_data_byte(srcoffset);
1582 DECODE_PRINTF("\n");
1583 TRACE_AND_STEP();
1584 *destreg = sbb_byte(*destreg, srcval);
1585 break;
1586 case 3: /* register to register */
1587 destreg = DECODE_RM_BYTE_REGISTER(rh);
1588 DECODE_PRINTF(",");
1589 srcreg = DECODE_RM_BYTE_REGISTER(rl);
1590 DECODE_PRINTF("\n");
1591 TRACE_AND_STEP();
1592 *destreg = sbb_byte(*destreg, *srcreg);
1593 break;
1594 }
1595 DECODE_CLEAR_SEGOVR();
1596 END_OF_INSTR();
1597 }
1598
1599 /****************************************************************************
1600 REMARKS:
1601 Handles opcode 0x1b
1602 ****************************************************************************/
1603 static void x86emuOp_sbb_word_R_RM(u8 X86EMU_UNUSED(op1))
1604 {
1605 int mod, rl, rh;
1606 uint srcoffset;
1607
1608 START_OF_INSTR();
1609 DECODE_PRINTF("SBB\t");
1610 FETCH_DECODE_MODRM(mod, rh, rl);
1611 switch (mod) {
1612 case 0:
1613 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1614 u32 *destreg;
1615 u32 srcval;
1616
1617 destreg = DECODE_RM_LONG_REGISTER(rh);
1618 DECODE_PRINTF(",");
1619 srcoffset = decode_rm00_address(rl);
1620 srcval = fetch_data_long(srcoffset);
1621 DECODE_PRINTF("\n");
1622 TRACE_AND_STEP();
1623 *destreg = sbb_long(*destreg, srcval);
1624 } else {
1625 u16 *destreg;
1626 u16 srcval;
1627
1628 destreg = DECODE_RM_WORD_REGISTER(rh);
1629 DECODE_PRINTF(",");
1630 srcoffset = decode_rm00_address(rl);
1631 srcval = fetch_data_word(srcoffset);
1632 DECODE_PRINTF("\n");
1633 TRACE_AND_STEP();
1634 *destreg = sbb_word(*destreg, srcval);
1635 }
1636 break;
1637 case 1:
1638 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1639 u32 *destreg;
1640 u32 srcval;
1641
1642 destreg = DECODE_RM_LONG_REGISTER(rh);
1643 DECODE_PRINTF(",");
1644 srcoffset = decode_rm01_address(rl);
1645 srcval = fetch_data_long(srcoffset);
1646 DECODE_PRINTF("\n");
1647 TRACE_AND_STEP();
1648 *destreg = sbb_long(*destreg, srcval);
1649 } else {
1650 u16 *destreg;
1651 u16 srcval;
1652
1653 destreg = DECODE_RM_WORD_REGISTER(rh);
1654 DECODE_PRINTF(",");
1655 srcoffset = decode_rm01_address(rl);
1656 srcval = fetch_data_word(srcoffset);
1657 DECODE_PRINTF("\n");
1658 TRACE_AND_STEP();
1659 *destreg = sbb_word(*destreg, srcval);
1660 }
1661 break;
1662 case 2:
1663 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1664 u32 *destreg;
1665 u32 srcval;
1666
1667 destreg = DECODE_RM_LONG_REGISTER(rh);
1668 DECODE_PRINTF(",");
1669 srcoffset = decode_rm10_address(rl);
1670 srcval = fetch_data_long(srcoffset);
1671 DECODE_PRINTF("\n");
1672 TRACE_AND_STEP();
1673 *destreg = sbb_long(*destreg, srcval);
1674 } else {
1675 u16 *destreg;
1676 u16 srcval;
1677
1678 destreg = DECODE_RM_WORD_REGISTER(rh);
1679 DECODE_PRINTF(",");
1680 srcoffset = decode_rm10_address(rl);
1681 srcval = fetch_data_word(srcoffset);
1682 DECODE_PRINTF("\n");
1683 TRACE_AND_STEP();
1684 *destreg = sbb_word(*destreg, srcval);
1685 }
1686 break;
1687 case 3: /* register to register */
1688 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1689 u32 *destreg,*srcreg;
1690
1691 destreg = DECODE_RM_LONG_REGISTER(rh);
1692 DECODE_PRINTF(",");
1693 srcreg = DECODE_RM_LONG_REGISTER(rl);
1694 DECODE_PRINTF("\n");
1695 TRACE_AND_STEP();
1696 *destreg = sbb_long(*destreg, *srcreg);
1697 } else {
1698 u16 *destreg,*srcreg;
1699
1700 destreg = DECODE_RM_WORD_REGISTER(rh);
1701 DECODE_PRINTF(",");
1702 srcreg = DECODE_RM_WORD_REGISTER(rl);
1703 DECODE_PRINTF("\n");
1704 TRACE_AND_STEP();
1705 *destreg = sbb_word(*destreg, *srcreg);
1706 }
1707 break;
1708 }
1709 DECODE_CLEAR_SEGOVR();
1710 END_OF_INSTR();
1711 }
1712
1713 /****************************************************************************
1714 REMARKS:
1715 Handles opcode 0x1c
1716 ****************************************************************************/
1717 static void x86emuOp_sbb_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
1718 {
1719 u8 srcval;
1720
1721 START_OF_INSTR();
1722 DECODE_PRINTF("SBB\tAL,");
1723 srcval = fetch_byte_imm();
1724 DECODE_PRINTF2("%x\n", srcval);
1725 TRACE_AND_STEP();
1726 M.x86.R_AL = sbb_byte(M.x86.R_AL, srcval);
1727 DECODE_CLEAR_SEGOVR();
1728 END_OF_INSTR();
1729 }
1730
1731 /****************************************************************************
1732 REMARKS:
1733 Handles opcode 0x1d
1734 ****************************************************************************/
1735 static void x86emuOp_sbb_word_AX_IMM(u8 X86EMU_UNUSED(op1))
1736 {
1737 u32 srcval;
1738
1739 START_OF_INSTR();
1740 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1741 DECODE_PRINTF("SBB\tEAX,");
1742 srcval = fetch_long_imm();
1743 } else {
1744 DECODE_PRINTF("SBB\tAX,");
1745 srcval = fetch_word_imm();
1746 }
1747 DECODE_PRINTF2("%x\n", srcval);
1748 TRACE_AND_STEP();
1749 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1750 M.x86.R_EAX = sbb_long(M.x86.R_EAX, srcval);
1751 } else {
1752 M.x86.R_AX = sbb_word(M.x86.R_AX, (u16)srcval);
1753 }
1754 DECODE_CLEAR_SEGOVR();
1755 END_OF_INSTR();
1756 }
1757
1758 /****************************************************************************
1759 REMARKS:
1760 Handles opcode 0x1e
1761 ****************************************************************************/
1762 static void x86emuOp_push_DS(u8 X86EMU_UNUSED(op1))
1763 {
1764 START_OF_INSTR();
1765 DECODE_PRINTF("PUSH\tDS\n");
1766 TRACE_AND_STEP();
1767 push_word(M.x86.R_DS);
1768 DECODE_CLEAR_SEGOVR();
1769 END_OF_INSTR();
1770 }
1771
1772 /****************************************************************************
1773 REMARKS:
1774 Handles opcode 0x1f
1775 ****************************************************************************/
1776 static void x86emuOp_pop_DS(u8 X86EMU_UNUSED(op1))
1777 {
1778 START_OF_INSTR();
1779 DECODE_PRINTF("POP\tDS\n");
1780 TRACE_AND_STEP();
1781 M.x86.R_DS = pop_word();
1782 DECODE_CLEAR_SEGOVR();
1783 END_OF_INSTR();
1784 }
1785
1786 /****************************************************************************
1787 REMARKS:
1788 Handles opcode 0x20
1789 ****************************************************************************/
1790 static void x86emuOp_and_byte_RM_R(u8 X86EMU_UNUSED(op1))
1791 {
1792 int mod, rl, rh;
1793 u8 *destreg, *srcreg;
1794 uint destoffset;
1795 u8 destval;
1796
1797 START_OF_INSTR();
1798 DECODE_PRINTF("AND\t");
1799 FETCH_DECODE_MODRM(mod, rh, rl);
1800
1801 switch (mod) {
1802 case 0:
1803 destoffset = decode_rm00_address(rl);
1804 DECODE_PRINTF(",");
1805 destval = fetch_data_byte(destoffset);
1806 srcreg = DECODE_RM_BYTE_REGISTER(rh);
1807 DECODE_PRINTF("\n");
1808 TRACE_AND_STEP();
1809 destval = and_byte(destval, *srcreg);
1810 store_data_byte(destoffset, destval);
1811 break;
1812
1813 case 1:
1814 destoffset = decode_rm01_address(rl);
1815 DECODE_PRINTF(",");
1816 destval = fetch_data_byte(destoffset);
1817 srcreg = DECODE_RM_BYTE_REGISTER(rh);
1818 DECODE_PRINTF("\n");
1819 TRACE_AND_STEP();
1820 destval = and_byte(destval, *srcreg);
1821 store_data_byte(destoffset, destval);
1822 break;
1823
1824 case 2:
1825 destoffset = decode_rm10_address(rl);
1826 DECODE_PRINTF(",");
1827 destval = fetch_data_byte(destoffset);
1828 srcreg = DECODE_RM_BYTE_REGISTER(rh);
1829 DECODE_PRINTF("\n");
1830 TRACE_AND_STEP();
1831 destval = and_byte(destval, *srcreg);
1832 store_data_byte(destoffset, destval);
1833 break;
1834
1835 case 3: /* register to register */
1836 destreg = DECODE_RM_BYTE_REGISTER(rl);
1837 DECODE_PRINTF(",");
1838 srcreg = DECODE_RM_BYTE_REGISTER(rh);
1839 DECODE_PRINTF("\n");
1840 TRACE_AND_STEP();
1841 *destreg = and_byte(*destreg, *srcreg);
1842 break;
1843 }
1844 DECODE_CLEAR_SEGOVR();
1845 END_OF_INSTR();
1846 }
1847
1848 /****************************************************************************
1849 REMARKS:
1850 Handles opcode 0x21
1851 ****************************************************************************/
1852 static void x86emuOp_and_word_RM_R(u8 X86EMU_UNUSED(op1))
1853 {
1854 int mod, rl, rh;
1855 uint destoffset;
1856
1857 START_OF_INSTR();
1858 DECODE_PRINTF("AND\t");
1859 FETCH_DECODE_MODRM(mod, rh, rl);
1860 switch (mod) {
1861 case 0:
1862 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1863 u32 destval;
1864 u32 *srcreg;
1865
1866 destoffset = decode_rm00_address(rl);
1867 DECODE_PRINTF(",");
1868 destval = fetch_data_long(destoffset);
1869 srcreg = DECODE_RM_LONG_REGISTER(rh);
1870 DECODE_PRINTF("\n");
1871 TRACE_AND_STEP();
1872 destval = and_long(destval, *srcreg);
1873 store_data_long(destoffset, destval);
1874 } else {
1875 u16 destval;
1876 u16 *srcreg;
1877
1878 destoffset = decode_rm00_address(rl);
1879 DECODE_PRINTF(",");
1880 destval = fetch_data_word(destoffset);
1881 srcreg = DECODE_RM_WORD_REGISTER(rh);
1882 DECODE_PRINTF("\n");
1883 TRACE_AND_STEP();
1884 destval = and_word(destval, *srcreg);
1885 store_data_word(destoffset, destval);
1886 }
1887 break;
1888 case 1:
1889 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1890 u32 destval;
1891 u32 *srcreg;
1892
1893 destoffset = decode_rm01_address(rl);
1894 DECODE_PRINTF(",");
1895 destval = fetch_data_long(destoffset);
1896 srcreg = DECODE_RM_LONG_REGISTER(rh);
1897 DECODE_PRINTF("\n");
1898 TRACE_AND_STEP();
1899 destval = and_long(destval, *srcreg);
1900 store_data_long(destoffset, destval);
1901 } else {
1902 u16 destval;
1903 u16 *srcreg;
1904
1905 destoffset = decode_rm01_address(rl);
1906 DECODE_PRINTF(",");
1907 destval = fetch_data_word(destoffset);
1908 srcreg = DECODE_RM_WORD_REGISTER(rh);
1909 DECODE_PRINTF("\n");
1910 TRACE_AND_STEP();
1911 destval = and_word(destval, *srcreg);
1912 store_data_word(destoffset, destval);
1913 }
1914 break;
1915 case 2:
1916 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1917 u32 destval;
1918 u32 *srcreg;
1919
1920 destoffset = decode_rm10_address(rl);
1921 DECODE_PRINTF(",");
1922 destval = fetch_data_long(destoffset);
1923 srcreg = DECODE_RM_LONG_REGISTER(rh);
1924 DECODE_PRINTF("\n");
1925 TRACE_AND_STEP();
1926 destval = and_long(destval, *srcreg);
1927 store_data_long(destoffset, destval);
1928 } else {
1929 u16 destval;
1930 u16 *srcreg;
1931
1932 destoffset = decode_rm10_address(rl);
1933 DECODE_PRINTF(",");
1934 destval = fetch_data_word(destoffset);
1935 srcreg = DECODE_RM_WORD_REGISTER(rh);
1936 DECODE_PRINTF("\n");
1937 TRACE_AND_STEP();
1938 destval = and_word(destval, *srcreg);
1939 store_data_word(destoffset, destval);
1940 }
1941 break;
1942 case 3: /* register to register */
1943 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1944 u32 *destreg,*srcreg;
1945
1946 destreg = DECODE_RM_LONG_REGISTER(rl);
1947 DECODE_PRINTF(",");
1948 srcreg = DECODE_RM_LONG_REGISTER(rh);
1949 DECODE_PRINTF("\n");
1950 TRACE_AND_STEP();
1951 *destreg = and_long(*destreg, *srcreg);
1952 } else {
1953 u16 *destreg,*srcreg;
1954
1955 destreg = DECODE_RM_WORD_REGISTER(rl);
1956 DECODE_PRINTF(",");
1957 srcreg = DECODE_RM_WORD_REGISTER(rh);
1958 DECODE_PRINTF("\n");
1959 TRACE_AND_STEP();
1960 *destreg = and_word(*destreg, *srcreg);
1961 }
1962 break;
1963 }
1964 DECODE_CLEAR_SEGOVR();
1965 END_OF_INSTR();
1966 }
1967
1968 /****************************************************************************
1969 REMARKS:
1970 Handles opcode 0x22
1971 ****************************************************************************/
1972 static void x86emuOp_and_byte_R_RM(u8 X86EMU_UNUSED(op1))
1973 {
1974 int mod, rl, rh;
1975 u8 *destreg, *srcreg;
1976 uint srcoffset;
1977 u8 srcval;
1978
1979 START_OF_INSTR();
1980 DECODE_PRINTF("AND\t");
1981 FETCH_DECODE_MODRM(mod, rh, rl);
1982 switch (mod) {
1983 case 0:
1984 destreg = DECODE_RM_BYTE_REGISTER(rh);
1985 DECODE_PRINTF(",");
1986 srcoffset = decode_rm00_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 1:
1993 destreg = DECODE_RM_BYTE_REGISTER(rh);
1994 DECODE_PRINTF(",");
1995 srcoffset = decode_rm01_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 2:
2002 destreg = DECODE_RM_BYTE_REGISTER(rh);
2003 DECODE_PRINTF(",");
2004 srcoffset = decode_rm10_address(rl);
2005 srcval = fetch_data_byte(srcoffset);
2006 DECODE_PRINTF("\n");
2007 TRACE_AND_STEP();
2008 *destreg = and_byte(*destreg, srcval);
2009 break;
2010 case 3: /* register to register */
2011 destreg = DECODE_RM_BYTE_REGISTER(rh);
2012 DECODE_PRINTF(",");
2013 srcreg = DECODE_RM_BYTE_REGISTER(rl);
2014 DECODE_PRINTF("\n");
2015 TRACE_AND_STEP();
2016 *destreg = and_byte(*destreg, *srcreg);
2017 break;
2018 }
2019 DECODE_CLEAR_SEGOVR();
2020 END_OF_INSTR();
2021 }
2022
2023 /****************************************************************************
2024 REMARKS:
2025 Handles opcode 0x23
2026 ****************************************************************************/
2027 static void x86emuOp_and_word_R_RM(u8 X86EMU_UNUSED(op1))
2028 {
2029 int mod, rl, rh;
2030 uint srcoffset;
2031
2032 START_OF_INSTR();
2033 DECODE_PRINTF("AND\t");
2034 FETCH_DECODE_MODRM(mod, rh, rl);
2035 switch (mod) {
2036 case 0:
2037 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2038 u32 *destreg;
2039 u32 srcval;
2040
2041 destreg = DECODE_RM_LONG_REGISTER(rh);
2042 DECODE_PRINTF(",");
2043 srcoffset = decode_rm00_address(rl);
2044 srcval = fetch_data_long(srcoffset);
2045 DECODE_PRINTF("\n");
2046 TRACE_AND_STEP();
2047 *destreg = and_long(*destreg, srcval);
2048 } else {
2049 u16 *destreg;
2050 u16 srcval;
2051
2052 destreg = DECODE_RM_WORD_REGISTER(rh);
2053 DECODE_PRINTF(",");
2054 srcoffset = decode_rm00_address(rl);
2055 srcval = fetch_data_word(srcoffset);
2056 DECODE_PRINTF("\n");
2057 TRACE_AND_STEP();
2058 *destreg = and_word(*destreg, srcval);
2059 }
2060 break;
2061 case 1:
2062 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2063 u32 *destreg;
2064 u32 srcval;
2065
2066 destreg = DECODE_RM_LONG_REGISTER(rh);
2067 DECODE_PRINTF(",");
2068 srcoffset = decode_rm01_address(rl);
2069 srcval = fetch_data_long(srcoffset);
2070 DECODE_PRINTF("\n");
2071 TRACE_AND_STEP();
2072 *destreg = and_long(*destreg, srcval);
2073 break;
2074 } else {
2075 u16 *destreg;
2076 u16 srcval;
2077
2078 destreg = DECODE_RM_WORD_REGISTER(rh);
2079 DECODE_PRINTF(",");
2080 srcoffset = decode_rm01_address(rl);
2081 srcval = fetch_data_word(srcoffset);
2082 DECODE_PRINTF("\n");
2083 TRACE_AND_STEP();
2084 *destreg = and_word(*destreg, srcval);
2085 break;
2086 }
2087 case 2:
2088 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2089 u32 *destreg;
2090 u32 srcval;
2091
2092 destreg = DECODE_RM_LONG_REGISTER(rh);
2093 DECODE_PRINTF(",");
2094 srcoffset = decode_rm10_address(rl);
2095 srcval = fetch_data_long(srcoffset);
2096 DECODE_PRINTF("\n");
2097 TRACE_AND_STEP();
2098 *destreg = and_long(*destreg, srcval);
2099 } else {
2100 u16 *destreg;
2101 u16 srcval;
2102
2103 destreg = DECODE_RM_WORD_REGISTER(rh);
2104 DECODE_PRINTF(",");
2105 srcoffset = decode_rm10_address(rl);
2106 srcval = fetch_data_word(srcoffset);
2107 DECODE_PRINTF("\n");
2108 TRACE_AND_STEP();
2109 *destreg = and_word(*destreg, srcval);
2110 }
2111 break;
2112 case 3: /* register to register */
2113 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2114 u32 *destreg,*srcreg;
2115
2116 destreg = DECODE_RM_LONG_REGISTER(rh);
2117 DECODE_PRINTF(",");
2118 srcreg = DECODE_RM_LONG_REGISTER(rl);
2119 DECODE_PRINTF("\n");
2120 TRACE_AND_STEP();
2121 *destreg = and_long(*destreg, *srcreg);
2122 } else {
2123 u16 *destreg,*srcreg;
2124
2125 destreg = DECODE_RM_WORD_REGISTER(rh);
2126 DECODE_PRINTF(",");
2127 srcreg = DECODE_RM_WORD_REGISTER(rl);
2128 DECODE_PRINTF("\n");
2129 TRACE_AND_STEP();
2130 *destreg = and_word(*destreg, *srcreg);
2131 }
2132 break;
2133 }
2134 DECODE_CLEAR_SEGOVR();
2135 END_OF_INSTR();
2136 }
2137
2138 /****************************************************************************
2139 REMARKS:
2140 Handles opcode 0x24
2141 ****************************************************************************/
2142 static void x86emuOp_and_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
2143 {
2144 u8 srcval;
2145
2146 START_OF_INSTR();
2147 DECODE_PRINTF("AND\tAL,");
2148 srcval = fetch_byte_imm();
2149 DECODE_PRINTF2("%x\n", srcval);
2150 TRACE_AND_STEP();
2151 M.x86.R_AL = and_byte(M.x86.R_AL, srcval);
2152 DECODE_CLEAR_SEGOVR();
2153 END_OF_INSTR();
2154 }
2155
2156 /****************************************************************************
2157 REMARKS:
2158 Handles opcode 0x25
2159 ****************************************************************************/
2160 static void x86emuOp_and_word_AX_IMM(u8 X86EMU_UNUSED(op1))
2161 {
2162 u32 srcval;
2163
2164 START_OF_INSTR();
2165 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2166 DECODE_PRINTF("AND\tEAX,");
2167 srcval = fetch_long_imm();
2168 } else {
2169 DECODE_PRINTF("AND\tAX,");
2170 srcval = fetch_word_imm();
2171 }
2172 DECODE_PRINTF2("%x\n", srcval);
2173 TRACE_AND_STEP();
2174 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2175 M.x86.R_EAX = and_long(M.x86.R_EAX, srcval);
2176 } else {
2177 M.x86.R_AX = and_word(M.x86.R_AX, (u16)srcval);
2178 }
2179 DECODE_CLEAR_SEGOVR();
2180 END_OF_INSTR();
2181 }
2182
2183 /****************************************************************************
2184 REMARKS:
2185 Handles opcode 0x26
2186 ****************************************************************************/
2187 static void x86emuOp_segovr_ES(u8 X86EMU_UNUSED(op1))
2188 {
2189 START_OF_INSTR();
2190 DECODE_PRINTF("ES:\n");
2191 TRACE_AND_STEP();
2192 M.x86.mode |= SYSMODE_SEGOVR_ES;
2193 /*
2194 * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
2195 * opcode subroutines we do not want to do this.
2196 */
2197 END_OF_INSTR();
2198 }
2199
2200 /****************************************************************************
2201 REMARKS:
2202 Handles opcode 0x27
2203 ****************************************************************************/
2204 static void x86emuOp_daa(u8 X86EMU_UNUSED(op1))
2205 {
2206 START_OF_INSTR();
2207 DECODE_PRINTF("DAA\n");
2208 TRACE_AND_STEP();
2209 M.x86.R_AL = daa_byte(M.x86.R_AL);
2210 DECODE_CLEAR_SEGOVR();
2211 END_OF_INSTR();
2212 }
2213
2214 /****************************************************************************
2215 REMARKS:
2216 Handles opcode 0x28
2217 ****************************************************************************/
2218 static void x86emuOp_sub_byte_RM_R(u8 X86EMU_UNUSED(op1))
2219 {
2220 int mod, rl, rh;
2221 u8 *destreg, *srcreg;
2222 uint destoffset;
2223 u8 destval;
2224
2225 START_OF_INSTR();
2226 DECODE_PRINTF("SUB\t");
2227 FETCH_DECODE_MODRM(mod, rh, rl);
2228 switch (mod) {
2229 case 0:
2230 destoffset = decode_rm00_address(rl);
2231 DECODE_PRINTF(",");
2232 destval = fetch_data_byte(destoffset);
2233 srcreg = DECODE_RM_BYTE_REGISTER(rh);
2234 DECODE_PRINTF("\n");
2235 TRACE_AND_STEP();
2236 destval = sub_byte(destval, *srcreg);
2237 store_data_byte(destoffset, destval);
2238 break;
2239 case 1:
2240 destoffset = decode_rm01_address(rl);
2241 DECODE_PRINTF(",");
2242 destval = fetch_data_byte(destoffset);
2243 srcreg = DECODE_RM_BYTE_REGISTER(rh);
2244 DECODE_PRINTF("\n");
2245 TRACE_AND_STEP();
2246 destval = sub_byte(destval, *srcreg);
2247 store_data_byte(destoffset, destval);
2248 break;
2249 case 2:
2250 destoffset = decode_rm10_address(rl);
2251 DECODE_PRINTF(",");
2252 destval = fetch_data_byte(destoffset);
2253 srcreg = DECODE_RM_BYTE_REGISTER(rh);
2254 DECODE_PRINTF("\n");
2255 TRACE_AND_STEP();
2256 destval = sub_byte(destval, *srcreg);
2257 store_data_byte(destoffset, destval);
2258 break;
2259 case 3: /* register to register */
2260 destreg = DECODE_RM_BYTE_REGISTER(rl);
2261 DECODE_PRINTF(",");
2262 srcreg = DECODE_RM_BYTE_REGISTER(rh);
2263 DECODE_PRINTF("\n");
2264 TRACE_AND_STEP();
2265 *destreg = sub_byte(*destreg, *srcreg);
2266 break;
2267 }
2268 DECODE_CLEAR_SEGOVR();
2269 END_OF_INSTR();
2270 }
2271
2272 /****************************************************************************
2273 REMARKS:
2274 Handles opcode 0x29
2275 ****************************************************************************/
2276 static void x86emuOp_sub_word_RM_R(u8 X86EMU_UNUSED(op1))
2277 {
2278 int mod, rl, rh;
2279 uint destoffset;
2280
2281 START_OF_INSTR();
2282 DECODE_PRINTF("SUB\t");
2283 FETCH_DECODE_MODRM(mod, rh, rl);
2284 switch (mod) {
2285 case 0:
2286 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2287 u32 destval;
2288 u32 *srcreg;
2289
2290 destoffset = decode_rm00_address(rl);
2291 DECODE_PRINTF(",");
2292 destval = fetch_data_long(destoffset);
2293 srcreg = DECODE_RM_LONG_REGISTER(rh);
2294 DECODE_PRINTF("\n");
2295 TRACE_AND_STEP();
2296 destval = sub_long(destval, *srcreg);
2297 store_data_long(destoffset, destval);
2298 } else {
2299 u16 destval;
2300 u16 *srcreg;
2301
2302 destoffset = decode_rm00_address(rl);
2303 DECODE_PRINTF(",");
2304 destval = fetch_data_word(destoffset);
2305 srcreg = DECODE_RM_WORD_REGISTER(rh);
2306 DECODE_PRINTF("\n");
2307 TRACE_AND_STEP();
2308 destval = sub_word(destval, *srcreg);
2309 store_data_word(destoffset, destval);
2310 }
2311 break;
2312 case 1:
2313 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2314 u32 destval;
2315 u32 *srcreg;
2316
2317 destoffset = decode_rm01_address(rl);
2318 DECODE_PRINTF(",");
2319 destval = fetch_data_long(destoffset);
2320 srcreg = DECODE_RM_LONG_REGISTER(rh);
2321 DECODE_PRINTF("\n");
2322 TRACE_AND_STEP();
2323 destval = sub_long(destval, *srcreg);
2324 store_data_long(destoffset, destval);
2325 } else {
2326 u16 destval;
2327 u16 *srcreg;
2328
2329 destoffset = decode_rm01_address(rl);
2330 DECODE_PRINTF(",");
2331 destval = fetch_data_word(destoffset);
2332 srcreg = DECODE_RM_WORD_REGISTER(rh);
2333 DECODE_PRINTF("\n");
2334 TRACE_AND_STEP();
2335 destval = sub_word(destval, *srcreg);
2336 store_data_word(destoffset, destval);
2337 }
2338 break;
2339 case 2:
2340 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2341 u32 destval;
2342 u32 *srcreg;
2343
2344 destoffset = decode_rm10_address(rl);
2345 DECODE_PRINTF(",");
2346 destval = fetch_data_long(destoffset);
2347 srcreg = DECODE_RM_LONG_REGISTER(rh);
2348 DECODE_PRINTF("\n");
2349 TRACE_AND_STEP();
2350 destval = sub_long(destval, *srcreg);
2351 store_data_long(destoffset, destval);
2352 } else {
2353 u16 destval;
2354 u16 *srcreg;
2355
2356 destoffset = decode_rm10_address(rl);
2357 DECODE_PRINTF(",");
2358 destval = fetch_data_word(destoffset);
2359 srcreg = DECODE_RM_WORD_REGISTER(rh);
2360 DECODE_PRINTF("\n");
2361 TRACE_AND_STEP();
2362 destval = sub_word(destval, *srcreg);
2363 store_data_word(destoffset, destval);
2364 }
2365 break;
2366 case 3: /* register to register */
2367 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2368 u32 *destreg,*srcreg;
2369
2370 destreg = DECODE_RM_LONG_REGISTER(rl);
2371 DECODE_PRINTF(",");
2372 srcreg = DECODE_RM_LONG_REGISTER(rh);
2373 DECODE_PRINTF("\n");
2374 TRACE_AND_STEP();
2375 *destreg = sub_long(*destreg, *srcreg);
2376 } else {
2377 u16 *destreg,*srcreg;
2378
2379 destreg = DECODE_RM_WORD_REGISTER(rl);
2380 DECODE_PRINTF(",");
2381 srcreg = DECODE_RM_WORD_REGISTER(rh);
2382 DECODE_PRINTF("\n");
2383 TRACE_AND_STEP();
2384 *destreg = sub_word(*destreg, *srcreg);
2385 }
2386 break;
2387 }
2388 DECODE_CLEAR_SEGOVR();
2389 END_OF_INSTR();
2390 }
2391
2392 /****************************************************************************
2393 REMARKS:
2394 Handles opcode 0x2a
2395 ****************************************************************************/
2396 static void x86emuOp_sub_byte_R_RM(u8 X86EMU_UNUSED(op1))
2397 {
2398 int mod, rl, rh;
2399 u8 *destreg, *srcreg;
2400 uint srcoffset;
2401 u8 srcval;
2402
2403 START_OF_INSTR();
2404 DECODE_PRINTF("SUB\t");
2405 FETCH_DECODE_MODRM(mod, rh, rl);
2406 switch (mod) {
2407 case 0:
2408 destreg = DECODE_RM_BYTE_REGISTER(rh);
2409 DECODE_PRINTF(",");
2410 srcoffset = decode_rm00_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 1:
2417 destreg = DECODE_RM_BYTE_REGISTER(rh);
2418 DECODE_PRINTF(",");
2419 srcoffset = decode_rm01_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 2:
2426 destreg = DECODE_RM_BYTE_REGISTER(rh);
2427 DECODE_PRINTF(",");
2428 srcoffset = decode_rm10_address(rl);
2429 srcval = fetch_data_byte(srcoffset);
2430 DECODE_PRINTF("\n");
2431 TRACE_AND_STEP();
2432 *destreg = sub_byte(*destreg, srcval);
2433 break;
2434 case 3: /* register to register */
2435 destreg = DECODE_RM_BYTE_REGISTER(rh);
2436 DECODE_PRINTF(",");
2437 srcreg = DECODE_RM_BYTE_REGISTER(rl);
2438 DECODE_PRINTF("\n");
2439 TRACE_AND_STEP();
2440 *destreg = sub_byte(*destreg, *srcreg);
2441 break;
2442 }
2443 DECODE_CLEAR_SEGOVR();
2444 END_OF_INSTR();
2445 }
2446
2447 /****************************************************************************
2448 REMARKS:
2449 Handles opcode 0x2b
2450 ****************************************************************************/
2451 static void x86emuOp_sub_word_R_RM(u8 X86EMU_UNUSED(op1))
2452 {
2453 int mod, rl, rh;
2454 uint srcoffset;
2455
2456 START_OF_INSTR();
2457 DECODE_PRINTF("SUB\t");
2458 FETCH_DECODE_MODRM(mod, rh, rl);
2459 switch (mod) {
2460 case 0:
2461 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2462 u32 *destreg;
2463 u32 srcval;
2464
2465 destreg = DECODE_RM_LONG_REGISTER(rh);
2466 DECODE_PRINTF(",");
2467 srcoffset = decode_rm00_address(rl);
2468 srcval = fetch_data_long(srcoffset);
2469 DECODE_PRINTF("\n");
2470 TRACE_AND_STEP();
2471 *destreg = sub_long(*destreg, srcval);
2472 } else {
2473 u16 *destreg;
2474 u16 srcval;
2475
2476 destreg = DECODE_RM_WORD_REGISTER(rh);
2477 DECODE_PRINTF(",");
2478 srcoffset = decode_rm00_address(rl);
2479 srcval = fetch_data_word(srcoffset);
2480 DECODE_PRINTF("\n");
2481 TRACE_AND_STEP();
2482 *destreg = sub_word(*destreg, srcval);
2483 }
2484 break;
2485 case 1:
2486 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2487 u32 *destreg;
2488 u32 srcval;
2489
2490 destreg = DECODE_RM_LONG_REGISTER(rh);
2491 DECODE_PRINTF(",");
2492 srcoffset = decode_rm01_address(rl);
2493 srcval = fetch_data_long(srcoffset);
2494 DECODE_PRINTF("\n");
2495 TRACE_AND_STEP();
2496 *destreg = sub_long(*destreg, srcval);
2497 } else {
2498 u16 *destreg;
2499 u16 srcval;
2500
2501 destreg = DECODE_RM_WORD_REGISTER(rh);
2502 DECODE_PRINTF(",");
2503 srcoffset = decode_rm01_address(rl);
2504 srcval = fetch_data_word(srcoffset);
2505 DECODE_PRINTF("\n");
2506 TRACE_AND_STEP();
2507 *destreg = sub_word(*destreg, srcval);
2508 }
2509 break;
2510 case 2:
2511 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2512 u32 *destreg;
2513 u32 srcval;
2514
2515 destreg = DECODE_RM_LONG_REGISTER(rh);
2516 DECODE_PRINTF(",");
2517 srcoffset = decode_rm10_address(rl);
2518 srcval = fetch_data_long(srcoffset);
2519 DECODE_PRINTF("\n");
2520 TRACE_AND_STEP();
2521 *destreg = sub_long(*destreg, srcval);
2522 } else {
2523 u16 *destreg;
2524 u16 srcval;
2525
2526 destreg = DECODE_RM_WORD_REGISTER(rh);
2527 DECODE_PRINTF(",");
2528 srcoffset = decode_rm10_address(rl);
2529 srcval = fetch_data_word(srcoffset);
2530 DECODE_PRINTF("\n");
2531 TRACE_AND_STEP();
2532 *destreg = sub_word(*destreg, srcval);
2533 }
2534 break;
2535 case 3: /* register to register */
2536 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2537 u32 *destreg,*srcreg;
2538
2539 destreg = DECODE_RM_LONG_REGISTER(rh);
2540 DECODE_PRINTF(",");
2541 srcreg = DECODE_RM_LONG_REGISTER(rl);
2542 DECODE_PRINTF("\n");
2543 TRACE_AND_STEP();
2544 *destreg = sub_long(*destreg, *srcreg);
2545 } else {
2546 u16 *destreg,*srcreg;
2547
2548 destreg = DECODE_RM_WORD_REGISTER(rh);
2549 DECODE_PRINTF(",");
2550 srcreg = DECODE_RM_WORD_REGISTER(rl);
2551 DECODE_PRINTF("\n");
2552 TRACE_AND_STEP();
2553 *destreg = sub_word(*destreg, *srcreg);
2554 }
2555 break;
2556 }
2557 DECODE_CLEAR_SEGOVR();
2558 END_OF_INSTR();
2559 }
2560
2561 /****************************************************************************
2562 REMARKS:
2563 Handles opcode 0x2c
2564 ****************************************************************************/
2565 static void x86emuOp_sub_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
2566 {
2567 u8 srcval;
2568
2569 START_OF_INSTR();
2570 DECODE_PRINTF("SUB\tAL,");
2571 srcval = fetch_byte_imm();
2572 DECODE_PRINTF2("%x\n", srcval);
2573 TRACE_AND_STEP();
2574 M.x86.R_AL = sub_byte(M.x86.R_AL, srcval);
2575 DECODE_CLEAR_SEGOVR();
2576 END_OF_INSTR();
2577 }
2578
2579 /****************************************************************************
2580 REMARKS:
2581 Handles opcode 0x2d
2582 ****************************************************************************/
2583 static void x86emuOp_sub_word_AX_IMM(u8 X86EMU_UNUSED(op1))
2584 {
2585 u32 srcval;
2586
2587 START_OF_INSTR();
2588 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2589 DECODE_PRINTF("SUB\tEAX,");
2590 srcval = fetch_long_imm();
2591 } else {
2592 DECODE_PRINTF("SUB\tAX,");
2593 srcval = fetch_word_imm();
2594 }
2595 DECODE_PRINTF2("%x\n", srcval);
2596 TRACE_AND_STEP();
2597 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2598 M.x86.R_EAX = sub_long(M.x86.R_EAX, srcval);
2599 } else {
2600 M.x86.R_AX = sub_word(M.x86.R_AX, (u16)srcval);
2601 }
2602 DECODE_CLEAR_SEGOVR();
2603 END_OF_INSTR();
2604 }
2605
2606 /****************************************************************************
2607 REMARKS:
2608 Handles opcode 0x2e
2609 ****************************************************************************/
2610 static void x86emuOp_segovr_CS(u8 X86EMU_UNUSED(op1))
2611 {
2612 START_OF_INSTR();
2613 DECODE_PRINTF("CS:\n");
2614 TRACE_AND_STEP();
2615 M.x86.mode |= SYSMODE_SEGOVR_CS;
2616 /* note no DECODE_CLEAR_SEGOVR here. */
2617 END_OF_INSTR();
2618 }
2619
2620 /****************************************************************************
2621 REMARKS:
2622 Handles opcode 0x2f
2623 ****************************************************************************/
2624 static void x86emuOp_das(u8 X86EMU_UNUSED(op1))
2625 {
2626 START_OF_INSTR();
2627 DECODE_PRINTF("DAS\n");
2628 TRACE_AND_STEP();
2629 M.x86.R_AL = das_byte(M.x86.R_AL);
2630 DECODE_CLEAR_SEGOVR();
2631 END_OF_INSTR();
2632 }
2633
2634 /****************************************************************************
2635 REMARKS:
2636 Handles opcode 0x30
2637 ****************************************************************************/
2638 static void x86emuOp_xor_byte_RM_R(u8 X86EMU_UNUSED(op1))
2639 {
2640 int mod, rl, rh;
2641 u8 *destreg, *srcreg;
2642 uint destoffset;
2643 u8 destval;
2644
2645 START_OF_INSTR();
2646 DECODE_PRINTF("XOR\t");
2647 FETCH_DECODE_MODRM(mod, rh, rl);
2648 switch (mod) {
2649 case 0:
2650 destoffset = decode_rm00_address(rl);
2651 DECODE_PRINTF(",");
2652 destval = fetch_data_byte(destoffset);
2653 srcreg = DECODE_RM_BYTE_REGISTER(rh);
2654 DECODE_PRINTF("\n");
2655 TRACE_AND_STEP();
2656 destval = xor_byte(destval, *srcreg);
2657 store_data_byte(destoffset, destval);
2658 break;
2659 case 1:
2660 destoffset = decode_rm01_address(rl);
2661 DECODE_PRINTF(",");
2662 destval = fetch_data_byte(destoffset);
2663 srcreg = DECODE_RM_BYTE_REGISTER(rh);
2664 DECODE_PRINTF("\n");
2665 TRACE_AND_STEP();
2666 destval = xor_byte(destval, *srcreg);
2667 store_data_byte(destoffset, destval);
2668 break;
2669 case 2:
2670 destoffset = decode_rm10_address(rl);
2671 DECODE_PRINTF(",");
2672 destval = fetch_data_byte(destoffset);
2673 srcreg = DECODE_RM_BYTE_REGISTER(rh);
2674 DECODE_PRINTF("\n");
2675 TRACE_AND_STEP();
2676 destval = xor_byte(destval, *srcreg);
2677 store_data_byte(destoffset, destval);
2678 break;
2679 case 3: /* register to register */
2680 destreg = DECODE_RM_BYTE_REGISTER(rl);
2681 DECODE_PRINTF(",");
2682 srcreg = DECODE_RM_BYTE_REGISTER(rh);
2683 DECODE_PRINTF("\n");
2684 TRACE_AND_STEP();
2685 *destreg = xor_byte(*destreg, *srcreg);
2686 break;
2687 }
2688 DECODE_CLEAR_SEGOVR();
2689 END_OF_INSTR();
2690 }
2691
2692 /****************************************************************************
2693 REMARKS:
2694 Handles opcode 0x31
2695 ****************************************************************************/
2696 static void x86emuOp_xor_word_RM_R(u8 X86EMU_UNUSED(op1))
2697 {
2698 int mod, rl, rh;
2699 uint destoffset;
2700
2701 START_OF_INSTR();
2702 DECODE_PRINTF("XOR\t");
2703 FETCH_DECODE_MODRM(mod, rh, rl);
2704 switch (mod) {
2705 case 0:
2706 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2707 u32 destval;
2708 u32 *srcreg;
2709
2710 destoffset = decode_rm00_address(rl);
2711 DECODE_PRINTF(",");
2712 destval = fetch_data_long(destoffset);
2713 srcreg = DECODE_RM_LONG_REGISTER(rh);
2714 DECODE_PRINTF("\n");
2715 TRACE_AND_STEP();
2716 destval = xor_long(destval, *srcreg);
2717 store_data_long(destoffset, destval);
2718 } else {
2719 u16 destval;
2720 u16 *srcreg;
2721
2722 destoffset = decode_rm00_address(rl);
2723 DECODE_PRINTF(",");
2724 destval = fetch_data_word(destoffset);
2725 srcreg = DECODE_RM_WORD_REGISTER(rh);
2726 DECODE_PRINTF("\n");
2727 TRACE_AND_STEP();
2728 destval = xor_word(destval, *srcreg);
2729 store_data_word(destoffset, destval);
2730 }
2731 break;
2732 case 1:
2733 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2734 u32 destval;
2735 u32 *srcreg;
2736
2737 destoffset = decode_rm01_address(rl);
2738 DECODE_PRINTF(",");
2739 destval = fetch_data_long(destoffset);
2740 srcreg = DECODE_RM_LONG_REGISTER(rh);
2741 DECODE_PRINTF("\n");
2742 TRACE_AND_STEP();
2743 destval = xor_long(destval, *srcreg);
2744 store_data_long(destoffset, destval);
2745 } else {
2746 u16 destval;
2747 u16 *srcreg;
2748
2749 destoffset = decode_rm01_address(rl);
2750 DECODE_PRINTF(",");
2751 destval = fetch_data_word(destoffset);
2752 srcreg = DECODE_RM_WORD_REGISTER(rh);
2753 DECODE_PRINTF("\n");
2754 TRACE_AND_STEP();
2755 destval = xor_word(destval, *srcreg);
2756 store_data_word(destoffset, destval);
2757 }
2758 break;
2759 case 2:
2760 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2761 u32 destval;
2762 u32 *srcreg;
2763
2764 destoffset = decode_rm10_address(rl);
2765 DECODE_PRINTF(",");
2766 destval = fetch_data_long(destoffset);
2767 srcreg = DECODE_RM_LONG_REGISTER(rh);
2768 DECODE_PRINTF("\n");
2769 TRACE_AND_STEP();
2770 destval = xor_long(destval, *srcreg);
2771 store_data_long(destoffset, destval);
2772 } else {
2773 u16 destval;
2774 u16 *srcreg;
2775
2776 destoffset = decode_rm10_address(rl);
2777 DECODE_PRINTF(",");
2778 destval = fetch_data_word(destoffset);
2779 srcreg = DECODE_RM_WORD_REGISTER(rh);
2780 DECODE_PRINTF("\n");
2781 TRACE_AND_STEP();
2782 destval = xor_word(destval, *srcreg);
2783 store_data_word(destoffset, destval);
2784 }
2785 break;
2786 case 3: /* register to register */
2787 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2788 u32 *destreg,*srcreg;
2789
2790 destreg = DECODE_RM_LONG_REGISTER(rl);
2791 DECODE_PRINTF(",");
2792 srcreg = DECODE_RM_LONG_REGISTER(rh);
2793 DECODE_PRINTF("\n");
2794 TRACE_AND_STEP();
2795 *destreg = xor_long(*destreg, *srcreg);
2796 } else {
2797 u16 *destreg,*srcreg;
2798
2799 destreg = DECODE_RM_WORD_REGISTER(rl);
2800 DECODE_PRINTF(",");
2801 srcreg = DECODE_RM_WORD_REGISTER(rh);
2802 DECODE_PRINTF("\n");
2803 TRACE_AND_STEP();
2804 *destreg = xor_word(*destreg, *srcreg);
2805 }
2806 break;
2807 }
2808 DECODE_CLEAR_SEGOVR();
2809 END_OF_INSTR();
2810 }
2811
2812 /****************************************************************************
2813 REMARKS:
2814 Handles opcode 0x32
2815 ****************************************************************************/
2816 static void x86emuOp_xor_byte_R_RM(u8 X86EMU_UNUSED(op1))
2817 {
2818 int mod, rl, rh;
2819 u8 *destreg, *srcreg;
2820 uint srcoffset;
2821 u8 srcval;
2822
2823 START_OF_INSTR();
2824 DECODE_PRINTF("XOR\t");
2825 FETCH_DECODE_MODRM(mod, rh, rl);
2826 switch (mod) {
2827 case 0:
2828 destreg = DECODE_RM_BYTE_REGISTER(rh);
2829 DECODE_PRINTF(",");
2830 srcoffset = decode_rm00_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 1:
2837 destreg = DECODE_RM_BYTE_REGISTER(rh);
2838 DECODE_PRINTF(",");
2839 srcoffset = decode_rm01_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 2:
2846 destreg = DECODE_RM_BYTE_REGISTER(rh);
2847 DECODE_PRINTF(",");
2848 srcoffset = decode_rm10_address(rl);
2849 srcval = fetch_data_byte(srcoffset);
2850 DECODE_PRINTF("\n");
2851 TRACE_AND_STEP();
2852 *destreg = xor_byte(*destreg, srcval);
2853 break;
2854 case 3: /* register to register */
2855 destreg = DECODE_RM_BYTE_REGISTER(rh);
2856 DECODE_PRINTF(",");
2857 srcreg = DECODE_RM_BYTE_REGISTER(rl);
2858 DECODE_PRINTF("\n");
2859 TRACE_AND_STEP();
2860 *destreg = xor_byte(*destreg, *srcreg);
2861 break;
2862 }
2863 DECODE_CLEAR_SEGOVR();
2864 END_OF_INSTR();
2865 }
2866
2867 /****************************************************************************
2868 REMARKS:
2869 Handles opcode 0x33
2870 ****************************************************************************/
2871 static void x86emuOp_xor_word_R_RM(u8 X86EMU_UNUSED(op1))
2872 {
2873 int mod, rl, rh;
2874 uint srcoffset;
2875
2876 START_OF_INSTR();
2877 DECODE_PRINTF("XOR\t");
2878 FETCH_DECODE_MODRM(mod, rh, rl);
2879 switch (mod) {
2880 case 0:
2881 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2882 u32 *destreg;
2883 u32 srcval;
2884
2885 destreg = DECODE_RM_LONG_REGISTER(rh);
2886 DECODE_PRINTF(",");
2887 srcoffset = decode_rm00_address(rl);
2888 srcval = fetch_data_long(srcoffset);
2889 DECODE_PRINTF("\n");
2890 TRACE_AND_STEP();
2891 *destreg = xor_long(*destreg, srcval);
2892 } else {
2893 u16 *destreg;
2894 u16 srcval;
2895
2896 destreg = DECODE_RM_WORD_REGISTER(rh);
2897 DECODE_PRINTF(",");
2898 srcoffset = decode_rm00_address(rl);
2899 srcval = fetch_data_word(srcoffset);
2900 DECODE_PRINTF("\n");
2901 TRACE_AND_STEP();
2902 *destreg = xor_word(*destreg, srcval);
2903 }
2904 break;
2905 case 1:
2906 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2907 u32 *destreg;
2908 u32 srcval;
2909
2910 destreg = DECODE_RM_LONG_REGISTER(rh);
2911 DECODE_PRINTF(",");
2912 srcoffset = decode_rm01_address(rl);
2913 srcval = fetch_data_long(srcoffset);
2914 DECODE_PRINTF("\n");
2915 TRACE_AND_STEP();
2916 *destreg = xor_long(*destreg, srcval);
2917 } else {
2918 u16 *destreg;
2919 u16 srcval;
2920
2921 destreg = DECODE_RM_WORD_REGISTER(rh);
2922 DECODE_PRINTF(",");
2923 srcoffset = decode_rm01_address(rl);
2924 srcval = fetch_data_word(srcoffset);
2925 DECODE_PRINTF("\n");
2926 TRACE_AND_STEP();
2927 *destreg = xor_word(*destreg, srcval);
2928 }
2929 break;
2930 case 2:
2931 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2932 u32 *destreg;
2933 u32 srcval;
2934
2935 destreg = DECODE_RM_LONG_REGISTER(rh);
2936 DECODE_PRINTF(",");
2937 srcoffset = decode_rm10_address(rl);
2938 srcval = fetch_data_long(srcoffset);
2939 DECODE_PRINTF("\n");
2940 TRACE_AND_STEP();
2941 *destreg = xor_long(*destreg, srcval);
2942 } else {
2943 u16 *destreg;
2944 u16 srcval;
2945
2946 destreg = DECODE_RM_WORD_REGISTER(rh);
2947 DECODE_PRINTF(",");
2948 srcoffset = decode_rm10_address(rl);
2949 srcval = fetch_data_word(srcoffset);
2950 DECODE_PRINTF("\n");
2951 TRACE_AND_STEP();
2952 *destreg = xor_word(*destreg, srcval);
2953 }
2954 break;
2955 case 3: /* register to register */
2956 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2957 u32 *destreg,*srcreg;
2958
2959 destreg = DECODE_RM_LONG_REGISTER(rh);
2960 DECODE_PRINTF(",");
2961 srcreg = DECODE_RM_LONG_REGISTER(rl);
2962 DECODE_PRINTF("\n");
2963 TRACE_AND_STEP();
2964 *destreg = xor_long(*destreg, *srcreg);
2965 } else {
2966 u16 *destreg,*srcreg;
2967
2968 destreg = DECODE_RM_WORD_REGISTER(rh);
2969 DECODE_PRINTF(",");
2970 srcreg = DECODE_RM_WORD_REGISTER(rl);
2971 DECODE_PRINTF("\n");
2972 TRACE_AND_STEP();
2973 *destreg = xor_word(*destreg, *srcreg);
2974 }
2975 break;
2976 }
2977 DECODE_CLEAR_SEGOVR();
2978 END_OF_INSTR();
2979 }
2980
2981 /****************************************************************************
2982 REMARKS:
2983 Handles opcode 0x34
2984 ****************************************************************************/
2985 static void x86emuOp_xor_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
2986 {
2987 u8 srcval;
2988
2989 START_OF_INSTR();
2990 DECODE_PRINTF("XOR\tAL,");
2991 srcval = fetch_byte_imm();
2992 DECODE_PRINTF2("%x\n", srcval);
2993 TRACE_AND_STEP();
2994 M.x86.R_AL = xor_byte(M.x86.R_AL, srcval);
2995 DECODE_CLEAR_SEGOVR();
2996 END_OF_INSTR();
2997 }
2998
2999 /****************************************************************************
3000 REMARKS:
3001 Handles opcode 0x35
3002 ****************************************************************************/
3003 static void x86emuOp_xor_word_AX_IMM(u8 X86EMU_UNUSED(op1))
3004 {
3005 u32 srcval;
3006
3007 START_OF_INSTR();
3008 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3009 DECODE_PRINTF("XOR\tEAX,");
3010 srcval = fetch_long_imm();
3011 } else {
3012 DECODE_PRINTF("XOR\tAX,");
3013 srcval = fetch_word_imm();
3014 }
3015 DECODE_PRINTF2("%x\n", srcval);
3016 TRACE_AND_STEP();
3017 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3018 M.x86.R_EAX = xor_long(M.x86.R_EAX, srcval);
3019 } else {
3020 M.x86.R_AX = xor_word(M.x86.R_AX, (u16)srcval);
3021 }
3022 DECODE_CLEAR_SEGOVR();
3023 END_OF_INSTR();
3024 }
3025
3026 /****************************************************************************
3027 REMARKS:
3028 Handles opcode 0x36
3029 ****************************************************************************/
3030 static void x86emuOp_segovr_SS(u8 X86EMU_UNUSED(op1))
3031 {
3032 START_OF_INSTR();
3033 DECODE_PRINTF("SS:\n");
3034 TRACE_AND_STEP();
3035 M.x86.mode |= SYSMODE_SEGOVR_SS;
3036 /* no DECODE_CLEAR_SEGOVR ! */
3037 END_OF_INSTR();
3038 }
3039
3040 /****************************************************************************
3041 REMARKS:
3042 Handles opcode 0x37
3043 ****************************************************************************/
3044 static void x86emuOp_aaa(u8 X86EMU_UNUSED(op1))
3045 {
3046 START_OF_INSTR();
3047 DECODE_PRINTF("AAA\n");
3048 TRACE_AND_STEP();
3049 M.x86.R_AX = aaa_word(M.x86.R_AX);
3050 DECODE_CLEAR_SEGOVR();
3051 END_OF_INSTR();
3052 }
3053
3054 /****************************************************************************
3055 REMARKS:
3056 Handles opcode 0x38
3057 ****************************************************************************/
3058 static void x86emuOp_cmp_byte_RM_R(u8 X86EMU_UNUSED(op1))
3059 {
3060 int mod, rl, rh;
3061 uint destoffset;
3062 u8 *destreg, *srcreg;
3063 u8 destval;
3064
3065 START_OF_INSTR();
3066 DECODE_PRINTF("CMP\t");
3067 FETCH_DECODE_MODRM(mod, rh, rl);
3068 switch (mod) {
3069 case 0:
3070 destoffset = decode_rm00_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 1:
3079 destoffset = decode_rm01_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 2:
3088 destoffset = decode_rm10_address(rl);
3089 DECODE_PRINTF(",");
3090 destval = fetch_data_byte(destoffset);
3091 srcreg = DECODE_RM_BYTE_REGISTER(rh);
3092 DECODE_PRINTF("\n");
3093 TRACE_AND_STEP();
3094 cmp_byte(destval, *srcreg);
3095 break;
3096 case 3: /* register to register */
3097 destreg = DECODE_RM_BYTE_REGISTER(rl);
3098 DECODE_PRINTF(",");
3099 srcreg = DECODE_RM_BYTE_REGISTER(rh);
3100 DECODE_PRINTF("\n");
3101 TRACE_AND_STEP();
3102 cmp_byte(*destreg, *srcreg);
3103 break;
3104 }
3105 DECODE_CLEAR_SEGOVR();
3106 END_OF_INSTR();
3107 }
3108
3109 /****************************************************************************
3110 REMARKS:
3111 Handles opcode 0x39
3112 ****************************************************************************/
3113 static void x86emuOp_cmp_word_RM_R(u8 X86EMU_UNUSED(op1))
3114 {
3115 int mod, rl, rh;
3116 uint destoffset;
3117
3118 START_OF_INSTR();
3119 DECODE_PRINTF("CMP\t");
3120 FETCH_DECODE_MODRM(mod, rh, rl);
3121 switch (mod) {
3122 case 0:
3123 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3124 u32 destval;
3125 u32 *srcreg;
3126
3127 destoffset = decode_rm00_address(rl);
3128 DECODE_PRINTF(",");
3129 destval = fetch_data_long(destoffset);
3130 srcreg = DECODE_RM_LONG_REGISTER(rh);
3131 DECODE_PRINTF("\n");
3132 TRACE_AND_STEP();
3133 cmp_long(destval, *srcreg);
3134 } else {
3135 u16 destval;
3136 u16 *srcreg;
3137
3138 destoffset = decode_rm00_address(rl);
3139 DECODE_PRINTF(",");
3140 destval = fetch_data_word(destoffset);
3141 srcreg = DECODE_RM_WORD_REGISTER(rh);
3142 DECODE_PRINTF("\n");
3143 TRACE_AND_STEP();
3144 cmp_word(destval, *srcreg);
3145 }
3146 break;
3147 case 1:
3148 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3149 u32 destval;
3150 u32 *srcreg;
3151
3152 destoffset = decode_rm01_address(rl);
3153 DECODE_PRINTF(",");
3154 destval = fetch_data_long(destoffset);
3155 srcreg = DECODE_RM_LONG_REGISTER(rh);
3156 DECODE_PRINTF("\n");
3157 TRACE_AND_STEP();
3158 cmp_long(destval, *srcreg);
3159 } else {
3160 u16 destval;
3161 u16 *srcreg;
3162
3163 destoffset = decode_rm01_address(rl);
3164 DECODE_PRINTF(",");
3165 destval = fetch_data_word(destoffset);
3166 srcreg = DECODE_RM_WORD_REGISTER(rh);
3167 DECODE_PRINTF("\n");
3168 TRACE_AND_STEP();
3169 cmp_word(destval, *srcreg);
3170 }
3171 break;
3172 case 2:
3173 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3174 u32 destval;
3175 u32 *srcreg;
3176
3177 destoffset = decode_rm10_address(rl);
3178 DECODE_PRINTF(",");
3179 destval = fetch_data_long(destoffset);
3180 srcreg = DECODE_RM_LONG_REGISTER(rh);
3181 DECODE_PRINTF("\n");
3182 TRACE_AND_STEP();
3183 cmp_long(destval, *srcreg);
3184 } else {
3185 u16 destval;
3186 u16 *srcreg;
3187
3188 destoffset = decode_rm10_address(rl);
3189 DECODE_PRINTF(",");
3190 destval = fetch_data_word(destoffset);
3191 srcreg = DECODE_RM_WORD_REGISTER(rh);
3192 DECODE_PRINTF("\n");
3193 TRACE_AND_STEP();
3194 cmp_word(destval, *srcreg);
3195 }
3196 break;
3197 case 3: /* register to register */
3198 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3199 u32 *destreg,*srcreg;
3200
3201 destreg = DECODE_RM_LONG_REGISTER(rl);
3202 DECODE_PRINTF(",");
3203 srcreg = DECODE_RM_LONG_REGISTER(rh);
3204 DECODE_PRINTF("\n");
3205 TRACE_AND_STEP();
3206 cmp_long(*destreg, *srcreg);
3207 } else {
3208 u16 *destreg,*srcreg;
3209
3210 destreg = DECODE_RM_WORD_REGISTER(rl);
3211 DECODE_PRINTF(",");
3212 srcreg = DECODE_RM_WORD_REGISTER(rh);
3213 DECODE_PRINTF("\n");
3214 TRACE_AND_STEP();
3215 cmp_word(*destreg, *srcreg);
3216 }
3217 break;
3218 }
3219 DECODE_CLEAR_SEGOVR();
3220 END_OF_INSTR();
3221 }
3222
3223 /****************************************************************************
3224 REMARKS:
3225 Handles opcode 0x3a
3226 ****************************************************************************/
3227 static void x86emuOp_cmp_byte_R_RM(u8 X86EMU_UNUSED(op1))
3228 {
3229 int mod, rl, rh;
3230 u8 *destreg, *srcreg;
3231 uint srcoffset;
3232 u8 srcval;
3233
3234 START_OF_INSTR();
3235 DECODE_PRINTF("CMP\t");
3236 FETCH_DECODE_MODRM(mod, rh, rl);
3237 switch (mod) {
3238 case 0:
3239 destreg = DECODE_RM_BYTE_REGISTER(rh);
3240 DECODE_PRINTF(",");
3241 srcoffset = decode_rm00_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 1:
3248 destreg = DECODE_RM_BYTE_REGISTER(rh);
3249 DECODE_PRINTF(",");
3250 srcoffset = decode_rm01_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 2:
3257 destreg = DECODE_RM_BYTE_REGISTER(rh);
3258 DECODE_PRINTF(",");
3259 srcoffset = decode_rm10_address(rl);
3260 srcval = fetch_data_byte(srcoffset);
3261 DECODE_PRINTF("\n");
3262 TRACE_AND_STEP();
3263 cmp_byte(*destreg, srcval);
3264 break;
3265 case 3: /* register to register */
3266 destreg = DECODE_RM_BYTE_REGISTER(rh);
3267 DECODE_PRINTF(",");
3268 srcreg = DECODE_RM_BYTE_REGISTER(rl);
3269 DECODE_PRINTF("\n");
3270 TRACE_AND_STEP();
3271 cmp_byte(*destreg, *srcreg);
3272 break;
3273 }
3274 DECODE_CLEAR_SEGOVR();
3275 END_OF_INSTR();
3276 }
3277
3278 /****************************************************************************
3279 REMARKS:
3280 Handles opcode 0x3b
3281 ****************************************************************************/
3282 static void x86emuOp_cmp_word_R_RM(u8 X86EMU_UNUSED(op1))
3283 {
3284 int mod, rl, rh;
3285 uint srcoffset;
3286
3287 START_OF_INSTR();
3288 DECODE_PRINTF("CMP\t");
3289 FETCH_DECODE_MODRM(mod, rh, rl);
3290 switch (mod) {
3291 case 0:
3292 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3293 u32 *destreg;
3294 u32 srcval;
3295
3296 destreg = DECODE_RM_LONG_REGISTER(rh);
3297 DECODE_PRINTF(",");
3298 srcoffset = decode_rm00_address(rl);
3299 srcval = fetch_data_long(srcoffset);
3300 DECODE_PRINTF("\n");
3301 TRACE_AND_STEP();
3302 cmp_long(*destreg, srcval);
3303 } else {
3304 u16 *destreg;
3305 u16 srcval;
3306
3307 destreg = DECODE_RM_WORD_REGISTER(rh);
3308 DECODE_PRINTF(",");
3309 srcoffset = decode_rm00_address(rl);
3310 srcval = fetch_data_word(srcoffset);
3311 DECODE_PRINTF("\n");
3312 TRACE_AND_STEP();
3313 cmp_word(*destreg, srcval);
3314 }
3315 break;
3316 case 1:
3317 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3318 u32 *destreg;
3319 u32 srcval;
3320
3321 destreg = DECODE_RM_LONG_REGISTER(rh);
3322 DECODE_PRINTF(",");
3323 srcoffset = decode_rm01_address(rl);
3324 srcval = fetch_data_long(srcoffset);
3325 DECODE_PRINTF("\n");
3326 TRACE_AND_STEP();
3327 cmp_long(*destreg, srcval);
3328 } else {
3329 u16 *destreg;
3330 u16 srcval;
3331
3332 destreg = DECODE_RM_WORD_REGISTER(rh);
3333 DECODE_PRINTF(",");
3334 srcoffset = decode_rm01_address(rl);
3335 srcval = fetch_data_word(srcoffset);
3336 DECODE_PRINTF("\n");
3337 TRACE_AND_STEP();
3338 cmp_word(*destreg, srcval);
3339 }
3340 break;
3341 case 2:
3342 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3343 u32 *destreg;
3344 u32 srcval;
3345
3346 destreg = DECODE_RM_LONG_REGISTER(rh);
3347 DECODE_PRINTF(",");
3348 srcoffset = decode_rm10_address(rl);
3349 srcval = fetch_data_long(srcoffset);
3350 DECODE_PRINTF("\n");
3351 TRACE_AND_STEP();
3352 cmp_long(*destreg, srcval);
3353 } else {
3354 u16 *destreg;
3355 u16 srcval;
3356
3357 destreg = DECODE_RM_WORD_REGISTER(rh);
3358 DECODE_PRINTF(",");
3359 srcoffset = decode_rm10_address(rl);
3360 srcval = fetch_data_word(srcoffset);
3361 DECODE_PRINTF("\n");
3362 TRACE_AND_STEP();
3363 cmp_word(*destreg, srcval);
3364 }
3365 break;
3366 case 3: /* register to register */
3367 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3368 u32 *destreg,*srcreg;
3369
3370 destreg = DECODE_RM_LONG_REGISTER(rh);
3371 DECODE_PRINTF(",");
3372 srcreg = DECODE_RM_LONG_REGISTER(rl);
3373 DECODE_PRINTF("\n");
3374 TRACE_AND_STEP();
3375 cmp_long(*destreg, *srcreg);
3376 } else {
3377 u16 *destreg,*srcreg;
3378
3379 destreg = DECODE_RM_WORD_REGISTER(rh);
3380 DECODE_PRINTF(",");
3381 srcreg = DECODE_RM_WORD_REGISTER(rl);
3382 DECODE_PRINTF("\n");
3383 TRACE_AND_STEP();
3384 cmp_word(*destreg, *srcreg);
3385 }
3386 break;
3387 }
3388 DECODE_CLEAR_SEGOVR();
3389 END_OF_INSTR();
3390 }
3391
3392 /****************************************************************************
3393 REMARKS:
3394 Handles opcode 0x3c
3395 ****************************************************************************/
3396 static void x86emuOp_cmp_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
3397 {
3398 u8 srcval;
3399
3400 START_OF_INSTR();
3401 DECODE_PRINTF("CMP\tAL,");
3402 srcval = fetch_byte_imm();
3403 DECODE_PRINTF2("%x\n", srcval);
3404 TRACE_AND_STEP();
3405 cmp_byte(M.x86.R_AL, srcval);
3406 DECODE_CLEAR_SEGOVR();
3407 END_OF_INSTR();
3408 }
3409
3410 /****************************************************************************
3411 REMARKS:
3412 Handles opcode 0x3d
3413 ****************************************************************************/
3414 static void x86emuOp_cmp_word_AX_IMM(u8 X86EMU_UNUSED(op1))
3415 {
3416 u32 srcval;
3417
3418 START_OF_INSTR();
3419 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3420 DECODE_PRINTF("CMP\tEAX,");
3421 srcval = fetch_long_imm();
3422 } else {
3423 DECODE_PRINTF("CMP\tAX,");
3424 srcval = fetch_word_imm();
3425 }
3426 DECODE_PRINTF2("%x\n", srcval);
3427 TRACE_AND_STEP();
3428 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3429 cmp_long(M.x86.R_EAX, srcval);
3430 } else {
3431 cmp_word(M.x86.R_AX, (u16)srcval);
3432 }
3433 DECODE_CLEAR_SEGOVR();
3434 END_OF_INSTR();
3435 }
3436
3437 /****************************************************************************
3438 REMARKS:
3439 Handles opcode 0x3e
3440 ****************************************************************************/
3441 static void x86emuOp_segovr_DS(u8 X86EMU_UNUSED(op1))
3442 {
3443 START_OF_INSTR();
3444 DECODE_PRINTF("DS:\n");
3445 TRACE_AND_STEP();
3446 M.x86.mode |= SYSMODE_SEGOVR_DS;
3447 /* NO DECODE_CLEAR_SEGOVR! */
3448 END_OF_INSTR();
3449 }
3450
3451 /****************************************************************************
3452 REMARKS:
3453 Handles opcode 0x3f
3454 ****************************************************************************/
3455 static void x86emuOp_aas(u8 X86EMU_UNUSED(op1))
3456 {
3457 START_OF_INSTR();
3458 DECODE_PRINTF("AAS\n");
3459 TRACE_AND_STEP();
3460 M.x86.R_AX = aas_word(M.x86.R_AX);
3461 DECODE_CLEAR_SEGOVR();
3462 END_OF_INSTR();
3463 }
3464
3465 /****************************************************************************
3466 REMARKS:
3467 Handles opcode 0x40
3468 ****************************************************************************/
3469 static void x86emuOp_inc_AX(u8 X86EMU_UNUSED(op1))
3470 {
3471 START_OF_INSTR();
3472 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3473 DECODE_PRINTF("INC\tEAX\n");
3474 } else {
3475 DECODE_PRINTF("INC\tAX\n");
3476 }
3477 TRACE_AND_STEP();
3478 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3479 M.x86.R_EAX = inc_long(M.x86.R_EAX);
3480 } else {
3481 M.x86.R_AX = inc_word(M.x86.R_AX);
3482 }
3483 DECODE_CLEAR_SEGOVR();
3484 END_OF_INSTR();
3485 }
3486
3487 /****************************************************************************
3488 REMARKS:
3489 Handles opcode 0x41
3490 ****************************************************************************/
3491 static void x86emuOp_inc_CX(u8 X86EMU_UNUSED(op1))
3492 {
3493 START_OF_INSTR();
3494 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3495 DECODE_PRINTF("INC\tECX\n");
3496 } else {
3497 DECODE_PRINTF("INC\tCX\n");
3498 }
3499 TRACE_AND_STEP();
3500 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3501 M.x86.R_ECX = inc_long(M.x86.R_ECX);
3502 } else {
3503 M.x86.R_CX = inc_word(M.x86.R_CX);
3504 }
3505 DECODE_CLEAR_SEGOVR();
3506 END_OF_INSTR();
3507 }
3508
3509 /****************************************************************************
3510 REMARKS:
3511 Handles opcode 0x42
3512 ****************************************************************************/
3513 static void x86emuOp_inc_DX(u8 X86EMU_UNUSED(op1))
3514 {
3515 START_OF_INSTR();
3516 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3517 DECODE_PRINTF("INC\tEDX\n");
3518 } else {
3519 DECODE_PRINTF("INC\tDX\n");
3520 }
3521 TRACE_AND_STEP();
3522 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3523 M.x86.R_EDX = inc_long(M.x86.R_EDX);
3524 } else {
3525 M.x86.R_DX = inc_word(M.x86.R_DX);
3526 }
3527 DECODE_CLEAR_SEGOVR();
3528 END_OF_INSTR();
3529 }
3530
3531 /****************************************************************************
3532 REMARKS:
3533 Handles opcode 0x43
3534 ****************************************************************************/
3535 static void x86emuOp_inc_BX(u8 X86EMU_UNUSED(op1))
3536 {
3537 START_OF_INSTR();
3538 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3539 DECODE_PRINTF("INC\tEBX\n");
3540 } else {
3541 DECODE_PRINTF("INC\tBX\n");
3542 }
3543 TRACE_AND_STEP();
3544 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3545 M.x86.R_EBX = inc_long(M.x86.R_EBX);
3546 } else {
3547 M.x86.R_BX = inc_word(M.x86.R_BX);
3548 }
3549 DECODE_CLEAR_SEGOVR();
3550 END_OF_INSTR();
3551 }
3552
3553 /****************************************************************************
3554 REMARKS:
3555 Handles opcode 0x44
3556 ****************************************************************************/
3557 static void x86emuOp_inc_SP(u8 X86EMU_UNUSED(op1))
3558 {
3559 START_OF_INSTR();
3560 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3561 DECODE_PRINTF("INC\tESP\n");
3562 } else {
3563 DECODE_PRINTF("INC\tSP\n");
3564 }
3565 TRACE_AND_STEP();
3566 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3567 M.x86.R_ESP = inc_long(M.x86.R_ESP);
3568 } else {
3569 M.x86.R_SP = inc_word(M.x86.R_SP);
3570 }
3571 DECODE_CLEAR_SEGOVR();
3572 END_OF_INSTR();
3573 }
3574
3575 /****************************************************************************
3576 REMARKS:
3577 Handles opcode 0x45
3578 ****************************************************************************/
3579 static void x86emuOp_inc_BP(u8 X86EMU_UNUSED(op1))
3580 {
3581 START_OF_INSTR();
3582 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3583 DECODE_PRINTF("INC\tEBP\n");
3584 } else {
3585 DECODE_PRINTF("INC\tBP\n");
3586 }
3587 TRACE_AND_STEP();
3588 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3589 M.x86.R_EBP = inc_long(M.x86.R_EBP);
3590 } else {
3591 M.x86.R_BP = inc_word(M.x86.R_BP);
3592 }
3593 DECODE_CLEAR_SEGOVR();
3594 END_OF_INSTR();
3595 }
3596
3597 /****************************************************************************
3598 REMARKS:
3599 Handles opcode 0x46
3600 ****************************************************************************/
3601 static void x86emuOp_inc_SI(u8 X86EMU_UNUSED(op1))
3602 {
3603 START_OF_INSTR();
3604 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3605 DECODE_PRINTF("INC\tESI\n");
3606 } else {
3607 DECODE_PRINTF("INC\tSI\n");
3608 }
3609 TRACE_AND_STEP();
3610 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3611 M.x86.R_ESI = inc_long(M.x86.R_ESI);
3612 } else {
3613 M.x86.R_SI = inc_word(M.x86.R_SI);
3614 }
3615 DECODE_CLEAR_SEGOVR();
3616 END_OF_INSTR();
3617 }
3618
3619 /****************************************************************************
3620 REMARKS:
3621 Handles opcode 0x47
3622 ****************************************************************************/
3623 static void x86emuOp_inc_DI(u8 X86EMU_UNUSED(op1))
3624 {
3625 START_OF_INSTR();
3626 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3627 DECODE_PRINTF("INC\tEDI\n");
3628 } else {
3629 DECODE_PRINTF("INC\tDI\n");
3630 }
3631 TRACE_AND_STEP();
3632 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3633 M.x86.R_EDI = inc_long(M.x86.R_EDI);
3634 } else {
3635 M.x86.R_DI = inc_word(M.x86.R_DI);
3636 }
3637 DECODE_CLEAR_SEGOVR();
3638 END_OF_INSTR();
3639 }
3640
3641 /****************************************************************************
3642 REMARKS:
3643 Handles opcode 0x48
3644 ****************************************************************************/
3645 static void x86emuOp_dec_AX(u8 X86EMU_UNUSED(op1))
3646 {
3647 START_OF_INSTR();
3648 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3649 DECODE_PRINTF("DEC\tEAX\n");
3650 } else {
3651 DECODE_PRINTF("DEC\tAX\n");
3652 }
3653 TRACE_AND_STEP();
3654 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3655 M.x86.R_EAX = dec_long(M.x86.R_EAX);
3656 } else {
3657 M.x86.R_AX = dec_word(M.x86.R_AX);
3658 }
3659 DECODE_CLEAR_SEGOVR();
3660 END_OF_INSTR();
3661 }
3662
3663 /****************************************************************************
3664 REMARKS:
3665 Handles opcode 0x49
3666 ****************************************************************************/
3667 static void x86emuOp_dec_CX(u8 X86EMU_UNUSED(op1))
3668 {
3669 START_OF_INSTR();
3670 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3671 DECODE_PRINTF("DEC\tECX\n");
3672 } else {
3673 DECODE_PRINTF("DEC\tCX\n");
3674 }
3675 TRACE_AND_STEP();
3676 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3677 M.x86.R_ECX = dec_long(M.x86.R_ECX);
3678 } else {
3679 M.x86.R_CX = dec_word(M.x86.R_CX);
3680 }
3681 DECODE_CLEAR_SEGOVR();
3682 END_OF_INSTR();
3683 }
3684
3685 /****************************************************************************
3686 REMARKS:
3687 Handles opcode 0x4a
3688 ****************************************************************************/
3689 static void x86emuOp_dec_DX(u8 X86EMU_UNUSED(op1))
3690 {
3691 START_OF_INSTR();
3692 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3693 DECODE_PRINTF("DEC\tEDX\n");
3694 } else {
3695 DECODE_PRINTF("DEC\tDX\n");
3696 }
3697 TRACE_AND_STEP();
3698 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3699 M.x86.R_EDX = dec_long(M.x86.R_EDX);
3700 } else {
3701 M.x86.R_DX = dec_word(M.x86.R_DX);
3702 }
3703 DECODE_CLEAR_SEGOVR();
3704 END_OF_INSTR();
3705 }
3706
3707 /****************************************************************************
3708 REMARKS:
3709 Handles opcode 0x4b
3710 ****************************************************************************/
3711 static void x86emuOp_dec_BX(u8 X86EMU_UNUSED(op1))
3712 {
3713 START_OF_INSTR();
3714 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3715 DECODE_PRINTF("DEC\tEBX\n");
3716 } else {
3717 DECODE_PRINTF("DEC\tBX\n");
3718 }
3719 TRACE_AND_STEP();
3720 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3721 M.x86.R_EBX = dec_long(M.x86.R_EBX);
3722 } else {
3723 M.x86.R_BX = dec_word(M.x86.R_BX);
3724 }
3725 DECODE_CLEAR_SEGOVR();
3726 END_OF_INSTR();
3727 }
3728
3729 /****************************************************************************
3730 REMARKS:
3731 Handles opcode 0x4c
3732 ****************************************************************************/
3733 static void x86emuOp_dec_SP(u8 X86EMU_UNUSED(op1))
3734 {
3735 START_OF_INSTR();
3736 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3737 DECODE_PRINTF("DEC\tESP\n");
3738 } else {
3739 DECODE_PRINTF("DEC\tSP\n");
3740 }
3741 TRACE_AND_STEP();
3742 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3743 M.x86.R_ESP = dec_long(M.x86.R_ESP);
3744 } else {
3745 M.x86.R_SP = dec_word(M.x86.R_SP);
3746 }
3747 DECODE_CLEAR_SEGOVR();
3748 END_OF_INSTR();
3749 }
3750
3751 /****************************************************************************
3752 REMARKS:
3753 Handles opcode 0x4d
3754 ****************************************************************************/
3755 static void x86emuOp_dec_BP(u8 X86EMU_UNUSED(op1))
3756 {
3757 START_OF_INSTR();
3758 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3759 DECODE_PRINTF("DEC\tEBP\n");
3760 } else {
3761 DECODE_PRINTF("DEC\tBP\n");
3762 }
3763 TRACE_AND_STEP();
3764 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3765 M.x86.R_EBP = dec_long(M.x86.R_EBP);
3766 } else {
3767 M.x86.R_BP = dec_word(M.x86.R_BP);
3768 }
3769 DECODE_CLEAR_SEGOVR();
3770 END_OF_INSTR();
3771 }
3772
3773 /****************************************************************************
3774 REMARKS:
3775 Handles opcode 0x4e
3776 ****************************************************************************/
3777 static void x86emuOp_dec_SI(u8 X86EMU_UNUSED(op1))
3778 {
3779 START_OF_INSTR();
3780 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3781 DECODE_PRINTF("DEC\tESI\n");
3782 } else {
3783 DECODE_PRINTF("DEC\tSI\n");
3784 }
3785 TRACE_AND_STEP();
3786 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3787 M.x86.R_ESI = dec_long(M.x86.R_ESI);
3788 } else {
3789 M.x86.R_SI = dec_word(M.x86.R_SI);
3790 }
3791 DECODE_CLEAR_SEGOVR();
3792 END_OF_INSTR();
3793 }
3794
3795 /****************************************************************************
3796 REMARKS:
3797 Handles opcode 0x4f
3798 ****************************************************************************/
3799 static void x86emuOp_dec_DI(u8 X86EMU_UNUSED(op1))
3800 {
3801 START_OF_INSTR();
3802 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3803 DECODE_PRINTF("DEC\tEDI\n");
3804 } else {
3805 DECODE_PRINTF("DEC\tDI\n");
3806 }
3807 TRACE_AND_STEP();
3808 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3809 M.x86.R_EDI = dec_long(M.x86.R_EDI);
3810 } else {
3811 M.x86.R_DI = dec_word(M.x86.R_DI);
3812 }
3813 DECODE_CLEAR_SEGOVR();
3814 END_OF_INSTR();
3815 }
3816
3817 /****************************************************************************
3818 REMARKS:
3819 Handles opcode 0x50
3820 ****************************************************************************/
3821 static void x86emuOp_push_AX(u8 X86EMU_UNUSED(op1))
3822 {
3823 START_OF_INSTR();
3824 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3825 DECODE_PRINTF("PUSH\tEAX\n");
3826 } else {
3827 DECODE_PRINTF("PUSH\tAX\n");
3828 }
3829 TRACE_AND_STEP();
3830 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3831 push_long(M.x86.R_EAX);
3832 } else {
3833 push_word(M.x86.R_AX);
3834 }
3835 DECODE_CLEAR_SEGOVR();
3836 END_OF_INSTR();
3837 }
3838
3839 /****************************************************************************
3840 REMARKS:
3841 Handles opcode 0x51
3842 ****************************************************************************/
3843 static void x86emuOp_push_CX(u8 X86EMU_UNUSED(op1))
3844 {
3845 START_OF_INSTR();
3846 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3847 DECODE_PRINTF("PUSH\tECX\n");
3848 } else {
3849 DECODE_PRINTF("PUSH\tCX\n");
3850 }
3851 TRACE_AND_STEP();
3852 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3853 push_long(M.x86.R_ECX);
3854 } else {
3855 push_word(M.x86.R_CX);
3856 }
3857 DECODE_CLEAR_SEGOVR();
3858 END_OF_INSTR();
3859 }
3860
3861 /****************************************************************************
3862 REMARKS:
3863 Handles opcode 0x52
3864 ****************************************************************************/
3865 static void x86emuOp_push_DX(u8 X86EMU_UNUSED(op1))
3866 {
3867 START_OF_INSTR();
3868 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3869 DECODE_PRINTF("PUSH\tEDX\n");
3870 } else {
3871 DECODE_PRINTF("PUSH\tDX\n");
3872 }
3873 TRACE_AND_STEP();
3874 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3875 push_long(M.x86.R_EDX);
3876 } else {
3877 push_word(M.x86.R_DX);
3878 }
3879 DECODE_CLEAR_SEGOVR();
3880 END_OF_INSTR();
3881 }
3882
3883 /****************************************************************************
3884 REMARKS:
3885 Handles opcode 0x53
3886 ****************************************************************************/
3887 static void x86emuOp_push_BX(u8 X86EMU_UNUSED(op1))
3888 {
3889 START_OF_INSTR();
3890 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3891 DECODE_PRINTF("PUSH\tEBX\n");
3892 } else {
3893 DECODE_PRINTF("PUSH\tBX\n");
3894 }
3895 TRACE_AND_STEP();
3896 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3897 push_long(M.x86.R_EBX);
3898 } else {
3899 push_word(M.x86.R_BX);
3900 }
3901 DECODE_CLEAR_SEGOVR();
3902 END_OF_INSTR();
3903 }
3904
3905 /****************************************************************************
3906 REMARKS:
3907 Handles opcode 0x54
3908 ****************************************************************************/
3909 static void x86emuOp_push_SP(u8 X86EMU_UNUSED(op1))
3910 {
3911 START_OF_INSTR();
3912 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3913 DECODE_PRINTF("PUSH\tESP\n");
3914 } else {
3915 DECODE_PRINTF("PUSH\tSP\n");
3916 }
3917 TRACE_AND_STEP();
3918 /* Always push (E)SP, since we are emulating an i386 and above
3919 * processor. This is necessary as some BIOS'es use this to check
3920 * what type of processor is in the system.
3921 */
3922 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3923 push_long(M.x86.R_ESP);
3924 } else {
3925 push_word((u16)(M.x86.R_SP));
3926 }
3927 DECODE_CLEAR_SEGOVR();
3928 END_OF_INSTR();
3929 }
3930
3931 /****************************************************************************
3932 REMARKS:
3933 Handles opcode 0x55
3934 ****************************************************************************/
3935 static void x86emuOp_push_BP(u8 X86EMU_UNUSED(op1))
3936 {
3937 START_OF_INSTR();
3938 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3939 DECODE_PRINTF("PUSH\tEBP\n");
3940 } else {
3941 DECODE_PRINTF("PUSH\tBP\n");
3942 }
3943 TRACE_AND_STEP();
3944 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3945 push_long(M.x86.R_EBP);
3946 } else {
3947 push_word(M.x86.R_BP);
3948 }
3949 DECODE_CLEAR_SEGOVR();
3950 END_OF_INSTR();
3951 }
3952
3953 /****************************************************************************
3954 REMARKS:
3955 Handles opcode 0x56
3956 ****************************************************************************/
3957 static void x86emuOp_push_SI(u8 X86EMU_UNUSED(op1))
3958 {
3959 START_OF_INSTR();
3960 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3961 DECODE_PRINTF("PUSH\tESI\n");
3962 } else {
3963 DECODE_PRINTF("PUSH\tSI\n");
3964 }
3965 TRACE_AND_STEP();
3966 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3967 push_long(M.x86.R_ESI);
3968 } else {
3969 push_word(M.x86.R_SI);
3970 }
3971 DECODE_CLEAR_SEGOVR();
3972 END_OF_INSTR();
3973 }
3974
3975 /****************************************************************************
3976 REMARKS:
3977 Handles opcode 0x57
3978 ****************************************************************************/
3979 static void x86emuOp_push_DI(u8 X86EMU_UNUSED(op1))
3980 {
3981 START_OF_INSTR();
3982 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3983 DECODE_PRINTF("PUSH\tEDI\n");
3984 } else {
3985 DECODE_PRINTF("PUSH\tDI\n");
3986 }
3987 TRACE_AND_STEP();
3988 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3989 push_long(M.x86.R_EDI);
3990 } else {
3991 push_word(M.x86.R_DI);
3992 }
3993 DECODE_CLEAR_SEGOVR();
3994 END_OF_INSTR();
3995 }
3996
3997 /****************************************************************************
3998 REMARKS:
3999 Handles opcode 0x58
4000 ****************************************************************************/
4001 static void x86emuOp_pop_AX(u8 X86EMU_UNUSED(op1))
4002 {
4003 START_OF_INSTR();
4004 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4005 DECODE_PRINTF("POP\tEAX\n");
4006 } else {
4007 DECODE_PRINTF("POP\tAX\n");
4008 }
4009 TRACE_AND_STEP();
4010 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4011 M.x86.R_EAX = pop_long();
4012 } else {
4013 M.x86.R_AX = pop_word();
4014 }
4015 DECODE_CLEAR_SEGOVR();
4016 END_OF_INSTR();
4017 }
4018
4019 /****************************************************************************
4020 REMARKS:
4021 Handles opcode 0x59
4022 ****************************************************************************/
4023 static void x86emuOp_pop_CX(u8 X86EMU_UNUSED(op1))
4024 {
4025 START_OF_INSTR();
4026 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4027 DECODE_PRINTF("POP\tECX\n");
4028 } else {
4029 DECODE_PRINTF("POP\tCX\n");
4030 }
4031 TRACE_AND_STEP();
4032 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4033 M.x86.R_ECX = pop_long();
4034 } else {
4035 M.x86.R_CX = pop_word();
4036 }
4037 DECODE_CLEAR_SEGOVR();
4038 END_OF_INSTR();
4039 }
4040
4041 /****************************************************************************
4042 REMARKS:
4043 Handles opcode 0x5a
4044 ****************************************************************************/
4045 static void x86emuOp_pop_DX(u8 X86EMU_UNUSED(op1))
4046 {
4047 START_OF_INSTR();
4048 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4049 DECODE_PRINTF("POP\tEDX\n");
4050 } else {
4051 DECODE_PRINTF("POP\tDX\n");
4052 }
4053 TRACE_AND_STEP();
4054 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4055 M.x86.R_EDX = pop_long();
4056 } else {
4057 M.x86.R_DX = pop_word();
4058 }
4059 DECODE_CLEAR_SEGOVR();
4060 END_OF_INSTR();
4061 }
4062
4063 /****************************************************************************
4064 REMARKS:
4065 Handles opcode 0x5b
4066 ****************************************************************************/
4067 static void x86emuOp_pop_BX(u8 X86EMU_UNUSED(op1))
4068 {
4069 START_OF_INSTR();
4070 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4071 DECODE_PRINTF("POP\tEBX\n");
4072 } else {
4073 DECODE_PRINTF("POP\tBX\n");
4074 }
4075 TRACE_AND_STEP();
4076 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4077 M.x86.R_EBX = pop_long();
4078 } else {
4079 M.x86.R_BX = pop_word();
4080 }
4081 DECODE_CLEAR_SEGOVR();
4082 END_OF_INSTR();
4083 }
4084
4085 /****************************************************************************
4086 REMARKS:
4087 Handles opcode 0x5c
4088 ****************************************************************************/
4089 static void x86emuOp_pop_SP(u8 X86EMU_UNUSED(op1))
4090 {
4091 START_OF_INSTR();
4092 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4093 DECODE_PRINTF("POP\tESP\n");
4094 } else {
4095 DECODE_PRINTF("POP\tSP\n");
4096 }
4097 TRACE_AND_STEP();
4098 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4099 M.x86.R_ESP = pop_long();
4100 } else {
4101 M.x86.R_SP = pop_word();
4102 }
4103 DECODE_CLEAR_SEGOVR();
4104 END_OF_INSTR();
4105 }
4106
4107 /****************************************************************************
4108 REMARKS:
4109 Handles opcode 0x5d
4110 ****************************************************************************/
4111 static void x86emuOp_pop_BP(u8 X86EMU_UNUSED(op1))
4112 {
4113 START_OF_INSTR();
4114 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4115 DECODE_PRINTF("POP\tEBP\n");
4116 } else {
4117 DECODE_PRINTF("POP\tBP\n");
4118 }
4119 TRACE_AND_STEP();
4120 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4121 M.x86.R_EBP = pop_long();
4122 } else {
4123 M.x86.R_BP = pop_word();
4124 }
4125 DECODE_CLEAR_SEGOVR();
4126 END_OF_INSTR();
4127 }
4128
4129 /****************************************************************************
4130 REMARKS:
4131 Handles opcode 0x5e
4132 ****************************************************************************/
4133 static void x86emuOp_pop_SI(u8 X86EMU_UNUSED(op1))
4134 {
4135 START_OF_INSTR();
4136 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4137 DECODE_PRINTF("POP\tESI\n");
4138 } else {
4139 DECODE_PRINTF("POP\tSI\n");
4140 }
4141 TRACE_AND_STEP();
4142 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4143 M.x86.R_ESI = pop_long();
4144 } else {
4145 M.x86.R_SI = pop_word();
4146 }
4147 DECODE_CLEAR_SEGOVR();
4148 END_OF_INSTR();
4149 }
4150
4151 /****************************************************************************
4152 REMARKS:
4153 Handles opcode 0x5f
4154 ****************************************************************************/
4155 static void x86emuOp_pop_DI(u8 X86EMU_UNUSED(op1))
4156 {
4157 START_OF_INSTR();
4158 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4159 DECODE_PRINTF("POP\tEDI\n");
4160 } else {
4161 DECODE_PRINTF("POP\tDI\n");
4162 }
4163 TRACE_AND_STEP();
4164 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4165 M.x86.R_EDI = pop_long();
4166 } else {
4167 M.x86.R_DI = pop_word();
4168 }
4169 DECODE_CLEAR_SEGOVR();
4170 END_OF_INSTR();
4171 }
4172
4173 /****************************************************************************
4174 REMARKS:
4175 Handles opcode 0x60
4176 ****************************************************************************/
4177 static void x86emuOp_push_all(u8 X86EMU_UNUSED(op1))
4178 {
4179 START_OF_INSTR();
4180 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4181 DECODE_PRINTF("PUSHAD\n");
4182 } else {
4183 DECODE_PRINTF("PUSHA\n");
4184 }
4185 TRACE_AND_STEP();
4186 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4187 u32 old_sp = M.x86.R_ESP;
4188
4189 push_long(M.x86.R_EAX);
4190 push_long(M.x86.R_ECX);
4191 push_long(M.x86.R_EDX);
4192 push_long(M.x86.R_EBX);
4193 push_long(old_sp);
4194 push_long(M.x86.R_EBP);
4195 push_long(M.x86.R_ESI);
4196 push_long(M.x86.R_EDI);
4197 } else {
4198 u16 old_sp = M.x86.R_SP;
4199
4200 push_word(M.x86.R_AX);
4201 push_word(M.x86.R_CX);
4202 push_word(M.x86.R_DX);
4203 push_word(M.x86.R_BX);
4204 push_word(old_sp);
4205 push_word(M.x86.R_BP);
4206 push_word(M.x86.R_SI);
4207 push_word(M.x86.R_DI);
4208 }
4209 DECODE_CLEAR_SEGOVR();
4210 END_OF_INSTR();
4211 }
4212
4213 /****************************************************************************
4214 REMARKS:
4215 Handles opcode 0x61
4216 ****************************************************************************/
4217 static void x86emuOp_pop_all(u8 X86EMU_UNUSED(op1))
4218 {
4219 START_OF_INSTR();
4220 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4221 DECODE_PRINTF("POPAD\n");
4222 } else {
4223 DECODE_PRINTF("POPA\n");
4224 }
4225 TRACE_AND_STEP();
4226 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4227 M.x86.R_EDI = pop_long();
4228 M.x86.R_ESI = pop_long();
4229 M.x86.R_EBP = pop_long();
4230 M.x86.R_ESP += 4; /* skip ESP */
4231 M.x86.R_EBX = pop_long();
4232 M.x86.R_EDX = pop_long();
4233 M.x86.R_ECX = pop_long();
4234 M.x86.R_EAX = pop_long();
4235 } else {
4236 M.x86.R_DI = pop_word();
4237 M.x86.R_SI = pop_word();
4238 M.x86.R_BP = pop_word();
4239 M.x86.R_SP += 2; /* skip SP */
4240 M.x86.R_BX = pop_word();
4241 M.x86.R_DX = pop_word();
4242 M.x86.R_CX = pop_word();
4243 M.x86.R_AX = pop_word();
4244 }
4245 DECODE_CLEAR_SEGOVR();
4246 END_OF_INSTR();
4247 }
4248
4249 /*opcode 0x62 ILLEGAL OP, calls x86emuOp_illegal_op() */
4250 /*opcode 0x63 ILLEGAL OP, calls x86emuOp_illegal_op() */
4251
4252 /****************************************************************************
4253 REMARKS:
4254 Handles opcode 0x64
4255 ****************************************************************************/
4256 static void x86emuOp_segovr_FS(u8 X86EMU_UNUSED(op1))
4257 {
4258 START_OF_INSTR();
4259 DECODE_PRINTF("FS:\n");
4260 TRACE_AND_STEP();
4261 M.x86.mode |= SYSMODE_SEGOVR_FS;
4262 /*
4263 * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
4264 * opcode subroutines we do not want to do this.
4265 */
4266 END_OF_INSTR();
4267 }
4268
4269 /****************************************************************************
4270 REMARKS:
4271 Handles opcode 0x65
4272 ****************************************************************************/
4273 static void x86emuOp_segovr_GS(u8 X86EMU_UNUSED(op1))
4274 {
4275 START_OF_INSTR();
4276 DECODE_PRINTF("GS:\n");
4277 TRACE_AND_STEP();
4278 M.x86.mode |= SYSMODE_SEGOVR_GS;
4279 /*
4280 * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
4281 * opcode subroutines we do not want to do this.
4282 */
4283 END_OF_INSTR();
4284 }
4285
4286 /****************************************************************************
4287 REMARKS:
4288 Handles opcode 0x66 - prefix for 32-bit register
4289 ****************************************************************************/
4290 static void x86emuOp_prefix_data(u8 X86EMU_UNUSED(op1))
4291 {
4292 START_OF_INSTR();
4293 DECODE_PRINTF("DATA:\n");
4294 TRACE_AND_STEP();
4295 M.x86.mode |= SYSMODE_PREFIX_DATA;
4296 /* note no DECODE_CLEAR_SEGOVR here. */
4297 END_OF_INSTR();
4298 }
4299
4300 /****************************************************************************
4301 REMARKS:
4302 Handles opcode 0x67 - prefix for 32-bit address
4303 ****************************************************************************/
4304 static void x86emuOp_prefix_addr(u8 X86EMU_UNUSED(op1))
4305 {
4306 START_OF_INSTR();
4307 DECODE_PRINTF("ADDR:\n");
4308 TRACE_AND_STEP();
4309 M.x86.mode |= SYSMODE_PREFIX_ADDR;
4310 /* note no DECODE_CLEAR_SEGOVR here. */
4311 END_OF_INSTR();
4312 }
4313
4314 /****************************************************************************
4315 REMARKS:
4316 Handles opcode 0x68
4317 ****************************************************************************/
4318 static void x86emuOp_push_word_IMM(u8 X86EMU_UNUSED(op1))
4319 {
4320 u32 imm;
4321
4322 START_OF_INSTR();
4323 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4324 imm = fetch_long_imm();
4325 } else {
4326 imm = fetch_word_imm();
4327 }
4328 DECODE_PRINTF2("PUSH\t%x\n", imm);
4329 TRACE_AND_STEP();
4330 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4331 push_long(imm);
4332 } else {
4333 push_word((u16)imm);
4334 }
4335 DECODE_CLEAR_SEGOVR();
4336 END_OF_INSTR();
4337 }
4338
4339 /****************************************************************************
4340 REMARKS:
4341 Handles opcode 0x69
4342 ****************************************************************************/
4343 static void x86emuOp_imul_word_IMM(u8 X86EMU_UNUSED(op1))
4344 {
4345 int mod, rl, rh;
4346 uint srcoffset;
4347
4348 START_OF_INSTR();
4349 DECODE_PRINTF("IMUL\t");
4350 FETCH_DECODE_MODRM(mod, rh, rl);
4351 switch (mod) {
4352 case 0:
4353 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4354 u32 *destreg;
4355 u32 srcval;
4356 u32 res_lo,res_hi;
4357 s32 imm;
4358
4359 destreg = DECODE_RM_LONG_REGISTER(rh);
4360 DECODE_PRINTF(",");
4361 srcoffset = decode_rm00_address(rl);
4362 srcval = fetch_data_long(srcoffset);
4363 imm = fetch_long_imm();
4364 DECODE_PRINTF2(",%d\n", (s32)imm);
4365 TRACE_AND_STEP();
4366 imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
4367 if (res_hi != 0) {
4368 SET_FLAG(F_CF);
4369 SET_FLAG(F_OF);
4370 } else {
4371 CLEAR_FLAG(F_CF);
4372 CLEAR_FLAG(F_OF);
4373 }
4374 *destreg = (u32)res_lo;
4375 } else {
4376 u16 *destreg;
4377 u16 srcval;
4378 u32 res;
4379 s16 imm;
4380
4381 destreg = DECODE_RM_WORD_REGISTER(rh);
4382 DECODE_PRINTF(",");
4383 srcoffset = decode_rm00_address(rl);
4384 srcval = fetch_data_word(srcoffset);
4385 imm = fetch_word_imm();
4386 DECODE_PRINTF2(",%d\n", (s32)imm);
4387 TRACE_AND_STEP();
4388 res = (s16)srcval * (s16)imm;
4389 if (res > 0xFFFF) {
4390 SET_FLAG(F_CF);
4391 SET_FLAG(F_OF);
4392 } else {
4393 CLEAR_FLAG(F_CF);
4394 CLEAR_FLAG(F_OF);
4395 }
4396 *destreg = (u16)res;
4397 }
4398 break;
4399 case 1:
4400 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4401 u32 *destreg;
4402 u32 srcval;
4403 u32 res_lo,res_hi;
4404 s32 imm;
4405
4406 destreg = DECODE_RM_LONG_REGISTER(rh);
4407 DECODE_PRINTF(",");
4408 srcoffset = decode_rm01_address(rl);
4409 srcval = fetch_data_long(srcoffset);
4410 imm = fetch_long_imm();
4411 DECODE_PRINTF2(",%d\n", (s32)imm);
4412 TRACE_AND_STEP();
4413 imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
4414 if (res_hi != 0) {
4415 SET_FLAG(F_CF);
4416 SET_FLAG(F_OF);
4417 } else {
4418 CLEAR_FLAG(F_CF);
4419 CLEAR_FLAG(F_OF);
4420 }
4421 *destreg = (u32)res_lo;
4422 } else {
4423 u16 *destreg;
4424 u16 srcval;
4425 u32 res;
4426 s16 imm;
4427
4428 destreg = DECODE_RM_WORD_REGISTER(rh);
4429 DECODE_PRINTF(",");
4430 srcoffset = decode_rm01_address(rl);
4431 srcval = fetch_data_word(srcoffset);
4432 imm = fetch_word_imm();
4433 DECODE_PRINTF2(",%d\n", (s32)imm);
4434 TRACE_AND_STEP();
4435 res = (s16)srcval * (s16)imm;
4436 if (res > 0xFFFF) {
4437 SET_FLAG(F_CF);
4438 SET_FLAG(F_OF);
4439 } else {
4440 CLEAR_FLAG(F_CF);
4441 CLEAR_FLAG(F_OF);
4442 }
4443 *destreg = (u16)res;
4444 }
4445 break;
4446 case 2:
4447 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4448 u32 *destreg;
4449 u32 srcval;
4450 u32 res_lo,res_hi;
4451 s32 imm;
4452
4453 destreg = DECODE_RM_LONG_REGISTER(rh);
4454 DECODE_PRINTF(",");
4455 srcoffset = decode_rm10_address(rl);
4456 srcval = fetch_data_long(srcoffset);
4457 imm = fetch_long_imm();
4458 DECODE_PRINTF2(",%d\n", (s32)imm);
4459 TRACE_AND_STEP();
4460 imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
4461 if (res_hi != 0) {
4462 SET_FLAG(F_CF);
4463 SET_FLAG(F_OF);
4464 } else {
4465 CLEAR_FLAG(F_CF);
4466 CLEAR_FLAG(F_OF);
4467 }
4468 *destreg = (u32)res_lo;
4469 } else {
4470 u16 *destreg;
4471 u16 srcval;
4472 u32 res;
4473 s16 imm;
4474
4475 destreg = DECODE_RM_WORD_REGISTER(rh);
4476 DECODE_PRINTF(",");
4477 srcoffset = decode_rm10_address(rl);
4478 srcval = fetch_data_word(srcoffset);
4479 imm = fetch_word_imm();
4480 DECODE_PRINTF2(",%d\n", (s32)imm);
4481 TRACE_AND_STEP();
4482 res = (s16)srcval * (s16)imm;
4483 if (res > 0xFFFF) {
4484 SET_FLAG(F_CF);
4485 SET_FLAG(F_OF);
4486 } else {
4487 CLEAR_FLAG(F_CF);
4488 CLEAR_FLAG(F_OF);
4489 }
4490 *destreg = (u16)res;
4491 }
4492 break;
4493 case 3: /* register to register */
4494 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4495 u32 *destreg,*srcreg;
4496 u32 res_lo,res_hi;
4497 s32 imm;
4498
4499 destreg = DECODE_RM_LONG_REGISTER(rh);
4500 DECODE_PRINTF(",");
4501 srcreg = DECODE_RM_LONG_REGISTER(rl);
4502 imm = fetch_long_imm();
4503 DECODE_PRINTF2(",%d\n", (s32)imm);
4504 TRACE_AND_STEP();
4505 imul_long_direct(&res_lo,&res_hi,(s32)*srcreg,(s32)imm);
4506 if (res_hi != 0) {
4507 SET_FLAG(F_CF);
4508 SET_FLAG(F_OF);
4509 } else {
4510 CLEAR_FLAG(F_CF);
4511 CLEAR_FLAG(F_OF);
4512 }
4513 *destreg = (u32)res_lo;
4514 } else {
4515 u16 *destreg,*srcreg;
4516 u32 res;
4517 s16 imm;
4518
4519 destreg = DECODE_RM_WORD_REGISTER(rh);
4520 DECODE_PRINTF(",");
4521 srcreg = DECODE_RM_WORD_REGISTER(rl);
4522 imm = fetch_word_imm();
4523 DECODE_PRINTF2(",%d\n", (s32)imm);
4524 res = (s16)*srcreg * (s16)imm;
4525 if (res > 0xFFFF) {
4526 SET_FLAG(F_CF);
4527 SET_FLAG(F_OF);
4528 } else {
4529 CLEAR_FLAG(F_CF);
4530 CLEAR_FLAG(F_OF);
4531 }
4532 *destreg = (u16)res;
4533 }
4534 break;
4535 }
4536 DECODE_CLEAR_SEGOVR();
4537 END_OF_INSTR();
4538 }
4539
4540 /****************************************************************************
4541 REMARKS:
4542 Handles opcode 0x6a
4543 ****************************************************************************/
4544 static void x86emuOp_push_byte_IMM(u8 X86EMU_UNUSED(op1))
4545 {
4546 s16 imm;
4547
4548 START_OF_INSTR();
4549 imm = (s8)fetch_byte_imm();
4550 DECODE_PRINTF2("PUSH\t%d\n", imm);
4551 TRACE_AND_STEP();
4552 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4553 push_long((s32)imm);
4554 } else {
4555 push_word(imm);
4556 }
4557 DECODE_CLEAR_SEGOVR();
4558 END_OF_INSTR();
4559 }
4560
4561 /****************************************************************************
4562 REMARKS:
4563 Handles opcode 0x6b
4564 ****************************************************************************/
4565 static void x86emuOp_imul_byte_IMM(u8 X86EMU_UNUSED(op1))
4566 {
4567 int mod, rl, rh;
4568 uint srcoffset;
4569 s8 imm;
4570
4571 START_OF_INSTR();
4572 DECODE_PRINTF("IMUL\t");
4573 FETCH_DECODE_MODRM(mod, rh, rl);
4574 switch (mod) {
4575 case 0:
4576 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4577 u32 *destreg;
4578 u32 srcval;
4579 u32 res_lo,res_hi;
4580
4581 destreg = DECODE_RM_LONG_REGISTER(rh);
4582 DECODE_PRINTF(",");
4583 srcoffset = decode_rm00_address(rl);
4584 srcval = fetch_data_long(srcoffset);
4585 imm = fetch_byte_imm();
4586 DECODE_PRINTF2(",%d\n", (s32)imm);
4587 TRACE_AND_STEP();
4588 imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
4589 if (res_hi != 0) {
4590 SET_FLAG(F_CF);
4591 SET_FLAG(F_OF);
4592 } else {
4593 CLEAR_FLAG(F_CF);
4594 CLEAR_FLAG(F_OF);
4595 }
4596 *destreg = (u32)res_lo;
4597 } else {
4598 u16 *destreg;
4599 u16 srcval;
4600 u32 res;
4601
4602 destreg = DECODE_RM_WORD_REGISTER(rh);
4603 DECODE_PRINTF(",");
4604 srcoffset = decode_rm00_address(rl);
4605 srcval = fetch_data_word(srcoffset);
4606 imm = fetch_byte_imm();
4607 DECODE_PRINTF2(",%d\n", (s32)imm);
4608 TRACE_AND_STEP();
4609 res = (s16)srcval * (s16)imm;
4610 if (res > 0xFFFF) {
4611 SET_FLAG(F_CF);
4612 SET_FLAG(F_OF);
4613 } else {
4614 CLEAR_FLAG(F_CF);
4615 CLEAR_FLAG(F_OF);
4616 }
4617 *destreg = (u16)res;
4618 }
4619 break;
4620 case 1:
4621 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4622 u32 *destreg;
4623 u32 srcval;
4624 u32 res_lo,res_hi;
4625
4626 destreg = DECODE_RM_LONG_REGISTER(rh);
4627 DECODE_PRINTF(",");
4628 srcoffset = decode_rm01_address(rl);
4629 srcval = fetch_data_long(srcoffset);
4630 imm = fetch_byte_imm();
4631 DECODE_PRINTF2(",%d\n", (s32)imm);
4632 TRACE_AND_STEP();
4633 imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
4634 if (res_hi != 0) {
4635 SET_FLAG(F_CF);
4636 SET_FLAG(F_OF);
4637 } else {
4638 CLEAR_FLAG(F_CF);
4639 CLEAR_FLAG(F_OF);
4640 }
4641 *destreg = (u32)res_lo;
4642 } else {
4643 u16 *destreg;
4644 u16 srcval;
4645 u32 res;
4646
4647 destreg = DECODE_RM_WORD_REGISTER(rh);
4648 DECODE_PRINTF(",");
4649 srcoffset = decode_rm01_address(rl);
4650 srcval = fetch_data_word(srcoffset);
4651 imm = fetch_byte_imm();
4652 DECODE_PRINTF2(",%d\n", (s32)imm);
4653 TRACE_AND_STEP();
4654 res = (s16)srcval * (s16)imm;
4655 if (res > 0xFFFF) {
4656 SET_FLAG(F_CF);
4657 SET_FLAG(F_OF);
4658 } else {
4659 CLEAR_FLAG(F_CF);
4660 CLEAR_FLAG(F_OF);
4661 }
4662 *destreg = (u16)res;
4663 }
4664 break;
4665 case 2:
4666 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4667 u32 *destreg;
4668 u32 srcval;
4669 u32 res_lo,res_hi;
4670
4671 destreg = DECODE_RM_LONG_REGISTER(rh);
4672 DECODE_PRINTF(",");
4673 srcoffset = decode_rm10_address(rl);
4674 srcval = fetch_data_long(srcoffset);
4675 imm = fetch_byte_imm();
4676 DECODE_PRINTF2(",%d\n", (s32)imm);
4677 TRACE_AND_STEP();
4678 imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
4679 if (res_hi != 0) {
4680 SET_FLAG(F_CF);
4681 SET_FLAG(F_OF);
4682 } else {
4683 CLEAR_FLAG(F_CF);
4684 CLEAR_FLAG(F_OF);
4685 }
4686 *destreg = (u32)res_lo;
4687 } else {
4688 u16 *destreg;
4689 u16 srcval;
4690 u32 res;
4691
4692 destreg = DECODE_RM_WORD_REGISTER(rh);
4693 DECODE_PRINTF(",");
4694 srcoffset = decode_rm10_address(rl);
4695 srcval = fetch_data_word(srcoffset);
4696 imm = fetch_byte_imm();
4697 DECODE_PRINTF2(",%d\n", (s32)imm);
4698 TRACE_AND_STEP();
4699 res = (s16)srcval * (s16)imm;
4700 if (res > 0xFFFF) {
4701 SET_FLAG(F_CF);
4702 SET_FLAG(F_OF);
4703 } else {
4704 CLEAR_FLAG(F_CF);
4705 CLEAR_FLAG(F_OF);
4706 }
4707 *destreg = (u16)res;
4708 }
4709 break;
4710 case 3: /* register to register */
4711 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4712 u32 *destreg,*srcreg;
4713 u32 res_lo,res_hi;
4714
4715 destreg = DECODE_RM_LONG_REGISTER(rh);
4716 DECODE_PRINTF(",");
4717 srcreg = DECODE_RM_LONG_REGISTER(rl);
4718 imm = fetch_byte_imm();
4719 DECODE_PRINTF2(",%d\n", (s32)imm);
4720 TRACE_AND_STEP();
4721 imul_long_direct(&res_lo,&res_hi,(s32)*srcreg,(s32)imm);
4722 if (res_hi != 0) {
4723 SET_FLAG(F_CF);
4724 SET_FLAG(F_OF);
4725 } else {
4726 CLEAR_FLAG(F_CF);
4727 CLEAR_FLAG(F_OF);
4728 }
4729 *destreg = (u32)res_lo;
4730 } else {
4731 u16 *destreg,*srcreg;
4732 u32 res;
4733
4734 destreg = DECODE_RM_WORD_REGISTER(rh);
4735 DECODE_PRINTF(",");
4736 srcreg = DECODE_RM_WORD_REGISTER(rl);
4737 imm = fetch_byte_imm();
4738 DECODE_PRINTF2(",%d\n", (s32)imm);
4739 res = (s16)*srcreg * (s16)imm;
4740 if (res > 0xFFFF) {
4741 SET_FLAG(F_CF);
4742 SET_FLAG(F_OF);
4743 } else {
4744 CLEAR_FLAG(F_CF);
4745 CLEAR_FLAG(F_OF);
4746 }
4747 *destreg = (u16)res;
4748 }
4749 break;
4750 }
4751 DECODE_CLEAR_SEGOVR();
4752 END_OF_INSTR();
4753 }
4754
4755 /****************************************************************************
4756 REMARKS:
4757 Handles opcode 0x6c
4758 ****************************************************************************/
4759 static void x86emuOp_ins_byte(u8 X86EMU_UNUSED(op1))
4760 {
4761 START_OF_INSTR();
4762 DECODE_PRINTF("INSB\n");
4763 ins(1);
4764 TRACE_AND_STEP();
4765 DECODE_CLEAR_SEGOVR();
4766 END_OF_INSTR();
4767 }
4768
4769 /****************************************************************************
4770 REMARKS:
4771 Handles opcode 0x6d
4772 ****************************************************************************/
4773 static void x86emuOp_ins_word(u8 X86EMU_UNUSED(op1))
4774 {
4775 START_OF_INSTR();
4776 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4777 DECODE_PRINTF("INSD\n");
4778 ins(4);
4779 } else {
4780 DECODE_PRINTF("INSW\n");
4781 ins(2);
4782 }
4783 TRACE_AND_STEP();
4784 DECODE_CLEAR_SEGOVR();
4785 END_OF_INSTR();
4786 }
4787
4788 /****************************************************************************
4789 REMARKS:
4790 Handles opcode 0x6e
4791 ****************************************************************************/
4792 static void x86emuOp_outs_byte(u8 X86EMU_UNUSED(op1))
4793 {
4794 START_OF_INSTR();
4795 DECODE_PRINTF("OUTSB\n");
4796 outs(1);
4797 TRACE_AND_STEP();
4798 DECODE_CLEAR_SEGOVR();
4799 END_OF_INSTR();
4800 }
4801
4802 /****************************************************************************
4803 REMARKS:
4804 Handles opcode 0x6f
4805 ****************************************************************************/
4806 static void x86emuOp_outs_word(u8 X86EMU_UNUSED(op1))
4807 {
4808 START_OF_INSTR();
4809 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4810 DECODE_PRINTF("OUTSD\n");
4811 outs(4);
4812 } else {
4813 DECODE_PRINTF("OUTSW\n");
4814 outs(2);
4815 }
4816 TRACE_AND_STEP();
4817 DECODE_CLEAR_SEGOVR();
4818 END_OF_INSTR();
4819 }
4820
4821 /****************************************************************************
4822 REMARKS:
4823 Handles opcode 0x70
4824 ****************************************************************************/
4825 static void x86emuOp_jump_near_O(u8 X86EMU_UNUSED(op1))
4826 {
4827 s8 offset;
4828 u16 target;
4829
4830 /* jump to byte offset if overflow flag is set */
4831 START_OF_INSTR();
4832 DECODE_PRINTF("JO\t");
4833 offset = (s8)fetch_byte_imm();
4834 target = (u16)(M.x86.R_IP + (s16)offset);
4835 DECODE_PRINTF2("%x\n", target);
4836 TRACE_AND_STEP();
4837 if (ACCESS_FLAG(F_OF))
4838 M.x86.R_IP = target;
4839 DECODE_CLEAR_SEGOVR();
4840 END_OF_INSTR();
4841 }
4842
4843 /****************************************************************************
4844 REMARKS:
4845 Handles opcode 0x71
4846 ****************************************************************************/
4847 static void x86emuOp_jump_near_NO(u8 X86EMU_UNUSED(op1))
4848 {
4849 s8 offset;
4850 u16 target;
4851
4852 /* jump to byte offset if overflow is not set */
4853 START_OF_INSTR();
4854 DECODE_PRINTF("JNO\t");
4855 offset = (s8)fetch_byte_imm();
4856 target = (u16)(M.x86.R_IP + (s16)offset);
4857 DECODE_PRINTF2("%x\n", target);
4858 TRACE_AND_STEP();
4859 if (!ACCESS_FLAG(F_OF))
4860 M.x86.R_IP = target;
4861 DECODE_CLEAR_SEGOVR();
4862 END_OF_INSTR();
4863 }
4864
4865 /****************************************************************************
4866 REMARKS:
4867 Handles opcode 0x72
4868 ****************************************************************************/
4869 static void x86emuOp_jump_near_B(u8 X86EMU_UNUSED(op1))
4870 {
4871 s8 offset;
4872 u16 target;
4873
4874 /* jump to byte offset if carry flag is set. */
4875 START_OF_INSTR();
4876 DECODE_PRINTF("JB\t");
4877 offset = (s8)fetch_byte_imm();
4878 target = (u16)(M.x86.R_IP + (s16)offset);
4879 DECODE_PRINTF2("%x\n", target);
4880 TRACE_AND_STEP();
4881 if (ACCESS_FLAG(F_CF))
4882 M.x86.R_IP = target;
4883 DECODE_CLEAR_SEGOVR();
4884 END_OF_INSTR();
4885 }
4886
4887 /****************************************************************************
4888 REMARKS:
4889 Handles opcode 0x73
4890 ****************************************************************************/
4891 static void x86emuOp_jump_near_NB(u8 X86EMU_UNUSED(op1))
4892 {
4893 s8 offset;
4894 u16 target;
4895
4896 /* jump to byte offset if carry flag is clear. */
4897 START_OF_INSTR();
4898 DECODE_PRINTF("JNB\t");
4899 offset = (s8)fetch_byte_imm();
4900 target = (u16)(M.x86.R_IP + (s16)offset);
4901 DECODE_PRINTF2("%x\n", target);
4902 TRACE_AND_STEP();
4903 if (!ACCESS_FLAG(F_CF))
4904 M.x86.R_IP = target;
4905 DECODE_CLEAR_SEGOVR();
4906 END_OF_INSTR();
4907 }
4908
4909 /****************************************************************************
4910 REMARKS:
4911 Handles opcode 0x74
4912 ****************************************************************************/
4913 static void x86emuOp_jump_near_Z(u8 X86EMU_UNUSED(op1))
4914 {
4915 s8 offset;
4916 u16 target;
4917
4918 /* jump to byte offset if zero flag is set. */
4919 START_OF_INSTR();
4920 DECODE_PRINTF("JZ\t");
4921 offset = (s8)fetch_byte_imm();
4922 target = (u16)(M.x86.R_IP + (s16)offset);
4923 DECODE_PRINTF2("%x\n", target);
4924 TRACE_AND_STEP();
4925 if (ACCESS_FLAG(F_ZF))
4926 M.x86.R_IP = target;
4927 DECODE_CLEAR_SEGOVR();
4928 END_OF_INSTR();
4929 }
4930
4931 /****************************************************************************
4932 REMARKS:
4933 Handles opcode 0x75
4934 ****************************************************************************/
4935 static void x86emuOp_jump_near_NZ(u8 X86EMU_UNUSED(op1))
4936 {
4937 s8 offset;
4938 u16 target;
4939
4940 /* jump to byte offset if zero flag is clear. */
4941 START_OF_INSTR();
4942 DECODE_PRINTF("JNZ\t");
4943 offset = (s8)fetch_byte_imm();
4944 target = (u16)(M.x86.R_IP + (s16)offset);
4945 DECODE_PRINTF2("%x\n", target);
4946 TRACE_AND_STEP();
4947 if (!ACCESS_FLAG(F_ZF))
4948 M.x86.R_IP = target;
4949 DECODE_CLEAR_SEGOVR();
4950 END_OF_INSTR();
4951 }
4952
4953 /****************************************************************************
4954 REMARKS:
4955 Handles opcode 0x76
4956 ****************************************************************************/
4957 static void x86emuOp_jump_near_BE(u8 X86EMU_UNUSED(op1))
4958 {
4959 s8 offset;
4960 u16 target;
4961
4962 /* jump to byte offset if carry flag is set or if the zero
4963 flag is set. */
4964 START_OF_INSTR();
4965 DECODE_PRINTF("JBE\t");
4966 offset = (s8)fetch_byte_imm();
4967 target = (u16)(M.x86.R_IP + (s16)offset);
4968 DECODE_PRINTF2("%x\n", target);
4969 TRACE_AND_STEP();
4970 if (ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF))
4971 M.x86.R_IP = target;
4972 DECODE_CLEAR_SEGOVR();
4973 END_OF_INSTR();
4974 }
4975
4976 /****************************************************************************
4977 REMARKS:
4978 Handles opcode 0x77
4979 ****************************************************************************/
4980 static void x86emuOp_jump_near_NBE(u8 X86EMU_UNUSED(op1))
4981 {
4982 s8 offset;
4983 u16 target;
4984
4985 /* jump to byte offset if carry flag is clear and if the zero
4986 flag is clear */
4987 START_OF_INSTR();
4988 DECODE_PRINTF("JNBE\t");
4989 offset = (s8)fetch_byte_imm();
4990 target = (u16)(M.x86.R_IP + (s16)offset);
4991 DECODE_PRINTF2("%x\n", target);
4992 TRACE_AND_STEP();
4993 if (!(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF)))
4994 M.x86.R_IP = target;
4995 DECODE_CLEAR_SEGOVR();
4996 END_OF_INSTR();
4997 }
4998
4999 /****************************************************************************
5000 REMARKS:
5001 Handles opcode 0x78
5002 ****************************************************************************/
5003 static void x86emuOp_jump_near_S(u8 X86EMU_UNUSED(op1))
5004 {
5005 s8 offset;
5006 u16 target;
5007
5008 /* jump to byte offset if sign flag is set */
5009 START_OF_INSTR();
5010 DECODE_PRINTF("JS\t");
5011 offset = (s8)fetch_byte_imm();
5012 target = (u16)(M.x86.R_IP + (s16)offset);
5013 DECODE_PRINTF2("%x\n", target);
5014 TRACE_AND_STEP();
5015 if (ACCESS_FLAG(F_SF))
5016 M.x86.R_IP = target;
5017 DECODE_CLEAR_SEGOVR();
5018 END_OF_INSTR();
5019 }
5020
5021 /****************************************************************************
5022 REMARKS:
5023 Handles opcode 0x79
5024 ****************************************************************************/
5025 static void x86emuOp_jump_near_NS(u8 X86EMU_UNUSED(op1))
5026 {
5027 s8 offset;
5028 u16 target;
5029
5030 /* jump to byte offset if sign flag is clear */
5031 START_OF_INSTR();
5032 DECODE_PRINTF("JNS\t");
5033 offset = (s8)fetch_byte_imm();
5034 target = (u16)(M.x86.R_IP + (s16)offset);
5035 DECODE_PRINTF2("%x\n", target);
5036 TRACE_AND_STEP();
5037 if (!ACCESS_FLAG(F_SF))
5038 M.x86.R_IP = target;
5039 DECODE_CLEAR_SEGOVR();
5040 END_OF_INSTR();
5041 }
5042
5043 /****************************************************************************
5044 REMARKS:
5045 Handles opcode 0x7a
5046 ****************************************************************************/
5047 static void x86emuOp_jump_near_P(u8 X86EMU_UNUSED(op1))
5048 {
5049 s8 offset;
5050 u16 target;
5051
5052 /* jump to byte offset if parity flag is set (even parity) */
5053 START_OF_INSTR();
5054 DECODE_PRINTF("JP\t");
5055 offset = (s8)fetch_byte_imm();
5056 target = (u16)(M.x86.R_IP + (s16)offset);
5057 DECODE_PRINTF2("%x\n", target);
5058 TRACE_AND_STEP();
5059 if (ACCESS_FLAG(F_PF))
5060 M.x86.R_IP = target;
5061 DECODE_CLEAR_SEGOVR();
5062 END_OF_INSTR();
5063 }
5064
5065 /****************************************************************************
5066 REMARKS:
5067 Handles opcode 0x7b
5068 ****************************************************************************/
5069 static void x86emuOp_jump_near_NP(u8 X86EMU_UNUSED(op1))
5070 {
5071 s8 offset;
5072 u16 target;
5073
5074 /* jump to byte offset if parity flag is clear (odd parity) */
5075 START_OF_INSTR();
5076 DECODE_PRINTF("JNP\t");
5077 offset = (s8)fetch_byte_imm();
5078 target = (u16)(M.x86.R_IP + (s16)offset);
5079 DECODE_PRINTF2("%x\n", target);
5080 TRACE_AND_STEP();
5081 if (!ACCESS_FLAG(F_PF))
5082 M.x86.R_IP = target;
5083 DECODE_CLEAR_SEGOVR();
5084 END_OF_INSTR();
5085 }
5086
5087 /****************************************************************************
5088 REMARKS:
5089 Handles opcode 0x7c
5090 ****************************************************************************/
5091 static void x86emuOp_jump_near_L(u8 X86EMU_UNUSED(op1))
5092 {
5093 s8 offset;
5094 u16 target;
5095 int sf, of;
5096
5097 /* jump to byte offset if sign flag not equal to overflow flag. */
5098 START_OF_INSTR();
5099 DECODE_PRINTF("JL\t");
5100 offset = (s8)fetch_byte_imm();
5101 target = (u16)(M.x86.R_IP + (s16)offset);
5102 DECODE_PRINTF2("%x\n", target);
5103 TRACE_AND_STEP();
5104 sf = ACCESS_FLAG(F_SF) != 0;
5105 of = ACCESS_FLAG(F_OF) != 0;
5106 if (sf ^ of)
5107 M.x86.R_IP = target;
5108 DECODE_CLEAR_SEGOVR();
5109 END_OF_INSTR();
5110 }
5111
5112 /****************************************************************************
5113 REMARKS:
5114 Handles opcode 0x7d
5115 ****************************************************************************/
5116 static void x86emuOp_jump_near_NL(u8 X86EMU_UNUSED(op1))
5117 {
5118 s8 offset;
5119 u16 target;
5120 int sf, of;
5121
5122 /* jump to byte offset if sign flag not equal to overflow flag. */
5123 START_OF_INSTR();
5124 DECODE_PRINTF("JNL\t");
5125 offset = (s8)fetch_byte_imm();
5126 target = (u16)(M.x86.R_IP + (s16)offset);
5127 DECODE_PRINTF2("%x\n", target);
5128 TRACE_AND_STEP();
5129 sf = ACCESS_FLAG(F_SF) != 0;
5130 of = ACCESS_FLAG(F_OF) != 0;
5131 /* note: inverse of above, but using == instead of xor. */
5132 if (sf == of)
5133 M.x86.R_IP = target;
5134 DECODE_CLEAR_SEGOVR();
5135 END_OF_INSTR();
5136 }
5137
5138 /****************************************************************************
5139 REMARKS:
5140 Handles opcode 0x7e
5141 ****************************************************************************/
5142 static void x86emuOp_jump_near_LE(u8 X86EMU_UNUSED(op1))
5143 {
5144 s8 offset;
5145 u16 target;
5146 int sf, of;
5147
5148 /* jump to byte offset if sign flag not equal to overflow flag
5149 or the zero flag is set */
5150 START_OF_INSTR();
5151 DECODE_PRINTF("JLE\t");
5152 offset = (s8)fetch_byte_imm();
5153 target = (u16)(M.x86.R_IP + (s16)offset);
5154 DECODE_PRINTF2("%x\n", target);
5155 TRACE_AND_STEP();
5156 sf = ACCESS_FLAG(F_SF) != 0;
5157 of = ACCESS_FLAG(F_OF) != 0;
5158 if ((sf ^ of) || ACCESS_FLAG(F_ZF))
5159 M.x86.R_IP = target;
5160 DECODE_CLEAR_SEGOVR();
5161 END_OF_INSTR();
5162 }
5163
5164 /****************************************************************************
5165 REMARKS:
5166 Handles opcode 0x7f
5167 ****************************************************************************/
5168 static void x86emuOp_jump_near_NLE(u8 X86EMU_UNUSED(op1))
5169 {
5170 s8 offset;
5171 u16 target;
5172 int sf, of;
5173
5174 /* jump to byte offset if sign flag equal to overflow flag.
5175 and the zero flag is clear */
5176 START_OF_INSTR();
5177 DECODE_PRINTF("JNLE\t");
5178 offset = (s8)fetch_byte_imm();
5179 target = (u16)(M.x86.R_IP + (s16)offset);
5180 DECODE_PRINTF2("%x\n", target);
5181 TRACE_AND_STEP();
5182 sf = ACCESS_FLAG(F_SF) != 0;
5183 of = ACCESS_FLAG(F_OF) != 0;
5184 if ((sf == of) && !ACCESS_FLAG(F_ZF))
5185 M.x86.R_IP = target;
5186 DECODE_CLEAR_SEGOVR();
5187 END_OF_INSTR();
5188 }
5189
5190 static u8 (*opc80_byte_operation[])(u8 d, u8 s) =
5191 {
5192 add_byte, /* 00 */
5193 or_byte, /* 01 */
5194 adc_byte, /* 02 */
5195 sbb_byte, /* 03 */
5196 and_byte, /* 04 */
5197 sub_byte, /* 05 */
5198 xor_byte, /* 06 */
5199 cmp_byte, /* 07 */
5200 };
5201
5202 /****************************************************************************
5203 REMARKS:
5204 Handles opcode 0x80
5205 ****************************************************************************/
5206 static void x86emuOp_opc80_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
5207 {
5208 int mod, rl, rh;
5209 u8 *destreg;
5210 uint destoffset;
5211 u8 imm;
5212 u8 destval;
5213
5214 /*
5215 * Weirdo special case instruction format. Part of the opcode
5216 * held below in "RH". Doubly nested case would result, except
5217 * that the decoded instruction
5218 */
5219 START_OF_INSTR();
5220 FETCH_DECODE_MODRM(mod, rh, rl);
5221 #ifdef DEBUG
5222 if (DEBUG_DECODE()) {
5223 /* XXX DECODE_PRINTF may be changed to something more
5224 general, so that it is important to leave the strings
5225 in the same format, even though the result is that the
5226 above test is done twice. */
5227
5228 switch (rh) {
5229 case 0:
5230 DECODE_PRINTF("ADD\t");
5231 break;
5232 case 1:
5233 DECODE_PRINTF("OR\t");
5234 break;
5235 case 2:
5236 DECODE_PRINTF("ADC\t");
5237 break;
5238 case 3:
5239 DECODE_PRINTF("SBB\t");
5240 break;
5241 case 4:
5242 DECODE_PRINTF("AND\t");
5243 break;
5244 case 5:
5245 DECODE_PRINTF("SUB\t");
5246 break;
5247 case 6:
5248 DECODE_PRINTF("XOR\t");
5249 break;
5250 case 7:
5251 DECODE_PRINTF("CMP\t");
5252 break;
5253 }
5254 }
5255 #endif
5256 /* know operation, decode the mod byte to find the addressing
5257 mode. */
5258 switch (mod) {
5259 case 0:
5260 DECODE_PRINTF("BYTE PTR ");
5261 destoffset = decode_rm00_address(rl);
5262 DECODE_PRINTF(",");
5263 destval = fetch_data_byte(destoffset);
5264 imm = fetch_byte_imm();
5265 DECODE_PRINTF2("%x\n", imm);
5266 TRACE_AND_STEP();
5267 destval = (*opc80_byte_operation[rh]) (destval, imm);
5268 if (rh != 7)
5269 store_data_byte(destoffset, destval);
5270 break;
5271 case 1:
5272 DECODE_PRINTF("BYTE PTR ");
5273 destoffset = decode_rm01_address(rl);
5274 DECODE_PRINTF(",");
5275 destval = fetch_data_byte(destoffset);
5276 imm = fetch_byte_imm();
5277 DECODE_PRINTF2("%x\n", imm);
5278 TRACE_AND_STEP();
5279 destval = (*opc80_byte_operation[rh]) (destval, imm);
5280 if (rh != 7)
5281 store_data_byte(destoffset, destval);
5282 break;
5283 case 2:
5284 DECODE_PRINTF("BYTE PTR ");
5285 destoffset = decode_rm10_address(rl);
5286 DECODE_PRINTF(",");
5287 destval = fetch_data_byte(destoffset);
5288 imm = fetch_byte_imm();
5289 DECODE_PRINTF2("%x\n", imm);
5290 TRACE_AND_STEP();
5291 destval = (*opc80_byte_operation[rh]) (destval, imm);
5292 if (rh != 7)
5293 store_data_byte(destoffset, destval);
5294 break;
5295 case 3: /* register to register */
5296 destreg = DECODE_RM_BYTE_REGISTER(rl);
5297 DECODE_PRINTF(",");
5298 imm = fetch_byte_imm();
5299 DECODE_PRINTF2("%x\n", imm);
5300 TRACE_AND_STEP();
5301 destval = (*opc80_byte_operation[rh]) (*destreg, imm);
5302 if (rh != 7)
5303 *destreg = destval;
5304 break;
5305 }
5306 DECODE_CLEAR_SEGOVR();
5307 END_OF_INSTR();
5308 }
5309
5310 static u16 (*opc81_word_operation[])(u16 d, u16 s) =
5311 {
5312 add_word, /*00 */
5313 or_word, /*01 */
5314 adc_word, /*02 */
5315 sbb_word, /*03 */
5316 and_word, /*04 */
5317 sub_word, /*05 */
5318 xor_word, /*06 */
5319 cmp_word, /*07 */
5320 };
5321
5322 static u32 (*opc81_long_operation[])(u32 d, u32 s) =
5323 {
5324 add_long, /*00 */
5325 or_long, /*01 */
5326 adc_long, /*02 */
5327 sbb_long, /*03 */
5328 and_long, /*04 */
5329 sub_long, /*05 */
5330 xor_long, /*06 */
5331 cmp_long, /*07 */
5332 };
5333
5334 /****************************************************************************
5335 REMARKS:
5336 Handles opcode 0x81
5337 ****************************************************************************/
5338 static void x86emuOp_opc81_word_RM_IMM(u8 X86EMU_UNUSED(op1))
5339 {
5340 int mod, rl, rh;
5341 uint destoffset;
5342
5343 /*
5344 * Weirdo special case instruction format. Part of the opcode
5345 * held below in "RH". Doubly nested case would result, except
5346 * that the decoded instruction
5347 */
5348 START_OF_INSTR();
5349 FETCH_DECODE_MODRM(mod, rh, rl);
5350 #ifdef DEBUG
5351 if (DEBUG_DECODE()) {
5352 /* XXX DECODE_PRINTF may be changed to something more
5353 general, so that it is important to leave the strings
5354 in the same format, even though the result is that the
5355 above test is done twice. */
5356
5357 switch (rh) {
5358 case 0:
5359 DECODE_PRINTF("ADD\t");
5360 break;
5361 case 1:
5362 DECODE_PRINTF("OR\t");
5363 break;
5364 case 2:
5365 DECODE_PRINTF("ADC\t");
5366 break;
5367 case 3:
5368 DECODE_PRINTF("SBB\t");
5369 break;
5370 case 4:
5371 DECODE_PRINTF("AND\t");
5372 break;
5373 case 5:
5374 DECODE_PRINTF("SUB\t");
5375 break;
5376 case 6:
5377 DECODE_PRINTF("XOR\t");
5378 break;
5379 case 7:
5380 DECODE_PRINTF("CMP\t");
5381 break;
5382 }
5383 }
5384 #endif
5385 /*
5386 * Know operation, decode the mod byte to find the addressing
5387 * mode.
5388 */
5389 switch (mod) {
5390 case 0:
5391 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5392 u32 destval,imm;
5393
5394 DECODE_PRINTF("DWORD PTR ");
5395 destoffset = decode_rm00_address(rl);
5396 DECODE_PRINTF(",");
5397 destval = fetch_data_long(destoffset);
5398 imm = fetch_long_imm();
5399 DECODE_PRINTF2("%x\n", imm);
5400 TRACE_AND_STEP();
5401 destval = (*opc81_long_operation[rh]) (destval, imm);
5402 if (rh != 7)
5403 store_data_long(destoffset, destval);
5404 } else {
5405 u16 destval,imm;
5406
5407 DECODE_PRINTF("WORD PTR ");
5408 destoffset = decode_rm00_address(rl);
5409 DECODE_PRINTF(",");
5410 destval = fetch_data_word(destoffset);
5411 imm = fetch_word_imm();
5412 DECODE_PRINTF2("%x\n", imm);
5413 TRACE_AND_STEP();
5414 destval = (*opc81_word_operation[rh]) (destval, imm);
5415 if (rh != 7)
5416 store_data_word(destoffset, destval);
5417 }
5418 break;
5419 case 1:
5420 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5421 u32 destval,imm;
5422
5423 DECODE_PRINTF("DWORD PTR ");
5424 destoffset = decode_rm01_address(rl);
5425 DECODE_PRINTF(",");
5426 destval = fetch_data_long(destoffset);
5427 imm = fetch_long_imm();
5428 DECODE_PRINTF2("%x\n", imm);
5429 TRACE_AND_STEP();
5430 destval = (*opc81_long_operation[rh]) (destval, imm);
5431 if (rh != 7)
5432 store_data_long(destoffset, destval);
5433 } else {
5434 u16 destval,imm;
5435
5436 DECODE_PRINTF("WORD PTR ");
5437 destoffset = decode_rm01_address(rl);
5438 DECODE_PRINTF(",");
5439 destval = fetch_data_word(destoffset);
5440 imm = fetch_word_imm();
5441 DECODE_PRINTF2("%x\n", imm);
5442 TRACE_AND_STEP();
5443 destval = (*opc81_word_operation[rh]) (destval, imm);
5444 if (rh != 7)
5445 store_data_word(destoffset, destval);
5446 }
5447 break;
5448 case 2:
5449 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5450 u32 destval,imm;
5451
5452 DECODE_PRINTF("DWORD PTR ");
5453 destoffset = decode_rm10_address(rl);
5454 DECODE_PRINTF(",");
5455 destval = fetch_data_long(destoffset);
5456 imm = fetch_long_imm();
5457 DECODE_PRINTF2("%x\n", imm);
5458 TRACE_AND_STEP();
5459 destval = (*opc81_long_operation[rh]) (destval, imm);
5460 if (rh != 7)
5461 store_data_long(destoffset, destval);
5462 } else {
5463 u16 destval,imm;
5464
5465 DECODE_PRINTF("WORD PTR ");
5466 destoffset = decode_rm10_address(rl);
5467 DECODE_PRINTF(",");
5468 destval = fetch_data_word(destoffset);
5469 imm = fetch_word_imm();
5470 DECODE_PRINTF2("%x\n", imm);
5471 TRACE_AND_STEP();
5472 destval = (*opc81_word_operation[rh]) (destval, imm);
5473 if (rh != 7)
5474 store_data_word(destoffset, destval);
5475 }
5476 break;
5477 case 3: /* register to register */
5478 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5479 u32 *destreg;
5480 u32 destval,imm;
5481
5482 destreg = DECODE_RM_LONG_REGISTER(rl);
5483 DECODE_PRINTF(",");
5484 imm = fetch_long_imm();
5485 DECODE_PRINTF2("%x\n", imm);
5486 TRACE_AND_STEP();
5487 destval = (*opc81_long_operation[rh]) (*destreg, imm);
5488 if (rh != 7)
5489 *destreg = destval;
5490 } else {
5491 u16 *destreg;
5492 u16 destval,imm;
5493
5494 destreg = DECODE_RM_WORD_REGISTER(rl);
5495 DECODE_PRINTF(",");
5496 imm = fetch_word_imm();
5497 DECODE_PRINTF2("%x\n", imm);
5498 TRACE_AND_STEP();
5499 destval = (*opc81_word_operation[rh]) (*destreg, imm);
5500 if (rh != 7)
5501 *destreg = destval;
5502 }
5503 break;
5504 }
5505 DECODE_CLEAR_SEGOVR();
5506 END_OF_INSTR();
5507 }
5508
5509 static u8 (*opc82_byte_operation[])(u8 s, u8 d) =
5510 {
5511 add_byte, /*00 */
5512 or_byte, /*01 *//*YYY UNUSED ???? */
5513 adc_byte, /*02 */
5514 sbb_byte, /*03 */
5515 and_byte, /*04 *//*YYY UNUSED ???? */
5516 sub_byte, /*05 */
5517 xor_byte, /*06 *//*YYY UNUSED ???? */
5518 cmp_byte, /*07 */
5519 };
5520
5521 /****************************************************************************
5522 REMARKS:
5523 Handles opcode 0x82
5524 ****************************************************************************/
5525 static void x86emuOp_opc82_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
5526 {
5527 int mod, rl, rh;
5528 u8 *destreg;
5529 uint destoffset;
5530 u8 imm;
5531 u8 destval;
5532
5533 /*
5534 * Weirdo special case instruction format. Part of the opcode
5535 * held below in "RH". Doubly nested case would result, except
5536 * that the decoded instruction Similar to opcode 81, except that
5537 * the immediate byte is sign extended to a word length.
5538 */
5539 START_OF_INSTR();
5540 FETCH_DECODE_MODRM(mod, rh, rl);
5541 #ifdef DEBUG
5542 if (DEBUG_DECODE()) {
5543 /* XXX DECODE_PRINTF may be changed to something more
5544 general, so that it is important to leave the strings
5545 in the same format, even though the result is that the
5546 above test is done twice. */
5547 switch (rh) {
5548 case 0:
5549 DECODE_PRINTF("ADD\t");
5550 break;
5551 case 1:
5552 DECODE_PRINTF("OR\t");
5553 break;
5554 case 2:
5555 DECODE_PRINTF("ADC\t");
5556 break;
5557 case 3:
5558 DECODE_PRINTF("SBB\t");
5559 break;
5560 case 4:
5561 DECODE_PRINTF("AND\t");
5562 break;
5563 case 5:
5564 DECODE_PRINTF("SUB\t");
5565 break;
5566 case 6:
5567 DECODE_PRINTF("XOR\t");
5568 break;
5569 case 7:
5570 DECODE_PRINTF("CMP\t");
5571 break;
5572 }
5573 }
5574 #endif
5575 /* know operation, decode the mod byte to find the addressing
5576 mode. */
5577 switch (mod) {
5578 case 0:
5579 DECODE_PRINTF("BYTE PTR ");
5580 destoffset = decode_rm00_address(rl);
5581 destval = fetch_data_byte(destoffset);
5582 imm = fetch_byte_imm();
5583 DECODE_PRINTF2(",%x\n", imm);
5584 TRACE_AND_STEP();
5585 destval = (*opc82_byte_operation[rh]) (destval, imm);
5586 if (rh != 7)
5587 store_data_byte(destoffset, destval);
5588 break;
5589 case 1:
5590 DECODE_PRINTF("BYTE PTR ");
5591 destoffset = decode_rm01_address(rl);
5592 destval = fetch_data_byte(destoffset);
5593 imm = fetch_byte_imm();
5594 DECODE_PRINTF2(",%x\n", imm);
5595 TRACE_AND_STEP();
5596 destval = (*opc82_byte_operation[rh]) (destval, imm);
5597 if (rh != 7)
5598 store_data_byte(destoffset, destval);
5599 break;
5600 case 2:
5601 DECODE_PRINTF("BYTE PTR ");
5602 destoffset = decode_rm10_address(rl);
5603 destval = fetch_data_byte(destoffset);
5604 imm = fetch_byte_imm();
5605 DECODE_PRINTF2(",%x\n", imm);
5606 TRACE_AND_STEP();
5607 destval = (*opc82_byte_operation[rh]) (destval, imm);
5608 if (rh != 7)
5609 store_data_byte(destoffset, destval);
5610 break;
5611 case 3: /* register to register */
5612 destreg = DECODE_RM_BYTE_REGISTER(rl);
5613 imm = fetch_byte_imm();
5614 DECODE_PRINTF2(",%x\n", imm);
5615 TRACE_AND_STEP();
5616 destval = (*opc82_byte_operation[rh]) (*destreg, imm);
5617 if (rh != 7)
5618 *destreg = destval;
5619 break;
5620 }
5621 DECODE_CLEAR_SEGOVR();
5622 END_OF_INSTR();
5623 }
5624
5625 static u16 (*opc83_word_operation[])(u16 s, u16 d) =
5626 {
5627 add_word, /*00 */
5628 or_word, /*01 *//*YYY UNUSED ???? */
5629 adc_word, /*02 */
5630 sbb_word, /*03 */
5631 and_word, /*04 *//*YYY UNUSED ???? */
5632 sub_word, /*05 */
5633 xor_word, /*06 *//*YYY UNUSED ???? */
5634 cmp_word, /*07 */
5635 };
5636
5637 static u32 (*opc83_long_operation[])(u32 s, u32 d) =
5638 {
5639 add_long, /*00 */
5640 or_long, /*01 *//*YYY UNUSED ???? */
5641 adc_long, /*02 */
5642 sbb_long, /*03 */
5643 and_long, /*04 *//*YYY UNUSED ???? */
5644 sub_long, /*05 */
5645 xor_long, /*06 *//*YYY UNUSED ???? */
5646 cmp_long, /*07 */
5647 };
5648
5649 /****************************************************************************
5650 REMARKS:
5651 Handles opcode 0x83
5652 ****************************************************************************/
5653 static void x86emuOp_opc83_word_RM_IMM(u8 X86EMU_UNUSED(op1))
5654 {
5655 int mod, rl, rh;
5656 uint destoffset;
5657
5658 /*
5659 * Weirdo special case instruction format. Part of the opcode
5660 * held below in "RH". Doubly nested case would result, except
5661 * that the decoded instruction Similar to opcode 81, except that
5662 * the immediate byte is sign extended to a word length.
5663 */
5664 START_OF_INSTR();
5665 FETCH_DECODE_MODRM(mod, rh, rl);
5666 #ifdef DEBUG
5667 if (DEBUG_DECODE()) {
5668 /* XXX DECODE_PRINTF may be changed to something more
5669 general, so that it is important to leave the strings
5670 in the same format, even though the result is that the
5671 above test is done twice. */
5672 switch (rh) {
5673 case 0:
5674 DECODE_PRINTF("ADD\t");
5675 break;
5676 case 1:
5677 DECODE_PRINTF("OR\t");
5678 break;
5679 case 2:
5680 DECODE_PRINTF("ADC\t");
5681 break;
5682 case 3:
5683 DECODE_PRINTF("SBB\t");
5684 break;
5685 case 4:
5686 DECODE_PRINTF("AND\t");
5687 break;
5688 case 5:
5689 DECODE_PRINTF("SUB\t");
5690 break;
5691 case 6:
5692 DECODE_PRINTF("XOR\t");
5693 break;
5694 case 7:
5695 DECODE_PRINTF("CMP\t");
5696 break;
5697 }
5698 }
5699 #endif
5700 /* know operation, decode the mod byte to find the addressing
5701 mode. */
5702 switch (mod) {
5703 case 0:
5704 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5705 u32 destval,imm;
5706
5707 DECODE_PRINTF("DWORD PTR ");
5708 destoffset = decode_rm00_address(rl);
5709 destval = fetch_data_long(destoffset);
5710 imm = (s8) fetch_byte_imm();
5711 DECODE_PRINTF2(",%x\n", imm);
5712 TRACE_AND_STEP();
5713 destval = (*opc83_long_operation[rh]) (destval, imm);
5714 if (rh != 7)
5715 store_data_long(destoffset, destval);
5716 } else {
5717 u16 destval,imm;
5718
5719 DECODE_PRINTF("WORD PTR ");
5720 destoffset = decode_rm00_address(rl);
5721 destval = fetch_data_word(destoffset);
5722 imm = (s8) fetch_byte_imm();
5723 DECODE_PRINTF2(",%x\n", imm);
5724 TRACE_AND_STEP();
5725 destval = (*opc83_word_operation[rh]) (destval, imm);
5726 if (rh != 7)
5727 store_data_word(destoffset, destval);
5728 }
5729 break;
5730 case 1:
5731 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5732 u32 destval,imm;
5733
5734 DECODE_PRINTF("DWORD PTR ");
5735 destoffset = decode_rm01_address(rl);
5736 destval = fetch_data_long(destoffset);
5737 imm = (s8) fetch_byte_imm();
5738 DECODE_PRINTF2(",%x\n", imm);
5739 TRACE_AND_STEP();
5740 destval = (*opc83_long_operation[rh]) (destval, imm);
5741 if (rh != 7)
5742 store_data_long(destoffset, destval);
5743 } else {
5744 u16 destval,imm;
5745
5746 DECODE_PRINTF("WORD PTR ");
5747 destoffset = decode_rm01_address(rl);
5748 destval = fetch_data_word(destoffset);
5749 imm = (s8) fetch_byte_imm();
5750 DECODE_PRINTF2(",%x\n", imm);
5751 TRACE_AND_STEP();
5752 destval = (*opc83_word_operation[rh]) (destval, imm);
5753 if (rh != 7)
5754 store_data_word(destoffset, destval);
5755 }
5756 break;
5757 case 2:
5758 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5759 u32 destval,imm;
5760
5761 DECODE_PRINTF("DWORD PTR ");
5762 destoffset = decode_rm10_address(rl);
5763 destval = fetch_data_long(destoffset);
5764 imm = (s8) fetch_byte_imm();
5765 DECODE_PRINTF2(",%x\n", imm);
5766 TRACE_AND_STEP();
5767 destval = (*opc83_long_operation[rh]) (destval, imm);
5768 if (rh != 7)
5769 store_data_long(destoffset, destval);
5770 } else {
5771 u16 destval,imm;
5772
5773 DECODE_PRINTF("WORD PTR ");
5774 destoffset = decode_rm10_address(rl);
5775 destval = fetch_data_word(destoffset);
5776 imm = (s8) fetch_byte_imm();
5777 DECODE_PRINTF2(",%x\n", imm);
5778 TRACE_AND_STEP();
5779 destval = (*opc83_word_operation[rh]) (destval, imm);
5780 if (rh != 7)
5781 store_data_word(destoffset, destval);
5782 }
5783 break;
5784 case 3: /* register to register */
5785 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5786 u32 *destreg;
5787 u32 destval,imm;
5788
5789 destreg = DECODE_RM_LONG_REGISTER(rl);
5790 imm = (s8) fetch_byte_imm();
5791 DECODE_PRINTF2(",%x\n", imm);
5792 TRACE_AND_STEP();
5793 destval = (*opc83_long_operation[rh]) (*destreg, imm);
5794 if (rh != 7)
5795 *destreg = destval;
5796 } else {
5797 u16 *destreg;
5798 u16 destval,imm;
5799
5800 destreg = DECODE_RM_WORD_REGISTER(rl);
5801 imm = (s8) fetch_byte_imm();
5802 DECODE_PRINTF2(",%x\n", imm);
5803 TRACE_AND_STEP();
5804 destval = (*opc83_word_operation[rh]) (*destreg, imm);
5805 if (rh != 7)
5806 *destreg = destval;
5807 }
5808 break;
5809 }
5810 DECODE_CLEAR_SEGOVR();
5811 END_OF_INSTR();
5812 }
5813
5814 /****************************************************************************
5815 REMARKS:
5816 Handles opcode 0x84
5817 ****************************************************************************/
5818 static void x86emuOp_test_byte_RM_R(u8 X86EMU_UNUSED(op1))
5819 {
5820 int mod, rl, rh;
5821 u8 *destreg, *srcreg;
5822 uint destoffset;
5823 u8 destval;
5824
5825 START_OF_INSTR();
5826 DECODE_PRINTF("TEST\t");
5827 FETCH_DECODE_MODRM(mod, rh, rl);
5828 switch (mod) {
5829 case 0:
5830 destoffset = decode_rm00_address(rl);
5831 DECODE_PRINTF(",");
5832 destval = fetch_data_byte(destoffset);
5833 srcreg = DECODE_RM_BYTE_REGISTER(rh);
5834 DECODE_PRINTF("\n");
5835 TRACE_AND_STEP();
5836 test_byte(destval, *srcreg);
5837 break;
5838 case 1:
5839 destoffset = decode_rm01_address(rl);
5840 DECODE_PRINTF(",");
5841 destval = fetch_data_byte(destoffset);
5842 srcreg = DECODE_RM_BYTE_REGISTER(rh);
5843 DECODE_PRINTF("\n");
5844 TRACE_AND_STEP();
5845 test_byte(destval, *srcreg);
5846 break;
5847 case 2:
5848 destoffset = decode_rm10_address(rl);
5849 DECODE_PRINTF(",");
5850 destval = fetch_data_byte(destoffset);
5851 srcreg = DECODE_RM_BYTE_REGISTER(rh);
5852 DECODE_PRINTF("\n");
5853 TRACE_AND_STEP();
5854 test_byte(destval, *srcreg);
5855 break;
5856 case 3: /* register to register */
5857 destreg = DECODE_RM_BYTE_REGISTER(rl);
5858 DECODE_PRINTF(",");
5859 srcreg = DECODE_RM_BYTE_REGISTER(rh);
5860 DECODE_PRINTF("\n");
5861 TRACE_AND_STEP();
5862 test_byte(*destreg, *srcreg);
5863 break;
5864 }
5865 DECODE_CLEAR_SEGOVR();
5866 END_OF_INSTR();
5867 }
5868
5869 /****************************************************************************
5870 REMARKS:
5871 Handles opcode 0x85
5872 ****************************************************************************/
5873 static void x86emuOp_test_word_RM_R(u8 X86EMU_UNUSED(op1))
5874 {
5875 int mod, rl, rh;
5876 uint destoffset;
5877
5878 START_OF_INSTR();
5879 DECODE_PRINTF("TEST\t");
5880 FETCH_DECODE_MODRM(mod, rh, rl);
5881 switch (mod) {
5882 case 0:
5883 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5884 u32 destval;
5885 u32 *srcreg;
5886
5887 destoffset = decode_rm00_address(rl);
5888 DECODE_PRINTF(",");
5889 destval = fetch_data_long(destoffset);
5890 srcreg = DECODE_RM_LONG_REGISTER(rh);
5891 DECODE_PRINTF("\n");
5892 TRACE_AND_STEP();
5893 test_long(destval, *srcreg);
5894 } else {
5895 u16 destval;
5896 u16 *srcreg;
5897
5898 destoffset = decode_rm00_address(rl);
5899 DECODE_PRINTF(",");
5900 destval = fetch_data_word(destoffset);
5901 srcreg = DECODE_RM_WORD_REGISTER(rh);
5902 DECODE_PRINTF("\n");
5903 TRACE_AND_STEP();
5904 test_word(destval, *srcreg);
5905 }
5906 break;
5907 case 1:
5908 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5909 u32 destval;
5910 u32 *srcreg;
5911
5912 destoffset = decode_rm01_address(rl);
5913 DECODE_PRINTF(",");
5914 destval = fetch_data_long(destoffset);
5915 srcreg = DECODE_RM_LONG_REGISTER(rh);
5916 DECODE_PRINTF("\n");
5917 TRACE_AND_STEP();
5918 test_long(destval, *srcreg);
5919 } else {
5920 u16 destval;
5921 u16 *srcreg;
5922
5923 destoffset = decode_rm01_address(rl);
5924 DECODE_PRINTF(",");
5925 destval = fetch_data_word(destoffset);
5926 srcreg = DECODE_RM_WORD_REGISTER(rh);
5927 DECODE_PRINTF("\n");
5928 TRACE_AND_STEP();
5929 test_word(destval, *srcreg);
5930 }
5931 break;
5932 case 2:
5933 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5934 u32 destval;
5935 u32 *srcreg;
5936
5937 destoffset = decode_rm10_address(rl);
5938 DECODE_PRINTF(",");
5939 destval = fetch_data_long(destoffset);
5940 srcreg = DECODE_RM_LONG_REGISTER(rh);
5941 DECODE_PRINTF("\n");
5942 TRACE_AND_STEP();
5943 test_long(destval, *srcreg);
5944 } else {
5945 u16 destval;
5946 u16 *srcreg;
5947
5948 destoffset = decode_rm10_address(rl);
5949 DECODE_PRINTF(",");
5950 destval = fetch_data_word(destoffset);
5951 srcreg = DECODE_RM_WORD_REGISTER(rh);
5952 DECODE_PRINTF("\n");
5953 TRACE_AND_STEP();
5954 test_word(destval, *srcreg);
5955 }
5956 break;
5957 case 3: /* register to register */
5958 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5959 u32 *destreg,*srcreg;
5960
5961 destreg = DECODE_RM_LONG_REGISTER(rl);
5962 DECODE_PRINTF(",");
5963 srcreg = DECODE_RM_LONG_REGISTER(rh);
5964 DECODE_PRINTF("\n");
5965 TRACE_AND_STEP();
5966 test_long(*destreg, *srcreg);
5967 } else {
5968 u16 *destreg,*srcreg;
5969
5970 destreg = DECODE_RM_WORD_REGISTER(rl);
5971 DECODE_PRINTF(",");
5972 srcreg = DECODE_RM_WORD_REGISTER(rh);
5973 DECODE_PRINTF("\n");
5974 TRACE_AND_STEP();
5975 test_word(*destreg, *srcreg);
5976 }
5977 break;
5978 }
5979 DECODE_CLEAR_SEGOVR();
5980 END_OF_INSTR();
5981 }
5982
5983 /****************************************************************************
5984 REMARKS:
5985 Handles opcode 0x86
5986 ****************************************************************************/
5987 static void x86emuOp_xchg_byte_RM_R(u8 X86EMU_UNUSED(op1))
5988 {
5989 int mod, rl, rh;
5990 u8 *destreg, *srcreg;
5991 uint destoffset;
5992 u8 destval;
5993 u8 tmp;
5994
5995 START_OF_INSTR();
5996 DECODE_PRINTF("XCHG\t");
5997 FETCH_DECODE_MODRM(mod, rh, rl);
5998 switch (mod) {
5999 case 0:
6000 destoffset = decode_rm00_address(rl);
6001 DECODE_PRINTF(",");
6002 destval = fetch_data_byte(destoffset);
6003 srcreg = DECODE_RM_BYTE_REGISTER(rh);
6004 DECODE_PRINTF("\n");
6005 TRACE_AND_STEP();
6006 tmp = *srcreg;
6007 *srcreg = destval;
6008 destval = tmp;
6009 store_data_byte(destoffset, destval);
6010 break;
6011 case 1:
6012 destoffset = decode_rm01_address(rl);
6013 DECODE_PRINTF(",");
6014 destval = fetch_data_byte(destoffset);
6015 srcreg = DECODE_RM_BYTE_REGISTER(rh);
6016 DECODE_PRINTF("\n");
6017 TRACE_AND_STEP();
6018 tmp = *srcreg;
6019 *srcreg = destval;
6020 destval = tmp;
6021 store_data_byte(destoffset, destval);
6022 break;
6023 case 2:
6024 destoffset = decode_rm10_address(rl);
6025 DECODE_PRINTF(",");
6026 destval = fetch_data_byte(destoffset);
6027 srcreg = DECODE_RM_BYTE_REGISTER(rh);
6028 DECODE_PRINTF("\n");
6029 TRACE_AND_STEP();
6030 tmp = *srcreg;
6031 *srcreg = destval;
6032 destval = tmp;
6033 store_data_byte(destoffset, destval);
6034 break;
6035 case 3: /* register to register */
6036 destreg = DECODE_RM_BYTE_REGISTER(rl);
6037 DECODE_PRINTF(",");
6038 srcreg = DECODE_RM_BYTE_REGISTER(rh);
6039 DECODE_PRINTF("\n");
6040 TRACE_AND_STEP();
6041 tmp = *srcreg;
6042 *srcreg = *destreg;
6043 *destreg = tmp;
6044 break;
6045 }
6046 DECODE_CLEAR_SEGOVR();
6047 END_OF_INSTR();
6048 }
6049
6050 /****************************************************************************
6051 REMARKS:
6052 Handles opcode 0x87
6053 ****************************************************************************/
6054 static void x86emuOp_xchg_word_RM_R(u8 X86EMU_UNUSED(op1))
6055 {
6056 int mod, rl, rh;
6057 uint destoffset;
6058
6059 START_OF_INSTR();
6060 DECODE_PRINTF("XCHG\t");
6061 FETCH_DECODE_MODRM(mod, rh, rl);
6062 switch (mod) {
6063 case 0:
6064 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6065 u32 *srcreg;
6066 u32 destval,tmp;
6067
6068 destoffset = decode_rm00_address(rl);
6069 DECODE_PRINTF(",");
6070 destval = fetch_data_long(destoffset);
6071 srcreg = DECODE_RM_LONG_REGISTER(rh);
6072 DECODE_PRINTF("\n");
6073 TRACE_AND_STEP();
6074 tmp = *srcreg;
6075 *srcreg = destval;
6076 destval = tmp;
6077 store_data_long(destoffset, destval);
6078 } else {
6079 u16 *srcreg;
6080 u16 destval,tmp;
6081
6082 destoffset = decode_rm00_address(rl);
6083 DECODE_PRINTF(",");
6084 destval = fetch_data_word(destoffset);
6085 srcreg = DECODE_RM_WORD_REGISTER(rh);
6086 DECODE_PRINTF("\n");
6087 TRACE_AND_STEP();
6088 tmp = *srcreg;
6089 *srcreg = destval;
6090 destval = tmp;
6091 store_data_word(destoffset, destval);
6092 }
6093 break;
6094 case 1:
6095 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6096 u32 *srcreg;
6097 u32 destval,tmp;
6098
6099 destoffset = decode_rm01_address(rl);
6100 DECODE_PRINTF(",");
6101 destval = fetch_data_long(destoffset);
6102 srcreg = DECODE_RM_LONG_REGISTER(rh);
6103 DECODE_PRINTF("\n");
6104 TRACE_AND_STEP();
6105 tmp = *srcreg;
6106 *srcreg = destval;
6107 destval = tmp;
6108 store_data_long(destoffset, destval);
6109 } else {
6110 u16 *srcreg;
6111 u16 destval,tmp;
6112
6113 destoffset = decode_rm01_address(rl);
6114 DECODE_PRINTF(",");
6115 destval = fetch_data_word(destoffset);
6116 srcreg = DECODE_RM_WORD_REGISTER(rh);
6117 DECODE_PRINTF("\n");
6118 TRACE_AND_STEP();
6119 tmp = *srcreg;
6120 *srcreg = destval;
6121 destval = tmp;
6122 store_data_word(destoffset, destval);
6123 }
6124 break;
6125 case 2:
6126 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6127 u32 *srcreg;
6128 u32 destval,tmp;
6129
6130 destoffset = decode_rm10_address(rl);
6131 DECODE_PRINTF(",");
6132 destval = fetch_data_long(destoffset);
6133 srcreg = DECODE_RM_LONG_REGISTER(rh);
6134 DECODE_PRINTF("\n");
6135 TRACE_AND_STEP();
6136 tmp = *srcreg;
6137 *srcreg = destval;
6138 destval = tmp;
6139 store_data_long(destoffset, destval);
6140 } else {
6141 u16 *srcreg;
6142 u16 destval,tmp;
6143
6144 destoffset = decode_rm10_address(rl);
6145 DECODE_PRINTF(",");
6146 destval = fetch_data_word(destoffset);
6147 srcreg = DECODE_RM_WORD_REGISTER(rh);
6148 DECODE_PRINTF("\n");
6149 TRACE_AND_STEP();
6150 tmp = *srcreg;
6151 *srcreg = destval;
6152 destval = tmp;
6153 store_data_word(destoffset, destval);
6154 }
6155 break;
6156 case 3: /* register to register */
6157 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6158 u32 *destreg,*srcreg;
6159 u32 tmp;
6160
6161 destreg = DECODE_RM_LONG_REGISTER(rl);
6162 DECODE_PRINTF(",");
6163 srcreg = DECODE_RM_LONG_REGISTER(rh);
6164 DECODE_PRINTF("\n");
6165 TRACE_AND_STEP();
6166 tmp = *srcreg;
6167 *srcreg = *destreg;
6168 *destreg = tmp;
6169 } else {
6170 u16 *destreg,*srcreg;
6171 u16 tmp;
6172
6173 destreg = DECODE_RM_WORD_REGISTER(rl);
6174 DECODE_PRINTF(",");
6175 srcreg = DECODE_RM_WORD_REGISTER(rh);
6176 DECODE_PRINTF("\n");
6177 TRACE_AND_STEP();
6178 tmp = *srcreg;
6179 *srcreg = *destreg;
6180 *destreg = tmp;
6181 }
6182 break;
6183 }
6184 DECODE_CLEAR_SEGOVR();
6185 END_OF_INSTR();
6186 }
6187
6188 /****************************************************************************
6189 REMARKS:
6190 Handles opcode 0x88
6191 ****************************************************************************/
6192 static void x86emuOp_mov_byte_RM_R(u8 X86EMU_UNUSED(op1))
6193 {
6194 int mod, rl, rh;
6195 u8 *destreg, *srcreg;
6196 uint destoffset;
6197
6198 START_OF_INSTR();
6199 DECODE_PRINTF("MOV\t");
6200 FETCH_DECODE_MODRM(mod, rh, rl);
6201 switch (mod) {
6202 case 0:
6203 destoffset = decode_rm00_address(rl);
6204 DECODE_PRINTF(",");
6205 srcreg = DECODE_RM_BYTE_REGISTER(rh);
6206 DECODE_PRINTF("\n");
6207 TRACE_AND_STEP();
6208 store_data_byte(destoffset, *srcreg);
6209 break;
6210 case 1:
6211 destoffset = decode_rm01_address(rl);
6212 DECODE_PRINTF(",");
6213 srcreg = DECODE_RM_BYTE_REGISTER(rh);
6214 DECODE_PRINTF("\n");
6215 TRACE_AND_STEP();
6216 store_data_byte(destoffset, *srcreg);
6217 break;
6218 case 2:
6219 destoffset = decode_rm10_address(rl);
6220 DECODE_PRINTF(",");
6221 srcreg = DECODE_RM_BYTE_REGISTER(rh);
6222 DECODE_PRINTF("\n");
6223 TRACE_AND_STEP();
6224 store_data_byte(destoffset, *srcreg);
6225 break;
6226 case 3: /* register to register */
6227 destreg = DECODE_RM_BYTE_REGISTER(rl);
6228 DECODE_PRINTF(",");
6229 srcreg = DECODE_RM_BYTE_REGISTER(rh);
6230 DECODE_PRINTF("\n");
6231 TRACE_AND_STEP();
6232 *destreg = *srcreg;
6233 break;
6234 }
6235 DECODE_CLEAR_SEGOVR();
6236 END_OF_INSTR();
6237 }
6238
6239 /****************************************************************************
6240 REMARKS:
6241 Handles opcode 0x89
6242 ****************************************************************************/
6243 static void x86emuOp_mov_word_RM_R(u8 X86EMU_UNUSED(op1))
6244 {
6245 int mod, rl, rh;
6246 u32 destoffset;
6247
6248 START_OF_INSTR();
6249 DECODE_PRINTF("MOV\t");
6250 FETCH_DECODE_MODRM(mod, rh, rl);
6251 switch (mod) {
6252 case 0:
6253 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6254 u32 *srcreg;
6255
6256 destoffset = decode_rm00_address(rl);
6257 DECODE_PRINTF(",");
6258 srcreg = DECODE_RM_LONG_REGISTER(rh);
6259 DECODE_PRINTF("\n");
6260 TRACE_AND_STEP();
6261 store_data_long(destoffset, *srcreg);
6262 } else {
6263 u16 *srcreg;
6264
6265 destoffset = decode_rm00_address(rl);
6266 DECODE_PRINTF(",");
6267 srcreg = DECODE_RM_WORD_REGISTER(rh);
6268 DECODE_PRINTF("\n");
6269 TRACE_AND_STEP();
6270 store_data_word(destoffset, *srcreg);
6271 }
6272 break;
6273 case 1:
6274 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6275 u32 *srcreg;
6276
6277 destoffset = decode_rm01_address(rl);
6278 DECODE_PRINTF(",");
6279 srcreg = DECODE_RM_LONG_REGISTER(rh);
6280 DECODE_PRINTF("\n");
6281 TRACE_AND_STEP();
6282 store_data_long(destoffset, *srcreg);
6283 } else {
6284 u16 *srcreg;
6285
6286 destoffset = decode_rm01_address(rl);
6287 DECODE_PRINTF(",");
6288 srcreg = DECODE_RM_WORD_REGISTER(rh);
6289 DECODE_PRINTF("\n");
6290 TRACE_AND_STEP();
6291 store_data_word(destoffset, *srcreg);
6292 }
6293 break;
6294 case 2:
6295 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6296 u32 *srcreg;
6297
6298 destoffset = decode_rm10_address(rl);
6299 DECODE_PRINTF(",");
6300 srcreg = DECODE_RM_LONG_REGISTER(rh);
6301 DECODE_PRINTF("\n");
6302 TRACE_AND_STEP();
6303 store_data_long(destoffset, *srcreg);
6304 } else {
6305 u16 *srcreg;
6306
6307 destoffset = decode_rm10_address(rl);
6308 DECODE_PRINTF(",");
6309 srcreg = DECODE_RM_WORD_REGISTER(rh);
6310 DECODE_PRINTF("\n");
6311 TRACE_AND_STEP();
6312 store_data_word(destoffset, *srcreg);
6313 }
6314 break;
6315 case 3: /* register to register */
6316 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6317 u32 *destreg,*srcreg;
6318
6319 destreg = DECODE_RM_LONG_REGISTER(rl);
6320 DECODE_PRINTF(",");
6321 srcreg = DECODE_RM_LONG_REGISTER(rh);
6322 DECODE_PRINTF("\n");
6323 TRACE_AND_STEP();
6324 *destreg = *srcreg;
6325 } else {
6326 u16 *destreg,*srcreg;
6327
6328 destreg = DECODE_RM_WORD_REGISTER(rl);
6329 DECODE_PRINTF(",");
6330 srcreg = DECODE_RM_WORD_REGISTER(rh);
6331 DECODE_PRINTF("\n");
6332 TRACE_AND_STEP();
6333 *destreg = *srcreg;
6334 }
6335 break;
6336 }
6337 DECODE_CLEAR_SEGOVR();
6338 END_OF_INSTR();
6339 }
6340
6341 /****************************************************************************
6342 REMARKS:
6343 Handles opcode 0x8a
6344 ****************************************************************************/
6345 static void x86emuOp_mov_byte_R_RM(u8 X86EMU_UNUSED(op1))
6346 {
6347 int mod, rl, rh;
6348 u8 *destreg, *srcreg;
6349 uint srcoffset;
6350 u8 srcval;
6351
6352 START_OF_INSTR();
6353 DECODE_PRINTF("MOV\t");
6354 FETCH_DECODE_MODRM(mod, rh, rl);
6355 switch (mod) {
6356 case 0:
6357 destreg = DECODE_RM_BYTE_REGISTER(rh);
6358 DECODE_PRINTF(",");
6359 srcoffset = decode_rm00_address(rl);
6360 srcval = fetch_data_byte(srcoffset);
6361 DECODE_PRINTF("\n");
6362 TRACE_AND_STEP();
6363 *destreg = srcval;
6364 break;
6365 case 1:
6366 destreg = DECODE_RM_BYTE_REGISTER(rh);
6367 DECODE_PRINTF(",");
6368 srcoffset = decode_rm01_address(rl);
6369 srcval = fetch_data_byte(srcoffset);
6370 DECODE_PRINTF("\n");
6371 TRACE_AND_STEP();
6372 *destreg = srcval;
6373 break;
6374 case 2:
6375 destreg = DECODE_RM_BYTE_REGISTER(rh);
6376 DECODE_PRINTF(",");
6377 srcoffset = decode_rm10_address(rl);
6378 srcval = fetch_data_byte(srcoffset);
6379 DECODE_PRINTF("\n");
6380 TRACE_AND_STEP();
6381 *destreg = srcval;
6382 break;
6383 case 3: /* register to register */
6384 destreg = DECODE_RM_BYTE_REGISTER(rh);
6385 DECODE_PRINTF(",");
6386 srcreg = DECODE_RM_BYTE_REGISTER(rl);
6387 DECODE_PRINTF("\n");
6388 TRACE_AND_STEP();
6389 *destreg = *srcreg;
6390 break;
6391 }
6392 DECODE_CLEAR_SEGOVR();
6393 END_OF_INSTR();
6394 }
6395
6396 /****************************************************************************
6397 REMARKS:
6398 Handles opcode 0x8b
6399 ****************************************************************************/
6400 static void x86emuOp_mov_word_R_RM(u8 X86EMU_UNUSED(op1))
6401 {
6402 int mod, rl, rh;
6403 uint srcoffset;
6404
6405 START_OF_INSTR();
6406 DECODE_PRINTF("MOV\t");
6407 FETCH_DECODE_MODRM(mod, rh, rl);
6408 switch (mod) {
6409 case 0:
6410 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6411 u32 *destreg;
6412 u32 srcval;
6413
6414 destreg = DECODE_RM_LONG_REGISTER(rh);
6415 DECODE_PRINTF(",");
6416 srcoffset = decode_rm00_address(rl);
6417 srcval = fetch_data_long(srcoffset);
6418 DECODE_PRINTF("\n");
6419 TRACE_AND_STEP();
6420 *destreg = srcval;
6421 } else {
6422 u16 *destreg;
6423 u16 srcval;
6424
6425 destreg = DECODE_RM_WORD_REGISTER(rh);
6426 DECODE_PRINTF(",");
6427 srcoffset = decode_rm00_address(rl);
6428 srcval = fetch_data_word(srcoffset);
6429 DECODE_PRINTF("\n");
6430 TRACE_AND_STEP();
6431 *destreg = srcval;
6432 }
6433 break;
6434 case 1:
6435 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6436 u32 *destreg;
6437 u32 srcval;
6438
6439 destreg = DECODE_RM_LONG_REGISTER(rh);
6440 DECODE_PRINTF(",");
6441 srcoffset = decode_rm01_address(rl);
6442 srcval = fetch_data_long(srcoffset);
6443 DECODE_PRINTF("\n");
6444 TRACE_AND_STEP();
6445 *destreg = srcval;
6446 } else {
6447 u16 *destreg;
6448 u16 srcval;
6449
6450 destreg = DECODE_RM_WORD_REGISTER(rh);
6451 DECODE_PRINTF(",");
6452 srcoffset = decode_rm01_address(rl);
6453 srcval = fetch_data_word(srcoffset);
6454 DECODE_PRINTF("\n");
6455 TRACE_AND_STEP();
6456 *destreg = srcval;
6457 }
6458 break;
6459 case 2:
6460 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6461 u32 *destreg;
6462 u32 srcval;
6463
6464 destreg = DECODE_RM_LONG_REGISTER(rh);
6465 DECODE_PRINTF(",");
6466 srcoffset = decode_rm10_address(rl);
6467 srcval = fetch_data_long(srcoffset);
6468 DECODE_PRINTF("\n");
6469 TRACE_AND_STEP();
6470 *destreg = srcval;
6471 } else {
6472 u16 *destreg;
6473 u16 srcval;
6474
6475 destreg = DECODE_RM_WORD_REGISTER(rh);
6476 DECODE_PRINTF(",");
6477 srcoffset = decode_rm10_address(rl);
6478 srcval = fetch_data_word(srcoffset);
6479 DECODE_PRINTF("\n");
6480 TRACE_AND_STEP();
6481 *destreg = srcval;
6482 }
6483 break;
6484 case 3: /* register to register */
6485 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6486 u32 *destreg, *srcreg;
6487
6488 destreg = DECODE_RM_LONG_REGISTER(rh);
6489 DECODE_PRINTF(",");
6490 srcreg = DECODE_RM_LONG_REGISTER(rl);
6491 DECODE_PRINTF("\n");
6492 TRACE_AND_STEP();
6493 *destreg = *srcreg;
6494 } else {
6495 u16 *destreg, *srcreg;
6496
6497 destreg = DECODE_RM_WORD_REGISTER(rh);
6498 DECODE_PRINTF(",");
6499 srcreg = DECODE_RM_WORD_REGISTER(rl);
6500 DECODE_PRINTF("\n");
6501 TRACE_AND_STEP();
6502 *destreg = *srcreg;
6503 }
6504 break;
6505 }
6506 DECODE_CLEAR_SEGOVR();
6507 END_OF_INSTR();
6508 }
6509
6510 /****************************************************************************
6511 REMARKS:
6512 Handles opcode 0x8c
6513 ****************************************************************************/
6514 static void x86emuOp_mov_word_RM_SR(u8 X86EMU_UNUSED(op1))
6515 {
6516 int mod, rl, rh;
6517 u16 *destreg, *srcreg;
6518 uint destoffset;
6519 u16 destval;
6520
6521 START_OF_INSTR();
6522 DECODE_PRINTF("MOV\t");
6523 FETCH_DECODE_MODRM(mod, rh, rl);
6524 switch (mod) {
6525 case 0:
6526 destoffset = decode_rm00_address(rl);
6527 DECODE_PRINTF(",");
6528 srcreg = decode_rm_seg_register(rh);
6529 DECODE_PRINTF("\n");
6530 TRACE_AND_STEP();
6531 destval = *srcreg;
6532 store_data_word(destoffset, destval);
6533 break;
6534 case 1:
6535 destoffset = decode_rm01_address(rl);
6536 DECODE_PRINTF(",");
6537 srcreg = decode_rm_seg_register(rh);
6538 DECODE_PRINTF("\n");
6539 TRACE_AND_STEP();
6540 destval = *srcreg;
6541 store_data_word(destoffset, destval);
6542 break;
6543 case 2:
6544 destoffset = decode_rm10_address(rl);
6545 DECODE_PRINTF(",");
6546 srcreg = decode_rm_seg_register(rh);
6547 DECODE_PRINTF("\n");
6548 TRACE_AND_STEP();
6549 destval = *srcreg;
6550 store_data_word(destoffset, destval);
6551 break;
6552 case 3: /* register to register */
6553 destreg = DECODE_RM_WORD_REGISTER(rl);
6554 DECODE_PRINTF(",");
6555 srcreg = decode_rm_seg_register(rh);
6556 DECODE_PRINTF("\n");
6557 TRACE_AND_STEP();
6558 *destreg = *srcreg;
6559 break;
6560 }
6561 DECODE_CLEAR_SEGOVR();
6562 END_OF_INSTR();
6563 }
6564
6565 /****************************************************************************
6566 REMARKS:
6567 Handles opcode 0x8d
6568 ****************************************************************************/
6569 static void x86emuOp_lea_word_R_M(u8 X86EMU_UNUSED(op1))
6570 {
6571 int mod, rl, rh;
6572 u16 *srcreg;
6573 uint destoffset;
6574
6575 /*
6576 * TODO: Need to handle address size prefix!
6577 *
6578 * lea eax,[eax+ebx*2] ??
6579 */
6580
6581 START_OF_INSTR();
6582 DECODE_PRINTF("LEA\t");
6583 FETCH_DECODE_MODRM(mod, rh, rl);
6584 switch (mod) {
6585 case 0:
6586 srcreg = DECODE_RM_WORD_REGISTER(rh);
6587 DECODE_PRINTF(",");
6588 destoffset = decode_rm00_address(rl);
6589 DECODE_PRINTF("\n");
6590 TRACE_AND_STEP();
6591 *srcreg = (u16)destoffset;
6592 break;
6593 case 1:
6594 srcreg = DECODE_RM_WORD_REGISTER(rh);
6595 DECODE_PRINTF(",");
6596 destoffset = decode_rm01_address(rl);
6597 DECODE_PRINTF("\n");
6598 TRACE_AND_STEP();
6599 *srcreg = (u16)destoffset;
6600 break;
6601 case 2:
6602 srcreg = DECODE_RM_WORD_REGISTER(rh);
6603 DECODE_PRINTF(",");
6604 destoffset = decode_rm10_address(rl);
6605 DECODE_PRINTF("\n");
6606 TRACE_AND_STEP();
6607 *srcreg = (u16)destoffset;
6608 break;
6609 case 3: /* register to register */
6610 /* undefined. Do nothing. */
6611 break;
6612 }
6613 DECODE_CLEAR_SEGOVR();
6614 END_OF_INSTR();
6615 }
6616
6617 /****************************************************************************
6618 REMARKS:
6619 Handles opcode 0x8e
6620 ****************************************************************************/
6621 static void x86emuOp_mov_word_SR_RM(u8 X86EMU_UNUSED(op1))
6622 {
6623 int mod, rl, rh;
6624 u16 *destreg, *srcreg;
6625 uint srcoffset;
6626 u16 srcval;
6627
6628 START_OF_INSTR();
6629 DECODE_PRINTF("MOV\t");
6630 FETCH_DECODE_MODRM(mod, rh, rl);
6631 switch (mod) {
6632 case 0:
6633 destreg = decode_rm_seg_register(rh);
6634 DECODE_PRINTF(",");
6635 srcoffset = decode_rm00_address(rl);
6636 srcval = fetch_data_word(srcoffset);
6637 DECODE_PRINTF("\n");
6638 TRACE_AND_STEP();
6639 *destreg = srcval;
6640 break;
6641 case 1:
6642 destreg = decode_rm_seg_register(rh);
6643 DECODE_PRINTF(",");
6644 srcoffset = decode_rm01_address(rl);
6645 srcval = fetch_data_word(srcoffset);
6646 DECODE_PRINTF("\n");
6647 TRACE_AND_STEP();
6648 *destreg = srcval;
6649 break;
6650 case 2:
6651 destreg = decode_rm_seg_register(rh);
6652 DECODE_PRINTF(",");
6653 srcoffset = decode_rm10_address(rl);
6654 srcval = fetch_data_word(srcoffset);
6655 DECODE_PRINTF("\n");
6656 TRACE_AND_STEP();
6657 *destreg = srcval;
6658 break;
6659 case 3: /* register to register */
6660 destreg = decode_rm_seg_register(rh);
6661 DECODE_PRINTF(",");
6662 srcreg = DECODE_RM_WORD_REGISTER(rl);
6663 DECODE_PRINTF("\n");
6664 TRACE_AND_STEP();
6665 *destreg = *srcreg;
6666 break;
6667 }
6668 /*
6669 * Clean up, and reset all the R_xSP pointers to the correct
6670 * locations. This is about 3x too much overhead (doing all the
6671 * segreg ptrs when only one is needed, but this instruction
6672 * *cannot* be that common, and this isn't too much work anyway.
6673 */
6674 DECODE_CLEAR_SEGOVR();
6675 END_OF_INSTR();
6676 }
6677
6678 /****************************************************************************
6679 REMARKS:
6680 Handles opcode 0x8f
6681 ****************************************************************************/
6682 static void x86emuOp_pop_RM(u8 X86EMU_UNUSED(op1))
6683 {
6684 int mod, rl, rh;
6685 uint destoffset;
6686
6687 START_OF_INSTR();
6688 DECODE_PRINTF("POP\t");
6689 FETCH_DECODE_MODRM(mod, rh, rl);
6690 if (rh != 0) {
6691 DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n");
6692 HALT_SYS();
6693 }
6694 switch (mod) {
6695 case 0:
6696 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6697 u32 destval;
6698
6699 destoffset = decode_rm00_address(rl);
6700 DECODE_PRINTF("\n");
6701 TRACE_AND_STEP();
6702 destval = pop_long();
6703 store_data_long(destoffset, destval);
6704 } else {
6705 u16 destval;
6706
6707 destoffset = decode_rm00_address(rl);
6708 DECODE_PRINTF("\n");
6709 TRACE_AND_STEP();
6710 destval = pop_word();
6711 store_data_word(destoffset, destval);
6712 }
6713 break;
6714 case 1:
6715 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6716 u32 destval;
6717
6718 destoffset = decode_rm01_address(rl);
6719 DECODE_PRINTF("\n");
6720 TRACE_AND_STEP();
6721 destval = pop_long();
6722 store_data_long(destoffset, destval);
6723 } else {
6724 u16 destval;
6725
6726 destoffset = decode_rm01_address(rl);
6727 DECODE_PRINTF("\n");
6728 TRACE_AND_STEP();
6729 destval = pop_word();
6730 store_data_word(destoffset, destval);
6731 }
6732 break;
6733 case 2:
6734 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6735 u32 destval;
6736
6737 destoffset = decode_rm10_address(rl);
6738 DECODE_PRINTF("\n");
6739 TRACE_AND_STEP();
6740 destval = pop_long();
6741 store_data_long(destoffset, destval);
6742 } else {
6743 u16 destval;
6744
6745 destoffset = decode_rm10_address(rl);
6746 DECODE_PRINTF("\n");
6747 TRACE_AND_STEP();
6748 destval = pop_word();
6749 store_data_word(destoffset, destval);
6750 }
6751 break;
6752 case 3: /* register to register */
6753 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6754 u32 *destreg;
6755
6756 destreg = DECODE_RM_LONG_REGISTER(rl);
6757 DECODE_PRINTF("\n");
6758 TRACE_AND_STEP();
6759 *destreg = pop_long();
6760 } else {
6761 u16 *destreg;
6762
6763 destreg = DECODE_RM_WORD_REGISTER(rl);
6764 DECODE_PRINTF("\n");
6765 TRACE_AND_STEP();
6766 *destreg = pop_word();
6767 }
6768 break;
6769 }
6770 DECODE_CLEAR_SEGOVR();
6771 END_OF_INSTR();
6772 }
6773
6774 /****************************************************************************
6775 REMARKS:
6776 Handles opcode 0x90
6777 ****************************************************************************/
6778 static void x86emuOp_nop(u8 X86EMU_UNUSED(op1))
6779 {
6780 START_OF_INSTR();
6781 DECODE_PRINTF("NOP\n");
6782 TRACE_AND_STEP();
6783 DECODE_CLEAR_SEGOVR();
6784 END_OF_INSTR();
6785 }
6786
6787 /****************************************************************************
6788 REMARKS:
6789 Handles opcode 0x91
6790 ****************************************************************************/
6791 static void x86emuOp_xchg_word_AX_CX(u8 X86EMU_UNUSED(op1))
6792 {
6793 u32 tmp;
6794
6795 START_OF_INSTR();
6796 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6797 DECODE_PRINTF("XCHG\tEAX,ECX\n");
6798 } else {
6799 DECODE_PRINTF("XCHG\tAX,CX\n");
6800 }
6801 TRACE_AND_STEP();
6802 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6803 tmp = M.x86.R_EAX;
6804 M.x86.R_EAX = M.x86.R_ECX;
6805 M.x86.R_ECX = tmp;
6806 } else {
6807 tmp = M.x86.R_AX;
6808 M.x86.R_AX = M.x86.R_CX;
6809 M.x86.R_CX = (u16)tmp;
6810 }
6811 DECODE_CLEAR_SEGOVR();
6812 END_OF_INSTR();
6813 }
6814
6815 /****************************************************************************
6816 REMARKS:
6817 Handles opcode 0x92
6818 ****************************************************************************/
6819 static void x86emuOp_xchg_word_AX_DX(u8 X86EMU_UNUSED(op1))
6820 {
6821 u32 tmp;
6822
6823 START_OF_INSTR();
6824 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6825 DECODE_PRINTF("XCHG\tEAX,EDX\n");
6826 } else {
6827 DECODE_PRINTF("XCHG\tAX,DX\n");
6828 }
6829 TRACE_AND_STEP();
6830 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6831 tmp = M.x86.R_EAX;
6832 M.x86.R_EAX = M.x86.R_EDX;
6833 M.x86.R_EDX = tmp;
6834 } else {
6835 tmp = M.x86.R_AX;
6836 M.x86.R_AX = M.x86.R_DX;
6837 M.x86.R_DX = (u16)tmp;
6838 }
6839 DECODE_CLEAR_SEGOVR();
6840 END_OF_INSTR();
6841 }
6842
6843 /****************************************************************************
6844 REMARKS:
6845 Handles opcode 0x93
6846 ****************************************************************************/
6847 static void x86emuOp_xchg_word_AX_BX(u8 X86EMU_UNUSED(op1))
6848 {
6849 u32 tmp;
6850
6851 START_OF_INSTR();
6852 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6853 DECODE_PRINTF("XCHG\tEAX,EBX\n");
6854 } else {
6855 DECODE_PRINTF("XCHG\tAX,BX\n");
6856 }
6857 TRACE_AND_STEP();
6858 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6859 tmp = M.x86.R_EAX;
6860 M.x86.R_EAX = M.x86.R_EBX;
6861 M.x86.R_EBX = tmp;
6862 } else {
6863 tmp = M.x86.R_AX;
6864 M.x86.R_AX = M.x86.R_BX;
6865 M.x86.R_BX = (u16)tmp;
6866 }
6867 DECODE_CLEAR_SEGOVR();
6868 END_OF_INSTR();
6869 }
6870
6871 /****************************************************************************
6872 REMARKS:
6873 Handles opcode 0x94
6874 ****************************************************************************/
6875 static void x86emuOp_xchg_word_AX_SP(u8 X86EMU_UNUSED(op1))
6876 {
6877 u32 tmp;
6878
6879 START_OF_INSTR();
6880 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6881 DECODE_PRINTF("XCHG\tEAX,ESP\n");
6882 } else {
6883 DECODE_PRINTF("XCHG\tAX,SP\n");
6884 }
6885 TRACE_AND_STEP();
6886 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6887 tmp = M.x86.R_EAX;
6888 M.x86.R_EAX = M.x86.R_ESP;
6889 M.x86.R_ESP = tmp;
6890 } else {
6891 tmp = M.x86.R_AX;
6892 M.x86.R_AX = M.x86.R_SP;
6893 M.x86.R_SP = (u16)tmp;
6894 }
6895 DECODE_CLEAR_SEGOVR();
6896 END_OF_INSTR();
6897 }
6898
6899 /****************************************************************************
6900 REMARKS:
6901 Handles opcode 0x95
6902 ****************************************************************************/
6903 static void x86emuOp_xchg_word_AX_BP(u8 X86EMU_UNUSED(op1))
6904 {
6905 u32 tmp;
6906
6907 START_OF_INSTR();
6908 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6909 DECODE_PRINTF("XCHG\tEAX,EBP\n");
6910 } else {
6911 DECODE_PRINTF("XCHG\tAX,BP\n");
6912 }
6913 TRACE_AND_STEP();
6914 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6915 tmp = M.x86.R_EAX;
6916 M.x86.R_EAX = M.x86.R_EBP;
6917 M.x86.R_EBP = tmp;
6918 } else {
6919 tmp = M.x86.R_AX;
6920 M.x86.R_AX = M.x86.R_BP;
6921 M.x86.R_BP = (u16)tmp;
6922 }
6923 DECODE_CLEAR_SEGOVR();
6924 END_OF_INSTR();
6925 }
6926
6927 /****************************************************************************
6928 REMARKS:
6929 Handles opcode 0x96
6930 ****************************************************************************/
6931 static void x86emuOp_xchg_word_AX_SI(u8 X86EMU_UNUSED(op1))
6932 {
6933 u32 tmp;
6934
6935 START_OF_INSTR();
6936 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6937 DECODE_PRINTF("XCHG\tEAX,ESI\n");
6938 } else {
6939 DECODE_PRINTF("XCHG\tAX,SI\n");
6940 }
6941 TRACE_AND_STEP();
6942 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6943 tmp = M.x86.R_EAX;
6944 M.x86.R_EAX = M.x86.R_ESI;
6945 M.x86.R_ESI = tmp;
6946 } else {
6947 tmp = M.x86.R_AX;
6948 M.x86.R_AX = M.x86.R_SI;
6949 M.x86.R_SI = (u16)tmp;
6950 }
6951 DECODE_CLEAR_SEGOVR();
6952 END_OF_INSTR();
6953 }
6954
6955 /****************************************************************************
6956 REMARKS:
6957 Handles opcode 0x97
6958 ****************************************************************************/
6959 static void x86emuOp_xchg_word_AX_DI(u8 X86EMU_UNUSED(op1))
6960 {
6961 u32 tmp;
6962
6963 START_OF_INSTR();
6964 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6965 DECODE_PRINTF("XCHG\tEAX,EDI\n");
6966 } else {
6967 DECODE_PRINTF("XCHG\tAX,DI\n");
6968 }
6969 TRACE_AND_STEP();
6970 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6971 tmp = M.x86.R_EAX;
6972 M.x86.R_EAX = M.x86.R_EDI;
6973 M.x86.R_EDI = tmp;
6974 } else {
6975 tmp = M.x86.R_AX;
6976 M.x86.R_AX = M.x86.R_DI;
6977 M.x86.R_DI = (u16)tmp;
6978 }
6979 DECODE_CLEAR_SEGOVR();
6980 END_OF_INSTR();
6981 }
6982
6983 /****************************************************************************
6984 REMARKS:
6985 Handles opcode 0x98
6986 ****************************************************************************/
6987 static void x86emuOp_cbw(u8 X86EMU_UNUSED(op1))
6988 {
6989 START_OF_INSTR();
6990 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6991 DECODE_PRINTF("CWDE\n");
6992 } else {
6993 DECODE_PRINTF("CBW\n");
6994 }
6995 TRACE_AND_STEP();
6996 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6997 if (M.x86.R_AX & 0x8000) {
6998 M.x86.R_EAX |= 0xffff0000;
6999 } else {
7000 M.x86.R_EAX &= 0x0000ffff;
7001 }
7002 } else {
7003 if (M.x86.R_AL & 0x80) {
7004 M.x86.R_AH = 0xff;
7005 } else {
7006 M.x86.R_AH = 0x0;
7007 }
7008 }
7009 DECODE_CLEAR_SEGOVR();
7010 END_OF_INSTR();
7011 }
7012
7013 /****************************************************************************
7014 REMARKS:
7015 Handles opcode 0x99
7016 ****************************************************************************/
7017 static void x86emuOp_cwd(u8 X86EMU_UNUSED(op1))
7018 {
7019 START_OF_INSTR();
7020 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7021 DECODE_PRINTF("CDQ\n");
7022 } else {
7023 DECODE_PRINTF("CWD\n");
7024 }
7025 DECODE_PRINTF("CWD\n");
7026 TRACE_AND_STEP();
7027 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7028 if (M.x86.R_EAX & 0x80000000) {
7029 M.x86.R_EDX = 0xffffffff;
7030 } else {
7031 M.x86.R_EDX = 0x0;
7032 }
7033 } else {
7034 if (M.x86.R_AX & 0x8000) {
7035 M.x86.R_DX = 0xffff;
7036 } else {
7037 M.x86.R_DX = 0x0;
7038 }
7039 }
7040 DECODE_CLEAR_SEGOVR();
7041 END_OF_INSTR();
7042 }
7043
7044 /****************************************************************************
7045 REMARKS:
7046 Handles opcode 0x9a
7047 ****************************************************************************/
7048 static void x86emuOp_call_far_IMM(u8 X86EMU_UNUSED(op1))
7049 {
7050 u16 farseg, faroff;
7051
7052 START_OF_INSTR();
7053 DECODE_PRINTF("CALL\t");
7054 faroff = fetch_word_imm();
7055 farseg = fetch_word_imm();
7056 DECODE_PRINTF2("%04x:", farseg);
7057 DECODE_PRINTF2("%04x\n", faroff);
7058 CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, farseg, faroff, "FAR ");
7059
7060 /* XXX
7061 *
7062 * Hooked interrupt vectors calling into our "BIOS" will cause
7063 * problems unless all intersegment stuff is checked for BIOS
7064 * access. Check needed here. For moment, let it alone.
7065 */
7066 TRACE_AND_STEP();
7067 push_word(M.x86.R_CS);
7068 M.x86.R_CS = farseg;
7069 push_word(M.x86.R_IP);
7070 M.x86.R_IP = faroff;
7071 DECODE_CLEAR_SEGOVR();
7072 END_OF_INSTR();
7073 }
7074
7075 /****************************************************************************
7076 REMARKS:
7077 Handles opcode 0x9b
7078 ****************************************************************************/
7079 static void x86emuOp_wait(u8 X86EMU_UNUSED(op1))
7080 {
7081 START_OF_INSTR();
7082 DECODE_PRINTF("WAIT");
7083 TRACE_AND_STEP();
7084 /* NADA. */
7085 DECODE_CLEAR_SEGOVR();
7086 END_OF_INSTR();
7087 }
7088
7089 /****************************************************************************
7090 REMARKS:
7091 Handles opcode 0x9c
7092 ****************************************************************************/
7093 static void x86emuOp_pushf_word(u8 X86EMU_UNUSED(op1))
7094 {
7095 u32 flags;
7096
7097 START_OF_INSTR();
7098 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7099 DECODE_PRINTF("PUSHFD\n");
7100 } else {
7101 DECODE_PRINTF("PUSHF\n");
7102 }
7103 TRACE_AND_STEP();
7104
7105 /* clear out *all* bits not representing flags, and turn on real bits */
7106 flags = (M.x86.R_EFLG & F_MSK) | F_ALWAYS_ON;
7107 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7108 push_long(flags);
7109 } else {
7110 push_word((u16)flags);
7111 }
7112 DECODE_CLEAR_SEGOVR();
7113 END_OF_INSTR();
7114 }
7115
7116 /****************************************************************************
7117 REMARKS:
7118 Handles opcode 0x9d
7119 ****************************************************************************/
7120 static void x86emuOp_popf_word(u8 X86EMU_UNUSED(op1))
7121 {
7122 START_OF_INSTR();
7123 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7124 DECODE_PRINTF("POPFD\n");
7125 } else {
7126 DECODE_PRINTF("POPF\n");
7127 }
7128 TRACE_AND_STEP();
7129 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7130 M.x86.R_EFLG = pop_long();
7131 } else {
7132 M.x86.R_FLG = pop_word();
7133 }
7134 DECODE_CLEAR_SEGOVR();
7135 END_OF_INSTR();
7136 }
7137
7138 /****************************************************************************
7139 REMARKS:
7140 Handles opcode 0x9e
7141 ****************************************************************************/
7142 static void x86emuOp_sahf(u8 X86EMU_UNUSED(op1))
7143 {
7144 START_OF_INSTR();
7145 DECODE_PRINTF("SAHF\n");
7146 TRACE_AND_STEP();
7147 /* clear the lower bits of the flag register */
7148 M.x86.R_FLG &= 0xffffff00;
7149 /* or in the AH register into the flags register */
7150 M.x86.R_FLG |= M.x86.R_AH;
7151 DECODE_CLEAR_SEGOVR();
7152 END_OF_INSTR();
7153 }
7154
7155 /****************************************************************************
7156 REMARKS:
7157 Handles opcode 0x9f
7158 ****************************************************************************/
7159 static void x86emuOp_lahf(u8 X86EMU_UNUSED(op1))
7160 {
7161 START_OF_INSTR();
7162 DECODE_PRINTF("LAHF\n");
7163 TRACE_AND_STEP();
7164 M.x86.R_AH = (u8)(M.x86.R_FLG & 0xff);
7165 /*undocumented TC++ behavior??? Nope. It's documented, but
7166 you have too look real hard to notice it. */
7167 M.x86.R_AH |= 0x2;
7168 DECODE_CLEAR_SEGOVR();
7169 END_OF_INSTR();
7170 }
7171
7172 /****************************************************************************
7173 REMARKS:
7174 Handles opcode 0xa0
7175 ****************************************************************************/
7176 static void x86emuOp_mov_AL_M_IMM(u8 X86EMU_UNUSED(op1))
7177 {
7178 u16 offset;
7179
7180 START_OF_INSTR();
7181 DECODE_PRINTF("MOV\tAL,");
7182 offset = fetch_word_imm();
7183 DECODE_PRINTF2("[%04x]\n", offset);
7184 TRACE_AND_STEP();
7185 M.x86.R_AL = fetch_data_byte(offset);
7186 DECODE_CLEAR_SEGOVR();
7187 END_OF_INSTR();
7188 }
7189
7190 /****************************************************************************
7191 REMARKS:
7192 Handles opcode 0xa1
7193 ****************************************************************************/
7194 static void x86emuOp_mov_AX_M_IMM(u8 X86EMU_UNUSED(op1))
7195 {
7196 u16 offset;
7197
7198 START_OF_INSTR();
7199 offset = fetch_word_imm();
7200 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7201 DECODE_PRINTF2("MOV\tEAX,[%04x]\n", offset);
7202 } else {
7203 DECODE_PRINTF2("MOV\tAX,[%04x]\n", offset);
7204 }
7205 TRACE_AND_STEP();
7206 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7207 M.x86.R_EAX = fetch_data_long(offset);
7208 } else {
7209 M.x86.R_AX = fetch_data_word(offset);
7210 }
7211 DECODE_CLEAR_SEGOVR();
7212 END_OF_INSTR();
7213 }
7214
7215 /****************************************************************************
7216 REMARKS:
7217 Handles opcode 0xa2
7218 ****************************************************************************/
7219 static void x86emuOp_mov_M_AL_IMM(u8 X86EMU_UNUSED(op1))
7220 {
7221 u16 offset;
7222
7223 START_OF_INSTR();
7224 DECODE_PRINTF("MOV\t");
7225 offset = fetch_word_imm();
7226 DECODE_PRINTF2("[%04x],AL\n", offset);
7227 TRACE_AND_STEP();
7228 store_data_byte(offset, M.x86.R_AL);
7229 DECODE_CLEAR_SEGOVR();
7230 END_OF_INSTR();
7231 }
7232
7233 /****************************************************************************
7234 REMARKS:
7235 Handles opcode 0xa3
7236 ****************************************************************************/
7237 static void x86emuOp_mov_M_AX_IMM(u8 X86EMU_UNUSED(op1))
7238 {
7239 u16 offset;
7240
7241 START_OF_INSTR();
7242 offset = fetch_word_imm();
7243 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7244 DECODE_PRINTF2("MOV\t[%04x],EAX\n", offset);
7245 } else {
7246 DECODE_PRINTF2("MOV\t[%04x],AX\n", offset);
7247 }
7248 TRACE_AND_STEP();
7249 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7250 store_data_long(offset, M.x86.R_EAX);
7251 } else {
7252 store_data_word(offset, M.x86.R_AX);
7253 }
7254 DECODE_CLEAR_SEGOVR();
7255 END_OF_INSTR();
7256 }
7257
7258 /****************************************************************************
7259 REMARKS:
7260 Handles opcode 0xa4
7261 ****************************************************************************/
7262 static void x86emuOp_movs_byte(u8 X86EMU_UNUSED(op1))
7263 {
7264 u8 val;
7265 u32 count;
7266 int inc;
7267
7268 START_OF_INSTR();
7269 DECODE_PRINTF("MOVS\tBYTE\n");
7270 if (ACCESS_FLAG(F_DF)) /* down */
7271 inc = -1;
7272 else
7273 inc = 1;
7274 TRACE_AND_STEP();
7275 count = 1;
7276 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7277 /* dont care whether REPE or REPNE */
7278 /* move them until CX is ZERO. */
7279 count = M.x86.R_CX;
7280 M.x86.R_CX = 0;
7281 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7282 }
7283 while (count--) {
7284 val = fetch_data_byte(M.x86.R_SI);
7285 store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, val);
7286 M.x86.R_SI += inc;
7287 M.x86.R_DI += inc;
7288 }
7289 DECODE_CLEAR_SEGOVR();
7290 END_OF_INSTR();
7291 }
7292
7293 /****************************************************************************
7294 REMARKS:
7295 Handles opcode 0xa5
7296 ****************************************************************************/
7297 static void x86emuOp_movs_word(u8 X86EMU_UNUSED(op1))
7298 {
7299 u32 val;
7300 int inc;
7301 u32 count;
7302
7303 START_OF_INSTR();
7304 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7305 DECODE_PRINTF("MOVS\tDWORD\n");
7306 if (ACCESS_FLAG(F_DF)) /* down */
7307 inc = -4;
7308 else
7309 inc = 4;
7310 } else {
7311 DECODE_PRINTF("MOVS\tWORD\n");
7312 if (ACCESS_FLAG(F_DF)) /* down */
7313 inc = -2;
7314 else
7315 inc = 2;
7316 }
7317 TRACE_AND_STEP();
7318 count = 1;
7319 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7320 /* dont care whether REPE or REPNE */
7321 /* move them until CX is ZERO. */
7322 count = M.x86.R_CX;
7323 M.x86.R_CX = 0;
7324 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7325 }
7326 while (count--) {
7327 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7328 val = fetch_data_long(M.x86.R_SI);
7329 store_data_long_abs(M.x86.R_ES, M.x86.R_DI, val);
7330 } else {
7331 val = fetch_data_word(M.x86.R_SI);
7332 store_data_word_abs(M.x86.R_ES, M.x86.R_DI, (u16)val);
7333 }
7334 M.x86.R_SI += inc;
7335 M.x86.R_DI += inc;
7336 }
7337 DECODE_CLEAR_SEGOVR();
7338 END_OF_INSTR();
7339 }
7340
7341 /****************************************************************************
7342 REMARKS:
7343 Handles opcode 0xa6
7344 ****************************************************************************/
7345 static void x86emuOp_cmps_byte(u8 X86EMU_UNUSED(op1))
7346 {
7347 s8 val1, val2;
7348 int inc;
7349
7350 START_OF_INSTR();
7351 DECODE_PRINTF("CMPS\tBYTE\n");
7352 TRACE_AND_STEP();
7353 if (ACCESS_FLAG(F_DF)) /* down */
7354 inc = -1;
7355 else
7356 inc = 1;
7357
7358 if (M.x86.mode & SYSMODE_PREFIX_REPE) {
7359 /* REPE */
7360 /* move them until CX is ZERO. */
7361 while (M.x86.R_CX != 0) {
7362 val1 = fetch_data_byte(M.x86.R_SI);
7363 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7364 cmp_byte(val1, val2);
7365 M.x86.R_CX -= 1;
7366 M.x86.R_SI += inc;
7367 M.x86.R_DI += inc;
7368 if (ACCESS_FLAG(F_ZF) == 0)
7369 break;
7370 }
7371 M.x86.mode &= ~SYSMODE_PREFIX_REPE;
7372 } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
7373 /* REPNE */
7374 /* move them until CX is ZERO. */
7375 while (M.x86.R_CX != 0) {
7376 val1 = fetch_data_byte(M.x86.R_SI);
7377 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7378 cmp_byte(val1, val2);
7379 M.x86.R_CX -= 1;
7380 M.x86.R_SI += inc;
7381 M.x86.R_DI += inc;
7382 if (ACCESS_FLAG(F_ZF))
7383 break; /* zero flag set means equal */
7384 }
7385 M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
7386 } else {
7387 val1 = fetch_data_byte(M.x86.R_SI);
7388 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7389 cmp_byte(val1, val2);
7390 M.x86.R_SI += inc;
7391 M.x86.R_DI += inc;
7392 }
7393 DECODE_CLEAR_SEGOVR();
7394 END_OF_INSTR();
7395 }
7396
7397 /****************************************************************************
7398 REMARKS:
7399 Handles opcode 0xa7
7400 ****************************************************************************/
7401 static void x86emuOp_cmps_word(u8 X86EMU_UNUSED(op1))
7402 {
7403 u32 val1,val2;
7404 int inc;
7405
7406 START_OF_INSTR();
7407 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7408 DECODE_PRINTF("CMPS\tDWORD\n");
7409 if (ACCESS_FLAG(F_DF)) /* down */
7410 inc = -4;
7411 else
7412 inc = 4;
7413 } else {
7414 DECODE_PRINTF("CMPS\tWORD\n");
7415 if (ACCESS_FLAG(F_DF)) /* down */
7416 inc = -2;
7417 else
7418 inc = 2;
7419 }
7420 TRACE_AND_STEP();
7421 if (M.x86.mode & SYSMODE_PREFIX_REPE) {
7422 /* REPE */
7423 /* move them until CX is ZERO. */
7424 while (M.x86.R_CX != 0) {
7425 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7426 val1 = fetch_data_long(M.x86.R_SI);
7427 val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7428 cmp_long(val1, val2);
7429 } else {
7430 val1 = fetch_data_word(M.x86.R_SI);
7431 val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7432 cmp_word((u16)val1, (u16)val2);
7433 }
7434 M.x86.R_CX -= 1;
7435 M.x86.R_SI += inc;
7436 M.x86.R_DI += inc;
7437 if (ACCESS_FLAG(F_ZF) == 0)
7438 break;
7439 }
7440 M.x86.mode &= ~SYSMODE_PREFIX_REPE;
7441 } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
7442 /* REPNE */
7443 /* move them until CX is ZERO. */
7444 while (M.x86.R_CX != 0) {
7445 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7446 val1 = fetch_data_long(M.x86.R_SI);
7447 val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7448 cmp_long(val1, val2);
7449 } else {
7450 val1 = fetch_data_word(M.x86.R_SI);
7451 val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7452 cmp_word((u16)val1, (u16)val2);
7453 }
7454 M.x86.R_CX -= 1;
7455 M.x86.R_SI += inc;
7456 M.x86.R_DI += inc;
7457 if (ACCESS_FLAG(F_ZF))
7458 break; /* zero flag set means equal */
7459 }
7460 M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
7461 } else {
7462 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7463 val1 = fetch_data_long(M.x86.R_SI);
7464 val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7465 cmp_long(val1, val2);
7466 } else {
7467 val1 = fetch_data_word(M.x86.R_SI);
7468 val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7469 cmp_word((u16)val1, (u16)val2);
7470 }
7471 M.x86.R_SI += inc;
7472 M.x86.R_DI += inc;
7473 }
7474 DECODE_CLEAR_SEGOVR();
7475 END_OF_INSTR();
7476 }
7477
7478 /****************************************************************************
7479 REMARKS:
7480 Handles opcode 0xa8
7481 ****************************************************************************/
7482 static void x86emuOp_test_AL_IMM(u8 X86EMU_UNUSED(op1))
7483 {
7484 int imm;
7485
7486 START_OF_INSTR();
7487 DECODE_PRINTF("TEST\tAL,");
7488 imm = fetch_byte_imm();
7489 DECODE_PRINTF2("%04x\n", imm);
7490 TRACE_AND_STEP();
7491 test_byte(M.x86.R_AL, (u8)imm);
7492 DECODE_CLEAR_SEGOVR();
7493 END_OF_INSTR();
7494 }
7495
7496 /****************************************************************************
7497 REMARKS:
7498 Handles opcode 0xa9
7499 ****************************************************************************/
7500 static void x86emuOp_test_AX_IMM(u8 X86EMU_UNUSED(op1))
7501 {
7502 u32 srcval;
7503
7504 START_OF_INSTR();
7505 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7506 DECODE_PRINTF("TEST\tEAX,");
7507 srcval = fetch_long_imm();
7508 } else {
7509 DECODE_PRINTF("TEST\tAX,");
7510 srcval = fetch_word_imm();
7511 }
7512 DECODE_PRINTF2("%x\n", srcval);
7513 TRACE_AND_STEP();
7514 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7515 test_long(M.x86.R_EAX, srcval);
7516 } else {
7517 test_word(M.x86.R_AX, (u16)srcval);
7518 }
7519 DECODE_CLEAR_SEGOVR();
7520 END_OF_INSTR();
7521 }
7522
7523 /****************************************************************************
7524 REMARKS:
7525 Handles opcode 0xaa
7526 ****************************************************************************/
7527 static void x86emuOp_stos_byte(u8 X86EMU_UNUSED(op1))
7528 {
7529 int inc;
7530
7531 START_OF_INSTR();
7532 DECODE_PRINTF("STOS\tBYTE\n");
7533 if (ACCESS_FLAG(F_DF)) /* down */
7534 inc = -1;
7535 else
7536 inc = 1;
7537 TRACE_AND_STEP();
7538 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7539 /* dont care whether REPE or REPNE */
7540 /* move them until CX is ZERO. */
7541 while (M.x86.R_CX != 0) {
7542 store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL);
7543 M.x86.R_CX -= 1;
7544 M.x86.R_DI += inc;
7545 }
7546 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7547 } else {
7548 store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL);
7549 M.x86.R_DI += inc;
7550 }
7551 DECODE_CLEAR_SEGOVR();
7552 END_OF_INSTR();
7553 }
7554
7555 /****************************************************************************
7556 REMARKS:
7557 Handles opcode 0xab
7558 ****************************************************************************/
7559 static void x86emuOp_stos_word(u8 X86EMU_UNUSED(op1))
7560 {
7561 int inc;
7562 u32 count;
7563
7564 START_OF_INSTR();
7565 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7566 DECODE_PRINTF("STOS\tDWORD\n");
7567 if (ACCESS_FLAG(F_DF)) /* down */
7568 inc = -4;
7569 else
7570 inc = 4;
7571 } else {
7572 DECODE_PRINTF("STOS\tWORD\n");
7573 if (ACCESS_FLAG(F_DF)) /* down */
7574 inc = -2;
7575 else
7576 inc = 2;
7577 }
7578 TRACE_AND_STEP();
7579 count = 1;
7580 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7581 /* dont care whether REPE or REPNE */
7582 /* move them until CX is ZERO. */
7583 count = M.x86.R_CX;
7584 M.x86.R_CX = 0;
7585 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7586 }
7587 while (count--) {
7588 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7589 store_data_long_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_EAX);
7590 } else {
7591 store_data_word_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AX);
7592 }
7593 M.x86.R_DI += inc;
7594 }
7595 DECODE_CLEAR_SEGOVR();
7596 END_OF_INSTR();
7597 }
7598
7599 /****************************************************************************
7600 REMARKS:
7601 Handles opcode 0xac
7602 ****************************************************************************/
7603 static void x86emuOp_lods_byte(u8 X86EMU_UNUSED(op1))
7604 {
7605 int inc;
7606
7607 START_OF_INSTR();
7608 DECODE_PRINTF("LODS\tBYTE\n");
7609 TRACE_AND_STEP();
7610 if (ACCESS_FLAG(F_DF)) /* down */
7611 inc = -1;
7612 else
7613 inc = 1;
7614 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7615 /* dont care whether REPE or REPNE */
7616 /* move them until CX is ZERO. */
7617 while (M.x86.R_CX != 0) {
7618 M.x86.R_AL = fetch_data_byte(M.x86.R_SI);
7619 M.x86.R_CX -= 1;
7620 M.x86.R_SI += inc;
7621 }
7622 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7623 } else {
7624 M.x86.R_AL = fetch_data_byte(M.x86.R_SI);
7625 M.x86.R_SI += inc;
7626 }
7627 DECODE_CLEAR_SEGOVR();
7628 END_OF_INSTR();
7629 }
7630
7631 /****************************************************************************
7632 REMARKS:
7633 Handles opcode 0xad
7634 ****************************************************************************/
7635 static void x86emuOp_lods_word(u8 X86EMU_UNUSED(op1))
7636 {
7637 int inc;
7638 u32 count;
7639
7640 START_OF_INSTR();
7641 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7642 DECODE_PRINTF("LODS\tDWORD\n");
7643 if (ACCESS_FLAG(F_DF)) /* down */
7644 inc = -4;
7645 else
7646 inc = 4;
7647 } else {
7648 DECODE_PRINTF("LODS\tWORD\n");
7649 if (ACCESS_FLAG(F_DF)) /* down */
7650 inc = -2;
7651 else
7652 inc = 2;
7653 }
7654 TRACE_AND_STEP();
7655 count = 1;
7656 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7657 /* dont care whether REPE or REPNE */
7658 /* move them until CX is ZERO. */
7659 count = M.x86.R_CX;
7660 M.x86.R_CX = 0;
7661 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7662 }
7663 while (count--) {
7664 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7665 M.x86.R_EAX = fetch_data_long(M.x86.R_SI);
7666 } else {
7667 M.x86.R_AX = fetch_data_word(M.x86.R_SI);
7668 }
7669 M.x86.R_SI += inc;
7670 }
7671 DECODE_CLEAR_SEGOVR();
7672 END_OF_INSTR();
7673 }
7674
7675 /****************************************************************************
7676 REMARKS:
7677 Handles opcode 0xae
7678 ****************************************************************************/
7679 static void x86emuOp_scas_byte(u8 X86EMU_UNUSED(op1))
7680 {
7681 s8 val2;
7682 int inc;
7683
7684 START_OF_INSTR();
7685 DECODE_PRINTF("SCAS\tBYTE\n");
7686 TRACE_AND_STEP();
7687 if (ACCESS_FLAG(F_DF)) /* down */
7688 inc = -1;
7689 else
7690 inc = 1;
7691 if (M.x86.mode & SYSMODE_PREFIX_REPE) {
7692 /* REPE */
7693 /* move them until CX is ZERO. */
7694 while (M.x86.R_CX != 0) {
7695 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7696 cmp_byte(M.x86.R_AL, val2);
7697 M.x86.R_CX -= 1;
7698 M.x86.R_DI += inc;
7699 if (ACCESS_FLAG(F_ZF) == 0)
7700 break;
7701 }
7702 M.x86.mode &= ~SYSMODE_PREFIX_REPE;
7703 } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
7704 /* REPNE */
7705 /* move them until CX is ZERO. */
7706 while (M.x86.R_CX != 0) {
7707 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7708 cmp_byte(M.x86.R_AL, val2);
7709 M.x86.R_CX -= 1;
7710 M.x86.R_DI += inc;
7711 if (ACCESS_FLAG(F_ZF))
7712 break; /* zero flag set means equal */
7713 }
7714 M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
7715 } else {
7716 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7717 cmp_byte(M.x86.R_AL, val2);
7718 M.x86.R_DI += inc;
7719 }
7720 DECODE_CLEAR_SEGOVR();
7721 END_OF_INSTR();
7722 }
7723
7724 /****************************************************************************
7725 REMARKS:
7726 Handles opcode 0xaf
7727 ****************************************************************************/
7728 static void x86emuOp_scas_word(u8 X86EMU_UNUSED(op1))
7729 {
7730 int inc;
7731 u32 val;
7732
7733 START_OF_INSTR();
7734 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7735 DECODE_PRINTF("SCAS\tDWORD\n");
7736 if (ACCESS_FLAG(F_DF)) /* down */
7737 inc = -4;
7738 else
7739 inc = 4;
7740 } else {
7741 DECODE_PRINTF("SCAS\tWORD\n");
7742 if (ACCESS_FLAG(F_DF)) /* down */
7743 inc = -2;
7744 else
7745 inc = 2;
7746 }
7747 TRACE_AND_STEP();
7748 if (M.x86.mode & SYSMODE_PREFIX_REPE) {
7749 /* REPE */
7750 /* move them until CX is ZERO. */
7751 while (M.x86.R_CX != 0) {
7752 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7753 val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7754 cmp_long(M.x86.R_EAX, val);
7755 } else {
7756 val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7757 cmp_word(M.x86.R_AX, (u16)val);
7758 }
7759 M.x86.R_CX -= 1;
7760 M.x86.R_DI += inc;
7761 if (ACCESS_FLAG(F_ZF) == 0)
7762 break;
7763 }
7764 M.x86.mode &= ~SYSMODE_PREFIX_REPE;
7765 } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
7766 /* REPNE */
7767 /* move them until CX is ZERO. */
7768 while (M.x86.R_CX != 0) {
7769 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7770 val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7771 cmp_long(M.x86.R_EAX, val);
7772 } else {
7773 val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7774 cmp_word(M.x86.R_AX, (u16)val);
7775 }
7776 M.x86.R_CX -= 1;
7777 M.x86.R_DI += inc;
7778 if (ACCESS_FLAG(F_ZF))
7779 break; /* zero flag set means equal */
7780 }
7781 M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
7782 } else {
7783 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7784 val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7785 cmp_long(M.x86.R_EAX, val);
7786 } else {
7787 val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7788 cmp_word(M.x86.R_AX, (u16)val);
7789 }
7790 M.x86.R_DI += inc;
7791 }
7792 DECODE_CLEAR_SEGOVR();
7793 END_OF_INSTR();
7794 }
7795
7796 /****************************************************************************
7797 REMARKS:
7798 Handles opcode 0xb0
7799 ****************************************************************************/
7800 static void x86emuOp_mov_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
7801 {
7802 u8 imm;
7803
7804 START_OF_INSTR();
7805 DECODE_PRINTF("MOV\tAL,");
7806 imm = fetch_byte_imm();
7807 DECODE_PRINTF2("%x\n", imm);
7808 TRACE_AND_STEP();
7809 M.x86.R_AL = imm;
7810 DECODE_CLEAR_SEGOVR();
7811 END_OF_INSTR();
7812 }
7813
7814 /****************************************************************************
7815 REMARKS:
7816 Handles opcode 0xb1
7817 ****************************************************************************/
7818 static void x86emuOp_mov_byte_CL_IMM(u8 X86EMU_UNUSED(op1))
7819 {
7820 u8 imm;
7821
7822 START_OF_INSTR();
7823 DECODE_PRINTF("MOV\tCL,");
7824 imm = fetch_byte_imm();
7825 DECODE_PRINTF2("%x\n", imm);
7826 TRACE_AND_STEP();
7827 M.x86.R_CL = imm;
7828 DECODE_CLEAR_SEGOVR();
7829 END_OF_INSTR();
7830 }
7831
7832 /****************************************************************************
7833 REMARKS:
7834 Handles opcode 0xb2
7835 ****************************************************************************/
7836 static void x86emuOp_mov_byte_DL_IMM(u8 X86EMU_UNUSED(op1))
7837 {
7838 u8 imm;
7839
7840 START_OF_INSTR();
7841 DECODE_PRINTF("MOV\tDL,");
7842 imm = fetch_byte_imm();
7843 DECODE_PRINTF2("%x\n", imm);
7844 TRACE_AND_STEP();
7845 M.x86.R_DL = imm;
7846 DECODE_CLEAR_SEGOVR();
7847 END_OF_INSTR();
7848 }
7849
7850 /****************************************************************************
7851 REMARKS:
7852 Handles opcode 0xb3
7853 ****************************************************************************/
7854 static void x86emuOp_mov_byte_BL_IMM(u8 X86EMU_UNUSED(op1))
7855 {
7856 u8 imm;
7857
7858 START_OF_INSTR();
7859 DECODE_PRINTF("MOV\tBL,");
7860 imm = fetch_byte_imm();
7861 DECODE_PRINTF2("%x\n", imm);
7862 TRACE_AND_STEP();
7863 M.x86.R_BL = imm;
7864 DECODE_CLEAR_SEGOVR();
7865 END_OF_INSTR();
7866 }
7867
7868 /****************************************************************************
7869 REMARKS:
7870 Handles opcode 0xb4
7871 ****************************************************************************/
7872 static void x86emuOp_mov_byte_AH_IMM(u8 X86EMU_UNUSED(op1))
7873 {
7874 u8 imm;
7875
7876 START_OF_INSTR();
7877 DECODE_PRINTF("MOV\tAH,");
7878 imm = fetch_byte_imm();
7879 DECODE_PRINTF2("%x\n", imm);
7880 TRACE_AND_STEP();
7881 M.x86.R_AH = imm;
7882 DECODE_CLEAR_SEGOVR();
7883 END_OF_INSTR();
7884 }
7885
7886 /****************************************************************************
7887 REMARKS:
7888 Handles opcode 0xb5
7889 ****************************************************************************/
7890 static void x86emuOp_mov_byte_CH_IMM(u8 X86EMU_UNUSED(op1))
7891 {
7892 u8 imm;
7893
7894 START_OF_INSTR();
7895 DECODE_PRINTF("MOV\tCH,");
7896 imm = fetch_byte_imm();
7897 DECODE_PRINTF2("%x\n", imm);
7898 TRACE_AND_STEP();
7899 M.x86.R_CH = imm;
7900 DECODE_CLEAR_SEGOVR();
7901 END_OF_INSTR();
7902 }
7903
7904 /****************************************************************************
7905 REMARKS:
7906 Handles opcode 0xb6
7907 ****************************************************************************/
7908 static void x86emuOp_mov_byte_DH_IMM(u8 X86EMU_UNUSED(op1))
7909 {
7910 u8 imm;
7911
7912 START_OF_INSTR();
7913 DECODE_PRINTF("MOV\tDH,");
7914 imm = fetch_byte_imm();
7915 DECODE_PRINTF2("%x\n", imm);
7916 TRACE_AND_STEP();
7917 M.x86.R_DH = imm;
7918 DECODE_CLEAR_SEGOVR();
7919 END_OF_INSTR();
7920 }
7921
7922 /****************************************************************************
7923 REMARKS:
7924 Handles opcode 0xb7
7925 ****************************************************************************/
7926 static void x86emuOp_mov_byte_BH_IMM(u8 X86EMU_UNUSED(op1))
7927 {
7928 u8 imm;
7929
7930 START_OF_INSTR();
7931 DECODE_PRINTF("MOV\tBH,");
7932 imm = fetch_byte_imm();
7933 DECODE_PRINTF2("%x\n", imm);
7934 TRACE_AND_STEP();
7935 M.x86.R_BH = imm;
7936 DECODE_CLEAR_SEGOVR();
7937 END_OF_INSTR();
7938 }
7939
7940 /****************************************************************************
7941 REMARKS:
7942 Handles opcode 0xb8
7943 ****************************************************************************/
7944 static void x86emuOp_mov_word_AX_IMM(u8 X86EMU_UNUSED(op1))
7945 {
7946 u32 srcval;
7947
7948 START_OF_INSTR();
7949 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7950 DECODE_PRINTF("MOV\tEAX,");
7951 srcval = fetch_long_imm();
7952 } else {
7953 DECODE_PRINTF("MOV\tAX,");
7954 srcval = fetch_word_imm();
7955 }
7956 DECODE_PRINTF2("%x\n", srcval);
7957 TRACE_AND_STEP();
7958 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7959 M.x86.R_EAX = srcval;
7960 } else {
7961 M.x86.R_AX = (u16)srcval;
7962 }
7963 DECODE_CLEAR_SEGOVR();
7964 END_OF_INSTR();
7965 }
7966
7967 /****************************************************************************
7968 REMARKS:
7969 Handles opcode 0xb9
7970 ****************************************************************************/
7971 static void x86emuOp_mov_word_CX_IMM(u8 X86EMU_UNUSED(op1))
7972 {
7973 u32 srcval;
7974
7975 START_OF_INSTR();
7976 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7977 DECODE_PRINTF("MOV\tECX,");
7978 srcval = fetch_long_imm();
7979 } else {
7980 DECODE_PRINTF("MOV\tCX,");
7981 srcval = fetch_word_imm();
7982 }
7983 DECODE_PRINTF2("%x\n", srcval);
7984 TRACE_AND_STEP();
7985 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7986 M.x86.R_ECX = srcval;
7987 } else {
7988 M.x86.R_CX = (u16)srcval;
7989 }
7990 DECODE_CLEAR_SEGOVR();
7991 END_OF_INSTR();
7992 }
7993
7994 /****************************************************************************
7995 REMARKS:
7996 Handles opcode 0xba
7997 ****************************************************************************/
7998 static void x86emuOp_mov_word_DX_IMM(u8 X86EMU_UNUSED(op1))
7999 {
8000 u32 srcval;
8001
8002 START_OF_INSTR();
8003 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8004 DECODE_PRINTF("MOV\tEDX,");
8005 srcval = fetch_long_imm();
8006 } else {
8007 DECODE_PRINTF("MOV\tDX,");
8008 srcval = fetch_word_imm();
8009 }
8010 DECODE_PRINTF2("%x\n", srcval);
8011 TRACE_AND_STEP();
8012 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8013 M.x86.R_EDX = srcval;
8014 } else {
8015 M.x86.R_DX = (u16)srcval;
8016 }
8017 DECODE_CLEAR_SEGOVR();
8018 END_OF_INSTR();
8019 }
8020
8021 /****************************************************************************
8022 REMARKS:
8023 Handles opcode 0xbb
8024 ****************************************************************************/
8025 static void x86emuOp_mov_word_BX_IMM(u8 X86EMU_UNUSED(op1))
8026 {
8027 u32 srcval;
8028
8029 START_OF_INSTR();
8030 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8031 DECODE_PRINTF("MOV\tEBX,");
8032 srcval = fetch_long_imm();
8033 } else {
8034 DECODE_PRINTF("MOV\tBX,");
8035 srcval = fetch_word_imm();
8036 }
8037 DECODE_PRINTF2("%x\n", srcval);
8038 TRACE_AND_STEP();
8039 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8040 M.x86.R_EBX = srcval;
8041 } else {
8042 M.x86.R_BX = (u16)srcval;
8043 }
8044 DECODE_CLEAR_SEGOVR();
8045 END_OF_INSTR();
8046 }
8047
8048 /****************************************************************************
8049 REMARKS:
8050 Handles opcode 0xbc
8051 ****************************************************************************/
8052 static void x86emuOp_mov_word_SP_IMM(u8 X86EMU_UNUSED(op1))
8053 {
8054 u32 srcval;
8055
8056 START_OF_INSTR();
8057 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8058 DECODE_PRINTF("MOV\tESP,");
8059 srcval = fetch_long_imm();
8060 } else {
8061 DECODE_PRINTF("MOV\tSP,");
8062 srcval = fetch_word_imm();
8063 }
8064 DECODE_PRINTF2("%x\n", srcval);
8065 TRACE_AND_STEP();
8066 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8067 M.x86.R_ESP = srcval;
8068 } else {
8069 M.x86.R_SP = (u16)srcval;
8070 }
8071 DECODE_CLEAR_SEGOVR();
8072 END_OF_INSTR();
8073 }
8074
8075 /****************************************************************************
8076 REMARKS:
8077 Handles opcode 0xbd
8078 ****************************************************************************/
8079 static void x86emuOp_mov_word_BP_IMM(u8 X86EMU_UNUSED(op1))
8080 {
8081 u32 srcval;
8082
8083 START_OF_INSTR();
8084 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8085 DECODE_PRINTF("MOV\tEBP,");
8086 srcval = fetch_long_imm();
8087 } else {
8088 DECODE_PRINTF("MOV\tBP,");
8089 srcval = fetch_word_imm();
8090 }
8091 DECODE_PRINTF2("%x\n", srcval);
8092 TRACE_AND_STEP();
8093 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8094 M.x86.R_EBP = srcval;
8095 } else {
8096 M.x86.R_BP = (u16)srcval;
8097 }
8098 DECODE_CLEAR_SEGOVR();
8099 END_OF_INSTR();
8100 }
8101
8102 /****************************************************************************
8103 REMARKS:
8104 Handles opcode 0xbe
8105 ****************************************************************************/
8106 static void x86emuOp_mov_word_SI_IMM(u8 X86EMU_UNUSED(op1))
8107 {
8108 u32 srcval;
8109
8110 START_OF_INSTR();
8111 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8112 DECODE_PRINTF("MOV\tESI,");
8113 srcval = fetch_long_imm();
8114 } else {
8115 DECODE_PRINTF("MOV\tSI,");
8116 srcval = fetch_word_imm();
8117 }
8118 DECODE_PRINTF2("%x\n", srcval);
8119 TRACE_AND_STEP();
8120 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8121 M.x86.R_ESI = srcval;
8122 } else {
8123 M.x86.R_SI = (u16)srcval;
8124 }
8125 DECODE_CLEAR_SEGOVR();
8126 END_OF_INSTR();
8127 }
8128
8129 /****************************************************************************
8130 REMARKS:
8131 Handles opcode 0xbf
8132 ****************************************************************************/
8133 static void x86emuOp_mov_word_DI_IMM(u8 X86EMU_UNUSED(op1))
8134 {
8135 u32 srcval;
8136
8137 START_OF_INSTR();
8138 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8139 DECODE_PRINTF("MOV\tEDI,");
8140 srcval = fetch_long_imm();
8141 } else {
8142 DECODE_PRINTF("MOV\tDI,");
8143 srcval = fetch_word_imm();
8144 }
8145 DECODE_PRINTF2("%x\n", srcval);
8146 TRACE_AND_STEP();
8147 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8148 M.x86.R_EDI = srcval;
8149 } else {
8150 M.x86.R_DI = (u16)srcval;
8151 }
8152 DECODE_CLEAR_SEGOVR();
8153 END_OF_INSTR();
8154 }
8155
8156 /* used by opcodes c0, d0, and d2. */
8157 static u8(*opcD0_byte_operation[])(u8 d, u8 s) =
8158 {
8159 rol_byte,
8160 ror_byte,
8161 rcl_byte,
8162 rcr_byte,
8163 shl_byte,
8164 shr_byte,
8165 shl_byte, /* sal_byte === shl_byte by definition */
8166 sar_byte,
8167 };
8168
8169 /****************************************************************************
8170 REMARKS:
8171 Handles opcode 0xc0
8172 ****************************************************************************/
8173 static void x86emuOp_opcC0_byte_RM_MEM(u8 X86EMU_UNUSED(op1))
8174 {
8175 int mod, rl, rh;
8176 u8 *destreg;
8177 uint destoffset;
8178 u8 destval;
8179 u8 amt;
8180
8181 /*
8182 * Yet another weirdo special case instruction format. Part of
8183 * the opcode held below in "RH". Doubly nested case would
8184 * result, except that the decoded instruction
8185 */
8186 START_OF_INSTR();
8187 FETCH_DECODE_MODRM(mod, rh, rl);
8188 #ifdef DEBUG
8189 if (DEBUG_DECODE()) {
8190 /* XXX DECODE_PRINTF may be changed to something more
8191 general, so that it is important to leave the strings
8192 in the same format, even though the result is that the
8193 above test is done twice. */
8194
8195 switch (rh) {
8196 case 0:
8197 DECODE_PRINTF("ROL\t");
8198 break;
8199 case 1:
8200 DECODE_PRINTF("ROR\t");
8201 break;
8202 case 2:
8203 DECODE_PRINTF("RCL\t");
8204 break;
8205 case 3:
8206 DECODE_PRINTF("RCR\t");
8207 break;
8208 case 4:
8209 DECODE_PRINTF("SHL\t");
8210 break;
8211 case 5:
8212 DECODE_PRINTF("SHR\t");
8213 break;
8214 case 6:
8215 DECODE_PRINTF("SAL\t");
8216 break;
8217 case 7:
8218 DECODE_PRINTF("SAR\t");
8219 break;
8220 }
8221 }
8222 #endif
8223 /* know operation, decode the mod byte to find the addressing
8224 mode. */
8225 switch (mod) {
8226 case 0:
8227 DECODE_PRINTF("BYTE PTR ");
8228 destoffset = decode_rm00_address(rl);
8229 amt = fetch_byte_imm();
8230 DECODE_PRINTF2(",%x\n", amt);
8231 destval = fetch_data_byte(destoffset);
8232 TRACE_AND_STEP();
8233 destval = (*opcD0_byte_operation[rh]) (destval, amt);
8234 store_data_byte(destoffset, destval);
8235 break;
8236 case 1:
8237 DECODE_PRINTF("BYTE PTR ");
8238 destoffset = decode_rm01_address(rl);
8239 amt = fetch_byte_imm();
8240 DECODE_PRINTF2(",%x\n", amt);
8241 destval = fetch_data_byte(destoffset);
8242 TRACE_AND_STEP();
8243 destval = (*opcD0_byte_operation[rh]) (destval, amt);
8244 store_data_byte(destoffset, destval);
8245 break;
8246 case 2:
8247 DECODE_PRINTF("BYTE PTR ");
8248 destoffset = decode_rm10_address(rl);
8249 amt = fetch_byte_imm();
8250 DECODE_PRINTF2(",%x\n", amt);
8251 destval = fetch_data_byte(destoffset);
8252 TRACE_AND_STEP();
8253 destval = (*opcD0_byte_operation[rh]) (destval, amt);
8254 store_data_byte(destoffset, destval);
8255 break;
8256 case 3: /* register to register */
8257 destreg = DECODE_RM_BYTE_REGISTER(rl);
8258 amt = fetch_byte_imm();
8259 DECODE_PRINTF2(",%x\n", amt);
8260 TRACE_AND_STEP();
8261 destval = (*opcD0_byte_operation[rh]) (*destreg, amt);
8262 *destreg = destval;
8263 break;
8264 }
8265 DECODE_CLEAR_SEGOVR();
8266 END_OF_INSTR();
8267 }
8268
8269 /* used by opcodes c1, d1, and d3. */
8270 static u16(*opcD1_word_operation[])(u16 s, u8 d) =
8271 {
8272 rol_word,
8273 ror_word,
8274 rcl_word,
8275 rcr_word,
8276 shl_word,
8277 shr_word,
8278 shl_word, /* sal_byte === shl_byte by definition */
8279 sar_word,
8280 };
8281
8282 /* used by opcodes c1, d1, and d3. */
8283 static u32 (*opcD1_long_operation[])(u32 s, u8 d) =
8284 {
8285 rol_long,
8286 ror_long,
8287 rcl_long,
8288 rcr_long,
8289 shl_long,
8290 shr_long,
8291 shl_long, /* sal_byte === shl_byte by definition */
8292 sar_long,
8293 };
8294
8295 /****************************************************************************
8296 REMARKS:
8297 Handles opcode 0xc1
8298 ****************************************************************************/
8299 static void x86emuOp_opcC1_word_RM_MEM(u8 X86EMU_UNUSED(op1))
8300 {
8301 int mod, rl, rh;
8302 uint destoffset;
8303 u8 amt;
8304
8305 /*
8306 * Yet another weirdo special case instruction format. Part of
8307 * the opcode held below in "RH". Doubly nested case would
8308 * result, except that the decoded instruction
8309 */
8310 START_OF_INSTR();
8311 FETCH_DECODE_MODRM(mod, rh, rl);
8312 #ifdef DEBUG
8313 if (DEBUG_DECODE()) {
8314 /* XXX DECODE_PRINTF may be changed to something more
8315 general, so that it is important to leave the strings
8316 in the same format, even though the result is that the
8317 above test is done twice. */
8318
8319 switch (rh) {
8320 case 0:
8321 DECODE_PRINTF("ROL\t");
8322 break;
8323 case 1:
8324 DECODE_PRINTF("ROR\t");
8325 break;
8326 case 2:
8327 DECODE_PRINTF("RCL\t");
8328 break;
8329 case 3:
8330 DECODE_PRINTF("RCR\t");
8331 break;
8332 case 4:
8333 DECODE_PRINTF("SHL\t");
8334 break;
8335 case 5:
8336 DECODE_PRINTF("SHR\t");
8337 break;
8338 case 6:
8339 DECODE_PRINTF("SAL\t");
8340 break;
8341 case 7:
8342 DECODE_PRINTF("SAR\t");
8343 break;
8344 }
8345 }
8346 #endif
8347 /* know operation, decode the mod byte to find the addressing
8348 mode. */
8349 switch (mod) {
8350 case 0:
8351 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8352 u32 destval;
8353
8354 DECODE_PRINTF("DWORD PTR ");
8355 destoffset = decode_rm00_address(rl);
8356 amt = fetch_byte_imm();
8357 DECODE_PRINTF2(",%x\n", amt);
8358 destval = fetch_data_long(destoffset);
8359 TRACE_AND_STEP();
8360 destval = (*opcD1_long_operation[rh]) (destval, amt);
8361 store_data_long(destoffset, destval);
8362 } else {
8363 u16 destval;
8364
8365 DECODE_PRINTF("WORD PTR ");
8366 destoffset = decode_rm00_address(rl);
8367 amt = fetch_byte_imm();
8368 DECODE_PRINTF2(",%x\n", amt);
8369 destval = fetch_data_word(destoffset);
8370 TRACE_AND_STEP();
8371 destval = (*opcD1_word_operation[rh]) (destval, amt);
8372 store_data_word(destoffset, destval);
8373 }
8374 break;
8375 case 1:
8376 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8377 u32 destval;
8378
8379 DECODE_PRINTF("DWORD PTR ");
8380 destoffset = decode_rm01_address(rl);
8381 amt = fetch_byte_imm();
8382 DECODE_PRINTF2(",%x\n", amt);
8383 destval = fetch_data_long(destoffset);
8384 TRACE_AND_STEP();
8385 destval = (*opcD1_long_operation[rh]) (destval, amt);
8386 store_data_long(destoffset, destval);
8387 } else {
8388 u16 destval;
8389
8390 DECODE_PRINTF("WORD PTR ");
8391 destoffset = decode_rm01_address(rl);
8392 amt = fetch_byte_imm();
8393 DECODE_PRINTF2(",%x\n", amt);
8394 destval = fetch_data_word(destoffset);
8395 TRACE_AND_STEP();
8396 destval = (*opcD1_word_operation[rh]) (destval, amt);
8397 store_data_word(destoffset, destval);
8398 }
8399 break;
8400 case 2:
8401 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8402 u32 destval;
8403
8404 DECODE_PRINTF("DWORD PTR ");
8405 destoffset = decode_rm10_address(rl);
8406 amt = fetch_byte_imm();
8407 DECODE_PRINTF2(",%x\n", amt);
8408 destval = fetch_data_long(destoffset);
8409 TRACE_AND_STEP();
8410 destval = (*opcD1_long_operation[rh]) (destval, amt);
8411 store_data_long(destoffset, destval);
8412 } else {
8413 u16 destval;
8414
8415 DECODE_PRINTF("WORD PTR ");
8416 destoffset = decode_rm10_address(rl);
8417 amt = fetch_byte_imm();
8418 DECODE_PRINTF2(",%x\n", amt);
8419 destval = fetch_data_word(destoffset);
8420 TRACE_AND_STEP();
8421 destval = (*opcD1_word_operation[rh]) (destval, amt);
8422 store_data_word(destoffset, destval);
8423 }
8424 break;
8425 case 3: /* register to register */
8426 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8427 u32 *destreg;
8428
8429 destreg = DECODE_RM_LONG_REGISTER(rl);
8430 amt = fetch_byte_imm();
8431 DECODE_PRINTF2(",%x\n", amt);
8432 TRACE_AND_STEP();
8433 *destreg = (*opcD1_long_operation[rh]) (*destreg, amt);
8434 } else {
8435 u16 *destreg;
8436
8437 destreg = DECODE_RM_WORD_REGISTER(rl);
8438 amt = fetch_byte_imm();
8439 DECODE_PRINTF2(",%x\n", amt);
8440 TRACE_AND_STEP();
8441 *destreg = (*opcD1_word_operation[rh]) (*destreg, amt);
8442 }
8443 break;
8444 }
8445 DECODE_CLEAR_SEGOVR();
8446 END_OF_INSTR();
8447 }
8448
8449 /****************************************************************************
8450 REMARKS:
8451 Handles opcode 0xc2
8452 ****************************************************************************/
8453 static void x86emuOp_ret_near_IMM(u8 X86EMU_UNUSED(op1))
8454 {
8455 u16 imm;
8456
8457 START_OF_INSTR();
8458 DECODE_PRINTF("RET\t");
8459 imm = fetch_word_imm();
8460 DECODE_PRINTF2("%x\n", imm);
8461 RETURN_TRACE("RET",M.x86.saved_cs,M.x86.saved_ip);
8462 TRACE_AND_STEP();
8463 M.x86.R_IP = pop_word();
8464 M.x86.R_SP += imm;
8465 DECODE_CLEAR_SEGOVR();
8466 END_OF_INSTR();
8467 }
8468
8469 /****************************************************************************
8470 REMARKS:
8471 Handles opcode 0xc3
8472 ****************************************************************************/
8473 static void x86emuOp_ret_near(u8 X86EMU_UNUSED(op1))
8474 {
8475 START_OF_INSTR();
8476 DECODE_PRINTF("RET\n");
8477 RETURN_TRACE("RET",M.x86.saved_cs,M.x86.saved_ip);
8478 TRACE_AND_STEP();
8479 M.x86.R_IP = pop_word();
8480 DECODE_CLEAR_SEGOVR();
8481 END_OF_INSTR();
8482 }
8483
8484 /****************************************************************************
8485 REMARKS:
8486 Handles opcode 0xc4
8487 ****************************************************************************/
8488 static void x86emuOp_les_R_IMM(u8 X86EMU_UNUSED(op1))
8489 {
8490 int mod, rh, rl;
8491 u16 *dstreg;
8492 uint srcoffset;
8493
8494 START_OF_INSTR();
8495 DECODE_PRINTF("LES\t");
8496 FETCH_DECODE_MODRM(mod, rh, rl);
8497 switch (mod) {
8498 case 0:
8499 dstreg = DECODE_RM_WORD_REGISTER(rh);
8500 DECODE_PRINTF(",");
8501 srcoffset = decode_rm00_address(rl);
8502 DECODE_PRINTF("\n");
8503 TRACE_AND_STEP();
8504 *dstreg = fetch_data_word(srcoffset);
8505 M.x86.R_ES = fetch_data_word(srcoffset + 2);
8506 break;
8507 case 1:
8508 dstreg = DECODE_RM_WORD_REGISTER(rh);
8509 DECODE_PRINTF(",");
8510 srcoffset = decode_rm01_address(rl);
8511 DECODE_PRINTF("\n");
8512 TRACE_AND_STEP();
8513 *dstreg = fetch_data_word(srcoffset);
8514 M.x86.R_ES = fetch_data_word(srcoffset + 2);
8515 break;
8516 case 2:
8517 dstreg = DECODE_RM_WORD_REGISTER(rh);
8518 DECODE_PRINTF(",");
8519 srcoffset = decode_rm10_address(rl);
8520 DECODE_PRINTF("\n");
8521 TRACE_AND_STEP();
8522 *dstreg = fetch_data_word(srcoffset);
8523 M.x86.R_ES = fetch_data_word(srcoffset + 2);
8524 break;
8525 case 3: /* register to register */
8526 /* UNDEFINED! */
8527 TRACE_AND_STEP();
8528 }
8529 DECODE_CLEAR_SEGOVR();
8530 END_OF_INSTR();
8531 }
8532
8533 /****************************************************************************
8534 REMARKS:
8535 Handles opcode 0xc5
8536 ****************************************************************************/
8537 static void x86emuOp_lds_R_IMM(u8 X86EMU_UNUSED(op1))
8538 {
8539 int mod, rh, rl;
8540 u16 *dstreg;
8541 uint srcoffset;
8542
8543 START_OF_INSTR();
8544 DECODE_PRINTF("LDS\t");
8545 FETCH_DECODE_MODRM(mod, rh, rl);
8546 switch (mod) {
8547 case 0:
8548 dstreg = DECODE_RM_WORD_REGISTER(rh);
8549 DECODE_PRINTF(",");
8550 srcoffset = decode_rm00_address(rl);
8551 DECODE_PRINTF("\n");
8552 TRACE_AND_STEP();
8553 *dstreg = fetch_data_word(srcoffset);
8554 M.x86.R_DS = fetch_data_word(srcoffset + 2);
8555 break;
8556 case 1:
8557 dstreg = DECODE_RM_WORD_REGISTER(rh);
8558 DECODE_PRINTF(",");
8559 srcoffset = decode_rm01_address(rl);
8560 DECODE_PRINTF("\n");
8561 TRACE_AND_STEP();
8562 *dstreg = fetch_data_word(srcoffset);
8563 M.x86.R_DS = fetch_data_word(srcoffset + 2);
8564 break;
8565 case 2:
8566 dstreg = DECODE_RM_WORD_REGISTER(rh);
8567 DECODE_PRINTF(",");
8568 srcoffset = decode_rm10_address(rl);
8569 DECODE_PRINTF("\n");
8570 TRACE_AND_STEP();
8571 *dstreg = fetch_data_word(srcoffset);
8572 M.x86.R_DS = fetch_data_word(srcoffset + 2);
8573 break;
8574 case 3: /* register to register */
8575 /* UNDEFINED! */
8576 TRACE_AND_STEP();
8577 }
8578 DECODE_CLEAR_SEGOVR();
8579 END_OF_INSTR();
8580 }
8581
8582 /****************************************************************************
8583 REMARKS:
8584 Handles opcode 0xc6
8585 ****************************************************************************/
8586 static void x86emuOp_mov_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
8587 {
8588 int mod, rl, rh;
8589 u8 *destreg;
8590 uint destoffset;
8591 u8 imm;
8592
8593 START_OF_INSTR();
8594 DECODE_PRINTF("MOV\t");
8595 FETCH_DECODE_MODRM(mod, rh, rl);
8596 if (rh != 0) {
8597 DECODE_PRINTF("ILLEGAL DECODE OF OPCODE c6\n");
8598 HALT_SYS();
8599 }
8600 switch (mod) {
8601 case 0:
8602 DECODE_PRINTF("BYTE PTR ");
8603 destoffset = decode_rm00_address(rl);
8604 imm = fetch_byte_imm();
8605 DECODE_PRINTF2(",%2x\n", imm);
8606 TRACE_AND_STEP();
8607 store_data_byte(destoffset, imm);
8608 break;
8609 case 1:
8610 DECODE_PRINTF("BYTE PTR ");
8611 destoffset = decode_rm01_address(rl);
8612 imm = fetch_byte_imm();
8613 DECODE_PRINTF2(",%2x\n", imm);
8614 TRACE_AND_STEP();
8615 store_data_byte(destoffset, imm);
8616 break;
8617 case 2:
8618 DECODE_PRINTF("BYTE PTR ");
8619 destoffset = decode_rm10_address(rl);
8620 imm = fetch_byte_imm();
8621 DECODE_PRINTF2(",%2x\n", imm);
8622 TRACE_AND_STEP();
8623 store_data_byte(destoffset, imm);
8624 break;
8625 case 3: /* register to register */
8626 destreg = DECODE_RM_BYTE_REGISTER(rl);
8627 imm = fetch_byte_imm();
8628 DECODE_PRINTF2(",%2x\n", imm);
8629 TRACE_AND_STEP();
8630 *destreg = imm;
8631 break;
8632 }
8633 DECODE_CLEAR_SEGOVR();
8634 END_OF_INSTR();
8635 }
8636
8637 /****************************************************************************
8638 REMARKS:
8639 Handles opcode 0xc7
8640 ****************************************************************************/
8641 static void x86emuOp_mov_word_RM_IMM(u8 X86EMU_UNUSED(op1))
8642 {
8643 int mod, rl, rh;
8644 uint destoffset;
8645
8646 START_OF_INSTR();
8647 DECODE_PRINTF("MOV\t");
8648 FETCH_DECODE_MODRM(mod, rh, rl);
8649 if (rh != 0) {
8650 DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n");
8651 HALT_SYS();
8652 }
8653 switch (mod) {
8654 case 0:
8655 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8656 u32 imm;
8657
8658 DECODE_PRINTF("DWORD PTR ");
8659 destoffset = decode_rm00_address(rl);
8660 imm = fetch_long_imm();
8661 DECODE_PRINTF2(",%x\n", imm);
8662 TRACE_AND_STEP();
8663 store_data_long(destoffset, imm);
8664 } else {
8665 u16 imm;
8666
8667 DECODE_PRINTF("WORD PTR ");
8668 destoffset = decode_rm00_address(rl);
8669 imm = fetch_word_imm();
8670 DECODE_PRINTF2(",%x\n", imm);
8671 TRACE_AND_STEP();
8672 store_data_word(destoffset, imm);
8673 }
8674 break;
8675 case 1:
8676 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8677 u32 imm;
8678
8679 DECODE_PRINTF("DWORD PTR ");
8680 destoffset = decode_rm01_address(rl);
8681 imm = fetch_long_imm();
8682 DECODE_PRINTF2(",%x\n", imm);
8683 TRACE_AND_STEP();
8684 store_data_long(destoffset, imm);
8685 } else {
8686 u16 imm;
8687
8688 DECODE_PRINTF("WORD PTR ");
8689 destoffset = decode_rm01_address(rl);
8690 imm = fetch_word_imm();
8691 DECODE_PRINTF2(",%x\n", imm);
8692 TRACE_AND_STEP();
8693 store_data_word(destoffset, imm);
8694 }
8695 break;
8696 case 2:
8697 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8698 u32 imm;
8699
8700 DECODE_PRINTF("DWORD PTR ");
8701 destoffset = decode_rm10_address(rl);
8702 imm = fetch_long_imm();
8703 DECODE_PRINTF2(",%x\n", imm);
8704 TRACE_AND_STEP();
8705 store_data_long(destoffset, imm);
8706 } else {
8707 u16 imm;
8708
8709 DECODE_PRINTF("WORD PTR ");
8710 destoffset = decode_rm10_address(rl);
8711 imm = fetch_word_imm();
8712 DECODE_PRINTF2(",%x\n", imm);
8713 TRACE_AND_STEP();
8714 store_data_word(destoffset, imm);
8715 }
8716 break;
8717 case 3: /* register to register */
8718 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8719 u32 *destreg;
8720 u32 imm;
8721
8722 destreg = DECODE_RM_LONG_REGISTER(rl);
8723 imm = fetch_long_imm();
8724 DECODE_PRINTF2(",%x\n", imm);
8725 TRACE_AND_STEP();
8726 *destreg = imm;
8727 } else {
8728 u16 *destreg;
8729 u16 imm;
8730
8731 destreg = DECODE_RM_WORD_REGISTER(rl);
8732 imm = fetch_word_imm();
8733 DECODE_PRINTF2(",%x\n", imm);
8734 TRACE_AND_STEP();
8735 *destreg = imm;
8736 }
8737 break;
8738 }
8739 DECODE_CLEAR_SEGOVR();
8740 END_OF_INSTR();
8741 }
8742
8743 /****************************************************************************
8744 REMARKS:
8745 Handles opcode 0xc8
8746 ****************************************************************************/
8747 static void x86emuOp_enter(u8 X86EMU_UNUSED(op1))
8748 {
8749 u16 local,frame_pointer;
8750 u8 nesting;
8751 int i;
8752
8753 START_OF_INSTR();
8754 local = fetch_word_imm();
8755 nesting = fetch_byte_imm();
8756 DECODE_PRINTF2("ENTER %x\n", local);
8757 DECODE_PRINTF2(",%x\n", nesting);
8758 TRACE_AND_STEP();
8759 push_word(M.x86.R_BP);
8760 frame_pointer = M.x86.R_SP;
8761 if (nesting > 0) {
8762 for (i = 1; i < nesting; i++) {
8763 M.x86.R_BP -= 2;
8764 push_word(fetch_data_word_abs(M.x86.R_SS, M.x86.R_BP));
8765 }
8766 push_word(frame_pointer);
8767 }
8768 M.x86.R_BP = frame_pointer;
8769 M.x86.R_SP = (u16)(M.x86.R_SP - local);
8770 DECODE_CLEAR_SEGOVR();
8771 END_OF_INSTR();
8772 }
8773
8774 /****************************************************************************
8775 REMARKS:
8776 Handles opcode 0xc9
8777 ****************************************************************************/
8778 static void x86emuOp_leave(u8 X86EMU_UNUSED(op1))
8779 {
8780 START_OF_INSTR();
8781 DECODE_PRINTF("LEAVE\n");
8782 TRACE_AND_STEP();
8783 M.x86.R_SP = M.x86.R_BP;
8784 M.x86.R_BP = pop_word();
8785 DECODE_CLEAR_SEGOVR();
8786 END_OF_INSTR();
8787 }
8788
8789 /****************************************************************************
8790 REMARKS:
8791 Handles opcode 0xca
8792 ****************************************************************************/
8793 static void x86emuOp_ret_far_IMM(u8 X86EMU_UNUSED(op1))
8794 {
8795 u16 imm;
8796
8797 START_OF_INSTR();
8798 DECODE_PRINTF("RETF\t");
8799 imm = fetch_word_imm();
8800 DECODE_PRINTF2("%x\n", imm);
8801 RETURN_TRACE("RETF",M.x86.saved_cs,M.x86.saved_ip);
8802 TRACE_AND_STEP();
8803 M.x86.R_IP = pop_word();
8804 M.x86.R_CS = pop_word();
8805 M.x86.R_SP += imm;
8806 DECODE_CLEAR_SEGOVR();
8807 END_OF_INSTR();
8808 }
8809
8810 /****************************************************************************
8811 REMARKS:
8812 Handles opcode 0xcb
8813 ****************************************************************************/
8814 static void x86emuOp_ret_far(u8 X86EMU_UNUSED(op1))
8815 {
8816 START_OF_INSTR();
8817 DECODE_PRINTF("RETF\n");
8818 RETURN_TRACE("RETF",M.x86.saved_cs,M.x86.saved_ip);
8819 TRACE_AND_STEP();
8820 M.x86.R_IP = pop_word();
8821 M.x86.R_CS = pop_word();
8822 DECODE_CLEAR_SEGOVR();
8823 END_OF_INSTR();
8824 }
8825
8826 /****************************************************************************
8827 REMARKS:
8828 Handles opcode 0xcc
8829 ****************************************************************************/
8830 static void x86emuOp_int3(u8 X86EMU_UNUSED(op1))
8831 {
8832 START_OF_INSTR();
8833 DECODE_PRINTF("INT 3\n");
8834 TRACE_AND_STEP();
8835 if (_X86EMU_intrTab[3]) {
8836 (*_X86EMU_intrTab[3])(3);
8837 } else {
8838 push_word((u16)M.x86.R_FLG);
8839 CLEAR_FLAG(F_IF);
8840 CLEAR_FLAG(F_TF);
8841 push_word(M.x86.R_CS);
8842 M.x86.R_CS = mem_access_word(3 * 4 + 2);
8843 push_word(M.x86.R_IP);
8844 M.x86.R_IP = mem_access_word(3 * 4);
8845 }
8846 DECODE_CLEAR_SEGOVR();
8847 END_OF_INSTR();
8848 }
8849
8850 /****************************************************************************
8851 REMARKS:
8852 Handles opcode 0xcd
8853 ****************************************************************************/
8854 static void x86emuOp_int_IMM(u8 X86EMU_UNUSED(op1))
8855 {
8856 u8 intnum;
8857
8858 START_OF_INSTR();
8859 DECODE_PRINTF("INT\t");
8860 intnum = fetch_byte_imm();
8861 DECODE_PRINTF2("%x\n", intnum);
8862 TRACE_AND_STEP();
8863 if (_X86EMU_intrTab[intnum]) {
8864 (*_X86EMU_intrTab[intnum])(intnum);
8865 } else {
8866 push_word((u16)M.x86.R_FLG);
8867 CLEAR_FLAG(F_IF);
8868 CLEAR_FLAG(F_TF);
8869 push_word(M.x86.R_CS);
8870 M.x86.R_CS = mem_access_word(intnum * 4 + 2);
8871 push_word(M.x86.R_IP);
8872 M.x86.R_IP = mem_access_word(intnum * 4);
8873 }
8874 DECODE_CLEAR_SEGOVR();
8875 END_OF_INSTR();
8876 }
8877
8878 /****************************************************************************
8879 REMARKS:
8880 Handles opcode 0xce
8881 ****************************************************************************/
8882 static void x86emuOp_into(u8 X86EMU_UNUSED(op1))
8883 {
8884 START_OF_INSTR();
8885 DECODE_PRINTF("INTO\n");
8886 TRACE_AND_STEP();
8887 if (ACCESS_FLAG(F_OF)) {
8888 if (_X86EMU_intrTab[4]) {
8889 (*_X86EMU_intrTab[4])(4);
8890 } else {
8891 push_word((u16)M.x86.R_FLG);
8892 CLEAR_FLAG(F_IF);
8893 CLEAR_FLAG(F_TF);
8894 push_word(M.x86.R_CS);
8895 M.x86.R_CS = mem_access_word(4 * 4 + 2);
8896 push_word(M.x86.R_IP);
8897 M.x86.R_IP = mem_access_word(4 * 4);
8898 }
8899 }
8900 DECODE_CLEAR_SEGOVR();
8901 END_OF_INSTR();
8902 }
8903
8904 /****************************************************************************
8905 REMARKS:
8906 Handles opcode 0xcf
8907 ****************************************************************************/
8908 static void x86emuOp_iret(u8 X86EMU_UNUSED(op1))
8909 {
8910 START_OF_INSTR();
8911 DECODE_PRINTF("IRET\n");
8912
8913 TRACE_AND_STEP();
8914
8915 M.x86.R_IP = pop_word();
8916 M.x86.R_CS = pop_word();
8917 M.x86.R_FLG = pop_word();
8918 DECODE_CLEAR_SEGOVR();
8919 END_OF_INSTR();
8920 }
8921
8922 /****************************************************************************
8923 REMARKS:
8924 Handles opcode 0xd0
8925 ****************************************************************************/
8926 static void x86emuOp_opcD0_byte_RM_1(u8 X86EMU_UNUSED(op1))
8927 {
8928 int mod, rl, rh;
8929 u8 *destreg;
8930 uint destoffset;
8931 u8 destval;
8932
8933 /*
8934 * Yet another weirdo special case instruction format. Part of
8935 * the opcode held below in "RH". Doubly nested case would
8936 * result, except that the decoded instruction
8937 */
8938 START_OF_INSTR();
8939 FETCH_DECODE_MODRM(mod, rh, rl);
8940 #ifdef DEBUG
8941 if (DEBUG_DECODE()) {
8942 /* XXX DECODE_PRINTF may be changed to something more
8943 general, so that it is important to leave the strings
8944 in the same format, even though the result is that the
8945 above test is done twice. */
8946 switch (rh) {
8947 case 0:
8948 DECODE_PRINTF("ROL\t");
8949 break;
8950 case 1:
8951 DECODE_PRINTF("ROR\t");
8952 break;
8953 case 2:
8954 DECODE_PRINTF("RCL\t");
8955 break;
8956 case 3:
8957 DECODE_PRINTF("RCR\t");
8958 break;
8959 case 4:
8960 DECODE_PRINTF("SHL\t");
8961 break;
8962 case 5:
8963 DECODE_PRINTF("SHR\t");
8964 break;
8965 case 6:
8966 DECODE_PRINTF("SAL\t");
8967 break;
8968 case 7:
8969 DECODE_PRINTF("SAR\t");
8970 break;
8971 }
8972 }
8973 #endif
8974 /* know operation, decode the mod byte to find the addressing
8975 mode. */
8976 switch (mod) {
8977 case 0:
8978 DECODE_PRINTF("BYTE PTR ");
8979 destoffset = decode_rm00_address(rl);
8980 DECODE_PRINTF(",1\n");
8981 destval = fetch_data_byte(destoffset);
8982 TRACE_AND_STEP();
8983 destval = (*opcD0_byte_operation[rh]) (destval, 1);
8984 store_data_byte(destoffset, destval);
8985 break;
8986 case 1:
8987 DECODE_PRINTF("BYTE PTR ");
8988 destoffset = decode_rm01_address(rl);
8989 DECODE_PRINTF(",1\n");
8990 destval = fetch_data_byte(destoffset);
8991 TRACE_AND_STEP();
8992 destval = (*opcD0_byte_operation[rh]) (destval, 1);
8993 store_data_byte(destoffset, destval);
8994 break;
8995 case 2:
8996 DECODE_PRINTF("BYTE PTR ");
8997 destoffset = decode_rm10_address(rl);
8998 DECODE_PRINTF(",1\n");
8999 destval = fetch_data_byte(destoffset);
9000 TRACE_AND_STEP();
9001 destval = (*opcD0_byte_operation[rh]) (destval, 1);
9002 store_data_byte(destoffset, destval);
9003 break;
9004 case 3: /* register to register */
9005 destreg = DECODE_RM_BYTE_REGISTER(rl);
9006 DECODE_PRINTF(",1\n");
9007 TRACE_AND_STEP();
9008 destval = (*opcD0_byte_operation[rh]) (*destreg, 1);
9009 *destreg = destval;
9010 break;
9011 }
9012 DECODE_CLEAR_SEGOVR();
9013 END_OF_INSTR();
9014 }
9015
9016 /****************************************************************************
9017 REMARKS:
9018 Handles opcode 0xd1
9019 ****************************************************************************/
9020 static void x86emuOp_opcD1_word_RM_1(u8 X86EMU_UNUSED(op1))
9021 {
9022 int mod, rl, rh;
9023 uint destoffset;
9024
9025 /*
9026 * Yet another weirdo special case instruction format. Part of
9027 * the opcode held below in "RH". Doubly nested case would
9028 * result, except that the decoded instruction
9029 */
9030 START_OF_INSTR();
9031 FETCH_DECODE_MODRM(mod, rh, rl);
9032 #ifdef DEBUG
9033 if (DEBUG_DECODE()) {
9034 /* XXX DECODE_PRINTF may be changed to something more
9035 general, so that it is important to leave the strings
9036 in the same format, even though the result is that the
9037 above test is done twice. */
9038 switch (rh) {
9039 case 0:
9040 DECODE_PRINTF("ROL\t");
9041 break;
9042 case 1:
9043 DECODE_PRINTF("ROR\t");
9044 break;
9045 case 2:
9046 DECODE_PRINTF("RCL\t");
9047 break;
9048 case 3:
9049 DECODE_PRINTF("RCR\t");
9050 break;
9051 case 4:
9052 DECODE_PRINTF("SHL\t");
9053 break;
9054 case 5:
9055 DECODE_PRINTF("SHR\t");
9056 break;
9057 case 6:
9058 DECODE_PRINTF("SAL\t");
9059 break;
9060 case 7:
9061 DECODE_PRINTF("SAR\t");
9062 break;
9063 }
9064 }
9065 #endif
9066 /* know operation, decode the mod byte to find the addressing
9067 mode. */
9068 switch (mod) {
9069 case 0:
9070 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9071 u32 destval;
9072
9073 DECODE_PRINTF("DWORD PTR ");
9074 destoffset = decode_rm00_address(rl);
9075 DECODE_PRINTF(",1\n");
9076 destval = fetch_data_long(destoffset);
9077 TRACE_AND_STEP();
9078 destval = (*opcD1_long_operation[rh]) (destval, 1);
9079 store_data_long(destoffset, destval);
9080 } else {
9081 u16 destval;
9082
9083 DECODE_PRINTF("WORD PTR ");
9084 destoffset = decode_rm00_address(rl);
9085 DECODE_PRINTF(",1\n");
9086 destval = fetch_data_word(destoffset);
9087 TRACE_AND_STEP();
9088 destval = (*opcD1_word_operation[rh]) (destval, 1);
9089 store_data_word(destoffset, destval);
9090 }
9091 break;
9092 case 1:
9093 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9094 u32 destval;
9095
9096 DECODE_PRINTF("DWORD PTR ");
9097 destoffset = decode_rm01_address(rl);
9098 DECODE_PRINTF(",1\n");
9099 destval = fetch_data_long(destoffset);
9100 TRACE_AND_STEP();
9101 destval = (*opcD1_long_operation[rh]) (destval, 1);
9102 store_data_long(destoffset, destval);
9103 } else {
9104 u16 destval;
9105
9106 DECODE_PRINTF("WORD PTR ");
9107 destoffset = decode_rm01_address(rl);
9108 DECODE_PRINTF(",1\n");
9109 destval = fetch_data_word(destoffset);
9110 TRACE_AND_STEP();
9111 destval = (*opcD1_word_operation[rh]) (destval, 1);
9112 store_data_word(destoffset, destval);
9113 }
9114 break;
9115 case 2:
9116 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9117 u32 destval;
9118
9119 DECODE_PRINTF("DWORD PTR ");
9120 destoffset = decode_rm10_address(rl);
9121 DECODE_PRINTF(",1\n");
9122 destval = fetch_data_long(destoffset);
9123 TRACE_AND_STEP();
9124 destval = (*opcD1_long_operation[rh]) (destval, 1);
9125 store_data_long(destoffset, destval);
9126 } else {
9127 u16 destval;
9128
9129 DECODE_PRINTF("BYTE PTR ");
9130 destoffset = decode_rm10_address(rl);
9131 DECODE_PRINTF(",1\n");
9132 destval = fetch_data_word(destoffset);
9133 TRACE_AND_STEP();
9134 destval = (*opcD1_word_operation[rh]) (destval, 1);
9135 store_data_word(destoffset, destval);
9136 }
9137 break;
9138 case 3: /* register to register */
9139 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9140 u32 destval;
9141 u32 *destreg;
9142
9143 destreg = DECODE_RM_LONG_REGISTER(rl);
9144 DECODE_PRINTF(",1\n");
9145 TRACE_AND_STEP();
9146 destval = (*opcD1_long_operation[rh]) (*destreg, 1);
9147 *destreg = destval;
9148 } else {
9149 u16 destval;
9150 u16 *destreg;
9151
9152 destreg = DECODE_RM_WORD_REGISTER(rl);
9153 DECODE_PRINTF(",1\n");
9154 TRACE_AND_STEP();
9155 destval = (*opcD1_word_operation[rh]) (*destreg, 1);
9156 *destreg = destval;
9157 }
9158 break;
9159 }
9160 DECODE_CLEAR_SEGOVR();
9161 END_OF_INSTR();
9162 }
9163
9164 /****************************************************************************
9165 REMARKS:
9166 Handles opcode 0xd2
9167 ****************************************************************************/
9168 static void x86emuOp_opcD2_byte_RM_CL(u8 X86EMU_UNUSED(op1))
9169 {
9170 int mod, rl, rh;
9171 u8 *destreg;
9172 uint destoffset;
9173 u8 destval;
9174 u8 amt;
9175
9176 /*
9177 * Yet another weirdo special case instruction format. Part of
9178 * the opcode held below in "RH". Doubly nested case would
9179 * result, except that the decoded instruction
9180 */
9181 START_OF_INSTR();
9182 FETCH_DECODE_MODRM(mod, rh, rl);
9183 #ifdef DEBUG
9184 if (DEBUG_DECODE()) {
9185 /* XXX DECODE_PRINTF may be changed to something more
9186 general, so that it is important to leave the strings
9187 in the same format, even though the result is that the
9188 above test is done twice. */
9189 switch (rh) {
9190 case 0:
9191 DECODE_PRINTF("ROL\t");
9192 break;
9193 case 1:
9194 DECODE_PRINTF("ROR\t");
9195 break;
9196 case 2:
9197 DECODE_PRINTF("RCL\t");
9198 break;
9199 case 3:
9200 DECODE_PRINTF("RCR\t");
9201 break;
9202 case 4:
9203 DECODE_PRINTF("SHL\t");
9204 break;
9205 case 5:
9206 DECODE_PRINTF("SHR\t");
9207 break;
9208 case 6:
9209 DECODE_PRINTF("SAL\t");
9210 break;
9211 case 7:
9212 DECODE_PRINTF("SAR\t");
9213 break;
9214 }
9215 }
9216 #endif
9217 /* know operation, decode the mod byte to find the addressing
9218 mode. */
9219 amt = M.x86.R_CL;
9220 switch (mod) {
9221 case 0:
9222 DECODE_PRINTF("BYTE PTR ");
9223 destoffset = decode_rm00_address(rl);
9224 DECODE_PRINTF(",CL\n");
9225 destval = fetch_data_byte(destoffset);
9226 TRACE_AND_STEP();
9227 destval = (*opcD0_byte_operation[rh]) (destval, amt);
9228 store_data_byte(destoffset, destval);
9229 break;
9230 case 1:
9231 DECODE_PRINTF("BYTE PTR ");
9232 destoffset = decode_rm01_address(rl);
9233 DECODE_PRINTF(",CL\n");
9234 destval = fetch_data_byte(destoffset);
9235 TRACE_AND_STEP();
9236 destval = (*opcD0_byte_operation[rh]) (destval, amt);
9237 store_data_byte(destoffset, destval);
9238 break;
9239 case 2:
9240 DECODE_PRINTF("BYTE PTR ");
9241 destoffset = decode_rm10_address(rl);
9242 DECODE_PRINTF(",CL\n");
9243 destval = fetch_data_byte(destoffset);
9244 TRACE_AND_STEP();
9245 destval = (*opcD0_byte_operation[rh]) (destval, amt);
9246 store_data_byte(destoffset, destval);
9247 break;
9248 case 3: /* register to register */
9249 destreg = DECODE_RM_BYTE_REGISTER(rl);
9250 DECODE_PRINTF(",CL\n");
9251 TRACE_AND_STEP();
9252 destval = (*opcD0_byte_operation[rh]) (*destreg, amt);
9253 *destreg = destval;
9254 break;
9255 }
9256 DECODE_CLEAR_SEGOVR();
9257 END_OF_INSTR();
9258 }
9259
9260 /****************************************************************************
9261 REMARKS:
9262 Handles opcode 0xd3
9263 ****************************************************************************/
9264 static void x86emuOp_opcD3_word_RM_CL(u8 X86EMU_UNUSED(op1))
9265 {
9266 int mod, rl, rh;
9267 uint destoffset;
9268 u8 amt;
9269
9270 /*
9271 * Yet another weirdo special case instruction format. Part of
9272 * the opcode held below in "RH". Doubly nested case would
9273 * result, except that the decoded instruction
9274 */
9275 START_OF_INSTR();
9276 FETCH_DECODE_MODRM(mod, rh, rl);
9277 #ifdef DEBUG
9278 if (DEBUG_DECODE()) {
9279 /* XXX DECODE_PRINTF may be changed to something more
9280 general, so that it is important to leave the strings
9281 in the same format, even though the result is that the
9282 above test is done twice. */
9283 switch (rh) {
9284 case 0:
9285 DECODE_PRINTF("ROL\t");
9286 break;
9287 case 1:
9288 DECODE_PRINTF("ROR\t");
9289 break;
9290 case 2:
9291 DECODE_PRINTF("RCL\t");
9292 break;
9293 case 3:
9294 DECODE_PRINTF("RCR\t");
9295 break;
9296 case 4:
9297 DECODE_PRINTF("SHL\t");
9298 break;
9299 case 5:
9300 DECODE_PRINTF("SHR\t");
9301 break;
9302 case 6:
9303 DECODE_PRINTF("SAL\t");
9304 break;
9305 case 7:
9306 DECODE_PRINTF("SAR\t");
9307 break;
9308 }
9309 }
9310 #endif
9311 /* know operation, decode the mod byte to find the addressing
9312 mode. */
9313 amt = M.x86.R_CL;
9314 switch (mod) {
9315 case 0:
9316 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9317 u32 destval;
9318
9319 DECODE_PRINTF("DWORD PTR ");
9320 destoffset = decode_rm00_address(rl);
9321 DECODE_PRINTF(",CL\n");
9322 destval = fetch_data_long(destoffset);
9323 TRACE_AND_STEP();
9324 destval = (*opcD1_long_operation[rh]) (destval, amt);
9325 store_data_long(destoffset, destval);
9326 } else {
9327 u16 destval;
9328
9329 DECODE_PRINTF("WORD PTR ");
9330 destoffset = decode_rm00_address(rl);
9331 DECODE_PRINTF(",CL\n");
9332 destval = fetch_data_word(destoffset);
9333 TRACE_AND_STEP();
9334 destval = (*opcD1_word_operation[rh]) (destval, amt);
9335 store_data_word(destoffset, destval);
9336 }
9337 break;
9338 case 1:
9339 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9340 u32 destval;
9341
9342 DECODE_PRINTF("DWORD PTR ");
9343 destoffset = decode_rm01_address(rl);
9344 DECODE_PRINTF(",CL\n");
9345 destval = fetch_data_long(destoffset);
9346 TRACE_AND_STEP();
9347 destval = (*opcD1_long_operation[rh]) (destval, amt);
9348 store_data_long(destoffset, destval);
9349 } else {
9350 u16 destval;
9351
9352 DECODE_PRINTF("WORD PTR ");
9353 destoffset = decode_rm01_address(rl);
9354 DECODE_PRINTF(",CL\n");
9355 destval = fetch_data_word(destoffset);
9356 TRACE_AND_STEP();
9357 destval = (*opcD1_word_operation[rh]) (destval, amt);
9358 store_data_word(destoffset, destval);
9359 }
9360 break;
9361 case 2:
9362 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9363 u32 destval;
9364
9365 DECODE_PRINTF("DWORD PTR ");
9366 destoffset = decode_rm10_address(rl);
9367 DECODE_PRINTF(",CL\n");
9368 destval = fetch_data_long(destoffset);
9369 TRACE_AND_STEP();
9370 destval = (*opcD1_long_operation[rh]) (destval, amt);
9371 store_data_long(destoffset, destval);
9372 } else {
9373 u16 destval;
9374
9375 DECODE_PRINTF("WORD PTR ");
9376 destoffset = decode_rm10_address(rl);
9377 DECODE_PRINTF(",CL\n");
9378 destval = fetch_data_word(destoffset);
9379 TRACE_AND_STEP();
9380 destval = (*opcD1_word_operation[rh]) (destval, amt);
9381 store_data_word(destoffset, destval);
9382 }
9383 break;
9384 case 3: /* register to register */
9385 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9386 u32 *destreg;
9387
9388 destreg = DECODE_RM_LONG_REGISTER(rl);
9389 DECODE_PRINTF(",CL\n");
9390 TRACE_AND_STEP();
9391 *destreg = (*opcD1_long_operation[rh]) (*destreg, amt);
9392 } else {
9393 u16 *destreg;
9394
9395 destreg = DECODE_RM_WORD_REGISTER(rl);
9396 DECODE_PRINTF(",CL\n");
9397 TRACE_AND_STEP();
9398 *destreg = (*opcD1_word_operation[rh]) (*destreg, amt);
9399 }
9400 break;
9401 }
9402 DECODE_CLEAR_SEGOVR();
9403 END_OF_INSTR();
9404 }
9405
9406 /****************************************************************************
9407 REMARKS:
9408 Handles opcode 0xd4
9409 ****************************************************************************/
9410 static void x86emuOp_aam(u8 X86EMU_UNUSED(op1))
9411 {
9412 u8 a;
9413
9414 START_OF_INSTR();
9415 DECODE_PRINTF("AAM\n");
9416 a = fetch_byte_imm(); /* this is a stupid encoding. */
9417 if (a != 10) {
9418 /* fix: add base decoding
9419 aam_word(u8 val, int base a) */
9420 DECODE_PRINTF("ERROR DECODING AAM\n");
9421 TRACE_REGS();
9422 HALT_SYS();
9423 }
9424 TRACE_AND_STEP();
9425 /* note the type change here --- returning AL and AH in AX. */
9426 M.x86.R_AX = aam_word(M.x86.R_AL);
9427 DECODE_CLEAR_SEGOVR();
9428 END_OF_INSTR();
9429 }
9430
9431 /****************************************************************************
9432 REMARKS:
9433 Handles opcode 0xd5
9434 ****************************************************************************/
9435 static void x86emuOp_aad(u8 X86EMU_UNUSED(op1))
9436 {
9437 u8 a;
9438
9439 START_OF_INSTR();
9440 DECODE_PRINTF("AAD\n");
9441 a = fetch_byte_imm();
9442 if (a != 10) {
9443 /* fix: add base decoding
9444 aad_word(u16 val, int base a) */
9445 DECODE_PRINTF("ERROR DECODING AAM\n");
9446 TRACE_REGS();
9447 HALT_SYS();
9448 }
9449 TRACE_AND_STEP();
9450 M.x86.R_AX = aad_word(M.x86.R_AX);
9451 DECODE_CLEAR_SEGOVR();
9452 END_OF_INSTR();
9453 }
9454
9455 /* opcode 0xd6 ILLEGAL OPCODE */
9456
9457 /****************************************************************************
9458 REMARKS:
9459 Handles opcode 0xd7
9460 ****************************************************************************/
9461 static void x86emuOp_xlat(u8 X86EMU_UNUSED(op1))
9462 {
9463 u16 addr;
9464
9465 START_OF_INSTR();
9466 DECODE_PRINTF("XLAT\n");
9467 TRACE_AND_STEP();
9468 addr = (u16)(M.x86.R_BX + (u8)M.x86.R_AL);
9469 M.x86.R_AL = fetch_data_byte(addr);
9470 DECODE_CLEAR_SEGOVR();
9471 END_OF_INSTR();
9472 }
9473
9474 /* instuctions D8 .. DF are in i87_ops.c */
9475
9476 /****************************************************************************
9477 REMARKS:
9478 Handles opcode 0xe0
9479 ****************************************************************************/
9480 static void x86emuOp_loopne(u8 X86EMU_UNUSED(op1))
9481 {
9482 s16 ip;
9483
9484 START_OF_INSTR();
9485 DECODE_PRINTF("LOOPNE\t");
9486 ip = (s8) fetch_byte_imm();
9487 ip += (s16) M.x86.R_IP;
9488 DECODE_PRINTF2("%04x\n", ip);
9489 TRACE_AND_STEP();
9490 M.x86.R_CX -= 1;
9491 if (M.x86.R_CX != 0 && !ACCESS_FLAG(F_ZF)) /* CX != 0 and !ZF */
9492 M.x86.R_IP = ip;
9493 DECODE_CLEAR_SEGOVR();
9494 END_OF_INSTR();
9495 }
9496
9497 /****************************************************************************
9498 REMARKS:
9499 Handles opcode 0xe1
9500 ****************************************************************************/
9501 static void x86emuOp_loope(u8 X86EMU_UNUSED(op1))
9502 {
9503 s16 ip;
9504
9505 START_OF_INSTR();
9506 DECODE_PRINTF("LOOPE\t");
9507 ip = (s8) fetch_byte_imm();
9508 ip += (s16) M.x86.R_IP;
9509 DECODE_PRINTF2("%04x\n", ip);
9510 TRACE_AND_STEP();
9511 M.x86.R_CX -= 1;
9512 if (M.x86.R_CX != 0 && ACCESS_FLAG(F_ZF)) /* CX != 0 and ZF */
9513 M.x86.R_IP = ip;
9514 DECODE_CLEAR_SEGOVR();
9515 END_OF_INSTR();
9516 }
9517
9518 /****************************************************************************
9519 REMARKS:
9520 Handles opcode 0xe2
9521 ****************************************************************************/
9522 static void x86emuOp_loop(u8 X86EMU_UNUSED(op1))
9523 {
9524 s16 ip;
9525
9526 START_OF_INSTR();
9527 DECODE_PRINTF("LOOP\t");
9528 ip = (s8) fetch_byte_imm();
9529 ip += (s16) M.x86.R_IP;
9530 DECODE_PRINTF2("%04x\n", ip);
9531 TRACE_AND_STEP();
9532 M.x86.R_CX -= 1;
9533 if (M.x86.R_CX != 0)
9534 M.x86.R_IP = ip;
9535 DECODE_CLEAR_SEGOVR();
9536 END_OF_INSTR();
9537 }
9538
9539 /****************************************************************************
9540 REMARKS:
9541 Handles opcode 0xe3
9542 ****************************************************************************/
9543 static void x86emuOp_jcxz(u8 X86EMU_UNUSED(op1))
9544 {
9545 u16 target;
9546 s8 offset;
9547
9548 /* jump to byte offset if overflow flag is set */
9549 START_OF_INSTR();
9550 DECODE_PRINTF("JCXZ\t");
9551 offset = (s8)fetch_byte_imm();
9552 target = (u16)(M.x86.R_IP + offset);
9553 DECODE_PRINTF2("%x\n", target);
9554 TRACE_AND_STEP();
9555 if (M.x86.R_CX == 0)
9556 M.x86.R_IP = target;
9557 DECODE_CLEAR_SEGOVR();
9558 END_OF_INSTR();
9559 }
9560
9561 /****************************************************************************
9562 REMARKS:
9563 Handles opcode 0xe4
9564 ****************************************************************************/
9565 static void x86emuOp_in_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
9566 {
9567 u8 port;
9568
9569 START_OF_INSTR();
9570 DECODE_PRINTF("IN\t");
9571 port = (u8) fetch_byte_imm();
9572 DECODE_PRINTF2("%x,AL\n", port);
9573 TRACE_AND_STEP();
9574 M.x86.R_AL = (*sys_inb)(port);
9575 DECODE_CLEAR_SEGOVR();
9576 END_OF_INSTR();
9577 }
9578
9579 /****************************************************************************
9580 REMARKS:
9581 Handles opcode 0xe5
9582 ****************************************************************************/
9583 static void x86emuOp_in_word_AX_IMM(u8 X86EMU_UNUSED(op1))
9584 {
9585 u8 port;
9586
9587 START_OF_INSTR();
9588 DECODE_PRINTF("IN\t");
9589 port = (u8) fetch_byte_imm();
9590 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9591 DECODE_PRINTF2("EAX,%x\n", port);
9592 } else {
9593 DECODE_PRINTF2("AX,%x\n", port);
9594 }
9595 TRACE_AND_STEP();
9596 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9597 M.x86.R_EAX = (*sys_inl)(port);
9598 } else {
9599 M.x86.R_AX = (*sys_inw)(port);
9600 }
9601 DECODE_CLEAR_SEGOVR();
9602 END_OF_INSTR();
9603 }
9604
9605 /****************************************************************************
9606 REMARKS:
9607 Handles opcode 0xe6
9608 ****************************************************************************/
9609 static void x86emuOp_out_byte_IMM_AL(u8 X86EMU_UNUSED(op1))
9610 {
9611 u8 port;
9612
9613 START_OF_INSTR();
9614 DECODE_PRINTF("OUT\t");
9615 port = (u8) fetch_byte_imm();
9616 DECODE_PRINTF2("%x,AL\n", port);
9617 TRACE_AND_STEP();
9618 (*sys_outb)(port, M.x86.R_AL);
9619 DECODE_CLEAR_SEGOVR();
9620 END_OF_INSTR();
9621 }
9622
9623 /****************************************************************************
9624 REMARKS:
9625 Handles opcode 0xe7
9626 ****************************************************************************/
9627 static void x86emuOp_out_word_IMM_AX(u8 X86EMU_UNUSED(op1))
9628 {
9629 u8 port;
9630
9631 START_OF_INSTR();
9632 DECODE_PRINTF("OUT\t");
9633 port = (u8) fetch_byte_imm();
9634 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9635 DECODE_PRINTF2("%x,EAX\n", port);
9636 } else {
9637 DECODE_PRINTF2("%x,AX\n", port);
9638 }
9639 TRACE_AND_STEP();
9640 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9641 (*sys_outl)(port, M.x86.R_EAX);
9642 } else {
9643 (*sys_outw)(port, M.x86.R_AX);
9644 }
9645 DECODE_CLEAR_SEGOVR();
9646 END_OF_INSTR();
9647 }
9648
9649 /****************************************************************************
9650 REMARKS:
9651 Handles opcode 0xe8
9652 ****************************************************************************/
9653 static void x86emuOp_call_near_IMM(u8 X86EMU_UNUSED(op1))
9654 {
9655 s16 ip;
9656
9657 START_OF_INSTR();
9658 DECODE_PRINTF("CALL\t");
9659 ip = (s16) fetch_word_imm();
9660 ip += (s16) M.x86.R_IP; /* CHECK SIGN */
9661 DECODE_PRINTF2("%04x\n", (u16)ip);
9662 CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, M.x86.R_CS, ip, "");
9663 TRACE_AND_STEP();
9664 push_word(M.x86.R_IP);
9665 M.x86.R_IP = ip;
9666 DECODE_CLEAR_SEGOVR();
9667 END_OF_INSTR();
9668 }
9669
9670 /****************************************************************************
9671 REMARKS:
9672 Handles opcode 0xe9
9673 ****************************************************************************/
9674 static void x86emuOp_jump_near_IMM(u8 X86EMU_UNUSED(op1))
9675 {
9676 int ip;
9677
9678 START_OF_INSTR();
9679 DECODE_PRINTF("JMP\t");
9680 ip = (s16)fetch_word_imm();
9681 ip += (s16)M.x86.R_IP;
9682 DECODE_PRINTF2("%04x\n", (u16)ip);
9683 TRACE_AND_STEP();
9684 M.x86.R_IP = (u16)ip;
9685 DECODE_CLEAR_SEGOVR();
9686 END_OF_INSTR();
9687 }
9688
9689 /****************************************************************************
9690 REMARKS:
9691 Handles opcode 0xea
9692 ****************************************************************************/
9693 static void x86emuOp_jump_far_IMM(u8 X86EMU_UNUSED(op1))
9694 {
9695 u16 cs, ip;
9696
9697 START_OF_INSTR();
9698 DECODE_PRINTF("JMP\tFAR ");
9699 ip = fetch_word_imm();
9700 cs = fetch_word_imm();
9701 DECODE_PRINTF2("%04x:", cs);
9702 DECODE_PRINTF2("%04x\n", ip);
9703 TRACE_AND_STEP();
9704 M.x86.R_IP = ip;
9705 M.x86.R_CS = cs;
9706 DECODE_CLEAR_SEGOVR();
9707 END_OF_INSTR();
9708 }
9709
9710 /****************************************************************************
9711 REMARKS:
9712 Handles opcode 0xeb
9713 ****************************************************************************/
9714 static void x86emuOp_jump_byte_IMM(u8 X86EMU_UNUSED(op1))
9715 {
9716 u16 target;
9717 s8 offset;
9718
9719 START_OF_INSTR();
9720 DECODE_PRINTF("JMP\t");
9721 offset = (s8)fetch_byte_imm();
9722 target = (u16)(M.x86.R_IP + offset);
9723 DECODE_PRINTF2("%x\n", target);
9724 TRACE_AND_STEP();
9725 M.x86.R_IP = target;
9726 DECODE_CLEAR_SEGOVR();
9727 END_OF_INSTR();
9728 }
9729
9730 /****************************************************************************
9731 REMARKS:
9732 Handles opcode 0xec
9733 ****************************************************************************/
9734 static void x86emuOp_in_byte_AL_DX(u8 X86EMU_UNUSED(op1))
9735 {
9736 START_OF_INSTR();
9737 DECODE_PRINTF("IN\tAL,DX\n");
9738 TRACE_AND_STEP();
9739 M.x86.R_AL = (*sys_inb)(M.x86.R_DX);
9740 DECODE_CLEAR_SEGOVR();
9741 END_OF_INSTR();
9742 }
9743
9744 /****************************************************************************
9745 REMARKS:
9746 Handles opcode 0xed
9747 ****************************************************************************/
9748 static void x86emuOp_in_word_AX_DX(u8 X86EMU_UNUSED(op1))
9749 {
9750 START_OF_INSTR();
9751 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9752 DECODE_PRINTF("IN\tEAX,DX\n");
9753 } else {
9754 DECODE_PRINTF("IN\tAX,DX\n");
9755 }
9756 TRACE_AND_STEP();
9757 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9758 M.x86.R_EAX = (*sys_inl)(M.x86.R_DX);
9759 } else {
9760 M.x86.R_AX = (*sys_inw)(M.x86.R_DX);
9761 }
9762 DECODE_CLEAR_SEGOVR();
9763 END_OF_INSTR();
9764 }
9765
9766 /****************************************************************************
9767 REMARKS:
9768 Handles opcode 0xee
9769 ****************************************************************************/
9770 static void x86emuOp_out_byte_DX_AL(u8 X86EMU_UNUSED(op1))
9771 {
9772 START_OF_INSTR();
9773 DECODE_PRINTF("OUT\tDX,AL\n");
9774 TRACE_AND_STEP();
9775 (*sys_outb)(M.x86.R_DX, M.x86.R_AL);
9776 DECODE_CLEAR_SEGOVR();
9777 END_OF_INSTR();
9778 }
9779
9780 /****************************************************************************
9781 REMARKS:
9782 Handles opcode 0xef
9783 ****************************************************************************/
9784 static void x86emuOp_out_word_DX_AX(u8 X86EMU_UNUSED(op1))
9785 {
9786 START_OF_INSTR();
9787 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9788 DECODE_PRINTF("OUT\tDX,EAX\n");
9789 } else {
9790 DECODE_PRINTF("OUT\tDX,AX\n");
9791 }
9792 TRACE_AND_STEP();
9793 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9794 (*sys_outl)(M.x86.R_DX, M.x86.R_EAX);
9795 } else {
9796 (*sys_outw)(M.x86.R_DX, M.x86.R_AX);
9797 }
9798 DECODE_CLEAR_SEGOVR();
9799 END_OF_INSTR();
9800 }
9801
9802 /****************************************************************************
9803 REMARKS:
9804 Handles opcode 0xf0
9805 ****************************************************************************/
9806 static void x86emuOp_lock(u8 X86EMU_UNUSED(op1))
9807 {
9808 START_OF_INSTR();
9809 DECODE_PRINTF("LOCK:\n");
9810 TRACE_AND_STEP();
9811 DECODE_CLEAR_SEGOVR();
9812 END_OF_INSTR();
9813 }
9814
9815 /*opcode 0xf1 ILLEGAL OPERATION */
9816
9817 /****************************************************************************
9818 REMARKS:
9819 Handles opcode 0xf2
9820 ****************************************************************************/
9821 static void x86emuOp_repne(u8 X86EMU_UNUSED(op1))
9822 {
9823 START_OF_INSTR();
9824 DECODE_PRINTF("REPNE\n");
9825 TRACE_AND_STEP();
9826 M.x86.mode |= SYSMODE_PREFIX_REPNE;
9827 DECODE_CLEAR_SEGOVR();
9828 END_OF_INSTR();
9829 }
9830
9831 /****************************************************************************
9832 REMARKS:
9833 Handles opcode 0xf3
9834 ****************************************************************************/
9835 static void x86emuOp_repe(u8 X86EMU_UNUSED(op1))
9836 {
9837 START_OF_INSTR();
9838 DECODE_PRINTF("REPE\n");
9839 TRACE_AND_STEP();
9840 M.x86.mode |= SYSMODE_PREFIX_REPE;
9841 DECODE_CLEAR_SEGOVR();
9842 END_OF_INSTR();
9843 }
9844
9845 /****************************************************************************
9846 REMARKS:
9847 Handles opcode 0xf4
9848 ****************************************************************************/
9849 static void x86emuOp_halt(u8 X86EMU_UNUSED(op1))
9850 {
9851 START_OF_INSTR();
9852 DECODE_PRINTF("HALT\n");
9853 TRACE_AND_STEP();
9854 HALT_SYS();
9855 DECODE_CLEAR_SEGOVR();
9856 END_OF_INSTR();
9857 }
9858
9859 /****************************************************************************
9860 REMARKS:
9861 Handles opcode 0xf5
9862 ****************************************************************************/
9863 static void x86emuOp_cmc(u8 X86EMU_UNUSED(op1))
9864 {
9865 /* complement the carry flag. */
9866 START_OF_INSTR();
9867 DECODE_PRINTF("CMC\n");
9868 TRACE_AND_STEP();
9869 TOGGLE_FLAG(F_CF);
9870 DECODE_CLEAR_SEGOVR();
9871 END_OF_INSTR();
9872 }
9873
9874 /****************************************************************************
9875 REMARKS:
9876 Handles opcode 0xf6
9877 ****************************************************************************/
9878 static void x86emuOp_opcF6_byte_RM(u8 X86EMU_UNUSED(op1))
9879 {
9880 int mod, rl, rh;
9881 u8 *destreg;
9882 uint destoffset;
9883 u8 destval, srcval;
9884
9885 /* long, drawn out code follows. Double switch for a total
9886 of 32 cases. */
9887 START_OF_INSTR();
9888 FETCH_DECODE_MODRM(mod, rh, rl);
9889 switch (mod) {
9890 case 0: /* mod=00 */
9891 switch (rh) {
9892 case 0: /* test byte imm */
9893 DECODE_PRINTF("TEST\tBYTE PTR ");
9894 destoffset = decode_rm00_address(rl);
9895 DECODE_PRINTF(",");
9896 srcval = fetch_byte_imm();
9897 DECODE_PRINTF2("%02x\n", srcval);
9898 destval = fetch_data_byte(destoffset);
9899 TRACE_AND_STEP();
9900 test_byte(destval, srcval);
9901 break;
9902 case 1:
9903 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
9904 HALT_SYS();
9905 break;
9906 case 2:
9907 DECODE_PRINTF("NOT\tBYTE PTR ");
9908 destoffset = decode_rm00_address(rl);
9909 DECODE_PRINTF("\n");
9910 destval = fetch_data_byte(destoffset);
9911 TRACE_AND_STEP();
9912 destval = not_byte(destval);
9913 store_data_byte(destoffset, destval);
9914 break;
9915 case 3:
9916 DECODE_PRINTF("NEG\tBYTE PTR ");
9917 destoffset = decode_rm00_address(rl);
9918 DECODE_PRINTF("\n");
9919 destval = fetch_data_byte(destoffset);
9920 TRACE_AND_STEP();
9921 destval = neg_byte(destval);
9922 store_data_byte(destoffset, destval);
9923 break;
9924 case 4:
9925 DECODE_PRINTF("MUL\tBYTE PTR ");
9926 destoffset = decode_rm00_address(rl);
9927 DECODE_PRINTF("\n");
9928 destval = fetch_data_byte(destoffset);
9929 TRACE_AND_STEP();
9930 mul_byte(destval);
9931 break;
9932 case 5:
9933 DECODE_PRINTF("IMUL\tBYTE PTR ");
9934 destoffset = decode_rm00_address(rl);
9935 DECODE_PRINTF("\n");
9936 destval = fetch_data_byte(destoffset);
9937 TRACE_AND_STEP();
9938 imul_byte(destval);
9939 break;
9940 case 6:
9941 DECODE_PRINTF("DIV\tBYTE PTR ");
9942 destoffset = decode_rm00_address(rl);
9943 DECODE_PRINTF("\n");
9944 destval = fetch_data_byte(destoffset);
9945 TRACE_AND_STEP();
9946 div_byte(destval);
9947 break;
9948 case 7:
9949 DECODE_PRINTF("IDIV\tBYTE PTR ");
9950 destoffset = decode_rm00_address(rl);
9951 DECODE_PRINTF("\n");
9952 destval = fetch_data_byte(destoffset);
9953 TRACE_AND_STEP();
9954 idiv_byte(destval);
9955 break;
9956 }
9957 break; /* end mod==00 */
9958 case 1: /* mod=01 */
9959 switch (rh) {
9960 case 0: /* test byte imm */
9961 DECODE_PRINTF("TEST\tBYTE PTR ");
9962 destoffset = decode_rm01_address(rl);
9963 DECODE_PRINTF(",");
9964 srcval = fetch_byte_imm();
9965 DECODE_PRINTF2("%02x\n", srcval);
9966 destval = fetch_data_byte(destoffset);
9967 TRACE_AND_STEP();
9968 test_byte(destval, srcval);
9969 break;
9970 case 1:
9971 DECODE_PRINTF("ILLEGAL OP MOD=01 RH=01 OP=F6\n");
9972 HALT_SYS();
9973 break;
9974 case 2:
9975 DECODE_PRINTF("NOT\tBYTE PTR ");
9976 destoffset = decode_rm01_address(rl);
9977 DECODE_PRINTF("\n");
9978 destval = fetch_data_byte(destoffset);
9979 TRACE_AND_STEP();
9980 destval = not_byte(destval);
9981 store_data_byte(destoffset, destval);
9982 break;
9983 case 3:
9984 DECODE_PRINTF("NEG\tBYTE PTR ");
9985 destoffset = decode_rm01_address(rl);
9986 DECODE_PRINTF("\n");
9987 destval = fetch_data_byte(destoffset);
9988 TRACE_AND_STEP();
9989 destval = neg_byte(destval);
9990 store_data_byte(destoffset, destval);
9991 break;
9992 case 4:
9993 DECODE_PRINTF("MUL\tBYTE PTR ");
9994 destoffset = decode_rm01_address(rl);
9995 DECODE_PRINTF("\n");
9996 destval = fetch_data_byte(destoffset);
9997 TRACE_AND_STEP();
9998 mul_byte(destval);
9999 break;
10000 case 5:
10001 DECODE_PRINTF("IMUL\tBYTE PTR ");
10002 destoffset = decode_rm01_address(rl);
10003 DECODE_PRINTF("\n");
10004 destval = fetch_data_byte(destoffset);
10005 TRACE_AND_STEP();
10006 imul_byte(destval);
10007 break;
10008 case 6:
10009 DECODE_PRINTF("DIV\tBYTE PTR ");
10010 destoffset = decode_rm01_address(rl);
10011 DECODE_PRINTF("\n");
10012 destval = fetch_data_byte(destoffset);
10013 TRACE_AND_STEP();
10014 div_byte(destval);
10015 break;
10016 case 7:
10017 DECODE_PRINTF("IDIV\tBYTE PTR ");
10018 destoffset = decode_rm01_address(rl);
10019 DECODE_PRINTF("\n");
10020 destval = fetch_data_byte(destoffset);
10021 TRACE_AND_STEP();
10022 idiv_byte(destval);
10023 break;
10024 }
10025 break; /* end mod==01 */
10026 case 2: /* mod=10 */
10027 switch (rh) {
10028 case 0: /* test byte imm */
10029 DECODE_PRINTF("TEST\tBYTE PTR ");
10030 destoffset = decode_rm10_address(rl);
10031 DECODE_PRINTF(",");
10032 srcval = fetch_byte_imm();
10033 DECODE_PRINTF2("%02x\n", srcval);
10034 destval = fetch_data_byte(destoffset);
10035 TRACE_AND_STEP();
10036 test_byte(destval, srcval);
10037 break;
10038 case 1:
10039 DECODE_PRINTF("ILLEGAL OP MOD=10 RH=01 OP=F6\n");
10040 HALT_SYS();
10041 break;
10042 case 2:
10043 DECODE_PRINTF("NOT\tBYTE PTR ");
10044 destoffset = decode_rm10_address(rl);
10045 DECODE_PRINTF("\n");
10046 destval = fetch_data_byte(destoffset);
10047 TRACE_AND_STEP();
10048 destval = not_byte(destval);
10049 store_data_byte(destoffset, destval);
10050 break;
10051 case 3:
10052 DECODE_PRINTF("NEG\tBYTE PTR ");
10053 destoffset = decode_rm10_address(rl);
10054 DECODE_PRINTF("\n");
10055 destval = fetch_data_byte(destoffset);
10056 TRACE_AND_STEP();
10057 destval = neg_byte(destval);
10058 store_data_byte(destoffset, destval);
10059 break;
10060 case 4:
10061 DECODE_PRINTF("MUL\tBYTE PTR ");
10062 destoffset = decode_rm10_address(rl);
10063 DECODE_PRINTF("\n");
10064 destval = fetch_data_byte(destoffset);
10065 TRACE_AND_STEP();
10066 mul_byte(destval);
10067 break;
10068 case 5:
10069 DECODE_PRINTF("IMUL\tBYTE PTR ");
10070 destoffset = decode_rm10_address(rl);
10071 DECODE_PRINTF("\n");
10072 destval = fetch_data_byte(destoffset);
10073 TRACE_AND_STEP();
10074 imul_byte(destval);
10075 break;
10076 case 6:
10077 DECODE_PRINTF("DIV\tBYTE PTR ");
10078 destoffset = decode_rm10_address(rl);
10079 DECODE_PRINTF("\n");
10080 destval = fetch_data_byte(destoffset);
10081 TRACE_AND_STEP();
10082 div_byte(destval);
10083 break;
10084 case 7:
10085 DECODE_PRINTF("IDIV\tBYTE PTR ");
10086 destoffset = decode_rm10_address(rl);
10087 DECODE_PRINTF("\n");
10088 destval = fetch_data_byte(destoffset);
10089 TRACE_AND_STEP();
10090 idiv_byte(destval);
10091 break;
10092 }
10093 break; /* end mod==10 */
10094 case 3: /* mod=11 */
10095 switch (rh) {
10096 case 0: /* test byte imm */
10097 DECODE_PRINTF("TEST\t");
10098 destreg = DECODE_RM_BYTE_REGISTER(rl);
10099 DECODE_PRINTF(",");
10100 srcval = fetch_byte_imm();
10101 DECODE_PRINTF2("%02x\n", srcval);
10102 TRACE_AND_STEP();
10103 test_byte(*destreg, srcval);
10104 break;
10105 case 1:
10106 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
10107 HALT_SYS();
10108 break;
10109 case 2:
10110 DECODE_PRINTF("NOT\t");
10111 destreg = DECODE_RM_BYTE_REGISTER(rl);
10112 DECODE_PRINTF("\n");
10113 TRACE_AND_STEP();
10114 *destreg = not_byte(*destreg);
10115 break;
10116 case 3:
10117 DECODE_PRINTF("NEG\t");
10118 destreg = DECODE_RM_BYTE_REGISTER(rl);
10119 DECODE_PRINTF("\n");
10120 TRACE_AND_STEP();
10121 *destreg = neg_byte(*destreg);
10122 break;
10123 case 4:
10124 DECODE_PRINTF("MUL\t");
10125 destreg = DECODE_RM_BYTE_REGISTER(rl);
10126 DECODE_PRINTF("\n");
10127 TRACE_AND_STEP();
10128 mul_byte(*destreg); /*!!! */
10129 break;
10130 case 5:
10131 DECODE_PRINTF("IMUL\t");
10132 destreg = DECODE_RM_BYTE_REGISTER(rl);
10133 DECODE_PRINTF("\n");
10134 TRACE_AND_STEP();
10135 imul_byte(*destreg);
10136 break;
10137 case 6:
10138 DECODE_PRINTF("DIV\t");
10139 destreg = DECODE_RM_BYTE_REGISTER(rl);
10140 DECODE_PRINTF("\n");
10141 TRACE_AND_STEP();
10142 div_byte(*destreg);
10143 break;
10144 case 7:
10145 DECODE_PRINTF("IDIV\t");
10146 destreg = DECODE_RM_BYTE_REGISTER(rl);
10147 DECODE_PRINTF("\n");
10148 TRACE_AND_STEP();
10149 idiv_byte(*destreg);
10150 break;
10151 }
10152 break; /* end mod==11 */
10153 }
10154 DECODE_CLEAR_SEGOVR();
10155 END_OF_INSTR();
10156 }
10157
10158 /****************************************************************************
10159 REMARKS:
10160 Handles opcode 0xf7
10161 ****************************************************************************/
10162 static void x86emuOp_opcF7_word_RM(u8 X86EMU_UNUSED(op1))
10163 {
10164 int mod, rl, rh;
10165 uint destoffset;
10166
10167 /* long, drawn out code follows. Double switch for a total
10168 of 32 cases. */
10169 START_OF_INSTR();
10170 FETCH_DECODE_MODRM(mod, rh, rl);
10171 switch (mod) {
10172 case 0: /* mod=00 */
10173 switch (rh) {
10174 case 0: /* test word imm */
10175 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10176 u32 destval,srcval;
10177
10178 DECODE_PRINTF("TEST\tDWORD PTR ");
10179 destoffset = decode_rm00_address(rl);
10180 DECODE_PRINTF(",");
10181 srcval = fetch_long_imm();
10182 DECODE_PRINTF2("%x\n", srcval);
10183 destval = fetch_data_long(destoffset);
10184 TRACE_AND_STEP();
10185 test_long(destval, srcval);
10186 } else {
10187 u16 destval,srcval;
10188
10189 DECODE_PRINTF("TEST\tWORD PTR ");
10190 destoffset = decode_rm00_address(rl);
10191 DECODE_PRINTF(",");
10192 srcval = fetch_word_imm();
10193 DECODE_PRINTF2("%x\n", srcval);
10194 destval = fetch_data_word(destoffset);
10195 TRACE_AND_STEP();
10196 test_word(destval, srcval);
10197 }
10198 break;
10199 case 1:
10200 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F7\n");
10201 HALT_SYS();
10202 break;
10203 case 2:
10204 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10205 u32 destval;
10206
10207 DECODE_PRINTF("NOT\tDWORD PTR ");
10208 destoffset = decode_rm00_address(rl);
10209 DECODE_PRINTF("\n");
10210 destval = fetch_data_long(destoffset);
10211 TRACE_AND_STEP();
10212 destval = not_long(destval);
10213 store_data_long(destoffset, destval);
10214 } else {
10215 u16 destval;
10216
10217 DECODE_PRINTF("NOT\tWORD PTR ");
10218 destoffset = decode_rm00_address(rl);
10219 DECODE_PRINTF("\n");
10220 destval = fetch_data_word(destoffset);
10221 TRACE_AND_STEP();
10222 destval = not_word(destval);
10223 store_data_word(destoffset, destval);
10224 }
10225 break;
10226 case 3:
10227 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10228 u32 destval;
10229
10230 DECODE_PRINTF("NEG\tDWORD PTR ");
10231 destoffset = decode_rm00_address(rl);
10232 DECODE_PRINTF("\n");
10233 destval = fetch_data_long(destoffset);
10234 TRACE_AND_STEP();
10235 destval = neg_long(destval);
10236 store_data_long(destoffset, destval);
10237 } else {
10238 u16 destval;
10239
10240 DECODE_PRINTF("NEG\tWORD PTR ");
10241 destoffset = decode_rm00_address(rl);
10242 DECODE_PRINTF("\n");
10243 destval = fetch_data_word(destoffset);
10244 TRACE_AND_STEP();
10245 destval = neg_word(destval);
10246 store_data_word(destoffset, destval);
10247 }
10248 break;
10249 case 4:
10250 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10251 u32 destval;
10252
10253 DECODE_PRINTF("MUL\tDWORD PTR ");
10254 destoffset = decode_rm00_address(rl);
10255 DECODE_PRINTF("\n");
10256 destval = fetch_data_long(destoffset);
10257 TRACE_AND_STEP();
10258 mul_long(destval);
10259 } else {
10260 u16 destval;
10261
10262 DECODE_PRINTF("MUL\tWORD PTR ");
10263 destoffset = decode_rm00_address(rl);
10264 DECODE_PRINTF("\n");
10265 destval = fetch_data_word(destoffset);
10266 TRACE_AND_STEP();
10267 mul_word(destval);
10268 }
10269 break;
10270 case 5:
10271 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10272 u32 destval;
10273
10274 DECODE_PRINTF("IMUL\tDWORD PTR ");
10275 destoffset = decode_rm00_address(rl);
10276 DECODE_PRINTF("\n");
10277 destval = fetch_data_long(destoffset);
10278 TRACE_AND_STEP();
10279 imul_long(destval);
10280 } else {
10281 u16 destval;
10282
10283 DECODE_PRINTF("IMUL\tWORD PTR ");
10284 destoffset = decode_rm00_address(rl);
10285 DECODE_PRINTF("\n");
10286 destval = fetch_data_word(destoffset);
10287 TRACE_AND_STEP();
10288 imul_word(destval);
10289 }
10290 break;
10291 case 6:
10292 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10293 u32 destval;
10294
10295 DECODE_PRINTF("DIV\tDWORD PTR ");
10296 destoffset = decode_rm00_address(rl);
10297 DECODE_PRINTF("\n");
10298 destval = fetch_data_long(destoffset);
10299 TRACE_AND_STEP();
10300 div_long(destval);
10301 } else {
10302 u16 destval;
10303
10304 DECODE_PRINTF("DIV\tWORD PTR ");
10305 destoffset = decode_rm00_address(rl);
10306 DECODE_PRINTF("\n");
10307 destval = fetch_data_word(destoffset);
10308 TRACE_AND_STEP();
10309 div_word(destval);
10310 }
10311 break;
10312 case 7:
10313 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10314 u32 destval;
10315
10316 DECODE_PRINTF("IDIV\tDWORD PTR ");
10317 destoffset = decode_rm00_address(rl);
10318 DECODE_PRINTF("\n");
10319 destval = fetch_data_long(destoffset);
10320 TRACE_AND_STEP();
10321 idiv_long(destval);
10322 } else {
10323 u16 destval;
10324
10325 DECODE_PRINTF("IDIV\tWORD PTR ");
10326 destoffset = decode_rm00_address(rl);
10327 DECODE_PRINTF("\n");
10328 destval = fetch_data_word(destoffset);
10329 TRACE_AND_STEP();
10330 idiv_word(destval);
10331 }
10332 break;
10333 }
10334 break; /* end mod==00 */
10335 case 1: /* mod=01 */
10336 switch (rh) {
10337 case 0: /* test word imm */
10338 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10339 u32 destval,srcval;
10340
10341 DECODE_PRINTF("TEST\tDWORD PTR ");
10342 destoffset = decode_rm01_address(rl);
10343 DECODE_PRINTF(",");
10344 srcval = fetch_long_imm();
10345 DECODE_PRINTF2("%x\n", srcval);
10346 destval = fetch_data_long(destoffset);
10347 TRACE_AND_STEP();
10348 test_long(destval, srcval);
10349 } else {
10350 u16 destval,srcval;
10351
10352 DECODE_PRINTF("TEST\tWORD PTR ");
10353 destoffset = decode_rm01_address(rl);
10354 DECODE_PRINTF(",");
10355 srcval = fetch_word_imm();
10356 DECODE_PRINTF2("%x\n", srcval);
10357 destval = fetch_data_word(destoffset);
10358 TRACE_AND_STEP();
10359 test_word(destval, srcval);
10360 }
10361 break;
10362 case 1:
10363 DECODE_PRINTF("ILLEGAL OP MOD=01 RH=01 OP=F6\n");
10364 HALT_SYS();
10365 break;
10366 case 2:
10367 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10368 u32 destval;
10369
10370 DECODE_PRINTF("NOT\tDWORD PTR ");
10371 destoffset = decode_rm01_address(rl);
10372 DECODE_PRINTF("\n");
10373 destval = fetch_data_long(destoffset);
10374 TRACE_AND_STEP();
10375 destval = not_long(destval);
10376 store_data_long(destoffset, destval);
10377 } else {
10378 u16 destval;
10379
10380 DECODE_PRINTF("NOT\tWORD PTR ");
10381 destoffset = decode_rm01_address(rl);
10382 DECODE_PRINTF("\n");
10383 destval = fetch_data_word(destoffset);
10384 TRACE_AND_STEP();
10385 destval = not_word(destval);
10386 store_data_word(destoffset, destval);
10387 }
10388 break;
10389 case 3:
10390 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10391 u32 destval;
10392
10393 DECODE_PRINTF("NEG\tDWORD PTR ");
10394 destoffset = decode_rm01_address(rl);
10395 DECODE_PRINTF("\n");
10396 destval = fetch_data_long(destoffset);
10397 TRACE_AND_STEP();
10398 destval = neg_long(destval);
10399 store_data_long(destoffset, destval);
10400 } else {
10401 u16 destval;
10402
10403 DECODE_PRINTF("NEG\tWORD PTR ");
10404 destoffset = decode_rm01_address(rl);
10405 DECODE_PRINTF("\n");
10406 destval = fetch_data_word(destoffset);
10407 TRACE_AND_STEP();
10408 destval = neg_word(destval);
10409 store_data_word(destoffset, destval);
10410 }
10411 break;
10412 case 4:
10413 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10414 u32 destval;
10415
10416 DECODE_PRINTF("MUL\tDWORD PTR ");
10417 destoffset = decode_rm01_address(rl);
10418 DECODE_PRINTF("\n");
10419 destval = fetch_data_long(destoffset);
10420 TRACE_AND_STEP();
10421 mul_long(destval);
10422 } else {
10423 u16 destval;
10424
10425 DECODE_PRINTF("MUL\tWORD PTR ");
10426 destoffset = decode_rm01_address(rl);
10427 DECODE_PRINTF("\n");
10428 destval = fetch_data_word(destoffset);
10429 TRACE_AND_STEP();
10430 mul_word(destval);
10431 }
10432 break;
10433 case 5:
10434 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10435 u32 destval;
10436
10437 DECODE_PRINTF("IMUL\tDWORD PTR ");
10438 destoffset = decode_rm01_address(rl);
10439 DECODE_PRINTF("\n");
10440 destval = fetch_data_long(destoffset);
10441 TRACE_AND_STEP();
10442 imul_long(destval);
10443 } else {
10444 u16 destval;
10445
10446 DECODE_PRINTF("IMUL\tWORD PTR ");
10447 destoffset = decode_rm01_address(rl);
10448 DECODE_PRINTF("\n");
10449 destval = fetch_data_word(destoffset);
10450 TRACE_AND_STEP();
10451 imul_word(destval);
10452 }
10453 break;
10454 case 6:
10455 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10456 u32 destval;
10457
10458 DECODE_PRINTF("DIV\tDWORD PTR ");
10459 destoffset = decode_rm01_address(rl);
10460 DECODE_PRINTF("\n");
10461 destval = fetch_data_long(destoffset);
10462 TRACE_AND_STEP();
10463 div_long(destval);
10464 } else {
10465 u16 destval;
10466
10467 DECODE_PRINTF("DIV\tWORD PTR ");
10468 destoffset = decode_rm01_address(rl);
10469 DECODE_PRINTF("\n");
10470 destval = fetch_data_word(destoffset);
10471 TRACE_AND_STEP();
10472 div_word(destval);
10473 }
10474 break;
10475 case 7:
10476 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10477 u32 destval;
10478
10479 DECODE_PRINTF("IDIV\tDWORD PTR ");
10480 destoffset = decode_rm01_address(rl);
10481 DECODE_PRINTF("\n");
10482 destval = fetch_data_long(destoffset);
10483 TRACE_AND_STEP();
10484 idiv_long(destval);
10485 } else {
10486 u16 destval;
10487
10488 DECODE_PRINTF("IDIV\tWORD PTR ");
10489 destoffset = decode_rm01_address(rl);
10490 DECODE_PRINTF("\n");
10491 destval = fetch_data_word(destoffset);
10492 TRACE_AND_STEP();
10493 idiv_word(destval);
10494 }
10495 break;
10496 }
10497 break; /* end mod==01 */
10498 case 2: /* mod=10 */
10499 switch (rh) {
10500 case 0: /* test word imm */
10501 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10502 u32 destval,srcval;
10503
10504 DECODE_PRINTF("TEST\tDWORD PTR ");
10505 destoffset = decode_rm10_address(rl);
10506 DECODE_PRINTF(",");
10507 srcval = fetch_long_imm();
10508 DECODE_PRINTF2("%x\n", srcval);
10509 destval = fetch_data_long(destoffset);
10510 TRACE_AND_STEP();
10511 test_long(destval, srcval);
10512 } else {
10513 u16 destval,srcval;
10514
10515 DECODE_PRINTF("TEST\tWORD PTR ");
10516 destoffset = decode_rm10_address(rl);
10517 DECODE_PRINTF(",");
10518 srcval = fetch_word_imm();
10519 DECODE_PRINTF2("%x\n", srcval);
10520 destval = fetch_data_word(destoffset);
10521 TRACE_AND_STEP();
10522 test_word(destval, srcval);
10523 }
10524 break;
10525 case 1:
10526 DECODE_PRINTF("ILLEGAL OP MOD=10 RH=01 OP=F6\n");
10527 HALT_SYS();
10528 break;
10529 case 2:
10530 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10531 u32 destval;
10532
10533 DECODE_PRINTF("NOT\tDWORD PTR ");
10534 destoffset = decode_rm10_address(rl);
10535 DECODE_PRINTF("\n");
10536 destval = fetch_data_long(destoffset);
10537 TRACE_AND_STEP();
10538 destval = not_long(destval);
10539 store_data_long(destoffset, destval);
10540 } else {
10541 u16 destval;
10542
10543 DECODE_PRINTF("NOT\tWORD PTR ");
10544 destoffset = decode_rm10_address(rl);
10545 DECODE_PRINTF("\n");
10546 destval = fetch_data_word(destoffset);
10547 TRACE_AND_STEP();
10548 destval = not_word(destval);
10549 store_data_word(destoffset, destval);
10550 }
10551 break;
10552 case 3:
10553 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10554 u32 destval;
10555
10556 DECODE_PRINTF("NEG\tDWORD PTR ");
10557 destoffset = decode_rm10_address(rl);
10558 DECODE_PRINTF("\n");
10559 destval = fetch_data_long(destoffset);
10560 TRACE_AND_STEP();
10561 destval = neg_long(destval);
10562 store_data_long(destoffset, destval);
10563 } else {
10564 u16 destval;
10565
10566 DECODE_PRINTF("NEG\tWORD PTR ");
10567 destoffset = decode_rm10_address(rl);
10568 DECODE_PRINTF("\n");
10569 destval = fetch_data_word(destoffset);
10570 TRACE_AND_STEP();
10571 destval = neg_word(destval);
10572 store_data_word(destoffset, destval);
10573 }
10574 break;
10575 case 4:
10576 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10577 u32 destval;
10578
10579 DECODE_PRINTF("MUL\tDWORD PTR ");
10580 destoffset = decode_rm10_address(rl);
10581 DECODE_PRINTF("\n");
10582 destval = fetch_data_long(destoffset);
10583 TRACE_AND_STEP();
10584 mul_long(destval);
10585 } else {
10586 u16 destval;
10587
10588 DECODE_PRINTF("MUL\tWORD PTR ");
10589 destoffset = decode_rm10_address(rl);
10590 DECODE_PRINTF("\n");
10591 destval = fetch_data_word(destoffset);
10592 TRACE_AND_STEP();
10593 mul_word(destval);
10594 }
10595 break;
10596 case 5:
10597 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10598 u32 destval;
10599
10600 DECODE_PRINTF("IMUL\tDWORD PTR ");
10601 destoffset = decode_rm10_address(rl);
10602 DECODE_PRINTF("\n");
10603 destval = fetch_data_long(destoffset);
10604 TRACE_AND_STEP();
10605 imul_long(destval);
10606 } else {
10607 u16 destval;
10608
10609 DECODE_PRINTF("IMUL\tWORD PTR ");
10610 destoffset = decode_rm10_address(rl);
10611 DECODE_PRINTF("\n");
10612 destval = fetch_data_word(destoffset);
10613 TRACE_AND_STEP();
10614 imul_word(destval);
10615 }
10616 break;
10617 case 6:
10618 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10619 u32 destval;
10620
10621 DECODE_PRINTF("DIV\tDWORD PTR ");
10622 destoffset = decode_rm10_address(rl);
10623 DECODE_PRINTF("\n");
10624 destval = fetch_data_long(destoffset);
10625 TRACE_AND_STEP();
10626 div_long(destval);
10627 } else {
10628 u16 destval;
10629
10630 DECODE_PRINTF("DIV\tWORD PTR ");
10631 destoffset = decode_rm10_address(rl);
10632 DECODE_PRINTF("\n");
10633 destval = fetch_data_word(destoffset);
10634 TRACE_AND_STEP();
10635 div_word(destval);
10636 }
10637 break;
10638 case 7:
10639 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10640 u32 destval;
10641
10642 DECODE_PRINTF("IDIV\tDWORD PTR ");
10643 destoffset = decode_rm10_address(rl);
10644 DECODE_PRINTF("\n");
10645 destval = fetch_data_long(destoffset);
10646 TRACE_AND_STEP();
10647 idiv_long(destval);
10648 } else {
10649 u16 destval;
10650
10651 DECODE_PRINTF("IDIV\tWORD PTR ");
10652 destoffset = decode_rm10_address(rl);
10653 DECODE_PRINTF("\n");
10654 destval = fetch_data_word(destoffset);
10655 TRACE_AND_STEP();
10656 idiv_word(destval);
10657 }
10658 break;
10659 }
10660 break; /* end mod==10 */
10661 case 3: /* mod=11 */
10662 switch (rh) {
10663 case 0: /* test word imm */
10664 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10665 u32 *destreg;
10666 u32 srcval;
10667
10668 DECODE_PRINTF("TEST\t");
10669 destreg = DECODE_RM_LONG_REGISTER(rl);
10670 DECODE_PRINTF(",");
10671 srcval = fetch_long_imm();
10672 DECODE_PRINTF2("%x\n", srcval);
10673 TRACE_AND_STEP();
10674 test_long(*destreg, srcval);
10675 } else {
10676 u16 *destreg;
10677 u16 srcval;
10678
10679 DECODE_PRINTF("TEST\t");
10680 destreg = DECODE_RM_WORD_REGISTER(rl);
10681 DECODE_PRINTF(",");
10682 srcval = fetch_word_imm();
10683 DECODE_PRINTF2("%x\n", srcval);
10684 TRACE_AND_STEP();
10685 test_word(*destreg, srcval);
10686 }
10687 break;
10688 case 1:
10689 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
10690 HALT_SYS();
10691 break;
10692 case 2:
10693 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10694 u32 *destreg;
10695
10696 DECODE_PRINTF("NOT\t");
10697 destreg = DECODE_RM_LONG_REGISTER(rl);
10698 DECODE_PRINTF("\n");
10699 TRACE_AND_STEP();
10700 *destreg = not_long(*destreg);
10701 } else {
10702 u16 *destreg;
10703
10704 DECODE_PRINTF("NOT\t");
10705 destreg = DECODE_RM_WORD_REGISTER(rl);
10706 DECODE_PRINTF("\n");
10707 TRACE_AND_STEP();
10708 *destreg = not_word(*destreg);
10709 }
10710 break;
10711 case 3:
10712 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10713 u32 *destreg;
10714
10715 DECODE_PRINTF("NEG\t");
10716 destreg = DECODE_RM_LONG_REGISTER(rl);
10717 DECODE_PRINTF("\n");
10718 TRACE_AND_STEP();
10719 *destreg = neg_long(*destreg);
10720 } else {
10721 u16 *destreg;
10722
10723 DECODE_PRINTF("NEG\t");
10724 destreg = DECODE_RM_WORD_REGISTER(rl);
10725 DECODE_PRINTF("\n");
10726 TRACE_AND_STEP();
10727 *destreg = neg_word(*destreg);
10728 }
10729 break;
10730 case 4:
10731 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10732 u32 *destreg;
10733
10734 DECODE_PRINTF("MUL\t");
10735 destreg = DECODE_RM_LONG_REGISTER(rl);
10736 DECODE_PRINTF("\n");
10737 TRACE_AND_STEP();
10738 mul_long(*destreg); /*!!! */
10739 } else {
10740 u16 *destreg;
10741
10742 DECODE_PRINTF("MUL\t");
10743 destreg = DECODE_RM_WORD_REGISTER(rl);
10744 DECODE_PRINTF("\n");
10745 TRACE_AND_STEP();
10746 mul_word(*destreg); /*!!! */
10747 }
10748 break;
10749 case 5:
10750 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10751 u32 *destreg;
10752
10753 DECODE_PRINTF("IMUL\t");
10754 destreg = DECODE_RM_LONG_REGISTER(rl);
10755 DECODE_PRINTF("\n");
10756 TRACE_AND_STEP();
10757 imul_long(*destreg);
10758 } else {
10759 u16 *destreg;
10760
10761 DECODE_PRINTF("IMUL\t");
10762 destreg = DECODE_RM_WORD_REGISTER(rl);
10763 DECODE_PRINTF("\n");
10764 TRACE_AND_STEP();
10765 imul_word(*destreg);
10766 }
10767 break;
10768 case 6:
10769 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10770 u32 *destreg;
10771
10772 DECODE_PRINTF("DIV\t");
10773 destreg = DECODE_RM_LONG_REGISTER(rl);
10774 DECODE_PRINTF("\n");
10775 TRACE_AND_STEP();
10776 div_long(*destreg);
10777 } else {
10778 u16 *destreg;
10779
10780 DECODE_PRINTF("DIV\t");
10781 destreg = DECODE_RM_WORD_REGISTER(rl);
10782 DECODE_PRINTF("\n");
10783 TRACE_AND_STEP();
10784 div_word(*destreg);
10785 }
10786 break;
10787 case 7:
10788 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10789 u32 *destreg;
10790
10791 DECODE_PRINTF("IDIV\t");
10792 destreg = DECODE_RM_LONG_REGISTER(rl);
10793 DECODE_PRINTF("\n");
10794 TRACE_AND_STEP();
10795 idiv_long(*destreg);
10796 } else {
10797 u16 *destreg;
10798
10799 DECODE_PRINTF("IDIV\t");
10800 destreg = DECODE_RM_WORD_REGISTER(rl);
10801 DECODE_PRINTF("\n");
10802 TRACE_AND_STEP();
10803 idiv_word(*destreg);
10804 }
10805 break;
10806 }
10807 break; /* end mod==11 */
10808 }
10809 DECODE_CLEAR_SEGOVR();
10810 END_OF_INSTR();
10811 }
10812
10813 /****************************************************************************
10814 REMARKS:
10815 Handles opcode 0xf8
10816 ****************************************************************************/
10817 static void x86emuOp_clc(u8 X86EMU_UNUSED(op1))
10818 {
10819 /* clear the carry flag. */
10820 START_OF_INSTR();
10821 DECODE_PRINTF("CLC\n");
10822 TRACE_AND_STEP();
10823 CLEAR_FLAG(F_CF);
10824 DECODE_CLEAR_SEGOVR();
10825 END_OF_INSTR();
10826 }
10827
10828 /****************************************************************************
10829 REMARKS:
10830 Handles opcode 0xf9
10831 ****************************************************************************/
10832 static void x86emuOp_stc(u8 X86EMU_UNUSED(op1))
10833 {
10834 /* set the carry flag. */
10835 START_OF_INSTR();
10836 DECODE_PRINTF("STC\n");
10837 TRACE_AND_STEP();
10838 SET_FLAG(F_CF);
10839 DECODE_CLEAR_SEGOVR();
10840 END_OF_INSTR();
10841 }
10842
10843 /****************************************************************************
10844 REMARKS:
10845 Handles opcode 0xfa
10846 ****************************************************************************/
10847 static void x86emuOp_cli(u8 X86EMU_UNUSED(op1))
10848 {
10849 /* clear interrupts. */
10850 START_OF_INSTR();
10851 DECODE_PRINTF("CLI\n");
10852 TRACE_AND_STEP();
10853 CLEAR_FLAG(F_IF);
10854 DECODE_CLEAR_SEGOVR();
10855 END_OF_INSTR();
10856 }
10857
10858 /****************************************************************************
10859 REMARKS:
10860 Handles opcode 0xfb
10861 ****************************************************************************/
10862 static void x86emuOp_sti(u8 X86EMU_UNUSED(op1))
10863 {
10864 /* enable interrupts. */
10865 START_OF_INSTR();
10866 DECODE_PRINTF("STI\n");
10867 TRACE_AND_STEP();
10868 SET_FLAG(F_IF);
10869 DECODE_CLEAR_SEGOVR();
10870 END_OF_INSTR();
10871 }
10872
10873 /****************************************************************************
10874 REMARKS:
10875 Handles opcode 0xfc
10876 ****************************************************************************/
10877 static void x86emuOp_cld(u8 X86EMU_UNUSED(op1))
10878 {
10879 /* clear interrupts. */
10880 START_OF_INSTR();
10881 DECODE_PRINTF("CLD\n");
10882 TRACE_AND_STEP();
10883 CLEAR_FLAG(F_DF);
10884 DECODE_CLEAR_SEGOVR();
10885 END_OF_INSTR();
10886 }
10887
10888 /****************************************************************************
10889 REMARKS:
10890 Handles opcode 0xfd
10891 ****************************************************************************/
10892 static void x86emuOp_std(u8 X86EMU_UNUSED(op1))
10893 {
10894 /* clear interrupts. */
10895 START_OF_INSTR();
10896 DECODE_PRINTF("STD\n");
10897 TRACE_AND_STEP();
10898 SET_FLAG(F_DF);
10899 DECODE_CLEAR_SEGOVR();
10900 END_OF_INSTR();
10901 }
10902
10903 /****************************************************************************
10904 REMARKS:
10905 Handles opcode 0xfe
10906 ****************************************************************************/
10907 static void x86emuOp_opcFE_byte_RM(u8 X86EMU_UNUSED(op1))
10908 {
10909 int mod, rh, rl;
10910 u8 destval;
10911 uint destoffset;
10912 u8 *destreg;
10913
10914 /* Yet another special case instruction. */
10915 START_OF_INSTR();
10916 FETCH_DECODE_MODRM(mod, rh, rl);
10917 #ifdef DEBUG
10918 if (DEBUG_DECODE()) {
10919 /* XXX DECODE_PRINTF may be changed to something more
10920 general, so that it is important to leave the strings
10921 in the same format, even though the result is that the
10922 above test is done twice. */
10923
10924 switch (rh) {
10925 case 0:
10926 DECODE_PRINTF("INC\t");
10927 break;
10928 case 1:
10929 DECODE_PRINTF("DEC\t");
10930 break;
10931 case 2:
10932 case 3:
10933 case 4:
10934 case 5:
10935 case 6:
10936 case 7:
10937 DECODE_PRINTF2("ILLEGAL OP MAJOR OP 0xFE MINOR OP %x \n", mod);
10938 HALT_SYS();
10939 break;
10940 }
10941 }
10942 #endif
10943 switch (mod) {
10944 case 0:
10945 DECODE_PRINTF("BYTE PTR ");
10946 destoffset = decode_rm00_address(rl);
10947 DECODE_PRINTF("\n");
10948 switch (rh) {
10949 case 0: /* inc word ptr ... */
10950 destval = fetch_data_byte(destoffset);
10951 TRACE_AND_STEP();
10952 destval = inc_byte(destval);
10953 store_data_byte(destoffset, destval);
10954 break;
10955 case 1: /* dec word ptr ... */
10956 destval = fetch_data_byte(destoffset);
10957 TRACE_AND_STEP();
10958 destval = dec_byte(destval);
10959 store_data_byte(destoffset, destval);
10960 break;
10961 }
10962 break;
10963 case 1:
10964 DECODE_PRINTF("BYTE PTR ");
10965 destoffset = decode_rm01_address(rl);
10966 DECODE_PRINTF("\n");
10967 switch (rh) {
10968 case 0:
10969 destval = fetch_data_byte(destoffset);
10970 TRACE_AND_STEP();
10971 destval = inc_byte(destval);
10972 store_data_byte(destoffset, destval);
10973 break;
10974 case 1:
10975 destval = fetch_data_byte(destoffset);
10976 TRACE_AND_STEP();
10977 destval = dec_byte(destval);
10978 store_data_byte(destoffset, destval);
10979 break;
10980 }
10981 break;
10982 case 2:
10983 DECODE_PRINTF("BYTE PTR ");
10984 destoffset = decode_rm10_address(rl);
10985 DECODE_PRINTF("\n");
10986 switch (rh) {
10987 case 0:
10988 destval = fetch_data_byte(destoffset);
10989 TRACE_AND_STEP();
10990 destval = inc_byte(destval);
10991 store_data_byte(destoffset, destval);
10992 break;
10993 case 1:
10994 destval = fetch_data_byte(destoffset);
10995 TRACE_AND_STEP();
10996 destval = dec_byte(destval);
10997 store_data_byte(destoffset, destval);
10998 break;
10999 }
11000 break;
11001 case 3:
11002 destreg = DECODE_RM_BYTE_REGISTER(rl);
11003 DECODE_PRINTF("\n");
11004 switch (rh) {
11005 case 0:
11006 TRACE_AND_STEP();
11007 *destreg = inc_byte(*destreg);
11008 break;
11009 case 1:
11010 TRACE_AND_STEP();
11011 *destreg = dec_byte(*destreg);
11012 break;
11013 }
11014 break;
11015 }
11016 DECODE_CLEAR_SEGOVR();
11017 END_OF_INSTR();
11018 }
11019
11020 /****************************************************************************
11021 REMARKS:
11022 Handles opcode 0xff
11023 ****************************************************************************/
11024 static void x86emuOp_opcFF_word_RM(u8 X86EMU_UNUSED(op1))
11025 {
11026 int mod, rh, rl;
11027 uint destoffset = 0;
11028 u16 *destreg;
11029 u16 destval,destval2;
11030
11031 /* Yet another special case instruction. */
11032 START_OF_INSTR();
11033 FETCH_DECODE_MODRM(mod, rh, rl);
11034 #ifdef DEBUG
11035 if (DEBUG_DECODE()) {
11036 /* XXX DECODE_PRINTF may be changed to something more
11037 general, so that it is important to leave the strings
11038 in the same format, even though the result is that the
11039 above test is done twice. */
11040
11041 switch (rh) {
11042 case 0:
11043 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11044 DECODE_PRINTF("INC\tDWORD PTR ");
11045 } else {
11046 DECODE_PRINTF("INC\tWORD PTR ");
11047 }
11048 break;
11049 case 1:
11050 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11051 DECODE_PRINTF("DEC\tDWORD PTR ");
11052 } else {
11053 DECODE_PRINTF("DEC\tWORD PTR ");
11054 }
11055 break;
11056 case 2:
11057 DECODE_PRINTF("CALL\t");
11058 break;
11059 case 3:
11060 DECODE_PRINTF("CALL\tFAR ");
11061 break;
11062 case 4:
11063 DECODE_PRINTF("JMP\t");
11064 break;
11065 case 5:
11066 DECODE_PRINTF("JMP\tFAR ");
11067 break;
11068 case 6:
11069 DECODE_PRINTF("PUSH\t");
11070 break;
11071 case 7:
11072 DECODE_PRINTF("ILLEGAL DECODING OF OPCODE FF\t");
11073 HALT_SYS();
11074 break;
11075 }
11076 }
11077 #endif
11078 switch (mod) {
11079 case 0:
11080 destoffset = decode_rm00_address(rl);
11081 DECODE_PRINTF("\n");
11082 switch (rh) {
11083 case 0: /* inc word ptr ... */
11084 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11085 u32 destval;
11086
11087 destval = fetch_data_long(destoffset);
11088 TRACE_AND_STEP();
11089 destval = inc_long(destval);
11090 store_data_long(destoffset, destval);
11091 } else {
11092 u16 destval;
11093
11094 destval = fetch_data_word(destoffset);
11095 TRACE_AND_STEP();
11096 destval = inc_word(destval);
11097 store_data_word(destoffset, destval);
11098 }
11099 break;
11100 case 1: /* dec word ptr ... */
11101 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11102 u32 destval;
11103
11104 destval = fetch_data_long(destoffset);
11105 TRACE_AND_STEP();
11106 destval = dec_long(destval);
11107 store_data_long(destoffset, destval);
11108 } else {
11109 u16 destval;
11110
11111 destval = fetch_data_word(destoffset);
11112 TRACE_AND_STEP();
11113 destval = dec_word(destval);
11114 store_data_word(destoffset, destval);
11115 }
11116 break;
11117 case 2: /* call word ptr ... */
11118 destval = fetch_data_word(destoffset);
11119 TRACE_AND_STEP();
11120 push_word(M.x86.R_IP);
11121 M.x86.R_IP = destval;
11122 break;
11123 case 3: /* call far ptr ... */
11124 destval = fetch_data_word(destoffset);
11125 destval2 = fetch_data_word(destoffset + 2);
11126 TRACE_AND_STEP();
11127 push_word(M.x86.R_CS);
11128 M.x86.R_CS = destval2;
11129 push_word(M.x86.R_IP);
11130 M.x86.R_IP = destval;
11131 break;
11132 case 4: /* jmp word ptr ... */
11133 destval = fetch_data_word(destoffset);
11134 TRACE_AND_STEP();
11135 M.x86.R_IP = destval;
11136 break;
11137 case 5: /* jmp far ptr ... */
11138 destval = fetch_data_word(destoffset);
11139 destval2 = fetch_data_word(destoffset + 2);
11140 TRACE_AND_STEP();
11141 M.x86.R_IP = destval;
11142 M.x86.R_CS = destval2;
11143 break;
11144 case 6: /* push word ptr ... */
11145 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11146 u32 destval;
11147
11148 destval = fetch_data_long(destoffset);
11149 TRACE_AND_STEP();
11150 push_long(destval);
11151 } else {
11152 u16 destval;
11153
11154 destval = fetch_data_word(destoffset);
11155 TRACE_AND_STEP();
11156 push_word(destval);
11157 }
11158 break;
11159 }
11160 break;
11161 case 1:
11162 destoffset = decode_rm01_address(rl);
11163 DECODE_PRINTF("\n");
11164 switch (rh) {
11165 case 0:
11166 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11167 u32 destval;
11168
11169 destval = fetch_data_long(destoffset);
11170 TRACE_AND_STEP();
11171 destval = inc_long(destval);
11172 store_data_long(destoffset, destval);
11173 } else {
11174 u16 destval;
11175
11176 destval = fetch_data_word(destoffset);
11177 TRACE_AND_STEP();
11178 destval = inc_word(destval);
11179 store_data_word(destoffset, destval);
11180 }
11181 break;
11182 case 1:
11183 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11184 u32 destval;
11185
11186 destval = fetch_data_long(destoffset);
11187 TRACE_AND_STEP();
11188 destval = dec_long(destval);
11189 store_data_long(destoffset, destval);
11190 } else {
11191 u16 destval;
11192
11193 destval = fetch_data_word(destoffset);
11194 TRACE_AND_STEP();
11195 destval = dec_word(destval);
11196 store_data_word(destoffset, destval);
11197 }
11198 break;
11199 case 2: /* call word ptr ... */
11200 destval = fetch_data_word(destoffset);
11201 TRACE_AND_STEP();
11202 push_word(M.x86.R_IP);
11203 M.x86.R_IP = destval;
11204 break;
11205 case 3: /* call far ptr ... */
11206 destval = fetch_data_word(destoffset);
11207 destval2 = fetch_data_word(destoffset + 2);
11208 TRACE_AND_STEP();
11209 push_word(M.x86.R_CS);
11210 M.x86.R_CS = destval2;
11211 push_word(M.x86.R_IP);
11212 M.x86.R_IP = destval;
11213 break;
11214 case 4: /* jmp word ptr ... */
11215 destval = fetch_data_word(destoffset);
11216 TRACE_AND_STEP();
11217 M.x86.R_IP = destval;
11218 break;
11219 case 5: /* jmp far ptr ... */
11220 destval = fetch_data_word(destoffset);
11221 destval2 = fetch_data_word(destoffset + 2);
11222 TRACE_AND_STEP();
11223 M.x86.R_IP = destval;
11224 M.x86.R_CS = destval2;
11225 break;
11226 case 6: /* push word ptr ... */
11227 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11228 u32 destval;
11229
11230 destval = fetch_data_long(destoffset);
11231 TRACE_AND_STEP();
11232 push_long(destval);
11233 } else {
11234 u16 destval;
11235
11236 destval = fetch_data_word(destoffset);
11237 TRACE_AND_STEP();
11238 push_word(destval);
11239 }
11240 break;
11241 }
11242 break;
11243 case 2:
11244 destoffset = decode_rm10_address(rl);
11245 DECODE_PRINTF("\n");
11246 switch (rh) {
11247 case 0:
11248 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11249 u32 destval;
11250
11251 destval = fetch_data_long(destoffset);
11252 TRACE_AND_STEP();
11253 destval = inc_long(destval);
11254 store_data_long(destoffset, destval);
11255 } else {
11256 u16 destval;
11257
11258 destval = fetch_data_word(destoffset);
11259 TRACE_AND_STEP();
11260 destval = inc_word(destval);
11261 store_data_word(destoffset, destval);
11262 }
11263 break;
11264 case 1:
11265 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11266 u32 destval;
11267
11268 destval = fetch_data_long(destoffset);
11269 TRACE_AND_STEP();
11270 destval = dec_long(destval);
11271 store_data_long(destoffset, destval);
11272 } else {
11273 u16 destval;
11274
11275 destval = fetch_data_word(destoffset);
11276 TRACE_AND_STEP();
11277 destval = dec_word(destval);
11278 store_data_word(destoffset, destval);
11279 }
11280 break;
11281 case 2: /* call word ptr ... */
11282 destval = fetch_data_word(destoffset);
11283 TRACE_AND_STEP();
11284 push_word(M.x86.R_IP);
11285 M.x86.R_IP = destval;
11286 break;
11287 case 3: /* call far ptr ... */
11288 destval = fetch_data_word(destoffset);
11289 destval2 = fetch_data_word(destoffset + 2);
11290 TRACE_AND_STEP();
11291 push_word(M.x86.R_CS);
11292 M.x86.R_CS = destval2;
11293 push_word(M.x86.R_IP);
11294 M.x86.R_IP = destval;
11295 break;
11296 case 4: /* jmp word ptr ... */
11297 destval = fetch_data_word(destoffset);
11298 TRACE_AND_STEP();
11299 M.x86.R_IP = destval;
11300 break;
11301 case 5: /* jmp far ptr ... */
11302 destval = fetch_data_word(destoffset);
11303 destval2 = fetch_data_word(destoffset + 2);
11304 TRACE_AND_STEP();
11305 M.x86.R_IP = destval;
11306 M.x86.R_CS = destval2;
11307 break;
11308 case 6: /* push word ptr ... */
11309 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11310 u32 destval;
11311
11312 destval = fetch_data_long(destoffset);
11313 TRACE_AND_STEP();
11314 push_long(destval);
11315 } else {
11316 u16 destval;
11317
11318 destval = fetch_data_word(destoffset);
11319 TRACE_AND_STEP();
11320 push_word(destval);
11321 }
11322 break;
11323 }
11324 break;
11325 case 3:
11326 switch (rh) {
11327 case 0:
11328 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11329 u32 *destreg;
11330
11331 destreg = DECODE_RM_LONG_REGISTER(rl);
11332 DECODE_PRINTF("\n");
11333 TRACE_AND_STEP();
11334 *destreg = inc_long(*destreg);
11335 } else {
11336 u16 *destreg;
11337
11338 destreg = DECODE_RM_WORD_REGISTER(rl);
11339 DECODE_PRINTF("\n");
11340 TRACE_AND_STEP();
11341 *destreg = inc_word(*destreg);
11342 }
11343 break;
11344 case 1:
11345 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11346 u32 *destreg;
11347
11348 destreg = DECODE_RM_LONG_REGISTER(rl);
11349 DECODE_PRINTF("\n");
11350 TRACE_AND_STEP();
11351 *destreg = dec_long(*destreg);
11352 } else {
11353 u16 *destreg;
11354
11355 destreg = DECODE_RM_WORD_REGISTER(rl);
11356 DECODE_PRINTF("\n");
11357 TRACE_AND_STEP();
11358 *destreg = dec_word(*destreg);
11359 }
11360 break;
11361 case 2: /* call word ptr ... */
11362 destreg = DECODE_RM_WORD_REGISTER(rl);
11363 DECODE_PRINTF("\n");
11364 TRACE_AND_STEP();
11365 push_word(M.x86.R_IP);
11366 M.x86.R_IP = *destreg;
11367 break;
11368 case 3: /* jmp far ptr ... */
11369 DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n");
11370 TRACE_AND_STEP();
11371 HALT_SYS();
11372 break;
11373
11374 case 4: /* jmp ... */
11375 destreg = DECODE_RM_WORD_REGISTER(rl);
11376 DECODE_PRINTF("\n");
11377 TRACE_AND_STEP();
11378 M.x86.R_IP = (u16) (*destreg);
11379 break;
11380 case 5: /* jmp far ptr ... */
11381 DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n");
11382 TRACE_AND_STEP();
11383 HALT_SYS();
11384 break;
11385 case 6:
11386 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11387 u32 *destreg;
11388
11389 destreg = DECODE_RM_LONG_REGISTER(rl);
11390 DECODE_PRINTF("\n");
11391 TRACE_AND_STEP();
11392 push_long(*destreg);
11393 } else {
11394 u16 *destreg;
11395
11396 destreg = DECODE_RM_WORD_REGISTER(rl);
11397 DECODE_PRINTF("\n");
11398 TRACE_AND_STEP();
11399 push_word(*destreg);
11400 }
11401 break;
11402 }
11403 break;
11404 }
11405 DECODE_CLEAR_SEGOVR();
11406 END_OF_INSTR();
11407 }
11408
11409 /***************************************************************************
11410 * Single byte operation code table:
11411 **************************************************************************/
11412 void (*x86emu_optab[256])(u8) =
11413 {
11414 /* 0x00 */ x86emuOp_add_byte_RM_R,
11415 /* 0x01 */ x86emuOp_add_word_RM_R,
11416 /* 0x02 */ x86emuOp_add_byte_R_RM,
11417 /* 0x03 */ x86emuOp_add_word_R_RM,
11418 /* 0x04 */ x86emuOp_add_byte_AL_IMM,
11419 /* 0x05 */ x86emuOp_add_word_AX_IMM,
11420 /* 0x06 */ x86emuOp_push_ES,
11421 /* 0x07 */ x86emuOp_pop_ES,
11422
11423 /* 0x08 */ x86emuOp_or_byte_RM_R,
11424 /* 0x09 */ x86emuOp_or_word_RM_R,
11425 /* 0x0a */ x86emuOp_or_byte_R_RM,
11426 /* 0x0b */ x86emuOp_or_word_R_RM,
11427 /* 0x0c */ x86emuOp_or_byte_AL_IMM,
11428 /* 0x0d */ x86emuOp_or_word_AX_IMM,
11429 /* 0x0e */ x86emuOp_push_CS,
11430 /* 0x0f */ x86emuOp_two_byte,
11431
11432 /* 0x10 */ x86emuOp_adc_byte_RM_R,
11433 /* 0x11 */ x86emuOp_adc_word_RM_R,
11434 /* 0x12 */ x86emuOp_adc_byte_R_RM,
11435 /* 0x13 */ x86emuOp_adc_word_R_RM,
11436 /* 0x14 */ x86emuOp_adc_byte_AL_IMM,
11437 /* 0x15 */ x86emuOp_adc_word_AX_IMM,
11438 /* 0x16 */ x86emuOp_push_SS,
11439 /* 0x17 */ x86emuOp_pop_SS,
11440
11441 /* 0x18 */ x86emuOp_sbb_byte_RM_R,
11442 /* 0x19 */ x86emuOp_sbb_word_RM_R,
11443 /* 0x1a */ x86emuOp_sbb_byte_R_RM,
11444 /* 0x1b */ x86emuOp_sbb_word_R_RM,
11445 /* 0x1c */ x86emuOp_sbb_byte_AL_IMM,
11446 /* 0x1d */ x86emuOp_sbb_word_AX_IMM,
11447 /* 0x1e */ x86emuOp_push_DS,
11448 /* 0x1f */ x86emuOp_pop_DS,
11449
11450 /* 0x20 */ x86emuOp_and_byte_RM_R,
11451 /* 0x21 */ x86emuOp_and_word_RM_R,
11452 /* 0x22 */ x86emuOp_and_byte_R_RM,
11453 /* 0x23 */ x86emuOp_and_word_R_RM,
11454 /* 0x24 */ x86emuOp_and_byte_AL_IMM,
11455 /* 0x25 */ x86emuOp_and_word_AX_IMM,
11456 /* 0x26 */ x86emuOp_segovr_ES,
11457 /* 0x27 */ x86emuOp_daa,
11458
11459 /* 0x28 */ x86emuOp_sub_byte_RM_R,
11460 /* 0x29 */ x86emuOp_sub_word_RM_R,
11461 /* 0x2a */ x86emuOp_sub_byte_R_RM,
11462 /* 0x2b */ x86emuOp_sub_word_R_RM,
11463 /* 0x2c */ x86emuOp_sub_byte_AL_IMM,
11464 /* 0x2d */ x86emuOp_sub_word_AX_IMM,
11465 /* 0x2e */ x86emuOp_segovr_CS,
11466 /* 0x2f */ x86emuOp_das,
11467
11468 /* 0x30 */ x86emuOp_xor_byte_RM_R,
11469 /* 0x31 */ x86emuOp_xor_word_RM_R,
11470 /* 0x32 */ x86emuOp_xor_byte_R_RM,
11471 /* 0x33 */ x86emuOp_xor_word_R_RM,
11472 /* 0x34 */ x86emuOp_xor_byte_AL_IMM,
11473 /* 0x35 */ x86emuOp_xor_word_AX_IMM,
11474 /* 0x36 */ x86emuOp_segovr_SS,
11475 /* 0x37 */ x86emuOp_aaa,
11476
11477 /* 0x38 */ x86emuOp_cmp_byte_RM_R,
11478 /* 0x39 */ x86emuOp_cmp_word_RM_R,
11479 /* 0x3a */ x86emuOp_cmp_byte_R_RM,
11480 /* 0x3b */ x86emuOp_cmp_word_R_RM,
11481 /* 0x3c */ x86emuOp_cmp_byte_AL_IMM,
11482 /* 0x3d */ x86emuOp_cmp_word_AX_IMM,
11483 /* 0x3e */ x86emuOp_segovr_DS,
11484 /* 0x3f */ x86emuOp_aas,
11485
11486 /* 0x40 */ x86emuOp_inc_AX,
11487 /* 0x41 */ x86emuOp_inc_CX,
11488 /* 0x42 */ x86emuOp_inc_DX,
11489 /* 0x43 */ x86emuOp_inc_BX,
11490 /* 0x44 */ x86emuOp_inc_SP,
11491 /* 0x45 */ x86emuOp_inc_BP,
11492 /* 0x46 */ x86emuOp_inc_SI,
11493 /* 0x47 */ x86emuOp_inc_DI,
11494
11495 /* 0x48 */ x86emuOp_dec_AX,
11496 /* 0x49 */ x86emuOp_dec_CX,
11497 /* 0x4a */ x86emuOp_dec_DX,
11498 /* 0x4b */ x86emuOp_dec_BX,
11499 /* 0x4c */ x86emuOp_dec_SP,
11500 /* 0x4d */ x86emuOp_dec_BP,
11501 /* 0x4e */ x86emuOp_dec_SI,
11502 /* 0x4f */ x86emuOp_dec_DI,
11503
11504 /* 0x50 */ x86emuOp_push_AX,
11505 /* 0x51 */ x86emuOp_push_CX,
11506 /* 0x52 */ x86emuOp_push_DX,
11507 /* 0x53 */ x86emuOp_push_BX,
11508 /* 0x54 */ x86emuOp_push_SP,
11509 /* 0x55 */ x86emuOp_push_BP,
11510 /* 0x56 */ x86emuOp_push_SI,
11511 /* 0x57 */ x86emuOp_push_DI,
11512
11513 /* 0x58 */ x86emuOp_pop_AX,
11514 /* 0x59 */ x86emuOp_pop_CX,
11515 /* 0x5a */ x86emuOp_pop_DX,
11516 /* 0x5b */ x86emuOp_pop_BX,
11517 /* 0x5c */ x86emuOp_pop_SP,
11518 /* 0x5d */ x86emuOp_pop_BP,
11519 /* 0x5e */ x86emuOp_pop_SI,
11520 /* 0x5f */ x86emuOp_pop_DI,
11521
11522 /* 0x60 */ x86emuOp_push_all,
11523 /* 0x61 */ x86emuOp_pop_all,
11524 /* 0x62 */ x86emuOp_illegal_op, /* bound */
11525 /* 0x63 */ x86emuOp_illegal_op, /* arpl */
11526 /* 0x64 */ x86emuOp_segovr_FS,
11527 /* 0x65 */ x86emuOp_segovr_GS,
11528 /* 0x66 */ x86emuOp_prefix_data,
11529 /* 0x67 */ x86emuOp_prefix_addr,
11530
11531 /* 0x68 */ x86emuOp_push_word_IMM,
11532 /* 0x69 */ x86emuOp_imul_word_IMM,
11533 /* 0x6a */ x86emuOp_push_byte_IMM,
11534 /* 0x6b */ x86emuOp_imul_byte_IMM,
11535 /* 0x6c */ x86emuOp_ins_byte,
11536 /* 0x6d */ x86emuOp_ins_word,
11537 /* 0x6e */ x86emuOp_outs_byte,
11538 /* 0x6f */ x86emuOp_outs_word,
11539
11540 /* 0x70 */ x86emuOp_jump_near_O,
11541 /* 0x71 */ x86emuOp_jump_near_NO,
11542 /* 0x72 */ x86emuOp_jump_near_B,
11543 /* 0x73 */ x86emuOp_jump_near_NB,
11544 /* 0x74 */ x86emuOp_jump_near_Z,
11545 /* 0x75 */ x86emuOp_jump_near_NZ,
11546 /* 0x76 */ x86emuOp_jump_near_BE,
11547 /* 0x77 */ x86emuOp_jump_near_NBE,
11548
11549 /* 0x78 */ x86emuOp_jump_near_S,
11550 /* 0x79 */ x86emuOp_jump_near_NS,
11551 /* 0x7a */ x86emuOp_jump_near_P,
11552 /* 0x7b */ x86emuOp_jump_near_NP,
11553 /* 0x7c */ x86emuOp_jump_near_L,
11554 /* 0x7d */ x86emuOp_jump_near_NL,
11555 /* 0x7e */ x86emuOp_jump_near_LE,
11556 /* 0x7f */ x86emuOp_jump_near_NLE,
11557
11558 /* 0x80 */ x86emuOp_opc80_byte_RM_IMM,
11559 /* 0x81 */ x86emuOp_opc81_word_RM_IMM,
11560 /* 0x82 */ x86emuOp_opc82_byte_RM_IMM,
11561 /* 0x83 */ x86emuOp_opc83_word_RM_IMM,
11562 /* 0x84 */ x86emuOp_test_byte_RM_R,
11563 /* 0x85 */ x86emuOp_test_word_RM_R,
11564 /* 0x86 */ x86emuOp_xchg_byte_RM_R,
11565 /* 0x87 */ x86emuOp_xchg_word_RM_R,
11566
11567 /* 0x88 */ x86emuOp_mov_byte_RM_R,
11568 /* 0x89 */ x86emuOp_mov_word_RM_R,
11569 /* 0x8a */ x86emuOp_mov_byte_R_RM,
11570 /* 0x8b */ x86emuOp_mov_word_R_RM,
11571 /* 0x8c */ x86emuOp_mov_word_RM_SR,
11572 /* 0x8d */ x86emuOp_lea_word_R_M,
11573 /* 0x8e */ x86emuOp_mov_word_SR_RM,
11574 /* 0x8f */ x86emuOp_pop_RM,
11575
11576 /* 0x90 */ x86emuOp_nop,
11577 /* 0x91 */ x86emuOp_xchg_word_AX_CX,
11578 /* 0x92 */ x86emuOp_xchg_word_AX_DX,
11579 /* 0x93 */ x86emuOp_xchg_word_AX_BX,
11580 /* 0x94 */ x86emuOp_xchg_word_AX_SP,
11581 /* 0x95 */ x86emuOp_xchg_word_AX_BP,
11582 /* 0x96 */ x86emuOp_xchg_word_AX_SI,
11583 /* 0x97 */ x86emuOp_xchg_word_AX_DI,
11584
11585 /* 0x98 */ x86emuOp_cbw,
11586 /* 0x99 */ x86emuOp_cwd,
11587 /* 0x9a */ x86emuOp_call_far_IMM,
11588 /* 0x9b */ x86emuOp_wait,
11589 /* 0x9c */ x86emuOp_pushf_word,
11590 /* 0x9d */ x86emuOp_popf_word,
11591 /* 0x9e */ x86emuOp_sahf,
11592 /* 0x9f */ x86emuOp_lahf,
11593
11594 /* 0xa0 */ x86emuOp_mov_AL_M_IMM,
11595 /* 0xa1 */ x86emuOp_mov_AX_M_IMM,
11596 /* 0xa2 */ x86emuOp_mov_M_AL_IMM,
11597 /* 0xa3 */ x86emuOp_mov_M_AX_IMM,
11598 /* 0xa4 */ x86emuOp_movs_byte,
11599 /* 0xa5 */ x86emuOp_movs_word,
11600 /* 0xa6 */ x86emuOp_cmps_byte,
11601 /* 0xa7 */ x86emuOp_cmps_word,
11602 /* 0xa8 */ x86emuOp_test_AL_IMM,
11603 /* 0xa9 */ x86emuOp_test_AX_IMM,
11604 /* 0xaa */ x86emuOp_stos_byte,
11605 /* 0xab */ x86emuOp_stos_word,
11606 /* 0xac */ x86emuOp_lods_byte,
11607 /* 0xad */ x86emuOp_lods_word,
11608 /* 0xac */ x86emuOp_scas_byte,
11609 /* 0xad */ x86emuOp_scas_word,
11610
11611
11612 /* 0xb0 */ x86emuOp_mov_byte_AL_IMM,
11613 /* 0xb1 */ x86emuOp_mov_byte_CL_IMM,
11614 /* 0xb2 */ x86emuOp_mov_byte_DL_IMM,
11615 /* 0xb3 */ x86emuOp_mov_byte_BL_IMM,
11616 /* 0xb4 */ x86emuOp_mov_byte_AH_IMM,
11617 /* 0xb5 */ x86emuOp_mov_byte_CH_IMM,
11618 /* 0xb6 */ x86emuOp_mov_byte_DH_IMM,
11619 /* 0xb7 */ x86emuOp_mov_byte_BH_IMM,
11620
11621 /* 0xb8 */ x86emuOp_mov_word_AX_IMM,
11622 /* 0xb9 */ x86emuOp_mov_word_CX_IMM,
11623 /* 0xba */ x86emuOp_mov_word_DX_IMM,
11624 /* 0xbb */ x86emuOp_mov_word_BX_IMM,
11625 /* 0xbc */ x86emuOp_mov_word_SP_IMM,
11626 /* 0xbd */ x86emuOp_mov_word_BP_IMM,
11627 /* 0xbe */ x86emuOp_mov_word_SI_IMM,
11628 /* 0xbf */ x86emuOp_mov_word_DI_IMM,
11629
11630 /* 0xc0 */ x86emuOp_opcC0_byte_RM_MEM,
11631 /* 0xc1 */ x86emuOp_opcC1_word_RM_MEM,
11632 /* 0xc2 */ x86emuOp_ret_near_IMM,
11633 /* 0xc3 */ x86emuOp_ret_near,
11634 /* 0xc4 */ x86emuOp_les_R_IMM,
11635 /* 0xc5 */ x86emuOp_lds_R_IMM,
11636 /* 0xc6 */ x86emuOp_mov_byte_RM_IMM,
11637 /* 0xc7 */ x86emuOp_mov_word_RM_IMM,
11638 /* 0xc8 */ x86emuOp_enter,
11639 /* 0xc9 */ x86emuOp_leave,
11640 /* 0xca */ x86emuOp_ret_far_IMM,
11641 /* 0xcb */ x86emuOp_ret_far,
11642 /* 0xcc */ x86emuOp_int3,
11643 /* 0xcd */ x86emuOp_int_IMM,
11644 /* 0xce */ x86emuOp_into,
11645 /* 0xcf */ x86emuOp_iret,
11646
11647 /* 0xd0 */ x86emuOp_opcD0_byte_RM_1,
11648 /* 0xd1 */ x86emuOp_opcD1_word_RM_1,
11649 /* 0xd2 */ x86emuOp_opcD2_byte_RM_CL,
11650 /* 0xd3 */ x86emuOp_opcD3_word_RM_CL,
11651 /* 0xd4 */ x86emuOp_aam,
11652 /* 0xd5 */ x86emuOp_aad,
11653 /* 0xd6 */ x86emuOp_illegal_op, /* Undocumented SETALC instruction */
11654 /* 0xd7 */ x86emuOp_xlat,
11655 /* 0xd8 */ x86emuOp_esc_coprocess_d8,
11656 /* 0xd9 */ x86emuOp_esc_coprocess_d9,
11657 /* 0xda */ x86emuOp_esc_coprocess_da,
11658 /* 0xdb */ x86emuOp_esc_coprocess_db,
11659 /* 0xdc */ x86emuOp_esc_coprocess_dc,
11660 /* 0xdd */ x86emuOp_esc_coprocess_dd,
11661 /* 0xde */ x86emuOp_esc_coprocess_de,
11662 /* 0xdf */ x86emuOp_esc_coprocess_df,
11663
11664 /* 0xe0 */ x86emuOp_loopne,
11665 /* 0xe1 */ x86emuOp_loope,
11666 /* 0xe2 */ x86emuOp_loop,
11667 /* 0xe3 */ x86emuOp_jcxz,
11668 /* 0xe4 */ x86emuOp_in_byte_AL_IMM,
11669 /* 0xe5 */ x86emuOp_in_word_AX_IMM,
11670 /* 0xe6 */ x86emuOp_out_byte_IMM_AL,
11671 /* 0xe7 */ x86emuOp_out_word_IMM_AX,
11672
11673 /* 0xe8 */ x86emuOp_call_near_IMM,
11674 /* 0xe9 */ x86emuOp_jump_near_IMM,
11675 /* 0xea */ x86emuOp_jump_far_IMM,
11676 /* 0xeb */ x86emuOp_jump_byte_IMM,
11677 /* 0xec */ x86emuOp_in_byte_AL_DX,
11678 /* 0xed */ x86emuOp_in_word_AX_DX,
11679 /* 0xee */ x86emuOp_out_byte_DX_AL,
11680 /* 0xef */ x86emuOp_out_word_DX_AX,
11681
11682 /* 0xf0 */ x86emuOp_lock,
11683 /* 0xf1 */ x86emuOp_illegal_op,
11684 /* 0xf2 */ x86emuOp_repne,
11685 /* 0xf3 */ x86emuOp_repe,
11686 /* 0xf4 */ x86emuOp_halt,
11687 /* 0xf5 */ x86emuOp_cmc,
11688 /* 0xf6 */ x86emuOp_opcF6_byte_RM,
11689 /* 0xf7 */ x86emuOp_opcF7_word_RM,
11690
11691 /* 0xf8 */ x86emuOp_clc,
11692 /* 0xf9 */ x86emuOp_stc,
11693 /* 0xfa */ x86emuOp_cli,
11694 /* 0xfb */ x86emuOp_sti,
11695 /* 0xfc */ x86emuOp_cld,
11696 /* 0xfd */ x86emuOp_std,
11697 /* 0xfe */ x86emuOp_opcFE_byte_RM,
11698 /* 0xff */ x86emuOp_opcFF_word_RM,
11699 };