Imported Upstream version 1.15.1
[deb_xorg-server.git] / hw / xfree86 / x86emu / ops.c
CommitLineData
a09e091a
JB
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#include "x86emu/x86emui.h"
74
75/*----------------------------- Implementation ----------------------------*/
76
77/****************************************************************************
78PARAMETERS:
79op1 - Instruction op code
80
81REMARKS:
82Handles illegal opcodes.
83****************************************************************************/
84static void
85x86emuOp_illegal_op(u8 op1)
86{
87 START_OF_INSTR();
88 if (M.x86.R_SP != 0) {
89 DECODE_PRINTF("ILLEGAL X86 OPCODE\n");
90 TRACE_REGS();
91 DB(printk("%04x:%04x: %02X ILLEGAL X86 OPCODE!\n",
92 M.x86.R_CS, M.x86.R_IP - 1, op1));
93 HALT_SYS();
94 }
95 else {
96 /* If we get here, it means the stack pointer is back to zero
97 * so we are just returning from an emulator service call
98 * so therte is no need to display an error message. We trap
99 * the emulator with an 0xF1 opcode to finish the service
100 * call.
101 */
102 X86EMU_halt_sys();
103 }
104 END_OF_INSTR();
105}
106
107/****************************************************************************
108REMARKS:
109Handles opcode 0x00
110****************************************************************************/
111static void
112x86emuOp_add_byte_RM_R(u8 X86EMU_UNUSED(op1))
113{
114 int mod, rl, rh;
115 uint destoffset;
116 u8 *destreg, *srcreg;
117 u8 destval;
118
119 START_OF_INSTR();
120 DECODE_PRINTF("ADD\t");
121 FETCH_DECODE_MODRM(mod, rh, rl);
122 switch (mod) {
123 case 0:
124 destoffset = decode_rm00_address(rl);
125 DECODE_PRINTF(",");
126 destval = fetch_data_byte(destoffset);
127 srcreg = DECODE_RM_BYTE_REGISTER(rh);
128 DECODE_PRINTF("\n");
129 TRACE_AND_STEP();
130 destval = add_byte(destval, *srcreg);
131 store_data_byte(destoffset, destval);
132 break;
133 case 1:
134 destoffset = decode_rm01_address(rl);
135 DECODE_PRINTF(",");
136 destval = fetch_data_byte(destoffset);
137 srcreg = DECODE_RM_BYTE_REGISTER(rh);
138 DECODE_PRINTF("\n");
139 TRACE_AND_STEP();
140 destval = add_byte(destval, *srcreg);
141 store_data_byte(destoffset, destval);
142 break;
143 case 2:
144 destoffset = decode_rm10_address(rl);
145 DECODE_PRINTF(",");
146 destval = fetch_data_byte(destoffset);
147 srcreg = DECODE_RM_BYTE_REGISTER(rh);
148 DECODE_PRINTF("\n");
149 TRACE_AND_STEP();
150 destval = add_byte(destval, *srcreg);
151 store_data_byte(destoffset, destval);
152 break;
153 case 3: /* register to register */
154 destreg = DECODE_RM_BYTE_REGISTER(rl);
155 DECODE_PRINTF(",");
156 srcreg = DECODE_RM_BYTE_REGISTER(rh);
157 DECODE_PRINTF("\n");
158 TRACE_AND_STEP();
159 *destreg = add_byte(*destreg, *srcreg);
160 break;
161 }
162 DECODE_CLEAR_SEGOVR();
163 END_OF_INSTR();
164}
165
166/****************************************************************************
167REMARKS:
168Handles opcode 0x01
169****************************************************************************/
170static void
171x86emuOp_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 }
194 else {
195 u16 destval;
196 u16 *srcreg;
197
198 destoffset = decode_rm00_address(rl);
199 DECODE_PRINTF(",");
200 destval = fetch_data_word(destoffset);
201 srcreg = DECODE_RM_WORD_REGISTER(rh);
202 DECODE_PRINTF("\n");
203 TRACE_AND_STEP();
204 destval = add_word(destval, *srcreg);
205 store_data_word(destoffset, destval);
206 }
207 break;
208 case 1:
209 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
210 u32 destval;
211 u32 *srcreg;
212
213 destoffset = decode_rm01_address(rl);
214 DECODE_PRINTF(",");
215 destval = fetch_data_long(destoffset);
216 srcreg = DECODE_RM_LONG_REGISTER(rh);
217 DECODE_PRINTF("\n");
218 TRACE_AND_STEP();
219 destval = add_long(destval, *srcreg);
220 store_data_long(destoffset, destval);
221 }
222 else {
223 u16 destval;
224 u16 *srcreg;
225
226 destoffset = decode_rm01_address(rl);
227 DECODE_PRINTF(",");
228 destval = fetch_data_word(destoffset);
229 srcreg = DECODE_RM_WORD_REGISTER(rh);
230 DECODE_PRINTF("\n");
231 TRACE_AND_STEP();
232 destval = add_word(destval, *srcreg);
233 store_data_word(destoffset, destval);
234 }
235 break;
236 case 2:
237 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
238 u32 destval;
239 u32 *srcreg;
240
241 destoffset = decode_rm10_address(rl);
242 DECODE_PRINTF(",");
243 destval = fetch_data_long(destoffset);
244 srcreg = DECODE_RM_LONG_REGISTER(rh);
245 DECODE_PRINTF("\n");
246 TRACE_AND_STEP();
247 destval = add_long(destval, *srcreg);
248 store_data_long(destoffset, destval);
249 }
250 else {
251 u16 destval;
252 u16 *srcreg;
253
254 destoffset = decode_rm10_address(rl);
255 DECODE_PRINTF(",");
256 destval = fetch_data_word(destoffset);
257 srcreg = DECODE_RM_WORD_REGISTER(rh);
258 DECODE_PRINTF("\n");
259 TRACE_AND_STEP();
260 destval = add_word(destval, *srcreg);
261 store_data_word(destoffset, destval);
262 }
263 break;
264 case 3: /* register to register */
265 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
266 u32 *destreg, *srcreg;
267
268 destreg = DECODE_RM_LONG_REGISTER(rl);
269 DECODE_PRINTF(",");
270 srcreg = DECODE_RM_LONG_REGISTER(rh);
271 DECODE_PRINTF("\n");
272 TRACE_AND_STEP();
273 *destreg = add_long(*destreg, *srcreg);
274 }
275 else {
276 u16 *destreg, *srcreg;
277
278 destreg = DECODE_RM_WORD_REGISTER(rl);
279 DECODE_PRINTF(",");
280 srcreg = DECODE_RM_WORD_REGISTER(rh);
281 DECODE_PRINTF("\n");
282 TRACE_AND_STEP();
283 *destreg = add_word(*destreg, *srcreg);
284 }
285 break;
286 }
287 DECODE_CLEAR_SEGOVR();
288 END_OF_INSTR();
289}
290
291/****************************************************************************
292REMARKS:
293Handles opcode 0x02
294****************************************************************************/
295static void
296x86emuOp_add_byte_R_RM(u8 X86EMU_UNUSED(op1))
297{
298 int mod, rl, rh;
299 u8 *destreg, *srcreg;
300 uint srcoffset;
301 u8 srcval;
302
303 START_OF_INSTR();
304 DECODE_PRINTF("ADD\t");
305 FETCH_DECODE_MODRM(mod, rh, rl);
306 switch (mod) {
307 case 0:
308 destreg = DECODE_RM_BYTE_REGISTER(rh);
309 DECODE_PRINTF(",");
310 srcoffset = decode_rm00_address(rl);
311 srcval = fetch_data_byte(srcoffset);
312 DECODE_PRINTF("\n");
313 TRACE_AND_STEP();
314 *destreg = add_byte(*destreg, srcval);
315 break;
316 case 1:
317 destreg = DECODE_RM_BYTE_REGISTER(rh);
318 DECODE_PRINTF(",");
319 srcoffset = decode_rm01_address(rl);
320 srcval = fetch_data_byte(srcoffset);
321 DECODE_PRINTF("\n");
322 TRACE_AND_STEP();
323 *destreg = add_byte(*destreg, srcval);
324 break;
325 case 2:
326 destreg = DECODE_RM_BYTE_REGISTER(rh);
327 DECODE_PRINTF(",");
328 srcoffset = decode_rm10_address(rl);
329 srcval = fetch_data_byte(srcoffset);
330 DECODE_PRINTF("\n");
331 TRACE_AND_STEP();
332 *destreg = add_byte(*destreg, srcval);
333 break;
334 case 3: /* register to register */
335 destreg = DECODE_RM_BYTE_REGISTER(rh);
336 DECODE_PRINTF(",");
337 srcreg = DECODE_RM_BYTE_REGISTER(rl);
338 DECODE_PRINTF("\n");
339 TRACE_AND_STEP();
340 *destreg = add_byte(*destreg, *srcreg);
341 break;
342 }
343 DECODE_CLEAR_SEGOVR();
344 END_OF_INSTR();
345}
346
347/****************************************************************************
348REMARKS:
349Handles opcode 0x03
350****************************************************************************/
351static void
352x86emuOp_add_word_R_RM(u8 X86EMU_UNUSED(op1))
353{
354 int mod, rl, rh;
355 uint srcoffset;
356
357 START_OF_INSTR();
358 DECODE_PRINTF("ADD\t");
359 FETCH_DECODE_MODRM(mod, rh, rl);
360 switch (mod) {
361 case 0:
362 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
363 u32 *destreg;
364 u32 srcval;
365
366 destreg = DECODE_RM_LONG_REGISTER(rh);
367 DECODE_PRINTF(",");
368 srcoffset = decode_rm00_address(rl);
369 srcval = fetch_data_long(srcoffset);
370 DECODE_PRINTF("\n");
371 TRACE_AND_STEP();
372 *destreg = add_long(*destreg, srcval);
373 }
374 else {
375 u16 *destreg;
376 u16 srcval;
377
378 destreg = DECODE_RM_WORD_REGISTER(rh);
379 DECODE_PRINTF(",");
380 srcoffset = decode_rm00_address(rl);
381 srcval = fetch_data_word(srcoffset);
382 DECODE_PRINTF("\n");
383 TRACE_AND_STEP();
384 *destreg = add_word(*destreg, srcval);
385 }
386 break;
387 case 1:
388 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
389 u32 *destreg;
390 u32 srcval;
391
392 destreg = DECODE_RM_LONG_REGISTER(rh);
393 DECODE_PRINTF(",");
394 srcoffset = decode_rm01_address(rl);
395 srcval = fetch_data_long(srcoffset);
396 DECODE_PRINTF("\n");
397 TRACE_AND_STEP();
398 *destreg = add_long(*destreg, srcval);
399 }
400 else {
401 u16 *destreg;
402 u16 srcval;
403
404 destreg = DECODE_RM_WORD_REGISTER(rh);
405 DECODE_PRINTF(",");
406 srcoffset = decode_rm01_address(rl);
407 srcval = fetch_data_word(srcoffset);
408 DECODE_PRINTF("\n");
409 TRACE_AND_STEP();
410 *destreg = add_word(*destreg, srcval);
411 }
412 break;
413 case 2:
414 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
415 u32 *destreg;
416 u32 srcval;
417
418 destreg = DECODE_RM_LONG_REGISTER(rh);
419 DECODE_PRINTF(",");
420 srcoffset = decode_rm10_address(rl);
421 srcval = fetch_data_long(srcoffset);
422 DECODE_PRINTF("\n");
423 TRACE_AND_STEP();
424 *destreg = add_long(*destreg, srcval);
425 }
426 else {
427 u16 *destreg;
428 u16 srcval;
429
430 destreg = DECODE_RM_WORD_REGISTER(rh);
431 DECODE_PRINTF(",");
432 srcoffset = decode_rm10_address(rl);
433 srcval = fetch_data_word(srcoffset);
434 DECODE_PRINTF("\n");
435 TRACE_AND_STEP();
436 *destreg = add_word(*destreg, srcval);
437 }
438 break;
439 case 3: /* register to register */
440 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
441 u32 *destreg, *srcreg;
442
443 destreg = DECODE_RM_LONG_REGISTER(rh);
444 DECODE_PRINTF(",");
445 srcreg = DECODE_RM_LONG_REGISTER(rl);
446 DECODE_PRINTF("\n");
447 TRACE_AND_STEP();
448 *destreg = add_long(*destreg, *srcreg);
449 }
450 else {
451 u16 *destreg, *srcreg;
452
453 destreg = DECODE_RM_WORD_REGISTER(rh);
454 DECODE_PRINTF(",");
455 srcreg = DECODE_RM_WORD_REGISTER(rl);
456 DECODE_PRINTF("\n");
457 TRACE_AND_STEP();
458 *destreg = add_word(*destreg, *srcreg);
459 }
460 break;
461 }
462 DECODE_CLEAR_SEGOVR();
463 END_OF_INSTR();
464}
465
466/****************************************************************************
467REMARKS:
468Handles opcode 0x04
469****************************************************************************/
470static void
471x86emuOp_add_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
472{
473 u8 srcval;
474
475 START_OF_INSTR();
476 DECODE_PRINTF("ADD\tAL,");
477 srcval = fetch_byte_imm();
478 DECODE_PRINTF2("%x\n", srcval);
479 TRACE_AND_STEP();
480 M.x86.R_AL = add_byte(M.x86.R_AL, srcval);
481 DECODE_CLEAR_SEGOVR();
482 END_OF_INSTR();
483}
484
485/****************************************************************************
486REMARKS:
487Handles opcode 0x05
488****************************************************************************/
489static void
490x86emuOp_add_word_AX_IMM(u8 X86EMU_UNUSED(op1))
491{
492 u32 srcval;
493
494 START_OF_INSTR();
495 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
496 DECODE_PRINTF("ADD\tEAX,");
497 srcval = fetch_long_imm();
498 }
499 else {
500 DECODE_PRINTF("ADD\tAX,");
501 srcval = fetch_word_imm();
502 }
503 DECODE_PRINTF2("%x\n", srcval);
504 TRACE_AND_STEP();
505 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
506 M.x86.R_EAX = add_long(M.x86.R_EAX, srcval);
507 }
508 else {
509 M.x86.R_AX = add_word(M.x86.R_AX, (u16) srcval);
510 }
511 DECODE_CLEAR_SEGOVR();
512 END_OF_INSTR();
513}
514
515/****************************************************************************
516REMARKS:
517Handles opcode 0x06
518****************************************************************************/
519static void
520x86emuOp_push_ES(u8 X86EMU_UNUSED(op1))
521{
522 START_OF_INSTR();
523 DECODE_PRINTF("PUSH\tES\n");
524 TRACE_AND_STEP();
525 push_word(M.x86.R_ES);
526 DECODE_CLEAR_SEGOVR();
527 END_OF_INSTR();
528}
529
530/****************************************************************************
531REMARKS:
532Handles opcode 0x07
533****************************************************************************/
534static void
535x86emuOp_pop_ES(u8 X86EMU_UNUSED(op1))
536{
537 START_OF_INSTR();
538 DECODE_PRINTF("POP\tES\n");
539 TRACE_AND_STEP();
540 M.x86.R_ES = pop_word();
541 DECODE_CLEAR_SEGOVR();
542 END_OF_INSTR();
543}
544
545/****************************************************************************
546REMARKS:
547Handles opcode 0x08
548****************************************************************************/
549static void
550x86emuOp_or_byte_RM_R(u8 X86EMU_UNUSED(op1))
551{
552 int mod, rl, rh;
553 u8 *destreg, *srcreg;
554 uint destoffset;
555 u8 destval;
556
557 START_OF_INSTR();
558 DECODE_PRINTF("OR\t");
559 FETCH_DECODE_MODRM(mod, rh, rl);
560 switch (mod) {
561 case 0:
562 destoffset = decode_rm00_address(rl);
563 DECODE_PRINTF(",");
564 destval = fetch_data_byte(destoffset);
565 srcreg = DECODE_RM_BYTE_REGISTER(rh);
566 DECODE_PRINTF("\n");
567 TRACE_AND_STEP();
568 destval = or_byte(destval, *srcreg);
569 store_data_byte(destoffset, destval);
570 break;
571 case 1:
572 destoffset = decode_rm01_address(rl);
573 DECODE_PRINTF(",");
574 destval = fetch_data_byte(destoffset);
575 srcreg = DECODE_RM_BYTE_REGISTER(rh);
576 DECODE_PRINTF("\n");
577 TRACE_AND_STEP();
578 destval = or_byte(destval, *srcreg);
579 store_data_byte(destoffset, destval);
580 break;
581 case 2:
582 destoffset = decode_rm10_address(rl);
583 DECODE_PRINTF(",");
584 destval = fetch_data_byte(destoffset);
585 srcreg = DECODE_RM_BYTE_REGISTER(rh);
586 DECODE_PRINTF("\n");
587 TRACE_AND_STEP();
588 destval = or_byte(destval, *srcreg);
589 store_data_byte(destoffset, destval);
590 break;
591 case 3: /* register to register */
592 destreg = DECODE_RM_BYTE_REGISTER(rl);
593 DECODE_PRINTF(",");
594 srcreg = DECODE_RM_BYTE_REGISTER(rh);
595 DECODE_PRINTF("\n");
596 TRACE_AND_STEP();
597 *destreg = or_byte(*destreg, *srcreg);
598 break;
599 }
600 DECODE_CLEAR_SEGOVR();
601 END_OF_INSTR();
602}
603
604/****************************************************************************
605REMARKS:
606Handles opcode 0x09
607****************************************************************************/
608static void
609x86emuOp_or_word_RM_R(u8 X86EMU_UNUSED(op1))
610{
611 int mod, rl, rh;
612 uint destoffset;
613
614 START_OF_INSTR();
615 DECODE_PRINTF("OR\t");
616 FETCH_DECODE_MODRM(mod, rh, rl);
617 switch (mod) {
618 case 0:
619 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
620 u32 destval;
621 u32 *srcreg;
622
623 destoffset = decode_rm00_address(rl);
624 DECODE_PRINTF(",");
625 destval = fetch_data_long(destoffset);
626 srcreg = DECODE_RM_LONG_REGISTER(rh);
627 DECODE_PRINTF("\n");
628 TRACE_AND_STEP();
629 destval = or_long(destval, *srcreg);
630 store_data_long(destoffset, destval);
631 }
632 else {
633 u16 destval;
634 u16 *srcreg;
635
636 destoffset = decode_rm00_address(rl);
637 DECODE_PRINTF(",");
638 destval = fetch_data_word(destoffset);
639 srcreg = DECODE_RM_WORD_REGISTER(rh);
640 DECODE_PRINTF("\n");
641 TRACE_AND_STEP();
642 destval = or_word(destval, *srcreg);
643 store_data_word(destoffset, destval);
644 }
645 break;
646 case 1:
647 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
648 u32 destval;
649 u32 *srcreg;
650
651 destoffset = decode_rm01_address(rl);
652 DECODE_PRINTF(",");
653 destval = fetch_data_long(destoffset);
654 srcreg = DECODE_RM_LONG_REGISTER(rh);
655 DECODE_PRINTF("\n");
656 TRACE_AND_STEP();
657 destval = or_long(destval, *srcreg);
658 store_data_long(destoffset, destval);
659 }
660 else {
661 u16 destval;
662 u16 *srcreg;
663
664 destoffset = decode_rm01_address(rl);
665 DECODE_PRINTF(",");
666 destval = fetch_data_word(destoffset);
667 srcreg = DECODE_RM_WORD_REGISTER(rh);
668 DECODE_PRINTF("\n");
669 TRACE_AND_STEP();
670 destval = or_word(destval, *srcreg);
671 store_data_word(destoffset, destval);
672 }
673 break;
674 case 2:
675 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
676 u32 destval;
677 u32 *srcreg;
678
679 destoffset = decode_rm10_address(rl);
680 DECODE_PRINTF(",");
681 destval = fetch_data_long(destoffset);
682 srcreg = DECODE_RM_LONG_REGISTER(rh);
683 DECODE_PRINTF("\n");
684 TRACE_AND_STEP();
685 destval = or_long(destval, *srcreg);
686 store_data_long(destoffset, destval);
687 }
688 else {
689 u16 destval;
690 u16 *srcreg;
691
692 destoffset = decode_rm10_address(rl);
693 DECODE_PRINTF(",");
694 destval = fetch_data_word(destoffset);
695 srcreg = DECODE_RM_WORD_REGISTER(rh);
696 DECODE_PRINTF("\n");
697 TRACE_AND_STEP();
698 destval = or_word(destval, *srcreg);
699 store_data_word(destoffset, destval);
700 }
701 break;
702 case 3: /* register to register */
703 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
704 u32 *destreg, *srcreg;
705
706 destreg = DECODE_RM_LONG_REGISTER(rl);
707 DECODE_PRINTF(",");
708 srcreg = DECODE_RM_LONG_REGISTER(rh);
709 DECODE_PRINTF("\n");
710 TRACE_AND_STEP();
711 *destreg = or_long(*destreg, *srcreg);
712 }
713 else {
714 u16 *destreg, *srcreg;
715
716 destreg = DECODE_RM_WORD_REGISTER(rl);
717 DECODE_PRINTF(",");
718 srcreg = DECODE_RM_WORD_REGISTER(rh);
719 DECODE_PRINTF("\n");
720 TRACE_AND_STEP();
721 *destreg = or_word(*destreg, *srcreg);
722 }
723 break;
724 }
725 DECODE_CLEAR_SEGOVR();
726 END_OF_INSTR();
727}
728
729/****************************************************************************
730REMARKS:
731Handles opcode 0x0a
732****************************************************************************/
733static void
734x86emuOp_or_byte_R_RM(u8 X86EMU_UNUSED(op1))
735{
736 int mod, rl, rh;
737 u8 *destreg, *srcreg;
738 uint srcoffset;
739 u8 srcval;
740
741 START_OF_INSTR();
742 DECODE_PRINTF("OR\t");
743 FETCH_DECODE_MODRM(mod, rh, rl);
744 switch (mod) {
745 case 0:
746 destreg = DECODE_RM_BYTE_REGISTER(rh);
747 DECODE_PRINTF(",");
748 srcoffset = decode_rm00_address(rl);
749 srcval = fetch_data_byte(srcoffset);
750 DECODE_PRINTF("\n");
751 TRACE_AND_STEP();
752 *destreg = or_byte(*destreg, srcval);
753 break;
754 case 1:
755 destreg = DECODE_RM_BYTE_REGISTER(rh);
756 DECODE_PRINTF(",");
757 srcoffset = decode_rm01_address(rl);
758 srcval = fetch_data_byte(srcoffset);
759 DECODE_PRINTF("\n");
760 TRACE_AND_STEP();
761 *destreg = or_byte(*destreg, srcval);
762 break;
763 case 2:
764 destreg = DECODE_RM_BYTE_REGISTER(rh);
765 DECODE_PRINTF(",");
766 srcoffset = decode_rm10_address(rl);
767 srcval = fetch_data_byte(srcoffset);
768 DECODE_PRINTF("\n");
769 TRACE_AND_STEP();
770 *destreg = or_byte(*destreg, srcval);
771 break;
772 case 3: /* register to register */
773 destreg = DECODE_RM_BYTE_REGISTER(rh);
774 DECODE_PRINTF(",");
775 srcreg = DECODE_RM_BYTE_REGISTER(rl);
776 DECODE_PRINTF("\n");
777 TRACE_AND_STEP();
778 *destreg = or_byte(*destreg, *srcreg);
779 break;
780 }
781 DECODE_CLEAR_SEGOVR();
782 END_OF_INSTR();
783}
784
785/****************************************************************************
786REMARKS:
787Handles opcode 0x0b
788****************************************************************************/
789static void
790x86emuOp_or_word_R_RM(u8 X86EMU_UNUSED(op1))
791{
792 int mod, rl, rh;
793 uint srcoffset;
794
795 START_OF_INSTR();
796 DECODE_PRINTF("OR\t");
797 FETCH_DECODE_MODRM(mod, rh, rl);
798 switch (mod) {
799 case 0:
800 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
801 u32 *destreg;
802 u32 srcval;
803
804 destreg = DECODE_RM_LONG_REGISTER(rh);
805 DECODE_PRINTF(",");
806 srcoffset = decode_rm00_address(rl);
807 srcval = fetch_data_long(srcoffset);
808 DECODE_PRINTF("\n");
809 TRACE_AND_STEP();
810 *destreg = or_long(*destreg, srcval);
811 }
812 else {
813 u16 *destreg;
814 u16 srcval;
815
816 destreg = DECODE_RM_WORD_REGISTER(rh);
817 DECODE_PRINTF(",");
818 srcoffset = decode_rm00_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 1:
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_rm01_address(rl);
833 srcval = fetch_data_long(srcoffset);
834 DECODE_PRINTF("\n");
835 TRACE_AND_STEP();
836 *destreg = or_long(*destreg, srcval);
837 }
838 else {
839 u16 *destreg;
840 u16 srcval;
841
842 destreg = DECODE_RM_WORD_REGISTER(rh);
843 DECODE_PRINTF(",");
844 srcoffset = decode_rm01_address(rl);
845 srcval = fetch_data_word(srcoffset);
846 DECODE_PRINTF("\n");
847 TRACE_AND_STEP();
848 *destreg = or_word(*destreg, srcval);
849 }
850 break;
851 case 2:
852 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
853 u32 *destreg;
854 u32 srcval;
855
856 destreg = DECODE_RM_LONG_REGISTER(rh);
857 DECODE_PRINTF(",");
858 srcoffset = decode_rm10_address(rl);
859 srcval = fetch_data_long(srcoffset);
860 DECODE_PRINTF("\n");
861 TRACE_AND_STEP();
862 *destreg = or_long(*destreg, srcval);
863 }
864 else {
865 u16 *destreg;
866 u16 srcval;
867
868 destreg = DECODE_RM_WORD_REGISTER(rh);
869 DECODE_PRINTF(",");
870 srcoffset = decode_rm10_address(rl);
871 srcval = fetch_data_word(srcoffset);
872 DECODE_PRINTF("\n");
873 TRACE_AND_STEP();
874 *destreg = or_word(*destreg, srcval);
875 }
876 break;
877 case 3: /* register to register */
878 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
879 u32 *destreg, *srcreg;
880
881 destreg = DECODE_RM_LONG_REGISTER(rh);
882 DECODE_PRINTF(",");
883 srcreg = DECODE_RM_LONG_REGISTER(rl);
884 DECODE_PRINTF("\n");
885 TRACE_AND_STEP();
886 *destreg = or_long(*destreg, *srcreg);
887 }
888 else {
889 u16 *destreg, *srcreg;
890
891 destreg = DECODE_RM_WORD_REGISTER(rh);
892 DECODE_PRINTF(",");
893 srcreg = DECODE_RM_WORD_REGISTER(rl);
894 DECODE_PRINTF("\n");
895 TRACE_AND_STEP();
896 *destreg = or_word(*destreg, *srcreg);
897 }
898 break;
899 }
900 DECODE_CLEAR_SEGOVR();
901 END_OF_INSTR();
902}
903
904/****************************************************************************
905REMARKS:
906Handles opcode 0x0c
907****************************************************************************/
908static void
909x86emuOp_or_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
910{
911 u8 srcval;
912
913 START_OF_INSTR();
914 DECODE_PRINTF("OR\tAL,");
915 srcval = fetch_byte_imm();
916 DECODE_PRINTF2("%x\n", srcval);
917 TRACE_AND_STEP();
918 M.x86.R_AL = or_byte(M.x86.R_AL, srcval);
919 DECODE_CLEAR_SEGOVR();
920 END_OF_INSTR();
921}
922
923/****************************************************************************
924REMARKS:
925Handles opcode 0x0d
926****************************************************************************/
927static void
928x86emuOp_or_word_AX_IMM(u8 X86EMU_UNUSED(op1))
929{
930 u32 srcval;
931
932 START_OF_INSTR();
933 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
934 DECODE_PRINTF("OR\tEAX,");
935 srcval = fetch_long_imm();
936 }
937 else {
938 DECODE_PRINTF("OR\tAX,");
939 srcval = fetch_word_imm();
940 }
941 DECODE_PRINTF2("%x\n", srcval);
942 TRACE_AND_STEP();
943 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
944 M.x86.R_EAX = or_long(M.x86.R_EAX, srcval);
945 }
946 else {
947 M.x86.R_AX = or_word(M.x86.R_AX, (u16) srcval);
948 }
949 DECODE_CLEAR_SEGOVR();
950 END_OF_INSTR();
951}
952
953/****************************************************************************
954REMARKS:
955Handles opcode 0x0e
956****************************************************************************/
957static void
958x86emuOp_push_CS(u8 X86EMU_UNUSED(op1))
959{
960 START_OF_INSTR();
961 DECODE_PRINTF("PUSH\tCS\n");
962 TRACE_AND_STEP();
963 push_word(M.x86.R_CS);
964 DECODE_CLEAR_SEGOVR();
965 END_OF_INSTR();
966}
967
968/****************************************************************************
969REMARKS:
970Handles opcode 0x0f. Escape for two-byte opcode (286 or better)
971****************************************************************************/
972static void
973x86emuOp_two_byte(u8 X86EMU_UNUSED(op1))
974{
975 u8 op2 = (*sys_rdb) (((u32) M.x86.R_CS << 4) + (M.x86.R_IP++));
976
977 INC_DECODED_INST_LEN(1);
978 (*x86emu_optab2[op2]) (op2);
979}
980
981/****************************************************************************
982REMARKS:
983Handles opcode 0x10
984****************************************************************************/
985static void
986x86emuOp_adc_byte_RM_R(u8 X86EMU_UNUSED(op1))
987{
988 int mod, rl, rh;
989 u8 *destreg, *srcreg;
990 uint destoffset;
991 u8 destval;
992
993 START_OF_INSTR();
994 DECODE_PRINTF("ADC\t");
995 FETCH_DECODE_MODRM(mod, rh, rl);
996 switch (mod) {
997 case 0:
998 destoffset = decode_rm00_address(rl);
999 DECODE_PRINTF(",");
1000 destval = fetch_data_byte(destoffset);
1001 srcreg = DECODE_RM_BYTE_REGISTER(rh);
1002 DECODE_PRINTF("\n");
1003 TRACE_AND_STEP();
1004 destval = adc_byte(destval, *srcreg);
1005 store_data_byte(destoffset, destval);
1006 break;
1007 case 1:
1008 destoffset = decode_rm01_address(rl);
1009 DECODE_PRINTF(",");
1010 destval = fetch_data_byte(destoffset);
1011 srcreg = DECODE_RM_BYTE_REGISTER(rh);
1012 DECODE_PRINTF("\n");
1013 TRACE_AND_STEP();
1014 destval = adc_byte(destval, *srcreg);
1015 store_data_byte(destoffset, destval);
1016 break;
1017 case 2:
1018 destoffset = decode_rm10_address(rl);
1019 DECODE_PRINTF(",");
1020 destval = fetch_data_byte(destoffset);
1021 srcreg = DECODE_RM_BYTE_REGISTER(rh);
1022 DECODE_PRINTF("\n");
1023 TRACE_AND_STEP();
1024 destval = adc_byte(destval, *srcreg);
1025 store_data_byte(destoffset, destval);
1026 break;
1027 case 3: /* register to register */
1028 destreg = DECODE_RM_BYTE_REGISTER(rl);
1029 DECODE_PRINTF(",");
1030 srcreg = DECODE_RM_BYTE_REGISTER(rh);
1031 DECODE_PRINTF("\n");
1032 TRACE_AND_STEP();
1033 *destreg = adc_byte(*destreg, *srcreg);
1034 break;
1035 }
1036 DECODE_CLEAR_SEGOVR();
1037 END_OF_INSTR();
1038}
1039
1040/****************************************************************************
1041REMARKS:
1042Handles opcode 0x11
1043****************************************************************************/
1044static void
1045x86emuOp_adc_word_RM_R(u8 X86EMU_UNUSED(op1))
1046{
1047 int mod, rl, rh;
1048 uint destoffset;
1049
1050 START_OF_INSTR();
1051 DECODE_PRINTF("ADC\t");
1052 FETCH_DECODE_MODRM(mod, rh, rl);
1053 switch (mod) {
1054 case 0:
1055 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1056 u32 destval;
1057 u32 *srcreg;
1058
1059 destoffset = decode_rm00_address(rl);
1060 DECODE_PRINTF(",");
1061 destval = fetch_data_long(destoffset);
1062 srcreg = DECODE_RM_LONG_REGISTER(rh);
1063 DECODE_PRINTF("\n");
1064 TRACE_AND_STEP();
1065 destval = adc_long(destval, *srcreg);
1066 store_data_long(destoffset, destval);
1067 }
1068 else {
1069 u16 destval;
1070 u16 *srcreg;
1071
1072 destoffset = decode_rm00_address(rl);
1073 DECODE_PRINTF(",");
1074 destval = fetch_data_word(destoffset);
1075 srcreg = DECODE_RM_WORD_REGISTER(rh);
1076 DECODE_PRINTF("\n");
1077 TRACE_AND_STEP();
1078 destval = adc_word(destval, *srcreg);
1079 store_data_word(destoffset, destval);
1080 }
1081 break;
1082 case 1:
1083 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1084 u32 destval;
1085 u32 *srcreg;
1086
1087 destoffset = decode_rm01_address(rl);
1088 DECODE_PRINTF(",");
1089 destval = fetch_data_long(destoffset);
1090 srcreg = DECODE_RM_LONG_REGISTER(rh);
1091 DECODE_PRINTF("\n");
1092 TRACE_AND_STEP();
1093 destval = adc_long(destval, *srcreg);
1094 store_data_long(destoffset, destval);
1095 }
1096 else {
1097 u16 destval;
1098 u16 *srcreg;
1099
1100 destoffset = decode_rm01_address(rl);
1101 DECODE_PRINTF(",");
1102 destval = fetch_data_word(destoffset);
1103 srcreg = DECODE_RM_WORD_REGISTER(rh);
1104 DECODE_PRINTF("\n");
1105 TRACE_AND_STEP();
1106 destval = adc_word(destval, *srcreg);
1107 store_data_word(destoffset, destval);
1108 }
1109 break;
1110 case 2:
1111 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1112 u32 destval;
1113 u32 *srcreg;
1114
1115 destoffset = decode_rm10_address(rl);
1116 DECODE_PRINTF(",");
1117 destval = fetch_data_long(destoffset);
1118 srcreg = DECODE_RM_LONG_REGISTER(rh);
1119 DECODE_PRINTF("\n");
1120 TRACE_AND_STEP();
1121 destval = adc_long(destval, *srcreg);
1122 store_data_long(destoffset, destval);
1123 }
1124 else {
1125 u16 destval;
1126 u16 *srcreg;
1127
1128 destoffset = decode_rm10_address(rl);
1129 DECODE_PRINTF(",");
1130 destval = fetch_data_word(destoffset);
1131 srcreg = DECODE_RM_WORD_REGISTER(rh);
1132 DECODE_PRINTF("\n");
1133 TRACE_AND_STEP();
1134 destval = adc_word(destval, *srcreg);
1135 store_data_word(destoffset, destval);
1136 }
1137 break;
1138 case 3: /* register to register */
1139 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1140 u32 *destreg, *srcreg;
1141
1142 destreg = DECODE_RM_LONG_REGISTER(rl);
1143 DECODE_PRINTF(",");
1144 srcreg = DECODE_RM_LONG_REGISTER(rh);
1145 DECODE_PRINTF("\n");
1146 TRACE_AND_STEP();
1147 *destreg = adc_long(*destreg, *srcreg);
1148 }
1149 else {
1150 u16 *destreg, *srcreg;
1151
1152 destreg = DECODE_RM_WORD_REGISTER(rl);
1153 DECODE_PRINTF(",");
1154 srcreg = DECODE_RM_WORD_REGISTER(rh);
1155 DECODE_PRINTF("\n");
1156 TRACE_AND_STEP();
1157 *destreg = adc_word(*destreg, *srcreg);
1158 }
1159 break;
1160 }
1161 DECODE_CLEAR_SEGOVR();
1162 END_OF_INSTR();
1163}
1164
1165/****************************************************************************
1166REMARKS:
1167Handles opcode 0x12
1168****************************************************************************/
1169static void
1170x86emuOp_adc_byte_R_RM(u8 X86EMU_UNUSED(op1))
1171{
1172 int mod, rl, rh;
1173 u8 *destreg, *srcreg;
1174 uint srcoffset;
1175 u8 srcval;
1176
1177 START_OF_INSTR();
1178 DECODE_PRINTF("ADC\t");
1179 FETCH_DECODE_MODRM(mod, rh, rl);
1180 switch (mod) {
1181 case 0:
1182 destreg = DECODE_RM_BYTE_REGISTER(rh);
1183 DECODE_PRINTF(",");
1184 srcoffset = decode_rm00_address(rl);
1185 srcval = fetch_data_byte(srcoffset);
1186 DECODE_PRINTF("\n");
1187 TRACE_AND_STEP();
1188 *destreg = adc_byte(*destreg, srcval);
1189 break;
1190 case 1:
1191 destreg = DECODE_RM_BYTE_REGISTER(rh);
1192 DECODE_PRINTF(",");
1193 srcoffset = decode_rm01_address(rl);
1194 srcval = fetch_data_byte(srcoffset);
1195 DECODE_PRINTF("\n");
1196 TRACE_AND_STEP();
1197 *destreg = adc_byte(*destreg, srcval);
1198 break;
1199 case 2:
1200 destreg = DECODE_RM_BYTE_REGISTER(rh);
1201 DECODE_PRINTF(",");
1202 srcoffset = decode_rm10_address(rl);
1203 srcval = fetch_data_byte(srcoffset);
1204 DECODE_PRINTF("\n");
1205 TRACE_AND_STEP();
1206 *destreg = adc_byte(*destreg, srcval);
1207 break;
1208 case 3: /* register to register */
1209 destreg = DECODE_RM_BYTE_REGISTER(rh);
1210 DECODE_PRINTF(",");
1211 srcreg = DECODE_RM_BYTE_REGISTER(rl);
1212 DECODE_PRINTF("\n");
1213 TRACE_AND_STEP();
1214 *destreg = adc_byte(*destreg, *srcreg);
1215 break;
1216 }
1217 DECODE_CLEAR_SEGOVR();
1218 END_OF_INSTR();
1219}
1220
1221/****************************************************************************
1222REMARKS:
1223Handles opcode 0x13
1224****************************************************************************/
1225static void
1226x86emuOp_adc_word_R_RM(u8 X86EMU_UNUSED(op1))
1227{
1228 int mod, rl, rh;
1229 uint srcoffset;
1230
1231 START_OF_INSTR();
1232 DECODE_PRINTF("ADC\t");
1233 FETCH_DECODE_MODRM(mod, rh, rl);
1234 switch (mod) {
1235 case 0:
1236 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1237 u32 *destreg;
1238 u32 srcval;
1239
1240 destreg = DECODE_RM_LONG_REGISTER(rh);
1241 DECODE_PRINTF(",");
1242 srcoffset = decode_rm00_address(rl);
1243 srcval = fetch_data_long(srcoffset);
1244 DECODE_PRINTF("\n");
1245 TRACE_AND_STEP();
1246 *destreg = adc_long(*destreg, srcval);
1247 }
1248 else {
1249 u16 *destreg;
1250 u16 srcval;
1251
1252 destreg = DECODE_RM_WORD_REGISTER(rh);
1253 DECODE_PRINTF(",");
1254 srcoffset = decode_rm00_address(rl);
1255 srcval = fetch_data_word(srcoffset);
1256 DECODE_PRINTF("\n");
1257 TRACE_AND_STEP();
1258 *destreg = adc_word(*destreg, srcval);
1259 }
1260 break;
1261 case 1:
1262 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1263 u32 *destreg;
1264 u32 srcval;
1265
1266 destreg = DECODE_RM_LONG_REGISTER(rh);
1267 DECODE_PRINTF(",");
1268 srcoffset = decode_rm01_address(rl);
1269 srcval = fetch_data_long(srcoffset);
1270 DECODE_PRINTF("\n");
1271 TRACE_AND_STEP();
1272 *destreg = adc_long(*destreg, srcval);
1273 }
1274 else {
1275 u16 *destreg;
1276 u16 srcval;
1277
1278 destreg = DECODE_RM_WORD_REGISTER(rh);
1279 DECODE_PRINTF(",");
1280 srcoffset = decode_rm01_address(rl);
1281 srcval = fetch_data_word(srcoffset);
1282 DECODE_PRINTF("\n");
1283 TRACE_AND_STEP();
1284 *destreg = adc_word(*destreg, srcval);
1285 }
1286 break;
1287 case 2:
1288 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1289 u32 *destreg;
1290 u32 srcval;
1291
1292 destreg = DECODE_RM_LONG_REGISTER(rh);
1293 DECODE_PRINTF(",");
1294 srcoffset = decode_rm10_address(rl);
1295 srcval = fetch_data_long(srcoffset);
1296 DECODE_PRINTF("\n");
1297 TRACE_AND_STEP();
1298 *destreg = adc_long(*destreg, srcval);
1299 }
1300 else {
1301 u16 *destreg;
1302 u16 srcval;
1303
1304 destreg = DECODE_RM_WORD_REGISTER(rh);
1305 DECODE_PRINTF(",");
1306 srcoffset = decode_rm10_address(rl);
1307 srcval = fetch_data_word(srcoffset);
1308 DECODE_PRINTF("\n");
1309 TRACE_AND_STEP();
1310 *destreg = adc_word(*destreg, srcval);
1311 }
1312 break;
1313 case 3: /* register to register */
1314 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1315 u32 *destreg, *srcreg;
1316
1317 destreg = DECODE_RM_LONG_REGISTER(rh);
1318 DECODE_PRINTF(",");
1319 srcreg = DECODE_RM_LONG_REGISTER(rl);
1320 DECODE_PRINTF("\n");
1321 TRACE_AND_STEP();
1322 *destreg = adc_long(*destreg, *srcreg);
1323 }
1324 else {
1325 u16 *destreg, *srcreg;
1326
1327 destreg = DECODE_RM_WORD_REGISTER(rh);
1328 DECODE_PRINTF(",");
1329 srcreg = DECODE_RM_WORD_REGISTER(rl);
1330 DECODE_PRINTF("\n");
1331 TRACE_AND_STEP();
1332 *destreg = adc_word(*destreg, *srcreg);
1333 }
1334 break;
1335 }
1336 DECODE_CLEAR_SEGOVR();
1337 END_OF_INSTR();
1338}
1339
1340/****************************************************************************
1341REMARKS:
1342Handles opcode 0x14
1343****************************************************************************/
1344static void
1345x86emuOp_adc_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
1346{
1347 u8 srcval;
1348
1349 START_OF_INSTR();
1350 DECODE_PRINTF("ADC\tAL,");
1351 srcval = fetch_byte_imm();
1352 DECODE_PRINTF2("%x\n", srcval);
1353 TRACE_AND_STEP();
1354 M.x86.R_AL = adc_byte(M.x86.R_AL, srcval);
1355 DECODE_CLEAR_SEGOVR();
1356 END_OF_INSTR();
1357}
1358
1359/****************************************************************************
1360REMARKS:
1361Handles opcode 0x15
1362****************************************************************************/
1363static void
1364x86emuOp_adc_word_AX_IMM(u8 X86EMU_UNUSED(op1))
1365{
1366 u32 srcval;
1367
1368 START_OF_INSTR();
1369 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1370 DECODE_PRINTF("ADC\tEAX,");
1371 srcval = fetch_long_imm();
1372 }
1373 else {
1374 DECODE_PRINTF("ADC\tAX,");
1375 srcval = fetch_word_imm();
1376 }
1377 DECODE_PRINTF2("%x\n", srcval);
1378 TRACE_AND_STEP();
1379 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1380 M.x86.R_EAX = adc_long(M.x86.R_EAX, srcval);
1381 }
1382 else {
1383 M.x86.R_AX = adc_word(M.x86.R_AX, (u16) srcval);
1384 }
1385 DECODE_CLEAR_SEGOVR();
1386 END_OF_INSTR();
1387}
1388
1389/****************************************************************************
1390REMARKS:
1391Handles opcode 0x16
1392****************************************************************************/
1393static void
1394x86emuOp_push_SS(u8 X86EMU_UNUSED(op1))
1395{
1396 START_OF_INSTR();
1397 DECODE_PRINTF("PUSH\tSS\n");
1398 TRACE_AND_STEP();
1399 push_word(M.x86.R_SS);
1400 DECODE_CLEAR_SEGOVR();
1401 END_OF_INSTR();
1402}
1403
1404/****************************************************************************
1405REMARKS:
1406Handles opcode 0x17
1407****************************************************************************/
1408static void
1409x86emuOp_pop_SS(u8 X86EMU_UNUSED(op1))
1410{
1411 START_OF_INSTR();
1412 DECODE_PRINTF("POP\tSS\n");
1413 TRACE_AND_STEP();
1414 M.x86.R_SS = pop_word();
1415 DECODE_CLEAR_SEGOVR();
1416 END_OF_INSTR();
1417}
1418
1419/****************************************************************************
1420REMARKS:
1421Handles opcode 0x18
1422****************************************************************************/
1423static void
1424x86emuOp_sbb_byte_RM_R(u8 X86EMU_UNUSED(op1))
1425{
1426 int mod, rl, rh;
1427 u8 *destreg, *srcreg;
1428 uint destoffset;
1429 u8 destval;
1430
1431 START_OF_INSTR();
1432 DECODE_PRINTF("SBB\t");
1433 FETCH_DECODE_MODRM(mod, rh, rl);
1434 switch (mod) {
1435 case 0:
1436 destoffset = decode_rm00_address(rl);
1437 DECODE_PRINTF(",");
1438 destval = fetch_data_byte(destoffset);
1439 srcreg = DECODE_RM_BYTE_REGISTER(rh);
1440 DECODE_PRINTF("\n");
1441 TRACE_AND_STEP();
1442 destval = sbb_byte(destval, *srcreg);
1443 store_data_byte(destoffset, destval);
1444 break;
1445 case 1:
1446 destoffset = decode_rm01_address(rl);
1447 DECODE_PRINTF(",");
1448 destval = fetch_data_byte(destoffset);
1449 srcreg = DECODE_RM_BYTE_REGISTER(rh);
1450 DECODE_PRINTF("\n");
1451 TRACE_AND_STEP();
1452 destval = sbb_byte(destval, *srcreg);
1453 store_data_byte(destoffset, destval);
1454 break;
1455 case 2:
1456 destoffset = decode_rm10_address(rl);
1457 DECODE_PRINTF(",");
1458 destval = fetch_data_byte(destoffset);
1459 srcreg = DECODE_RM_BYTE_REGISTER(rh);
1460 DECODE_PRINTF("\n");
1461 TRACE_AND_STEP();
1462 destval = sbb_byte(destval, *srcreg);
1463 store_data_byte(destoffset, destval);
1464 break;
1465 case 3: /* register to register */
1466 destreg = DECODE_RM_BYTE_REGISTER(rl);
1467 DECODE_PRINTF(",");
1468 srcreg = DECODE_RM_BYTE_REGISTER(rh);
1469 DECODE_PRINTF("\n");
1470 TRACE_AND_STEP();
1471 *destreg = sbb_byte(*destreg, *srcreg);
1472 break;
1473 }
1474 DECODE_CLEAR_SEGOVR();
1475 END_OF_INSTR();
1476}
1477
1478/****************************************************************************
1479REMARKS:
1480Handles opcode 0x19
1481****************************************************************************/
1482static void
1483x86emuOp_sbb_word_RM_R(u8 X86EMU_UNUSED(op1))
1484{
1485 int mod, rl, rh;
1486 uint destoffset;
1487
1488 START_OF_INSTR();
1489 DECODE_PRINTF("SBB\t");
1490 FETCH_DECODE_MODRM(mod, rh, rl);
1491 switch (mod) {
1492 case 0:
1493 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1494 u32 destval;
1495 u32 *srcreg;
1496
1497 destoffset = decode_rm00_address(rl);
1498 DECODE_PRINTF(",");
1499 destval = fetch_data_long(destoffset);
1500 srcreg = DECODE_RM_LONG_REGISTER(rh);
1501 DECODE_PRINTF("\n");
1502 TRACE_AND_STEP();
1503 destval = sbb_long(destval, *srcreg);
1504 store_data_long(destoffset, destval);
1505 }
1506 else {
1507 u16 destval;
1508 u16 *srcreg;
1509
1510 destoffset = decode_rm00_address(rl);
1511 DECODE_PRINTF(",");
1512 destval = fetch_data_word(destoffset);
1513 srcreg = DECODE_RM_WORD_REGISTER(rh);
1514 DECODE_PRINTF("\n");
1515 TRACE_AND_STEP();
1516 destval = sbb_word(destval, *srcreg);
1517 store_data_word(destoffset, destval);
1518 }
1519 break;
1520 case 1:
1521 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1522 u32 destval;
1523 u32 *srcreg;
1524
1525 destoffset = decode_rm01_address(rl);
1526 DECODE_PRINTF(",");
1527 destval = fetch_data_long(destoffset);
1528 srcreg = DECODE_RM_LONG_REGISTER(rh);
1529 DECODE_PRINTF("\n");
1530 TRACE_AND_STEP();
1531 destval = sbb_long(destval, *srcreg);
1532 store_data_long(destoffset, destval);
1533 }
1534 else {
1535 u16 destval;
1536 u16 *srcreg;
1537
1538 destoffset = decode_rm01_address(rl);
1539 DECODE_PRINTF(",");
1540 destval = fetch_data_word(destoffset);
1541 srcreg = DECODE_RM_WORD_REGISTER(rh);
1542 DECODE_PRINTF("\n");
1543 TRACE_AND_STEP();
1544 destval = sbb_word(destval, *srcreg);
1545 store_data_word(destoffset, destval);
1546 }
1547 break;
1548 case 2:
1549 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1550 u32 destval;
1551 u32 *srcreg;
1552
1553 destoffset = decode_rm10_address(rl);
1554 DECODE_PRINTF(",");
1555 destval = fetch_data_long(destoffset);
1556 srcreg = DECODE_RM_LONG_REGISTER(rh);
1557 DECODE_PRINTF("\n");
1558 TRACE_AND_STEP();
1559 destval = sbb_long(destval, *srcreg);
1560 store_data_long(destoffset, destval);
1561 }
1562 else {
1563 u16 destval;
1564 u16 *srcreg;
1565
1566 destoffset = decode_rm10_address(rl);
1567 DECODE_PRINTF(",");
1568 destval = fetch_data_word(destoffset);
1569 srcreg = DECODE_RM_WORD_REGISTER(rh);
1570 DECODE_PRINTF("\n");
1571 TRACE_AND_STEP();
1572 destval = sbb_word(destval, *srcreg);
1573 store_data_word(destoffset, destval);
1574 }
1575 break;
1576 case 3: /* register to register */
1577 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1578 u32 *destreg, *srcreg;
1579
1580 destreg = DECODE_RM_LONG_REGISTER(rl);
1581 DECODE_PRINTF(",");
1582 srcreg = DECODE_RM_LONG_REGISTER(rh);
1583 DECODE_PRINTF("\n");
1584 TRACE_AND_STEP();
1585 *destreg = sbb_long(*destreg, *srcreg);
1586 }
1587 else {
1588 u16 *destreg, *srcreg;
1589
1590 destreg = DECODE_RM_WORD_REGISTER(rl);
1591 DECODE_PRINTF(",");
1592 srcreg = DECODE_RM_WORD_REGISTER(rh);
1593 DECODE_PRINTF("\n");
1594 TRACE_AND_STEP();
1595 *destreg = sbb_word(*destreg, *srcreg);
1596 }
1597 break;
1598 }
1599 DECODE_CLEAR_SEGOVR();
1600 END_OF_INSTR();
1601}
1602
1603/****************************************************************************
1604REMARKS:
1605Handles opcode 0x1a
1606****************************************************************************/
1607static void
1608x86emuOp_sbb_byte_R_RM(u8 X86EMU_UNUSED(op1))
1609{
1610 int mod, rl, rh;
1611 u8 *destreg, *srcreg;
1612 uint srcoffset;
1613 u8 srcval;
1614
1615 START_OF_INSTR();
1616 DECODE_PRINTF("SBB\t");
1617 FETCH_DECODE_MODRM(mod, rh, rl);
1618 switch (mod) {
1619 case 0:
1620 destreg = DECODE_RM_BYTE_REGISTER(rh);
1621 DECODE_PRINTF(",");
1622 srcoffset = decode_rm00_address(rl);
1623 srcval = fetch_data_byte(srcoffset);
1624 DECODE_PRINTF("\n");
1625 TRACE_AND_STEP();
1626 *destreg = sbb_byte(*destreg, srcval);
1627 break;
1628 case 1:
1629 destreg = DECODE_RM_BYTE_REGISTER(rh);
1630 DECODE_PRINTF(",");
1631 srcoffset = decode_rm01_address(rl);
1632 srcval = fetch_data_byte(srcoffset);
1633 DECODE_PRINTF("\n");
1634 TRACE_AND_STEP();
1635 *destreg = sbb_byte(*destreg, srcval);
1636 break;
1637 case 2:
1638 destreg = DECODE_RM_BYTE_REGISTER(rh);
1639 DECODE_PRINTF(",");
1640 srcoffset = decode_rm10_address(rl);
1641 srcval = fetch_data_byte(srcoffset);
1642 DECODE_PRINTF("\n");
1643 TRACE_AND_STEP();
1644 *destreg = sbb_byte(*destreg, srcval);
1645 break;
1646 case 3: /* register to register */
1647 destreg = DECODE_RM_BYTE_REGISTER(rh);
1648 DECODE_PRINTF(",");
1649 srcreg = DECODE_RM_BYTE_REGISTER(rl);
1650 DECODE_PRINTF("\n");
1651 TRACE_AND_STEP();
1652 *destreg = sbb_byte(*destreg, *srcreg);
1653 break;
1654 }
1655 DECODE_CLEAR_SEGOVR();
1656 END_OF_INSTR();
1657}
1658
1659/****************************************************************************
1660REMARKS:
1661Handles opcode 0x1b
1662****************************************************************************/
1663static void
1664x86emuOp_sbb_word_R_RM(u8 X86EMU_UNUSED(op1))
1665{
1666 int mod, rl, rh;
1667 uint srcoffset;
1668
1669 START_OF_INSTR();
1670 DECODE_PRINTF("SBB\t");
1671 FETCH_DECODE_MODRM(mod, rh, rl);
1672 switch (mod) {
1673 case 0:
1674 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1675 u32 *destreg;
1676 u32 srcval;
1677
1678 destreg = DECODE_RM_LONG_REGISTER(rh);
1679 DECODE_PRINTF(",");
1680 srcoffset = decode_rm00_address(rl);
1681 srcval = fetch_data_long(srcoffset);
1682 DECODE_PRINTF("\n");
1683 TRACE_AND_STEP();
1684 *destreg = sbb_long(*destreg, srcval);
1685 }
1686 else {
1687 u16 *destreg;
1688 u16 srcval;
1689
1690 destreg = DECODE_RM_WORD_REGISTER(rh);
1691 DECODE_PRINTF(",");
1692 srcoffset = decode_rm00_address(rl);
1693 srcval = fetch_data_word(srcoffset);
1694 DECODE_PRINTF("\n");
1695 TRACE_AND_STEP();
1696 *destreg = sbb_word(*destreg, srcval);
1697 }
1698 break;
1699 case 1:
1700 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1701 u32 *destreg;
1702 u32 srcval;
1703
1704 destreg = DECODE_RM_LONG_REGISTER(rh);
1705 DECODE_PRINTF(",");
1706 srcoffset = decode_rm01_address(rl);
1707 srcval = fetch_data_long(srcoffset);
1708 DECODE_PRINTF("\n");
1709 TRACE_AND_STEP();
1710 *destreg = sbb_long(*destreg, srcval);
1711 }
1712 else {
1713 u16 *destreg;
1714 u16 srcval;
1715
1716 destreg = DECODE_RM_WORD_REGISTER(rh);
1717 DECODE_PRINTF(",");
1718 srcoffset = decode_rm01_address(rl);
1719 srcval = fetch_data_word(srcoffset);
1720 DECODE_PRINTF("\n");
1721 TRACE_AND_STEP();
1722 *destreg = sbb_word(*destreg, srcval);
1723 }
1724 break;
1725 case 2:
1726 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1727 u32 *destreg;
1728 u32 srcval;
1729
1730 destreg = DECODE_RM_LONG_REGISTER(rh);
1731 DECODE_PRINTF(",");
1732 srcoffset = decode_rm10_address(rl);
1733 srcval = fetch_data_long(srcoffset);
1734 DECODE_PRINTF("\n");
1735 TRACE_AND_STEP();
1736 *destreg = sbb_long(*destreg, srcval);
1737 }
1738 else {
1739 u16 *destreg;
1740 u16 srcval;
1741
1742 destreg = DECODE_RM_WORD_REGISTER(rh);
1743 DECODE_PRINTF(",");
1744 srcoffset = decode_rm10_address(rl);
1745 srcval = fetch_data_word(srcoffset);
1746 DECODE_PRINTF("\n");
1747 TRACE_AND_STEP();
1748 *destreg = sbb_word(*destreg, srcval);
1749 }
1750 break;
1751 case 3: /* register to register */
1752 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1753 u32 *destreg, *srcreg;
1754
1755 destreg = DECODE_RM_LONG_REGISTER(rh);
1756 DECODE_PRINTF(",");
1757 srcreg = DECODE_RM_LONG_REGISTER(rl);
1758 DECODE_PRINTF("\n");
1759 TRACE_AND_STEP();
1760 *destreg = sbb_long(*destreg, *srcreg);
1761 }
1762 else {
1763 u16 *destreg, *srcreg;
1764
1765 destreg = DECODE_RM_WORD_REGISTER(rh);
1766 DECODE_PRINTF(",");
1767 srcreg = DECODE_RM_WORD_REGISTER(rl);
1768 DECODE_PRINTF("\n");
1769 TRACE_AND_STEP();
1770 *destreg = sbb_word(*destreg, *srcreg);
1771 }
1772 break;
1773 }
1774 DECODE_CLEAR_SEGOVR();
1775 END_OF_INSTR();
1776}
1777
1778/****************************************************************************
1779REMARKS:
1780Handles opcode 0x1c
1781****************************************************************************/
1782static void
1783x86emuOp_sbb_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
1784{
1785 u8 srcval;
1786
1787 START_OF_INSTR();
1788 DECODE_PRINTF("SBB\tAL,");
1789 srcval = fetch_byte_imm();
1790 DECODE_PRINTF2("%x\n", srcval);
1791 TRACE_AND_STEP();
1792 M.x86.R_AL = sbb_byte(M.x86.R_AL, srcval);
1793 DECODE_CLEAR_SEGOVR();
1794 END_OF_INSTR();
1795}
1796
1797/****************************************************************************
1798REMARKS:
1799Handles opcode 0x1d
1800****************************************************************************/
1801static void
1802x86emuOp_sbb_word_AX_IMM(u8 X86EMU_UNUSED(op1))
1803{
1804 u32 srcval;
1805
1806 START_OF_INSTR();
1807 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1808 DECODE_PRINTF("SBB\tEAX,");
1809 srcval = fetch_long_imm();
1810 }
1811 else {
1812 DECODE_PRINTF("SBB\tAX,");
1813 srcval = fetch_word_imm();
1814 }
1815 DECODE_PRINTF2("%x\n", srcval);
1816 TRACE_AND_STEP();
1817 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1818 M.x86.R_EAX = sbb_long(M.x86.R_EAX, srcval);
1819 }
1820 else {
1821 M.x86.R_AX = sbb_word(M.x86.R_AX, (u16) srcval);
1822 }
1823 DECODE_CLEAR_SEGOVR();
1824 END_OF_INSTR();
1825}
1826
1827/****************************************************************************
1828REMARKS:
1829Handles opcode 0x1e
1830****************************************************************************/
1831static void
1832x86emuOp_push_DS(u8 X86EMU_UNUSED(op1))
1833{
1834 START_OF_INSTR();
1835 DECODE_PRINTF("PUSH\tDS\n");
1836 TRACE_AND_STEP();
1837 push_word(M.x86.R_DS);
1838 DECODE_CLEAR_SEGOVR();
1839 END_OF_INSTR();
1840}
1841
1842/****************************************************************************
1843REMARKS:
1844Handles opcode 0x1f
1845****************************************************************************/
1846static void
1847x86emuOp_pop_DS(u8 X86EMU_UNUSED(op1))
1848{
1849 START_OF_INSTR();
1850 DECODE_PRINTF("POP\tDS\n");
1851 TRACE_AND_STEP();
1852 M.x86.R_DS = pop_word();
1853 DECODE_CLEAR_SEGOVR();
1854 END_OF_INSTR();
1855}
1856
1857/****************************************************************************
1858REMARKS:
1859Handles opcode 0x20
1860****************************************************************************/
1861static void
1862x86emuOp_and_byte_RM_R(u8 X86EMU_UNUSED(op1))
1863{
1864 int mod, rl, rh;
1865 u8 *destreg, *srcreg;
1866 uint destoffset;
1867 u8 destval;
1868
1869 START_OF_INSTR();
1870 DECODE_PRINTF("AND\t");
1871 FETCH_DECODE_MODRM(mod, rh, rl);
1872
1873 switch (mod) {
1874 case 0:
1875 destoffset = decode_rm00_address(rl);
1876 DECODE_PRINTF(",");
1877 destval = fetch_data_byte(destoffset);
1878 srcreg = DECODE_RM_BYTE_REGISTER(rh);
1879 DECODE_PRINTF("\n");
1880 TRACE_AND_STEP();
1881 destval = and_byte(destval, *srcreg);
1882 store_data_byte(destoffset, destval);
1883 break;
1884
1885 case 1:
1886 destoffset = decode_rm01_address(rl);
1887 DECODE_PRINTF(",");
1888 destval = fetch_data_byte(destoffset);
1889 srcreg = DECODE_RM_BYTE_REGISTER(rh);
1890 DECODE_PRINTF("\n");
1891 TRACE_AND_STEP();
1892 destval = and_byte(destval, *srcreg);
1893 store_data_byte(destoffset, destval);
1894 break;
1895
1896 case 2:
1897 destoffset = decode_rm10_address(rl);
1898 DECODE_PRINTF(",");
1899 destval = fetch_data_byte(destoffset);
1900 srcreg = DECODE_RM_BYTE_REGISTER(rh);
1901 DECODE_PRINTF("\n");
1902 TRACE_AND_STEP();
1903 destval = and_byte(destval, *srcreg);
1904 store_data_byte(destoffset, destval);
1905 break;
1906
1907 case 3: /* register to register */
1908 destreg = DECODE_RM_BYTE_REGISTER(rl);
1909 DECODE_PRINTF(",");
1910 srcreg = DECODE_RM_BYTE_REGISTER(rh);
1911 DECODE_PRINTF("\n");
1912 TRACE_AND_STEP();
1913 *destreg = and_byte(*destreg, *srcreg);
1914 break;
1915 }
1916 DECODE_CLEAR_SEGOVR();
1917 END_OF_INSTR();
1918}
1919
1920/****************************************************************************
1921REMARKS:
1922Handles opcode 0x21
1923****************************************************************************/
1924static void
1925x86emuOp_and_word_RM_R(u8 X86EMU_UNUSED(op1))
1926{
1927 int mod, rl, rh;
1928 uint destoffset;
1929
1930 START_OF_INSTR();
1931 DECODE_PRINTF("AND\t");
1932 FETCH_DECODE_MODRM(mod, rh, rl);
1933 switch (mod) {
1934 case 0:
1935 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1936 u32 destval;
1937 u32 *srcreg;
1938
1939 destoffset = decode_rm00_address(rl);
1940 DECODE_PRINTF(",");
1941 destval = fetch_data_long(destoffset);
1942 srcreg = DECODE_RM_LONG_REGISTER(rh);
1943 DECODE_PRINTF("\n");
1944 TRACE_AND_STEP();
1945 destval = and_long(destval, *srcreg);
1946 store_data_long(destoffset, destval);
1947 }
1948 else {
1949 u16 destval;
1950 u16 *srcreg;
1951
1952 destoffset = decode_rm00_address(rl);
1953 DECODE_PRINTF(",");
1954 destval = fetch_data_word(destoffset);
1955 srcreg = DECODE_RM_WORD_REGISTER(rh);
1956 DECODE_PRINTF("\n");
1957 TRACE_AND_STEP();
1958 destval = and_word(destval, *srcreg);
1959 store_data_word(destoffset, destval);
1960 }
1961 break;
1962 case 1:
1963 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1964 u32 destval;
1965 u32 *srcreg;
1966
1967 destoffset = decode_rm01_address(rl);
1968 DECODE_PRINTF(",");
1969 destval = fetch_data_long(destoffset);
1970 srcreg = DECODE_RM_LONG_REGISTER(rh);
1971 DECODE_PRINTF("\n");
1972 TRACE_AND_STEP();
1973 destval = and_long(destval, *srcreg);
1974 store_data_long(destoffset, destval);
1975 }
1976 else {
1977 u16 destval;
1978 u16 *srcreg;
1979
1980 destoffset = decode_rm01_address(rl);
1981 DECODE_PRINTF(",");
1982 destval = fetch_data_word(destoffset);
1983 srcreg = DECODE_RM_WORD_REGISTER(rh);
1984 DECODE_PRINTF("\n");
1985 TRACE_AND_STEP();
1986 destval = and_word(destval, *srcreg);
1987 store_data_word(destoffset, destval);
1988 }
1989 break;
1990 case 2:
1991 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1992 u32 destval;
1993 u32 *srcreg;
1994
1995 destoffset = decode_rm10_address(rl);
1996 DECODE_PRINTF(",");
1997 destval = fetch_data_long(destoffset);
1998 srcreg = DECODE_RM_LONG_REGISTER(rh);
1999 DECODE_PRINTF("\n");
2000 TRACE_AND_STEP();
2001 destval = and_long(destval, *srcreg);
2002 store_data_long(destoffset, destval);
2003 }
2004 else {
2005 u16 destval;
2006 u16 *srcreg;
2007
2008 destoffset = decode_rm10_address(rl);
2009 DECODE_PRINTF(",");
2010 destval = fetch_data_word(destoffset);
2011 srcreg = DECODE_RM_WORD_REGISTER(rh);
2012 DECODE_PRINTF("\n");
2013 TRACE_AND_STEP();
2014 destval = and_word(destval, *srcreg);
2015 store_data_word(destoffset, destval);
2016 }
2017 break;
2018 case 3: /* register to register */
2019 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2020 u32 *destreg, *srcreg;
2021
2022 destreg = DECODE_RM_LONG_REGISTER(rl);
2023 DECODE_PRINTF(",");
2024 srcreg = DECODE_RM_LONG_REGISTER(rh);
2025 DECODE_PRINTF("\n");
2026 TRACE_AND_STEP();
2027 *destreg = and_long(*destreg, *srcreg);
2028 }
2029 else {
2030 u16 *destreg, *srcreg;
2031
2032 destreg = DECODE_RM_WORD_REGISTER(rl);
2033 DECODE_PRINTF(",");
2034 srcreg = DECODE_RM_WORD_REGISTER(rh);
2035 DECODE_PRINTF("\n");
2036 TRACE_AND_STEP();
2037 *destreg = and_word(*destreg, *srcreg);
2038 }
2039 break;
2040 }
2041 DECODE_CLEAR_SEGOVR();
2042 END_OF_INSTR();
2043}
2044
2045/****************************************************************************
2046REMARKS:
2047Handles opcode 0x22
2048****************************************************************************/
2049static void
2050x86emuOp_and_byte_R_RM(u8 X86EMU_UNUSED(op1))
2051{
2052 int mod, rl, rh;
2053 u8 *destreg, *srcreg;
2054 uint srcoffset;
2055 u8 srcval;
2056
2057 START_OF_INSTR();
2058 DECODE_PRINTF("AND\t");
2059 FETCH_DECODE_MODRM(mod, rh, rl);
2060 switch (mod) {
2061 case 0:
2062 destreg = DECODE_RM_BYTE_REGISTER(rh);
2063 DECODE_PRINTF(",");
2064 srcoffset = decode_rm00_address(rl);
2065 srcval = fetch_data_byte(srcoffset);
2066 DECODE_PRINTF("\n");
2067 TRACE_AND_STEP();
2068 *destreg = and_byte(*destreg, srcval);
2069 break;
2070 case 1:
2071 destreg = DECODE_RM_BYTE_REGISTER(rh);
2072 DECODE_PRINTF(",");
2073 srcoffset = decode_rm01_address(rl);
2074 srcval = fetch_data_byte(srcoffset);
2075 DECODE_PRINTF("\n");
2076 TRACE_AND_STEP();
2077 *destreg = and_byte(*destreg, srcval);
2078 break;
2079 case 2:
2080 destreg = DECODE_RM_BYTE_REGISTER(rh);
2081 DECODE_PRINTF(",");
2082 srcoffset = decode_rm10_address(rl);
2083 srcval = fetch_data_byte(srcoffset);
2084 DECODE_PRINTF("\n");
2085 TRACE_AND_STEP();
2086 *destreg = and_byte(*destreg, srcval);
2087 break;
2088 case 3: /* register to register */
2089 destreg = DECODE_RM_BYTE_REGISTER(rh);
2090 DECODE_PRINTF(",");
2091 srcreg = DECODE_RM_BYTE_REGISTER(rl);
2092 DECODE_PRINTF("\n");
2093 TRACE_AND_STEP();
2094 *destreg = and_byte(*destreg, *srcreg);
2095 break;
2096 }
2097 DECODE_CLEAR_SEGOVR();
2098 END_OF_INSTR();
2099}
2100
2101/****************************************************************************
2102REMARKS:
2103Handles opcode 0x23
2104****************************************************************************/
2105static void
2106x86emuOp_and_word_R_RM(u8 X86EMU_UNUSED(op1))
2107{
2108 int mod, rl, rh;
2109 uint srcoffset;
2110
2111 START_OF_INSTR();
2112 DECODE_PRINTF("AND\t");
2113 FETCH_DECODE_MODRM(mod, rh, rl);
2114 switch (mod) {
2115 case 0:
2116 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2117 u32 *destreg;
2118 u32 srcval;
2119
2120 destreg = DECODE_RM_LONG_REGISTER(rh);
2121 DECODE_PRINTF(",");
2122 srcoffset = decode_rm00_address(rl);
2123 srcval = fetch_data_long(srcoffset);
2124 DECODE_PRINTF("\n");
2125 TRACE_AND_STEP();
2126 *destreg = and_long(*destreg, srcval);
2127 }
2128 else {
2129 u16 *destreg;
2130 u16 srcval;
2131
2132 destreg = DECODE_RM_WORD_REGISTER(rh);
2133 DECODE_PRINTF(",");
2134 srcoffset = decode_rm00_address(rl);
2135 srcval = fetch_data_word(srcoffset);
2136 DECODE_PRINTF("\n");
2137 TRACE_AND_STEP();
2138 *destreg = and_word(*destreg, srcval);
2139 }
2140 break;
2141 case 1:
2142 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2143 u32 *destreg;
2144 u32 srcval;
2145
2146 destreg = DECODE_RM_LONG_REGISTER(rh);
2147 DECODE_PRINTF(",");
2148 srcoffset = decode_rm01_address(rl);
2149 srcval = fetch_data_long(srcoffset);
2150 DECODE_PRINTF("\n");
2151 TRACE_AND_STEP();
2152 *destreg = and_long(*destreg, srcval);
2153 break;
2154 }
2155 else {
2156 u16 *destreg;
2157 u16 srcval;
2158
2159 destreg = DECODE_RM_WORD_REGISTER(rh);
2160 DECODE_PRINTF(",");
2161 srcoffset = decode_rm01_address(rl);
2162 srcval = fetch_data_word(srcoffset);
2163 DECODE_PRINTF("\n");
2164 TRACE_AND_STEP();
2165 *destreg = and_word(*destreg, srcval);
2166 break;
2167 }
2168 case 2:
2169 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2170 u32 *destreg;
2171 u32 srcval;
2172
2173 destreg = DECODE_RM_LONG_REGISTER(rh);
2174 DECODE_PRINTF(",");
2175 srcoffset = decode_rm10_address(rl);
2176 srcval = fetch_data_long(srcoffset);
2177 DECODE_PRINTF("\n");
2178 TRACE_AND_STEP();
2179 *destreg = and_long(*destreg, srcval);
2180 }
2181 else {
2182 u16 *destreg;
2183 u16 srcval;
2184
2185 destreg = DECODE_RM_WORD_REGISTER(rh);
2186 DECODE_PRINTF(",");
2187 srcoffset = decode_rm10_address(rl);
2188 srcval = fetch_data_word(srcoffset);
2189 DECODE_PRINTF("\n");
2190 TRACE_AND_STEP();
2191 *destreg = and_word(*destreg, srcval);
2192 }
2193 break;
2194 case 3: /* register to register */
2195 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2196 u32 *destreg, *srcreg;
2197
2198 destreg = DECODE_RM_LONG_REGISTER(rh);
2199 DECODE_PRINTF(",");
2200 srcreg = DECODE_RM_LONG_REGISTER(rl);
2201 DECODE_PRINTF("\n");
2202 TRACE_AND_STEP();
2203 *destreg = and_long(*destreg, *srcreg);
2204 }
2205 else {
2206 u16 *destreg, *srcreg;
2207
2208 destreg = DECODE_RM_WORD_REGISTER(rh);
2209 DECODE_PRINTF(",");
2210 srcreg = DECODE_RM_WORD_REGISTER(rl);
2211 DECODE_PRINTF("\n");
2212 TRACE_AND_STEP();
2213 *destreg = and_word(*destreg, *srcreg);
2214 }
2215 break;
2216 }
2217 DECODE_CLEAR_SEGOVR();
2218 END_OF_INSTR();
2219}
2220
2221/****************************************************************************
2222REMARKS:
2223Handles opcode 0x24
2224****************************************************************************/
2225static void
2226x86emuOp_and_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
2227{
2228 u8 srcval;
2229
2230 START_OF_INSTR();
2231 DECODE_PRINTF("AND\tAL,");
2232 srcval = fetch_byte_imm();
2233 DECODE_PRINTF2("%x\n", srcval);
2234 TRACE_AND_STEP();
2235 M.x86.R_AL = and_byte(M.x86.R_AL, srcval);
2236 DECODE_CLEAR_SEGOVR();
2237 END_OF_INSTR();
2238}
2239
2240/****************************************************************************
2241REMARKS:
2242Handles opcode 0x25
2243****************************************************************************/
2244static void
2245x86emuOp_and_word_AX_IMM(u8 X86EMU_UNUSED(op1))
2246{
2247 u32 srcval;
2248
2249 START_OF_INSTR();
2250 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2251 DECODE_PRINTF("AND\tEAX,");
2252 srcval = fetch_long_imm();
2253 }
2254 else {
2255 DECODE_PRINTF("AND\tAX,");
2256 srcval = fetch_word_imm();
2257 }
2258 DECODE_PRINTF2("%x\n", srcval);
2259 TRACE_AND_STEP();
2260 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2261 M.x86.R_EAX = and_long(M.x86.R_EAX, srcval);
2262 }
2263 else {
2264 M.x86.R_AX = and_word(M.x86.R_AX, (u16) srcval);
2265 }
2266 DECODE_CLEAR_SEGOVR();
2267 END_OF_INSTR();
2268}
2269
2270/****************************************************************************
2271REMARKS:
2272Handles opcode 0x26
2273****************************************************************************/
2274static void
2275x86emuOp_segovr_ES(u8 X86EMU_UNUSED(op1))
2276{
2277 START_OF_INSTR();
2278 DECODE_PRINTF("ES:\n");
2279 TRACE_AND_STEP();
2280 M.x86.mode |= SYSMODE_SEGOVR_ES;
2281 /*
2282 * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
2283 * opcode subroutines we do not want to do this.
2284 */
2285 END_OF_INSTR();
2286}
2287
2288/****************************************************************************
2289REMARKS:
2290Handles opcode 0x27
2291****************************************************************************/
2292static void
2293x86emuOp_daa(u8 X86EMU_UNUSED(op1))
2294{
2295 START_OF_INSTR();
2296 DECODE_PRINTF("DAA\n");
2297 TRACE_AND_STEP();
2298 M.x86.R_AL = daa_byte(M.x86.R_AL);
2299 DECODE_CLEAR_SEGOVR();
2300 END_OF_INSTR();
2301}
2302
2303/****************************************************************************
2304REMARKS:
2305Handles opcode 0x28
2306****************************************************************************/
2307static void
2308x86emuOp_sub_byte_RM_R(u8 X86EMU_UNUSED(op1))
2309{
2310 int mod, rl, rh;
2311 u8 *destreg, *srcreg;
2312 uint destoffset;
2313 u8 destval;
2314
2315 START_OF_INSTR();
2316 DECODE_PRINTF("SUB\t");
2317 FETCH_DECODE_MODRM(mod, rh, rl);
2318 switch (mod) {
2319 case 0:
2320 destoffset = decode_rm00_address(rl);
2321 DECODE_PRINTF(",");
2322 destval = fetch_data_byte(destoffset);
2323 srcreg = DECODE_RM_BYTE_REGISTER(rh);
2324 DECODE_PRINTF("\n");
2325 TRACE_AND_STEP();
2326 destval = sub_byte(destval, *srcreg);
2327 store_data_byte(destoffset, destval);
2328 break;
2329 case 1:
2330 destoffset = decode_rm01_address(rl);
2331 DECODE_PRINTF(",");
2332 destval = fetch_data_byte(destoffset);
2333 srcreg = DECODE_RM_BYTE_REGISTER(rh);
2334 DECODE_PRINTF("\n");
2335 TRACE_AND_STEP();
2336 destval = sub_byte(destval, *srcreg);
2337 store_data_byte(destoffset, destval);
2338 break;
2339 case 2:
2340 destoffset = decode_rm10_address(rl);
2341 DECODE_PRINTF(",");
2342 destval = fetch_data_byte(destoffset);
2343 srcreg = DECODE_RM_BYTE_REGISTER(rh);
2344 DECODE_PRINTF("\n");
2345 TRACE_AND_STEP();
2346 destval = sub_byte(destval, *srcreg);
2347 store_data_byte(destoffset, destval);
2348 break;
2349 case 3: /* register to register */
2350 destreg = DECODE_RM_BYTE_REGISTER(rl);
2351 DECODE_PRINTF(",");
2352 srcreg = DECODE_RM_BYTE_REGISTER(rh);
2353 DECODE_PRINTF("\n");
2354 TRACE_AND_STEP();
2355 *destreg = sub_byte(*destreg, *srcreg);
2356 break;
2357 }
2358 DECODE_CLEAR_SEGOVR();
2359 END_OF_INSTR();
2360}
2361
2362/****************************************************************************
2363REMARKS:
2364Handles opcode 0x29
2365****************************************************************************/
2366static void
2367x86emuOp_sub_word_RM_R(u8 X86EMU_UNUSED(op1))
2368{
2369 int mod, rl, rh;
2370 uint destoffset;
2371
2372 START_OF_INSTR();
2373 DECODE_PRINTF("SUB\t");
2374 FETCH_DECODE_MODRM(mod, rh, rl);
2375 switch (mod) {
2376 case 0:
2377 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2378 u32 destval;
2379 u32 *srcreg;
2380
2381 destoffset = decode_rm00_address(rl);
2382 DECODE_PRINTF(",");
2383 destval = fetch_data_long(destoffset);
2384 srcreg = DECODE_RM_LONG_REGISTER(rh);
2385 DECODE_PRINTF("\n");
2386 TRACE_AND_STEP();
2387 destval = sub_long(destval, *srcreg);
2388 store_data_long(destoffset, destval);
2389 }
2390 else {
2391 u16 destval;
2392 u16 *srcreg;
2393
2394 destoffset = decode_rm00_address(rl);
2395 DECODE_PRINTF(",");
2396 destval = fetch_data_word(destoffset);
2397 srcreg = DECODE_RM_WORD_REGISTER(rh);
2398 DECODE_PRINTF("\n");
2399 TRACE_AND_STEP();
2400 destval = sub_word(destval, *srcreg);
2401 store_data_word(destoffset, destval);
2402 }
2403 break;
2404 case 1:
2405 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2406 u32 destval;
2407 u32 *srcreg;
2408
2409 destoffset = decode_rm01_address(rl);
2410 DECODE_PRINTF(",");
2411 destval = fetch_data_long(destoffset);
2412 srcreg = DECODE_RM_LONG_REGISTER(rh);
2413 DECODE_PRINTF("\n");
2414 TRACE_AND_STEP();
2415 destval = sub_long(destval, *srcreg);
2416 store_data_long(destoffset, destval);
2417 }
2418 else {
2419 u16 destval;
2420 u16 *srcreg;
2421
2422 destoffset = decode_rm01_address(rl);
2423 DECODE_PRINTF(",");
2424 destval = fetch_data_word(destoffset);
2425 srcreg = DECODE_RM_WORD_REGISTER(rh);
2426 DECODE_PRINTF("\n");
2427 TRACE_AND_STEP();
2428 destval = sub_word(destval, *srcreg);
2429 store_data_word(destoffset, destval);
2430 }
2431 break;
2432 case 2:
2433 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2434 u32 destval;
2435 u32 *srcreg;
2436
2437 destoffset = decode_rm10_address(rl);
2438 DECODE_PRINTF(",");
2439 destval = fetch_data_long(destoffset);
2440 srcreg = DECODE_RM_LONG_REGISTER(rh);
2441 DECODE_PRINTF("\n");
2442 TRACE_AND_STEP();
2443 destval = sub_long(destval, *srcreg);
2444 store_data_long(destoffset, destval);
2445 }
2446 else {
2447 u16 destval;
2448 u16 *srcreg;
2449
2450 destoffset = decode_rm10_address(rl);
2451 DECODE_PRINTF(",");
2452 destval = fetch_data_word(destoffset);
2453 srcreg = DECODE_RM_WORD_REGISTER(rh);
2454 DECODE_PRINTF("\n");
2455 TRACE_AND_STEP();
2456 destval = sub_word(destval, *srcreg);
2457 store_data_word(destoffset, destval);
2458 }
2459 break;
2460 case 3: /* register to register */
2461 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2462 u32 *destreg, *srcreg;
2463
2464 destreg = DECODE_RM_LONG_REGISTER(rl);
2465 DECODE_PRINTF(",");
2466 srcreg = DECODE_RM_LONG_REGISTER(rh);
2467 DECODE_PRINTF("\n");
2468 TRACE_AND_STEP();
2469 *destreg = sub_long(*destreg, *srcreg);
2470 }
2471 else {
2472 u16 *destreg, *srcreg;
2473
2474 destreg = DECODE_RM_WORD_REGISTER(rl);
2475 DECODE_PRINTF(",");
2476 srcreg = DECODE_RM_WORD_REGISTER(rh);
2477 DECODE_PRINTF("\n");
2478 TRACE_AND_STEP();
2479 *destreg = sub_word(*destreg, *srcreg);
2480 }
2481 break;
2482 }
2483 DECODE_CLEAR_SEGOVR();
2484 END_OF_INSTR();
2485}
2486
2487/****************************************************************************
2488REMARKS:
2489Handles opcode 0x2a
2490****************************************************************************/
2491static void
2492x86emuOp_sub_byte_R_RM(u8 X86EMU_UNUSED(op1))
2493{
2494 int mod, rl, rh;
2495 u8 *destreg, *srcreg;
2496 uint srcoffset;
2497 u8 srcval;
2498
2499 START_OF_INSTR();
2500 DECODE_PRINTF("SUB\t");
2501 FETCH_DECODE_MODRM(mod, rh, rl);
2502 switch (mod) {
2503 case 0:
2504 destreg = DECODE_RM_BYTE_REGISTER(rh);
2505 DECODE_PRINTF(",");
2506 srcoffset = decode_rm00_address(rl);
2507 srcval = fetch_data_byte(srcoffset);
2508 DECODE_PRINTF("\n");
2509 TRACE_AND_STEP();
2510 *destreg = sub_byte(*destreg, srcval);
2511 break;
2512 case 1:
2513 destreg = DECODE_RM_BYTE_REGISTER(rh);
2514 DECODE_PRINTF(",");
2515 srcoffset = decode_rm01_address(rl);
2516 srcval = fetch_data_byte(srcoffset);
2517 DECODE_PRINTF("\n");
2518 TRACE_AND_STEP();
2519 *destreg = sub_byte(*destreg, srcval);
2520 break;
2521 case 2:
2522 destreg = DECODE_RM_BYTE_REGISTER(rh);
2523 DECODE_PRINTF(",");
2524 srcoffset = decode_rm10_address(rl);
2525 srcval = fetch_data_byte(srcoffset);
2526 DECODE_PRINTF("\n");
2527 TRACE_AND_STEP();
2528 *destreg = sub_byte(*destreg, srcval);
2529 break;
2530 case 3: /* register to register */
2531 destreg = DECODE_RM_BYTE_REGISTER(rh);
2532 DECODE_PRINTF(",");
2533 srcreg = DECODE_RM_BYTE_REGISTER(rl);
2534 DECODE_PRINTF("\n");
2535 TRACE_AND_STEP();
2536 *destreg = sub_byte(*destreg, *srcreg);
2537 break;
2538 }
2539 DECODE_CLEAR_SEGOVR();
2540 END_OF_INSTR();
2541}
2542
2543/****************************************************************************
2544REMARKS:
2545Handles opcode 0x2b
2546****************************************************************************/
2547static void
2548x86emuOp_sub_word_R_RM(u8 X86EMU_UNUSED(op1))
2549{
2550 int mod, rl, rh;
2551 uint srcoffset;
2552
2553 START_OF_INSTR();
2554 DECODE_PRINTF("SUB\t");
2555 FETCH_DECODE_MODRM(mod, rh, rl);
2556 switch (mod) {
2557 case 0:
2558 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2559 u32 *destreg;
2560 u32 srcval;
2561
2562 destreg = DECODE_RM_LONG_REGISTER(rh);
2563 DECODE_PRINTF(",");
2564 srcoffset = decode_rm00_address(rl);
2565 srcval = fetch_data_long(srcoffset);
2566 DECODE_PRINTF("\n");
2567 TRACE_AND_STEP();
2568 *destreg = sub_long(*destreg, srcval);
2569 }
2570 else {
2571 u16 *destreg;
2572 u16 srcval;
2573
2574 destreg = DECODE_RM_WORD_REGISTER(rh);
2575 DECODE_PRINTF(",");
2576 srcoffset = decode_rm00_address(rl);
2577 srcval = fetch_data_word(srcoffset);
2578 DECODE_PRINTF("\n");
2579 TRACE_AND_STEP();
2580 *destreg = sub_word(*destreg, srcval);
2581 }
2582 break;
2583 case 1:
2584 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2585 u32 *destreg;
2586 u32 srcval;
2587
2588 destreg = DECODE_RM_LONG_REGISTER(rh);
2589 DECODE_PRINTF(",");
2590 srcoffset = decode_rm01_address(rl);
2591 srcval = fetch_data_long(srcoffset);
2592 DECODE_PRINTF("\n");
2593 TRACE_AND_STEP();
2594 *destreg = sub_long(*destreg, srcval);
2595 }
2596 else {
2597 u16 *destreg;
2598 u16 srcval;
2599
2600 destreg = DECODE_RM_WORD_REGISTER(rh);
2601 DECODE_PRINTF(",");
2602 srcoffset = decode_rm01_address(rl);
2603 srcval = fetch_data_word(srcoffset);
2604 DECODE_PRINTF("\n");
2605 TRACE_AND_STEP();
2606 *destreg = sub_word(*destreg, srcval);
2607 }
2608 break;
2609 case 2:
2610 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2611 u32 *destreg;
2612 u32 srcval;
2613
2614 destreg = DECODE_RM_LONG_REGISTER(rh);
2615 DECODE_PRINTF(",");
2616 srcoffset = decode_rm10_address(rl);
2617 srcval = fetch_data_long(srcoffset);
2618 DECODE_PRINTF("\n");
2619 TRACE_AND_STEP();
2620 *destreg = sub_long(*destreg, srcval);
2621 }
2622 else {
2623 u16 *destreg;
2624 u16 srcval;
2625
2626 destreg = DECODE_RM_WORD_REGISTER(rh);
2627 DECODE_PRINTF(",");
2628 srcoffset = decode_rm10_address(rl);
2629 srcval = fetch_data_word(srcoffset);
2630 DECODE_PRINTF("\n");
2631 TRACE_AND_STEP();
2632 *destreg = sub_word(*destreg, srcval);
2633 }
2634 break;
2635 case 3: /* register to register */
2636 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2637 u32 *destreg, *srcreg;
2638
2639 destreg = DECODE_RM_LONG_REGISTER(rh);
2640 DECODE_PRINTF(",");
2641 srcreg = DECODE_RM_LONG_REGISTER(rl);
2642 DECODE_PRINTF("\n");
2643 TRACE_AND_STEP();
2644 *destreg = sub_long(*destreg, *srcreg);
2645 }
2646 else {
2647 u16 *destreg, *srcreg;
2648
2649 destreg = DECODE_RM_WORD_REGISTER(rh);
2650 DECODE_PRINTF(",");
2651 srcreg = DECODE_RM_WORD_REGISTER(rl);
2652 DECODE_PRINTF("\n");
2653 TRACE_AND_STEP();
2654 *destreg = sub_word(*destreg, *srcreg);
2655 }
2656 break;
2657 }
2658 DECODE_CLEAR_SEGOVR();
2659 END_OF_INSTR();
2660}
2661
2662/****************************************************************************
2663REMARKS:
2664Handles opcode 0x2c
2665****************************************************************************/
2666static void
2667x86emuOp_sub_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
2668{
2669 u8 srcval;
2670
2671 START_OF_INSTR();
2672 DECODE_PRINTF("SUB\tAL,");
2673 srcval = fetch_byte_imm();
2674 DECODE_PRINTF2("%x\n", srcval);
2675 TRACE_AND_STEP();
2676 M.x86.R_AL = sub_byte(M.x86.R_AL, srcval);
2677 DECODE_CLEAR_SEGOVR();
2678 END_OF_INSTR();
2679}
2680
2681/****************************************************************************
2682REMARKS:
2683Handles opcode 0x2d
2684****************************************************************************/
2685static void
2686x86emuOp_sub_word_AX_IMM(u8 X86EMU_UNUSED(op1))
2687{
2688 u32 srcval;
2689
2690 START_OF_INSTR();
2691 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2692 DECODE_PRINTF("SUB\tEAX,");
2693 srcval = fetch_long_imm();
2694 }
2695 else {
2696 DECODE_PRINTF("SUB\tAX,");
2697 srcval = fetch_word_imm();
2698 }
2699 DECODE_PRINTF2("%x\n", srcval);
2700 TRACE_AND_STEP();
2701 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2702 M.x86.R_EAX = sub_long(M.x86.R_EAX, srcval);
2703 }
2704 else {
2705 M.x86.R_AX = sub_word(M.x86.R_AX, (u16) srcval);
2706 }
2707 DECODE_CLEAR_SEGOVR();
2708 END_OF_INSTR();
2709}
2710
2711/****************************************************************************
2712REMARKS:
2713Handles opcode 0x2e
2714****************************************************************************/
2715static void
2716x86emuOp_segovr_CS(u8 X86EMU_UNUSED(op1))
2717{
2718 START_OF_INSTR();
2719 DECODE_PRINTF("CS:\n");
2720 TRACE_AND_STEP();
2721 M.x86.mode |= SYSMODE_SEGOVR_CS;
2722 /* note no DECODE_CLEAR_SEGOVR here. */
2723 END_OF_INSTR();
2724}
2725
2726/****************************************************************************
2727REMARKS:
2728Handles opcode 0x2f
2729****************************************************************************/
2730static void
2731x86emuOp_das(u8 X86EMU_UNUSED(op1))
2732{
2733 START_OF_INSTR();
2734 DECODE_PRINTF("DAS\n");
2735 TRACE_AND_STEP();
2736 M.x86.R_AL = das_byte(M.x86.R_AL);
2737 DECODE_CLEAR_SEGOVR();
2738 END_OF_INSTR();
2739}
2740
2741/****************************************************************************
2742REMARKS:
2743Handles opcode 0x30
2744****************************************************************************/
2745static void
2746x86emuOp_xor_byte_RM_R(u8 X86EMU_UNUSED(op1))
2747{
2748 int mod, rl, rh;
2749 u8 *destreg, *srcreg;
2750 uint destoffset;
2751 u8 destval;
2752
2753 START_OF_INSTR();
2754 DECODE_PRINTF("XOR\t");
2755 FETCH_DECODE_MODRM(mod, rh, rl);
2756 switch (mod) {
2757 case 0:
2758 destoffset = decode_rm00_address(rl);
2759 DECODE_PRINTF(",");
2760 destval = fetch_data_byte(destoffset);
2761 srcreg = DECODE_RM_BYTE_REGISTER(rh);
2762 DECODE_PRINTF("\n");
2763 TRACE_AND_STEP();
2764 destval = xor_byte(destval, *srcreg);
2765 store_data_byte(destoffset, destval);
2766 break;
2767 case 1:
2768 destoffset = decode_rm01_address(rl);
2769 DECODE_PRINTF(",");
2770 destval = fetch_data_byte(destoffset);
2771 srcreg = DECODE_RM_BYTE_REGISTER(rh);
2772 DECODE_PRINTF("\n");
2773 TRACE_AND_STEP();
2774 destval = xor_byte(destval, *srcreg);
2775 store_data_byte(destoffset, destval);
2776 break;
2777 case 2:
2778 destoffset = decode_rm10_address(rl);
2779 DECODE_PRINTF(",");
2780 destval = fetch_data_byte(destoffset);
2781 srcreg = DECODE_RM_BYTE_REGISTER(rh);
2782 DECODE_PRINTF("\n");
2783 TRACE_AND_STEP();
2784 destval = xor_byte(destval, *srcreg);
2785 store_data_byte(destoffset, destval);
2786 break;
2787 case 3: /* register to register */
2788 destreg = DECODE_RM_BYTE_REGISTER(rl);
2789 DECODE_PRINTF(",");
2790 srcreg = DECODE_RM_BYTE_REGISTER(rh);
2791 DECODE_PRINTF("\n");
2792 TRACE_AND_STEP();
2793 *destreg = xor_byte(*destreg, *srcreg);
2794 break;
2795 }
2796 DECODE_CLEAR_SEGOVR();
2797 END_OF_INSTR();
2798}
2799
2800/****************************************************************************
2801REMARKS:
2802Handles opcode 0x31
2803****************************************************************************/
2804static void
2805x86emuOp_xor_word_RM_R(u8 X86EMU_UNUSED(op1))
2806{
2807 int mod, rl, rh;
2808 uint destoffset;
2809
2810 START_OF_INSTR();
2811 DECODE_PRINTF("XOR\t");
2812 FETCH_DECODE_MODRM(mod, rh, rl);
2813 switch (mod) {
2814 case 0:
2815 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2816 u32 destval;
2817 u32 *srcreg;
2818
2819 destoffset = decode_rm00_address(rl);
2820 DECODE_PRINTF(",");
2821 destval = fetch_data_long(destoffset);
2822 srcreg = DECODE_RM_LONG_REGISTER(rh);
2823 DECODE_PRINTF("\n");
2824 TRACE_AND_STEP();
2825 destval = xor_long(destval, *srcreg);
2826 store_data_long(destoffset, destval);
2827 }
2828 else {
2829 u16 destval;
2830 u16 *srcreg;
2831
2832 destoffset = decode_rm00_address(rl);
2833 DECODE_PRINTF(",");
2834 destval = fetch_data_word(destoffset);
2835 srcreg = DECODE_RM_WORD_REGISTER(rh);
2836 DECODE_PRINTF("\n");
2837 TRACE_AND_STEP();
2838 destval = xor_word(destval, *srcreg);
2839 store_data_word(destoffset, destval);
2840 }
2841 break;
2842 case 1:
2843 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2844 u32 destval;
2845 u32 *srcreg;
2846
2847 destoffset = decode_rm01_address(rl);
2848 DECODE_PRINTF(",");
2849 destval = fetch_data_long(destoffset);
2850 srcreg = DECODE_RM_LONG_REGISTER(rh);
2851 DECODE_PRINTF("\n");
2852 TRACE_AND_STEP();
2853 destval = xor_long(destval, *srcreg);
2854 store_data_long(destoffset, destval);
2855 }
2856 else {
2857 u16 destval;
2858 u16 *srcreg;
2859
2860 destoffset = decode_rm01_address(rl);
2861 DECODE_PRINTF(",");
2862 destval = fetch_data_word(destoffset);
2863 srcreg = DECODE_RM_WORD_REGISTER(rh);
2864 DECODE_PRINTF("\n");
2865 TRACE_AND_STEP();
2866 destval = xor_word(destval, *srcreg);
2867 store_data_word(destoffset, destval);
2868 }
2869 break;
2870 case 2:
2871 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2872 u32 destval;
2873 u32 *srcreg;
2874
2875 destoffset = decode_rm10_address(rl);
2876 DECODE_PRINTF(",");
2877 destval = fetch_data_long(destoffset);
2878 srcreg = DECODE_RM_LONG_REGISTER(rh);
2879 DECODE_PRINTF("\n");
2880 TRACE_AND_STEP();
2881 destval = xor_long(destval, *srcreg);
2882 store_data_long(destoffset, destval);
2883 }
2884 else {
2885 u16 destval;
2886 u16 *srcreg;
2887
2888 destoffset = decode_rm10_address(rl);
2889 DECODE_PRINTF(",");
2890 destval = fetch_data_word(destoffset);
2891 srcreg = DECODE_RM_WORD_REGISTER(rh);
2892 DECODE_PRINTF("\n");
2893 TRACE_AND_STEP();
2894 destval = xor_word(destval, *srcreg);
2895 store_data_word(destoffset, destval);
2896 }
2897 break;
2898 case 3: /* register to register */
2899 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2900 u32 *destreg, *srcreg;
2901
2902 destreg = DECODE_RM_LONG_REGISTER(rl);
2903 DECODE_PRINTF(",");
2904 srcreg = DECODE_RM_LONG_REGISTER(rh);
2905 DECODE_PRINTF("\n");
2906 TRACE_AND_STEP();
2907 *destreg = xor_long(*destreg, *srcreg);
2908 }
2909 else {
2910 u16 *destreg, *srcreg;
2911
2912 destreg = DECODE_RM_WORD_REGISTER(rl);
2913 DECODE_PRINTF(",");
2914 srcreg = DECODE_RM_WORD_REGISTER(rh);
2915 DECODE_PRINTF("\n");
2916 TRACE_AND_STEP();
2917 *destreg = xor_word(*destreg, *srcreg);
2918 }
2919 break;
2920 }
2921 DECODE_CLEAR_SEGOVR();
2922 END_OF_INSTR();
2923}
2924
2925/****************************************************************************
2926REMARKS:
2927Handles opcode 0x32
2928****************************************************************************/
2929static void
2930x86emuOp_xor_byte_R_RM(u8 X86EMU_UNUSED(op1))
2931{
2932 int mod, rl, rh;
2933 u8 *destreg, *srcreg;
2934 uint srcoffset;
2935 u8 srcval;
2936
2937 START_OF_INSTR();
2938 DECODE_PRINTF("XOR\t");
2939 FETCH_DECODE_MODRM(mod, rh, rl);
2940 switch (mod) {
2941 case 0:
2942 destreg = DECODE_RM_BYTE_REGISTER(rh);
2943 DECODE_PRINTF(",");
2944 srcoffset = decode_rm00_address(rl);
2945 srcval = fetch_data_byte(srcoffset);
2946 DECODE_PRINTF("\n");
2947 TRACE_AND_STEP();
2948 *destreg = xor_byte(*destreg, srcval);
2949 break;
2950 case 1:
2951 destreg = DECODE_RM_BYTE_REGISTER(rh);
2952 DECODE_PRINTF(",");
2953 srcoffset = decode_rm01_address(rl);
2954 srcval = fetch_data_byte(srcoffset);
2955 DECODE_PRINTF("\n");
2956 TRACE_AND_STEP();
2957 *destreg = xor_byte(*destreg, srcval);
2958 break;
2959 case 2:
2960 destreg = DECODE_RM_BYTE_REGISTER(rh);
2961 DECODE_PRINTF(",");
2962 srcoffset = decode_rm10_address(rl);
2963 srcval = fetch_data_byte(srcoffset);
2964 DECODE_PRINTF("\n");
2965 TRACE_AND_STEP();
2966 *destreg = xor_byte(*destreg, srcval);
2967 break;
2968 case 3: /* register to register */
2969 destreg = DECODE_RM_BYTE_REGISTER(rh);
2970 DECODE_PRINTF(",");
2971 srcreg = DECODE_RM_BYTE_REGISTER(rl);
2972 DECODE_PRINTF("\n");
2973 TRACE_AND_STEP();
2974 *destreg = xor_byte(*destreg, *srcreg);
2975 break;
2976 }
2977 DECODE_CLEAR_SEGOVR();
2978 END_OF_INSTR();
2979}
2980
2981/****************************************************************************
2982REMARKS:
2983Handles opcode 0x33
2984****************************************************************************/
2985static void
2986x86emuOp_xor_word_R_RM(u8 X86EMU_UNUSED(op1))
2987{
2988 int mod, rl, rh;
2989 uint srcoffset;
2990
2991 START_OF_INSTR();
2992 DECODE_PRINTF("XOR\t");
2993 FETCH_DECODE_MODRM(mod, rh, rl);
2994 switch (mod) {
2995 case 0:
2996 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2997 u32 *destreg;
2998 u32 srcval;
2999
3000 destreg = DECODE_RM_LONG_REGISTER(rh);
3001 DECODE_PRINTF(",");
3002 srcoffset = decode_rm00_address(rl);
3003 srcval = fetch_data_long(srcoffset);
3004 DECODE_PRINTF("\n");
3005 TRACE_AND_STEP();
3006 *destreg = xor_long(*destreg, srcval);
3007 }
3008 else {
3009 u16 *destreg;
3010 u16 srcval;
3011
3012 destreg = DECODE_RM_WORD_REGISTER(rh);
3013 DECODE_PRINTF(",");
3014 srcoffset = decode_rm00_address(rl);
3015 srcval = fetch_data_word(srcoffset);
3016 DECODE_PRINTF("\n");
3017 TRACE_AND_STEP();
3018 *destreg = xor_word(*destreg, srcval);
3019 }
3020 break;
3021 case 1:
3022 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3023 u32 *destreg;
3024 u32 srcval;
3025
3026 destreg = DECODE_RM_LONG_REGISTER(rh);
3027 DECODE_PRINTF(",");
3028 srcoffset = decode_rm01_address(rl);
3029 srcval = fetch_data_long(srcoffset);
3030 DECODE_PRINTF("\n");
3031 TRACE_AND_STEP();
3032 *destreg = xor_long(*destreg, srcval);
3033 }
3034 else {
3035 u16 *destreg;
3036 u16 srcval;
3037
3038 destreg = DECODE_RM_WORD_REGISTER(rh);
3039 DECODE_PRINTF(",");
3040 srcoffset = decode_rm01_address(rl);
3041 srcval = fetch_data_word(srcoffset);
3042 DECODE_PRINTF("\n");
3043 TRACE_AND_STEP();
3044 *destreg = xor_word(*destreg, srcval);
3045 }
3046 break;
3047 case 2:
3048 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3049 u32 *destreg;
3050 u32 srcval;
3051
3052 destreg = DECODE_RM_LONG_REGISTER(rh);
3053 DECODE_PRINTF(",");
3054 srcoffset = decode_rm10_address(rl);
3055 srcval = fetch_data_long(srcoffset);
3056 DECODE_PRINTF("\n");
3057 TRACE_AND_STEP();
3058 *destreg = xor_long(*destreg, srcval);
3059 }
3060 else {
3061 u16 *destreg;
3062 u16 srcval;
3063
3064 destreg = DECODE_RM_WORD_REGISTER(rh);
3065 DECODE_PRINTF(",");
3066 srcoffset = decode_rm10_address(rl);
3067 srcval = fetch_data_word(srcoffset);
3068 DECODE_PRINTF("\n");
3069 TRACE_AND_STEP();
3070 *destreg = xor_word(*destreg, srcval);
3071 }
3072 break;
3073 case 3: /* register to register */
3074 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3075 u32 *destreg, *srcreg;
3076
3077 destreg = DECODE_RM_LONG_REGISTER(rh);
3078 DECODE_PRINTF(",");
3079 srcreg = DECODE_RM_LONG_REGISTER(rl);
3080 DECODE_PRINTF("\n");
3081 TRACE_AND_STEP();
3082 *destreg = xor_long(*destreg, *srcreg);
3083 }
3084 else {
3085 u16 *destreg, *srcreg;
3086
3087 destreg = DECODE_RM_WORD_REGISTER(rh);
3088 DECODE_PRINTF(",");
3089 srcreg = DECODE_RM_WORD_REGISTER(rl);
3090 DECODE_PRINTF("\n");
3091 TRACE_AND_STEP();
3092 *destreg = xor_word(*destreg, *srcreg);
3093 }
3094 break;
3095 }
3096 DECODE_CLEAR_SEGOVR();
3097 END_OF_INSTR();
3098}
3099
3100/****************************************************************************
3101REMARKS:
3102Handles opcode 0x34
3103****************************************************************************/
3104static void
3105x86emuOp_xor_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
3106{
3107 u8 srcval;
3108
3109 START_OF_INSTR();
3110 DECODE_PRINTF("XOR\tAL,");
3111 srcval = fetch_byte_imm();
3112 DECODE_PRINTF2("%x\n", srcval);
3113 TRACE_AND_STEP();
3114 M.x86.R_AL = xor_byte(M.x86.R_AL, srcval);
3115 DECODE_CLEAR_SEGOVR();
3116 END_OF_INSTR();
3117}
3118
3119/****************************************************************************
3120REMARKS:
3121Handles opcode 0x35
3122****************************************************************************/
3123static void
3124x86emuOp_xor_word_AX_IMM(u8 X86EMU_UNUSED(op1))
3125{
3126 u32 srcval;
3127
3128 START_OF_INSTR();
3129 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3130 DECODE_PRINTF("XOR\tEAX,");
3131 srcval = fetch_long_imm();
3132 }
3133 else {
3134 DECODE_PRINTF("XOR\tAX,");
3135 srcval = fetch_word_imm();
3136 }
3137 DECODE_PRINTF2("%x\n", srcval);
3138 TRACE_AND_STEP();
3139 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3140 M.x86.R_EAX = xor_long(M.x86.R_EAX, srcval);
3141 }
3142 else {
3143 M.x86.R_AX = xor_word(M.x86.R_AX, (u16) srcval);
3144 }
3145 DECODE_CLEAR_SEGOVR();
3146 END_OF_INSTR();
3147}
3148
3149/****************************************************************************
3150REMARKS:
3151Handles opcode 0x36
3152****************************************************************************/
3153static void
3154x86emuOp_segovr_SS(u8 X86EMU_UNUSED(op1))
3155{
3156 START_OF_INSTR();
3157 DECODE_PRINTF("SS:\n");
3158 TRACE_AND_STEP();
3159 M.x86.mode |= SYSMODE_SEGOVR_SS;
3160 /* no DECODE_CLEAR_SEGOVR ! */
3161 END_OF_INSTR();
3162}
3163
3164/****************************************************************************
3165REMARKS:
3166Handles opcode 0x37
3167****************************************************************************/
3168static void
3169x86emuOp_aaa(u8 X86EMU_UNUSED(op1))
3170{
3171 START_OF_INSTR();
3172 DECODE_PRINTF("AAA\n");
3173 TRACE_AND_STEP();
3174 M.x86.R_AX = aaa_word(M.x86.R_AX);
3175 DECODE_CLEAR_SEGOVR();
3176 END_OF_INSTR();
3177}
3178
3179/****************************************************************************
3180REMARKS:
3181Handles opcode 0x38
3182****************************************************************************/
3183static void
3184x86emuOp_cmp_byte_RM_R(u8 X86EMU_UNUSED(op1))
3185{
3186 int mod, rl, rh;
3187 uint destoffset;
3188 u8 *destreg, *srcreg;
3189 u8 destval;
3190
3191 START_OF_INSTR();
3192 DECODE_PRINTF("CMP\t");
3193 FETCH_DECODE_MODRM(mod, rh, rl);
3194 switch (mod) {
3195 case 0:
3196 destoffset = decode_rm00_address(rl);
3197 DECODE_PRINTF(",");
3198 destval = fetch_data_byte(destoffset);
3199 srcreg = DECODE_RM_BYTE_REGISTER(rh);
3200 DECODE_PRINTF("\n");
3201 TRACE_AND_STEP();
3202 cmp_byte(destval, *srcreg);
3203 break;
3204 case 1:
3205 destoffset = decode_rm01_address(rl);
3206 DECODE_PRINTF(",");
3207 destval = fetch_data_byte(destoffset);
3208 srcreg = DECODE_RM_BYTE_REGISTER(rh);
3209 DECODE_PRINTF("\n");
3210 TRACE_AND_STEP();
3211 cmp_byte(destval, *srcreg);
3212 break;
3213 case 2:
3214 destoffset = decode_rm10_address(rl);
3215 DECODE_PRINTF(",");
3216 destval = fetch_data_byte(destoffset);
3217 srcreg = DECODE_RM_BYTE_REGISTER(rh);
3218 DECODE_PRINTF("\n");
3219 TRACE_AND_STEP();
3220 cmp_byte(destval, *srcreg);
3221 break;
3222 case 3: /* register to register */
3223 destreg = DECODE_RM_BYTE_REGISTER(rl);
3224 DECODE_PRINTF(",");
3225 srcreg = DECODE_RM_BYTE_REGISTER(rh);
3226 DECODE_PRINTF("\n");
3227 TRACE_AND_STEP();
3228 cmp_byte(*destreg, *srcreg);
3229 break;
3230 }
3231 DECODE_CLEAR_SEGOVR();
3232 END_OF_INSTR();
3233}
3234
3235/****************************************************************************
3236REMARKS:
3237Handles opcode 0x39
3238****************************************************************************/
3239static void
3240x86emuOp_cmp_word_RM_R(u8 X86EMU_UNUSED(op1))
3241{
3242 int mod, rl, rh;
3243 uint destoffset;
3244
3245 START_OF_INSTR();
3246 DECODE_PRINTF("CMP\t");
3247 FETCH_DECODE_MODRM(mod, rh, rl);
3248 switch (mod) {
3249 case 0:
3250 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3251 u32 destval;
3252 u32 *srcreg;
3253
3254 destoffset = decode_rm00_address(rl);
3255 DECODE_PRINTF(",");
3256 destval = fetch_data_long(destoffset);
3257 srcreg = DECODE_RM_LONG_REGISTER(rh);
3258 DECODE_PRINTF("\n");
3259 TRACE_AND_STEP();
3260 cmp_long(destval, *srcreg);
3261 }
3262 else {
3263 u16 destval;
3264 u16 *srcreg;
3265
3266 destoffset = decode_rm00_address(rl);
3267 DECODE_PRINTF(",");
3268 destval = fetch_data_word(destoffset);
3269 srcreg = DECODE_RM_WORD_REGISTER(rh);
3270 DECODE_PRINTF("\n");
3271 TRACE_AND_STEP();
3272 cmp_word(destval, *srcreg);
3273 }
3274 break;
3275 case 1:
3276 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3277 u32 destval;
3278 u32 *srcreg;
3279
3280 destoffset = decode_rm01_address(rl);
3281 DECODE_PRINTF(",");
3282 destval = fetch_data_long(destoffset);
3283 srcreg = DECODE_RM_LONG_REGISTER(rh);
3284 DECODE_PRINTF("\n");
3285 TRACE_AND_STEP();
3286 cmp_long(destval, *srcreg);
3287 }
3288 else {
3289 u16 destval;
3290 u16 *srcreg;
3291
3292 destoffset = decode_rm01_address(rl);
3293 DECODE_PRINTF(",");
3294 destval = fetch_data_word(destoffset);
3295 srcreg = DECODE_RM_WORD_REGISTER(rh);
3296 DECODE_PRINTF("\n");
3297 TRACE_AND_STEP();
3298 cmp_word(destval, *srcreg);
3299 }
3300 break;
3301 case 2:
3302 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3303 u32 destval;
3304 u32 *srcreg;
3305
3306 destoffset = decode_rm10_address(rl);
3307 DECODE_PRINTF(",");
3308 destval = fetch_data_long(destoffset);
3309 srcreg = DECODE_RM_LONG_REGISTER(rh);
3310 DECODE_PRINTF("\n");
3311 TRACE_AND_STEP();
3312 cmp_long(destval, *srcreg);
3313 }
3314 else {
3315 u16 destval;
3316 u16 *srcreg;
3317
3318 destoffset = decode_rm10_address(rl);
3319 DECODE_PRINTF(",");
3320 destval = fetch_data_word(destoffset);
3321 srcreg = DECODE_RM_WORD_REGISTER(rh);
3322 DECODE_PRINTF("\n");
3323 TRACE_AND_STEP();
3324 cmp_word(destval, *srcreg);
3325 }
3326 break;
3327 case 3: /* register to register */
3328 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3329 u32 *destreg, *srcreg;
3330
3331 destreg = DECODE_RM_LONG_REGISTER(rl);
3332 DECODE_PRINTF(",");
3333 srcreg = DECODE_RM_LONG_REGISTER(rh);
3334 DECODE_PRINTF("\n");
3335 TRACE_AND_STEP();
3336 cmp_long(*destreg, *srcreg);
3337 }
3338 else {
3339 u16 *destreg, *srcreg;
3340
3341 destreg = DECODE_RM_WORD_REGISTER(rl);
3342 DECODE_PRINTF(",");
3343 srcreg = DECODE_RM_WORD_REGISTER(rh);
3344 DECODE_PRINTF("\n");
3345 TRACE_AND_STEP();
3346 cmp_word(*destreg, *srcreg);
3347 }
3348 break;
3349 }
3350 DECODE_CLEAR_SEGOVR();
3351 END_OF_INSTR();
3352}
3353
3354/****************************************************************************
3355REMARKS:
3356Handles opcode 0x3a
3357****************************************************************************/
3358static void
3359x86emuOp_cmp_byte_R_RM(u8 X86EMU_UNUSED(op1))
3360{
3361 int mod, rl, rh;
3362 u8 *destreg, *srcreg;
3363 uint srcoffset;
3364 u8 srcval;
3365
3366 START_OF_INSTR();
3367 DECODE_PRINTF("CMP\t");
3368 FETCH_DECODE_MODRM(mod, rh, rl);
3369 switch (mod) {
3370 case 0:
3371 destreg = DECODE_RM_BYTE_REGISTER(rh);
3372 DECODE_PRINTF(",");
3373 srcoffset = decode_rm00_address(rl);
3374 srcval = fetch_data_byte(srcoffset);
3375 DECODE_PRINTF("\n");
3376 TRACE_AND_STEP();
3377 cmp_byte(*destreg, srcval);
3378 break;
3379 case 1:
3380 destreg = DECODE_RM_BYTE_REGISTER(rh);
3381 DECODE_PRINTF(",");
3382 srcoffset = decode_rm01_address(rl);
3383 srcval = fetch_data_byte(srcoffset);
3384 DECODE_PRINTF("\n");
3385 TRACE_AND_STEP();
3386 cmp_byte(*destreg, srcval);
3387 break;
3388 case 2:
3389 destreg = DECODE_RM_BYTE_REGISTER(rh);
3390 DECODE_PRINTF(",");
3391 srcoffset = decode_rm10_address(rl);
3392 srcval = fetch_data_byte(srcoffset);
3393 DECODE_PRINTF("\n");
3394 TRACE_AND_STEP();
3395 cmp_byte(*destreg, srcval);
3396 break;
3397 case 3: /* register to register */
3398 destreg = DECODE_RM_BYTE_REGISTER(rh);
3399 DECODE_PRINTF(",");
3400 srcreg = DECODE_RM_BYTE_REGISTER(rl);
3401 DECODE_PRINTF("\n");
3402 TRACE_AND_STEP();
3403 cmp_byte(*destreg, *srcreg);
3404 break;
3405 }
3406 DECODE_CLEAR_SEGOVR();
3407 END_OF_INSTR();
3408}
3409
3410/****************************************************************************
3411REMARKS:
3412Handles opcode 0x3b
3413****************************************************************************/
3414static void
3415x86emuOp_cmp_word_R_RM(u8 X86EMU_UNUSED(op1))
3416{
3417 int mod, rl, rh;
3418 uint srcoffset;
3419
3420 START_OF_INSTR();
3421 DECODE_PRINTF("CMP\t");
3422 FETCH_DECODE_MODRM(mod, rh, rl);
3423 switch (mod) {
3424 case 0:
3425 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3426 u32 *destreg;
3427 u32 srcval;
3428
3429 destreg = DECODE_RM_LONG_REGISTER(rh);
3430 DECODE_PRINTF(",");
3431 srcoffset = decode_rm00_address(rl);
3432 srcval = fetch_data_long(srcoffset);
3433 DECODE_PRINTF("\n");
3434 TRACE_AND_STEP();
3435 cmp_long(*destreg, srcval);
3436 }
3437 else {
3438 u16 *destreg;
3439 u16 srcval;
3440
3441 destreg = DECODE_RM_WORD_REGISTER(rh);
3442 DECODE_PRINTF(",");
3443 srcoffset = decode_rm00_address(rl);
3444 srcval = fetch_data_word(srcoffset);
3445 DECODE_PRINTF("\n");
3446 TRACE_AND_STEP();
3447 cmp_word(*destreg, srcval);
3448 }
3449 break;
3450 case 1:
3451 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3452 u32 *destreg;
3453 u32 srcval;
3454
3455 destreg = DECODE_RM_LONG_REGISTER(rh);
3456 DECODE_PRINTF(",");
3457 srcoffset = decode_rm01_address(rl);
3458 srcval = fetch_data_long(srcoffset);
3459 DECODE_PRINTF("\n");
3460 TRACE_AND_STEP();
3461 cmp_long(*destreg, srcval);
3462 }
3463 else {
3464 u16 *destreg;
3465 u16 srcval;
3466
3467 destreg = DECODE_RM_WORD_REGISTER(rh);
3468 DECODE_PRINTF(",");
3469 srcoffset = decode_rm01_address(rl);
3470 srcval = fetch_data_word(srcoffset);
3471 DECODE_PRINTF("\n");
3472 TRACE_AND_STEP();
3473 cmp_word(*destreg, srcval);
3474 }
3475 break;
3476 case 2:
3477 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3478 u32 *destreg;
3479 u32 srcval;
3480
3481 destreg = DECODE_RM_LONG_REGISTER(rh);
3482 DECODE_PRINTF(",");
3483 srcoffset = decode_rm10_address(rl);
3484 srcval = fetch_data_long(srcoffset);
3485 DECODE_PRINTF("\n");
3486 TRACE_AND_STEP();
3487 cmp_long(*destreg, srcval);
3488 }
3489 else {
3490 u16 *destreg;
3491 u16 srcval;
3492
3493 destreg = DECODE_RM_WORD_REGISTER(rh);
3494 DECODE_PRINTF(",");
3495 srcoffset = decode_rm10_address(rl);
3496 srcval = fetch_data_word(srcoffset);
3497 DECODE_PRINTF("\n");
3498 TRACE_AND_STEP();
3499 cmp_word(*destreg, srcval);
3500 }
3501 break;
3502 case 3: /* register to register */
3503 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3504 u32 *destreg, *srcreg;
3505
3506 destreg = DECODE_RM_LONG_REGISTER(rh);
3507 DECODE_PRINTF(",");
3508 srcreg = DECODE_RM_LONG_REGISTER(rl);
3509 DECODE_PRINTF("\n");
3510 TRACE_AND_STEP();
3511 cmp_long(*destreg, *srcreg);
3512 }
3513 else {
3514 u16 *destreg, *srcreg;
3515
3516 destreg = DECODE_RM_WORD_REGISTER(rh);
3517 DECODE_PRINTF(",");
3518 srcreg = DECODE_RM_WORD_REGISTER(rl);
3519 DECODE_PRINTF("\n");
3520 TRACE_AND_STEP();
3521 cmp_word(*destreg, *srcreg);
3522 }
3523 break;
3524 }
3525 DECODE_CLEAR_SEGOVR();
3526 END_OF_INSTR();
3527}
3528
3529/****************************************************************************
3530REMARKS:
3531Handles opcode 0x3c
3532****************************************************************************/
3533static void
3534x86emuOp_cmp_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
3535{
3536 u8 srcval;
3537
3538 START_OF_INSTR();
3539 DECODE_PRINTF("CMP\tAL,");
3540 srcval = fetch_byte_imm();
3541 DECODE_PRINTF2("%x\n", srcval);
3542 TRACE_AND_STEP();
3543 cmp_byte(M.x86.R_AL, srcval);
3544 DECODE_CLEAR_SEGOVR();
3545 END_OF_INSTR();
3546}
3547
3548/****************************************************************************
3549REMARKS:
3550Handles opcode 0x3d
3551****************************************************************************/
3552static void
3553x86emuOp_cmp_word_AX_IMM(u8 X86EMU_UNUSED(op1))
3554{
3555 u32 srcval;
3556
3557 START_OF_INSTR();
3558 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3559 DECODE_PRINTF("CMP\tEAX,");
3560 srcval = fetch_long_imm();
3561 }
3562 else {
3563 DECODE_PRINTF("CMP\tAX,");
3564 srcval = fetch_word_imm();
3565 }
3566 DECODE_PRINTF2("%x\n", srcval);
3567 TRACE_AND_STEP();
3568 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3569 cmp_long(M.x86.R_EAX, srcval);
3570 }
3571 else {
3572 cmp_word(M.x86.R_AX, (u16) srcval);
3573 }
3574 DECODE_CLEAR_SEGOVR();
3575 END_OF_INSTR();
3576}
3577
3578/****************************************************************************
3579REMARKS:
3580Handles opcode 0x3e
3581****************************************************************************/
3582static void
3583x86emuOp_segovr_DS(u8 X86EMU_UNUSED(op1))
3584{
3585 START_OF_INSTR();
3586 DECODE_PRINTF("DS:\n");
3587 TRACE_AND_STEP();
3588 M.x86.mode |= SYSMODE_SEGOVR_DS;
3589 /* NO DECODE_CLEAR_SEGOVR! */
3590 END_OF_INSTR();
3591}
3592
3593/****************************************************************************
3594REMARKS:
3595Handles opcode 0x3f
3596****************************************************************************/
3597static void
3598x86emuOp_aas(u8 X86EMU_UNUSED(op1))
3599{
3600 START_OF_INSTR();
3601 DECODE_PRINTF("AAS\n");
3602 TRACE_AND_STEP();
3603 M.x86.R_AX = aas_word(M.x86.R_AX);
3604 DECODE_CLEAR_SEGOVR();
3605 END_OF_INSTR();
3606}
3607
3608/****************************************************************************
3609REMARKS:
3610Handles opcode 0x40
3611****************************************************************************/
3612static void
3613x86emuOp_inc_AX(u8 X86EMU_UNUSED(op1))
3614{
3615 START_OF_INSTR();
3616 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3617 DECODE_PRINTF("INC\tEAX\n");
3618 }
3619 else {
3620 DECODE_PRINTF("INC\tAX\n");
3621 }
3622 TRACE_AND_STEP();
3623 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3624 M.x86.R_EAX = inc_long(M.x86.R_EAX);
3625 }
3626 else {
3627 M.x86.R_AX = inc_word(M.x86.R_AX);
3628 }
3629 DECODE_CLEAR_SEGOVR();
3630 END_OF_INSTR();
3631}
3632
3633/****************************************************************************
3634REMARKS:
3635Handles opcode 0x41
3636****************************************************************************/
3637static void
3638x86emuOp_inc_CX(u8 X86EMU_UNUSED(op1))
3639{
3640 START_OF_INSTR();
3641 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3642 DECODE_PRINTF("INC\tECX\n");
3643 }
3644 else {
3645 DECODE_PRINTF("INC\tCX\n");
3646 }
3647 TRACE_AND_STEP();
3648 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3649 M.x86.R_ECX = inc_long(M.x86.R_ECX);
3650 }
3651 else {
3652 M.x86.R_CX = inc_word(M.x86.R_CX);
3653 }
3654 DECODE_CLEAR_SEGOVR();
3655 END_OF_INSTR();
3656}
3657
3658/****************************************************************************
3659REMARKS:
3660Handles opcode 0x42
3661****************************************************************************/
3662static void
3663x86emuOp_inc_DX(u8 X86EMU_UNUSED(op1))
3664{
3665 START_OF_INSTR();
3666 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3667 DECODE_PRINTF("INC\tEDX\n");
3668 }
3669 else {
3670 DECODE_PRINTF("INC\tDX\n");
3671 }
3672 TRACE_AND_STEP();
3673 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3674 M.x86.R_EDX = inc_long(M.x86.R_EDX);
3675 }
3676 else {
3677 M.x86.R_DX = inc_word(M.x86.R_DX);
3678 }
3679 DECODE_CLEAR_SEGOVR();
3680 END_OF_INSTR();
3681}
3682
3683/****************************************************************************
3684REMARKS:
3685Handles opcode 0x43
3686****************************************************************************/
3687static void
3688x86emuOp_inc_BX(u8 X86EMU_UNUSED(op1))
3689{
3690 START_OF_INSTR();
3691 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3692 DECODE_PRINTF("INC\tEBX\n");
3693 }
3694 else {
3695 DECODE_PRINTF("INC\tBX\n");
3696 }
3697 TRACE_AND_STEP();
3698 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3699 M.x86.R_EBX = inc_long(M.x86.R_EBX);
3700 }
3701 else {
3702 M.x86.R_BX = inc_word(M.x86.R_BX);
3703 }
3704 DECODE_CLEAR_SEGOVR();
3705 END_OF_INSTR();
3706}
3707
3708/****************************************************************************
3709REMARKS:
3710Handles opcode 0x44
3711****************************************************************************/
3712static void
3713x86emuOp_inc_SP(u8 X86EMU_UNUSED(op1))
3714{
3715 START_OF_INSTR();
3716 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3717 DECODE_PRINTF("INC\tESP\n");
3718 }
3719 else {
3720 DECODE_PRINTF("INC\tSP\n");
3721 }
3722 TRACE_AND_STEP();
3723 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3724 M.x86.R_ESP = inc_long(M.x86.R_ESP);
3725 }
3726 else {
3727 M.x86.R_SP = inc_word(M.x86.R_SP);
3728 }
3729 DECODE_CLEAR_SEGOVR();
3730 END_OF_INSTR();
3731}
3732
3733/****************************************************************************
3734REMARKS:
3735Handles opcode 0x45
3736****************************************************************************/
3737static void
3738x86emuOp_inc_BP(u8 X86EMU_UNUSED(op1))
3739{
3740 START_OF_INSTR();
3741 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3742 DECODE_PRINTF("INC\tEBP\n");
3743 }
3744 else {
3745 DECODE_PRINTF("INC\tBP\n");
3746 }
3747 TRACE_AND_STEP();
3748 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3749 M.x86.R_EBP = inc_long(M.x86.R_EBP);
3750 }
3751 else {
3752 M.x86.R_BP = inc_word(M.x86.R_BP);
3753 }
3754 DECODE_CLEAR_SEGOVR();
3755 END_OF_INSTR();
3756}
3757
3758/****************************************************************************
3759REMARKS:
3760Handles opcode 0x46
3761****************************************************************************/
3762static void
3763x86emuOp_inc_SI(u8 X86EMU_UNUSED(op1))
3764{
3765 START_OF_INSTR();
3766 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3767 DECODE_PRINTF("INC\tESI\n");
3768 }
3769 else {
3770 DECODE_PRINTF("INC\tSI\n");
3771 }
3772 TRACE_AND_STEP();
3773 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3774 M.x86.R_ESI = inc_long(M.x86.R_ESI);
3775 }
3776 else {
3777 M.x86.R_SI = inc_word(M.x86.R_SI);
3778 }
3779 DECODE_CLEAR_SEGOVR();
3780 END_OF_INSTR();
3781}
3782
3783/****************************************************************************
3784REMARKS:
3785Handles opcode 0x47
3786****************************************************************************/
3787static void
3788x86emuOp_inc_DI(u8 X86EMU_UNUSED(op1))
3789{
3790 START_OF_INSTR();
3791 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3792 DECODE_PRINTF("INC\tEDI\n");
3793 }
3794 else {
3795 DECODE_PRINTF("INC\tDI\n");
3796 }
3797 TRACE_AND_STEP();
3798 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3799 M.x86.R_EDI = inc_long(M.x86.R_EDI);
3800 }
3801 else {
3802 M.x86.R_DI = inc_word(M.x86.R_DI);
3803 }
3804 DECODE_CLEAR_SEGOVR();
3805 END_OF_INSTR();
3806}
3807
3808/****************************************************************************
3809REMARKS:
3810Handles opcode 0x48
3811****************************************************************************/
3812static void
3813x86emuOp_dec_AX(u8 X86EMU_UNUSED(op1))
3814{
3815 START_OF_INSTR();
3816 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3817 DECODE_PRINTF("DEC\tEAX\n");
3818 }
3819 else {
3820 DECODE_PRINTF("DEC\tAX\n");
3821 }
3822 TRACE_AND_STEP();
3823 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3824 M.x86.R_EAX = dec_long(M.x86.R_EAX);
3825 }
3826 else {
3827 M.x86.R_AX = dec_word(M.x86.R_AX);
3828 }
3829 DECODE_CLEAR_SEGOVR();
3830 END_OF_INSTR();
3831}
3832
3833/****************************************************************************
3834REMARKS:
3835Handles opcode 0x49
3836****************************************************************************/
3837static void
3838x86emuOp_dec_CX(u8 X86EMU_UNUSED(op1))
3839{
3840 START_OF_INSTR();
3841 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3842 DECODE_PRINTF("DEC\tECX\n");
3843 }
3844 else {
3845 DECODE_PRINTF("DEC\tCX\n");
3846 }
3847 TRACE_AND_STEP();
3848 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3849 M.x86.R_ECX = dec_long(M.x86.R_ECX);
3850 }
3851 else {
3852 M.x86.R_CX = dec_word(M.x86.R_CX);
3853 }
3854 DECODE_CLEAR_SEGOVR();
3855 END_OF_INSTR();
3856}
3857
3858/****************************************************************************
3859REMARKS:
3860Handles opcode 0x4a
3861****************************************************************************/
3862static void
3863x86emuOp_dec_DX(u8 X86EMU_UNUSED(op1))
3864{
3865 START_OF_INSTR();
3866 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3867 DECODE_PRINTF("DEC\tEDX\n");
3868 }
3869 else {
3870 DECODE_PRINTF("DEC\tDX\n");
3871 }
3872 TRACE_AND_STEP();
3873 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3874 M.x86.R_EDX = dec_long(M.x86.R_EDX);
3875 }
3876 else {
3877 M.x86.R_DX = dec_word(M.x86.R_DX);
3878 }
3879 DECODE_CLEAR_SEGOVR();
3880 END_OF_INSTR();
3881}
3882
3883/****************************************************************************
3884REMARKS:
3885Handles opcode 0x4b
3886****************************************************************************/
3887static void
3888x86emuOp_dec_BX(u8 X86EMU_UNUSED(op1))
3889{
3890 START_OF_INSTR();
3891 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3892 DECODE_PRINTF("DEC\tEBX\n");
3893 }
3894 else {
3895 DECODE_PRINTF("DEC\tBX\n");
3896 }
3897 TRACE_AND_STEP();
3898 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3899 M.x86.R_EBX = dec_long(M.x86.R_EBX);
3900 }
3901 else {
3902 M.x86.R_BX = dec_word(M.x86.R_BX);
3903 }
3904 DECODE_CLEAR_SEGOVR();
3905 END_OF_INSTR();
3906}
3907
3908/****************************************************************************
3909REMARKS:
3910Handles opcode 0x4c
3911****************************************************************************/
3912static void
3913x86emuOp_dec_SP(u8 X86EMU_UNUSED(op1))
3914{
3915 START_OF_INSTR();
3916 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3917 DECODE_PRINTF("DEC\tESP\n");
3918 }
3919 else {
3920 DECODE_PRINTF("DEC\tSP\n");
3921 }
3922 TRACE_AND_STEP();
3923 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3924 M.x86.R_ESP = dec_long(M.x86.R_ESP);
3925 }
3926 else {
3927 M.x86.R_SP = dec_word(M.x86.R_SP);
3928 }
3929 DECODE_CLEAR_SEGOVR();
3930 END_OF_INSTR();
3931}
3932
3933/****************************************************************************
3934REMARKS:
3935Handles opcode 0x4d
3936****************************************************************************/
3937static void
3938x86emuOp_dec_BP(u8 X86EMU_UNUSED(op1))
3939{
3940 START_OF_INSTR();
3941 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3942 DECODE_PRINTF("DEC\tEBP\n");
3943 }
3944 else {
3945 DECODE_PRINTF("DEC\tBP\n");
3946 }
3947 TRACE_AND_STEP();
3948 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3949 M.x86.R_EBP = dec_long(M.x86.R_EBP);
3950 }
3951 else {
3952 M.x86.R_BP = dec_word(M.x86.R_BP);
3953 }
3954 DECODE_CLEAR_SEGOVR();
3955 END_OF_INSTR();
3956}
3957
3958/****************************************************************************
3959REMARKS:
3960Handles opcode 0x4e
3961****************************************************************************/
3962static void
3963x86emuOp_dec_SI(u8 X86EMU_UNUSED(op1))
3964{
3965 START_OF_INSTR();
3966 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3967 DECODE_PRINTF("DEC\tESI\n");
3968 }
3969 else {
3970 DECODE_PRINTF("DEC\tSI\n");
3971 }
3972 TRACE_AND_STEP();
3973 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3974 M.x86.R_ESI = dec_long(M.x86.R_ESI);
3975 }
3976 else {
3977 M.x86.R_SI = dec_word(M.x86.R_SI);
3978 }
3979 DECODE_CLEAR_SEGOVR();
3980 END_OF_INSTR();
3981}
3982
3983/****************************************************************************
3984REMARKS:
3985Handles opcode 0x4f
3986****************************************************************************/
3987static void
3988x86emuOp_dec_DI(u8 X86EMU_UNUSED(op1))
3989{
3990 START_OF_INSTR();
3991 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3992 DECODE_PRINTF("DEC\tEDI\n");
3993 }
3994 else {
3995 DECODE_PRINTF("DEC\tDI\n");
3996 }
3997 TRACE_AND_STEP();
3998 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3999 M.x86.R_EDI = dec_long(M.x86.R_EDI);
4000 }
4001 else {
4002 M.x86.R_DI = dec_word(M.x86.R_DI);
4003 }
4004 DECODE_CLEAR_SEGOVR();
4005 END_OF_INSTR();
4006}
4007
4008/****************************************************************************
4009REMARKS:
4010Handles opcode 0x50
4011****************************************************************************/
4012static void
4013x86emuOp_push_AX(u8 X86EMU_UNUSED(op1))
4014{
4015 START_OF_INSTR();
4016 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4017 DECODE_PRINTF("PUSH\tEAX\n");
4018 }
4019 else {
4020 DECODE_PRINTF("PUSH\tAX\n");
4021 }
4022 TRACE_AND_STEP();
4023 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4024 push_long(M.x86.R_EAX);
4025 }
4026 else {
4027 push_word(M.x86.R_AX);
4028 }
4029 DECODE_CLEAR_SEGOVR();
4030 END_OF_INSTR();
4031}
4032
4033/****************************************************************************
4034REMARKS:
4035Handles opcode 0x51
4036****************************************************************************/
4037static void
4038x86emuOp_push_CX(u8 X86EMU_UNUSED(op1))
4039{
4040 START_OF_INSTR();
4041 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4042 DECODE_PRINTF("PUSH\tECX\n");
4043 }
4044 else {
4045 DECODE_PRINTF("PUSH\tCX\n");
4046 }
4047 TRACE_AND_STEP();
4048 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4049 push_long(M.x86.R_ECX);
4050 }
4051 else {
4052 push_word(M.x86.R_CX);
4053 }
4054 DECODE_CLEAR_SEGOVR();
4055 END_OF_INSTR();
4056}
4057
4058/****************************************************************************
4059REMARKS:
4060Handles opcode 0x52
4061****************************************************************************/
4062static void
4063x86emuOp_push_DX(u8 X86EMU_UNUSED(op1))
4064{
4065 START_OF_INSTR();
4066 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4067 DECODE_PRINTF("PUSH\tEDX\n");
4068 }
4069 else {
4070 DECODE_PRINTF("PUSH\tDX\n");
4071 }
4072 TRACE_AND_STEP();
4073 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4074 push_long(M.x86.R_EDX);
4075 }
4076 else {
4077 push_word(M.x86.R_DX);
4078 }
4079 DECODE_CLEAR_SEGOVR();
4080 END_OF_INSTR();
4081}
4082
4083/****************************************************************************
4084REMARKS:
4085Handles opcode 0x53
4086****************************************************************************/
4087static void
4088x86emuOp_push_BX(u8 X86EMU_UNUSED(op1))
4089{
4090 START_OF_INSTR();
4091 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4092 DECODE_PRINTF("PUSH\tEBX\n");
4093 }
4094 else {
4095 DECODE_PRINTF("PUSH\tBX\n");
4096 }
4097 TRACE_AND_STEP();
4098 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4099 push_long(M.x86.R_EBX);
4100 }
4101 else {
4102 push_word(M.x86.R_BX);
4103 }
4104 DECODE_CLEAR_SEGOVR();
4105 END_OF_INSTR();
4106}
4107
4108/****************************************************************************
4109REMARKS:
4110Handles opcode 0x54
4111****************************************************************************/
4112static void
4113x86emuOp_push_SP(u8 X86EMU_UNUSED(op1))
4114{
4115 START_OF_INSTR();
4116 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4117 DECODE_PRINTF("PUSH\tESP\n");
4118 }
4119 else {
4120 DECODE_PRINTF("PUSH\tSP\n");
4121 }
4122 TRACE_AND_STEP();
4123 /* Always push (E)SP, since we are emulating an i386 and above
4124 * processor. This is necessary as some BIOS'es use this to check
4125 * what type of processor is in the system.
4126 */
4127 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4128 push_long(M.x86.R_ESP);
4129 }
4130 else {
4131 push_word((u16) (M.x86.R_SP));
4132 }
4133 DECODE_CLEAR_SEGOVR();
4134 END_OF_INSTR();
4135}
4136
4137/****************************************************************************
4138REMARKS:
4139Handles opcode 0x55
4140****************************************************************************/
4141static void
4142x86emuOp_push_BP(u8 X86EMU_UNUSED(op1))
4143{
4144 START_OF_INSTR();
4145 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4146 DECODE_PRINTF("PUSH\tEBP\n");
4147 }
4148 else {
4149 DECODE_PRINTF("PUSH\tBP\n");
4150 }
4151 TRACE_AND_STEP();
4152 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4153 push_long(M.x86.R_EBP);
4154 }
4155 else {
4156 push_word(M.x86.R_BP);
4157 }
4158 DECODE_CLEAR_SEGOVR();
4159 END_OF_INSTR();
4160}
4161
4162/****************************************************************************
4163REMARKS:
4164Handles opcode 0x56
4165****************************************************************************/
4166static void
4167x86emuOp_push_SI(u8 X86EMU_UNUSED(op1))
4168{
4169 START_OF_INSTR();
4170 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4171 DECODE_PRINTF("PUSH\tESI\n");
4172 }
4173 else {
4174 DECODE_PRINTF("PUSH\tSI\n");
4175 }
4176 TRACE_AND_STEP();
4177 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4178 push_long(M.x86.R_ESI);
4179 }
4180 else {
4181 push_word(M.x86.R_SI);
4182 }
4183 DECODE_CLEAR_SEGOVR();
4184 END_OF_INSTR();
4185}
4186
4187/****************************************************************************
4188REMARKS:
4189Handles opcode 0x57
4190****************************************************************************/
4191static void
4192x86emuOp_push_DI(u8 X86EMU_UNUSED(op1))
4193{
4194 START_OF_INSTR();
4195 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4196 DECODE_PRINTF("PUSH\tEDI\n");
4197 }
4198 else {
4199 DECODE_PRINTF("PUSH\tDI\n");
4200 }
4201 TRACE_AND_STEP();
4202 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4203 push_long(M.x86.R_EDI);
4204 }
4205 else {
4206 push_word(M.x86.R_DI);
4207 }
4208 DECODE_CLEAR_SEGOVR();
4209 END_OF_INSTR();
4210}
4211
4212/****************************************************************************
4213REMARKS:
4214Handles opcode 0x58
4215****************************************************************************/
4216static void
4217x86emuOp_pop_AX(u8 X86EMU_UNUSED(op1))
4218{
4219 START_OF_INSTR();
4220 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4221 DECODE_PRINTF("POP\tEAX\n");
4222 }
4223 else {
4224 DECODE_PRINTF("POP\tAX\n");
4225 }
4226 TRACE_AND_STEP();
4227 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4228 M.x86.R_EAX = pop_long();
4229 }
4230 else {
4231 M.x86.R_AX = pop_word();
4232 }
4233 DECODE_CLEAR_SEGOVR();
4234 END_OF_INSTR();
4235}
4236
4237/****************************************************************************
4238REMARKS:
4239Handles opcode 0x59
4240****************************************************************************/
4241static void
4242x86emuOp_pop_CX(u8 X86EMU_UNUSED(op1))
4243{
4244 START_OF_INSTR();
4245 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4246 DECODE_PRINTF("POP\tECX\n");
4247 }
4248 else {
4249 DECODE_PRINTF("POP\tCX\n");
4250 }
4251 TRACE_AND_STEP();
4252 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4253 M.x86.R_ECX = pop_long();
4254 }
4255 else {
4256 M.x86.R_CX = pop_word();
4257 }
4258 DECODE_CLEAR_SEGOVR();
4259 END_OF_INSTR();
4260}
4261
4262/****************************************************************************
4263REMARKS:
4264Handles opcode 0x5a
4265****************************************************************************/
4266static void
4267x86emuOp_pop_DX(u8 X86EMU_UNUSED(op1))
4268{
4269 START_OF_INSTR();
4270 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4271 DECODE_PRINTF("POP\tEDX\n");
4272 }
4273 else {
4274 DECODE_PRINTF("POP\tDX\n");
4275 }
4276 TRACE_AND_STEP();
4277 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4278 M.x86.R_EDX = pop_long();
4279 }
4280 else {
4281 M.x86.R_DX = pop_word();
4282 }
4283 DECODE_CLEAR_SEGOVR();
4284 END_OF_INSTR();
4285}
4286
4287/****************************************************************************
4288REMARKS:
4289Handles opcode 0x5b
4290****************************************************************************/
4291static void
4292x86emuOp_pop_BX(u8 X86EMU_UNUSED(op1))
4293{
4294 START_OF_INSTR();
4295 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4296 DECODE_PRINTF("POP\tEBX\n");
4297 }
4298 else {
4299 DECODE_PRINTF("POP\tBX\n");
4300 }
4301 TRACE_AND_STEP();
4302 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4303 M.x86.R_EBX = pop_long();
4304 }
4305 else {
4306 M.x86.R_BX = pop_word();
4307 }
4308 DECODE_CLEAR_SEGOVR();
4309 END_OF_INSTR();
4310}
4311
4312/****************************************************************************
4313REMARKS:
4314Handles opcode 0x5c
4315****************************************************************************/
4316static void
4317x86emuOp_pop_SP(u8 X86EMU_UNUSED(op1))
4318{
4319 START_OF_INSTR();
4320 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4321 DECODE_PRINTF("POP\tESP\n");
4322 }
4323 else {
4324 DECODE_PRINTF("POP\tSP\n");
4325 }
4326 TRACE_AND_STEP();
4327 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4328 M.x86.R_ESP = pop_long();
4329 }
4330 else {
4331 M.x86.R_SP = pop_word();
4332 }
4333 DECODE_CLEAR_SEGOVR();
4334 END_OF_INSTR();
4335}
4336
4337/****************************************************************************
4338REMARKS:
4339Handles opcode 0x5d
4340****************************************************************************/
4341static void
4342x86emuOp_pop_BP(u8 X86EMU_UNUSED(op1))
4343{
4344 START_OF_INSTR();
4345 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4346 DECODE_PRINTF("POP\tEBP\n");
4347 }
4348 else {
4349 DECODE_PRINTF("POP\tBP\n");
4350 }
4351 TRACE_AND_STEP();
4352 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4353 M.x86.R_EBP = pop_long();
4354 }
4355 else {
4356 M.x86.R_BP = pop_word();
4357 }
4358 DECODE_CLEAR_SEGOVR();
4359 END_OF_INSTR();
4360}
4361
4362/****************************************************************************
4363REMARKS:
4364Handles opcode 0x5e
4365****************************************************************************/
4366static void
4367x86emuOp_pop_SI(u8 X86EMU_UNUSED(op1))
4368{
4369 START_OF_INSTR();
4370 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4371 DECODE_PRINTF("POP\tESI\n");
4372 }
4373 else {
4374 DECODE_PRINTF("POP\tSI\n");
4375 }
4376 TRACE_AND_STEP();
4377 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4378 M.x86.R_ESI = pop_long();
4379 }
4380 else {
4381 M.x86.R_SI = pop_word();
4382 }
4383 DECODE_CLEAR_SEGOVR();
4384 END_OF_INSTR();
4385}
4386
4387/****************************************************************************
4388REMARKS:
4389Handles opcode 0x5f
4390****************************************************************************/
4391static void
4392x86emuOp_pop_DI(u8 X86EMU_UNUSED(op1))
4393{
4394 START_OF_INSTR();
4395 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4396 DECODE_PRINTF("POP\tEDI\n");
4397 }
4398 else {
4399 DECODE_PRINTF("POP\tDI\n");
4400 }
4401 TRACE_AND_STEP();
4402 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4403 M.x86.R_EDI = pop_long();
4404 }
4405 else {
4406 M.x86.R_DI = pop_word();
4407 }
4408 DECODE_CLEAR_SEGOVR();
4409 END_OF_INSTR();
4410}
4411
4412/****************************************************************************
4413REMARKS:
4414Handles opcode 0x60
4415****************************************************************************/
4416static void
4417x86emuOp_push_all(u8 X86EMU_UNUSED(op1))
4418{
4419 START_OF_INSTR();
4420 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4421 DECODE_PRINTF("PUSHAD\n");
4422 }
4423 else {
4424 DECODE_PRINTF("PUSHA\n");
4425 }
4426 TRACE_AND_STEP();
4427 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4428 u32 old_sp = M.x86.R_ESP;
4429
4430 push_long(M.x86.R_EAX);
4431 push_long(M.x86.R_ECX);
4432 push_long(M.x86.R_EDX);
4433 push_long(M.x86.R_EBX);
4434 push_long(old_sp);
4435 push_long(M.x86.R_EBP);
4436 push_long(M.x86.R_ESI);
4437 push_long(M.x86.R_EDI);
4438 }
4439 else {
4440 u16 old_sp = M.x86.R_SP;
4441
4442 push_word(M.x86.R_AX);
4443 push_word(M.x86.R_CX);
4444 push_word(M.x86.R_DX);
4445 push_word(M.x86.R_BX);
4446 push_word(old_sp);
4447 push_word(M.x86.R_BP);
4448 push_word(M.x86.R_SI);
4449 push_word(M.x86.R_DI);
4450 }
4451 DECODE_CLEAR_SEGOVR();
4452 END_OF_INSTR();
4453}
4454
4455/****************************************************************************
4456REMARKS:
4457Handles opcode 0x61
4458****************************************************************************/
4459static void
4460x86emuOp_pop_all(u8 X86EMU_UNUSED(op1))
4461{
4462 START_OF_INSTR();
4463 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4464 DECODE_PRINTF("POPAD\n");
4465 }
4466 else {
4467 DECODE_PRINTF("POPA\n");
4468 }
4469 TRACE_AND_STEP();
4470 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4471 M.x86.R_EDI = pop_long();
4472 M.x86.R_ESI = pop_long();
4473 M.x86.R_EBP = pop_long();
4474 M.x86.R_ESP += 4; /* skip ESP */
4475 M.x86.R_EBX = pop_long();
4476 M.x86.R_EDX = pop_long();
4477 M.x86.R_ECX = pop_long();
4478 M.x86.R_EAX = pop_long();
4479 }
4480 else {
4481 M.x86.R_DI = pop_word();
4482 M.x86.R_SI = pop_word();
4483 M.x86.R_BP = pop_word();
4484 M.x86.R_SP += 2; /* skip SP */
4485 M.x86.R_BX = pop_word();
4486 M.x86.R_DX = pop_word();
4487 M.x86.R_CX = pop_word();
4488 M.x86.R_AX = pop_word();
4489 }
4490 DECODE_CLEAR_SEGOVR();
4491 END_OF_INSTR();
4492}
4493
4494/*opcode 0x62 ILLEGAL OP, calls x86emuOp_illegal_op() */
4495/*opcode 0x63 ILLEGAL OP, calls x86emuOp_illegal_op() */
4496
4497/****************************************************************************
4498REMARKS:
4499Handles opcode 0x64
4500****************************************************************************/
4501static void
4502x86emuOp_segovr_FS(u8 X86EMU_UNUSED(op1))
4503{
4504 START_OF_INSTR();
4505 DECODE_PRINTF("FS:\n");
4506 TRACE_AND_STEP();
4507 M.x86.mode |= SYSMODE_SEGOVR_FS;
4508 /*
4509 * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
4510 * opcode subroutines we do not want to do this.
4511 */
4512 END_OF_INSTR();
4513}
4514
4515/****************************************************************************
4516REMARKS:
4517Handles opcode 0x65
4518****************************************************************************/
4519static void
4520x86emuOp_segovr_GS(u8 X86EMU_UNUSED(op1))
4521{
4522 START_OF_INSTR();
4523 DECODE_PRINTF("GS:\n");
4524 TRACE_AND_STEP();
4525 M.x86.mode |= SYSMODE_SEGOVR_GS;
4526 /*
4527 * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
4528 * opcode subroutines we do not want to do this.
4529 */
4530 END_OF_INSTR();
4531}
4532
4533/****************************************************************************
4534REMARKS:
4535Handles opcode 0x66 - prefix for 32-bit register
4536****************************************************************************/
4537static void
4538x86emuOp_prefix_data(u8 X86EMU_UNUSED(op1))
4539{
4540 START_OF_INSTR();
4541 DECODE_PRINTF("DATA:\n");
4542 TRACE_AND_STEP();
4543 M.x86.mode |= SYSMODE_PREFIX_DATA;
4544 /* note no DECODE_CLEAR_SEGOVR here. */
4545 END_OF_INSTR();
4546}
4547
4548/****************************************************************************
4549REMARKS:
4550Handles opcode 0x67 - prefix for 32-bit address
4551****************************************************************************/
4552static void
4553x86emuOp_prefix_addr(u8 X86EMU_UNUSED(op1))
4554{
4555 START_OF_INSTR();
4556 DECODE_PRINTF("ADDR:\n");
4557 TRACE_AND_STEP();
4558 M.x86.mode |= SYSMODE_PREFIX_ADDR;
4559 /* note no DECODE_CLEAR_SEGOVR here. */
4560 END_OF_INSTR();
4561}
4562
4563/****************************************************************************
4564REMARKS:
4565Handles opcode 0x68
4566****************************************************************************/
4567static void
4568x86emuOp_push_word_IMM(u8 X86EMU_UNUSED(op1))
4569{
4570 u32 imm;
4571
4572 START_OF_INSTR();
4573 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4574 imm = fetch_long_imm();
4575 }
4576 else {
4577 imm = fetch_word_imm();
4578 }
4579 DECODE_PRINTF2("PUSH\t%x\n", imm);
4580 TRACE_AND_STEP();
4581 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4582 push_long(imm);
4583 }
4584 else {
4585 push_word((u16) imm);
4586 }
4587 DECODE_CLEAR_SEGOVR();
4588 END_OF_INSTR();
4589}
4590
4591/****************************************************************************
4592REMARKS:
4593Handles opcode 0x69
4594****************************************************************************/
4595static void
4596x86emuOp_imul_word_IMM(u8 X86EMU_UNUSED(op1))
4597{
4598 int mod, rl, rh;
4599 uint srcoffset;
4600
4601 START_OF_INSTR();
4602 DECODE_PRINTF("IMUL\t");
4603 FETCH_DECODE_MODRM(mod, rh, rl);
4604 switch (mod) {
4605 case 0:
4606 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4607 u32 *destreg;
4608 u32 srcval;
4609 u32 res_lo, res_hi;
4610 s32 imm;
4611
4612 destreg = DECODE_RM_LONG_REGISTER(rh);
4613 DECODE_PRINTF(",");
4614 srcoffset = decode_rm00_address(rl);
4615 srcval = fetch_data_long(srcoffset);
4616 imm = fetch_long_imm();
4617 DECODE_PRINTF2(",%d\n", (s32) imm);
4618 TRACE_AND_STEP();
4619 imul_long_direct(&res_lo, &res_hi, (s32) srcval, (s32) imm);
4620 if (res_hi != 0) {
4621 SET_FLAG(F_CF);
4622 SET_FLAG(F_OF);
4623 }
4624 else {
4625 CLEAR_FLAG(F_CF);
4626 CLEAR_FLAG(F_OF);
4627 }
4628 *destreg = (u32) res_lo;
4629 }
4630 else {
4631 u16 *destreg;
4632 u16 srcval;
4633 u32 res;
4634 s16 imm;
4635
4636 destreg = DECODE_RM_WORD_REGISTER(rh);
4637 DECODE_PRINTF(",");
4638 srcoffset = decode_rm00_address(rl);
4639 srcval = fetch_data_word(srcoffset);
4640 imm = fetch_word_imm();
4641 DECODE_PRINTF2(",%d\n", (s32) imm);
4642 TRACE_AND_STEP();
4643 res = (s16) srcval *(s16) imm;
4644
4645 if (res > 0xFFFF) {
4646 SET_FLAG(F_CF);
4647 SET_FLAG(F_OF);
4648 }
4649 else {
4650 CLEAR_FLAG(F_CF);
4651 CLEAR_FLAG(F_OF);
4652 }
4653 *destreg = (u16) res;
4654 }
4655 break;
4656 case 1:
4657 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4658 u32 *destreg;
4659 u32 srcval;
4660 u32 res_lo, res_hi;
4661 s32 imm;
4662
4663 destreg = DECODE_RM_LONG_REGISTER(rh);
4664 DECODE_PRINTF(",");
4665 srcoffset = decode_rm01_address(rl);
4666 srcval = fetch_data_long(srcoffset);
4667 imm = fetch_long_imm();
4668 DECODE_PRINTF2(",%d\n", (s32) imm);
4669 TRACE_AND_STEP();
4670 imul_long_direct(&res_lo, &res_hi, (s32) srcval, (s32) imm);
4671 if (res_hi != 0) {
4672 SET_FLAG(F_CF);
4673 SET_FLAG(F_OF);
4674 }
4675 else {
4676 CLEAR_FLAG(F_CF);
4677 CLEAR_FLAG(F_OF);
4678 }
4679 *destreg = (u32) res_lo;
4680 }
4681 else {
4682 u16 *destreg;
4683 u16 srcval;
4684 u32 res;
4685 s16 imm;
4686
4687 destreg = DECODE_RM_WORD_REGISTER(rh);
4688 DECODE_PRINTF(",");
4689 srcoffset = decode_rm01_address(rl);
4690 srcval = fetch_data_word(srcoffset);
4691 imm = fetch_word_imm();
4692 DECODE_PRINTF2(",%d\n", (s32) imm);
4693 TRACE_AND_STEP();
4694 res = (s16) srcval *(s16) imm;
4695
4696 if (res > 0xFFFF) {
4697 SET_FLAG(F_CF);
4698 SET_FLAG(F_OF);
4699 }
4700 else {
4701 CLEAR_FLAG(F_CF);
4702 CLEAR_FLAG(F_OF);
4703 }
4704 *destreg = (u16) res;
4705 }
4706 break;
4707 case 2:
4708 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4709 u32 *destreg;
4710 u32 srcval;
4711 u32 res_lo, res_hi;
4712 s32 imm;
4713
4714 destreg = DECODE_RM_LONG_REGISTER(rh);
4715 DECODE_PRINTF(",");
4716 srcoffset = decode_rm10_address(rl);
4717 srcval = fetch_data_long(srcoffset);
4718 imm = fetch_long_imm();
4719 DECODE_PRINTF2(",%d\n", (s32) imm);
4720 TRACE_AND_STEP();
4721 imul_long_direct(&res_lo, &res_hi, (s32) srcval, (s32) imm);
4722 if (res_hi != 0) {
4723 SET_FLAG(F_CF);
4724 SET_FLAG(F_OF);
4725 }
4726 else {
4727 CLEAR_FLAG(F_CF);
4728 CLEAR_FLAG(F_OF);
4729 }
4730 *destreg = (u32) res_lo;
4731 }
4732 else {
4733 u16 *destreg;
4734 u16 srcval;
4735 u32 res;
4736 s16 imm;
4737
4738 destreg = DECODE_RM_WORD_REGISTER(rh);
4739 DECODE_PRINTF(",");
4740 srcoffset = decode_rm10_address(rl);
4741 srcval = fetch_data_word(srcoffset);
4742 imm = fetch_word_imm();
4743 DECODE_PRINTF2(",%d\n", (s32) imm);
4744 TRACE_AND_STEP();
4745 res = (s16) srcval *(s16) imm;
4746
4747 if (res > 0xFFFF) {
4748 SET_FLAG(F_CF);
4749 SET_FLAG(F_OF);
4750 }
4751 else {
4752 CLEAR_FLAG(F_CF);
4753 CLEAR_FLAG(F_OF);
4754 }
4755 *destreg = (u16) res;
4756 }
4757 break;
4758 case 3: /* register to register */
4759 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4760 u32 *destreg, *srcreg;
4761 u32 res_lo, res_hi;
4762 s32 imm;
4763
4764 destreg = DECODE_RM_LONG_REGISTER(rh);
4765 DECODE_PRINTF(",");
4766 srcreg = DECODE_RM_LONG_REGISTER(rl);
4767 imm = fetch_long_imm();
4768 DECODE_PRINTF2(",%d\n", (s32) imm);
4769 TRACE_AND_STEP();
4770 imul_long_direct(&res_lo, &res_hi, (s32) * srcreg, (s32) imm);
4771 if (res_hi != 0) {
4772 SET_FLAG(F_CF);
4773 SET_FLAG(F_OF);
4774 }
4775 else {
4776 CLEAR_FLAG(F_CF);
4777 CLEAR_FLAG(F_OF);
4778 }
4779 *destreg = (u32) res_lo;
4780 }
4781 else {
4782 u16 *destreg, *srcreg;
4783 u32 res;
4784 s16 imm;
4785
4786 destreg = DECODE_RM_WORD_REGISTER(rh);
4787 DECODE_PRINTF(",");
4788 srcreg = DECODE_RM_WORD_REGISTER(rl);
4789 imm = fetch_word_imm();
4790 DECODE_PRINTF2(",%d\n", (s32) imm);
4791 res = (s16) * srcreg * (s16) imm;
4792 if (res > 0xFFFF) {
4793 SET_FLAG(F_CF);
4794 SET_FLAG(F_OF);
4795 }
4796 else {
4797 CLEAR_FLAG(F_CF);
4798 CLEAR_FLAG(F_OF);
4799 }
4800 *destreg = (u16) res;
4801 }
4802 break;
4803 }
4804 DECODE_CLEAR_SEGOVR();
4805 END_OF_INSTR();
4806}
4807
4808/****************************************************************************
4809REMARKS:
4810Handles opcode 0x6a
4811****************************************************************************/
4812static void
4813x86emuOp_push_byte_IMM(u8 X86EMU_UNUSED(op1))
4814{
4815 s16 imm;
4816
4817 START_OF_INSTR();
4818 imm = (s8) fetch_byte_imm();
4819 DECODE_PRINTF2("PUSH\t%d\n", imm);
4820 TRACE_AND_STEP();
4821 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4822 push_long((s32) imm);
4823 }
4824 else {
4825 push_word(imm);
4826 }
4827 DECODE_CLEAR_SEGOVR();
4828 END_OF_INSTR();
4829}
4830
4831/****************************************************************************
4832REMARKS:
4833Handles opcode 0x6b
4834****************************************************************************/
4835static void
4836x86emuOp_imul_byte_IMM(u8 X86EMU_UNUSED(op1))
4837{
4838 int mod, rl, rh;
4839 uint srcoffset;
4840 s8 imm;
4841
4842 START_OF_INSTR();
4843 DECODE_PRINTF("IMUL\t");
4844 FETCH_DECODE_MODRM(mod, rh, rl);
4845 switch (mod) {
4846 case 0:
4847 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4848 u32 *destreg;
4849 u32 srcval;
4850 u32 res_lo, res_hi;
4851
4852 destreg = DECODE_RM_LONG_REGISTER(rh);
4853 DECODE_PRINTF(",");
4854 srcoffset = decode_rm00_address(rl);
4855 srcval = fetch_data_long(srcoffset);
4856 imm = fetch_byte_imm();
4857 DECODE_PRINTF2(",%d\n", (s32) imm);
4858 TRACE_AND_STEP();
4859 imul_long_direct(&res_lo, &res_hi, (s32) srcval, (s32) imm);
4860 if (res_hi != 0) {
4861 SET_FLAG(F_CF);
4862 SET_FLAG(F_OF);
4863 }
4864 else {
4865 CLEAR_FLAG(F_CF);
4866 CLEAR_FLAG(F_OF);
4867 }
4868 *destreg = (u32) res_lo;
4869 }
4870 else {
4871 u16 *destreg;
4872 u16 srcval;
4873 u32 res;
4874
4875 destreg = DECODE_RM_WORD_REGISTER(rh);
4876 DECODE_PRINTF(",");
4877 srcoffset = decode_rm00_address(rl);
4878 srcval = fetch_data_word(srcoffset);
4879 imm = fetch_byte_imm();
4880 DECODE_PRINTF2(",%d\n", (s32) imm);
4881 TRACE_AND_STEP();
4882 res = (s16) srcval *(s16) imm;
4883
4884 if (res > 0xFFFF) {
4885 SET_FLAG(F_CF);
4886 SET_FLAG(F_OF);
4887 }
4888 else {
4889 CLEAR_FLAG(F_CF);
4890 CLEAR_FLAG(F_OF);
4891 }
4892 *destreg = (u16) res;
4893 }
4894 break;
4895 case 1:
4896 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4897 u32 *destreg;
4898 u32 srcval;
4899 u32 res_lo, res_hi;
4900
4901 destreg = DECODE_RM_LONG_REGISTER(rh);
4902 DECODE_PRINTF(",");
4903 srcoffset = decode_rm01_address(rl);
4904 srcval = fetch_data_long(srcoffset);
4905 imm = fetch_byte_imm();
4906 DECODE_PRINTF2(",%d\n", (s32) imm);
4907 TRACE_AND_STEP();
4908 imul_long_direct(&res_lo, &res_hi, (s32) srcval, (s32) imm);
4909 if (res_hi != 0) {
4910 SET_FLAG(F_CF);
4911 SET_FLAG(F_OF);
4912 }
4913 else {
4914 CLEAR_FLAG(F_CF);
4915 CLEAR_FLAG(F_OF);
4916 }
4917 *destreg = (u32) res_lo;
4918 }
4919 else {
4920 u16 *destreg;
4921 u16 srcval;
4922 u32 res;
4923
4924 destreg = DECODE_RM_WORD_REGISTER(rh);
4925 DECODE_PRINTF(",");
4926 srcoffset = decode_rm01_address(rl);
4927 srcval = fetch_data_word(srcoffset);
4928 imm = fetch_byte_imm();
4929 DECODE_PRINTF2(",%d\n", (s32) imm);
4930 TRACE_AND_STEP();
4931 res = (s16) srcval *(s16) imm;
4932
4933 if (res > 0xFFFF) {
4934 SET_FLAG(F_CF);
4935 SET_FLAG(F_OF);
4936 }
4937 else {
4938 CLEAR_FLAG(F_CF);
4939 CLEAR_FLAG(F_OF);
4940 }
4941 *destreg = (u16) res;
4942 }
4943 break;
4944 case 2:
4945 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4946 u32 *destreg;
4947 u32 srcval;
4948 u32 res_lo, res_hi;
4949
4950 destreg = DECODE_RM_LONG_REGISTER(rh);
4951 DECODE_PRINTF(",");
4952 srcoffset = decode_rm10_address(rl);
4953 srcval = fetch_data_long(srcoffset);
4954 imm = fetch_byte_imm();
4955 DECODE_PRINTF2(",%d\n", (s32) imm);
4956 TRACE_AND_STEP();
4957 imul_long_direct(&res_lo, &res_hi, (s32) srcval, (s32) imm);
4958 if (res_hi != 0) {
4959 SET_FLAG(F_CF);
4960 SET_FLAG(F_OF);
4961 }
4962 else {
4963 CLEAR_FLAG(F_CF);
4964 CLEAR_FLAG(F_OF);
4965 }
4966 *destreg = (u32) res_lo;
4967 }
4968 else {
4969 u16 *destreg;
4970 u16 srcval;
4971 u32 res;
4972
4973 destreg = DECODE_RM_WORD_REGISTER(rh);
4974 DECODE_PRINTF(",");
4975 srcoffset = decode_rm10_address(rl);
4976 srcval = fetch_data_word(srcoffset);
4977 imm = fetch_byte_imm();
4978 DECODE_PRINTF2(",%d\n", (s32) imm);
4979 TRACE_AND_STEP();
4980 res = (s16) srcval *(s16) imm;
4981
4982 if (res > 0xFFFF) {
4983 SET_FLAG(F_CF);
4984 SET_FLAG(F_OF);
4985 }
4986 else {
4987 CLEAR_FLAG(F_CF);
4988 CLEAR_FLAG(F_OF);
4989 }
4990 *destreg = (u16) res;
4991 }
4992 break;
4993 case 3: /* register to register */
4994 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4995 u32 *destreg, *srcreg;
4996 u32 res_lo, res_hi;
4997
4998 destreg = DECODE_RM_LONG_REGISTER(rh);
4999 DECODE_PRINTF(",");
5000 srcreg = DECODE_RM_LONG_REGISTER(rl);
5001 imm = fetch_byte_imm();
5002 DECODE_PRINTF2(",%d\n", (s32) imm);
5003 TRACE_AND_STEP();
5004 imul_long_direct(&res_lo, &res_hi, (s32) * srcreg, (s32) imm);
5005 if (res_hi != 0) {
5006 SET_FLAG(F_CF);
5007 SET_FLAG(F_OF);
5008 }
5009 else {
5010 CLEAR_FLAG(F_CF);
5011 CLEAR_FLAG(F_OF);
5012 }
5013 *destreg = (u32) res_lo;
5014 }
5015 else {
5016 u16 *destreg, *srcreg;
5017 u32 res;
5018
5019 destreg = DECODE_RM_WORD_REGISTER(rh);
5020 DECODE_PRINTF(",");
5021 srcreg = DECODE_RM_WORD_REGISTER(rl);
5022 imm = fetch_byte_imm();
5023 DECODE_PRINTF2(",%d\n", (s32) imm);
5024 res = (s16) * srcreg * (s16) imm;
5025 if (res > 0xFFFF) {
5026 SET_FLAG(F_CF);
5027 SET_FLAG(F_OF);
5028 }
5029 else {
5030 CLEAR_FLAG(F_CF);
5031 CLEAR_FLAG(F_OF);
5032 }
5033 *destreg = (u16) res;
5034 }
5035 break;
5036 }
5037 DECODE_CLEAR_SEGOVR();
5038 END_OF_INSTR();
5039}
5040
5041/****************************************************************************
5042REMARKS:
5043Handles opcode 0x6c
5044****************************************************************************/
5045static void
5046x86emuOp_ins_byte(u8 X86EMU_UNUSED(op1))
5047{
5048 START_OF_INSTR();
5049 DECODE_PRINTF("INSB\n");
5050 ins(1);
5051 TRACE_AND_STEP();
5052 DECODE_CLEAR_SEGOVR();
5053 END_OF_INSTR();
5054}
5055
5056/****************************************************************************
5057REMARKS:
5058Handles opcode 0x6d
5059****************************************************************************/
5060static void
5061x86emuOp_ins_word(u8 X86EMU_UNUSED(op1))
5062{
5063 START_OF_INSTR();
5064 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5065 DECODE_PRINTF("INSD\n");
5066 ins(4);
5067 }
5068 else {
5069 DECODE_PRINTF("INSW\n");
5070 ins(2);
5071 }
5072 TRACE_AND_STEP();
5073 DECODE_CLEAR_SEGOVR();
5074 END_OF_INSTR();
5075}
5076
5077/****************************************************************************
5078REMARKS:
5079Handles opcode 0x6e
5080****************************************************************************/
5081static void
5082x86emuOp_outs_byte(u8 X86EMU_UNUSED(op1))
5083{
5084 START_OF_INSTR();
5085 DECODE_PRINTF("OUTSB\n");
5086 outs(1);
5087 TRACE_AND_STEP();
5088 DECODE_CLEAR_SEGOVR();
5089 END_OF_INSTR();
5090}
5091
5092/****************************************************************************
5093REMARKS:
5094Handles opcode 0x6f
5095****************************************************************************/
5096static void
5097x86emuOp_outs_word(u8 X86EMU_UNUSED(op1))
5098{
5099 START_OF_INSTR();
5100 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5101 DECODE_PRINTF("OUTSD\n");
5102 outs(4);
5103 }
5104 else {
5105 DECODE_PRINTF("OUTSW\n");
5106 outs(2);
5107 }
5108 TRACE_AND_STEP();
5109 DECODE_CLEAR_SEGOVR();
5110 END_OF_INSTR();
5111}
5112
5113/****************************************************************************
5114REMARKS:
5115Handles opcode 0x70
5116****************************************************************************/
5117static void
5118x86emuOp_jump_near_O(u8 X86EMU_UNUSED(op1))
5119{
5120 s8 offset;
5121 u16 target;
5122
5123 /* jump to byte offset if overflow flag is set */
5124 START_OF_INSTR();
5125 DECODE_PRINTF("JO\t");
5126 offset = (s8) fetch_byte_imm();
5127 target = (u16) (M.x86.R_IP + (s16) offset);
5128 DECODE_PRINTF2("%x\n", target);
5129 TRACE_AND_STEP();
5130 if (ACCESS_FLAG(F_OF))
5131 M.x86.R_IP = target;
5132 DECODE_CLEAR_SEGOVR();
5133 END_OF_INSTR();
5134}
5135
5136/****************************************************************************
5137REMARKS:
5138Handles opcode 0x71
5139****************************************************************************/
5140static void
5141x86emuOp_jump_near_NO(u8 X86EMU_UNUSED(op1))
5142{
5143 s8 offset;
5144 u16 target;
5145
5146 /* jump to byte offset if overflow is not set */
5147 START_OF_INSTR();
5148 DECODE_PRINTF("JNO\t");
5149 offset = (s8) fetch_byte_imm();
5150 target = (u16) (M.x86.R_IP + (s16) offset);
5151 DECODE_PRINTF2("%x\n", target);
5152 TRACE_AND_STEP();
5153 if (!ACCESS_FLAG(F_OF))
5154 M.x86.R_IP = target;
5155 DECODE_CLEAR_SEGOVR();
5156 END_OF_INSTR();
5157}
5158
5159/****************************************************************************
5160REMARKS:
5161Handles opcode 0x72
5162****************************************************************************/
5163static void
5164x86emuOp_jump_near_B(u8 X86EMU_UNUSED(op1))
5165{
5166 s8 offset;
5167 u16 target;
5168
5169 /* jump to byte offset if carry flag is set. */
5170 START_OF_INSTR();
5171 DECODE_PRINTF("JB\t");
5172 offset = (s8) fetch_byte_imm();
5173 target = (u16) (M.x86.R_IP + (s16) offset);
5174 DECODE_PRINTF2("%x\n", target);
5175 TRACE_AND_STEP();
5176 if (ACCESS_FLAG(F_CF))
5177 M.x86.R_IP = target;
5178 DECODE_CLEAR_SEGOVR();
5179 END_OF_INSTR();
5180}
5181
5182/****************************************************************************
5183REMARKS:
5184Handles opcode 0x73
5185****************************************************************************/
5186static void
5187x86emuOp_jump_near_NB(u8 X86EMU_UNUSED(op1))
5188{
5189 s8 offset;
5190 u16 target;
5191
5192 /* jump to byte offset if carry flag is clear. */
5193 START_OF_INSTR();
5194 DECODE_PRINTF("JNB\t");
5195 offset = (s8) fetch_byte_imm();
5196 target = (u16) (M.x86.R_IP + (s16) offset);
5197 DECODE_PRINTF2("%x\n", target);
5198 TRACE_AND_STEP();
5199 if (!ACCESS_FLAG(F_CF))
5200 M.x86.R_IP = target;
5201 DECODE_CLEAR_SEGOVR();
5202 END_OF_INSTR();
5203}
5204
5205/****************************************************************************
5206REMARKS:
5207Handles opcode 0x74
5208****************************************************************************/
5209static void
5210x86emuOp_jump_near_Z(u8 X86EMU_UNUSED(op1))
5211{
5212 s8 offset;
5213 u16 target;
5214
5215 /* jump to byte offset if zero flag is set. */
5216 START_OF_INSTR();
5217 DECODE_PRINTF("JZ\t");
5218 offset = (s8) fetch_byte_imm();
5219 target = (u16) (M.x86.R_IP + (s16) offset);
5220 DECODE_PRINTF2("%x\n", target);
5221 TRACE_AND_STEP();
5222 if (ACCESS_FLAG(F_ZF))
5223 M.x86.R_IP = target;
5224 DECODE_CLEAR_SEGOVR();
5225 END_OF_INSTR();
5226}
5227
5228/****************************************************************************
5229REMARKS:
5230Handles opcode 0x75
5231****************************************************************************/
5232static void
5233x86emuOp_jump_near_NZ(u8 X86EMU_UNUSED(op1))
5234{
5235 s8 offset;
5236 u16 target;
5237
5238 /* jump to byte offset if zero flag is clear. */
5239 START_OF_INSTR();
5240 DECODE_PRINTF("JNZ\t");
5241 offset = (s8) fetch_byte_imm();
5242 target = (u16) (M.x86.R_IP + (s16) offset);
5243 DECODE_PRINTF2("%x\n", target);
5244 TRACE_AND_STEP();
5245 if (!ACCESS_FLAG(F_ZF))
5246 M.x86.R_IP = target;
5247 DECODE_CLEAR_SEGOVR();
5248 END_OF_INSTR();
5249}
5250
5251/****************************************************************************
5252REMARKS:
5253Handles opcode 0x76
5254****************************************************************************/
5255static void
5256x86emuOp_jump_near_BE(u8 X86EMU_UNUSED(op1))
5257{
5258 s8 offset;
5259 u16 target;
5260
5261 /* jump to byte offset if carry flag is set or if the zero
5262 flag is set. */
5263 START_OF_INSTR();
5264 DECODE_PRINTF("JBE\t");
5265 offset = (s8) fetch_byte_imm();
5266 target = (u16) (M.x86.R_IP + (s16) offset);
5267 DECODE_PRINTF2("%x\n", target);
5268 TRACE_AND_STEP();
5269 if (ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF))
5270 M.x86.R_IP = target;
5271 DECODE_CLEAR_SEGOVR();
5272 END_OF_INSTR();
5273}
5274
5275/****************************************************************************
5276REMARKS:
5277Handles opcode 0x77
5278****************************************************************************/
5279static void
5280x86emuOp_jump_near_NBE(u8 X86EMU_UNUSED(op1))
5281{
5282 s8 offset;
5283 u16 target;
5284
5285 /* jump to byte offset if carry flag is clear and if the zero
5286 flag is clear */
5287 START_OF_INSTR();
5288 DECODE_PRINTF("JNBE\t");
5289 offset = (s8) fetch_byte_imm();
5290 target = (u16) (M.x86.R_IP + (s16) offset);
5291 DECODE_PRINTF2("%x\n", target);
5292 TRACE_AND_STEP();
5293 if (!(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF)))
5294 M.x86.R_IP = target;
5295 DECODE_CLEAR_SEGOVR();
5296 END_OF_INSTR();
5297}
5298
5299/****************************************************************************
5300REMARKS:
5301Handles opcode 0x78
5302****************************************************************************/
5303static void
5304x86emuOp_jump_near_S(u8 X86EMU_UNUSED(op1))
5305{
5306 s8 offset;
5307 u16 target;
5308
5309 /* jump to byte offset if sign flag is set */
5310 START_OF_INSTR();
5311 DECODE_PRINTF("JS\t");
5312 offset = (s8) fetch_byte_imm();
5313 target = (u16) (M.x86.R_IP + (s16) offset);
5314 DECODE_PRINTF2("%x\n", target);
5315 TRACE_AND_STEP();
5316 if (ACCESS_FLAG(F_SF))
5317 M.x86.R_IP = target;
5318 DECODE_CLEAR_SEGOVR();
5319 END_OF_INSTR();
5320}
5321
5322/****************************************************************************
5323REMARKS:
5324Handles opcode 0x79
5325****************************************************************************/
5326static void
5327x86emuOp_jump_near_NS(u8 X86EMU_UNUSED(op1))
5328{
5329 s8 offset;
5330 u16 target;
5331
5332 /* jump to byte offset if sign flag is clear */
5333 START_OF_INSTR();
5334 DECODE_PRINTF("JNS\t");
5335 offset = (s8) fetch_byte_imm();
5336 target = (u16) (M.x86.R_IP + (s16) offset);
5337 DECODE_PRINTF2("%x\n", target);
5338 TRACE_AND_STEP();
5339 if (!ACCESS_FLAG(F_SF))
5340 M.x86.R_IP = target;
5341 DECODE_CLEAR_SEGOVR();
5342 END_OF_INSTR();
5343}
5344
5345/****************************************************************************
5346REMARKS:
5347Handles opcode 0x7a
5348****************************************************************************/
5349static void
5350x86emuOp_jump_near_P(u8 X86EMU_UNUSED(op1))
5351{
5352 s8 offset;
5353 u16 target;
5354
5355 /* jump to byte offset if parity flag is set (even parity) */
5356 START_OF_INSTR();
5357 DECODE_PRINTF("JP\t");
5358 offset = (s8) fetch_byte_imm();
5359 target = (u16) (M.x86.R_IP + (s16) offset);
5360 DECODE_PRINTF2("%x\n", target);
5361 TRACE_AND_STEP();
5362 if (ACCESS_FLAG(F_PF))
5363 M.x86.R_IP = target;
5364 DECODE_CLEAR_SEGOVR();
5365 END_OF_INSTR();
5366}
5367
5368/****************************************************************************
5369REMARKS:
5370Handles opcode 0x7b
5371****************************************************************************/
5372static void
5373x86emuOp_jump_near_NP(u8 X86EMU_UNUSED(op1))
5374{
5375 s8 offset;
5376 u16 target;
5377
5378 /* jump to byte offset if parity flag is clear (odd parity) */
5379 START_OF_INSTR();
5380 DECODE_PRINTF("JNP\t");
5381 offset = (s8) fetch_byte_imm();
5382 target = (u16) (M.x86.R_IP + (s16) offset);
5383 DECODE_PRINTF2("%x\n", target);
5384 TRACE_AND_STEP();
5385 if (!ACCESS_FLAG(F_PF))
5386 M.x86.R_IP = target;
5387 DECODE_CLEAR_SEGOVR();
5388 END_OF_INSTR();
5389}
5390
5391/****************************************************************************
5392REMARKS:
5393Handles opcode 0x7c
5394****************************************************************************/
5395static void
5396x86emuOp_jump_near_L(u8 X86EMU_UNUSED(op1))
5397{
5398 s8 offset;
5399 u16 target;
5400 int sf, of;
5401
5402 /* jump to byte offset if sign flag not equal to overflow flag. */
5403 START_OF_INSTR();
5404 DECODE_PRINTF("JL\t");
5405 offset = (s8) fetch_byte_imm();
5406 target = (u16) (M.x86.R_IP + (s16) offset);
5407 DECODE_PRINTF2("%x\n", target);
5408 TRACE_AND_STEP();
5409 sf = ACCESS_FLAG(F_SF) != 0;
5410 of = ACCESS_FLAG(F_OF) != 0;
5411 if (sf ^ of)
5412 M.x86.R_IP = target;
5413 DECODE_CLEAR_SEGOVR();
5414 END_OF_INSTR();
5415}
5416
5417/****************************************************************************
5418REMARKS:
5419Handles opcode 0x7d
5420****************************************************************************/
5421static void
5422x86emuOp_jump_near_NL(u8 X86EMU_UNUSED(op1))
5423{
5424 s8 offset;
5425 u16 target;
5426 int sf, of;
5427
5428 /* jump to byte offset if sign flag not equal to overflow flag. */
5429 START_OF_INSTR();
5430 DECODE_PRINTF("JNL\t");
5431 offset = (s8) fetch_byte_imm();
5432 target = (u16) (M.x86.R_IP + (s16) offset);
5433 DECODE_PRINTF2("%x\n", target);
5434 TRACE_AND_STEP();
5435 sf = ACCESS_FLAG(F_SF) != 0;
5436 of = ACCESS_FLAG(F_OF) != 0;
5437 /* note: inverse of above, but using == instead of xor. */
5438 if (sf == of)
5439 M.x86.R_IP = target;
5440 DECODE_CLEAR_SEGOVR();
5441 END_OF_INSTR();
5442}
5443
5444/****************************************************************************
5445REMARKS:
5446Handles opcode 0x7e
5447****************************************************************************/
5448static void
5449x86emuOp_jump_near_LE(u8 X86EMU_UNUSED(op1))
5450{
5451 s8 offset;
5452 u16 target;
5453 int sf, of;
5454
5455 /* jump to byte offset if sign flag not equal to overflow flag
5456 or the zero flag is set */
5457 START_OF_INSTR();
5458 DECODE_PRINTF("JLE\t");
5459 offset = (s8) fetch_byte_imm();
5460 target = (u16) (M.x86.R_IP + (s16) offset);
5461 DECODE_PRINTF2("%x\n", target);
5462 TRACE_AND_STEP();
5463 sf = ACCESS_FLAG(F_SF) != 0;
5464 of = ACCESS_FLAG(F_OF) != 0;
5465 if ((sf ^ of) || ACCESS_FLAG(F_ZF))
5466 M.x86.R_IP = target;
5467 DECODE_CLEAR_SEGOVR();
5468 END_OF_INSTR();
5469}
5470
5471/****************************************************************************
5472REMARKS:
5473Handles opcode 0x7f
5474****************************************************************************/
5475static void
5476x86emuOp_jump_near_NLE(u8 X86EMU_UNUSED(op1))
5477{
5478 s8 offset;
5479 u16 target;
5480 int sf, of;
5481
5482 /* jump to byte offset if sign flag equal to overflow flag.
5483 and the zero flag is clear */
5484 START_OF_INSTR();
5485 DECODE_PRINTF("JNLE\t");
5486 offset = (s8) fetch_byte_imm();
5487 target = (u16) (M.x86.R_IP + (s16) offset);
5488 DECODE_PRINTF2("%x\n", target);
5489 TRACE_AND_STEP();
5490 sf = ACCESS_FLAG(F_SF) != 0;
5491 of = ACCESS_FLAG(F_OF) != 0;
5492 if ((sf == of) && !ACCESS_FLAG(F_ZF))
5493 M.x86.R_IP = target;
5494 DECODE_CLEAR_SEGOVR();
5495 END_OF_INSTR();
5496}
5497
5498static u8(*opc80_byte_operation[]) (u8 d, u8 s) = {
5499 add_byte, /* 00 */
5500 or_byte, /* 01 */
5501 adc_byte, /* 02 */
5502 sbb_byte, /* 03 */
5503 and_byte, /* 04 */
5504 sub_byte, /* 05 */
5505 xor_byte, /* 06 */
5506 cmp_byte, /* 07 */
5507};
5508
5509/****************************************************************************
5510REMARKS:
5511Handles opcode 0x80
5512****************************************************************************/
5513static void
5514x86emuOp_opc80_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
5515{
5516 int mod, rl, rh;
5517 u8 *destreg;
5518 uint destoffset;
5519 u8 imm;
5520 u8 destval;
5521
5522 /*
5523 * Weirdo special case instruction format. Part of the opcode
5524 * held below in "RH". Doubly nested case would result, except
5525 * that the decoded instruction
5526 */
5527 START_OF_INSTR();
5528 FETCH_DECODE_MODRM(mod, rh, rl);
5529#ifdef DEBUG
5530 if (DEBUG_DECODE()) {
5531 /* XXX DECODE_PRINTF may be changed to something more
5532 general, so that it is important to leave the strings
5533 in the same format, even though the result is that the
5534 above test is done twice. */
5535
5536 switch (rh) {
5537 case 0:
5538 DECODE_PRINTF("ADD\t");
5539 break;
5540 case 1:
5541 DECODE_PRINTF("OR\t");
5542 break;
5543 case 2:
5544 DECODE_PRINTF("ADC\t");
5545 break;
5546 case 3:
5547 DECODE_PRINTF("SBB\t");
5548 break;
5549 case 4:
5550 DECODE_PRINTF("AND\t");
5551 break;
5552 case 5:
5553 DECODE_PRINTF("SUB\t");
5554 break;
5555 case 6:
5556 DECODE_PRINTF("XOR\t");
5557 break;
5558 case 7:
5559 DECODE_PRINTF("CMP\t");
5560 break;
5561 }
5562 }
5563#endif
5564 /* know operation, decode the mod byte to find the addressing
5565 mode. */
5566 switch (mod) {
5567 case 0:
5568 DECODE_PRINTF("BYTE PTR ");
5569 destoffset = decode_rm00_address(rl);
5570 DECODE_PRINTF(",");
5571 destval = fetch_data_byte(destoffset);
5572 imm = fetch_byte_imm();
5573 DECODE_PRINTF2("%x\n", imm);
5574 TRACE_AND_STEP();
5575 destval = (*opc80_byte_operation[rh]) (destval, imm);
5576 if (rh != 7)
5577 store_data_byte(destoffset, destval);
5578 break;
5579 case 1:
5580 DECODE_PRINTF("BYTE PTR ");
5581 destoffset = decode_rm01_address(rl);
5582 DECODE_PRINTF(",");
5583 destval = fetch_data_byte(destoffset);
5584 imm = fetch_byte_imm();
5585 DECODE_PRINTF2("%x\n", imm);
5586 TRACE_AND_STEP();
5587 destval = (*opc80_byte_operation[rh]) (destval, imm);
5588 if (rh != 7)
5589 store_data_byte(destoffset, destval);
5590 break;
5591 case 2:
5592 DECODE_PRINTF("BYTE PTR ");
5593 destoffset = decode_rm10_address(rl);
5594 DECODE_PRINTF(",");
5595 destval = fetch_data_byte(destoffset);
5596 imm = fetch_byte_imm();
5597 DECODE_PRINTF2("%x\n", imm);
5598 TRACE_AND_STEP();
5599 destval = (*opc80_byte_operation[rh]) (destval, imm);
5600 if (rh != 7)
5601 store_data_byte(destoffset, destval);
5602 break;
5603 case 3: /* register to register */
5604 destreg = DECODE_RM_BYTE_REGISTER(rl);
5605 DECODE_PRINTF(",");
5606 imm = fetch_byte_imm();
5607 DECODE_PRINTF2("%x\n", imm);
5608 TRACE_AND_STEP();
5609 destval = (*opc80_byte_operation[rh]) (*destreg, imm);
5610 if (rh != 7)
5611 *destreg = destval;
5612 break;
5613 }
5614 DECODE_CLEAR_SEGOVR();
5615 END_OF_INSTR();
5616}
5617
5618static u16(*opc81_word_operation[]) (u16 d, u16 s) = {
5619 add_word, /*00 */
5620 or_word, /*01 */
5621 adc_word, /*02 */
5622 sbb_word, /*03 */
5623 and_word, /*04 */
5624 sub_word, /*05 */
5625 xor_word, /*06 */
5626 cmp_word, /*07 */
5627};
5628
5629static u32(*opc81_long_operation[]) (u32 d, u32 s) = {
5630 add_long, /*00 */
5631 or_long, /*01 */
5632 adc_long, /*02 */
5633 sbb_long, /*03 */
5634 and_long, /*04 */
5635 sub_long, /*05 */
5636 xor_long, /*06 */
5637 cmp_long, /*07 */
5638};
5639
5640/****************************************************************************
5641REMARKS:
5642Handles opcode 0x81
5643****************************************************************************/
5644static void
5645x86emuOp_opc81_word_RM_IMM(u8 X86EMU_UNUSED(op1))
5646{
5647 int mod, rl, rh;
5648 uint destoffset;
5649
5650 /*
5651 * Weirdo special case instruction format. Part of the opcode
5652 * held below in "RH". Doubly nested case would result, except
5653 * that the decoded instruction
5654 */
5655 START_OF_INSTR();
5656 FETCH_DECODE_MODRM(mod, rh, rl);
5657#ifdef DEBUG
5658 if (DEBUG_DECODE()) {
5659 /* XXX DECODE_PRINTF may be changed to something more
5660 general, so that it is important to leave the strings
5661 in the same format, even though the result is that the
5662 above test is done twice. */
5663
5664 switch (rh) {
5665 case 0:
5666 DECODE_PRINTF("ADD\t");
5667 break;
5668 case 1:
5669 DECODE_PRINTF("OR\t");
5670 break;
5671 case 2:
5672 DECODE_PRINTF("ADC\t");
5673 break;
5674 case 3:
5675 DECODE_PRINTF("SBB\t");
5676 break;
5677 case 4:
5678 DECODE_PRINTF("AND\t");
5679 break;
5680 case 5:
5681 DECODE_PRINTF("SUB\t");
5682 break;
5683 case 6:
5684 DECODE_PRINTF("XOR\t");
5685 break;
5686 case 7:
5687 DECODE_PRINTF("CMP\t");
5688 break;
5689 }
5690 }
5691#endif
5692 /*
5693 * Know operation, decode the mod byte to find the addressing
5694 * mode.
5695 */
5696 switch (mod) {
5697 case 0:
5698 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5699 u32 destval, imm;
5700
5701 DECODE_PRINTF("DWORD PTR ");
5702 destoffset = decode_rm00_address(rl);
5703 DECODE_PRINTF(",");
5704 destval = fetch_data_long(destoffset);
5705 imm = fetch_long_imm();
5706 DECODE_PRINTF2("%x\n", imm);
5707 TRACE_AND_STEP();
5708 destval = (*opc81_long_operation[rh]) (destval, imm);
5709 if (rh != 7)
5710 store_data_long(destoffset, destval);
5711 }
5712 else {
5713 u16 destval, imm;
5714
5715 DECODE_PRINTF("WORD PTR ");
5716 destoffset = decode_rm00_address(rl);
5717 DECODE_PRINTF(",");
5718 destval = fetch_data_word(destoffset);
5719 imm = fetch_word_imm();
5720 DECODE_PRINTF2("%x\n", imm);
5721 TRACE_AND_STEP();
5722 destval = (*opc81_word_operation[rh]) (destval, imm);
5723 if (rh != 7)
5724 store_data_word(destoffset, destval);
5725 }
5726 break;
5727 case 1:
5728 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5729 u32 destval, imm;
5730
5731 DECODE_PRINTF("DWORD PTR ");
5732 destoffset = decode_rm01_address(rl);
5733 DECODE_PRINTF(",");
5734 destval = fetch_data_long(destoffset);
5735 imm = fetch_long_imm();
5736 DECODE_PRINTF2("%x\n", imm);
5737 TRACE_AND_STEP();
5738 destval = (*opc81_long_operation[rh]) (destval, imm);
5739 if (rh != 7)
5740 store_data_long(destoffset, destval);
5741 }
5742 else {
5743 u16 destval, imm;
5744
5745 DECODE_PRINTF("WORD PTR ");
5746 destoffset = decode_rm01_address(rl);
5747 DECODE_PRINTF(",");
5748 destval = fetch_data_word(destoffset);
5749 imm = fetch_word_imm();
5750 DECODE_PRINTF2("%x\n", imm);
5751 TRACE_AND_STEP();
5752 destval = (*opc81_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 DECODE_PRINTF(",");
5764 destval = fetch_data_long(destoffset);
5765 imm = fetch_long_imm();
5766 DECODE_PRINTF2("%x\n", imm);
5767 TRACE_AND_STEP();
5768 destval = (*opc81_long_operation[rh]) (destval, imm);
5769 if (rh != 7)
5770 store_data_long(destoffset, destval);
5771 }
5772 else {
5773 u16 destval, imm;
5774
5775 DECODE_PRINTF("WORD PTR ");
5776 destoffset = decode_rm10_address(rl);
5777 DECODE_PRINTF(",");
5778 destval = fetch_data_word(destoffset);
5779 imm = fetch_word_imm();
5780 DECODE_PRINTF2("%x\n", imm);
5781 TRACE_AND_STEP();
5782 destval = (*opc81_word_operation[rh]) (destval, imm);
5783 if (rh != 7)
5784 store_data_word(destoffset, destval);
5785 }
5786 break;
5787 case 3: /* register to register */
5788 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5789 u32 *destreg;
5790 u32 destval, imm;
5791
5792 destreg = DECODE_RM_LONG_REGISTER(rl);
5793 DECODE_PRINTF(",");
5794 imm = fetch_long_imm();
5795 DECODE_PRINTF2("%x\n", imm);
5796 TRACE_AND_STEP();
5797 destval = (*opc81_long_operation[rh]) (*destreg, imm);
5798 if (rh != 7)
5799 *destreg = destval;
5800 }
5801 else {
5802 u16 *destreg;
5803 u16 destval, imm;
5804
5805 destreg = DECODE_RM_WORD_REGISTER(rl);
5806 DECODE_PRINTF(",");
5807 imm = fetch_word_imm();
5808 DECODE_PRINTF2("%x\n", imm);
5809 TRACE_AND_STEP();
5810 destval = (*opc81_word_operation[rh]) (*destreg, imm);
5811 if (rh != 7)
5812 *destreg = destval;
5813 }
5814 break;
5815 }
5816 DECODE_CLEAR_SEGOVR();
5817 END_OF_INSTR();
5818}
5819
5820static u8(*opc82_byte_operation[]) (u8 s, u8 d) = {
5821 add_byte, /*00 */
5822 or_byte, /*01 *//*YYY UNUSED ???? */
5823 adc_byte, /*02 */
5824 sbb_byte, /*03 */
5825 and_byte, /*04 *//*YYY UNUSED ???? */
5826 sub_byte, /*05 */
5827 xor_byte, /*06 *//*YYY UNUSED ???? */
5828 cmp_byte, /*07 */
5829};
5830
5831/****************************************************************************
5832REMARKS:
5833Handles opcode 0x82
5834****************************************************************************/
5835static void
5836x86emuOp_opc82_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
5837{
5838 int mod, rl, rh;
5839 u8 *destreg;
5840 uint destoffset;
5841 u8 imm;
5842 u8 destval;
5843
5844 /*
5845 * Weirdo special case instruction format. Part of the opcode
5846 * held below in "RH". Doubly nested case would result, except
5847 * that the decoded instruction Similar to opcode 81, except that
5848 * the immediate byte is sign extended to a word length.
5849 */
5850 START_OF_INSTR();
5851 FETCH_DECODE_MODRM(mod, rh, rl);
5852#ifdef DEBUG
5853 if (DEBUG_DECODE()) {
5854 /* XXX DECODE_PRINTF may be changed to something more
5855 general, so that it is important to leave the strings
5856 in the same format, even though the result is that the
5857 above test is done twice. */
5858 switch (rh) {
5859 case 0:
5860 DECODE_PRINTF("ADD\t");
5861 break;
5862 case 1:
5863 DECODE_PRINTF("OR\t");
5864 break;
5865 case 2:
5866 DECODE_PRINTF("ADC\t");
5867 break;
5868 case 3:
5869 DECODE_PRINTF("SBB\t");
5870 break;
5871 case 4:
5872 DECODE_PRINTF("AND\t");
5873 break;
5874 case 5:
5875 DECODE_PRINTF("SUB\t");
5876 break;
5877 case 6:
5878 DECODE_PRINTF("XOR\t");
5879 break;
5880 case 7:
5881 DECODE_PRINTF("CMP\t");
5882 break;
5883 }
5884 }
5885#endif
5886 /* know operation, decode the mod byte to find the addressing
5887 mode. */
5888 switch (mod) {
5889 case 0:
5890 DECODE_PRINTF("BYTE PTR ");
5891 destoffset = decode_rm00_address(rl);
5892 destval = fetch_data_byte(destoffset);
5893 imm = fetch_byte_imm();
5894 DECODE_PRINTF2(",%x\n", imm);
5895 TRACE_AND_STEP();
5896 destval = (*opc82_byte_operation[rh]) (destval, imm);
5897 if (rh != 7)
5898 store_data_byte(destoffset, destval);
5899 break;
5900 case 1:
5901 DECODE_PRINTF("BYTE PTR ");
5902 destoffset = decode_rm01_address(rl);
5903 destval = fetch_data_byte(destoffset);
5904 imm = fetch_byte_imm();
5905 DECODE_PRINTF2(",%x\n", imm);
5906 TRACE_AND_STEP();
5907 destval = (*opc82_byte_operation[rh]) (destval, imm);
5908 if (rh != 7)
5909 store_data_byte(destoffset, destval);
5910 break;
5911 case 2:
5912 DECODE_PRINTF("BYTE PTR ");
5913 destoffset = decode_rm10_address(rl);
5914 destval = fetch_data_byte(destoffset);
5915 imm = fetch_byte_imm();
5916 DECODE_PRINTF2(",%x\n", imm);
5917 TRACE_AND_STEP();
5918 destval = (*opc82_byte_operation[rh]) (destval, imm);
5919 if (rh != 7)
5920 store_data_byte(destoffset, destval);
5921 break;
5922 case 3: /* register to register */
5923 destreg = DECODE_RM_BYTE_REGISTER(rl);
5924 imm = fetch_byte_imm();
5925 DECODE_PRINTF2(",%x\n", imm);
5926 TRACE_AND_STEP();
5927 destval = (*opc82_byte_operation[rh]) (*destreg, imm);
5928 if (rh != 7)
5929 *destreg = destval;
5930 break;
5931 }
5932 DECODE_CLEAR_SEGOVR();
5933 END_OF_INSTR();
5934}
5935
5936static u16(*opc83_word_operation[]) (u16 s, u16 d) = {
5937 add_word, /*00 */
5938 or_word, /*01 *//*YYY UNUSED ???? */
5939 adc_word, /*02 */
5940 sbb_word, /*03 */
5941 and_word, /*04 *//*YYY UNUSED ???? */
5942 sub_word, /*05 */
5943 xor_word, /*06 *//*YYY UNUSED ???? */
5944 cmp_word, /*07 */
5945};
5946
5947static u32(*opc83_long_operation[]) (u32 s, u32 d) = {
5948 add_long, /*00 */
5949 or_long, /*01 *//*YYY UNUSED ???? */
5950 adc_long, /*02 */
5951 sbb_long, /*03 */
5952 and_long, /*04 *//*YYY UNUSED ???? */
5953 sub_long, /*05 */
5954 xor_long, /*06 *//*YYY UNUSED ???? */
5955 cmp_long, /*07 */
5956};
5957
5958/****************************************************************************
5959REMARKS:
5960Handles opcode 0x83
5961****************************************************************************/
5962static void
5963x86emuOp_opc83_word_RM_IMM(u8 X86EMU_UNUSED(op1))
5964{
5965 int mod, rl, rh;
5966 uint destoffset;
5967
5968 /*
5969 * Weirdo special case instruction format. Part of the opcode
5970 * held below in "RH". Doubly nested case would result, except
5971 * that the decoded instruction Similar to opcode 81, except that
5972 * the immediate byte is sign extended to a word length.
5973 */
5974 START_OF_INSTR();
5975 FETCH_DECODE_MODRM(mod, rh, rl);
5976#ifdef DEBUG
5977 if (DEBUG_DECODE()) {
5978 /* XXX DECODE_PRINTF may be changed to something more
5979 general, so that it is important to leave the strings
5980 in the same format, even though the result is that the
5981 above test is done twice. */
5982 switch (rh) {
5983 case 0:
5984 DECODE_PRINTF("ADD\t");
5985 break;
5986 case 1:
5987 DECODE_PRINTF("OR\t");
5988 break;
5989 case 2:
5990 DECODE_PRINTF("ADC\t");
5991 break;
5992 case 3:
5993 DECODE_PRINTF("SBB\t");
5994 break;
5995 case 4:
5996 DECODE_PRINTF("AND\t");
5997 break;
5998 case 5:
5999 DECODE_PRINTF("SUB\t");
6000 break;
6001 case 6:
6002 DECODE_PRINTF("XOR\t");
6003 break;
6004 case 7:
6005 DECODE_PRINTF("CMP\t");
6006 break;
6007 }
6008 }
6009#endif
6010 /* know operation, decode the mod byte to find the addressing
6011 mode. */
6012 switch (mod) {
6013 case 0:
6014 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6015 u32 destval, imm;
6016
6017 DECODE_PRINTF("DWORD PTR ");
6018 destoffset = decode_rm00_address(rl);
6019 destval = fetch_data_long(destoffset);
6020 imm = (s8) fetch_byte_imm();
6021 DECODE_PRINTF2(",%x\n", imm);
6022 TRACE_AND_STEP();
6023 destval = (*opc83_long_operation[rh]) (destval, imm);
6024 if (rh != 7)
6025 store_data_long(destoffset, destval);
6026 }
6027 else {
6028 u16 destval, imm;
6029
6030 DECODE_PRINTF("WORD PTR ");
6031 destoffset = decode_rm00_address(rl);
6032 destval = fetch_data_word(destoffset);
6033 imm = (s8) fetch_byte_imm();
6034 DECODE_PRINTF2(",%x\n", imm);
6035 TRACE_AND_STEP();
6036 destval = (*opc83_word_operation[rh]) (destval, imm);
6037 if (rh != 7)
6038 store_data_word(destoffset, destval);
6039 }
6040 break;
6041 case 1:
6042 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6043 u32 destval, imm;
6044
6045 DECODE_PRINTF("DWORD PTR ");
6046 destoffset = decode_rm01_address(rl);
6047 destval = fetch_data_long(destoffset);
6048 imm = (s8) fetch_byte_imm();
6049 DECODE_PRINTF2(",%x\n", imm);
6050 TRACE_AND_STEP();
6051 destval = (*opc83_long_operation[rh]) (destval, imm);
6052 if (rh != 7)
6053 store_data_long(destoffset, destval);
6054 }
6055 else {
6056 u16 destval, imm;
6057
6058 DECODE_PRINTF("WORD PTR ");
6059 destoffset = decode_rm01_address(rl);
6060 destval = fetch_data_word(destoffset);
6061 imm = (s8) fetch_byte_imm();
6062 DECODE_PRINTF2(",%x\n", imm);
6063 TRACE_AND_STEP();
6064 destval = (*opc83_word_operation[rh]) (destval, imm);
6065 if (rh != 7)
6066 store_data_word(destoffset, destval);
6067 }
6068 break;
6069 case 2:
6070 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6071 u32 destval, imm;
6072
6073 DECODE_PRINTF("DWORD PTR ");
6074 destoffset = decode_rm10_address(rl);
6075 destval = fetch_data_long(destoffset);
6076 imm = (s8) fetch_byte_imm();
6077 DECODE_PRINTF2(",%x\n", imm);
6078 TRACE_AND_STEP();
6079 destval = (*opc83_long_operation[rh]) (destval, imm);
6080 if (rh != 7)
6081 store_data_long(destoffset, destval);
6082 }
6083 else {
6084 u16 destval, imm;
6085
6086 DECODE_PRINTF("WORD PTR ");
6087 destoffset = decode_rm10_address(rl);
6088 destval = fetch_data_word(destoffset);
6089 imm = (s8) fetch_byte_imm();
6090 DECODE_PRINTF2(",%x\n", imm);
6091 TRACE_AND_STEP();
6092 destval = (*opc83_word_operation[rh]) (destval, imm);
6093 if (rh != 7)
6094 store_data_word(destoffset, destval);
6095 }
6096 break;
6097 case 3: /* register to register */
6098 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6099 u32 *destreg;
6100 u32 destval, imm;
6101
6102 destreg = DECODE_RM_LONG_REGISTER(rl);
6103 imm = (s8) fetch_byte_imm();
6104 DECODE_PRINTF2(",%x\n", imm);
6105 TRACE_AND_STEP();
6106 destval = (*opc83_long_operation[rh]) (*destreg, imm);
6107 if (rh != 7)
6108 *destreg = destval;
6109 }
6110 else {
6111 u16 *destreg;
6112 u16 destval, imm;
6113
6114 destreg = DECODE_RM_WORD_REGISTER(rl);
6115 imm = (s8) fetch_byte_imm();
6116 DECODE_PRINTF2(",%x\n", imm);
6117 TRACE_AND_STEP();
6118 destval = (*opc83_word_operation[rh]) (*destreg, imm);
6119 if (rh != 7)
6120 *destreg = destval;
6121 }
6122 break;
6123 }
6124 DECODE_CLEAR_SEGOVR();
6125 END_OF_INSTR();
6126}
6127
6128/****************************************************************************
6129REMARKS:
6130Handles opcode 0x84
6131****************************************************************************/
6132static void
6133x86emuOp_test_byte_RM_R(u8 X86EMU_UNUSED(op1))
6134{
6135 int mod, rl, rh;
6136 u8 *destreg, *srcreg;
6137 uint destoffset;
6138 u8 destval;
6139
6140 START_OF_INSTR();
6141 DECODE_PRINTF("TEST\t");
6142 FETCH_DECODE_MODRM(mod, rh, rl);
6143 switch (mod) {
6144 case 0:
6145 destoffset = decode_rm00_address(rl);
6146 DECODE_PRINTF(",");
6147 destval = fetch_data_byte(destoffset);
6148 srcreg = DECODE_RM_BYTE_REGISTER(rh);
6149 DECODE_PRINTF("\n");
6150 TRACE_AND_STEP();
6151 test_byte(destval, *srcreg);
6152 break;
6153 case 1:
6154 destoffset = decode_rm01_address(rl);
6155 DECODE_PRINTF(",");
6156 destval = fetch_data_byte(destoffset);
6157 srcreg = DECODE_RM_BYTE_REGISTER(rh);
6158 DECODE_PRINTF("\n");
6159 TRACE_AND_STEP();
6160 test_byte(destval, *srcreg);
6161 break;
6162 case 2:
6163 destoffset = decode_rm10_address(rl);
6164 DECODE_PRINTF(",");
6165 destval = fetch_data_byte(destoffset);
6166 srcreg = DECODE_RM_BYTE_REGISTER(rh);
6167 DECODE_PRINTF("\n");
6168 TRACE_AND_STEP();
6169 test_byte(destval, *srcreg);
6170 break;
6171 case 3: /* register to register */
6172 destreg = DECODE_RM_BYTE_REGISTER(rl);
6173 DECODE_PRINTF(",");
6174 srcreg = DECODE_RM_BYTE_REGISTER(rh);
6175 DECODE_PRINTF("\n");
6176 TRACE_AND_STEP();
6177 test_byte(*destreg, *srcreg);
6178 break;
6179 }
6180 DECODE_CLEAR_SEGOVR();
6181 END_OF_INSTR();
6182}
6183
6184/****************************************************************************
6185REMARKS:
6186Handles opcode 0x85
6187****************************************************************************/
6188static void
6189x86emuOp_test_word_RM_R(u8 X86EMU_UNUSED(op1))
6190{
6191 int mod, rl, rh;
6192 uint destoffset;
6193
6194 START_OF_INSTR();
6195 DECODE_PRINTF("TEST\t");
6196 FETCH_DECODE_MODRM(mod, rh, rl);
6197 switch (mod) {
6198 case 0:
6199 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6200 u32 destval;
6201 u32 *srcreg;
6202
6203 destoffset = decode_rm00_address(rl);
6204 DECODE_PRINTF(",");
6205 destval = fetch_data_long(destoffset);
6206 srcreg = DECODE_RM_LONG_REGISTER(rh);
6207 DECODE_PRINTF("\n");
6208 TRACE_AND_STEP();
6209 test_long(destval, *srcreg);
6210 }
6211 else {
6212 u16 destval;
6213 u16 *srcreg;
6214
6215 destoffset = decode_rm00_address(rl);
6216 DECODE_PRINTF(",");
6217 destval = fetch_data_word(destoffset);
6218 srcreg = DECODE_RM_WORD_REGISTER(rh);
6219 DECODE_PRINTF("\n");
6220 TRACE_AND_STEP();
6221 test_word(destval, *srcreg);
6222 }
6223 break;
6224 case 1:
6225 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6226 u32 destval;
6227 u32 *srcreg;
6228
6229 destoffset = decode_rm01_address(rl);
6230 DECODE_PRINTF(",");
6231 destval = fetch_data_long(destoffset);
6232 srcreg = DECODE_RM_LONG_REGISTER(rh);
6233 DECODE_PRINTF("\n");
6234 TRACE_AND_STEP();
6235 test_long(destval, *srcreg);
6236 }
6237 else {
6238 u16 destval;
6239 u16 *srcreg;
6240
6241 destoffset = decode_rm01_address(rl);
6242 DECODE_PRINTF(",");
6243 destval = fetch_data_word(destoffset);
6244 srcreg = DECODE_RM_WORD_REGISTER(rh);
6245 DECODE_PRINTF("\n");
6246 TRACE_AND_STEP();
6247 test_word(destval, *srcreg);
6248 }
6249 break;
6250 case 2:
6251 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6252 u32 destval;
6253 u32 *srcreg;
6254
6255 destoffset = decode_rm10_address(rl);
6256 DECODE_PRINTF(",");
6257 destval = fetch_data_long(destoffset);
6258 srcreg = DECODE_RM_LONG_REGISTER(rh);
6259 DECODE_PRINTF("\n");
6260 TRACE_AND_STEP();
6261 test_long(destval, *srcreg);
6262 }
6263 else {
6264 u16 destval;
6265 u16 *srcreg;
6266
6267 destoffset = decode_rm10_address(rl);
6268 DECODE_PRINTF(",");
6269 destval = fetch_data_word(destoffset);
6270 srcreg = DECODE_RM_WORD_REGISTER(rh);
6271 DECODE_PRINTF("\n");
6272 TRACE_AND_STEP();
6273 test_word(destval, *srcreg);
6274 }
6275 break;
6276 case 3: /* register to register */
6277 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6278 u32 *destreg, *srcreg;
6279
6280 destreg = DECODE_RM_LONG_REGISTER(rl);
6281 DECODE_PRINTF(",");
6282 srcreg = DECODE_RM_LONG_REGISTER(rh);
6283 DECODE_PRINTF("\n");
6284 TRACE_AND_STEP();
6285 test_long(*destreg, *srcreg);
6286 }
6287 else {
6288 u16 *destreg, *srcreg;
6289
6290 destreg = DECODE_RM_WORD_REGISTER(rl);
6291 DECODE_PRINTF(",");
6292 srcreg = DECODE_RM_WORD_REGISTER(rh);
6293 DECODE_PRINTF("\n");
6294 TRACE_AND_STEP();
6295 test_word(*destreg, *srcreg);
6296 }
6297 break;
6298 }
6299 DECODE_CLEAR_SEGOVR();
6300 END_OF_INSTR();
6301}
6302
6303/****************************************************************************
6304REMARKS:
6305Handles opcode 0x86
6306****************************************************************************/
6307static void
6308x86emuOp_xchg_byte_RM_R(u8 X86EMU_UNUSED(op1))
6309{
6310 int mod, rl, rh;
6311 u8 *destreg, *srcreg;
6312 uint destoffset;
6313 u8 destval;
6314 u8 tmp;
6315
6316 START_OF_INSTR();
6317 DECODE_PRINTF("XCHG\t");
6318 FETCH_DECODE_MODRM(mod, rh, rl);
6319 switch (mod) {
6320 case 0:
6321 destoffset = decode_rm00_address(rl);
6322 DECODE_PRINTF(",");
6323 destval = fetch_data_byte(destoffset);
6324 srcreg = DECODE_RM_BYTE_REGISTER(rh);
6325 DECODE_PRINTF("\n");
6326 TRACE_AND_STEP();
6327 tmp = *srcreg;
6328 *srcreg = destval;
6329 destval = tmp;
6330 store_data_byte(destoffset, destval);
6331 break;
6332 case 1:
6333 destoffset = decode_rm01_address(rl);
6334 DECODE_PRINTF(",");
6335 destval = fetch_data_byte(destoffset);
6336 srcreg = DECODE_RM_BYTE_REGISTER(rh);
6337 DECODE_PRINTF("\n");
6338 TRACE_AND_STEP();
6339 tmp = *srcreg;
6340 *srcreg = destval;
6341 destval = tmp;
6342 store_data_byte(destoffset, destval);
6343 break;
6344 case 2:
6345 destoffset = decode_rm10_address(rl);
6346 DECODE_PRINTF(",");
6347 destval = fetch_data_byte(destoffset);
6348 srcreg = DECODE_RM_BYTE_REGISTER(rh);
6349 DECODE_PRINTF("\n");
6350 TRACE_AND_STEP();
6351 tmp = *srcreg;
6352 *srcreg = destval;
6353 destval = tmp;
6354 store_data_byte(destoffset, destval);
6355 break;
6356 case 3: /* register to register */
6357 destreg = DECODE_RM_BYTE_REGISTER(rl);
6358 DECODE_PRINTF(",");
6359 srcreg = DECODE_RM_BYTE_REGISTER(rh);
6360 DECODE_PRINTF("\n");
6361 TRACE_AND_STEP();
6362 tmp = *srcreg;
6363 *srcreg = *destreg;
6364 *destreg = tmp;
6365 break;
6366 }
6367 DECODE_CLEAR_SEGOVR();
6368 END_OF_INSTR();
6369}
6370
6371/****************************************************************************
6372REMARKS:
6373Handles opcode 0x87
6374****************************************************************************/
6375static void
6376x86emuOp_xchg_word_RM_R(u8 X86EMU_UNUSED(op1))
6377{
6378 int mod, rl, rh;
6379 uint destoffset;
6380
6381 START_OF_INSTR();
6382 DECODE_PRINTF("XCHG\t");
6383 FETCH_DECODE_MODRM(mod, rh, rl);
6384 switch (mod) {
6385 case 0:
6386 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6387 u32 *srcreg;
6388 u32 destval, tmp;
6389
6390 destoffset = decode_rm00_address(rl);
6391 DECODE_PRINTF(",");
6392 destval = fetch_data_long(destoffset);
6393 srcreg = DECODE_RM_LONG_REGISTER(rh);
6394 DECODE_PRINTF("\n");
6395 TRACE_AND_STEP();
6396 tmp = *srcreg;
6397 *srcreg = destval;
6398 destval = tmp;
6399 store_data_long(destoffset, destval);
6400 }
6401 else {
6402 u16 *srcreg;
6403 u16 destval, tmp;
6404
6405 destoffset = decode_rm00_address(rl);
6406 DECODE_PRINTF(",");
6407 destval = fetch_data_word(destoffset);
6408 srcreg = DECODE_RM_WORD_REGISTER(rh);
6409 DECODE_PRINTF("\n");
6410 TRACE_AND_STEP();
6411 tmp = *srcreg;
6412 *srcreg = destval;
6413 destval = tmp;
6414 store_data_word(destoffset, destval);
6415 }
6416 break;
6417 case 1:
6418 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6419 u32 *srcreg;
6420 u32 destval, tmp;
6421
6422 destoffset = decode_rm01_address(rl);
6423 DECODE_PRINTF(",");
6424 destval = fetch_data_long(destoffset);
6425 srcreg = DECODE_RM_LONG_REGISTER(rh);
6426 DECODE_PRINTF("\n");
6427 TRACE_AND_STEP();
6428 tmp = *srcreg;
6429 *srcreg = destval;
6430 destval = tmp;
6431 store_data_long(destoffset, destval);
6432 }
6433 else {
6434 u16 *srcreg;
6435 u16 destval, tmp;
6436
6437 destoffset = decode_rm01_address(rl);
6438 DECODE_PRINTF(",");
6439 destval = fetch_data_word(destoffset);
6440 srcreg = DECODE_RM_WORD_REGISTER(rh);
6441 DECODE_PRINTF("\n");
6442 TRACE_AND_STEP();
6443 tmp = *srcreg;
6444 *srcreg = destval;
6445 destval = tmp;
6446 store_data_word(destoffset, destval);
6447 }
6448 break;
6449 case 2:
6450 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6451 u32 *srcreg;
6452 u32 destval, tmp;
6453
6454 destoffset = decode_rm10_address(rl);
6455 DECODE_PRINTF(",");
6456 destval = fetch_data_long(destoffset);
6457 srcreg = DECODE_RM_LONG_REGISTER(rh);
6458 DECODE_PRINTF("\n");
6459 TRACE_AND_STEP();
6460 tmp = *srcreg;
6461 *srcreg = destval;
6462 destval = tmp;
6463 store_data_long(destoffset, destval);
6464 }
6465 else {
6466 u16 *srcreg;
6467 u16 destval, tmp;
6468
6469 destoffset = decode_rm10_address(rl);
6470 DECODE_PRINTF(",");
6471 destval = fetch_data_word(destoffset);
6472 srcreg = DECODE_RM_WORD_REGISTER(rh);
6473 DECODE_PRINTF("\n");
6474 TRACE_AND_STEP();
6475 tmp = *srcreg;
6476 *srcreg = destval;
6477 destval = tmp;
6478 store_data_word(destoffset, destval);
6479 }
6480 break;
6481 case 3: /* register to register */
6482 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6483 u32 *destreg, *srcreg;
6484 u32 tmp;
6485
6486 destreg = DECODE_RM_LONG_REGISTER(rl);
6487 DECODE_PRINTF(",");
6488 srcreg = DECODE_RM_LONG_REGISTER(rh);
6489 DECODE_PRINTF("\n");
6490 TRACE_AND_STEP();
6491 tmp = *srcreg;
6492 *srcreg = *destreg;
6493 *destreg = tmp;
6494 }
6495 else {
6496 u16 *destreg, *srcreg;
6497 u16 tmp;
6498
6499 destreg = DECODE_RM_WORD_REGISTER(rl);
6500 DECODE_PRINTF(",");
6501 srcreg = DECODE_RM_WORD_REGISTER(rh);
6502 DECODE_PRINTF("\n");
6503 TRACE_AND_STEP();
6504 tmp = *srcreg;
6505 *srcreg = *destreg;
6506 *destreg = tmp;
6507 }
6508 break;
6509 }
6510 DECODE_CLEAR_SEGOVR();
6511 END_OF_INSTR();
6512}
6513
6514/****************************************************************************
6515REMARKS:
6516Handles opcode 0x88
6517****************************************************************************/
6518static void
6519x86emuOp_mov_byte_RM_R(u8 X86EMU_UNUSED(op1))
6520{
6521 int mod, rl, rh;
6522 u8 *destreg, *srcreg;
6523 uint destoffset;
6524
6525 START_OF_INSTR();
6526 DECODE_PRINTF("MOV\t");
6527 FETCH_DECODE_MODRM(mod, rh, rl);
6528 switch (mod) {
6529 case 0:
6530 destoffset = decode_rm00_address(rl);
6531 DECODE_PRINTF(",");
6532 srcreg = DECODE_RM_BYTE_REGISTER(rh);
6533 DECODE_PRINTF("\n");
6534 TRACE_AND_STEP();
6535 store_data_byte(destoffset, *srcreg);
6536 break;
6537 case 1:
6538 destoffset = decode_rm01_address(rl);
6539 DECODE_PRINTF(",");
6540 srcreg = DECODE_RM_BYTE_REGISTER(rh);
6541 DECODE_PRINTF("\n");
6542 TRACE_AND_STEP();
6543 store_data_byte(destoffset, *srcreg);
6544 break;
6545 case 2:
6546 destoffset = decode_rm10_address(rl);
6547 DECODE_PRINTF(",");
6548 srcreg = DECODE_RM_BYTE_REGISTER(rh);
6549 DECODE_PRINTF("\n");
6550 TRACE_AND_STEP();
6551 store_data_byte(destoffset, *srcreg);
6552 break;
6553 case 3: /* register to register */
6554 destreg = DECODE_RM_BYTE_REGISTER(rl);
6555 DECODE_PRINTF(",");
6556 srcreg = DECODE_RM_BYTE_REGISTER(rh);
6557 DECODE_PRINTF("\n");
6558 TRACE_AND_STEP();
6559 *destreg = *srcreg;
6560 break;
6561 }
6562 DECODE_CLEAR_SEGOVR();
6563 END_OF_INSTR();
6564}
6565
6566/****************************************************************************
6567REMARKS:
6568Handles opcode 0x89
6569****************************************************************************/
6570static void
6571x86emuOp_mov_word_RM_R(u8 X86EMU_UNUSED(op1))
6572{
6573 int mod, rl, rh;
6574 u32 destoffset;
6575
6576 START_OF_INSTR();
6577 DECODE_PRINTF("MOV\t");
6578 FETCH_DECODE_MODRM(mod, rh, rl);
6579 switch (mod) {
6580 case 0:
6581 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6582 u32 *srcreg;
6583
6584 destoffset = decode_rm00_address(rl);
6585 DECODE_PRINTF(",");
6586 srcreg = DECODE_RM_LONG_REGISTER(rh);
6587 DECODE_PRINTF("\n");
6588 TRACE_AND_STEP();
6589 store_data_long(destoffset, *srcreg);
6590 }
6591 else {
6592 u16 *srcreg;
6593
6594 destoffset = decode_rm00_address(rl);
6595 DECODE_PRINTF(",");
6596 srcreg = DECODE_RM_WORD_REGISTER(rh);
6597 DECODE_PRINTF("\n");
6598 TRACE_AND_STEP();
6599 store_data_word(destoffset, *srcreg);
6600 }
6601 break;
6602 case 1:
6603 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6604 u32 *srcreg;
6605
6606 destoffset = decode_rm01_address(rl);
6607 DECODE_PRINTF(",");
6608 srcreg = DECODE_RM_LONG_REGISTER(rh);
6609 DECODE_PRINTF("\n");
6610 TRACE_AND_STEP();
6611 store_data_long(destoffset, *srcreg);
6612 }
6613 else {
6614 u16 *srcreg;
6615
6616 destoffset = decode_rm01_address(rl);
6617 DECODE_PRINTF(",");
6618 srcreg = DECODE_RM_WORD_REGISTER(rh);
6619 DECODE_PRINTF("\n");
6620 TRACE_AND_STEP();
6621 store_data_word(destoffset, *srcreg);
6622 }
6623 break;
6624 case 2:
6625 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6626 u32 *srcreg;
6627
6628 destoffset = decode_rm10_address(rl);
6629 DECODE_PRINTF(",");
6630 srcreg = DECODE_RM_LONG_REGISTER(rh);
6631 DECODE_PRINTF("\n");
6632 TRACE_AND_STEP();
6633 store_data_long(destoffset, *srcreg);
6634 }
6635 else {
6636 u16 *srcreg;
6637
6638 destoffset = decode_rm10_address(rl);
6639 DECODE_PRINTF(",");
6640 srcreg = DECODE_RM_WORD_REGISTER(rh);
6641 DECODE_PRINTF("\n");
6642 TRACE_AND_STEP();
6643 store_data_word(destoffset, *srcreg);
6644 }
6645 break;
6646 case 3: /* register to register */
6647 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6648 u32 *destreg, *srcreg;
6649
6650 destreg = DECODE_RM_LONG_REGISTER(rl);
6651 DECODE_PRINTF(",");
6652 srcreg = DECODE_RM_LONG_REGISTER(rh);
6653 DECODE_PRINTF("\n");
6654 TRACE_AND_STEP();
6655 *destreg = *srcreg;
6656 }
6657 else {
6658 u16 *destreg, *srcreg;
6659
6660 destreg = DECODE_RM_WORD_REGISTER(rl);
6661 DECODE_PRINTF(",");
6662 srcreg = DECODE_RM_WORD_REGISTER(rh);
6663 DECODE_PRINTF("\n");
6664 TRACE_AND_STEP();
6665 *destreg = *srcreg;
6666 }
6667 break;
6668 }
6669 DECODE_CLEAR_SEGOVR();
6670 END_OF_INSTR();
6671}
6672
6673/****************************************************************************
6674REMARKS:
6675Handles opcode 0x8a
6676****************************************************************************/
6677static void
6678x86emuOp_mov_byte_R_RM(u8 X86EMU_UNUSED(op1))
6679{
6680 int mod, rl, rh;
6681 u8 *destreg, *srcreg;
6682 uint srcoffset;
6683 u8 srcval;
6684
6685 START_OF_INSTR();
6686 DECODE_PRINTF("MOV\t");
6687 FETCH_DECODE_MODRM(mod, rh, rl);
6688 switch (mod) {
6689 case 0:
6690 destreg = DECODE_RM_BYTE_REGISTER(rh);
6691 DECODE_PRINTF(",");
6692 srcoffset = decode_rm00_address(rl);
6693 srcval = fetch_data_byte(srcoffset);
6694 DECODE_PRINTF("\n");
6695 TRACE_AND_STEP();
6696 *destreg = srcval;
6697 break;
6698 case 1:
6699 destreg = DECODE_RM_BYTE_REGISTER(rh);
6700 DECODE_PRINTF(",");
6701 srcoffset = decode_rm01_address(rl);
6702 srcval = fetch_data_byte(srcoffset);
6703 DECODE_PRINTF("\n");
6704 TRACE_AND_STEP();
6705 *destreg = srcval;
6706 break;
6707 case 2:
6708 destreg = DECODE_RM_BYTE_REGISTER(rh);
6709 DECODE_PRINTF(",");
6710 srcoffset = decode_rm10_address(rl);
6711 srcval = fetch_data_byte(srcoffset);
6712 DECODE_PRINTF("\n");
6713 TRACE_AND_STEP();
6714 *destreg = srcval;
6715 break;
6716 case 3: /* register to register */
6717 destreg = DECODE_RM_BYTE_REGISTER(rh);
6718 DECODE_PRINTF(",");
6719 srcreg = DECODE_RM_BYTE_REGISTER(rl);
6720 DECODE_PRINTF("\n");
6721 TRACE_AND_STEP();
6722 *destreg = *srcreg;
6723 break;
6724 }
6725 DECODE_CLEAR_SEGOVR();
6726 END_OF_INSTR();
6727}
6728
6729/****************************************************************************
6730REMARKS:
6731Handles opcode 0x8b
6732****************************************************************************/
6733static void
6734x86emuOp_mov_word_R_RM(u8 X86EMU_UNUSED(op1))
6735{
6736 int mod, rl, rh;
6737 uint srcoffset;
6738
6739 START_OF_INSTR();
6740 DECODE_PRINTF("MOV\t");
6741 FETCH_DECODE_MODRM(mod, rh, rl);
6742 switch (mod) {
6743 case 0:
6744 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6745 u32 *destreg;
6746 u32 srcval;
6747
6748 destreg = DECODE_RM_LONG_REGISTER(rh);
6749 DECODE_PRINTF(",");
6750 srcoffset = decode_rm00_address(rl);
6751 srcval = fetch_data_long(srcoffset);
6752 DECODE_PRINTF("\n");
6753 TRACE_AND_STEP();
6754 *destreg = srcval;
6755 }
6756 else {
6757 u16 *destreg;
6758 u16 srcval;
6759
6760 destreg = DECODE_RM_WORD_REGISTER(rh);
6761 DECODE_PRINTF(",");
6762 srcoffset = decode_rm00_address(rl);
6763 srcval = fetch_data_word(srcoffset);
6764 DECODE_PRINTF("\n");
6765 TRACE_AND_STEP();
6766 *destreg = srcval;
6767 }
6768 break;
6769 case 1:
6770 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6771 u32 *destreg;
6772 u32 srcval;
6773
6774 destreg = DECODE_RM_LONG_REGISTER(rh);
6775 DECODE_PRINTF(",");
6776 srcoffset = decode_rm01_address(rl);
6777 srcval = fetch_data_long(srcoffset);
6778 DECODE_PRINTF("\n");
6779 TRACE_AND_STEP();
6780 *destreg = srcval;
6781 }
6782 else {
6783 u16 *destreg;
6784 u16 srcval;
6785
6786 destreg = DECODE_RM_WORD_REGISTER(rh);
6787 DECODE_PRINTF(",");
6788 srcoffset = decode_rm01_address(rl);
6789 srcval = fetch_data_word(srcoffset);
6790 DECODE_PRINTF("\n");
6791 TRACE_AND_STEP();
6792 *destreg = srcval;
6793 }
6794 break;
6795 case 2:
6796 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6797 u32 *destreg;
6798 u32 srcval;
6799
6800 destreg = DECODE_RM_LONG_REGISTER(rh);
6801 DECODE_PRINTF(",");
6802 srcoffset = decode_rm10_address(rl);
6803 srcval = fetch_data_long(srcoffset);
6804 DECODE_PRINTF("\n");
6805 TRACE_AND_STEP();
6806 *destreg = srcval;
6807 }
6808 else {
6809 u16 *destreg;
6810 u16 srcval;
6811
6812 destreg = DECODE_RM_WORD_REGISTER(rh);
6813 DECODE_PRINTF(",");
6814 srcoffset = decode_rm10_address(rl);
6815 srcval = fetch_data_word(srcoffset);
6816 DECODE_PRINTF("\n");
6817 TRACE_AND_STEP();
6818 *destreg = srcval;
6819 }
6820 break;
6821 case 3: /* register to register */
6822 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6823 u32 *destreg, *srcreg;
6824
6825 destreg = DECODE_RM_LONG_REGISTER(rh);
6826 DECODE_PRINTF(",");
6827 srcreg = DECODE_RM_LONG_REGISTER(rl);
6828 DECODE_PRINTF("\n");
6829 TRACE_AND_STEP();
6830 *destreg = *srcreg;
6831 }
6832 else {
6833 u16 *destreg, *srcreg;
6834
6835 destreg = DECODE_RM_WORD_REGISTER(rh);
6836 DECODE_PRINTF(",");
6837 srcreg = DECODE_RM_WORD_REGISTER(rl);
6838 DECODE_PRINTF("\n");
6839 TRACE_AND_STEP();
6840 *destreg = *srcreg;
6841 }
6842 break;
6843 }
6844 DECODE_CLEAR_SEGOVR();
6845 END_OF_INSTR();
6846}
6847
6848/****************************************************************************
6849REMARKS:
6850Handles opcode 0x8c
6851****************************************************************************/
6852static void
6853x86emuOp_mov_word_RM_SR(u8 X86EMU_UNUSED(op1))
6854{
6855 int mod, rl, rh;
6856 u16 *destreg, *srcreg;
6857 uint destoffset;
6858 u16 destval;
6859
6860 START_OF_INSTR();
6861 DECODE_PRINTF("MOV\t");
6862 FETCH_DECODE_MODRM(mod, rh, rl);
6863 switch (mod) {
6864 case 0:
6865 destoffset = decode_rm00_address(rl);
6866 DECODE_PRINTF(",");
6867 srcreg = decode_rm_seg_register(rh);
6868 DECODE_PRINTF("\n");
6869 TRACE_AND_STEP();
6870 destval = *srcreg;
6871 store_data_word(destoffset, destval);
6872 break;
6873 case 1:
6874 destoffset = decode_rm01_address(rl);
6875 DECODE_PRINTF(",");
6876 srcreg = decode_rm_seg_register(rh);
6877 DECODE_PRINTF("\n");
6878 TRACE_AND_STEP();
6879 destval = *srcreg;
6880 store_data_word(destoffset, destval);
6881 break;
6882 case 2:
6883 destoffset = decode_rm10_address(rl);
6884 DECODE_PRINTF(",");
6885 srcreg = decode_rm_seg_register(rh);
6886 DECODE_PRINTF("\n");
6887 TRACE_AND_STEP();
6888 destval = *srcreg;
6889 store_data_word(destoffset, destval);
6890 break;
6891 case 3: /* register to register */
6892 destreg = DECODE_RM_WORD_REGISTER(rl);
6893 DECODE_PRINTF(",");
6894 srcreg = decode_rm_seg_register(rh);
6895 DECODE_PRINTF("\n");
6896 TRACE_AND_STEP();
6897 *destreg = *srcreg;
6898 break;
6899 }
6900 DECODE_CLEAR_SEGOVR();
6901 END_OF_INSTR();
6902}
6903
6904/****************************************************************************
6905REMARKS:
6906Handles opcode 0x8d
6907****************************************************************************/
6908static void
6909x86emuOp_lea_word_R_M(u8 X86EMU_UNUSED(op1))
6910{
6911 int mod, rl, rh;
6912 uint destoffset;
6913
6914 START_OF_INSTR();
6915 DECODE_PRINTF("LEA\t");
6916 FETCH_DECODE_MODRM(mod, rh, rl);
6917 switch (mod) {
6918 case 0:
6919 if (M.x86.mode & SYSMODE_PREFIX_ADDR) {
6920 u32 *srcreg = DECODE_RM_LONG_REGISTER(rh);
6921
6922 DECODE_PRINTF(",");
6923 destoffset = decode_rm00_address(rl);
6924 DECODE_PRINTF("\n");
6925 TRACE_AND_STEP();
6926 *srcreg = (u32) destoffset;
6927 }
6928 else {
6929 u16 *srcreg = DECODE_RM_WORD_REGISTER(rh);
6930
6931 DECODE_PRINTF(",");
6932 destoffset = decode_rm00_address(rl);
6933 DECODE_PRINTF("\n");
6934 TRACE_AND_STEP();
6935 *srcreg = (u16) destoffset;
6936 }
6937 break;
6938 case 1:
6939 if (M.x86.mode & SYSMODE_PREFIX_ADDR) {
6940 u32 *srcreg = DECODE_RM_LONG_REGISTER(rh);
6941
6942 DECODE_PRINTF(",");
6943 destoffset = decode_rm01_address(rl);
6944 DECODE_PRINTF("\n");
6945 TRACE_AND_STEP();
6946 *srcreg = (u32) destoffset;
6947 }
6948 else {
6949 u16 *srcreg = DECODE_RM_WORD_REGISTER(rh);
6950
6951 DECODE_PRINTF(",");
6952 destoffset = decode_rm01_address(rl);
6953 DECODE_PRINTF("\n");
6954 TRACE_AND_STEP();
6955 *srcreg = (u16) destoffset;
6956 }
6957 break;
6958 case 2:
6959 if (M.x86.mode & SYSMODE_PREFIX_ADDR) {
6960 u32 *srcreg = DECODE_RM_LONG_REGISTER(rh);
6961
6962 DECODE_PRINTF(",");
6963 destoffset = decode_rm10_address(rl);
6964 DECODE_PRINTF("\n");
6965 TRACE_AND_STEP();
6966 *srcreg = (u32) destoffset;
6967 }
6968 else {
6969 u16 *srcreg = DECODE_RM_WORD_REGISTER(rh);
6970
6971 DECODE_PRINTF(",");
6972 destoffset = decode_rm10_address(rl);
6973 DECODE_PRINTF("\n");
6974 TRACE_AND_STEP();
6975 *srcreg = (u16) destoffset;
6976 }
6977 break;
6978 case 3: /* register to register */
6979 /* undefined. Do nothing. */
6980 break;
6981 }
6982 DECODE_CLEAR_SEGOVR();
6983 END_OF_INSTR();
6984}
6985
6986/****************************************************************************
6987REMARKS:
6988Handles opcode 0x8e
6989****************************************************************************/
6990static void
6991x86emuOp_mov_word_SR_RM(u8 X86EMU_UNUSED(op1))
6992{
6993 int mod, rl, rh;
6994 u16 *destreg, *srcreg;
6995 uint srcoffset;
6996 u16 srcval;
6997
6998 START_OF_INSTR();
6999 DECODE_PRINTF("MOV\t");
7000 FETCH_DECODE_MODRM(mod, rh, rl);
7001 switch (mod) {
7002 case 0:
7003 destreg = decode_rm_seg_register(rh);
7004 DECODE_PRINTF(",");
7005 srcoffset = decode_rm00_address(rl);
7006 srcval = fetch_data_word(srcoffset);
7007 DECODE_PRINTF("\n");
7008 TRACE_AND_STEP();
7009 *destreg = srcval;
7010 break;
7011 case 1:
7012 destreg = decode_rm_seg_register(rh);
7013 DECODE_PRINTF(",");
7014 srcoffset = decode_rm01_address(rl);
7015 srcval = fetch_data_word(srcoffset);
7016 DECODE_PRINTF("\n");
7017 TRACE_AND_STEP();
7018 *destreg = srcval;
7019 break;
7020 case 2:
7021 destreg = decode_rm_seg_register(rh);
7022 DECODE_PRINTF(",");
7023 srcoffset = decode_rm10_address(rl);
7024 srcval = fetch_data_word(srcoffset);
7025 DECODE_PRINTF("\n");
7026 TRACE_AND_STEP();
7027 *destreg = srcval;
7028 break;
7029 case 3: /* register to register */
7030 destreg = decode_rm_seg_register(rh);
7031 DECODE_PRINTF(",");
7032 srcreg = DECODE_RM_WORD_REGISTER(rl);
7033 DECODE_PRINTF("\n");
7034 TRACE_AND_STEP();
7035 *destreg = *srcreg;
7036 break;
7037 }
7038 /*
7039 * Clean up, and reset all the R_xSP pointers to the correct
7040 * locations. This is about 3x too much overhead (doing all the
7041 * segreg ptrs when only one is needed, but this instruction
7042 * *cannot* be that common, and this isn't too much work anyway.
7043 */
7044 DECODE_CLEAR_SEGOVR();
7045 END_OF_INSTR();
7046}
7047
7048/****************************************************************************
7049REMARKS:
7050Handles opcode 0x8f
7051****************************************************************************/
7052static void
7053x86emuOp_pop_RM(u8 X86EMU_UNUSED(op1))
7054{
7055 int mod, rl, rh;
7056 uint destoffset;
7057
7058 START_OF_INSTR();
7059 DECODE_PRINTF("POP\t");
7060 FETCH_DECODE_MODRM(mod, rh, rl);
7061 if (rh != 0) {
7062 DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n");
7063 HALT_SYS();
7064 }
7065 switch (mod) {
7066 case 0:
7067 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7068 u32 destval;
7069
7070 destoffset = decode_rm00_address(rl);
7071 DECODE_PRINTF("\n");
7072 TRACE_AND_STEP();
7073 destval = pop_long();
7074 store_data_long(destoffset, destval);
7075 }
7076 else {
7077 u16 destval;
7078
7079 destoffset = decode_rm00_address(rl);
7080 DECODE_PRINTF("\n");
7081 TRACE_AND_STEP();
7082 destval = pop_word();
7083 store_data_word(destoffset, destval);
7084 }
7085 break;
7086 case 1:
7087 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7088 u32 destval;
7089
7090 destoffset = decode_rm01_address(rl);
7091 DECODE_PRINTF("\n");
7092 TRACE_AND_STEP();
7093 destval = pop_long();
7094 store_data_long(destoffset, destval);
7095 }
7096 else {
7097 u16 destval;
7098
7099 destoffset = decode_rm01_address(rl);
7100 DECODE_PRINTF("\n");
7101 TRACE_AND_STEP();
7102 destval = pop_word();
7103 store_data_word(destoffset, destval);
7104 }
7105 break;
7106 case 2:
7107 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7108 u32 destval;
7109
7110 destoffset = decode_rm10_address(rl);
7111 DECODE_PRINTF("\n");
7112 TRACE_AND_STEP();
7113 destval = pop_long();
7114 store_data_long(destoffset, destval);
7115 }
7116 else {
7117 u16 destval;
7118
7119 destoffset = decode_rm10_address(rl);
7120 DECODE_PRINTF("\n");
7121 TRACE_AND_STEP();
7122 destval = pop_word();
7123 store_data_word(destoffset, destval);
7124 }
7125 break;
7126 case 3: /* register to register */
7127 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7128 u32 *destreg;
7129
7130 destreg = DECODE_RM_LONG_REGISTER(rl);
7131 DECODE_PRINTF("\n");
7132 TRACE_AND_STEP();
7133 *destreg = pop_long();
7134 }
7135 else {
7136 u16 *destreg;
7137
7138 destreg = DECODE_RM_WORD_REGISTER(rl);
7139 DECODE_PRINTF("\n");
7140 TRACE_AND_STEP();
7141 *destreg = pop_word();
7142 }
7143 break;
7144 }
7145 DECODE_CLEAR_SEGOVR();
7146 END_OF_INSTR();
7147}
7148
7149/****************************************************************************
7150REMARKS:
7151Handles opcode 0x90
7152****************************************************************************/
7153static void
7154x86emuOp_nop(u8 X86EMU_UNUSED(op1))
7155{
7156 START_OF_INSTR();
7157 DECODE_PRINTF("NOP\n");
7158 TRACE_AND_STEP();
7159 DECODE_CLEAR_SEGOVR();
7160 END_OF_INSTR();
7161}
7162
7163/****************************************************************************
7164REMARKS:
7165Handles opcode 0x91
7166****************************************************************************/
7167static void
7168x86emuOp_xchg_word_AX_CX(u8 X86EMU_UNUSED(op1))
7169{
7170 u32 tmp;
7171
7172 START_OF_INSTR();
7173 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7174 DECODE_PRINTF("XCHG\tEAX,ECX\n");
7175 }
7176 else {
7177 DECODE_PRINTF("XCHG\tAX,CX\n");
7178 }
7179 TRACE_AND_STEP();
7180 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7181 tmp = M.x86.R_EAX;
7182 M.x86.R_EAX = M.x86.R_ECX;
7183 M.x86.R_ECX = tmp;
7184 }
7185 else {
7186 tmp = M.x86.R_AX;
7187 M.x86.R_AX = M.x86.R_CX;
7188 M.x86.R_CX = (u16) tmp;
7189 }
7190 DECODE_CLEAR_SEGOVR();
7191 END_OF_INSTR();
7192}
7193
7194/****************************************************************************
7195REMARKS:
7196Handles opcode 0x92
7197****************************************************************************/
7198static void
7199x86emuOp_xchg_word_AX_DX(u8 X86EMU_UNUSED(op1))
7200{
7201 u32 tmp;
7202
7203 START_OF_INSTR();
7204 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7205 DECODE_PRINTF("XCHG\tEAX,EDX\n");
7206 }
7207 else {
7208 DECODE_PRINTF("XCHG\tAX,DX\n");
7209 }
7210 TRACE_AND_STEP();
7211 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7212 tmp = M.x86.R_EAX;
7213 M.x86.R_EAX = M.x86.R_EDX;
7214 M.x86.R_EDX = tmp;
7215 }
7216 else {
7217 tmp = M.x86.R_AX;
7218 M.x86.R_AX = M.x86.R_DX;
7219 M.x86.R_DX = (u16) tmp;
7220 }
7221 DECODE_CLEAR_SEGOVR();
7222 END_OF_INSTR();
7223}
7224
7225/****************************************************************************
7226REMARKS:
7227Handles opcode 0x93
7228****************************************************************************/
7229static void
7230x86emuOp_xchg_word_AX_BX(u8 X86EMU_UNUSED(op1))
7231{
7232 u32 tmp;
7233
7234 START_OF_INSTR();
7235 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7236 DECODE_PRINTF("XCHG\tEAX,EBX\n");
7237 }
7238 else {
7239 DECODE_PRINTF("XCHG\tAX,BX\n");
7240 }
7241 TRACE_AND_STEP();
7242 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7243 tmp = M.x86.R_EAX;
7244 M.x86.R_EAX = M.x86.R_EBX;
7245 M.x86.R_EBX = tmp;
7246 }
7247 else {
7248 tmp = M.x86.R_AX;
7249 M.x86.R_AX = M.x86.R_BX;
7250 M.x86.R_BX = (u16) tmp;
7251 }
7252 DECODE_CLEAR_SEGOVR();
7253 END_OF_INSTR();
7254}
7255
7256/****************************************************************************
7257REMARKS:
7258Handles opcode 0x94
7259****************************************************************************/
7260static void
7261x86emuOp_xchg_word_AX_SP(u8 X86EMU_UNUSED(op1))
7262{
7263 u32 tmp;
7264
7265 START_OF_INSTR();
7266 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7267 DECODE_PRINTF("XCHG\tEAX,ESP\n");
7268 }
7269 else {
7270 DECODE_PRINTF("XCHG\tAX,SP\n");
7271 }
7272 TRACE_AND_STEP();
7273 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7274 tmp = M.x86.R_EAX;
7275 M.x86.R_EAX = M.x86.R_ESP;
7276 M.x86.R_ESP = tmp;
7277 }
7278 else {
7279 tmp = M.x86.R_AX;
7280 M.x86.R_AX = M.x86.R_SP;
7281 M.x86.R_SP = (u16) tmp;
7282 }
7283 DECODE_CLEAR_SEGOVR();
7284 END_OF_INSTR();
7285}
7286
7287/****************************************************************************
7288REMARKS:
7289Handles opcode 0x95
7290****************************************************************************/
7291static void
7292x86emuOp_xchg_word_AX_BP(u8 X86EMU_UNUSED(op1))
7293{
7294 u32 tmp;
7295
7296 START_OF_INSTR();
7297 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7298 DECODE_PRINTF("XCHG\tEAX,EBP\n");
7299 }
7300 else {
7301 DECODE_PRINTF("XCHG\tAX,BP\n");
7302 }
7303 TRACE_AND_STEP();
7304 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7305 tmp = M.x86.R_EAX;
7306 M.x86.R_EAX = M.x86.R_EBP;
7307 M.x86.R_EBP = tmp;
7308 }
7309 else {
7310 tmp = M.x86.R_AX;
7311 M.x86.R_AX = M.x86.R_BP;
7312 M.x86.R_BP = (u16) tmp;
7313 }
7314 DECODE_CLEAR_SEGOVR();
7315 END_OF_INSTR();
7316}
7317
7318/****************************************************************************
7319REMARKS:
7320Handles opcode 0x96
7321****************************************************************************/
7322static void
7323x86emuOp_xchg_word_AX_SI(u8 X86EMU_UNUSED(op1))
7324{
7325 u32 tmp;
7326
7327 START_OF_INSTR();
7328 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7329 DECODE_PRINTF("XCHG\tEAX,ESI\n");
7330 }
7331 else {
7332 DECODE_PRINTF("XCHG\tAX,SI\n");
7333 }
7334 TRACE_AND_STEP();
7335 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7336 tmp = M.x86.R_EAX;
7337 M.x86.R_EAX = M.x86.R_ESI;
7338 M.x86.R_ESI = tmp;
7339 }
7340 else {
7341 tmp = M.x86.R_AX;
7342 M.x86.R_AX = M.x86.R_SI;
7343 M.x86.R_SI = (u16) tmp;
7344 }
7345 DECODE_CLEAR_SEGOVR();
7346 END_OF_INSTR();
7347}
7348
7349/****************************************************************************
7350REMARKS:
7351Handles opcode 0x97
7352****************************************************************************/
7353static void
7354x86emuOp_xchg_word_AX_DI(u8 X86EMU_UNUSED(op1))
7355{
7356 u32 tmp;
7357
7358 START_OF_INSTR();
7359 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7360 DECODE_PRINTF("XCHG\tEAX,EDI\n");
7361 }
7362 else {
7363 DECODE_PRINTF("XCHG\tAX,DI\n");
7364 }
7365 TRACE_AND_STEP();
7366 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7367 tmp = M.x86.R_EAX;
7368 M.x86.R_EAX = M.x86.R_EDI;
7369 M.x86.R_EDI = tmp;
7370 }
7371 else {
7372 tmp = M.x86.R_AX;
7373 M.x86.R_AX = M.x86.R_DI;
7374 M.x86.R_DI = (u16) tmp;
7375 }
7376 DECODE_CLEAR_SEGOVR();
7377 END_OF_INSTR();
7378}
7379
7380/****************************************************************************
7381REMARKS:
7382Handles opcode 0x98
7383****************************************************************************/
7384static void
7385x86emuOp_cbw(u8 X86EMU_UNUSED(op1))
7386{
7387 START_OF_INSTR();
7388 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7389 DECODE_PRINTF("CWDE\n");
7390 }
7391 else {
7392 DECODE_PRINTF("CBW\n");
7393 }
7394 TRACE_AND_STEP();
7395 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7396 if (M.x86.R_AX & 0x8000) {
7397 M.x86.R_EAX |= 0xffff0000;
7398 }
7399 else {
7400 M.x86.R_EAX &= 0x0000ffff;
7401 }
7402 }
7403 else {
7404 if (M.x86.R_AL & 0x80) {
7405 M.x86.R_AH = 0xff;
7406 }
7407 else {
7408 M.x86.R_AH = 0x0;
7409 }
7410 }
7411 DECODE_CLEAR_SEGOVR();
7412 END_OF_INSTR();
7413}
7414
7415/****************************************************************************
7416REMARKS:
7417Handles opcode 0x99
7418****************************************************************************/
7419static void
7420x86emuOp_cwd(u8 X86EMU_UNUSED(op1))
7421{
7422 START_OF_INSTR();
7423 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7424 DECODE_PRINTF("CDQ\n");
7425 }
7426 else {
7427 DECODE_PRINTF("CWD\n");
7428 }
7429 DECODE_PRINTF("CWD\n");
7430 TRACE_AND_STEP();
7431 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7432 if (M.x86.R_EAX & 0x80000000) {
7433 M.x86.R_EDX = 0xffffffff;
7434 }
7435 else {
7436 M.x86.R_EDX = 0x0;
7437 }
7438 }
7439 else {
7440 if (M.x86.R_AX & 0x8000) {
7441 M.x86.R_DX = 0xffff;
7442 }
7443 else {
7444 M.x86.R_DX = 0x0;
7445 }
7446 }
7447 DECODE_CLEAR_SEGOVR();
7448 END_OF_INSTR();
7449}
7450
7451/****************************************************************************
7452REMARKS:
7453Handles opcode 0x9a
7454****************************************************************************/
7455static void
7456x86emuOp_call_far_IMM(u8 X86EMU_UNUSED(op1))
7457{
7458 u32 farseg, faroff;
7459
7460 START_OF_INSTR();
7461 DECODE_PRINTF("CALL\t");
7462 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7463 faroff = fetch_long_imm();
7464 farseg = fetch_word_imm();
7465 }
7466 else {
7467 faroff = fetch_word_imm();
7468 farseg = fetch_word_imm();
7469 }
7470 DECODE_PRINTF2("%04x:", farseg);
7471 DECODE_PRINTF2("%04x\n", faroff);
7472 CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, farseg, faroff, "FAR ");
7473
7474 /* XXX
7475 *
7476 * Hooked interrupt vectors calling into our "BIOS" will cause
7477 * problems unless all intersegment stuff is checked for BIOS
7478 * access. Check needed here. For moment, let it alone.
7479 */
7480 TRACE_AND_STEP();
7481 push_word(M.x86.R_CS);
7482 M.x86.R_CS = farseg;
7483 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7484 push_long(M.x86.R_EIP);
7485 }
7486 else {
7487 push_word(M.x86.R_IP);
7488 }
7489 M.x86.R_EIP = faroff & 0xffff;
7490 DECODE_CLEAR_SEGOVR();
7491 END_OF_INSTR();
7492}
7493
7494/****************************************************************************
7495REMARKS:
7496Handles opcode 0x9b
7497****************************************************************************/
7498static void
7499x86emuOp_wait(u8 X86EMU_UNUSED(op1))
7500{
7501 START_OF_INSTR();
7502 DECODE_PRINTF("WAIT");
7503 TRACE_AND_STEP();
7504 /* NADA. */
7505 DECODE_CLEAR_SEGOVR();
7506 END_OF_INSTR();
7507}
7508
7509/****************************************************************************
7510REMARKS:
7511Handles opcode 0x9c
7512****************************************************************************/
7513static void
7514x86emuOp_pushf_word(u8 X86EMU_UNUSED(op1))
7515{
7516 u32 flags;
7517
7518 START_OF_INSTR();
7519 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7520 DECODE_PRINTF("PUSHFD\n");
7521 }
7522 else {
7523 DECODE_PRINTF("PUSHF\n");
7524 }
7525 TRACE_AND_STEP();
7526
7527 /* clear out *all* bits not representing flags, and turn on real bits */
7528 flags = (M.x86.R_EFLG & F_MSK) | F_ALWAYS_ON;
7529 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7530 push_long(flags);
7531 }
7532 else {
7533 push_word((u16) flags);
7534 }
7535 DECODE_CLEAR_SEGOVR();
7536 END_OF_INSTR();
7537}
7538
7539/****************************************************************************
7540REMARKS:
7541Handles opcode 0x9d
7542****************************************************************************/
7543static void
7544x86emuOp_popf_word(u8 X86EMU_UNUSED(op1))
7545{
7546 START_OF_INSTR();
7547 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7548 DECODE_PRINTF("POPFD\n");
7549 }
7550 else {
7551 DECODE_PRINTF("POPF\n");
7552 }
7553 TRACE_AND_STEP();
7554 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7555 M.x86.R_EFLG = pop_long();
7556 }
7557 else {
7558 M.x86.R_FLG = pop_word();
7559 }
7560 DECODE_CLEAR_SEGOVR();
7561 END_OF_INSTR();
7562}
7563
7564/****************************************************************************
7565REMARKS:
7566Handles opcode 0x9e
7567****************************************************************************/
7568static void
7569x86emuOp_sahf(u8 X86EMU_UNUSED(op1))
7570{
7571 START_OF_INSTR();
7572 DECODE_PRINTF("SAHF\n");
7573 TRACE_AND_STEP();
7574 /* clear the lower bits of the flag register */
7575 M.x86.R_FLG &= 0xffffff00;
7576 /* or in the AH register into the flags register */
7577 M.x86.R_FLG |= M.x86.R_AH;
7578 DECODE_CLEAR_SEGOVR();
7579 END_OF_INSTR();
7580}
7581
7582/****************************************************************************
7583REMARKS:
7584Handles opcode 0x9f
7585****************************************************************************/
7586static void
7587x86emuOp_lahf(u8 X86EMU_UNUSED(op1))
7588{
7589 START_OF_INSTR();
7590 DECODE_PRINTF("LAHF\n");
7591 TRACE_AND_STEP();
7592 M.x86.R_AH = (u8) (M.x86.R_FLG & 0xff);
7593 /*undocumented TC++ behavior??? Nope. It's documented, but
7594 you have too look real hard to notice it. */
7595 M.x86.R_AH |= 0x2;
7596 DECODE_CLEAR_SEGOVR();
7597 END_OF_INSTR();
7598}
7599
7600/****************************************************************************
7601REMARKS:
7602Handles opcode 0xa0
7603****************************************************************************/
7604static void
7605x86emuOp_mov_AL_M_IMM(u8 X86EMU_UNUSED(op1))
7606{
7607 u16 offset;
7608
7609 START_OF_INSTR();
7610 DECODE_PRINTF("MOV\tAL,");
7611 offset = fetch_word_imm();
7612 DECODE_PRINTF2("[%04x]\n", offset);
7613 TRACE_AND_STEP();
7614 M.x86.R_AL = fetch_data_byte(offset);
7615 DECODE_CLEAR_SEGOVR();
7616 END_OF_INSTR();
7617}
7618
7619/****************************************************************************
7620REMARKS:
7621Handles opcode 0xa1
7622****************************************************************************/
7623static void
7624x86emuOp_mov_AX_M_IMM(u8 X86EMU_UNUSED(op1))
7625{
7626 u16 offset;
7627
7628 START_OF_INSTR();
7629 offset = fetch_word_imm();
7630 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7631 DECODE_PRINTF2("MOV\tEAX,[%04x]\n", offset);
7632 }
7633 else {
7634 DECODE_PRINTF2("MOV\tAX,[%04x]\n", offset);
7635 }
7636 TRACE_AND_STEP();
7637 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7638 M.x86.R_EAX = fetch_data_long(offset);
7639 }
7640 else {
7641 M.x86.R_AX = fetch_data_word(offset);
7642 }
7643 DECODE_CLEAR_SEGOVR();
7644 END_OF_INSTR();
7645}
7646
7647/****************************************************************************
7648REMARKS:
7649Handles opcode 0xa2
7650****************************************************************************/
7651static void
7652x86emuOp_mov_M_AL_IMM(u8 X86EMU_UNUSED(op1))
7653{
7654 u16 offset;
7655
7656 START_OF_INSTR();
7657 DECODE_PRINTF("MOV\t");
7658 offset = fetch_word_imm();
7659 DECODE_PRINTF2("[%04x],AL\n", offset);
7660 TRACE_AND_STEP();
7661 store_data_byte(offset, M.x86.R_AL);
7662 DECODE_CLEAR_SEGOVR();
7663 END_OF_INSTR();
7664}
7665
7666/****************************************************************************
7667REMARKS:
7668Handles opcode 0xa3
7669****************************************************************************/
7670static void
7671x86emuOp_mov_M_AX_IMM(u8 X86EMU_UNUSED(op1))
7672{
7673 u16 offset;
7674
7675 START_OF_INSTR();
7676 offset = fetch_word_imm();
7677 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7678 DECODE_PRINTF2("MOV\t[%04x],EAX\n", offset);
7679 }
7680 else {
7681 DECODE_PRINTF2("MOV\t[%04x],AX\n", offset);
7682 }
7683 TRACE_AND_STEP();
7684 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7685 store_data_long(offset, M.x86.R_EAX);
7686 }
7687 else {
7688 store_data_word(offset, M.x86.R_AX);
7689 }
7690 DECODE_CLEAR_SEGOVR();
7691 END_OF_INSTR();
7692}
7693
7694/****************************************************************************
7695REMARKS:
7696Handles opcode 0xa4
7697****************************************************************************/
7698static void
7699x86emuOp_movs_byte(u8 X86EMU_UNUSED(op1))
7700{
7701 u8 val;
7702 u32 count;
7703 int inc;
7704
7705 START_OF_INSTR();
7706 DECODE_PRINTF("MOVS\tBYTE\n");
7707 if (ACCESS_FLAG(F_DF)) /* down */
7708 inc = -1;
7709 else
7710 inc = 1;
7711 TRACE_AND_STEP();
7712 count = 1;
7713 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7714 /* dont care whether REPE or REPNE */
7715 /* move them until CX is ZERO. */
7716 count = M.x86.R_CX;
7717 M.x86.R_CX = 0;
7718 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7719 }
7720 while (count--) {
7721 val = fetch_data_byte(M.x86.R_SI);
7722 store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, val);
7723 M.x86.R_SI += inc;
7724 M.x86.R_DI += inc;
7725 }
7726 DECODE_CLEAR_SEGOVR();
7727 END_OF_INSTR();
7728}
7729
7730/****************************************************************************
7731REMARKS:
7732Handles opcode 0xa5
7733****************************************************************************/
7734static void
7735x86emuOp_movs_word(u8 X86EMU_UNUSED(op1))
7736{
7737 u32 val;
7738 int inc;
7739 u32 count;
7740
7741 START_OF_INSTR();
7742 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7743 DECODE_PRINTF("MOVS\tDWORD\n");
7744 if (ACCESS_FLAG(F_DF)) /* down */
7745 inc = -4;
7746 else
7747 inc = 4;
7748 }
7749 else {
7750 DECODE_PRINTF("MOVS\tWORD\n");
7751 if (ACCESS_FLAG(F_DF)) /* down */
7752 inc = -2;
7753 else
7754 inc = 2;
7755 }
7756 TRACE_AND_STEP();
7757 count = 1;
7758 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7759 /* dont care whether REPE or REPNE */
7760 /* move them until CX is ZERO. */
7761 count = M.x86.R_CX;
7762 M.x86.R_CX = 0;
7763 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7764 }
7765 while (count--) {
7766 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7767 val = fetch_data_long(M.x86.R_SI);
7768 store_data_long_abs(M.x86.R_ES, M.x86.R_DI, val);
7769 }
7770 else {
7771 val = fetch_data_word(M.x86.R_SI);
7772 store_data_word_abs(M.x86.R_ES, M.x86.R_DI, (u16) val);
7773 }
7774 M.x86.R_SI += inc;
7775 M.x86.R_DI += inc;
7776 }
7777 DECODE_CLEAR_SEGOVR();
7778 END_OF_INSTR();
7779}
7780
7781/****************************************************************************
7782REMARKS:
7783Handles opcode 0xa6
7784****************************************************************************/
7785static void
7786x86emuOp_cmps_byte(u8 X86EMU_UNUSED(op1))
7787{
7788 s8 val1, val2;
7789 int inc;
7790
7791 START_OF_INSTR();
7792 DECODE_PRINTF("CMPS\tBYTE\n");
7793 TRACE_AND_STEP();
7794 if (ACCESS_FLAG(F_DF)) /* down */
7795 inc = -1;
7796 else
7797 inc = 1;
7798
7799 if (M.x86.mode & SYSMODE_PREFIX_REPE) {
7800 /* REPE */
7801 /* move them until CX is ZERO. */
7802 while (M.x86.R_CX != 0) {
7803 val1 = fetch_data_byte(M.x86.R_SI);
7804 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7805 cmp_byte(val1, val2);
7806 M.x86.R_CX -= 1;
7807 M.x86.R_SI += inc;
7808 M.x86.R_DI += inc;
7809 if (ACCESS_FLAG(F_ZF) == 0)
7810 break;
7811 }
7812 M.x86.mode &= ~SYSMODE_PREFIX_REPE;
7813 }
7814 else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
7815 /* REPNE */
7816 /* move them until CX is ZERO. */
7817 while (M.x86.R_CX != 0) {
7818 val1 = fetch_data_byte(M.x86.R_SI);
7819 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7820 cmp_byte(val1, val2);
7821 M.x86.R_CX -= 1;
7822 M.x86.R_SI += inc;
7823 M.x86.R_DI += inc;
7824 if (ACCESS_FLAG(F_ZF))
7825 break; /* zero flag set means equal */
7826 }
7827 M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
7828 }
7829 else {
7830 val1 = fetch_data_byte(M.x86.R_SI);
7831 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7832 cmp_byte(val1, val2);
7833 M.x86.R_SI += inc;
7834 M.x86.R_DI += inc;
7835 }
7836 DECODE_CLEAR_SEGOVR();
7837 END_OF_INSTR();
7838}
7839
7840/****************************************************************************
7841REMARKS:
7842Handles opcode 0xa7
7843****************************************************************************/
7844static void
7845x86emuOp_cmps_word(u8 X86EMU_UNUSED(op1))
7846{
7847 u32 val1, val2;
7848 int inc;
7849
7850 START_OF_INSTR();
7851 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7852 DECODE_PRINTF("CMPS\tDWORD\n");
7853 if (ACCESS_FLAG(F_DF)) /* down */
7854 inc = -4;
7855 else
7856 inc = 4;
7857 }
7858 else {
7859 DECODE_PRINTF("CMPS\tWORD\n");
7860 if (ACCESS_FLAG(F_DF)) /* down */
7861 inc = -2;
7862 else
7863 inc = 2;
7864 }
7865 TRACE_AND_STEP();
7866 if (M.x86.mode & SYSMODE_PREFIX_REPE) {
7867 /* REPE */
7868 /* move them until CX is ZERO. */
7869 while (M.x86.R_CX != 0) {
7870 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7871 val1 = fetch_data_long(M.x86.R_SI);
7872 val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7873 cmp_long(val1, val2);
7874 }
7875 else {
7876 val1 = fetch_data_word(M.x86.R_SI);
7877 val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7878 cmp_word((u16) val1, (u16) val2);
7879 }
7880 M.x86.R_CX -= 1;
7881 M.x86.R_SI += inc;
7882 M.x86.R_DI += inc;
7883 if (ACCESS_FLAG(F_ZF) == 0)
7884 break;
7885 }
7886 M.x86.mode &= ~SYSMODE_PREFIX_REPE;
7887 }
7888 else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
7889 /* REPNE */
7890 /* move them until CX is ZERO. */
7891 while (M.x86.R_CX != 0) {
7892 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7893 val1 = fetch_data_long(M.x86.R_SI);
7894 val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7895 cmp_long(val1, val2);
7896 }
7897 else {
7898 val1 = fetch_data_word(M.x86.R_SI);
7899 val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7900 cmp_word((u16) val1, (u16) val2);
7901 }
7902 M.x86.R_CX -= 1;
7903 M.x86.R_SI += inc;
7904 M.x86.R_DI += inc;
7905 if (ACCESS_FLAG(F_ZF))
7906 break; /* zero flag set means equal */
7907 }
7908 M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
7909 }
7910 else {
7911 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7912 val1 = fetch_data_long(M.x86.R_SI);
7913 val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7914 cmp_long(val1, val2);
7915 }
7916 else {
7917 val1 = fetch_data_word(M.x86.R_SI);
7918 val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7919 cmp_word((u16) val1, (u16) val2);
7920 }
7921 M.x86.R_SI += inc;
7922 M.x86.R_DI += inc;
7923 }
7924 DECODE_CLEAR_SEGOVR();
7925 END_OF_INSTR();
7926}
7927
7928/****************************************************************************
7929REMARKS:
7930Handles opcode 0xa8
7931****************************************************************************/
7932static void
7933x86emuOp_test_AL_IMM(u8 X86EMU_UNUSED(op1))
7934{
7935 int imm;
7936
7937 START_OF_INSTR();
7938 DECODE_PRINTF("TEST\tAL,");
7939 imm = fetch_byte_imm();
7940 DECODE_PRINTF2("%04x\n", imm);
7941 TRACE_AND_STEP();
7942 test_byte(M.x86.R_AL, (u8) imm);
7943 DECODE_CLEAR_SEGOVR();
7944 END_OF_INSTR();
7945}
7946
7947/****************************************************************************
7948REMARKS:
7949Handles opcode 0xa9
7950****************************************************************************/
7951static void
7952x86emuOp_test_AX_IMM(u8 X86EMU_UNUSED(op1))
7953{
7954 u32 srcval;
7955
7956 START_OF_INSTR();
7957 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7958 DECODE_PRINTF("TEST\tEAX,");
7959 srcval = fetch_long_imm();
7960 }
7961 else {
7962 DECODE_PRINTF("TEST\tAX,");
7963 srcval = fetch_word_imm();
7964 }
7965 DECODE_PRINTF2("%x\n", srcval);
7966 TRACE_AND_STEP();
7967 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7968 test_long(M.x86.R_EAX, srcval);
7969 }
7970 else {
7971 test_word(M.x86.R_AX, (u16) srcval);
7972 }
7973 DECODE_CLEAR_SEGOVR();
7974 END_OF_INSTR();
7975}
7976
7977/****************************************************************************
7978REMARKS:
7979Handles opcode 0xaa
7980****************************************************************************/
7981static void
7982x86emuOp_stos_byte(u8 X86EMU_UNUSED(op1))
7983{
7984 int inc;
7985
7986 START_OF_INSTR();
7987 DECODE_PRINTF("STOS\tBYTE\n");
7988 if (ACCESS_FLAG(F_DF)) /* down */
7989 inc = -1;
7990 else
7991 inc = 1;
7992 TRACE_AND_STEP();
7993 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7994 /* dont care whether REPE or REPNE */
7995 /* move them until CX is ZERO. */
7996 while (M.x86.R_CX != 0) {
7997 store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL);
7998 M.x86.R_CX -= 1;
7999 M.x86.R_DI += inc;
8000 }
8001 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
8002 }
8003 else {
8004 store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL);
8005 M.x86.R_DI += inc;
8006 }
8007 DECODE_CLEAR_SEGOVR();
8008 END_OF_INSTR();
8009}
8010
8011/****************************************************************************
8012REMARKS:
8013Handles opcode 0xab
8014****************************************************************************/
8015static void
8016x86emuOp_stos_word(u8 X86EMU_UNUSED(op1))
8017{
8018 int inc;
8019 u32 count;
8020
8021 START_OF_INSTR();
8022 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8023 DECODE_PRINTF("STOS\tDWORD\n");
8024 if (ACCESS_FLAG(F_DF)) /* down */
8025 inc = -4;
8026 else
8027 inc = 4;
8028 }
8029 else {
8030 DECODE_PRINTF("STOS\tWORD\n");
8031 if (ACCESS_FLAG(F_DF)) /* down */
8032 inc = -2;
8033 else
8034 inc = 2;
8035 }
8036 TRACE_AND_STEP();
8037 count = 1;
8038 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
8039 /* dont care whether REPE or REPNE */
8040 /* move them until CX is ZERO. */
8041 count = M.x86.R_CX;
8042 M.x86.R_CX = 0;
8043 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
8044 }
8045 while (count--) {
8046 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8047 store_data_long_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_EAX);
8048 }
8049 else {
8050 store_data_word_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AX);
8051 }
8052 M.x86.R_DI += inc;
8053 }
8054 DECODE_CLEAR_SEGOVR();
8055 END_OF_INSTR();
8056}
8057
8058/****************************************************************************
8059REMARKS:
8060Handles opcode 0xac
8061****************************************************************************/
8062static void
8063x86emuOp_lods_byte(u8 X86EMU_UNUSED(op1))
8064{
8065 int inc;
8066
8067 START_OF_INSTR();
8068 DECODE_PRINTF("LODS\tBYTE\n");
8069 TRACE_AND_STEP();
8070 if (ACCESS_FLAG(F_DF)) /* down */
8071 inc = -1;
8072 else
8073 inc = 1;
8074 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
8075 /* dont care whether REPE or REPNE */
8076 /* move them until CX is ZERO. */
8077 while (M.x86.R_CX != 0) {
8078 M.x86.R_AL = fetch_data_byte(M.x86.R_SI);
8079 M.x86.R_CX -= 1;
8080 M.x86.R_SI += inc;
8081 }
8082 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
8083 }
8084 else {
8085 M.x86.R_AL = fetch_data_byte(M.x86.R_SI);
8086 M.x86.R_SI += inc;
8087 }
8088 DECODE_CLEAR_SEGOVR();
8089 END_OF_INSTR();
8090}
8091
8092/****************************************************************************
8093REMARKS:
8094Handles opcode 0xad
8095****************************************************************************/
8096static void
8097x86emuOp_lods_word(u8 X86EMU_UNUSED(op1))
8098{
8099 int inc;
8100 u32 count;
8101
8102 START_OF_INSTR();
8103 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8104 DECODE_PRINTF("LODS\tDWORD\n");
8105 if (ACCESS_FLAG(F_DF)) /* down */
8106 inc = -4;
8107 else
8108 inc = 4;
8109 }
8110 else {
8111 DECODE_PRINTF("LODS\tWORD\n");
8112 if (ACCESS_FLAG(F_DF)) /* down */
8113 inc = -2;
8114 else
8115 inc = 2;
8116 }
8117 TRACE_AND_STEP();
8118 count = 1;
8119 if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
8120 /* dont care whether REPE or REPNE */
8121 /* move them until CX is ZERO. */
8122 count = M.x86.R_CX;
8123 M.x86.R_CX = 0;
8124 M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
8125 }
8126 while (count--) {
8127 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8128 M.x86.R_EAX = fetch_data_long(M.x86.R_SI);
8129 }
8130 else {
8131 M.x86.R_AX = fetch_data_word(M.x86.R_SI);
8132 }
8133 M.x86.R_SI += inc;
8134 }
8135 DECODE_CLEAR_SEGOVR();
8136 END_OF_INSTR();
8137}
8138
8139/****************************************************************************
8140REMARKS:
8141Handles opcode 0xae
8142****************************************************************************/
8143static void
8144x86emuOp_scas_byte(u8 X86EMU_UNUSED(op1))
8145{
8146 s8 val2;
8147 int inc;
8148
8149 START_OF_INSTR();
8150 DECODE_PRINTF("SCAS\tBYTE\n");
8151 TRACE_AND_STEP();
8152 if (ACCESS_FLAG(F_DF)) /* down */
8153 inc = -1;
8154 else
8155 inc = 1;
8156 if (M.x86.mode & SYSMODE_PREFIX_REPE) {
8157 /* REPE */
8158 /* move them until CX is ZERO. */
8159 while (M.x86.R_CX != 0) {
8160 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
8161 cmp_byte(M.x86.R_AL, val2);
8162 M.x86.R_CX -= 1;
8163 M.x86.R_DI += inc;
8164 if (ACCESS_FLAG(F_ZF) == 0)
8165 break;
8166 }
8167 M.x86.mode &= ~SYSMODE_PREFIX_REPE;
8168 }
8169 else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
8170 /* REPNE */
8171 /* move them until CX is ZERO. */
8172 while (M.x86.R_CX != 0) {
8173 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
8174 cmp_byte(M.x86.R_AL, val2);
8175 M.x86.R_CX -= 1;
8176 M.x86.R_DI += inc;
8177 if (ACCESS_FLAG(F_ZF))
8178 break; /* zero flag set means equal */
8179 }
8180 M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
8181 }
8182 else {
8183 val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
8184 cmp_byte(M.x86.R_AL, val2);
8185 M.x86.R_DI += inc;
8186 }
8187 DECODE_CLEAR_SEGOVR();
8188 END_OF_INSTR();
8189}
8190
8191/****************************************************************************
8192REMARKS:
8193Handles opcode 0xaf
8194****************************************************************************/
8195static void
8196x86emuOp_scas_word(u8 X86EMU_UNUSED(op1))
8197{
8198 int inc;
8199 u32 val;
8200
8201 START_OF_INSTR();
8202 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8203 DECODE_PRINTF("SCAS\tDWORD\n");
8204 if (ACCESS_FLAG(F_DF)) /* down */
8205 inc = -4;
8206 else
8207 inc = 4;
8208 }
8209 else {
8210 DECODE_PRINTF("SCAS\tWORD\n");
8211 if (ACCESS_FLAG(F_DF)) /* down */
8212 inc = -2;
8213 else
8214 inc = 2;
8215 }
8216 TRACE_AND_STEP();
8217 if (M.x86.mode & SYSMODE_PREFIX_REPE) {
8218 /* REPE */
8219 /* move them until CX is ZERO. */
8220 while (M.x86.R_CX != 0) {
8221 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8222 val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
8223 cmp_long(M.x86.R_EAX, val);
8224 }
8225 else {
8226 val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
8227 cmp_word(M.x86.R_AX, (u16) val);
8228 }
8229 M.x86.R_CX -= 1;
8230 M.x86.R_DI += inc;
8231 if (ACCESS_FLAG(F_ZF) == 0)
8232 break;
8233 }
8234 M.x86.mode &= ~SYSMODE_PREFIX_REPE;
8235 }
8236 else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
8237 /* REPNE */
8238 /* move them until CX is ZERO. */
8239 while (M.x86.R_CX != 0) {
8240 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8241 val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
8242 cmp_long(M.x86.R_EAX, val);
8243 }
8244 else {
8245 val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
8246 cmp_word(M.x86.R_AX, (u16) val);
8247 }
8248 M.x86.R_CX -= 1;
8249 M.x86.R_DI += inc;
8250 if (ACCESS_FLAG(F_ZF))
8251 break; /* zero flag set means equal */
8252 }
8253 M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
8254 }
8255 else {
8256 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8257 val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
8258 cmp_long(M.x86.R_EAX, val);
8259 }
8260 else {
8261 val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
8262 cmp_word(M.x86.R_AX, (u16) val);
8263 }
8264 M.x86.R_DI += inc;
8265 }
8266 DECODE_CLEAR_SEGOVR();
8267 END_OF_INSTR();
8268}
8269
8270/****************************************************************************
8271REMARKS:
8272Handles opcode 0xb0
8273****************************************************************************/
8274static void
8275x86emuOp_mov_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
8276{
8277 u8 imm;
8278
8279 START_OF_INSTR();
8280 DECODE_PRINTF("MOV\tAL,");
8281 imm = fetch_byte_imm();
8282 DECODE_PRINTF2("%x\n", imm);
8283 TRACE_AND_STEP();
8284 M.x86.R_AL = imm;
8285 DECODE_CLEAR_SEGOVR();
8286 END_OF_INSTR();
8287}
8288
8289/****************************************************************************
8290REMARKS:
8291Handles opcode 0xb1
8292****************************************************************************/
8293static void
8294x86emuOp_mov_byte_CL_IMM(u8 X86EMU_UNUSED(op1))
8295{
8296 u8 imm;
8297
8298 START_OF_INSTR();
8299 DECODE_PRINTF("MOV\tCL,");
8300 imm = fetch_byte_imm();
8301 DECODE_PRINTF2("%x\n", imm);
8302 TRACE_AND_STEP();
8303 M.x86.R_CL = imm;
8304 DECODE_CLEAR_SEGOVR();
8305 END_OF_INSTR();
8306}
8307
8308/****************************************************************************
8309REMARKS:
8310Handles opcode 0xb2
8311****************************************************************************/
8312static void
8313x86emuOp_mov_byte_DL_IMM(u8 X86EMU_UNUSED(op1))
8314{
8315 u8 imm;
8316
8317 START_OF_INSTR();
8318 DECODE_PRINTF("MOV\tDL,");
8319 imm = fetch_byte_imm();
8320 DECODE_PRINTF2("%x\n", imm);
8321 TRACE_AND_STEP();
8322 M.x86.R_DL = imm;
8323 DECODE_CLEAR_SEGOVR();
8324 END_OF_INSTR();
8325}
8326
8327/****************************************************************************
8328REMARKS:
8329Handles opcode 0xb3
8330****************************************************************************/
8331static void
8332x86emuOp_mov_byte_BL_IMM(u8 X86EMU_UNUSED(op1))
8333{
8334 u8 imm;
8335
8336 START_OF_INSTR();
8337 DECODE_PRINTF("MOV\tBL,");
8338 imm = fetch_byte_imm();
8339 DECODE_PRINTF2("%x\n", imm);
8340 TRACE_AND_STEP();
8341 M.x86.R_BL = imm;
8342 DECODE_CLEAR_SEGOVR();
8343 END_OF_INSTR();
8344}
8345
8346/****************************************************************************
8347REMARKS:
8348Handles opcode 0xb4
8349****************************************************************************/
8350static void
8351x86emuOp_mov_byte_AH_IMM(u8 X86EMU_UNUSED(op1))
8352{
8353 u8 imm;
8354
8355 START_OF_INSTR();
8356 DECODE_PRINTF("MOV\tAH,");
8357 imm = fetch_byte_imm();
8358 DECODE_PRINTF2("%x\n", imm);
8359 TRACE_AND_STEP();
8360 M.x86.R_AH = imm;
8361 DECODE_CLEAR_SEGOVR();
8362 END_OF_INSTR();
8363}
8364
8365/****************************************************************************
8366REMARKS:
8367Handles opcode 0xb5
8368****************************************************************************/
8369static void
8370x86emuOp_mov_byte_CH_IMM(u8 X86EMU_UNUSED(op1))
8371{
8372 u8 imm;
8373
8374 START_OF_INSTR();
8375 DECODE_PRINTF("MOV\tCH,");
8376 imm = fetch_byte_imm();
8377 DECODE_PRINTF2("%x\n", imm);
8378 TRACE_AND_STEP();
8379 M.x86.R_CH = imm;
8380 DECODE_CLEAR_SEGOVR();
8381 END_OF_INSTR();
8382}
8383
8384/****************************************************************************
8385REMARKS:
8386Handles opcode 0xb6
8387****************************************************************************/
8388static void
8389x86emuOp_mov_byte_DH_IMM(u8 X86EMU_UNUSED(op1))
8390{
8391 u8 imm;
8392
8393 START_OF_INSTR();
8394 DECODE_PRINTF("MOV\tDH,");
8395 imm = fetch_byte_imm();
8396 DECODE_PRINTF2("%x\n", imm);
8397 TRACE_AND_STEP();
8398 M.x86.R_DH = imm;
8399 DECODE_CLEAR_SEGOVR();
8400 END_OF_INSTR();
8401}
8402
8403/****************************************************************************
8404REMARKS:
8405Handles opcode 0xb7
8406****************************************************************************/
8407static void
8408x86emuOp_mov_byte_BH_IMM(u8 X86EMU_UNUSED(op1))
8409{
8410 u8 imm;
8411
8412 START_OF_INSTR();
8413 DECODE_PRINTF("MOV\tBH,");
8414 imm = fetch_byte_imm();
8415 DECODE_PRINTF2("%x\n", imm);
8416 TRACE_AND_STEP();
8417 M.x86.R_BH = imm;
8418 DECODE_CLEAR_SEGOVR();
8419 END_OF_INSTR();
8420}
8421
8422/****************************************************************************
8423REMARKS:
8424Handles opcode 0xb8
8425****************************************************************************/
8426static void
8427x86emuOp_mov_word_AX_IMM(u8 X86EMU_UNUSED(op1))
8428{
8429 u32 srcval;
8430
8431 START_OF_INSTR();
8432 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8433 DECODE_PRINTF("MOV\tEAX,");
8434 srcval = fetch_long_imm();
8435 }
8436 else {
8437 DECODE_PRINTF("MOV\tAX,");
8438 srcval = fetch_word_imm();
8439 }
8440 DECODE_PRINTF2("%x\n", srcval);
8441 TRACE_AND_STEP();
8442 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8443 M.x86.R_EAX = srcval;
8444 }
8445 else {
8446 M.x86.R_AX = (u16) srcval;
8447 }
8448 DECODE_CLEAR_SEGOVR();
8449 END_OF_INSTR();
8450}
8451
8452/****************************************************************************
8453REMARKS:
8454Handles opcode 0xb9
8455****************************************************************************/
8456static void
8457x86emuOp_mov_word_CX_IMM(u8 X86EMU_UNUSED(op1))
8458{
8459 u32 srcval;
8460
8461 START_OF_INSTR();
8462 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8463 DECODE_PRINTF("MOV\tECX,");
8464 srcval = fetch_long_imm();
8465 }
8466 else {
8467 DECODE_PRINTF("MOV\tCX,");
8468 srcval = fetch_word_imm();
8469 }
8470 DECODE_PRINTF2("%x\n", srcval);
8471 TRACE_AND_STEP();
8472 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8473 M.x86.R_ECX = srcval;
8474 }
8475 else {
8476 M.x86.R_CX = (u16) srcval;
8477 }
8478 DECODE_CLEAR_SEGOVR();
8479 END_OF_INSTR();
8480}
8481
8482/****************************************************************************
8483REMARKS:
8484Handles opcode 0xba
8485****************************************************************************/
8486static void
8487x86emuOp_mov_word_DX_IMM(u8 X86EMU_UNUSED(op1))
8488{
8489 u32 srcval;
8490
8491 START_OF_INSTR();
8492 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8493 DECODE_PRINTF("MOV\tEDX,");
8494 srcval = fetch_long_imm();
8495 }
8496 else {
8497 DECODE_PRINTF("MOV\tDX,");
8498 srcval = fetch_word_imm();
8499 }
8500 DECODE_PRINTF2("%x\n", srcval);
8501 TRACE_AND_STEP();
8502 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8503 M.x86.R_EDX = srcval;
8504 }
8505 else {
8506 M.x86.R_DX = (u16) srcval;
8507 }
8508 DECODE_CLEAR_SEGOVR();
8509 END_OF_INSTR();
8510}
8511
8512/****************************************************************************
8513REMARKS:
8514Handles opcode 0xbb
8515****************************************************************************/
8516static void
8517x86emuOp_mov_word_BX_IMM(u8 X86EMU_UNUSED(op1))
8518{
8519 u32 srcval;
8520
8521 START_OF_INSTR();
8522 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8523 DECODE_PRINTF("MOV\tEBX,");
8524 srcval = fetch_long_imm();
8525 }
8526 else {
8527 DECODE_PRINTF("MOV\tBX,");
8528 srcval = fetch_word_imm();
8529 }
8530 DECODE_PRINTF2("%x\n", srcval);
8531 TRACE_AND_STEP();
8532 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8533 M.x86.R_EBX = srcval;
8534 }
8535 else {
8536 M.x86.R_BX = (u16) srcval;
8537 }
8538 DECODE_CLEAR_SEGOVR();
8539 END_OF_INSTR();
8540}
8541
8542/****************************************************************************
8543REMARKS:
8544Handles opcode 0xbc
8545****************************************************************************/
8546static void
8547x86emuOp_mov_word_SP_IMM(u8 X86EMU_UNUSED(op1))
8548{
8549 u32 srcval;
8550
8551 START_OF_INSTR();
8552 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8553 DECODE_PRINTF("MOV\tESP,");
8554 srcval = fetch_long_imm();
8555 }
8556 else {
8557 DECODE_PRINTF("MOV\tSP,");
8558 srcval = fetch_word_imm();
8559 }
8560 DECODE_PRINTF2("%x\n", srcval);
8561 TRACE_AND_STEP();
8562 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8563 M.x86.R_ESP = srcval;
8564 }
8565 else {
8566 M.x86.R_SP = (u16) srcval;
8567 }
8568 DECODE_CLEAR_SEGOVR();
8569 END_OF_INSTR();
8570}
8571
8572/****************************************************************************
8573REMARKS:
8574Handles opcode 0xbd
8575****************************************************************************/
8576static void
8577x86emuOp_mov_word_BP_IMM(u8 X86EMU_UNUSED(op1))
8578{
8579 u32 srcval;
8580
8581 START_OF_INSTR();
8582 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8583 DECODE_PRINTF("MOV\tEBP,");
8584 srcval = fetch_long_imm();
8585 }
8586 else {
8587 DECODE_PRINTF("MOV\tBP,");
8588 srcval = fetch_word_imm();
8589 }
8590 DECODE_PRINTF2("%x\n", srcval);
8591 TRACE_AND_STEP();
8592 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8593 M.x86.R_EBP = srcval;
8594 }
8595 else {
8596 M.x86.R_BP = (u16) srcval;
8597 }
8598 DECODE_CLEAR_SEGOVR();
8599 END_OF_INSTR();
8600}
8601
8602/****************************************************************************
8603REMARKS:
8604Handles opcode 0xbe
8605****************************************************************************/
8606static void
8607x86emuOp_mov_word_SI_IMM(u8 X86EMU_UNUSED(op1))
8608{
8609 u32 srcval;
8610
8611 START_OF_INSTR();
8612 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8613 DECODE_PRINTF("MOV\tESI,");
8614 srcval = fetch_long_imm();
8615 }
8616 else {
8617 DECODE_PRINTF("MOV\tSI,");
8618 srcval = fetch_word_imm();
8619 }
8620 DECODE_PRINTF2("%x\n", srcval);
8621 TRACE_AND_STEP();
8622 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8623 M.x86.R_ESI = srcval;
8624 }
8625 else {
8626 M.x86.R_SI = (u16) srcval;
8627 }
8628 DECODE_CLEAR_SEGOVR();
8629 END_OF_INSTR();
8630}
8631
8632/****************************************************************************
8633REMARKS:
8634Handles opcode 0xbf
8635****************************************************************************/
8636static void
8637x86emuOp_mov_word_DI_IMM(u8 X86EMU_UNUSED(op1))
8638{
8639 u32 srcval;
8640
8641 START_OF_INSTR();
8642 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8643 DECODE_PRINTF("MOV\tEDI,");
8644 srcval = fetch_long_imm();
8645 }
8646 else {
8647 DECODE_PRINTF("MOV\tDI,");
8648 srcval = fetch_word_imm();
8649 }
8650 DECODE_PRINTF2("%x\n", srcval);
8651 TRACE_AND_STEP();
8652 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8653 M.x86.R_EDI = srcval;
8654 }
8655 else {
8656 M.x86.R_DI = (u16) srcval;
8657 }
8658 DECODE_CLEAR_SEGOVR();
8659 END_OF_INSTR();
8660}
8661
8662/* used by opcodes c0, d0, and d2. */
8663static u8(*opcD0_byte_operation[]) (u8 d, u8 s) = {
8664 rol_byte, ror_byte, rcl_byte, rcr_byte, shl_byte, shr_byte, shl_byte, /* sal_byte === shl_byte by definition */
8665sar_byte,};
8666
8667/****************************************************************************
8668REMARKS:
8669Handles opcode 0xc0
8670****************************************************************************/
8671static void
8672x86emuOp_opcC0_byte_RM_MEM(u8 X86EMU_UNUSED(op1))
8673{
8674 int mod, rl, rh;
8675 u8 *destreg;
8676 uint destoffset;
8677 u8 destval;
8678 u8 amt;
8679
8680 /*
8681 * Yet another weirdo special case instruction format. Part of
8682 * the opcode held below in "RH". Doubly nested case would
8683 * result, except that the decoded instruction
8684 */
8685 START_OF_INSTR();
8686 FETCH_DECODE_MODRM(mod, rh, rl);
8687#ifdef DEBUG
8688 if (DEBUG_DECODE()) {
8689 /* XXX DECODE_PRINTF may be changed to something more
8690 general, so that it is important to leave the strings
8691 in the same format, even though the result is that the
8692 above test is done twice. */
8693
8694 switch (rh) {
8695 case 0:
8696 DECODE_PRINTF("ROL\t");
8697 break;
8698 case 1:
8699 DECODE_PRINTF("ROR\t");
8700 break;
8701 case 2:
8702 DECODE_PRINTF("RCL\t");
8703 break;
8704 case 3:
8705 DECODE_PRINTF("RCR\t");
8706 break;
8707 case 4:
8708 DECODE_PRINTF("SHL\t");
8709 break;
8710 case 5:
8711 DECODE_PRINTF("SHR\t");
8712 break;
8713 case 6:
8714 DECODE_PRINTF("SAL\t");
8715 break;
8716 case 7:
8717 DECODE_PRINTF("SAR\t");
8718 break;
8719 }
8720 }
8721#endif
8722 /* know operation, decode the mod byte to find the addressing
8723 mode. */
8724 switch (mod) {
8725 case 0:
8726 DECODE_PRINTF("BYTE PTR ");
8727 destoffset = decode_rm00_address(rl);
8728 amt = fetch_byte_imm();
8729 DECODE_PRINTF2(",%x\n", amt);
8730 destval = fetch_data_byte(destoffset);
8731 TRACE_AND_STEP();
8732 destval = (*opcD0_byte_operation[rh]) (destval, amt);
8733 store_data_byte(destoffset, destval);
8734 break;
8735 case 1:
8736 DECODE_PRINTF("BYTE PTR ");
8737 destoffset = decode_rm01_address(rl);
8738 amt = fetch_byte_imm();
8739 DECODE_PRINTF2(",%x\n", amt);
8740 destval = fetch_data_byte(destoffset);
8741 TRACE_AND_STEP();
8742 destval = (*opcD0_byte_operation[rh]) (destval, amt);
8743 store_data_byte(destoffset, destval);
8744 break;
8745 case 2:
8746 DECODE_PRINTF("BYTE PTR ");
8747 destoffset = decode_rm10_address(rl);
8748 amt = fetch_byte_imm();
8749 DECODE_PRINTF2(",%x\n", amt);
8750 destval = fetch_data_byte(destoffset);
8751 TRACE_AND_STEP();
8752 destval = (*opcD0_byte_operation[rh]) (destval, amt);
8753 store_data_byte(destoffset, destval);
8754 break;
8755 case 3: /* register to register */
8756 destreg = DECODE_RM_BYTE_REGISTER(rl);
8757 amt = fetch_byte_imm();
8758 DECODE_PRINTF2(",%x\n", amt);
8759 TRACE_AND_STEP();
8760 destval = (*opcD0_byte_operation[rh]) (*destreg, amt);
8761 *destreg = destval;
8762 break;
8763 }
8764 DECODE_CLEAR_SEGOVR();
8765 END_OF_INSTR();
8766}
8767
8768/* used by opcodes c1, d1, and d3. */
8769static u16(*opcD1_word_operation[]) (u16 s, u8 d) = {
8770 rol_word, ror_word, rcl_word, rcr_word, shl_word, shr_word, shl_word, /* sal_byte === shl_byte by definition */
8771sar_word,};
8772
8773/* used by opcodes c1, d1, and d3. */
8774static u32(*opcD1_long_operation[]) (u32 s, u8 d) = {
8775 rol_long, ror_long, rcl_long, rcr_long, shl_long, shr_long, shl_long, /* sal_byte === shl_byte by definition */
8776sar_long,};
8777
8778/****************************************************************************
8779REMARKS:
8780Handles opcode 0xc1
8781****************************************************************************/
8782static void
8783x86emuOp_opcC1_word_RM_MEM(u8 X86EMU_UNUSED(op1))
8784{
8785 int mod, rl, rh;
8786 uint destoffset;
8787 u8 amt;
8788
8789 /*
8790 * Yet another weirdo special case instruction format. Part of
8791 * the opcode held below in "RH". Doubly nested case would
8792 * result, except that the decoded instruction
8793 */
8794 START_OF_INSTR();
8795 FETCH_DECODE_MODRM(mod, rh, rl);
8796#ifdef DEBUG
8797 if (DEBUG_DECODE()) {
8798 /* XXX DECODE_PRINTF may be changed to something more
8799 general, so that it is important to leave the strings
8800 in the same format, even though the result is that the
8801 above test is done twice. */
8802
8803 switch (rh) {
8804 case 0:
8805 DECODE_PRINTF("ROL\t");
8806 break;
8807 case 1:
8808 DECODE_PRINTF("ROR\t");
8809 break;
8810 case 2:
8811 DECODE_PRINTF("RCL\t");
8812 break;
8813 case 3:
8814 DECODE_PRINTF("RCR\t");
8815 break;
8816 case 4:
8817 DECODE_PRINTF("SHL\t");
8818 break;
8819 case 5:
8820 DECODE_PRINTF("SHR\t");
8821 break;
8822 case 6:
8823 DECODE_PRINTF("SAL\t");
8824 break;
8825 case 7:
8826 DECODE_PRINTF("SAR\t");
8827 break;
8828 }
8829 }
8830#endif
8831 /* know operation, decode the mod byte to find the addressing
8832 mode. */
8833 switch (mod) {
8834 case 0:
8835 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8836 u32 destval;
8837
8838 DECODE_PRINTF("DWORD PTR ");
8839 destoffset = decode_rm00_address(rl);
8840 amt = fetch_byte_imm();
8841 DECODE_PRINTF2(",%x\n", amt);
8842 destval = fetch_data_long(destoffset);
8843 TRACE_AND_STEP();
8844 destval = (*opcD1_long_operation[rh]) (destval, amt);
8845 store_data_long(destoffset, destval);
8846 }
8847 else {
8848 u16 destval;
8849
8850 DECODE_PRINTF("WORD PTR ");
8851 destoffset = decode_rm00_address(rl);
8852 amt = fetch_byte_imm();
8853 DECODE_PRINTF2(",%x\n", amt);
8854 destval = fetch_data_word(destoffset);
8855 TRACE_AND_STEP();
8856 destval = (*opcD1_word_operation[rh]) (destval, amt);
8857 store_data_word(destoffset, destval);
8858 }
8859 break;
8860 case 1:
8861 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8862 u32 destval;
8863
8864 DECODE_PRINTF("DWORD PTR ");
8865 destoffset = decode_rm01_address(rl);
8866 amt = fetch_byte_imm();
8867 DECODE_PRINTF2(",%x\n", amt);
8868 destval = fetch_data_long(destoffset);
8869 TRACE_AND_STEP();
8870 destval = (*opcD1_long_operation[rh]) (destval, amt);
8871 store_data_long(destoffset, destval);
8872 }
8873 else {
8874 u16 destval;
8875
8876 DECODE_PRINTF("WORD PTR ");
8877 destoffset = decode_rm01_address(rl);
8878 amt = fetch_byte_imm();
8879 DECODE_PRINTF2(",%x\n", amt);
8880 destval = fetch_data_word(destoffset);
8881 TRACE_AND_STEP();
8882 destval = (*opcD1_word_operation[rh]) (destval, amt);
8883 store_data_word(destoffset, destval);
8884 }
8885 break;
8886 case 2:
8887 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8888 u32 destval;
8889
8890 DECODE_PRINTF("DWORD PTR ");
8891 destoffset = decode_rm10_address(rl);
8892 amt = fetch_byte_imm();
8893 DECODE_PRINTF2(",%x\n", amt);
8894 destval = fetch_data_long(destoffset);
8895 TRACE_AND_STEP();
8896 destval = (*opcD1_long_operation[rh]) (destval, amt);
8897 store_data_long(destoffset, destval);
8898 }
8899 else {
8900 u16 destval;
8901
8902 DECODE_PRINTF("WORD PTR ");
8903 destoffset = decode_rm10_address(rl);
8904 amt = fetch_byte_imm();
8905 DECODE_PRINTF2(",%x\n", amt);
8906 destval = fetch_data_word(destoffset);
8907 TRACE_AND_STEP();
8908 destval = (*opcD1_word_operation[rh]) (destval, amt);
8909 store_data_word(destoffset, destval);
8910 }
8911 break;
8912 case 3: /* register to register */
8913 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8914 u32 *destreg;
8915
8916 destreg = DECODE_RM_LONG_REGISTER(rl);
8917 amt = fetch_byte_imm();
8918 DECODE_PRINTF2(",%x\n", amt);
8919 TRACE_AND_STEP();
8920 *destreg = (*opcD1_long_operation[rh]) (*destreg, amt);
8921 }
8922 else {
8923 u16 *destreg;
8924
8925 destreg = DECODE_RM_WORD_REGISTER(rl);
8926 amt = fetch_byte_imm();
8927 DECODE_PRINTF2(",%x\n", amt);
8928 TRACE_AND_STEP();
8929 *destreg = (*opcD1_word_operation[rh]) (*destreg, amt);
8930 }
8931 break;
8932 }
8933 DECODE_CLEAR_SEGOVR();
8934 END_OF_INSTR();
8935}
8936
8937/****************************************************************************
8938REMARKS:
8939Handles opcode 0xc2
8940****************************************************************************/
8941static void
8942x86emuOp_ret_near_IMM(u8 X86EMU_UNUSED(op1))
8943{
8944 u16 imm;
8945
8946 START_OF_INSTR();
8947 DECODE_PRINTF("RET\t");
8948 imm = fetch_word_imm();
8949 DECODE_PRINTF2("%x\n", imm);
8950 RETURN_TRACE("RET", M.x86.saved_cs, M.x86.saved_ip);
8951 TRACE_AND_STEP();
8952 M.x86.R_IP = pop_word();
8953 M.x86.R_SP += imm;
8954 DECODE_CLEAR_SEGOVR();
8955 END_OF_INSTR();
8956}
8957
8958/****************************************************************************
8959REMARKS:
8960Handles opcode 0xc3
8961****************************************************************************/
8962static void
8963x86emuOp_ret_near(u8 X86EMU_UNUSED(op1))
8964{
8965 START_OF_INSTR();
8966 DECODE_PRINTF("RET\n");
8967 RETURN_TRACE("RET", M.x86.saved_cs, M.x86.saved_ip);
8968 TRACE_AND_STEP();
8969 M.x86.R_IP = pop_word();
8970 DECODE_CLEAR_SEGOVR();
8971 END_OF_INSTR();
8972}
8973
8974/****************************************************************************
8975REMARKS:
8976Handles opcode 0xc4
8977****************************************************************************/
8978static void
8979x86emuOp_les_R_IMM(u8 X86EMU_UNUSED(op1))
8980{
8981 int mod, rh, rl;
8982 u16 *dstreg;
8983 uint srcoffset;
8984
8985 START_OF_INSTR();
8986 DECODE_PRINTF("LES\t");
8987 FETCH_DECODE_MODRM(mod, rh, rl);
8988 switch (mod) {
8989 case 0:
8990 dstreg = DECODE_RM_WORD_REGISTER(rh);
8991 DECODE_PRINTF(",");
8992 srcoffset = decode_rm00_address(rl);
8993 DECODE_PRINTF("\n");
8994 TRACE_AND_STEP();
8995 *dstreg = fetch_data_word(srcoffset);
8996 M.x86.R_ES = fetch_data_word(srcoffset + 2);
8997 break;
8998 case 1:
8999 dstreg = DECODE_RM_WORD_REGISTER(rh);
9000 DECODE_PRINTF(",");
9001 srcoffset = decode_rm01_address(rl);
9002 DECODE_PRINTF("\n");
9003 TRACE_AND_STEP();
9004 *dstreg = fetch_data_word(srcoffset);
9005 M.x86.R_ES = fetch_data_word(srcoffset + 2);
9006 break;
9007 case 2:
9008 dstreg = DECODE_RM_WORD_REGISTER(rh);
9009 DECODE_PRINTF(",");
9010 srcoffset = decode_rm10_address(rl);
9011 DECODE_PRINTF("\n");
9012 TRACE_AND_STEP();
9013 *dstreg = fetch_data_word(srcoffset);
9014 M.x86.R_ES = fetch_data_word(srcoffset + 2);
9015 break;
9016 case 3: /* register to register */
9017 /* UNDEFINED! */
9018 TRACE_AND_STEP();
9019 }
9020 DECODE_CLEAR_SEGOVR();
9021 END_OF_INSTR();
9022}
9023
9024/****************************************************************************
9025REMARKS:
9026Handles opcode 0xc5
9027****************************************************************************/
9028static void
9029x86emuOp_lds_R_IMM(u8 X86EMU_UNUSED(op1))
9030{
9031 int mod, rh, rl;
9032 u16 *dstreg;
9033 uint srcoffset;
9034
9035 START_OF_INSTR();
9036 DECODE_PRINTF("LDS\t");
9037 FETCH_DECODE_MODRM(mod, rh, rl);
9038 switch (mod) {
9039 case 0:
9040 dstreg = DECODE_RM_WORD_REGISTER(rh);
9041 DECODE_PRINTF(",");
9042 srcoffset = decode_rm00_address(rl);
9043 DECODE_PRINTF("\n");
9044 TRACE_AND_STEP();
9045 *dstreg = fetch_data_word(srcoffset);
9046 M.x86.R_DS = fetch_data_word(srcoffset + 2);
9047 break;
9048 case 1:
9049 dstreg = DECODE_RM_WORD_REGISTER(rh);
9050 DECODE_PRINTF(",");
9051 srcoffset = decode_rm01_address(rl);
9052 DECODE_PRINTF("\n");
9053 TRACE_AND_STEP();
9054 *dstreg = fetch_data_word(srcoffset);
9055 M.x86.R_DS = fetch_data_word(srcoffset + 2);
9056 break;
9057 case 2:
9058 dstreg = DECODE_RM_WORD_REGISTER(rh);
9059 DECODE_PRINTF(",");
9060 srcoffset = decode_rm10_address(rl);
9061 DECODE_PRINTF("\n");
9062 TRACE_AND_STEP();
9063 *dstreg = fetch_data_word(srcoffset);
9064 M.x86.R_DS = fetch_data_word(srcoffset + 2);
9065 break;
9066 case 3: /* register to register */
9067 /* UNDEFINED! */
9068 TRACE_AND_STEP();
9069 }
9070 DECODE_CLEAR_SEGOVR();
9071 END_OF_INSTR();
9072}
9073
9074/****************************************************************************
9075REMARKS:
9076Handles opcode 0xc6
9077****************************************************************************/
9078static void
9079x86emuOp_mov_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
9080{
9081 int mod, rl, rh;
9082 u8 *destreg;
9083 uint destoffset;
9084 u8 imm;
9085
9086 START_OF_INSTR();
9087 DECODE_PRINTF("MOV\t");
9088 FETCH_DECODE_MODRM(mod, rh, rl);
9089 if (rh != 0) {
9090 DECODE_PRINTF("ILLEGAL DECODE OF OPCODE c6\n");
9091 HALT_SYS();
9092 }
9093 switch (mod) {
9094 case 0:
9095 DECODE_PRINTF("BYTE PTR ");
9096 destoffset = decode_rm00_address(rl);
9097 imm = fetch_byte_imm();
9098 DECODE_PRINTF2(",%2x\n", imm);
9099 TRACE_AND_STEP();
9100 store_data_byte(destoffset, imm);
9101 break;
9102 case 1:
9103 DECODE_PRINTF("BYTE PTR ");
9104 destoffset = decode_rm01_address(rl);
9105 imm = fetch_byte_imm();
9106 DECODE_PRINTF2(",%2x\n", imm);
9107 TRACE_AND_STEP();
9108 store_data_byte(destoffset, imm);
9109 break;
9110 case 2:
9111 DECODE_PRINTF("BYTE PTR ");
9112 destoffset = decode_rm10_address(rl);
9113 imm = fetch_byte_imm();
9114 DECODE_PRINTF2(",%2x\n", imm);
9115 TRACE_AND_STEP();
9116 store_data_byte(destoffset, imm);
9117 break;
9118 case 3: /* register to register */
9119 destreg = DECODE_RM_BYTE_REGISTER(rl);
9120 imm = fetch_byte_imm();
9121 DECODE_PRINTF2(",%2x\n", imm);
9122 TRACE_AND_STEP();
9123 *destreg = imm;
9124 break;
9125 }
9126 DECODE_CLEAR_SEGOVR();
9127 END_OF_INSTR();
9128}
9129
9130/****************************************************************************
9131REMARKS:
9132Handles opcode 0xc7
9133****************************************************************************/
9134static void
9135x86emuOp_mov_word_RM_IMM(u8 X86EMU_UNUSED(op1))
9136{
9137 int mod, rl, rh;
9138 uint destoffset;
9139
9140 START_OF_INSTR();
9141 DECODE_PRINTF("MOV\t");
9142 FETCH_DECODE_MODRM(mod, rh, rl);
9143 if (rh != 0) {
9144 DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n");
9145 HALT_SYS();
9146 }
9147 switch (mod) {
9148 case 0:
9149 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9150 u32 imm;
9151
9152 DECODE_PRINTF("DWORD PTR ");
9153 destoffset = decode_rm00_address(rl);
9154 imm = fetch_long_imm();
9155 DECODE_PRINTF2(",%x\n", imm);
9156 TRACE_AND_STEP();
9157 store_data_long(destoffset, imm);
9158 }
9159 else {
9160 u16 imm;
9161
9162 DECODE_PRINTF("WORD PTR ");
9163 destoffset = decode_rm00_address(rl);
9164 imm = fetch_word_imm();
9165 DECODE_PRINTF2(",%x\n", imm);
9166 TRACE_AND_STEP();
9167 store_data_word(destoffset, imm);
9168 }
9169 break;
9170 case 1:
9171 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9172 u32 imm;
9173
9174 DECODE_PRINTF("DWORD PTR ");
9175 destoffset = decode_rm01_address(rl);
9176 imm = fetch_long_imm();
9177 DECODE_PRINTF2(",%x\n", imm);
9178 TRACE_AND_STEP();
9179 store_data_long(destoffset, imm);
9180 }
9181 else {
9182 u16 imm;
9183
9184 DECODE_PRINTF("WORD PTR ");
9185 destoffset = decode_rm01_address(rl);
9186 imm = fetch_word_imm();
9187 DECODE_PRINTF2(",%x\n", imm);
9188 TRACE_AND_STEP();
9189 store_data_word(destoffset, imm);
9190 }
9191 break;
9192 case 2:
9193 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9194 u32 imm;
9195
9196 DECODE_PRINTF("DWORD PTR ");
9197 destoffset = decode_rm10_address(rl);
9198 imm = fetch_long_imm();
9199 DECODE_PRINTF2(",%x\n", imm);
9200 TRACE_AND_STEP();
9201 store_data_long(destoffset, imm);
9202 }
9203 else {
9204 u16 imm;
9205
9206 DECODE_PRINTF("WORD PTR ");
9207 destoffset = decode_rm10_address(rl);
9208 imm = fetch_word_imm();
9209 DECODE_PRINTF2(",%x\n", imm);
9210 TRACE_AND_STEP();
9211 store_data_word(destoffset, imm);
9212 }
9213 break;
9214 case 3: /* register to register */
9215 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9216 u32 *destreg;
9217 u32 imm;
9218
9219 destreg = DECODE_RM_LONG_REGISTER(rl);
9220 imm = fetch_long_imm();
9221 DECODE_PRINTF2(",%x\n", imm);
9222 TRACE_AND_STEP();
9223 *destreg = imm;
9224 }
9225 else {
9226 u16 *destreg;
9227 u16 imm;
9228
9229 destreg = DECODE_RM_WORD_REGISTER(rl);
9230 imm = fetch_word_imm();
9231 DECODE_PRINTF2(",%x\n", imm);
9232 TRACE_AND_STEP();
9233 *destreg = imm;
9234 }
9235 break;
9236 }
9237 DECODE_CLEAR_SEGOVR();
9238 END_OF_INSTR();
9239}
9240
9241/****************************************************************************
9242REMARKS:
9243Handles opcode 0xc8
9244****************************************************************************/
9245static void
9246x86emuOp_enter(u8 X86EMU_UNUSED(op1))
9247{
9248 u16 local, frame_pointer;
9249 u8 nesting;
9250 int i;
9251
9252 START_OF_INSTR();
9253 local = fetch_word_imm();
9254 nesting = fetch_byte_imm();
9255 DECODE_PRINTF2("ENTER %x\n", local);
9256 DECODE_PRINTF2(",%x\n", nesting);
9257 TRACE_AND_STEP();
9258 push_word(M.x86.R_BP);
9259 frame_pointer = M.x86.R_SP;
9260 if (nesting > 0) {
9261 for (i = 1; i < nesting; i++) {
9262 M.x86.R_BP -= 2;
9263 push_word(fetch_data_word_abs(M.x86.R_SS, M.x86.R_BP));
9264 }
9265 push_word(frame_pointer);
9266 }
9267 M.x86.R_BP = frame_pointer;
9268 M.x86.R_SP = (u16) (M.x86.R_SP - local);
9269 DECODE_CLEAR_SEGOVR();
9270 END_OF_INSTR();
9271}
9272
9273/****************************************************************************
9274REMARKS:
9275Handles opcode 0xc9
9276****************************************************************************/
9277static void
9278x86emuOp_leave(u8 X86EMU_UNUSED(op1))
9279{
9280 START_OF_INSTR();
9281 DECODE_PRINTF("LEAVE\n");
9282 TRACE_AND_STEP();
9283 M.x86.R_SP = M.x86.R_BP;
9284 M.x86.R_BP = pop_word();
9285 DECODE_CLEAR_SEGOVR();
9286 END_OF_INSTR();
9287}
9288
9289/****************************************************************************
9290REMARKS:
9291Handles opcode 0xca
9292****************************************************************************/
9293static void
9294x86emuOp_ret_far_IMM(u8 X86EMU_UNUSED(op1))
9295{
9296 u16 imm;
9297
9298 START_OF_INSTR();
9299 DECODE_PRINTF("RETF\t");
9300 imm = fetch_word_imm();
9301 DECODE_PRINTF2("%x\n", imm);
9302 RETURN_TRACE("RETF", M.x86.saved_cs, M.x86.saved_ip);
9303 TRACE_AND_STEP();
9304 M.x86.R_IP = pop_word();
9305 M.x86.R_CS = pop_word();
9306 M.x86.R_SP += imm;
9307 DECODE_CLEAR_SEGOVR();
9308 END_OF_INSTR();
9309}
9310
9311/****************************************************************************
9312REMARKS:
9313Handles opcode 0xcb
9314****************************************************************************/
9315static void
9316x86emuOp_ret_far(u8 X86EMU_UNUSED(op1))
9317{
9318 START_OF_INSTR();
9319 DECODE_PRINTF("RETF\n");
9320 RETURN_TRACE("RETF", M.x86.saved_cs, M.x86.saved_ip);
9321 TRACE_AND_STEP();
9322 M.x86.R_IP = pop_word();
9323 M.x86.R_CS = pop_word();
9324 DECODE_CLEAR_SEGOVR();
9325 END_OF_INSTR();
9326}
9327
9328/****************************************************************************
9329REMARKS:
9330Handles opcode 0xcc
9331****************************************************************************/
9332static void
9333x86emuOp_int3(u8 X86EMU_UNUSED(op1))
9334{
9335 START_OF_INSTR();
9336 DECODE_PRINTF("INT 3\n");
9337 TRACE_AND_STEP();
9338 if (_X86EMU_intrTab[3]) {
9339 (*_X86EMU_intrTab[3]) (3);
9340 }
9341 else {
9342 push_word((u16) M.x86.R_FLG);
9343 CLEAR_FLAG(F_IF);
9344 CLEAR_FLAG(F_TF);
9345 push_word(M.x86.R_CS);
9346 M.x86.R_CS = mem_access_word(3 * 4 + 2);
9347 push_word(M.x86.R_IP);
9348 M.x86.R_IP = mem_access_word(3 * 4);
9349 }
9350 DECODE_CLEAR_SEGOVR();
9351 END_OF_INSTR();
9352}
9353
9354/****************************************************************************
9355REMARKS:
9356Handles opcode 0xcd
9357****************************************************************************/
9358static void
9359x86emuOp_int_IMM(u8 X86EMU_UNUSED(op1))
9360{
9361 u8 intnum;
9362
9363 START_OF_INSTR();
9364 DECODE_PRINTF("INT\t");
9365 intnum = fetch_byte_imm();
9366 DECODE_PRINTF2("%x\n", intnum);
9367 TRACE_AND_STEP();
9368 if (_X86EMU_intrTab[intnum]) {
9369 (*_X86EMU_intrTab[intnum]) (intnum);
9370 }
9371 else {
9372 push_word((u16) M.x86.R_FLG);
9373 CLEAR_FLAG(F_IF);
9374 CLEAR_FLAG(F_TF);
9375 push_word(M.x86.R_CS);
9376 M.x86.R_CS = mem_access_word(intnum * 4 + 2);
9377 push_word(M.x86.R_IP);
9378 M.x86.R_IP = mem_access_word(intnum * 4);
9379 }
9380 DECODE_CLEAR_SEGOVR();
9381 END_OF_INSTR();
9382}
9383
9384/****************************************************************************
9385REMARKS:
9386Handles opcode 0xce
9387****************************************************************************/
9388static void
9389x86emuOp_into(u8 X86EMU_UNUSED(op1))
9390{
9391 START_OF_INSTR();
9392 DECODE_PRINTF("INTO\n");
9393 TRACE_AND_STEP();
9394 if (ACCESS_FLAG(F_OF)) {
9395 if (_X86EMU_intrTab[4]) {
9396 (*_X86EMU_intrTab[4]) (4);
9397 }
9398 else {
9399 push_word((u16) M.x86.R_FLG);
9400 CLEAR_FLAG(F_IF);
9401 CLEAR_FLAG(F_TF);
9402 push_word(M.x86.R_CS);
9403 M.x86.R_CS = mem_access_word(4 * 4 + 2);
9404 push_word(M.x86.R_IP);
9405 M.x86.R_IP = mem_access_word(4 * 4);
9406 }
9407 }
9408 DECODE_CLEAR_SEGOVR();
9409 END_OF_INSTR();
9410}
9411
9412/****************************************************************************
9413REMARKS:
9414Handles opcode 0xcf
9415****************************************************************************/
9416static void
9417x86emuOp_iret(u8 X86EMU_UNUSED(op1))
9418{
9419 START_OF_INSTR();
9420 DECODE_PRINTF("IRET\n");
9421
9422 TRACE_AND_STEP();
9423
9424 M.x86.R_IP = pop_word();
9425 M.x86.R_CS = pop_word();
9426 M.x86.R_FLG = pop_word();
9427 DECODE_CLEAR_SEGOVR();
9428 END_OF_INSTR();
9429}
9430
9431/****************************************************************************
9432REMARKS:
9433Handles opcode 0xd0
9434****************************************************************************/
9435static void
9436x86emuOp_opcD0_byte_RM_1(u8 X86EMU_UNUSED(op1))
9437{
9438 int mod, rl, rh;
9439 u8 *destreg;
9440 uint destoffset;
9441 u8 destval;
9442
9443 /*
9444 * Yet another weirdo special case instruction format. Part of
9445 * the opcode held below in "RH". Doubly nested case would
9446 * result, except that the decoded instruction
9447 */
9448 START_OF_INSTR();
9449 FETCH_DECODE_MODRM(mod, rh, rl);
9450#ifdef DEBUG
9451 if (DEBUG_DECODE()) {
9452 /* XXX DECODE_PRINTF may be changed to something more
9453 general, so that it is important to leave the strings
9454 in the same format, even though the result is that the
9455 above test is done twice. */
9456 switch (rh) {
9457 case 0:
9458 DECODE_PRINTF("ROL\t");
9459 break;
9460 case 1:
9461 DECODE_PRINTF("ROR\t");
9462 break;
9463 case 2:
9464 DECODE_PRINTF("RCL\t");
9465 break;
9466 case 3:
9467 DECODE_PRINTF("RCR\t");
9468 break;
9469 case 4:
9470 DECODE_PRINTF("SHL\t");
9471 break;
9472 case 5:
9473 DECODE_PRINTF("SHR\t");
9474 break;
9475 case 6:
9476 DECODE_PRINTF("SAL\t");
9477 break;
9478 case 7:
9479 DECODE_PRINTF("SAR\t");
9480 break;
9481 }
9482 }
9483#endif
9484 /* know operation, decode the mod byte to find the addressing
9485 mode. */
9486 switch (mod) {
9487 case 0:
9488 DECODE_PRINTF("BYTE PTR ");
9489 destoffset = decode_rm00_address(rl);
9490 DECODE_PRINTF(",1\n");
9491 destval = fetch_data_byte(destoffset);
9492 TRACE_AND_STEP();
9493 destval = (*opcD0_byte_operation[rh]) (destval, 1);
9494 store_data_byte(destoffset, destval);
9495 break;
9496 case 1:
9497 DECODE_PRINTF("BYTE PTR ");
9498 destoffset = decode_rm01_address(rl);
9499 DECODE_PRINTF(",1\n");
9500 destval = fetch_data_byte(destoffset);
9501 TRACE_AND_STEP();
9502 destval = (*opcD0_byte_operation[rh]) (destval, 1);
9503 store_data_byte(destoffset, destval);
9504 break;
9505 case 2:
9506 DECODE_PRINTF("BYTE PTR ");
9507 destoffset = decode_rm10_address(rl);
9508 DECODE_PRINTF(",1\n");
9509 destval = fetch_data_byte(destoffset);
9510 TRACE_AND_STEP();
9511 destval = (*opcD0_byte_operation[rh]) (destval, 1);
9512 store_data_byte(destoffset, destval);
9513 break;
9514 case 3: /* register to register */
9515 destreg = DECODE_RM_BYTE_REGISTER(rl);
9516 DECODE_PRINTF(",1\n");
9517 TRACE_AND_STEP();
9518 destval = (*opcD0_byte_operation[rh]) (*destreg, 1);
9519 *destreg = destval;
9520 break;
9521 }
9522 DECODE_CLEAR_SEGOVR();
9523 END_OF_INSTR();
9524}
9525
9526/****************************************************************************
9527REMARKS:
9528Handles opcode 0xd1
9529****************************************************************************/
9530static void
9531x86emuOp_opcD1_word_RM_1(u8 X86EMU_UNUSED(op1))
9532{
9533 int mod, rl, rh;
9534 uint destoffset;
9535
9536 /*
9537 * Yet another weirdo special case instruction format. Part of
9538 * the opcode held below in "RH". Doubly nested case would
9539 * result, except that the decoded instruction
9540 */
9541 START_OF_INSTR();
9542 FETCH_DECODE_MODRM(mod, rh, rl);
9543#ifdef DEBUG
9544 if (DEBUG_DECODE()) {
9545 /* XXX DECODE_PRINTF may be changed to something more
9546 general, so that it is important to leave the strings
9547 in the same format, even though the result is that the
9548 above test is done twice. */
9549 switch (rh) {
9550 case 0:
9551 DECODE_PRINTF("ROL\t");
9552 break;
9553 case 1:
9554 DECODE_PRINTF("ROR\t");
9555 break;
9556 case 2:
9557 DECODE_PRINTF("RCL\t");
9558 break;
9559 case 3:
9560 DECODE_PRINTF("RCR\t");
9561 break;
9562 case 4:
9563 DECODE_PRINTF("SHL\t");
9564 break;
9565 case 5:
9566 DECODE_PRINTF("SHR\t");
9567 break;
9568 case 6:
9569 DECODE_PRINTF("SAL\t");
9570 break;
9571 case 7:
9572 DECODE_PRINTF("SAR\t");
9573 break;
9574 }
9575 }
9576#endif
9577 /* know operation, decode the mod byte to find the addressing
9578 mode. */
9579 switch (mod) {
9580 case 0:
9581 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9582 u32 destval;
9583
9584 DECODE_PRINTF("DWORD PTR ");
9585 destoffset = decode_rm00_address(rl);
9586 DECODE_PRINTF(",1\n");
9587 destval = fetch_data_long(destoffset);
9588 TRACE_AND_STEP();
9589 destval = (*opcD1_long_operation[rh]) (destval, 1);
9590 store_data_long(destoffset, destval);
9591 }
9592 else {
9593 u16 destval;
9594
9595 DECODE_PRINTF("WORD PTR ");
9596 destoffset = decode_rm00_address(rl);
9597 DECODE_PRINTF(",1\n");
9598 destval = fetch_data_word(destoffset);
9599 TRACE_AND_STEP();
9600 destval = (*opcD1_word_operation[rh]) (destval, 1);
9601 store_data_word(destoffset, destval);
9602 }
9603 break;
9604 case 1:
9605 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9606 u32 destval;
9607
9608 DECODE_PRINTF("DWORD PTR ");
9609 destoffset = decode_rm01_address(rl);
9610 DECODE_PRINTF(",1\n");
9611 destval = fetch_data_long(destoffset);
9612 TRACE_AND_STEP();
9613 destval = (*opcD1_long_operation[rh]) (destval, 1);
9614 store_data_long(destoffset, destval);
9615 }
9616 else {
9617 u16 destval;
9618
9619 DECODE_PRINTF("WORD PTR ");
9620 destoffset = decode_rm01_address(rl);
9621 DECODE_PRINTF(",1\n");
9622 destval = fetch_data_word(destoffset);
9623 TRACE_AND_STEP();
9624 destval = (*opcD1_word_operation[rh]) (destval, 1);
9625 store_data_word(destoffset, destval);
9626 }
9627 break;
9628 case 2:
9629 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9630 u32 destval;
9631
9632 DECODE_PRINTF("DWORD PTR ");
9633 destoffset = decode_rm10_address(rl);
9634 DECODE_PRINTF(",1\n");
9635 destval = fetch_data_long(destoffset);
9636 TRACE_AND_STEP();
9637 destval = (*opcD1_long_operation[rh]) (destval, 1);
9638 store_data_long(destoffset, destval);
9639 }
9640 else {
9641 u16 destval;
9642
9643 DECODE_PRINTF("BYTE PTR ");
9644 destoffset = decode_rm10_address(rl);
9645 DECODE_PRINTF(",1\n");
9646 destval = fetch_data_word(destoffset);
9647 TRACE_AND_STEP();
9648 destval = (*opcD1_word_operation[rh]) (destval, 1);
9649 store_data_word(destoffset, destval);
9650 }
9651 break;
9652 case 3: /* register to register */
9653 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9654 u32 destval;
9655 u32 *destreg;
9656
9657 destreg = DECODE_RM_LONG_REGISTER(rl);
9658 DECODE_PRINTF(",1\n");
9659 TRACE_AND_STEP();
9660 destval = (*opcD1_long_operation[rh]) (*destreg, 1);
9661 *destreg = destval;
9662 }
9663 else {
9664 u16 destval;
9665 u16 *destreg;
9666
9667 destreg = DECODE_RM_WORD_REGISTER(rl);
9668 DECODE_PRINTF(",1\n");
9669 TRACE_AND_STEP();
9670 destval = (*opcD1_word_operation[rh]) (*destreg, 1);
9671 *destreg = destval;
9672 }
9673 break;
9674 }
9675 DECODE_CLEAR_SEGOVR();
9676 END_OF_INSTR();
9677}
9678
9679/****************************************************************************
9680REMARKS:
9681Handles opcode 0xd2
9682****************************************************************************/
9683static void
9684x86emuOp_opcD2_byte_RM_CL(u8 X86EMU_UNUSED(op1))
9685{
9686 int mod, rl, rh;
9687 u8 *destreg;
9688 uint destoffset;
9689 u8 destval;
9690 u8 amt;
9691
9692 /*
9693 * Yet another weirdo special case instruction format. Part of
9694 * the opcode held below in "RH". Doubly nested case would
9695 * result, except that the decoded instruction
9696 */
9697 START_OF_INSTR();
9698 FETCH_DECODE_MODRM(mod, rh, rl);
9699#ifdef DEBUG
9700 if (DEBUG_DECODE()) {
9701 /* XXX DECODE_PRINTF may be changed to something more
9702 general, so that it is important to leave the strings
9703 in the same format, even though the result is that the
9704 above test is done twice. */
9705 switch (rh) {
9706 case 0:
9707 DECODE_PRINTF("ROL\t");
9708 break;
9709 case 1:
9710 DECODE_PRINTF("ROR\t");
9711 break;
9712 case 2:
9713 DECODE_PRINTF("RCL\t");
9714 break;
9715 case 3:
9716 DECODE_PRINTF("RCR\t");
9717 break;
9718 case 4:
9719 DECODE_PRINTF("SHL\t");
9720 break;
9721 case 5:
9722 DECODE_PRINTF("SHR\t");
9723 break;
9724 case 6:
9725 DECODE_PRINTF("SAL\t");
9726 break;
9727 case 7:
9728 DECODE_PRINTF("SAR\t");
9729 break;
9730 }
9731 }
9732#endif
9733 /* know operation, decode the mod byte to find the addressing
9734 mode. */
9735 amt = M.x86.R_CL;
9736 switch (mod) {
9737 case 0:
9738 DECODE_PRINTF("BYTE PTR ");
9739 destoffset = decode_rm00_address(rl);
9740 DECODE_PRINTF(",CL\n");
9741 destval = fetch_data_byte(destoffset);
9742 TRACE_AND_STEP();
9743 destval = (*opcD0_byte_operation[rh]) (destval, amt);
9744 store_data_byte(destoffset, destval);
9745 break;
9746 case 1:
9747 DECODE_PRINTF("BYTE PTR ");
9748 destoffset = decode_rm01_address(rl);
9749 DECODE_PRINTF(",CL\n");
9750 destval = fetch_data_byte(destoffset);
9751 TRACE_AND_STEP();
9752 destval = (*opcD0_byte_operation[rh]) (destval, amt);
9753 store_data_byte(destoffset, destval);
9754 break;
9755 case 2:
9756 DECODE_PRINTF("BYTE PTR ");
9757 destoffset = decode_rm10_address(rl);
9758 DECODE_PRINTF(",CL\n");
9759 destval = fetch_data_byte(destoffset);
9760 TRACE_AND_STEP();
9761 destval = (*opcD0_byte_operation[rh]) (destval, amt);
9762 store_data_byte(destoffset, destval);
9763 break;
9764 case 3: /* register to register */
9765 destreg = DECODE_RM_BYTE_REGISTER(rl);
9766 DECODE_PRINTF(",CL\n");
9767 TRACE_AND_STEP();
9768 destval = (*opcD0_byte_operation[rh]) (*destreg, amt);
9769 *destreg = destval;
9770 break;
9771 }
9772 DECODE_CLEAR_SEGOVR();
9773 END_OF_INSTR();
9774}
9775
9776/****************************************************************************
9777REMARKS:
9778Handles opcode 0xd3
9779****************************************************************************/
9780static void
9781x86emuOp_opcD3_word_RM_CL(u8 X86EMU_UNUSED(op1))
9782{
9783 int mod, rl, rh;
9784 uint destoffset;
9785 u8 amt;
9786
9787 /*
9788 * Yet another weirdo special case instruction format. Part of
9789 * the opcode held below in "RH". Doubly nested case would
9790 * result, except that the decoded instruction
9791 */
9792 START_OF_INSTR();
9793 FETCH_DECODE_MODRM(mod, rh, rl);
9794#ifdef DEBUG
9795 if (DEBUG_DECODE()) {
9796 /* XXX DECODE_PRINTF may be changed to something more
9797 general, so that it is important to leave the strings
9798 in the same format, even though the result is that the
9799 above test is done twice. */
9800 switch (rh) {
9801 case 0:
9802 DECODE_PRINTF("ROL\t");
9803 break;
9804 case 1:
9805 DECODE_PRINTF("ROR\t");
9806 break;
9807 case 2:
9808 DECODE_PRINTF("RCL\t");
9809 break;
9810 case 3:
9811 DECODE_PRINTF("RCR\t");
9812 break;
9813 case 4:
9814 DECODE_PRINTF("SHL\t");
9815 break;
9816 case 5:
9817 DECODE_PRINTF("SHR\t");
9818 break;
9819 case 6:
9820 DECODE_PRINTF("SAL\t");
9821 break;
9822 case 7:
9823 DECODE_PRINTF("SAR\t");
9824 break;
9825 }
9826 }
9827#endif
9828 /* know operation, decode the mod byte to find the addressing
9829 mode. */
9830 amt = M.x86.R_CL;
9831 switch (mod) {
9832 case 0:
9833 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9834 u32 destval;
9835
9836 DECODE_PRINTF("DWORD PTR ");
9837 destoffset = decode_rm00_address(rl);
9838 DECODE_PRINTF(",CL\n");
9839 destval = fetch_data_long(destoffset);
9840 TRACE_AND_STEP();
9841 destval = (*opcD1_long_operation[rh]) (destval, amt);
9842 store_data_long(destoffset, destval);
9843 }
9844 else {
9845 u16 destval;
9846
9847 DECODE_PRINTF("WORD PTR ");
9848 destoffset = decode_rm00_address(rl);
9849 DECODE_PRINTF(",CL\n");
9850 destval = fetch_data_word(destoffset);
9851 TRACE_AND_STEP();
9852 destval = (*opcD1_word_operation[rh]) (destval, amt);
9853 store_data_word(destoffset, destval);
9854 }
9855 break;
9856 case 1:
9857 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9858 u32 destval;
9859
9860 DECODE_PRINTF("DWORD PTR ");
9861 destoffset = decode_rm01_address(rl);
9862 DECODE_PRINTF(",CL\n");
9863 destval = fetch_data_long(destoffset);
9864 TRACE_AND_STEP();
9865 destval = (*opcD1_long_operation[rh]) (destval, amt);
9866 store_data_long(destoffset, destval);
9867 }
9868 else {
9869 u16 destval;
9870
9871 DECODE_PRINTF("WORD PTR ");
9872 destoffset = decode_rm01_address(rl);
9873 DECODE_PRINTF(",CL\n");
9874 destval = fetch_data_word(destoffset);
9875 TRACE_AND_STEP();
9876 destval = (*opcD1_word_operation[rh]) (destval, amt);
9877 store_data_word(destoffset, destval);
9878 }
9879 break;
9880 case 2:
9881 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9882 u32 destval;
9883
9884 DECODE_PRINTF("DWORD PTR ");
9885 destoffset = decode_rm10_address(rl);
9886 DECODE_PRINTF(",CL\n");
9887 destval = fetch_data_long(destoffset);
9888 TRACE_AND_STEP();
9889 destval = (*opcD1_long_operation[rh]) (destval, amt);
9890 store_data_long(destoffset, destval);
9891 }
9892 else {
9893 u16 destval;
9894
9895 DECODE_PRINTF("WORD PTR ");
9896 destoffset = decode_rm10_address(rl);
9897 DECODE_PRINTF(",CL\n");
9898 destval = fetch_data_word(destoffset);
9899 TRACE_AND_STEP();
9900 destval = (*opcD1_word_operation[rh]) (destval, amt);
9901 store_data_word(destoffset, destval);
9902 }
9903 break;
9904 case 3: /* register to register */
9905 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9906 u32 *destreg;
9907
9908 destreg = DECODE_RM_LONG_REGISTER(rl);
9909 DECODE_PRINTF(",CL\n");
9910 TRACE_AND_STEP();
9911 *destreg = (*opcD1_long_operation[rh]) (*destreg, amt);
9912 }
9913 else {
9914 u16 *destreg;
9915
9916 destreg = DECODE_RM_WORD_REGISTER(rl);
9917 DECODE_PRINTF(",CL\n");
9918 TRACE_AND_STEP();
9919 *destreg = (*opcD1_word_operation[rh]) (*destreg, amt);
9920 }
9921 break;
9922 }
9923 DECODE_CLEAR_SEGOVR();
9924 END_OF_INSTR();
9925}
9926
9927/****************************************************************************
9928REMARKS:
9929Handles opcode 0xd4
9930****************************************************************************/
9931static void
9932x86emuOp_aam(u8 X86EMU_UNUSED(op1))
9933{
9934 u8 a;
9935
9936 START_OF_INSTR();
9937 DECODE_PRINTF("AAM\n");
9938 a = fetch_byte_imm(); /* this is a stupid encoding. */
9939 if (a != 10) {
9940 /* fix: add base decoding
9941 aam_word(u8 val, int base a) */
9942 DECODE_PRINTF("ERROR DECODING AAM\n");
9943 TRACE_REGS();
9944 HALT_SYS();
9945 }
9946 TRACE_AND_STEP();
9947 /* note the type change here --- returning AL and AH in AX. */
9948 M.x86.R_AX = aam_word(M.x86.R_AL);
9949 DECODE_CLEAR_SEGOVR();
9950 END_OF_INSTR();
9951}
9952
9953/****************************************************************************
9954REMARKS:
9955Handles opcode 0xd5
9956****************************************************************************/
9957static void
9958x86emuOp_aad(u8 X86EMU_UNUSED(op1))
9959{
9960 u8 a;
9961
9962 START_OF_INSTR();
9963 DECODE_PRINTF("AAD\n");
9964 a = fetch_byte_imm();
9965 if (a != 10) {
9966 /* fix: add base decoding
9967 aad_word(u16 val, int base a) */
9968 DECODE_PRINTF("ERROR DECODING AAM\n");
9969 TRACE_REGS();
9970 HALT_SYS();
9971 }
9972 TRACE_AND_STEP();
9973 M.x86.R_AX = aad_word(M.x86.R_AX);
9974 DECODE_CLEAR_SEGOVR();
9975 END_OF_INSTR();
9976}
9977
9978/* opcode 0xd6 ILLEGAL OPCODE */
9979
9980/****************************************************************************
9981REMARKS:
9982Handles opcode 0xd7
9983****************************************************************************/
9984static void
9985x86emuOp_xlat(u8 X86EMU_UNUSED(op1))
9986{
9987 u16 addr;
9988
9989 START_OF_INSTR();
9990 DECODE_PRINTF("XLAT\n");
9991 TRACE_AND_STEP();
9992 addr = (u16) (M.x86.R_BX + (u8) M.x86.R_AL);
9993 M.x86.R_AL = fetch_data_byte(addr);
9994 DECODE_CLEAR_SEGOVR();
9995 END_OF_INSTR();
9996}
9997
9998/* instuctions D8 .. DF are in i87_ops.c */
9999
10000/****************************************************************************
10001REMARKS:
10002Handles opcode 0xe0
10003****************************************************************************/
10004static void
10005x86emuOp_loopne(u8 X86EMU_UNUSED(op1))
10006{
10007 s16 ip;
10008
10009 START_OF_INSTR();
10010 DECODE_PRINTF("LOOPNE\t");
10011 ip = (s8) fetch_byte_imm();
10012 ip += (s16) M.x86.R_IP;
10013 DECODE_PRINTF2("%04x\n", ip);
10014 TRACE_AND_STEP();
10015 M.x86.R_CX -= 1;
10016 if (M.x86.R_CX != 0 && !ACCESS_FLAG(F_ZF)) /* CX != 0 and !ZF */
10017 M.x86.R_IP = ip;
10018 DECODE_CLEAR_SEGOVR();
10019 END_OF_INSTR();
10020}
10021
10022/****************************************************************************
10023REMARKS:
10024Handles opcode 0xe1
10025****************************************************************************/
10026static void
10027x86emuOp_loope(u8 X86EMU_UNUSED(op1))
10028{
10029 s16 ip;
10030
10031 START_OF_INSTR();
10032 DECODE_PRINTF("LOOPE\t");
10033 ip = (s8) fetch_byte_imm();
10034 ip += (s16) M.x86.R_IP;
10035 DECODE_PRINTF2("%04x\n", ip);
10036 TRACE_AND_STEP();
10037 M.x86.R_CX -= 1;
10038 if (M.x86.R_CX != 0 && ACCESS_FLAG(F_ZF)) /* CX != 0 and ZF */
10039 M.x86.R_IP = ip;
10040 DECODE_CLEAR_SEGOVR();
10041 END_OF_INSTR();
10042}
10043
10044/****************************************************************************
10045REMARKS:
10046Handles opcode 0xe2
10047****************************************************************************/
10048static void
10049x86emuOp_loop(u8 X86EMU_UNUSED(op1))
10050{
10051 s16 ip;
10052
10053 START_OF_INSTR();
10054 DECODE_PRINTF("LOOP\t");
10055 ip = (s8) fetch_byte_imm();
10056 ip += (s16) M.x86.R_IP;
10057 DECODE_PRINTF2("%04x\n", ip);
10058 TRACE_AND_STEP();
10059 M.x86.R_CX -= 1;
10060 if (M.x86.R_CX != 0)
10061 M.x86.R_IP = ip;
10062 DECODE_CLEAR_SEGOVR();
10063 END_OF_INSTR();
10064}
10065
10066/****************************************************************************
10067REMARKS:
10068Handles opcode 0xe3
10069****************************************************************************/
10070static void
10071x86emuOp_jcxz(u8 X86EMU_UNUSED(op1))
10072{
10073 u16 target;
10074 s8 offset;
10075
10076 /* jump to byte offset if overflow flag is set */
10077 START_OF_INSTR();
10078 DECODE_PRINTF("JCXZ\t");
10079 offset = (s8) fetch_byte_imm();
10080 target = (u16) (M.x86.R_IP + offset);
10081 DECODE_PRINTF2("%x\n", target);
10082 TRACE_AND_STEP();
10083 if (M.x86.R_CX == 0)
10084 M.x86.R_IP = target;
10085 DECODE_CLEAR_SEGOVR();
10086 END_OF_INSTR();
10087}
10088
10089/****************************************************************************
10090REMARKS:
10091Handles opcode 0xe4
10092****************************************************************************/
10093static void
10094x86emuOp_in_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
10095{
10096 u8 port;
10097
10098 START_OF_INSTR();
10099 DECODE_PRINTF("IN\t");
10100 port = (u8) fetch_byte_imm();
10101 DECODE_PRINTF2("%x,AL\n", port);
10102 TRACE_AND_STEP();
10103 M.x86.R_AL = (*sys_inb) (port);
10104 DECODE_CLEAR_SEGOVR();
10105 END_OF_INSTR();
10106}
10107
10108/****************************************************************************
10109REMARKS:
10110Handles opcode 0xe5
10111****************************************************************************/
10112static void
10113x86emuOp_in_word_AX_IMM(u8 X86EMU_UNUSED(op1))
10114{
10115 u8 port;
10116
10117 START_OF_INSTR();
10118 DECODE_PRINTF("IN\t");
10119 port = (u8) fetch_byte_imm();
10120 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10121 DECODE_PRINTF2("EAX,%x\n", port);
10122 }
10123 else {
10124 DECODE_PRINTF2("AX,%x\n", port);
10125 }
10126 TRACE_AND_STEP();
10127 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10128 M.x86.R_EAX = (*sys_inl) (port);
10129 }
10130 else {
10131 M.x86.R_AX = (*sys_inw) (port);
10132 }
10133 DECODE_CLEAR_SEGOVR();
10134 END_OF_INSTR();
10135}
10136
10137/****************************************************************************
10138REMARKS:
10139Handles opcode 0xe6
10140****************************************************************************/
10141static void
10142x86emuOp_out_byte_IMM_AL(u8 X86EMU_UNUSED(op1))
10143{
10144 u8 port;
10145
10146 START_OF_INSTR();
10147 DECODE_PRINTF("OUT\t");
10148 port = (u8) fetch_byte_imm();
10149 DECODE_PRINTF2("%x,AL\n", port);
10150 TRACE_AND_STEP();
10151 (*sys_outb) (port, M.x86.R_AL);
10152 DECODE_CLEAR_SEGOVR();
10153 END_OF_INSTR();
10154}
10155
10156/****************************************************************************
10157REMARKS:
10158Handles opcode 0xe7
10159****************************************************************************/
10160static void
10161x86emuOp_out_word_IMM_AX(u8 X86EMU_UNUSED(op1))
10162{
10163 u8 port;
10164
10165 START_OF_INSTR();
10166 DECODE_PRINTF("OUT\t");
10167 port = (u8) fetch_byte_imm();
10168 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10169 DECODE_PRINTF2("%x,EAX\n", port);
10170 }
10171 else {
10172 DECODE_PRINTF2("%x,AX\n", port);
10173 }
10174 TRACE_AND_STEP();
10175 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10176 (*sys_outl) (port, M.x86.R_EAX);
10177 }
10178 else {
10179 (*sys_outw) (port, M.x86.R_AX);
10180 }
10181 DECODE_CLEAR_SEGOVR();
10182 END_OF_INSTR();
10183}
10184
10185/****************************************************************************
10186REMARKS:
10187Handles opcode 0xe8
10188****************************************************************************/
10189static void
10190x86emuOp_call_near_IMM(u8 X86EMU_UNUSED(op1))
10191{
10192 s16 ip16;
10193 s32 ip32;
10194
10195 START_OF_INSTR();
10196 DECODE_PRINTF("CALL\t");
10197 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10198 ip32 = (s32) fetch_long_imm();
10199 ip32 += (s16) M.x86.R_IP; /* CHECK SIGN */
10200 DECODE_PRINTF2("%04x\n", (u16) ip32);
10201 CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, M.x86.R_CS, ip32, "");
10202 }
10203 else {
10204 ip16 = (s16) fetch_word_imm();
10205 ip16 += (s16) M.x86.R_IP; /* CHECK SIGN */
10206 DECODE_PRINTF2("%04x\n", (u16) ip16);
10207 CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, M.x86.R_CS, ip16, "");
10208 }
10209 TRACE_AND_STEP();
10210 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10211 push_long(M.x86.R_EIP);
10212 M.x86.R_EIP = ip32 & 0xffff;
10213 }
10214 else {
10215 push_word(M.x86.R_IP);
10216 M.x86.R_EIP = ip16;
10217 }
10218 DECODE_CLEAR_SEGOVR();
10219 END_OF_INSTR();
10220}
10221
10222/****************************************************************************
10223REMARKS:
10224Handles opcode 0xe9
10225****************************************************************************/
10226static void
10227x86emuOp_jump_near_IMM(u8 X86EMU_UNUSED(op1))
10228{
10229 u32 ip;
10230
10231 START_OF_INSTR();
10232 DECODE_PRINTF("JMP\t");
10233 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10234 ip = (u32) fetch_long_imm();
10235 ip += (u32) M.x86.R_EIP;
10236 DECODE_PRINTF2("%08x\n", (u32) ip);
10237 TRACE_AND_STEP();
10238 M.x86.R_EIP = (u32) ip;
10239 }
10240 else {
10241 ip = (s16) fetch_word_imm();
10242 ip += (s16) M.x86.R_IP;
10243 DECODE_PRINTF2("%04x\n", (u16) ip);
10244 TRACE_AND_STEP();
10245 M.x86.R_IP = (u16) ip;
10246 }
10247 DECODE_CLEAR_SEGOVR();
10248 END_OF_INSTR();
10249}
10250
10251/****************************************************************************
10252REMARKS:
10253Handles opcode 0xea
10254****************************************************************************/
10255static void
10256x86emuOp_jump_far_IMM(u8 X86EMU_UNUSED(op1))
10257{
10258 u16 cs;
10259 u32 ip;
10260
10261 START_OF_INSTR();
10262 DECODE_PRINTF("JMP\tFAR ");
10263 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10264 ip = fetch_long_imm();
10265 }
10266 else {
10267 ip = fetch_word_imm();
10268 }
10269 cs = fetch_word_imm();
10270 DECODE_PRINTF2("%04x:", cs);
10271 DECODE_PRINTF2("%04x\n", ip);
10272 TRACE_AND_STEP();
10273 M.x86.R_EIP = ip & 0xffff;
10274 M.x86.R_CS = cs;
10275 DECODE_CLEAR_SEGOVR();
10276 END_OF_INSTR();
10277}
10278
10279/****************************************************************************
10280REMARKS:
10281Handles opcode 0xeb
10282****************************************************************************/
10283static void
10284x86emuOp_jump_byte_IMM(u8 X86EMU_UNUSED(op1))
10285{
10286 u16 target;
10287 s8 offset;
10288
10289 START_OF_INSTR();
10290 DECODE_PRINTF("JMP\t");
10291 offset = (s8) fetch_byte_imm();
10292 target = (u16) (M.x86.R_IP + offset);
10293 DECODE_PRINTF2("%x\n", target);
10294 TRACE_AND_STEP();
10295 M.x86.R_IP = target;
10296 DECODE_CLEAR_SEGOVR();
10297 END_OF_INSTR();
10298}
10299
10300/****************************************************************************
10301REMARKS:
10302Handles opcode 0xec
10303****************************************************************************/
10304static void
10305x86emuOp_in_byte_AL_DX(u8 X86EMU_UNUSED(op1))
10306{
10307 START_OF_INSTR();
10308 DECODE_PRINTF("IN\tAL,DX\n");
10309 TRACE_AND_STEP();
10310 M.x86.R_AL = (*sys_inb) (M.x86.R_DX);
10311 DECODE_CLEAR_SEGOVR();
10312 END_OF_INSTR();
10313}
10314
10315/****************************************************************************
10316REMARKS:
10317Handles opcode 0xed
10318****************************************************************************/
10319static void
10320x86emuOp_in_word_AX_DX(u8 X86EMU_UNUSED(op1))
10321{
10322 START_OF_INSTR();
10323 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10324 DECODE_PRINTF("IN\tEAX,DX\n");
10325 }
10326 else {
10327 DECODE_PRINTF("IN\tAX,DX\n");
10328 }
10329 TRACE_AND_STEP();
10330 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10331 M.x86.R_EAX = (*sys_inl) (M.x86.R_DX);
10332 }
10333 else {
10334 M.x86.R_AX = (*sys_inw) (M.x86.R_DX);
10335 }
10336 DECODE_CLEAR_SEGOVR();
10337 END_OF_INSTR();
10338}
10339
10340/****************************************************************************
10341REMARKS:
10342Handles opcode 0xee
10343****************************************************************************/
10344static void
10345x86emuOp_out_byte_DX_AL(u8 X86EMU_UNUSED(op1))
10346{
10347 START_OF_INSTR();
10348 DECODE_PRINTF("OUT\tDX,AL\n");
10349 TRACE_AND_STEP();
10350 (*sys_outb) (M.x86.R_DX, M.x86.R_AL);
10351 DECODE_CLEAR_SEGOVR();
10352 END_OF_INSTR();
10353}
10354
10355/****************************************************************************
10356REMARKS:
10357Handles opcode 0xef
10358****************************************************************************/
10359static void
10360x86emuOp_out_word_DX_AX(u8 X86EMU_UNUSED(op1))
10361{
10362 START_OF_INSTR();
10363 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10364 DECODE_PRINTF("OUT\tDX,EAX\n");
10365 }
10366 else {
10367 DECODE_PRINTF("OUT\tDX,AX\n");
10368 }
10369 TRACE_AND_STEP();
10370 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10371 (*sys_outl) (M.x86.R_DX, M.x86.R_EAX);
10372 }
10373 else {
10374 (*sys_outw) (M.x86.R_DX, M.x86.R_AX);
10375 }
10376 DECODE_CLEAR_SEGOVR();
10377 END_OF_INSTR();
10378}
10379
10380/****************************************************************************
10381REMARKS:
10382Handles opcode 0xf0
10383****************************************************************************/
10384static void
10385x86emuOp_lock(u8 X86EMU_UNUSED(op1))
10386{
10387 START_OF_INSTR();
10388 DECODE_PRINTF("LOCK:\n");
10389 TRACE_AND_STEP();
10390 DECODE_CLEAR_SEGOVR();
10391 END_OF_INSTR();
10392}
10393
10394/*opcode 0xf1 ILLEGAL OPERATION */
10395
10396/****************************************************************************
10397REMARKS:
10398Handles opcode 0xf2
10399****************************************************************************/
10400static void
10401x86emuOp_repne(u8 X86EMU_UNUSED(op1))
10402{
10403 START_OF_INSTR();
10404 DECODE_PRINTF("REPNE\n");
10405 TRACE_AND_STEP();
10406 M.x86.mode |= SYSMODE_PREFIX_REPNE;
10407 DECODE_CLEAR_SEGOVR();
10408 END_OF_INSTR();
10409}
10410
10411/****************************************************************************
10412REMARKS:
10413Handles opcode 0xf3
10414****************************************************************************/
10415static void
10416x86emuOp_repe(u8 X86EMU_UNUSED(op1))
10417{
10418 START_OF_INSTR();
10419 DECODE_PRINTF("REPE\n");
10420 TRACE_AND_STEP();
10421 M.x86.mode |= SYSMODE_PREFIX_REPE;
10422 DECODE_CLEAR_SEGOVR();
10423 END_OF_INSTR();
10424}
10425
10426/****************************************************************************
10427REMARKS:
10428Handles opcode 0xf4
10429****************************************************************************/
10430static void
10431x86emuOp_halt(u8 X86EMU_UNUSED(op1))
10432{
10433 START_OF_INSTR();
10434 DECODE_PRINTF("HALT\n");
10435 TRACE_AND_STEP();
10436 HALT_SYS();
10437 DECODE_CLEAR_SEGOVR();
10438 END_OF_INSTR();
10439}
10440
10441/****************************************************************************
10442REMARKS:
10443Handles opcode 0xf5
10444****************************************************************************/
10445static void
10446x86emuOp_cmc(u8 X86EMU_UNUSED(op1))
10447{
10448 /* complement the carry flag. */
10449 START_OF_INSTR();
10450 DECODE_PRINTF("CMC\n");
10451 TRACE_AND_STEP();
10452 TOGGLE_FLAG(F_CF);
10453 DECODE_CLEAR_SEGOVR();
10454 END_OF_INSTR();
10455}
10456
10457/****************************************************************************
10458REMARKS:
10459Handles opcode 0xf6
10460****************************************************************************/
10461static void
10462x86emuOp_opcF6_byte_RM(u8 X86EMU_UNUSED(op1))
10463{
10464 int mod, rl, rh;
10465 u8 *destreg;
10466 uint destoffset;
10467 u8 destval, srcval;
10468
10469 /* long, drawn out code follows. Double switch for a total
10470 of 32 cases. */
10471 START_OF_INSTR();
10472 FETCH_DECODE_MODRM(mod, rh, rl);
10473 switch (mod) {
10474 case 0: /* mod=00 */
10475 switch (rh) {
10476 case 0: /* test byte imm */
10477 DECODE_PRINTF("TEST\tBYTE PTR ");
10478 destoffset = decode_rm00_address(rl);
10479 DECODE_PRINTF(",");
10480 srcval = fetch_byte_imm();
10481 DECODE_PRINTF2("%02x\n", srcval);
10482 destval = fetch_data_byte(destoffset);
10483 TRACE_AND_STEP();
10484 test_byte(destval, srcval);
10485 break;
10486 case 1:
10487 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
10488 HALT_SYS();
10489 break;
10490 case 2:
10491 DECODE_PRINTF("NOT\tBYTE PTR ");
10492 destoffset = decode_rm00_address(rl);
10493 DECODE_PRINTF("\n");
10494 destval = fetch_data_byte(destoffset);
10495 TRACE_AND_STEP();
10496 destval = not_byte(destval);
10497 store_data_byte(destoffset, destval);
10498 break;
10499 case 3:
10500 DECODE_PRINTF("NEG\tBYTE PTR ");
10501 destoffset = decode_rm00_address(rl);
10502 DECODE_PRINTF("\n");
10503 destval = fetch_data_byte(destoffset);
10504 TRACE_AND_STEP();
10505 destval = neg_byte(destval);
10506 store_data_byte(destoffset, destval);
10507 break;
10508 case 4:
10509 DECODE_PRINTF("MUL\tBYTE PTR ");
10510 destoffset = decode_rm00_address(rl);
10511 DECODE_PRINTF("\n");
10512 destval = fetch_data_byte(destoffset);
10513 TRACE_AND_STEP();
10514 mul_byte(destval);
10515 break;
10516 case 5:
10517 DECODE_PRINTF("IMUL\tBYTE PTR ");
10518 destoffset = decode_rm00_address(rl);
10519 DECODE_PRINTF("\n");
10520 destval = fetch_data_byte(destoffset);
10521 TRACE_AND_STEP();
10522 imul_byte(destval);
10523 break;
10524 case 6:
10525 DECODE_PRINTF("DIV\tBYTE PTR ");
10526 destoffset = decode_rm00_address(rl);
10527 DECODE_PRINTF("\n");
10528 destval = fetch_data_byte(destoffset);
10529 TRACE_AND_STEP();
10530 div_byte(destval);
10531 break;
10532 case 7:
10533 DECODE_PRINTF("IDIV\tBYTE PTR ");
10534 destoffset = decode_rm00_address(rl);
10535 DECODE_PRINTF("\n");
10536 destval = fetch_data_byte(destoffset);
10537 TRACE_AND_STEP();
10538 idiv_byte(destval);
10539 break;
10540 }
10541 break; /* end mod==00 */
10542 case 1: /* mod=01 */
10543 switch (rh) {
10544 case 0: /* test byte imm */
10545 DECODE_PRINTF("TEST\tBYTE PTR ");
10546 destoffset = decode_rm01_address(rl);
10547 DECODE_PRINTF(",");
10548 srcval = fetch_byte_imm();
10549 DECODE_PRINTF2("%02x\n", srcval);
10550 destval = fetch_data_byte(destoffset);
10551 TRACE_AND_STEP();
10552 test_byte(destval, srcval);
10553 break;
10554 case 1:
10555 DECODE_PRINTF("ILLEGAL OP MOD=01 RH=01 OP=F6\n");
10556 HALT_SYS();
10557 break;
10558 case 2:
10559 DECODE_PRINTF("NOT\tBYTE PTR ");
10560 destoffset = decode_rm01_address(rl);
10561 DECODE_PRINTF("\n");
10562 destval = fetch_data_byte(destoffset);
10563 TRACE_AND_STEP();
10564 destval = not_byte(destval);
10565 store_data_byte(destoffset, destval);
10566 break;
10567 case 3:
10568 DECODE_PRINTF("NEG\tBYTE PTR ");
10569 destoffset = decode_rm01_address(rl);
10570 DECODE_PRINTF("\n");
10571 destval = fetch_data_byte(destoffset);
10572 TRACE_AND_STEP();
10573 destval = neg_byte(destval);
10574 store_data_byte(destoffset, destval);
10575 break;
10576 case 4:
10577 DECODE_PRINTF("MUL\tBYTE PTR ");
10578 destoffset = decode_rm01_address(rl);
10579 DECODE_PRINTF("\n");
10580 destval = fetch_data_byte(destoffset);
10581 TRACE_AND_STEP();
10582 mul_byte(destval);
10583 break;
10584 case 5:
10585 DECODE_PRINTF("IMUL\tBYTE PTR ");
10586 destoffset = decode_rm01_address(rl);
10587 DECODE_PRINTF("\n");
10588 destval = fetch_data_byte(destoffset);
10589 TRACE_AND_STEP();
10590 imul_byte(destval);
10591 break;
10592 case 6:
10593 DECODE_PRINTF("DIV\tBYTE PTR ");
10594 destoffset = decode_rm01_address(rl);
10595 DECODE_PRINTF("\n");
10596 destval = fetch_data_byte(destoffset);
10597 TRACE_AND_STEP();
10598 div_byte(destval);
10599 break;
10600 case 7:
10601 DECODE_PRINTF("IDIV\tBYTE PTR ");
10602 destoffset = decode_rm01_address(rl);
10603 DECODE_PRINTF("\n");
10604 destval = fetch_data_byte(destoffset);
10605 TRACE_AND_STEP();
10606 idiv_byte(destval);
10607 break;
10608 }
10609 break; /* end mod==01 */
10610 case 2: /* mod=10 */
10611 switch (rh) {
10612 case 0: /* test byte imm */
10613 DECODE_PRINTF("TEST\tBYTE PTR ");
10614 destoffset = decode_rm10_address(rl);
10615 DECODE_PRINTF(",");
10616 srcval = fetch_byte_imm();
10617 DECODE_PRINTF2("%02x\n", srcval);
10618 destval = fetch_data_byte(destoffset);
10619 TRACE_AND_STEP();
10620 test_byte(destval, srcval);
10621 break;
10622 case 1:
10623 DECODE_PRINTF("ILLEGAL OP MOD=10 RH=01 OP=F6\n");
10624 HALT_SYS();
10625 break;
10626 case 2:
10627 DECODE_PRINTF("NOT\tBYTE PTR ");
10628 destoffset = decode_rm10_address(rl);
10629 DECODE_PRINTF("\n");
10630 destval = fetch_data_byte(destoffset);
10631 TRACE_AND_STEP();
10632 destval = not_byte(destval);
10633 store_data_byte(destoffset, destval);
10634 break;
10635 case 3:
10636 DECODE_PRINTF("NEG\tBYTE PTR ");
10637 destoffset = decode_rm10_address(rl);
10638 DECODE_PRINTF("\n");
10639 destval = fetch_data_byte(destoffset);
10640 TRACE_AND_STEP();
10641 destval = neg_byte(destval);
10642 store_data_byte(destoffset, destval);
10643 break;
10644 case 4:
10645 DECODE_PRINTF("MUL\tBYTE PTR ");
10646 destoffset = decode_rm10_address(rl);
10647 DECODE_PRINTF("\n");
10648 destval = fetch_data_byte(destoffset);
10649 TRACE_AND_STEP();
10650 mul_byte(destval);
10651 break;
10652 case 5:
10653 DECODE_PRINTF("IMUL\tBYTE PTR ");
10654 destoffset = decode_rm10_address(rl);
10655 DECODE_PRINTF("\n");
10656 destval = fetch_data_byte(destoffset);
10657 TRACE_AND_STEP();
10658 imul_byte(destval);
10659 break;
10660 case 6:
10661 DECODE_PRINTF("DIV\tBYTE PTR ");
10662 destoffset = decode_rm10_address(rl);
10663 DECODE_PRINTF("\n");
10664 destval = fetch_data_byte(destoffset);
10665 TRACE_AND_STEP();
10666 div_byte(destval);
10667 break;
10668 case 7:
10669 DECODE_PRINTF("IDIV\tBYTE PTR ");
10670 destoffset = decode_rm10_address(rl);
10671 DECODE_PRINTF("\n");
10672 destval = fetch_data_byte(destoffset);
10673 TRACE_AND_STEP();
10674 idiv_byte(destval);
10675 break;
10676 }
10677 break; /* end mod==10 */
10678 case 3: /* mod=11 */
10679 switch (rh) {
10680 case 0: /* test byte imm */
10681 DECODE_PRINTF("TEST\t");
10682 destreg = DECODE_RM_BYTE_REGISTER(rl);
10683 DECODE_PRINTF(",");
10684 srcval = fetch_byte_imm();
10685 DECODE_PRINTF2("%02x\n", srcval);
10686 TRACE_AND_STEP();
10687 test_byte(*destreg, srcval);
10688 break;
10689 case 1:
10690 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
10691 HALT_SYS();
10692 break;
10693 case 2:
10694 DECODE_PRINTF("NOT\t");
10695 destreg = DECODE_RM_BYTE_REGISTER(rl);
10696 DECODE_PRINTF("\n");
10697 TRACE_AND_STEP();
10698 *destreg = not_byte(*destreg);
10699 break;
10700 case 3:
10701 DECODE_PRINTF("NEG\t");
10702 destreg = DECODE_RM_BYTE_REGISTER(rl);
10703 DECODE_PRINTF("\n");
10704 TRACE_AND_STEP();
10705 *destreg = neg_byte(*destreg);
10706 break;
10707 case 4:
10708 DECODE_PRINTF("MUL\t");
10709 destreg = DECODE_RM_BYTE_REGISTER(rl);
10710 DECODE_PRINTF("\n");
10711 TRACE_AND_STEP();
10712 mul_byte(*destreg); /*!!! */
10713 break;
10714 case 5:
10715 DECODE_PRINTF("IMUL\t");
10716 destreg = DECODE_RM_BYTE_REGISTER(rl);
10717 DECODE_PRINTF("\n");
10718 TRACE_AND_STEP();
10719 imul_byte(*destreg);
10720 break;
10721 case 6:
10722 DECODE_PRINTF("DIV\t");
10723 destreg = DECODE_RM_BYTE_REGISTER(rl);
10724 DECODE_PRINTF("\n");
10725 TRACE_AND_STEP();
10726 div_byte(*destreg);
10727 break;
10728 case 7:
10729 DECODE_PRINTF("IDIV\t");
10730 destreg = DECODE_RM_BYTE_REGISTER(rl);
10731 DECODE_PRINTF("\n");
10732 TRACE_AND_STEP();
10733 idiv_byte(*destreg);
10734 break;
10735 }
10736 break; /* end mod==11 */
10737 }
10738 DECODE_CLEAR_SEGOVR();
10739 END_OF_INSTR();
10740}
10741
10742/****************************************************************************
10743REMARKS:
10744Handles opcode 0xf7
10745****************************************************************************/
10746static void
10747x86emuOp_opcF7_word_RM(u8 X86EMU_UNUSED(op1))
10748{
10749 int mod, rl, rh;
10750 uint destoffset;
10751
10752 /* long, drawn out code follows. Double switch for a total
10753 of 32 cases. */
10754 START_OF_INSTR();
10755 FETCH_DECODE_MODRM(mod, rh, rl);
10756 switch (mod) {
10757 case 0: /* mod=00 */
10758 switch (rh) {
10759 case 0: /* test word imm */
10760 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10761 u32 destval, srcval;
10762
10763 DECODE_PRINTF("TEST\tDWORD PTR ");
10764 destoffset = decode_rm00_address(rl);
10765 DECODE_PRINTF(",");
10766 srcval = fetch_long_imm();
10767 DECODE_PRINTF2("%x\n", srcval);
10768 destval = fetch_data_long(destoffset);
10769 TRACE_AND_STEP();
10770 test_long(destval, srcval);
10771 }
10772 else {
10773 u16 destval, srcval;
10774
10775 DECODE_PRINTF("TEST\tWORD PTR ");
10776 destoffset = decode_rm00_address(rl);
10777 DECODE_PRINTF(",");
10778 srcval = fetch_word_imm();
10779 DECODE_PRINTF2("%x\n", srcval);
10780 destval = fetch_data_word(destoffset);
10781 TRACE_AND_STEP();
10782 test_word(destval, srcval);
10783 }
10784 break;
10785 case 1:
10786 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F7\n");
10787 HALT_SYS();
10788 break;
10789 case 2:
10790 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10791 u32 destval;
10792
10793 DECODE_PRINTF("NOT\tDWORD PTR ");
10794 destoffset = decode_rm00_address(rl);
10795 DECODE_PRINTF("\n");
10796 destval = fetch_data_long(destoffset);
10797 TRACE_AND_STEP();
10798 destval = not_long(destval);
10799 store_data_long(destoffset, destval);
10800 }
10801 else {
10802 u16 destval;
10803
10804 DECODE_PRINTF("NOT\tWORD PTR ");
10805 destoffset = decode_rm00_address(rl);
10806 DECODE_PRINTF("\n");
10807 destval = fetch_data_word(destoffset);
10808 TRACE_AND_STEP();
10809 destval = not_word(destval);
10810 store_data_word(destoffset, destval);
10811 }
10812 break;
10813 case 3:
10814 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10815 u32 destval;
10816
10817 DECODE_PRINTF("NEG\tDWORD PTR ");
10818 destoffset = decode_rm00_address(rl);
10819 DECODE_PRINTF("\n");
10820 destval = fetch_data_long(destoffset);
10821 TRACE_AND_STEP();
10822 destval = neg_long(destval);
10823 store_data_long(destoffset, destval);
10824 }
10825 else {
10826 u16 destval;
10827
10828 DECODE_PRINTF("NEG\tWORD PTR ");
10829 destoffset = decode_rm00_address(rl);
10830 DECODE_PRINTF("\n");
10831 destval = fetch_data_word(destoffset);
10832 TRACE_AND_STEP();
10833 destval = neg_word(destval);
10834 store_data_word(destoffset, destval);
10835 }
10836 break;
10837 case 4:
10838 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10839 u32 destval;
10840
10841 DECODE_PRINTF("MUL\tDWORD PTR ");
10842 destoffset = decode_rm00_address(rl);
10843 DECODE_PRINTF("\n");
10844 destval = fetch_data_long(destoffset);
10845 TRACE_AND_STEP();
10846 mul_long(destval);
10847 }
10848 else {
10849 u16 destval;
10850
10851 DECODE_PRINTF("MUL\tWORD PTR ");
10852 destoffset = decode_rm00_address(rl);
10853 DECODE_PRINTF("\n");
10854 destval = fetch_data_word(destoffset);
10855 TRACE_AND_STEP();
10856 mul_word(destval);
10857 }
10858 break;
10859 case 5:
10860 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10861 u32 destval;
10862
10863 DECODE_PRINTF("IMUL\tDWORD PTR ");
10864 destoffset = decode_rm00_address(rl);
10865 DECODE_PRINTF("\n");
10866 destval = fetch_data_long(destoffset);
10867 TRACE_AND_STEP();
10868 imul_long(destval);
10869 }
10870 else {
10871 u16 destval;
10872
10873 DECODE_PRINTF("IMUL\tWORD PTR ");
10874 destoffset = decode_rm00_address(rl);
10875 DECODE_PRINTF("\n");
10876 destval = fetch_data_word(destoffset);
10877 TRACE_AND_STEP();
10878 imul_word(destval);
10879 }
10880 break;
10881 case 6:
10882 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10883 u32 destval;
10884
10885 DECODE_PRINTF("DIV\tDWORD PTR ");
10886 destoffset = decode_rm00_address(rl);
10887 DECODE_PRINTF("\n");
10888 destval = fetch_data_long(destoffset);
10889 TRACE_AND_STEP();
10890 div_long(destval);
10891 }
10892 else {
10893 u16 destval;
10894
10895 DECODE_PRINTF("DIV\tWORD PTR ");
10896 destoffset = decode_rm00_address(rl);
10897 DECODE_PRINTF("\n");
10898 destval = fetch_data_word(destoffset);
10899 TRACE_AND_STEP();
10900 div_word(destval);
10901 }
10902 break;
10903 case 7:
10904 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10905 u32 destval;
10906
10907 DECODE_PRINTF("IDIV\tDWORD PTR ");
10908 destoffset = decode_rm00_address(rl);
10909 DECODE_PRINTF("\n");
10910 destval = fetch_data_long(destoffset);
10911 TRACE_AND_STEP();
10912 idiv_long(destval);
10913 }
10914 else {
10915 u16 destval;
10916
10917 DECODE_PRINTF("IDIV\tWORD PTR ");
10918 destoffset = decode_rm00_address(rl);
10919 DECODE_PRINTF("\n");
10920 destval = fetch_data_word(destoffset);
10921 TRACE_AND_STEP();
10922 idiv_word(destval);
10923 }
10924 break;
10925 }
10926 break; /* end mod==00 */
10927 case 1: /* mod=01 */
10928 switch (rh) {
10929 case 0: /* test word imm */
10930 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10931 u32 destval, srcval;
10932
10933 DECODE_PRINTF("TEST\tDWORD PTR ");
10934 destoffset = decode_rm01_address(rl);
10935 DECODE_PRINTF(",");
10936 srcval = fetch_long_imm();
10937 DECODE_PRINTF2("%x\n", srcval);
10938 destval = fetch_data_long(destoffset);
10939 TRACE_AND_STEP();
10940 test_long(destval, srcval);
10941 }
10942 else {
10943 u16 destval, srcval;
10944
10945 DECODE_PRINTF("TEST\tWORD PTR ");
10946 destoffset = decode_rm01_address(rl);
10947 DECODE_PRINTF(",");
10948 srcval = fetch_word_imm();
10949 DECODE_PRINTF2("%x\n", srcval);
10950 destval = fetch_data_word(destoffset);
10951 TRACE_AND_STEP();
10952 test_word(destval, srcval);
10953 }
10954 break;
10955 case 1:
10956 DECODE_PRINTF("ILLEGAL OP MOD=01 RH=01 OP=F6\n");
10957 HALT_SYS();
10958 break;
10959 case 2:
10960 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10961 u32 destval;
10962
10963 DECODE_PRINTF("NOT\tDWORD PTR ");
10964 destoffset = decode_rm01_address(rl);
10965 DECODE_PRINTF("\n");
10966 destval = fetch_data_long(destoffset);
10967 TRACE_AND_STEP();
10968 destval = not_long(destval);
10969 store_data_long(destoffset, destval);
10970 }
10971 else {
10972 u16 destval;
10973
10974 DECODE_PRINTF("NOT\tWORD PTR ");
10975 destoffset = decode_rm01_address(rl);
10976 DECODE_PRINTF("\n");
10977 destval = fetch_data_word(destoffset);
10978 TRACE_AND_STEP();
10979 destval = not_word(destval);
10980 store_data_word(destoffset, destval);
10981 }
10982 break;
10983 case 3:
10984 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10985 u32 destval;
10986
10987 DECODE_PRINTF("NEG\tDWORD PTR ");
10988 destoffset = decode_rm01_address(rl);
10989 DECODE_PRINTF("\n");
10990 destval = fetch_data_long(destoffset);
10991 TRACE_AND_STEP();
10992 destval = neg_long(destval);
10993 store_data_long(destoffset, destval);
10994 }
10995 else {
10996 u16 destval;
10997
10998 DECODE_PRINTF("NEG\tWORD PTR ");
10999 destoffset = decode_rm01_address(rl);
11000 DECODE_PRINTF("\n");
11001 destval = fetch_data_word(destoffset);
11002 TRACE_AND_STEP();
11003 destval = neg_word(destval);
11004 store_data_word(destoffset, destval);
11005 }
11006 break;
11007 case 4:
11008 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11009 u32 destval;
11010
11011 DECODE_PRINTF("MUL\tDWORD PTR ");
11012 destoffset = decode_rm01_address(rl);
11013 DECODE_PRINTF("\n");
11014 destval = fetch_data_long(destoffset);
11015 TRACE_AND_STEP();
11016 mul_long(destval);
11017 }
11018 else {
11019 u16 destval;
11020
11021 DECODE_PRINTF("MUL\tWORD PTR ");
11022 destoffset = decode_rm01_address(rl);
11023 DECODE_PRINTF("\n");
11024 destval = fetch_data_word(destoffset);
11025 TRACE_AND_STEP();
11026 mul_word(destval);
11027 }
11028 break;
11029 case 5:
11030 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11031 u32 destval;
11032
11033 DECODE_PRINTF("IMUL\tDWORD PTR ");
11034 destoffset = decode_rm01_address(rl);
11035 DECODE_PRINTF("\n");
11036 destval = fetch_data_long(destoffset);
11037 TRACE_AND_STEP();
11038 imul_long(destval);
11039 }
11040 else {
11041 u16 destval;
11042
11043 DECODE_PRINTF("IMUL\tWORD PTR ");
11044 destoffset = decode_rm01_address(rl);
11045 DECODE_PRINTF("\n");
11046 destval = fetch_data_word(destoffset);
11047 TRACE_AND_STEP();
11048 imul_word(destval);
11049 }
11050 break;
11051 case 6:
11052 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11053 u32 destval;
11054
11055 DECODE_PRINTF("DIV\tDWORD PTR ");
11056 destoffset = decode_rm01_address(rl);
11057 DECODE_PRINTF("\n");
11058 destval = fetch_data_long(destoffset);
11059 TRACE_AND_STEP();
11060 div_long(destval);
11061 }
11062 else {
11063 u16 destval;
11064
11065 DECODE_PRINTF("DIV\tWORD PTR ");
11066 destoffset = decode_rm01_address(rl);
11067 DECODE_PRINTF("\n");
11068 destval = fetch_data_word(destoffset);
11069 TRACE_AND_STEP();
11070 div_word(destval);
11071 }
11072 break;
11073 case 7:
11074 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11075 u32 destval;
11076
11077 DECODE_PRINTF("IDIV\tDWORD PTR ");
11078 destoffset = decode_rm01_address(rl);
11079 DECODE_PRINTF("\n");
11080 destval = fetch_data_long(destoffset);
11081 TRACE_AND_STEP();
11082 idiv_long(destval);
11083 }
11084 else {
11085 u16 destval;
11086
11087 DECODE_PRINTF("IDIV\tWORD PTR ");
11088 destoffset = decode_rm01_address(rl);
11089 DECODE_PRINTF("\n");
11090 destval = fetch_data_word(destoffset);
11091 TRACE_AND_STEP();
11092 idiv_word(destval);
11093 }
11094 break;
11095 }
11096 break; /* end mod==01 */
11097 case 2: /* mod=10 */
11098 switch (rh) {
11099 case 0: /* test word imm */
11100 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11101 u32 destval, srcval;
11102
11103 DECODE_PRINTF("TEST\tDWORD PTR ");
11104 destoffset = decode_rm10_address(rl);
11105 DECODE_PRINTF(",");
11106 srcval = fetch_long_imm();
11107 DECODE_PRINTF2("%x\n", srcval);
11108 destval = fetch_data_long(destoffset);
11109 TRACE_AND_STEP();
11110 test_long(destval, srcval);
11111 }
11112 else {
11113 u16 destval, srcval;
11114
11115 DECODE_PRINTF("TEST\tWORD PTR ");
11116 destoffset = decode_rm10_address(rl);
11117 DECODE_PRINTF(",");
11118 srcval = fetch_word_imm();
11119 DECODE_PRINTF2("%x\n", srcval);
11120 destval = fetch_data_word(destoffset);
11121 TRACE_AND_STEP();
11122 test_word(destval, srcval);
11123 }
11124 break;
11125 case 1:
11126 DECODE_PRINTF("ILLEGAL OP MOD=10 RH=01 OP=F6\n");
11127 HALT_SYS();
11128 break;
11129 case 2:
11130 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11131 u32 destval;
11132
11133 DECODE_PRINTF("NOT\tDWORD PTR ");
11134 destoffset = decode_rm10_address(rl);
11135 DECODE_PRINTF("\n");
11136 destval = fetch_data_long(destoffset);
11137 TRACE_AND_STEP();
11138 destval = not_long(destval);
11139 store_data_long(destoffset, destval);
11140 }
11141 else {
11142 u16 destval;
11143
11144 DECODE_PRINTF("NOT\tWORD PTR ");
11145 destoffset = decode_rm10_address(rl);
11146 DECODE_PRINTF("\n");
11147 destval = fetch_data_word(destoffset);
11148 TRACE_AND_STEP();
11149 destval = not_word(destval);
11150 store_data_word(destoffset, destval);
11151 }
11152 break;
11153 case 3:
11154 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11155 u32 destval;
11156
11157 DECODE_PRINTF("NEG\tDWORD PTR ");
11158 destoffset = decode_rm10_address(rl);
11159 DECODE_PRINTF("\n");
11160 destval = fetch_data_long(destoffset);
11161 TRACE_AND_STEP();
11162 destval = neg_long(destval);
11163 store_data_long(destoffset, destval);
11164 }
11165 else {
11166 u16 destval;
11167
11168 DECODE_PRINTF("NEG\tWORD PTR ");
11169 destoffset = decode_rm10_address(rl);
11170 DECODE_PRINTF("\n");
11171 destval = fetch_data_word(destoffset);
11172 TRACE_AND_STEP();
11173 destval = neg_word(destval);
11174 store_data_word(destoffset, destval);
11175 }
11176 break;
11177 case 4:
11178 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11179 u32 destval;
11180
11181 DECODE_PRINTF("MUL\tDWORD PTR ");
11182 destoffset = decode_rm10_address(rl);
11183 DECODE_PRINTF("\n");
11184 destval = fetch_data_long(destoffset);
11185 TRACE_AND_STEP();
11186 mul_long(destval);
11187 }
11188 else {
11189 u16 destval;
11190
11191 DECODE_PRINTF("MUL\tWORD PTR ");
11192 destoffset = decode_rm10_address(rl);
11193 DECODE_PRINTF("\n");
11194 destval = fetch_data_word(destoffset);
11195 TRACE_AND_STEP();
11196 mul_word(destval);
11197 }
11198 break;
11199 case 5:
11200 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11201 u32 destval;
11202
11203 DECODE_PRINTF("IMUL\tDWORD PTR ");
11204 destoffset = decode_rm10_address(rl);
11205 DECODE_PRINTF("\n");
11206 destval = fetch_data_long(destoffset);
11207 TRACE_AND_STEP();
11208 imul_long(destval);
11209 }
11210 else {
11211 u16 destval;
11212
11213 DECODE_PRINTF("IMUL\tWORD PTR ");
11214 destoffset = decode_rm10_address(rl);
11215 DECODE_PRINTF("\n");
11216 destval = fetch_data_word(destoffset);
11217 TRACE_AND_STEP();
11218 imul_word(destval);
11219 }
11220 break;
11221 case 6:
11222 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11223 u32 destval;
11224
11225 DECODE_PRINTF("DIV\tDWORD PTR ");
11226 destoffset = decode_rm10_address(rl);
11227 DECODE_PRINTF("\n");
11228 destval = fetch_data_long(destoffset);
11229 TRACE_AND_STEP();
11230 div_long(destval);
11231 }
11232 else {
11233 u16 destval;
11234
11235 DECODE_PRINTF("DIV\tWORD PTR ");
11236 destoffset = decode_rm10_address(rl);
11237 DECODE_PRINTF("\n");
11238 destval = fetch_data_word(destoffset);
11239 TRACE_AND_STEP();
11240 div_word(destval);
11241 }
11242 break;
11243 case 7:
11244 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11245 u32 destval;
11246
11247 DECODE_PRINTF("IDIV\tDWORD PTR ");
11248 destoffset = decode_rm10_address(rl);
11249 DECODE_PRINTF("\n");
11250 destval = fetch_data_long(destoffset);
11251 TRACE_AND_STEP();
11252 idiv_long(destval);
11253 }
11254 else {
11255 u16 destval;
11256
11257 DECODE_PRINTF("IDIV\tWORD PTR ");
11258 destoffset = decode_rm10_address(rl);
11259 DECODE_PRINTF("\n");
11260 destval = fetch_data_word(destoffset);
11261 TRACE_AND_STEP();
11262 idiv_word(destval);
11263 }
11264 break;
11265 }
11266 break; /* end mod==10 */
11267 case 3: /* mod=11 */
11268 switch (rh) {
11269 case 0: /* test word imm */
11270 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11271 u32 *destreg;
11272 u32 srcval;
11273
11274 DECODE_PRINTF("TEST\t");
11275 destreg = DECODE_RM_LONG_REGISTER(rl);
11276 DECODE_PRINTF(",");
11277 srcval = fetch_long_imm();
11278 DECODE_PRINTF2("%x\n", srcval);
11279 TRACE_AND_STEP();
11280 test_long(*destreg, srcval);
11281 }
11282 else {
11283 u16 *destreg;
11284 u16 srcval;
11285
11286 DECODE_PRINTF("TEST\t");
11287 destreg = DECODE_RM_WORD_REGISTER(rl);
11288 DECODE_PRINTF(",");
11289 srcval = fetch_word_imm();
11290 DECODE_PRINTF2("%x\n", srcval);
11291 TRACE_AND_STEP();
11292 test_word(*destreg, srcval);
11293 }
11294 break;
11295 case 1:
11296 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
11297 HALT_SYS();
11298 break;
11299 case 2:
11300 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11301 u32 *destreg;
11302
11303 DECODE_PRINTF("NOT\t");
11304 destreg = DECODE_RM_LONG_REGISTER(rl);
11305 DECODE_PRINTF("\n");
11306 TRACE_AND_STEP();
11307 *destreg = not_long(*destreg);
11308 }
11309 else {
11310 u16 *destreg;
11311
11312 DECODE_PRINTF("NOT\t");
11313 destreg = DECODE_RM_WORD_REGISTER(rl);
11314 DECODE_PRINTF("\n");
11315 TRACE_AND_STEP();
11316 *destreg = not_word(*destreg);
11317 }
11318 break;
11319 case 3:
11320 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11321 u32 *destreg;
11322
11323 DECODE_PRINTF("NEG\t");
11324 destreg = DECODE_RM_LONG_REGISTER(rl);
11325 DECODE_PRINTF("\n");
11326 TRACE_AND_STEP();
11327 *destreg = neg_long(*destreg);
11328 }
11329 else {
11330 u16 *destreg;
11331
11332 DECODE_PRINTF("NEG\t");
11333 destreg = DECODE_RM_WORD_REGISTER(rl);
11334 DECODE_PRINTF("\n");
11335 TRACE_AND_STEP();
11336 *destreg = neg_word(*destreg);
11337 }
11338 break;
11339 case 4:
11340 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11341 u32 *destreg;
11342
11343 DECODE_PRINTF("MUL\t");
11344 destreg = DECODE_RM_LONG_REGISTER(rl);
11345 DECODE_PRINTF("\n");
11346 TRACE_AND_STEP();
11347 mul_long(*destreg); /*!!! */
11348 }
11349 else {
11350 u16 *destreg;
11351
11352 DECODE_PRINTF("MUL\t");
11353 destreg = DECODE_RM_WORD_REGISTER(rl);
11354 DECODE_PRINTF("\n");
11355 TRACE_AND_STEP();
11356 mul_word(*destreg); /*!!! */
11357 }
11358 break;
11359 case 5:
11360 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11361 u32 *destreg;
11362
11363 DECODE_PRINTF("IMUL\t");
11364 destreg = DECODE_RM_LONG_REGISTER(rl);
11365 DECODE_PRINTF("\n");
11366 TRACE_AND_STEP();
11367 imul_long(*destreg);
11368 }
11369 else {
11370 u16 *destreg;
11371
11372 DECODE_PRINTF("IMUL\t");
11373 destreg = DECODE_RM_WORD_REGISTER(rl);
11374 DECODE_PRINTF("\n");
11375 TRACE_AND_STEP();
11376 imul_word(*destreg);
11377 }
11378 break;
11379 case 6:
11380 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11381 u32 *destreg;
11382
11383 DECODE_PRINTF("DIV\t");
11384 destreg = DECODE_RM_LONG_REGISTER(rl);
11385 DECODE_PRINTF("\n");
11386 TRACE_AND_STEP();
11387 div_long(*destreg);
11388 }
11389 else {
11390 u16 *destreg;
11391
11392 DECODE_PRINTF("DIV\t");
11393 destreg = DECODE_RM_WORD_REGISTER(rl);
11394 DECODE_PRINTF("\n");
11395 TRACE_AND_STEP();
11396 div_word(*destreg);
11397 }
11398 break;
11399 case 7:
11400 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11401 u32 *destreg;
11402
11403 DECODE_PRINTF("IDIV\t");
11404 destreg = DECODE_RM_LONG_REGISTER(rl);
11405 DECODE_PRINTF("\n");
11406 TRACE_AND_STEP();
11407 idiv_long(*destreg);
11408 }
11409 else {
11410 u16 *destreg;
11411
11412 DECODE_PRINTF("IDIV\t");
11413 destreg = DECODE_RM_WORD_REGISTER(rl);
11414 DECODE_PRINTF("\n");
11415 TRACE_AND_STEP();
11416 idiv_word(*destreg);
11417 }
11418 break;
11419 }
11420 break; /* end mod==11 */
11421 }
11422 DECODE_CLEAR_SEGOVR();
11423 END_OF_INSTR();
11424}
11425
11426/****************************************************************************
11427REMARKS:
11428Handles opcode 0xf8
11429****************************************************************************/
11430static void
11431x86emuOp_clc(u8 X86EMU_UNUSED(op1))
11432{
11433 /* clear the carry flag. */
11434 START_OF_INSTR();
11435 DECODE_PRINTF("CLC\n");
11436 TRACE_AND_STEP();
11437 CLEAR_FLAG(F_CF);
11438 DECODE_CLEAR_SEGOVR();
11439 END_OF_INSTR();
11440}
11441
11442/****************************************************************************
11443REMARKS:
11444Handles opcode 0xf9
11445****************************************************************************/
11446static void
11447x86emuOp_stc(u8 X86EMU_UNUSED(op1))
11448{
11449 /* set the carry flag. */
11450 START_OF_INSTR();
11451 DECODE_PRINTF("STC\n");
11452 TRACE_AND_STEP();
11453 SET_FLAG(F_CF);
11454 DECODE_CLEAR_SEGOVR();
11455 END_OF_INSTR();
11456}
11457
11458/****************************************************************************
11459REMARKS:
11460Handles opcode 0xfa
11461****************************************************************************/
11462static void
11463x86emuOp_cli(u8 X86EMU_UNUSED(op1))
11464{
11465 /* clear interrupts. */
11466 START_OF_INSTR();
11467 DECODE_PRINTF("CLI\n");
11468 TRACE_AND_STEP();
11469 CLEAR_FLAG(F_IF);
11470 DECODE_CLEAR_SEGOVR();
11471 END_OF_INSTR();
11472}
11473
11474/****************************************************************************
11475REMARKS:
11476Handles opcode 0xfb
11477****************************************************************************/
11478static void
11479x86emuOp_sti(u8 X86EMU_UNUSED(op1))
11480{
11481 /* enable interrupts. */
11482 START_OF_INSTR();
11483 DECODE_PRINTF("STI\n");
11484 TRACE_AND_STEP();
11485 SET_FLAG(F_IF);
11486 DECODE_CLEAR_SEGOVR();
11487 END_OF_INSTR();
11488}
11489
11490/****************************************************************************
11491REMARKS:
11492Handles opcode 0xfc
11493****************************************************************************/
11494static void
11495x86emuOp_cld(u8 X86EMU_UNUSED(op1))
11496{
11497 /* clear interrupts. */
11498 START_OF_INSTR();
11499 DECODE_PRINTF("CLD\n");
11500 TRACE_AND_STEP();
11501 CLEAR_FLAG(F_DF);
11502 DECODE_CLEAR_SEGOVR();
11503 END_OF_INSTR();
11504}
11505
11506/****************************************************************************
11507REMARKS:
11508Handles opcode 0xfd
11509****************************************************************************/
11510static void
11511x86emuOp_std(u8 X86EMU_UNUSED(op1))
11512{
11513 /* clear interrupts. */
11514 START_OF_INSTR();
11515 DECODE_PRINTF("STD\n");
11516 TRACE_AND_STEP();
11517 SET_FLAG(F_DF);
11518 DECODE_CLEAR_SEGOVR();
11519 END_OF_INSTR();
11520}
11521
11522/****************************************************************************
11523REMARKS:
11524Handles opcode 0xfe
11525****************************************************************************/
11526static void
11527x86emuOp_opcFE_byte_RM(u8 X86EMU_UNUSED(op1))
11528{
11529 int mod, rh, rl;
11530 u8 destval;
11531 uint destoffset;
11532 u8 *destreg;
11533
11534 /* Yet another special case instruction. */
11535 START_OF_INSTR();
11536 FETCH_DECODE_MODRM(mod, rh, rl);
11537#ifdef DEBUG
11538 if (DEBUG_DECODE()) {
11539 /* XXX DECODE_PRINTF may be changed to something more
11540 general, so that it is important to leave the strings
11541 in the same format, even though the result is that the
11542 above test is done twice. */
11543
11544 switch (rh) {
11545 case 0:
11546 DECODE_PRINTF("INC\t");
11547 break;
11548 case 1:
11549 DECODE_PRINTF("DEC\t");
11550 break;
11551 case 2:
11552 case 3:
11553 case 4:
11554 case 5:
11555 case 6:
11556 case 7:
11557 DECODE_PRINTF2("ILLEGAL OP MAJOR OP 0xFE MINOR OP %x \n", mod);
11558 HALT_SYS();
11559 break;
11560 }
11561 }
11562#endif
11563 switch (mod) {
11564 case 0:
11565 DECODE_PRINTF("BYTE PTR ");
11566 destoffset = decode_rm00_address(rl);
11567 DECODE_PRINTF("\n");
11568 switch (rh) {
11569 case 0: /* inc word ptr ... */
11570 destval = fetch_data_byte(destoffset);
11571 TRACE_AND_STEP();
11572 destval = inc_byte(destval);
11573 store_data_byte(destoffset, destval);
11574 break;
11575 case 1: /* dec word ptr ... */
11576 destval = fetch_data_byte(destoffset);
11577 TRACE_AND_STEP();
11578 destval = dec_byte(destval);
11579 store_data_byte(destoffset, destval);
11580 break;
11581 }
11582 break;
11583 case 1:
11584 DECODE_PRINTF("BYTE PTR ");
11585 destoffset = decode_rm01_address(rl);
11586 DECODE_PRINTF("\n");
11587 switch (rh) {
11588 case 0:
11589 destval = fetch_data_byte(destoffset);
11590 TRACE_AND_STEP();
11591 destval = inc_byte(destval);
11592 store_data_byte(destoffset, destval);
11593 break;
11594 case 1:
11595 destval = fetch_data_byte(destoffset);
11596 TRACE_AND_STEP();
11597 destval = dec_byte(destval);
11598 store_data_byte(destoffset, destval);
11599 break;
11600 }
11601 break;
11602 case 2:
11603 DECODE_PRINTF("BYTE PTR ");
11604 destoffset = decode_rm10_address(rl);
11605 DECODE_PRINTF("\n");
11606 switch (rh) {
11607 case 0:
11608 destval = fetch_data_byte(destoffset);
11609 TRACE_AND_STEP();
11610 destval = inc_byte(destval);
11611 store_data_byte(destoffset, destval);
11612 break;
11613 case 1:
11614 destval = fetch_data_byte(destoffset);
11615 TRACE_AND_STEP();
11616 destval = dec_byte(destval);
11617 store_data_byte(destoffset, destval);
11618 break;
11619 }
11620 break;
11621 case 3:
11622 destreg = DECODE_RM_BYTE_REGISTER(rl);
11623 DECODE_PRINTF("\n");
11624 switch (rh) {
11625 case 0:
11626 TRACE_AND_STEP();
11627 *destreg = inc_byte(*destreg);
11628 break;
11629 case 1:
11630 TRACE_AND_STEP();
11631 *destreg = dec_byte(*destreg);
11632 break;
11633 }
11634 break;
11635 }
11636 DECODE_CLEAR_SEGOVR();
11637 END_OF_INSTR();
11638}
11639
11640/****************************************************************************
11641REMARKS:
11642Handles opcode 0xff
11643****************************************************************************/
11644static void
11645x86emuOp_opcFF_word_RM(u8 X86EMU_UNUSED(op1))
11646{
11647 int mod, rh, rl;
11648 uint destoffset = 0;
11649 u16 *destreg;
11650 u16 destval, destval2;
11651
11652 /* Yet another special case instruction. */
11653 START_OF_INSTR();
11654 FETCH_DECODE_MODRM(mod, rh, rl);
11655#ifdef DEBUG
11656 if (DEBUG_DECODE()) {
11657 /* XXX DECODE_PRINTF may be changed to something more
11658 general, so that it is important to leave the strings
11659 in the same format, even though the result is that the
11660 above test is done twice. */
11661
11662 switch (rh) {
11663 case 0:
11664 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11665 DECODE_PRINTF("INC\tDWORD PTR ");
11666 }
11667 else {
11668 DECODE_PRINTF("INC\tWORD PTR ");
11669 }
11670 break;
11671 case 1:
11672 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11673 DECODE_PRINTF("DEC\tDWORD PTR ");
11674 }
11675 else {
11676 DECODE_PRINTF("DEC\tWORD PTR ");
11677 }
11678 break;
11679 case 2:
11680 DECODE_PRINTF("CALL\t");
11681 break;
11682 case 3:
11683 DECODE_PRINTF("CALL\tFAR ");
11684 break;
11685 case 4:
11686 DECODE_PRINTF("JMP\t");
11687 break;
11688 case 5:
11689 DECODE_PRINTF("JMP\tFAR ");
11690 break;
11691 case 6:
11692 DECODE_PRINTF("PUSH\t");
11693 break;
11694 case 7:
11695 DECODE_PRINTF("ILLEGAL DECODING OF OPCODE FF\t");
11696 HALT_SYS();
11697 break;
11698 }
11699 }
11700#endif
11701 switch (mod) {
11702 case 0:
11703 destoffset = decode_rm00_address(rl);
11704 DECODE_PRINTF("\n");
11705 switch (rh) {
11706 case 0: /* inc word ptr ... */
11707 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11708 u32 destval;
11709
11710 destval = fetch_data_long(destoffset);
11711 TRACE_AND_STEP();
11712 destval = inc_long(destval);
11713 store_data_long(destoffset, destval);
11714 }
11715 else {
11716 u16 destval;
11717
11718 destval = fetch_data_word(destoffset);
11719 TRACE_AND_STEP();
11720 destval = inc_word(destval);
11721 store_data_word(destoffset, destval);
11722 }
11723 break;
11724 case 1: /* dec word ptr ... */
11725 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11726 u32 destval;
11727
11728 destval = fetch_data_long(destoffset);
11729 TRACE_AND_STEP();
11730 destval = dec_long(destval);
11731 store_data_long(destoffset, destval);
11732 }
11733 else {
11734 u16 destval;
11735
11736 destval = fetch_data_word(destoffset);
11737 TRACE_AND_STEP();
11738 destval = dec_word(destval);
11739 store_data_word(destoffset, destval);
11740 }
11741 break;
11742 case 2: /* call word ptr ... */
11743 destval = fetch_data_word(destoffset);
11744 TRACE_AND_STEP();
11745 push_word(M.x86.R_IP);
11746 M.x86.R_IP = destval;
11747 break;
11748 case 3: /* call far ptr ... */
11749 destval = fetch_data_word(destoffset);
11750 destval2 = fetch_data_word(destoffset + 2);
11751 TRACE_AND_STEP();
11752 push_word(M.x86.R_CS);
11753 M.x86.R_CS = destval2;
11754 push_word(M.x86.R_IP);
11755 M.x86.R_IP = destval;
11756 break;
11757 case 4: /* jmp word ptr ... */
11758 destval = fetch_data_word(destoffset);
11759 TRACE_AND_STEP();
11760 M.x86.R_IP = destval;
11761 break;
11762 case 5: /* jmp far ptr ... */
11763 destval = fetch_data_word(destoffset);
11764 destval2 = fetch_data_word(destoffset + 2);
11765 TRACE_AND_STEP();
11766 M.x86.R_IP = destval;
11767 M.x86.R_CS = destval2;
11768 break;
11769 case 6: /* push word ptr ... */
11770 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11771 u32 destval;
11772
11773 destval = fetch_data_long(destoffset);
11774 TRACE_AND_STEP();
11775 push_long(destval);
11776 }
11777 else {
11778 u16 destval;
11779
11780 destval = fetch_data_word(destoffset);
11781 TRACE_AND_STEP();
11782 push_word(destval);
11783 }
11784 break;
11785 }
11786 break;
11787 case 1:
11788 destoffset = decode_rm01_address(rl);
11789 DECODE_PRINTF("\n");
11790 switch (rh) {
11791 case 0:
11792 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11793 u32 destval;
11794
11795 destval = fetch_data_long(destoffset);
11796 TRACE_AND_STEP();
11797 destval = inc_long(destval);
11798 store_data_long(destoffset, destval);
11799 }
11800 else {
11801 u16 destval;
11802
11803 destval = fetch_data_word(destoffset);
11804 TRACE_AND_STEP();
11805 destval = inc_word(destval);
11806 store_data_word(destoffset, destval);
11807 }
11808 break;
11809 case 1:
11810 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11811 u32 destval;
11812
11813 destval = fetch_data_long(destoffset);
11814 TRACE_AND_STEP();
11815 destval = dec_long(destval);
11816 store_data_long(destoffset, destval);
11817 }
11818 else {
11819 u16 destval;
11820
11821 destval = fetch_data_word(destoffset);
11822 TRACE_AND_STEP();
11823 destval = dec_word(destval);
11824 store_data_word(destoffset, destval);
11825 }
11826 break;
11827 case 2: /* call word ptr ... */
11828 destval = fetch_data_word(destoffset);
11829 TRACE_AND_STEP();
11830 push_word(M.x86.R_IP);
11831 M.x86.R_IP = destval;
11832 break;
11833 case 3: /* call far ptr ... */
11834 destval = fetch_data_word(destoffset);
11835 destval2 = fetch_data_word(destoffset + 2);
11836 TRACE_AND_STEP();
11837 push_word(M.x86.R_CS);
11838 M.x86.R_CS = destval2;
11839 push_word(M.x86.R_IP);
11840 M.x86.R_IP = destval;
11841 break;
11842 case 4: /* jmp word ptr ... */
11843 destval = fetch_data_word(destoffset);
11844 TRACE_AND_STEP();
11845 M.x86.R_IP = destval;
11846 break;
11847 case 5: /* jmp far ptr ... */
11848 destval = fetch_data_word(destoffset);
11849 destval2 = fetch_data_word(destoffset + 2);
11850 TRACE_AND_STEP();
11851 M.x86.R_IP = destval;
11852 M.x86.R_CS = destval2;
11853 break;
11854 case 6: /* push word ptr ... */
11855 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11856 u32 destval;
11857
11858 destval = fetch_data_long(destoffset);
11859 TRACE_AND_STEP();
11860 push_long(destval);
11861 }
11862 else {
11863 u16 destval;
11864
11865 destval = fetch_data_word(destoffset);
11866 TRACE_AND_STEP();
11867 push_word(destval);
11868 }
11869 break;
11870 }
11871 break;
11872 case 2:
11873 destoffset = decode_rm10_address(rl);
11874 DECODE_PRINTF("\n");
11875 switch (rh) {
11876 case 0:
11877 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11878 u32 destval;
11879
11880 destval = fetch_data_long(destoffset);
11881 TRACE_AND_STEP();
11882 destval = inc_long(destval);
11883 store_data_long(destoffset, destval);
11884 }
11885 else {
11886 u16 destval;
11887
11888 destval = fetch_data_word(destoffset);
11889 TRACE_AND_STEP();
11890 destval = inc_word(destval);
11891 store_data_word(destoffset, destval);
11892 }
11893 break;
11894 case 1:
11895 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11896 u32 destval;
11897
11898 destval = fetch_data_long(destoffset);
11899 TRACE_AND_STEP();
11900 destval = dec_long(destval);
11901 store_data_long(destoffset, destval);
11902 }
11903 else {
11904 u16 destval;
11905
11906 destval = fetch_data_word(destoffset);
11907 TRACE_AND_STEP();
11908 destval = dec_word(destval);
11909 store_data_word(destoffset, destval);
11910 }
11911 break;
11912 case 2: /* call word ptr ... */
11913 destval = fetch_data_word(destoffset);
11914 TRACE_AND_STEP();
11915 push_word(M.x86.R_IP);
11916 M.x86.R_IP = destval;
11917 break;
11918 case 3: /* call far ptr ... */
11919 destval = fetch_data_word(destoffset);
11920 destval2 = fetch_data_word(destoffset + 2);
11921 TRACE_AND_STEP();
11922 push_word(M.x86.R_CS);
11923 M.x86.R_CS = destval2;
11924 push_word(M.x86.R_IP);
11925 M.x86.R_IP = destval;
11926 break;
11927 case 4: /* jmp word ptr ... */
11928 destval = fetch_data_word(destoffset);
11929 TRACE_AND_STEP();
11930 M.x86.R_IP = destval;
11931 break;
11932 case 5: /* jmp far ptr ... */
11933 destval = fetch_data_word(destoffset);
11934 destval2 = fetch_data_word(destoffset + 2);
11935 TRACE_AND_STEP();
11936 M.x86.R_IP = destval;
11937 M.x86.R_CS = destval2;
11938 break;
11939 case 6: /* push word ptr ... */
11940 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11941 u32 destval;
11942
11943 destval = fetch_data_long(destoffset);
11944 TRACE_AND_STEP();
11945 push_long(destval);
11946 }
11947 else {
11948 u16 destval;
11949
11950 destval = fetch_data_word(destoffset);
11951 TRACE_AND_STEP();
11952 push_word(destval);
11953 }
11954 break;
11955 }
11956 break;
11957 case 3:
11958 switch (rh) {
11959 case 0:
11960 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11961 u32 *destreg;
11962
11963 destreg = DECODE_RM_LONG_REGISTER(rl);
11964 DECODE_PRINTF("\n");
11965 TRACE_AND_STEP();
11966 *destreg = inc_long(*destreg);
11967 }
11968 else {
11969 u16 *destreg;
11970
11971 destreg = DECODE_RM_WORD_REGISTER(rl);
11972 DECODE_PRINTF("\n");
11973 TRACE_AND_STEP();
11974 *destreg = inc_word(*destreg);
11975 }
11976 break;
11977 case 1:
11978 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11979 u32 *destreg;
11980
11981 destreg = DECODE_RM_LONG_REGISTER(rl);
11982 DECODE_PRINTF("\n");
11983 TRACE_AND_STEP();
11984 *destreg = dec_long(*destreg);
11985 }
11986 else {
11987 u16 *destreg;
11988
11989 destreg = DECODE_RM_WORD_REGISTER(rl);
11990 DECODE_PRINTF("\n");
11991 TRACE_AND_STEP();
11992 *destreg = dec_word(*destreg);
11993 }
11994 break;
11995 case 2: /* call word ptr ... */
11996 destreg = DECODE_RM_WORD_REGISTER(rl);
11997 DECODE_PRINTF("\n");
11998 TRACE_AND_STEP();
11999 push_word(M.x86.R_IP);
12000 M.x86.R_IP = *destreg;
12001 break;
12002 case 3: /* jmp far ptr ... */
12003 DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n");
12004 TRACE_AND_STEP();
12005 HALT_SYS();
12006 break;
12007
12008 case 4: /* jmp ... */
12009 destreg = DECODE_RM_WORD_REGISTER(rl);
12010 DECODE_PRINTF("\n");
12011 TRACE_AND_STEP();
12012 M.x86.R_IP = (u16) (*destreg);
12013 break;
12014 case 5: /* jmp far ptr ... */
12015 DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n");
12016 TRACE_AND_STEP();
12017 HALT_SYS();
12018 break;
12019 case 6:
12020 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
12021 u32 *destreg;
12022
12023 destreg = DECODE_RM_LONG_REGISTER(rl);
12024 DECODE_PRINTF("\n");
12025 TRACE_AND_STEP();
12026 push_long(*destreg);
12027 }
12028 else {
12029 u16 *destreg;
12030
12031 destreg = DECODE_RM_WORD_REGISTER(rl);
12032 DECODE_PRINTF("\n");
12033 TRACE_AND_STEP();
12034 push_word(*destreg);
12035 }
12036 break;
12037 }
12038 break;
12039 }
12040 DECODE_CLEAR_SEGOVR();
12041 END_OF_INSTR();
12042}
12043
12044/***************************************************************************
12045 * Single byte operation code table:
12046 **************************************************************************/
12047void (*x86emu_optab[256]) (u8) = {
12048/* 0x00 */ x86emuOp_add_byte_RM_R,
12049/* 0x01 */ x86emuOp_add_word_RM_R,
12050/* 0x02 */ x86emuOp_add_byte_R_RM,
12051/* 0x03 */ x86emuOp_add_word_R_RM,
12052/* 0x04 */ x86emuOp_add_byte_AL_IMM,
12053/* 0x05 */ x86emuOp_add_word_AX_IMM,
12054/* 0x06 */ x86emuOp_push_ES,
12055/* 0x07 */ x86emuOp_pop_ES,
12056/* 0x08 */ x86emuOp_or_byte_RM_R,
12057/* 0x09 */ x86emuOp_or_word_RM_R,
12058/* 0x0a */ x86emuOp_or_byte_R_RM,
12059/* 0x0b */ x86emuOp_or_word_R_RM,
12060/* 0x0c */ x86emuOp_or_byte_AL_IMM,
12061/* 0x0d */ x86emuOp_or_word_AX_IMM,
12062/* 0x0e */ x86emuOp_push_CS,
12063/* 0x0f */ x86emuOp_two_byte,
12064/* 0x10 */ x86emuOp_adc_byte_RM_R,
12065/* 0x11 */ x86emuOp_adc_word_RM_R,
12066/* 0x12 */ x86emuOp_adc_byte_R_RM,
12067/* 0x13 */ x86emuOp_adc_word_R_RM,
12068/* 0x14 */ x86emuOp_adc_byte_AL_IMM,
12069/* 0x15 */ x86emuOp_adc_word_AX_IMM,
12070/* 0x16 */ x86emuOp_push_SS,
12071/* 0x17 */ x86emuOp_pop_SS,
12072/* 0x18 */ x86emuOp_sbb_byte_RM_R,
12073/* 0x19 */ x86emuOp_sbb_word_RM_R,
12074/* 0x1a */ x86emuOp_sbb_byte_R_RM,
12075/* 0x1b */ x86emuOp_sbb_word_R_RM,
12076/* 0x1c */ x86emuOp_sbb_byte_AL_IMM,
12077/* 0x1d */ x86emuOp_sbb_word_AX_IMM,
12078/* 0x1e */ x86emuOp_push_DS,
12079/* 0x1f */ x86emuOp_pop_DS,
12080/* 0x20 */ x86emuOp_and_byte_RM_R,
12081/* 0x21 */ x86emuOp_and_word_RM_R,
12082/* 0x22 */ x86emuOp_and_byte_R_RM,
12083/* 0x23 */ x86emuOp_and_word_R_RM,
12084/* 0x24 */ x86emuOp_and_byte_AL_IMM,
12085/* 0x25 */ x86emuOp_and_word_AX_IMM,
12086/* 0x26 */ x86emuOp_segovr_ES,
12087/* 0x27 */ x86emuOp_daa,
12088/* 0x28 */ x86emuOp_sub_byte_RM_R,
12089/* 0x29 */ x86emuOp_sub_word_RM_R,
12090/* 0x2a */ x86emuOp_sub_byte_R_RM,
12091/* 0x2b */ x86emuOp_sub_word_R_RM,
12092/* 0x2c */ x86emuOp_sub_byte_AL_IMM,
12093/* 0x2d */ x86emuOp_sub_word_AX_IMM,
12094/* 0x2e */ x86emuOp_segovr_CS,
12095/* 0x2f */ x86emuOp_das,
12096/* 0x30 */ x86emuOp_xor_byte_RM_R,
12097/* 0x31 */ x86emuOp_xor_word_RM_R,
12098/* 0x32 */ x86emuOp_xor_byte_R_RM,
12099/* 0x33 */ x86emuOp_xor_word_R_RM,
12100/* 0x34 */ x86emuOp_xor_byte_AL_IMM,
12101/* 0x35 */ x86emuOp_xor_word_AX_IMM,
12102/* 0x36 */ x86emuOp_segovr_SS,
12103/* 0x37 */ x86emuOp_aaa,
12104/* 0x38 */ x86emuOp_cmp_byte_RM_R,
12105/* 0x39 */ x86emuOp_cmp_word_RM_R,
12106/* 0x3a */ x86emuOp_cmp_byte_R_RM,
12107/* 0x3b */ x86emuOp_cmp_word_R_RM,
12108/* 0x3c */ x86emuOp_cmp_byte_AL_IMM,
12109/* 0x3d */ x86emuOp_cmp_word_AX_IMM,
12110/* 0x3e */ x86emuOp_segovr_DS,
12111/* 0x3f */ x86emuOp_aas,
12112/* 0x40 */ x86emuOp_inc_AX,
12113/* 0x41 */ x86emuOp_inc_CX,
12114/* 0x42 */ x86emuOp_inc_DX,
12115/* 0x43 */ x86emuOp_inc_BX,
12116/* 0x44 */ x86emuOp_inc_SP,
12117/* 0x45 */ x86emuOp_inc_BP,
12118/* 0x46 */ x86emuOp_inc_SI,
12119/* 0x47 */ x86emuOp_inc_DI,
12120/* 0x48 */ x86emuOp_dec_AX,
12121/* 0x49 */ x86emuOp_dec_CX,
12122/* 0x4a */ x86emuOp_dec_DX,
12123/* 0x4b */ x86emuOp_dec_BX,
12124/* 0x4c */ x86emuOp_dec_SP,
12125/* 0x4d */ x86emuOp_dec_BP,
12126/* 0x4e */ x86emuOp_dec_SI,
12127/* 0x4f */ x86emuOp_dec_DI,
12128/* 0x50 */ x86emuOp_push_AX,
12129/* 0x51 */ x86emuOp_push_CX,
12130/* 0x52 */ x86emuOp_push_DX,
12131/* 0x53 */ x86emuOp_push_BX,
12132/* 0x54 */ x86emuOp_push_SP,
12133/* 0x55 */ x86emuOp_push_BP,
12134/* 0x56 */ x86emuOp_push_SI,
12135/* 0x57 */ x86emuOp_push_DI,
12136/* 0x58 */ x86emuOp_pop_AX,
12137/* 0x59 */ x86emuOp_pop_CX,
12138/* 0x5a */ x86emuOp_pop_DX,
12139/* 0x5b */ x86emuOp_pop_BX,
12140/* 0x5c */ x86emuOp_pop_SP,
12141/* 0x5d */ x86emuOp_pop_BP,
12142/* 0x5e */ x86emuOp_pop_SI,
12143/* 0x5f */ x86emuOp_pop_DI,
12144/* 0x60 */ x86emuOp_push_all,
12145/* 0x61 */ x86emuOp_pop_all,
12146 /* 0x62 */ x86emuOp_illegal_op,
12147 /* bound */
12148 /* 0x63 */ x86emuOp_illegal_op,
12149 /* arpl */
12150/* 0x64 */ x86emuOp_segovr_FS,
12151/* 0x65 */ x86emuOp_segovr_GS,
12152/* 0x66 */ x86emuOp_prefix_data,
12153/* 0x67 */ x86emuOp_prefix_addr,
12154/* 0x68 */ x86emuOp_push_word_IMM,
12155/* 0x69 */ x86emuOp_imul_word_IMM,
12156/* 0x6a */ x86emuOp_push_byte_IMM,
12157/* 0x6b */ x86emuOp_imul_byte_IMM,
12158/* 0x6c */ x86emuOp_ins_byte,
12159/* 0x6d */ x86emuOp_ins_word,
12160/* 0x6e */ x86emuOp_outs_byte,
12161/* 0x6f */ x86emuOp_outs_word,
12162/* 0x70 */ x86emuOp_jump_near_O,
12163/* 0x71 */ x86emuOp_jump_near_NO,
12164/* 0x72 */ x86emuOp_jump_near_B,
12165/* 0x73 */ x86emuOp_jump_near_NB,
12166/* 0x74 */ x86emuOp_jump_near_Z,
12167/* 0x75 */ x86emuOp_jump_near_NZ,
12168/* 0x76 */ x86emuOp_jump_near_BE,
12169/* 0x77 */ x86emuOp_jump_near_NBE,
12170/* 0x78 */ x86emuOp_jump_near_S,
12171/* 0x79 */ x86emuOp_jump_near_NS,
12172/* 0x7a */ x86emuOp_jump_near_P,
12173/* 0x7b */ x86emuOp_jump_near_NP,
12174/* 0x7c */ x86emuOp_jump_near_L,
12175/* 0x7d */ x86emuOp_jump_near_NL,
12176/* 0x7e */ x86emuOp_jump_near_LE,
12177/* 0x7f */ x86emuOp_jump_near_NLE,
12178/* 0x80 */ x86emuOp_opc80_byte_RM_IMM,
12179/* 0x81 */ x86emuOp_opc81_word_RM_IMM,
12180/* 0x82 */ x86emuOp_opc82_byte_RM_IMM,
12181/* 0x83 */ x86emuOp_opc83_word_RM_IMM,
12182/* 0x84 */ x86emuOp_test_byte_RM_R,
12183/* 0x85 */ x86emuOp_test_word_RM_R,
12184/* 0x86 */ x86emuOp_xchg_byte_RM_R,
12185/* 0x87 */ x86emuOp_xchg_word_RM_R,
12186/* 0x88 */ x86emuOp_mov_byte_RM_R,
12187/* 0x89 */ x86emuOp_mov_word_RM_R,
12188/* 0x8a */ x86emuOp_mov_byte_R_RM,
12189/* 0x8b */ x86emuOp_mov_word_R_RM,
12190/* 0x8c */ x86emuOp_mov_word_RM_SR,
12191/* 0x8d */ x86emuOp_lea_word_R_M,
12192/* 0x8e */ x86emuOp_mov_word_SR_RM,
12193/* 0x8f */ x86emuOp_pop_RM,
12194/* 0x90 */ x86emuOp_nop,
12195/* 0x91 */ x86emuOp_xchg_word_AX_CX,
12196/* 0x92 */ x86emuOp_xchg_word_AX_DX,
12197/* 0x93 */ x86emuOp_xchg_word_AX_BX,
12198/* 0x94 */ x86emuOp_xchg_word_AX_SP,
12199/* 0x95 */ x86emuOp_xchg_word_AX_BP,
12200/* 0x96 */ x86emuOp_xchg_word_AX_SI,
12201/* 0x97 */ x86emuOp_xchg_word_AX_DI,
12202/* 0x98 */ x86emuOp_cbw,
12203/* 0x99 */ x86emuOp_cwd,
12204/* 0x9a */ x86emuOp_call_far_IMM,
12205/* 0x9b */ x86emuOp_wait,
12206/* 0x9c */ x86emuOp_pushf_word,
12207/* 0x9d */ x86emuOp_popf_word,
12208/* 0x9e */ x86emuOp_sahf,
12209/* 0x9f */ x86emuOp_lahf,
12210/* 0xa0 */ x86emuOp_mov_AL_M_IMM,
12211/* 0xa1 */ x86emuOp_mov_AX_M_IMM,
12212/* 0xa2 */ x86emuOp_mov_M_AL_IMM,
12213/* 0xa3 */ x86emuOp_mov_M_AX_IMM,
12214/* 0xa4 */ x86emuOp_movs_byte,
12215/* 0xa5 */ x86emuOp_movs_word,
12216/* 0xa6 */ x86emuOp_cmps_byte,
12217/* 0xa7 */ x86emuOp_cmps_word,
12218/* 0xa8 */ x86emuOp_test_AL_IMM,
12219/* 0xa9 */ x86emuOp_test_AX_IMM,
12220/* 0xaa */ x86emuOp_stos_byte,
12221/* 0xab */ x86emuOp_stos_word,
12222/* 0xac */ x86emuOp_lods_byte,
12223/* 0xad */ x86emuOp_lods_word,
12224/* 0xac */ x86emuOp_scas_byte,
12225/* 0xad */ x86emuOp_scas_word,
12226/* 0xb0 */ x86emuOp_mov_byte_AL_IMM,
12227/* 0xb1 */ x86emuOp_mov_byte_CL_IMM,
12228/* 0xb2 */ x86emuOp_mov_byte_DL_IMM,
12229/* 0xb3 */ x86emuOp_mov_byte_BL_IMM,
12230/* 0xb4 */ x86emuOp_mov_byte_AH_IMM,
12231/* 0xb5 */ x86emuOp_mov_byte_CH_IMM,
12232/* 0xb6 */ x86emuOp_mov_byte_DH_IMM,
12233/* 0xb7 */ x86emuOp_mov_byte_BH_IMM,
12234/* 0xb8 */ x86emuOp_mov_word_AX_IMM,
12235/* 0xb9 */ x86emuOp_mov_word_CX_IMM,
12236/* 0xba */ x86emuOp_mov_word_DX_IMM,
12237/* 0xbb */ x86emuOp_mov_word_BX_IMM,
12238/* 0xbc */ x86emuOp_mov_word_SP_IMM,
12239/* 0xbd */ x86emuOp_mov_word_BP_IMM,
12240/* 0xbe */ x86emuOp_mov_word_SI_IMM,
12241/* 0xbf */ x86emuOp_mov_word_DI_IMM,
12242/* 0xc0 */ x86emuOp_opcC0_byte_RM_MEM,
12243/* 0xc1 */ x86emuOp_opcC1_word_RM_MEM,
12244/* 0xc2 */ x86emuOp_ret_near_IMM,
12245/* 0xc3 */ x86emuOp_ret_near,
12246/* 0xc4 */ x86emuOp_les_R_IMM,
12247/* 0xc5 */ x86emuOp_lds_R_IMM,
12248/* 0xc6 */ x86emuOp_mov_byte_RM_IMM,
12249/* 0xc7 */ x86emuOp_mov_word_RM_IMM,
12250/* 0xc8 */ x86emuOp_enter,
12251/* 0xc9 */ x86emuOp_leave,
12252/* 0xca */ x86emuOp_ret_far_IMM,
12253/* 0xcb */ x86emuOp_ret_far,
12254/* 0xcc */ x86emuOp_int3,
12255/* 0xcd */ x86emuOp_int_IMM,
12256/* 0xce */ x86emuOp_into,
12257/* 0xcf */ x86emuOp_iret,
12258/* 0xd0 */ x86emuOp_opcD0_byte_RM_1,
12259/* 0xd1 */ x86emuOp_opcD1_word_RM_1,
12260/* 0xd2 */ x86emuOp_opcD2_byte_RM_CL,
12261/* 0xd3 */ x86emuOp_opcD3_word_RM_CL,
12262/* 0xd4 */ x86emuOp_aam,
12263/* 0xd5 */ x86emuOp_aad,
12264 /* 0xd6 */ x86emuOp_illegal_op,
12265 /* Undocumented SETALC instruction */
12266/* 0xd7 */ x86emuOp_xlat,
12267/* 0xd8 */ x86emuOp_esc_coprocess_d8,
12268/* 0xd9 */ x86emuOp_esc_coprocess_d9,
12269/* 0xda */ x86emuOp_esc_coprocess_da,
12270/* 0xdb */ x86emuOp_esc_coprocess_db,
12271/* 0xdc */ x86emuOp_esc_coprocess_dc,
12272/* 0xdd */ x86emuOp_esc_coprocess_dd,
12273/* 0xde */ x86emuOp_esc_coprocess_de,
12274/* 0xdf */ x86emuOp_esc_coprocess_df,
12275/* 0xe0 */ x86emuOp_loopne,
12276/* 0xe1 */ x86emuOp_loope,
12277/* 0xe2 */ x86emuOp_loop,
12278/* 0xe3 */ x86emuOp_jcxz,
12279/* 0xe4 */ x86emuOp_in_byte_AL_IMM,
12280/* 0xe5 */ x86emuOp_in_word_AX_IMM,
12281/* 0xe6 */ x86emuOp_out_byte_IMM_AL,
12282/* 0xe7 */ x86emuOp_out_word_IMM_AX,
12283/* 0xe8 */ x86emuOp_call_near_IMM,
12284/* 0xe9 */ x86emuOp_jump_near_IMM,
12285/* 0xea */ x86emuOp_jump_far_IMM,
12286/* 0xeb */ x86emuOp_jump_byte_IMM,
12287/* 0xec */ x86emuOp_in_byte_AL_DX,
12288/* 0xed */ x86emuOp_in_word_AX_DX,
12289/* 0xee */ x86emuOp_out_byte_DX_AL,
12290/* 0xef */ x86emuOp_out_word_DX_AX,
12291/* 0xf0 */ x86emuOp_lock,
12292/* 0xf1 */ x86emuOp_illegal_op,
12293/* 0xf2 */ x86emuOp_repne,
12294/* 0xf3 */ x86emuOp_repe,
12295/* 0xf4 */ x86emuOp_halt,
12296/* 0xf5 */ x86emuOp_cmc,
12297/* 0xf6 */ x86emuOp_opcF6_byte_RM,
12298/* 0xf7 */ x86emuOp_opcF7_word_RM,
12299/* 0xf8 */ x86emuOp_clc,
12300/* 0xf9 */ x86emuOp_stc,
12301/* 0xfa */ x86emuOp_cli,
12302/* 0xfb */ x86emuOp_sti,
12303/* 0xfc */ x86emuOp_cld,
12304/* 0xfd */ x86emuOp_std,
12305/* 0xfe */ x86emuOp_opcFE_byte_RM,
12306/* 0xff */ x86emuOp_opcFF_word_RM,
12307};