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 preceding it which gives its 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 /****************************************************************************
78 PARAMETERS:
79 op1 - Instruction op code
80
81 REMARKS:
82 Handles illegal opcodes.
83 ****************************************************************************/
84 static void
x86emuOp_illegal_op(u8 op1)85 x86emuOp_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 /****************************************************************************
108 REMARKS:
109 Handles opcode 0x00
110 ****************************************************************************/
111 static void
x86emuOp_add_byte_RM_R(u8 X86EMU_UNUSED (op1))112 x86emuOp_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 /****************************************************************************
167 REMARKS:
168 Handles opcode 0x01
169 ****************************************************************************/
170 static void
x86emuOp_add_word_RM_R(u8 X86EMU_UNUSED (op1))171 x86emuOp_add_word_RM_R(u8 X86EMU_UNUSED(op1))
172 {
173 int mod, rl, rh;
174 uint destoffset;
175
176 START_OF_INSTR();
177 DECODE_PRINTF("ADD\t");
178 FETCH_DECODE_MODRM(mod, rh, rl);
179 switch (mod) {
180 case 0:
181 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
182 u32 destval;
183 u32 *srcreg;
184
185 destoffset = decode_rm00_address(rl);
186 DECODE_PRINTF(",");
187 destval = fetch_data_long(destoffset);
188 srcreg = DECODE_RM_LONG_REGISTER(rh);
189 DECODE_PRINTF("\n");
190 TRACE_AND_STEP();
191 destval = add_long(destval, *srcreg);
192 store_data_long(destoffset, destval);
193 }
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 /****************************************************************************
292 REMARKS:
293 Handles opcode 0x02
294 ****************************************************************************/
295 static void
x86emuOp_add_byte_R_RM(u8 X86EMU_UNUSED (op1))296 x86emuOp_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 /****************************************************************************
348 REMARKS:
349 Handles opcode 0x03
350 ****************************************************************************/
351 static void
x86emuOp_add_word_R_RM(u8 X86EMU_UNUSED (op1))352 x86emuOp_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 /****************************************************************************
467 REMARKS:
468 Handles opcode 0x04
469 ****************************************************************************/
470 static void
x86emuOp_add_byte_AL_IMM(u8 X86EMU_UNUSED (op1))471 x86emuOp_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 /****************************************************************************
486 REMARKS:
487 Handles opcode 0x05
488 ****************************************************************************/
489 static void
x86emuOp_add_word_AX_IMM(u8 X86EMU_UNUSED (op1))490 x86emuOp_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 /****************************************************************************
516 REMARKS:
517 Handles opcode 0x06
518 ****************************************************************************/
519 static void
x86emuOp_push_ES(u8 X86EMU_UNUSED (op1))520 x86emuOp_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 /****************************************************************************
531 REMARKS:
532 Handles opcode 0x07
533 ****************************************************************************/
534 static void
x86emuOp_pop_ES(u8 X86EMU_UNUSED (op1))535 x86emuOp_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 /****************************************************************************
546 REMARKS:
547 Handles opcode 0x08
548 ****************************************************************************/
549 static void
x86emuOp_or_byte_RM_R(u8 X86EMU_UNUSED (op1))550 x86emuOp_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 /****************************************************************************
605 REMARKS:
606 Handles opcode 0x09
607 ****************************************************************************/
608 static void
x86emuOp_or_word_RM_R(u8 X86EMU_UNUSED (op1))609 x86emuOp_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 /****************************************************************************
730 REMARKS:
731 Handles opcode 0x0a
732 ****************************************************************************/
733 static void
x86emuOp_or_byte_R_RM(u8 X86EMU_UNUSED (op1))734 x86emuOp_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 /****************************************************************************
786 REMARKS:
787 Handles opcode 0x0b
788 ****************************************************************************/
789 static void
x86emuOp_or_word_R_RM(u8 X86EMU_UNUSED (op1))790 x86emuOp_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 /****************************************************************************
905 REMARKS:
906 Handles opcode 0x0c
907 ****************************************************************************/
908 static void
x86emuOp_or_byte_AL_IMM(u8 X86EMU_UNUSED (op1))909 x86emuOp_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 /****************************************************************************
924 REMARKS:
925 Handles opcode 0x0d
926 ****************************************************************************/
927 static void
x86emuOp_or_word_AX_IMM(u8 X86EMU_UNUSED (op1))928 x86emuOp_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 /****************************************************************************
954 REMARKS:
955 Handles opcode 0x0e
956 ****************************************************************************/
957 static void
x86emuOp_push_CS(u8 X86EMU_UNUSED (op1))958 x86emuOp_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 /****************************************************************************
969 REMARKS:
970 Handles opcode 0x0f. Escape for two-byte opcode (286 or better)
971 ****************************************************************************/
972 static void
x86emuOp_two_byte(u8 X86EMU_UNUSED (op1))973 x86emuOp_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 /****************************************************************************
982 REMARKS:
983 Handles opcode 0x10
984 ****************************************************************************/
985 static void
x86emuOp_adc_byte_RM_R(u8 X86EMU_UNUSED (op1))986 x86emuOp_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 /****************************************************************************
1041 REMARKS:
1042 Handles opcode 0x11
1043 ****************************************************************************/
1044 static void
x86emuOp_adc_word_RM_R(u8 X86EMU_UNUSED (op1))1045 x86emuOp_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 /****************************************************************************
1166 REMARKS:
1167 Handles opcode 0x12
1168 ****************************************************************************/
1169 static void
x86emuOp_adc_byte_R_RM(u8 X86EMU_UNUSED (op1))1170 x86emuOp_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 /****************************************************************************
1222 REMARKS:
1223 Handles opcode 0x13
1224 ****************************************************************************/
1225 static void
x86emuOp_adc_word_R_RM(u8 X86EMU_UNUSED (op1))1226 x86emuOp_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 /****************************************************************************
1341 REMARKS:
1342 Handles opcode 0x14
1343 ****************************************************************************/
1344 static void
x86emuOp_adc_byte_AL_IMM(u8 X86EMU_UNUSED (op1))1345 x86emuOp_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 /****************************************************************************
1360 REMARKS:
1361 Handles opcode 0x15
1362 ****************************************************************************/
1363 static void
x86emuOp_adc_word_AX_IMM(u8 X86EMU_UNUSED (op1))1364 x86emuOp_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 /****************************************************************************
1390 REMARKS:
1391 Handles opcode 0x16
1392 ****************************************************************************/
1393 static void
x86emuOp_push_SS(u8 X86EMU_UNUSED (op1))1394 x86emuOp_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 /****************************************************************************
1405 REMARKS:
1406 Handles opcode 0x17
1407 ****************************************************************************/
1408 static void
x86emuOp_pop_SS(u8 X86EMU_UNUSED (op1))1409 x86emuOp_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 /****************************************************************************
1420 REMARKS:
1421 Handles opcode 0x18
1422 ****************************************************************************/
1423 static void
x86emuOp_sbb_byte_RM_R(u8 X86EMU_UNUSED (op1))1424 x86emuOp_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 /****************************************************************************
1479 REMARKS:
1480 Handles opcode 0x19
1481 ****************************************************************************/
1482 static void
x86emuOp_sbb_word_RM_R(u8 X86EMU_UNUSED (op1))1483 x86emuOp_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 /****************************************************************************
1604 REMARKS:
1605 Handles opcode 0x1a
1606 ****************************************************************************/
1607 static void
x86emuOp_sbb_byte_R_RM(u8 X86EMU_UNUSED (op1))1608 x86emuOp_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 /****************************************************************************
1660 REMARKS:
1661 Handles opcode 0x1b
1662 ****************************************************************************/
1663 static void
x86emuOp_sbb_word_R_RM(u8 X86EMU_UNUSED (op1))1664 x86emuOp_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 /****************************************************************************
1779 REMARKS:
1780 Handles opcode 0x1c
1781 ****************************************************************************/
1782 static void
x86emuOp_sbb_byte_AL_IMM(u8 X86EMU_UNUSED (op1))1783 x86emuOp_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 /****************************************************************************
1798 REMARKS:
1799 Handles opcode 0x1d
1800 ****************************************************************************/
1801 static void
x86emuOp_sbb_word_AX_IMM(u8 X86EMU_UNUSED (op1))1802 x86emuOp_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 /****************************************************************************
1828 REMARKS:
1829 Handles opcode 0x1e
1830 ****************************************************************************/
1831 static void
x86emuOp_push_DS(u8 X86EMU_UNUSED (op1))1832 x86emuOp_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 /****************************************************************************
1843 REMARKS:
1844 Handles opcode 0x1f
1845 ****************************************************************************/
1846 static void
x86emuOp_pop_DS(u8 X86EMU_UNUSED (op1))1847 x86emuOp_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 /****************************************************************************
1858 REMARKS:
1859 Handles opcode 0x20
1860 ****************************************************************************/
1861 static void
x86emuOp_and_byte_RM_R(u8 X86EMU_UNUSED (op1))1862 x86emuOp_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 /****************************************************************************
1921 REMARKS:
1922 Handles opcode 0x21
1923 ****************************************************************************/
1924 static void
x86emuOp_and_word_RM_R(u8 X86EMU_UNUSED (op1))1925 x86emuOp_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 /****************************************************************************
2046 REMARKS:
2047 Handles opcode 0x22
2048 ****************************************************************************/
2049 static void
x86emuOp_and_byte_R_RM(u8 X86EMU_UNUSED (op1))2050 x86emuOp_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 /****************************************************************************
2102 REMARKS:
2103 Handles opcode 0x23
2104 ****************************************************************************/
2105 static void
x86emuOp_and_word_R_RM(u8 X86EMU_UNUSED (op1))2106 x86emuOp_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 /****************************************************************************
2222 REMARKS:
2223 Handles opcode 0x24
2224 ****************************************************************************/
2225 static void
x86emuOp_and_byte_AL_IMM(u8 X86EMU_UNUSED (op1))2226 x86emuOp_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 /****************************************************************************
2241 REMARKS:
2242 Handles opcode 0x25
2243 ****************************************************************************/
2244 static void
x86emuOp_and_word_AX_IMM(u8 X86EMU_UNUSED (op1))2245 x86emuOp_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 /****************************************************************************
2271 REMARKS:
2272 Handles opcode 0x26
2273 ****************************************************************************/
2274 static void
x86emuOp_segovr_ES(u8 X86EMU_UNUSED (op1))2275 x86emuOp_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 /****************************************************************************
2289 REMARKS:
2290 Handles opcode 0x27
2291 ****************************************************************************/
2292 static void
x86emuOp_daa(u8 X86EMU_UNUSED (op1))2293 x86emuOp_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 /****************************************************************************
2304 REMARKS:
2305 Handles opcode 0x28
2306 ****************************************************************************/
2307 static void
x86emuOp_sub_byte_RM_R(u8 X86EMU_UNUSED (op1))2308 x86emuOp_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 /****************************************************************************
2363 REMARKS:
2364 Handles opcode 0x29
2365 ****************************************************************************/
2366 static void
x86emuOp_sub_word_RM_R(u8 X86EMU_UNUSED (op1))2367 x86emuOp_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 /****************************************************************************
2488 REMARKS:
2489 Handles opcode 0x2a
2490 ****************************************************************************/
2491 static void
x86emuOp_sub_byte_R_RM(u8 X86EMU_UNUSED (op1))2492 x86emuOp_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 /****************************************************************************
2544 REMARKS:
2545 Handles opcode 0x2b
2546 ****************************************************************************/
2547 static void
x86emuOp_sub_word_R_RM(u8 X86EMU_UNUSED (op1))2548 x86emuOp_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 /****************************************************************************
2663 REMARKS:
2664 Handles opcode 0x2c
2665 ****************************************************************************/
2666 static void
x86emuOp_sub_byte_AL_IMM(u8 X86EMU_UNUSED (op1))2667 x86emuOp_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 /****************************************************************************
2682 REMARKS:
2683 Handles opcode 0x2d
2684 ****************************************************************************/
2685 static void
x86emuOp_sub_word_AX_IMM(u8 X86EMU_UNUSED (op1))2686 x86emuOp_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 /****************************************************************************
2712 REMARKS:
2713 Handles opcode 0x2e
2714 ****************************************************************************/
2715 static void
x86emuOp_segovr_CS(u8 X86EMU_UNUSED (op1))2716 x86emuOp_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 /****************************************************************************
2727 REMARKS:
2728 Handles opcode 0x2f
2729 ****************************************************************************/
2730 static void
x86emuOp_das(u8 X86EMU_UNUSED (op1))2731 x86emuOp_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 /****************************************************************************
2742 REMARKS:
2743 Handles opcode 0x30
2744 ****************************************************************************/
2745 static void
x86emuOp_xor_byte_RM_R(u8 X86EMU_UNUSED (op1))2746 x86emuOp_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 /****************************************************************************
2801 REMARKS:
2802 Handles opcode 0x31
2803 ****************************************************************************/
2804 static void
x86emuOp_xor_word_RM_R(u8 X86EMU_UNUSED (op1))2805 x86emuOp_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 /****************************************************************************
2926 REMARKS:
2927 Handles opcode 0x32
2928 ****************************************************************************/
2929 static void
x86emuOp_xor_byte_R_RM(u8 X86EMU_UNUSED (op1))2930 x86emuOp_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 /****************************************************************************
2982 REMARKS:
2983 Handles opcode 0x33
2984 ****************************************************************************/
2985 static void
x86emuOp_xor_word_R_RM(u8 X86EMU_UNUSED (op1))2986 x86emuOp_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 /****************************************************************************
3101 REMARKS:
3102 Handles opcode 0x34
3103 ****************************************************************************/
3104 static void
x86emuOp_xor_byte_AL_IMM(u8 X86EMU_UNUSED (op1))3105 x86emuOp_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 /****************************************************************************
3120 REMARKS:
3121 Handles opcode 0x35
3122 ****************************************************************************/
3123 static void
x86emuOp_xor_word_AX_IMM(u8 X86EMU_UNUSED (op1))3124 x86emuOp_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 /****************************************************************************
3150 REMARKS:
3151 Handles opcode 0x36
3152 ****************************************************************************/
3153 static void
x86emuOp_segovr_SS(u8 X86EMU_UNUSED (op1))3154 x86emuOp_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 /****************************************************************************
3165 REMARKS:
3166 Handles opcode 0x37
3167 ****************************************************************************/
3168 static void
x86emuOp_aaa(u8 X86EMU_UNUSED (op1))3169 x86emuOp_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 /****************************************************************************
3180 REMARKS:
3181 Handles opcode 0x38
3182 ****************************************************************************/
3183 static void
x86emuOp_cmp_byte_RM_R(u8 X86EMU_UNUSED (op1))3184 x86emuOp_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 /****************************************************************************
3236 REMARKS:
3237 Handles opcode 0x39
3238 ****************************************************************************/
3239 static void
x86emuOp_cmp_word_RM_R(u8 X86EMU_UNUSED (op1))3240 x86emuOp_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 /****************************************************************************
3355 REMARKS:
3356 Handles opcode 0x3a
3357 ****************************************************************************/
3358 static void
x86emuOp_cmp_byte_R_RM(u8 X86EMU_UNUSED (op1))3359 x86emuOp_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 /****************************************************************************
3411 REMARKS:
3412 Handles opcode 0x3b
3413 ****************************************************************************/
3414 static void
x86emuOp_cmp_word_R_RM(u8 X86EMU_UNUSED (op1))3415 x86emuOp_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 /****************************************************************************
3530 REMARKS:
3531 Handles opcode 0x3c
3532 ****************************************************************************/
3533 static void
x86emuOp_cmp_byte_AL_IMM(u8 X86EMU_UNUSED (op1))3534 x86emuOp_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 /****************************************************************************
3549 REMARKS:
3550 Handles opcode 0x3d
3551 ****************************************************************************/
3552 static void
x86emuOp_cmp_word_AX_IMM(u8 X86EMU_UNUSED (op1))3553 x86emuOp_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 /****************************************************************************
3579 REMARKS:
3580 Handles opcode 0x3e
3581 ****************************************************************************/
3582 static void
x86emuOp_segovr_DS(u8 X86EMU_UNUSED (op1))3583 x86emuOp_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 /****************************************************************************
3594 REMARKS:
3595 Handles opcode 0x3f
3596 ****************************************************************************/
3597 static void
x86emuOp_aas(u8 X86EMU_UNUSED (op1))3598 x86emuOp_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 /****************************************************************************
3609 REMARKS:
3610 Handles opcode 0x40
3611 ****************************************************************************/
3612 static void
x86emuOp_inc_AX(u8 X86EMU_UNUSED (op1))3613 x86emuOp_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 /****************************************************************************
3634 REMARKS:
3635 Handles opcode 0x41
3636 ****************************************************************************/
3637 static void
x86emuOp_inc_CX(u8 X86EMU_UNUSED (op1))3638 x86emuOp_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 /****************************************************************************
3659 REMARKS:
3660 Handles opcode 0x42
3661 ****************************************************************************/
3662 static void
x86emuOp_inc_DX(u8 X86EMU_UNUSED (op1))3663 x86emuOp_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 /****************************************************************************
3684 REMARKS:
3685 Handles opcode 0x43
3686 ****************************************************************************/
3687 static void
x86emuOp_inc_BX(u8 X86EMU_UNUSED (op1))3688 x86emuOp_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 /****************************************************************************
3709 REMARKS:
3710 Handles opcode 0x44
3711 ****************************************************************************/
3712 static void
x86emuOp_inc_SP(u8 X86EMU_UNUSED (op1))3713 x86emuOp_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 /****************************************************************************
3734 REMARKS:
3735 Handles opcode 0x45
3736 ****************************************************************************/
3737 static void
x86emuOp_inc_BP(u8 X86EMU_UNUSED (op1))3738 x86emuOp_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 /****************************************************************************
3759 REMARKS:
3760 Handles opcode 0x46
3761 ****************************************************************************/
3762 static void
x86emuOp_inc_SI(u8 X86EMU_UNUSED (op1))3763 x86emuOp_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 /****************************************************************************
3784 REMARKS:
3785 Handles opcode 0x47
3786 ****************************************************************************/
3787 static void
x86emuOp_inc_DI(u8 X86EMU_UNUSED (op1))3788 x86emuOp_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 /****************************************************************************
3809 REMARKS:
3810 Handles opcode 0x48
3811 ****************************************************************************/
3812 static void
x86emuOp_dec_AX(u8 X86EMU_UNUSED (op1))3813 x86emuOp_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 /****************************************************************************
3834 REMARKS:
3835 Handles opcode 0x49
3836 ****************************************************************************/
3837 static void
x86emuOp_dec_CX(u8 X86EMU_UNUSED (op1))3838 x86emuOp_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 /****************************************************************************
3859 REMARKS:
3860 Handles opcode 0x4a
3861 ****************************************************************************/
3862 static void
x86emuOp_dec_DX(u8 X86EMU_UNUSED (op1))3863 x86emuOp_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 /****************************************************************************
3884 REMARKS:
3885 Handles opcode 0x4b
3886 ****************************************************************************/
3887 static void
x86emuOp_dec_BX(u8 X86EMU_UNUSED (op1))3888 x86emuOp_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 /****************************************************************************
3909 REMARKS:
3910 Handles opcode 0x4c
3911 ****************************************************************************/
3912 static void
x86emuOp_dec_SP(u8 X86EMU_UNUSED (op1))3913 x86emuOp_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 /****************************************************************************
3934 REMARKS:
3935 Handles opcode 0x4d
3936 ****************************************************************************/
3937 static void
x86emuOp_dec_BP(u8 X86EMU_UNUSED (op1))3938 x86emuOp_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 /****************************************************************************
3959 REMARKS:
3960 Handles opcode 0x4e
3961 ****************************************************************************/
3962 static void
x86emuOp_dec_SI(u8 X86EMU_UNUSED (op1))3963 x86emuOp_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 /****************************************************************************
3984 REMARKS:
3985 Handles opcode 0x4f
3986 ****************************************************************************/
3987 static void
x86emuOp_dec_DI(u8 X86EMU_UNUSED (op1))3988 x86emuOp_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 /****************************************************************************
4009 REMARKS:
4010 Handles opcode 0x50
4011 ****************************************************************************/
4012 static void
x86emuOp_push_AX(u8 X86EMU_UNUSED (op1))4013 x86emuOp_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 /****************************************************************************
4034 REMARKS:
4035 Handles opcode 0x51
4036 ****************************************************************************/
4037 static void
x86emuOp_push_CX(u8 X86EMU_UNUSED (op1))4038 x86emuOp_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 /****************************************************************************
4059 REMARKS:
4060 Handles opcode 0x52
4061 ****************************************************************************/
4062 static void
x86emuOp_push_DX(u8 X86EMU_UNUSED (op1))4063 x86emuOp_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 /****************************************************************************
4084 REMARKS:
4085 Handles opcode 0x53
4086 ****************************************************************************/
4087 static void
x86emuOp_push_BX(u8 X86EMU_UNUSED (op1))4088 x86emuOp_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 /****************************************************************************
4109 REMARKS:
4110 Handles opcode 0x54
4111 ****************************************************************************/
4112 static void
x86emuOp_push_SP(u8 X86EMU_UNUSED (op1))4113 x86emuOp_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 /****************************************************************************
4138 REMARKS:
4139 Handles opcode 0x55
4140 ****************************************************************************/
4141 static void
x86emuOp_push_BP(u8 X86EMU_UNUSED (op1))4142 x86emuOp_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 /****************************************************************************
4163 REMARKS:
4164 Handles opcode 0x56
4165 ****************************************************************************/
4166 static void
x86emuOp_push_SI(u8 X86EMU_UNUSED (op1))4167 x86emuOp_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 /****************************************************************************
4188 REMARKS:
4189 Handles opcode 0x57
4190 ****************************************************************************/
4191 static void
x86emuOp_push_DI(u8 X86EMU_UNUSED (op1))4192 x86emuOp_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 /****************************************************************************
4213 REMARKS:
4214 Handles opcode 0x58
4215 ****************************************************************************/
4216 static void
x86emuOp_pop_AX(u8 X86EMU_UNUSED (op1))4217 x86emuOp_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 /****************************************************************************
4238 REMARKS:
4239 Handles opcode 0x59
4240 ****************************************************************************/
4241 static void
x86emuOp_pop_CX(u8 X86EMU_UNUSED (op1))4242 x86emuOp_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 /****************************************************************************
4263 REMARKS:
4264 Handles opcode 0x5a
4265 ****************************************************************************/
4266 static void
x86emuOp_pop_DX(u8 X86EMU_UNUSED (op1))4267 x86emuOp_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 /****************************************************************************
4288 REMARKS:
4289 Handles opcode 0x5b
4290 ****************************************************************************/
4291 static void
x86emuOp_pop_BX(u8 X86EMU_UNUSED (op1))4292 x86emuOp_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 /****************************************************************************
4313 REMARKS:
4314 Handles opcode 0x5c
4315 ****************************************************************************/
4316 static void
x86emuOp_pop_SP(u8 X86EMU_UNUSED (op1))4317 x86emuOp_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 /****************************************************************************
4338 REMARKS:
4339 Handles opcode 0x5d
4340 ****************************************************************************/
4341 static void
x86emuOp_pop_BP(u8 X86EMU_UNUSED (op1))4342 x86emuOp_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 /****************************************************************************
4363 REMARKS:
4364 Handles opcode 0x5e
4365 ****************************************************************************/
4366 static void
x86emuOp_pop_SI(u8 X86EMU_UNUSED (op1))4367 x86emuOp_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 /****************************************************************************
4388 REMARKS:
4389 Handles opcode 0x5f
4390 ****************************************************************************/
4391 static void
x86emuOp_pop_DI(u8 X86EMU_UNUSED (op1))4392 x86emuOp_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 /****************************************************************************
4413 REMARKS:
4414 Handles opcode 0x60
4415 ****************************************************************************/
4416 static void
x86emuOp_push_all(u8 X86EMU_UNUSED (op1))4417 x86emuOp_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 /****************************************************************************
4456 REMARKS:
4457 Handles opcode 0x61
4458 ****************************************************************************/
4459 static void
x86emuOp_pop_all(u8 X86EMU_UNUSED (op1))4460 x86emuOp_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 /****************************************************************************
4498 REMARKS:
4499 Handles opcode 0x64
4500 ****************************************************************************/
4501 static void
x86emuOp_segovr_FS(u8 X86EMU_UNUSED (op1))4502 x86emuOp_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 /****************************************************************************
4516 REMARKS:
4517 Handles opcode 0x65
4518 ****************************************************************************/
4519 static void
x86emuOp_segovr_GS(u8 X86EMU_UNUSED (op1))4520 x86emuOp_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 /****************************************************************************
4534 REMARKS:
4535 Handles opcode 0x66 - prefix for 32-bit register
4536 ****************************************************************************/
4537 static void
x86emuOp_prefix_data(u8 X86EMU_UNUSED (op1))4538 x86emuOp_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 /****************************************************************************
4549 REMARKS:
4550 Handles opcode 0x67 - prefix for 32-bit address
4551 ****************************************************************************/
4552 static void
x86emuOp_prefix_addr(u8 X86EMU_UNUSED (op1))4553 x86emuOp_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 /****************************************************************************
4564 REMARKS:
4565 Handles opcode 0x68
4566 ****************************************************************************/
4567 static void
x86emuOp_push_word_IMM(u8 X86EMU_UNUSED (op1))4568 x86emuOp_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 /****************************************************************************
4592 REMARKS:
4593 Handles opcode 0x69
4594 ****************************************************************************/
4595 static void
x86emuOp_imul_word_IMM(u8 X86EMU_UNUSED (op1))4596 x86emuOp_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 /****************************************************************************
4809 REMARKS:
4810 Handles opcode 0x6a
4811 ****************************************************************************/
4812 static void
x86emuOp_push_byte_IMM(u8 X86EMU_UNUSED (op1))4813 x86emuOp_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 /****************************************************************************
4832 REMARKS:
4833 Handles opcode 0x6b
4834 ****************************************************************************/
4835 static void
x86emuOp_imul_byte_IMM(u8 X86EMU_UNUSED (op1))4836 x86emuOp_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 /****************************************************************************
5042 REMARKS:
5043 Handles opcode 0x6c
5044 ****************************************************************************/
5045 static void
x86emuOp_ins_byte(u8 X86EMU_UNUSED (op1))5046 x86emuOp_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 /****************************************************************************
5057 REMARKS:
5058 Handles opcode 0x6d
5059 ****************************************************************************/
5060 static void
x86emuOp_ins_word(u8 X86EMU_UNUSED (op1))5061 x86emuOp_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 /****************************************************************************
5078 REMARKS:
5079 Handles opcode 0x6e
5080 ****************************************************************************/
5081 static void
x86emuOp_outs_byte(u8 X86EMU_UNUSED (op1))5082 x86emuOp_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 /****************************************************************************
5093 REMARKS:
5094 Handles opcode 0x6f
5095 ****************************************************************************/
5096 static void
x86emuOp_outs_word(u8 X86EMU_UNUSED (op1))5097 x86emuOp_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 /****************************************************************************
5114 REMARKS:
5115 Handles opcode 0x70
5116 ****************************************************************************/
5117 static void
x86emuOp_jump_near_O(u8 X86EMU_UNUSED (op1))5118 x86emuOp_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 /****************************************************************************
5137 REMARKS:
5138 Handles opcode 0x71
5139 ****************************************************************************/
5140 static void
x86emuOp_jump_near_NO(u8 X86EMU_UNUSED (op1))5141 x86emuOp_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 /****************************************************************************
5160 REMARKS:
5161 Handles opcode 0x72
5162 ****************************************************************************/
5163 static void
x86emuOp_jump_near_B(u8 X86EMU_UNUSED (op1))5164 x86emuOp_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 /****************************************************************************
5183 REMARKS:
5184 Handles opcode 0x73
5185 ****************************************************************************/
5186 static void
x86emuOp_jump_near_NB(u8 X86EMU_UNUSED (op1))5187 x86emuOp_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 /****************************************************************************
5206 REMARKS:
5207 Handles opcode 0x74
5208 ****************************************************************************/
5209 static void
x86emuOp_jump_near_Z(u8 X86EMU_UNUSED (op1))5210 x86emuOp_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 /****************************************************************************
5229 REMARKS:
5230 Handles opcode 0x75
5231 ****************************************************************************/
5232 static void
x86emuOp_jump_near_NZ(u8 X86EMU_UNUSED (op1))5233 x86emuOp_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 /****************************************************************************
5252 REMARKS:
5253 Handles opcode 0x76
5254 ****************************************************************************/
5255 static void
x86emuOp_jump_near_BE(u8 X86EMU_UNUSED (op1))5256 x86emuOp_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 /****************************************************************************
5276 REMARKS:
5277 Handles opcode 0x77
5278 ****************************************************************************/
5279 static void
x86emuOp_jump_near_NBE(u8 X86EMU_UNUSED (op1))5280 x86emuOp_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 /****************************************************************************
5300 REMARKS:
5301 Handles opcode 0x78
5302 ****************************************************************************/
5303 static void
x86emuOp_jump_near_S(u8 X86EMU_UNUSED (op1))5304 x86emuOp_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 /****************************************************************************
5323 REMARKS:
5324 Handles opcode 0x79
5325 ****************************************************************************/
5326 static void
x86emuOp_jump_near_NS(u8 X86EMU_UNUSED (op1))5327 x86emuOp_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 /****************************************************************************
5346 REMARKS:
5347 Handles opcode 0x7a
5348 ****************************************************************************/
5349 static void
x86emuOp_jump_near_P(u8 X86EMU_UNUSED (op1))5350 x86emuOp_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 /****************************************************************************
5369 REMARKS:
5370 Handles opcode 0x7b
5371 ****************************************************************************/
5372 static void
x86emuOp_jump_near_NP(u8 X86EMU_UNUSED (op1))5373 x86emuOp_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 /****************************************************************************
5392 REMARKS:
5393 Handles opcode 0x7c
5394 ****************************************************************************/
5395 static void
x86emuOp_jump_near_L(u8 X86EMU_UNUSED (op1))5396 x86emuOp_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 /****************************************************************************
5418 REMARKS:
5419 Handles opcode 0x7d
5420 ****************************************************************************/
5421 static void
x86emuOp_jump_near_NL(u8 X86EMU_UNUSED (op1))5422 x86emuOp_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 /****************************************************************************
5445 REMARKS:
5446 Handles opcode 0x7e
5447 ****************************************************************************/
5448 static void
x86emuOp_jump_near_LE(u8 X86EMU_UNUSED (op1))5449 x86emuOp_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 /****************************************************************************
5472 REMARKS:
5473 Handles opcode 0x7f
5474 ****************************************************************************/
5475 static void
x86emuOp_jump_near_NLE(u8 X86EMU_UNUSED (op1))5476 x86emuOp_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
5498 static 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 /****************************************************************************
5510 REMARKS:
5511 Handles opcode 0x80
5512 ****************************************************************************/
5513 static void
x86emuOp_opc80_byte_RM_IMM(u8 X86EMU_UNUSED (op1))5514 x86emuOp_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
5618 static 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
5629 static 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 /****************************************************************************
5641 REMARKS:
5642 Handles opcode 0x81
5643 ****************************************************************************/
5644 static void
x86emuOp_opc81_word_RM_IMM(u8 X86EMU_UNUSED (op1))5645 x86emuOp_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
5820 static 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 /****************************************************************************
5832 REMARKS:
5833 Handles opcode 0x82
5834 ****************************************************************************/
5835 static void
x86emuOp_opc82_byte_RM_IMM(u8 X86EMU_UNUSED (op1))5836 x86emuOp_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
5936 static 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
5947 static 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 /****************************************************************************
5959 REMARKS:
5960 Handles opcode 0x83
5961 ****************************************************************************/
5962 static void
x86emuOp_opc83_word_RM_IMM(u8 X86EMU_UNUSED (op1))5963 x86emuOp_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 /****************************************************************************
6129 REMARKS:
6130 Handles opcode 0x84
6131 ****************************************************************************/
6132 static void
x86emuOp_test_byte_RM_R(u8 X86EMU_UNUSED (op1))6133 x86emuOp_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 /****************************************************************************
6185 REMARKS:
6186 Handles opcode 0x85
6187 ****************************************************************************/
6188 static void
x86emuOp_test_word_RM_R(u8 X86EMU_UNUSED (op1))6189 x86emuOp_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 /****************************************************************************
6304 REMARKS:
6305 Handles opcode 0x86
6306 ****************************************************************************/
6307 static void
x86emuOp_xchg_byte_RM_R(u8 X86EMU_UNUSED (op1))6308 x86emuOp_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 /****************************************************************************
6372 REMARKS:
6373 Handles opcode 0x87
6374 ****************************************************************************/
6375 static void
x86emuOp_xchg_word_RM_R(u8 X86EMU_UNUSED (op1))6376 x86emuOp_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 /****************************************************************************
6515 REMARKS:
6516 Handles opcode 0x88
6517 ****************************************************************************/
6518 static void
x86emuOp_mov_byte_RM_R(u8 X86EMU_UNUSED (op1))6519 x86emuOp_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 /****************************************************************************
6567 REMARKS:
6568 Handles opcode 0x89
6569 ****************************************************************************/
6570 static void
x86emuOp_mov_word_RM_R(u8 X86EMU_UNUSED (op1))6571 x86emuOp_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 /****************************************************************************
6674 REMARKS:
6675 Handles opcode 0x8a
6676 ****************************************************************************/
6677 static void
x86emuOp_mov_byte_R_RM(u8 X86EMU_UNUSED (op1))6678 x86emuOp_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 /****************************************************************************
6730 REMARKS:
6731 Handles opcode 0x8b
6732 ****************************************************************************/
6733 static void
x86emuOp_mov_word_R_RM(u8 X86EMU_UNUSED (op1))6734 x86emuOp_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 /****************************************************************************
6849 REMARKS:
6850 Handles opcode 0x8c
6851 ****************************************************************************/
6852 static void
x86emuOp_mov_word_RM_SR(u8 X86EMU_UNUSED (op1))6853 x86emuOp_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 /****************************************************************************
6905 REMARKS:
6906 Handles opcode 0x8d
6907 ****************************************************************************/
6908 static void
x86emuOp_lea_word_R_M(u8 X86EMU_UNUSED (op1))6909 x86emuOp_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 /****************************************************************************
6987 REMARKS:
6988 Handles opcode 0x8e
6989 ****************************************************************************/
6990 static void
x86emuOp_mov_word_SR_RM(u8 X86EMU_UNUSED (op1))6991 x86emuOp_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 /****************************************************************************
7049 REMARKS:
7050 Handles opcode 0x8f
7051 ****************************************************************************/
7052 static void
x86emuOp_pop_RM(u8 X86EMU_UNUSED (op1))7053 x86emuOp_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 /****************************************************************************
7150 REMARKS:
7151 Handles opcode 0x90
7152 ****************************************************************************/
7153 static void
x86emuOp_nop(u8 X86EMU_UNUSED (op1))7154 x86emuOp_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 /****************************************************************************
7164 REMARKS:
7165 Handles opcode 0x91
7166 ****************************************************************************/
7167 static void
x86emuOp_xchg_word_AX_CX(u8 X86EMU_UNUSED (op1))7168 x86emuOp_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 /****************************************************************************
7195 REMARKS:
7196 Handles opcode 0x92
7197 ****************************************************************************/
7198 static void
x86emuOp_xchg_word_AX_DX(u8 X86EMU_UNUSED (op1))7199 x86emuOp_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 /****************************************************************************
7226 REMARKS:
7227 Handles opcode 0x93
7228 ****************************************************************************/
7229 static void
x86emuOp_xchg_word_AX_BX(u8 X86EMU_UNUSED (op1))7230 x86emuOp_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 /****************************************************************************
7257 REMARKS:
7258 Handles opcode 0x94
7259 ****************************************************************************/
7260 static void
x86emuOp_xchg_word_AX_SP(u8 X86EMU_UNUSED (op1))7261 x86emuOp_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 /****************************************************************************
7288 REMARKS:
7289 Handles opcode 0x95
7290 ****************************************************************************/
7291 static void
x86emuOp_xchg_word_AX_BP(u8 X86EMU_UNUSED (op1))7292 x86emuOp_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 /****************************************************************************
7319 REMARKS:
7320 Handles opcode 0x96
7321 ****************************************************************************/
7322 static void
x86emuOp_xchg_word_AX_SI(u8 X86EMU_UNUSED (op1))7323 x86emuOp_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 /****************************************************************************
7350 REMARKS:
7351 Handles opcode 0x97
7352 ****************************************************************************/
7353 static void
x86emuOp_xchg_word_AX_DI(u8 X86EMU_UNUSED (op1))7354 x86emuOp_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 /****************************************************************************
7381 REMARKS:
7382 Handles opcode 0x98
7383 ****************************************************************************/
7384 static void
x86emuOp_cbw(u8 X86EMU_UNUSED (op1))7385 x86emuOp_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 /****************************************************************************
7416 REMARKS:
7417 Handles opcode 0x99
7418 ****************************************************************************/
7419 static void
x86emuOp_cwd(u8 X86EMU_UNUSED (op1))7420 x86emuOp_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 /****************************************************************************
7452 REMARKS:
7453 Handles opcode 0x9a
7454 ****************************************************************************/
7455 static void
x86emuOp_call_far_IMM(u8 X86EMU_UNUSED (op1))7456 x86emuOp_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 /****************************************************************************
7495 REMARKS:
7496 Handles opcode 0x9b
7497 ****************************************************************************/
7498 static void
x86emuOp_wait(u8 X86EMU_UNUSED (op1))7499 x86emuOp_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 /****************************************************************************
7510 REMARKS:
7511 Handles opcode 0x9c
7512 ****************************************************************************/
7513 static void
x86emuOp_pushf_word(u8 X86EMU_UNUSED (op1))7514 x86emuOp_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 /****************************************************************************
7540 REMARKS:
7541 Handles opcode 0x9d
7542 ****************************************************************************/
7543 static void
x86emuOp_popf_word(u8 X86EMU_UNUSED (op1))7544 x86emuOp_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 /****************************************************************************
7565 REMARKS:
7566 Handles opcode 0x9e
7567 ****************************************************************************/
7568 static void
x86emuOp_sahf(u8 X86EMU_UNUSED (op1))7569 x86emuOp_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 /****************************************************************************
7583 REMARKS:
7584 Handles opcode 0x9f
7585 ****************************************************************************/
7586 static void
x86emuOp_lahf(u8 X86EMU_UNUSED (op1))7587 x86emuOp_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 to look real hard to notice it. */
7595 M.x86.R_AH |= 0x2;
7596 DECODE_CLEAR_SEGOVR();
7597 END_OF_INSTR();
7598 }
7599
7600 /****************************************************************************
7601 REMARKS:
7602 Handles opcode 0xa0
7603 ****************************************************************************/
7604 static void
x86emuOp_mov_AL_M_IMM(u8 X86EMU_UNUSED (op1))7605 x86emuOp_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 /****************************************************************************
7620 REMARKS:
7621 Handles opcode 0xa1
7622 ****************************************************************************/
7623 static void
x86emuOp_mov_AX_M_IMM(u8 X86EMU_UNUSED (op1))7624 x86emuOp_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 /****************************************************************************
7648 REMARKS:
7649 Handles opcode 0xa2
7650 ****************************************************************************/
7651 static void
x86emuOp_mov_M_AL_IMM(u8 X86EMU_UNUSED (op1))7652 x86emuOp_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 /****************************************************************************
7667 REMARKS:
7668 Handles opcode 0xa3
7669 ****************************************************************************/
7670 static void
x86emuOp_mov_M_AX_IMM(u8 X86EMU_UNUSED (op1))7671 x86emuOp_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 /****************************************************************************
7695 REMARKS:
7696 Handles opcode 0xa4
7697 ****************************************************************************/
7698 static void
x86emuOp_movs_byte(u8 X86EMU_UNUSED (op1))7699 x86emuOp_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 /* don't 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 /****************************************************************************
7731 REMARKS:
7732 Handles opcode 0xa5
7733 ****************************************************************************/
7734 static void
x86emuOp_movs_word(u8 X86EMU_UNUSED (op1))7735 x86emuOp_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 /* don't 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 /****************************************************************************
7782 REMARKS:
7783 Handles opcode 0xa6
7784 ****************************************************************************/
7785 static void
x86emuOp_cmps_byte(u8 X86EMU_UNUSED (op1))7786 x86emuOp_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 /****************************************************************************
7841 REMARKS:
7842 Handles opcode 0xa7
7843 ****************************************************************************/
7844 static void
x86emuOp_cmps_word(u8 X86EMU_UNUSED (op1))7845 x86emuOp_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 /****************************************************************************
7929 REMARKS:
7930 Handles opcode 0xa8
7931 ****************************************************************************/
7932 static void
x86emuOp_test_AL_IMM(u8 X86EMU_UNUSED (op1))7933 x86emuOp_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 /****************************************************************************
7948 REMARKS:
7949 Handles opcode 0xa9
7950 ****************************************************************************/
7951 static void
x86emuOp_test_AX_IMM(u8 X86EMU_UNUSED (op1))7952 x86emuOp_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 /****************************************************************************
7978 REMARKS:
7979 Handles opcode 0xaa
7980 ****************************************************************************/
7981 static void
x86emuOp_stos_byte(u8 X86EMU_UNUSED (op1))7982 x86emuOp_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 /* don't 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 /****************************************************************************
8012 REMARKS:
8013 Handles opcode 0xab
8014 ****************************************************************************/
8015 static void
x86emuOp_stos_word(u8 X86EMU_UNUSED (op1))8016 x86emuOp_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 /* don't 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 /****************************************************************************
8059 REMARKS:
8060 Handles opcode 0xac
8061 ****************************************************************************/
8062 static void
x86emuOp_lods_byte(u8 X86EMU_UNUSED (op1))8063 x86emuOp_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 /* don't 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 /****************************************************************************
8093 REMARKS:
8094 Handles opcode 0xad
8095 ****************************************************************************/
8096 static void
x86emuOp_lods_word(u8 X86EMU_UNUSED (op1))8097 x86emuOp_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 /* don't 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 /****************************************************************************
8140 REMARKS:
8141 Handles opcode 0xae
8142 ****************************************************************************/
8143 static void
x86emuOp_scas_byte(u8 X86EMU_UNUSED (op1))8144 x86emuOp_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 /****************************************************************************
8192 REMARKS:
8193 Handles opcode 0xaf
8194 ****************************************************************************/
8195 static void
x86emuOp_scas_word(u8 X86EMU_UNUSED (op1))8196 x86emuOp_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 /****************************************************************************
8271 REMARKS:
8272 Handles opcode 0xb0
8273 ****************************************************************************/
8274 static void
x86emuOp_mov_byte_AL_IMM(u8 X86EMU_UNUSED (op1))8275 x86emuOp_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 /****************************************************************************
8290 REMARKS:
8291 Handles opcode 0xb1
8292 ****************************************************************************/
8293 static void
x86emuOp_mov_byte_CL_IMM(u8 X86EMU_UNUSED (op1))8294 x86emuOp_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 /****************************************************************************
8309 REMARKS:
8310 Handles opcode 0xb2
8311 ****************************************************************************/
8312 static void
x86emuOp_mov_byte_DL_IMM(u8 X86EMU_UNUSED (op1))8313 x86emuOp_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 /****************************************************************************
8328 REMARKS:
8329 Handles opcode 0xb3
8330 ****************************************************************************/
8331 static void
x86emuOp_mov_byte_BL_IMM(u8 X86EMU_UNUSED (op1))8332 x86emuOp_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 /****************************************************************************
8347 REMARKS:
8348 Handles opcode 0xb4
8349 ****************************************************************************/
8350 static void
x86emuOp_mov_byte_AH_IMM(u8 X86EMU_UNUSED (op1))8351 x86emuOp_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 /****************************************************************************
8366 REMARKS:
8367 Handles opcode 0xb5
8368 ****************************************************************************/
8369 static void
x86emuOp_mov_byte_CH_IMM(u8 X86EMU_UNUSED (op1))8370 x86emuOp_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 /****************************************************************************
8385 REMARKS:
8386 Handles opcode 0xb6
8387 ****************************************************************************/
8388 static void
x86emuOp_mov_byte_DH_IMM(u8 X86EMU_UNUSED (op1))8389 x86emuOp_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 /****************************************************************************
8404 REMARKS:
8405 Handles opcode 0xb7
8406 ****************************************************************************/
8407 static void
x86emuOp_mov_byte_BH_IMM(u8 X86EMU_UNUSED (op1))8408 x86emuOp_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 /****************************************************************************
8423 REMARKS:
8424 Handles opcode 0xb8
8425 ****************************************************************************/
8426 static void
x86emuOp_mov_word_AX_IMM(u8 X86EMU_UNUSED (op1))8427 x86emuOp_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 /****************************************************************************
8453 REMARKS:
8454 Handles opcode 0xb9
8455 ****************************************************************************/
8456 static void
x86emuOp_mov_word_CX_IMM(u8 X86EMU_UNUSED (op1))8457 x86emuOp_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 /****************************************************************************
8483 REMARKS:
8484 Handles opcode 0xba
8485 ****************************************************************************/
8486 static void
x86emuOp_mov_word_DX_IMM(u8 X86EMU_UNUSED (op1))8487 x86emuOp_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 /****************************************************************************
8513 REMARKS:
8514 Handles opcode 0xbb
8515 ****************************************************************************/
8516 static void
x86emuOp_mov_word_BX_IMM(u8 X86EMU_UNUSED (op1))8517 x86emuOp_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 /****************************************************************************
8543 REMARKS:
8544 Handles opcode 0xbc
8545 ****************************************************************************/
8546 static void
x86emuOp_mov_word_SP_IMM(u8 X86EMU_UNUSED (op1))8547 x86emuOp_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 /****************************************************************************
8573 REMARKS:
8574 Handles opcode 0xbd
8575 ****************************************************************************/
8576 static void
x86emuOp_mov_word_BP_IMM(u8 X86EMU_UNUSED (op1))8577 x86emuOp_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 /****************************************************************************
8603 REMARKS:
8604 Handles opcode 0xbe
8605 ****************************************************************************/
8606 static void
x86emuOp_mov_word_SI_IMM(u8 X86EMU_UNUSED (op1))8607 x86emuOp_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 /****************************************************************************
8633 REMARKS:
8634 Handles opcode 0xbf
8635 ****************************************************************************/
8636 static void
x86emuOp_mov_word_DI_IMM(u8 X86EMU_UNUSED (op1))8637 x86emuOp_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. */
8663 static 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 */
8665 sar_byte,};
8666
8667 /****************************************************************************
8668 REMARKS:
8669 Handles opcode 0xc0
8670 ****************************************************************************/
8671 static void
x86emuOp_opcC0_byte_RM_MEM(u8 X86EMU_UNUSED (op1))8672 x86emuOp_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. */
8769 static 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 */
8771 sar_word,};
8772
8773 /* used by opcodes c1, d1, and d3. */
8774 static 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 */
8776 sar_long,};
8777
8778 /****************************************************************************
8779 REMARKS:
8780 Handles opcode 0xc1
8781 ****************************************************************************/
8782 static void
x86emuOp_opcC1_word_RM_MEM(u8 X86EMU_UNUSED (op1))8783 x86emuOp_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 /****************************************************************************
8938 REMARKS:
8939 Handles opcode 0xc2
8940 ****************************************************************************/
8941 static void
x86emuOp_ret_near_IMM(u8 X86EMU_UNUSED (op1))8942 x86emuOp_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 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8953 M.x86.R_EIP = pop_long();
8954 } else {
8955 M.x86.R_IP = pop_word();
8956 }
8957 M.x86.R_SP += imm;
8958 DECODE_CLEAR_SEGOVR();
8959 END_OF_INSTR();
8960 }
8961
8962 /****************************************************************************
8963 REMARKS:
8964 Handles opcode 0xc3
8965 ****************************************************************************/
8966 static void
x86emuOp_ret_near(u8 X86EMU_UNUSED (op1))8967 x86emuOp_ret_near(u8 X86EMU_UNUSED(op1))
8968 {
8969 START_OF_INSTR();
8970 DECODE_PRINTF("RET\n");
8971 RETURN_TRACE("RET", M.x86.saved_cs, M.x86.saved_ip);
8972 TRACE_AND_STEP();
8973 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8974 M.x86.R_EIP = pop_long();
8975 } else {
8976 M.x86.R_IP = pop_word();
8977 }
8978 DECODE_CLEAR_SEGOVR();
8979 END_OF_INSTR();
8980 }
8981
8982 /****************************************************************************
8983 REMARKS:
8984 Handles opcode 0xc4
8985 ****************************************************************************/
8986 static void
x86emuOp_les_R_IMM(u8 X86EMU_UNUSED (op1))8987 x86emuOp_les_R_IMM(u8 X86EMU_UNUSED(op1))
8988 {
8989 int mod, rh, rl;
8990 u16 *dstreg;
8991 uint srcoffset;
8992
8993 START_OF_INSTR();
8994 DECODE_PRINTF("LES\t");
8995 FETCH_DECODE_MODRM(mod, rh, rl);
8996 switch (mod) {
8997 case 0:
8998 dstreg = DECODE_RM_WORD_REGISTER(rh);
8999 DECODE_PRINTF(",");
9000 srcoffset = decode_rm00_address(rl);
9001 DECODE_PRINTF("\n");
9002 TRACE_AND_STEP();
9003 *dstreg = fetch_data_word(srcoffset);
9004 M.x86.R_ES = fetch_data_word(srcoffset + 2);
9005 break;
9006 case 1:
9007 dstreg = DECODE_RM_WORD_REGISTER(rh);
9008 DECODE_PRINTF(",");
9009 srcoffset = decode_rm01_address(rl);
9010 DECODE_PRINTF("\n");
9011 TRACE_AND_STEP();
9012 *dstreg = fetch_data_word(srcoffset);
9013 M.x86.R_ES = fetch_data_word(srcoffset + 2);
9014 break;
9015 case 2:
9016 dstreg = DECODE_RM_WORD_REGISTER(rh);
9017 DECODE_PRINTF(",");
9018 srcoffset = decode_rm10_address(rl);
9019 DECODE_PRINTF("\n");
9020 TRACE_AND_STEP();
9021 *dstreg = fetch_data_word(srcoffset);
9022 M.x86.R_ES = fetch_data_word(srcoffset + 2);
9023 break;
9024 case 3: /* register to register */
9025 /* UNDEFINED! */
9026 TRACE_AND_STEP();
9027 }
9028 DECODE_CLEAR_SEGOVR();
9029 END_OF_INSTR();
9030 }
9031
9032 /****************************************************************************
9033 REMARKS:
9034 Handles opcode 0xc5
9035 ****************************************************************************/
9036 static void
x86emuOp_lds_R_IMM(u8 X86EMU_UNUSED (op1))9037 x86emuOp_lds_R_IMM(u8 X86EMU_UNUSED(op1))
9038 {
9039 int mod, rh, rl;
9040 u16 *dstreg;
9041 uint srcoffset;
9042
9043 START_OF_INSTR();
9044 DECODE_PRINTF("LDS\t");
9045 FETCH_DECODE_MODRM(mod, rh, rl);
9046 switch (mod) {
9047 case 0:
9048 dstreg = DECODE_RM_WORD_REGISTER(rh);
9049 DECODE_PRINTF(",");
9050 srcoffset = decode_rm00_address(rl);
9051 DECODE_PRINTF("\n");
9052 TRACE_AND_STEP();
9053 *dstreg = fetch_data_word(srcoffset);
9054 M.x86.R_DS = fetch_data_word(srcoffset + 2);
9055 break;
9056 case 1:
9057 dstreg = DECODE_RM_WORD_REGISTER(rh);
9058 DECODE_PRINTF(",");
9059 srcoffset = decode_rm01_address(rl);
9060 DECODE_PRINTF("\n");
9061 TRACE_AND_STEP();
9062 *dstreg = fetch_data_word(srcoffset);
9063 M.x86.R_DS = fetch_data_word(srcoffset + 2);
9064 break;
9065 case 2:
9066 dstreg = DECODE_RM_WORD_REGISTER(rh);
9067 DECODE_PRINTF(",");
9068 srcoffset = decode_rm10_address(rl);
9069 DECODE_PRINTF("\n");
9070 TRACE_AND_STEP();
9071 *dstreg = fetch_data_word(srcoffset);
9072 M.x86.R_DS = fetch_data_word(srcoffset + 2);
9073 break;
9074 case 3: /* register to register */
9075 /* UNDEFINED! */
9076 TRACE_AND_STEP();
9077 }
9078 DECODE_CLEAR_SEGOVR();
9079 END_OF_INSTR();
9080 }
9081
9082 /****************************************************************************
9083 REMARKS:
9084 Handles opcode 0xc6
9085 ****************************************************************************/
9086 static void
x86emuOp_mov_byte_RM_IMM(u8 X86EMU_UNUSED (op1))9087 x86emuOp_mov_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
9088 {
9089 int mod, rl, rh;
9090 u8 *destreg;
9091 uint destoffset;
9092 u8 imm;
9093
9094 START_OF_INSTR();
9095 DECODE_PRINTF("MOV\t");
9096 FETCH_DECODE_MODRM(mod, rh, rl);
9097 if (rh != 0) {
9098 DECODE_PRINTF("ILLEGAL DECODE OF OPCODE c6\n");
9099 HALT_SYS();
9100 }
9101 switch (mod) {
9102 case 0:
9103 DECODE_PRINTF("BYTE PTR ");
9104 destoffset = decode_rm00_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 1:
9111 DECODE_PRINTF("BYTE PTR ");
9112 destoffset = decode_rm01_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 2:
9119 DECODE_PRINTF("BYTE PTR ");
9120 destoffset = decode_rm10_address(rl);
9121 imm = fetch_byte_imm();
9122 DECODE_PRINTF2(",%2x\n", imm);
9123 TRACE_AND_STEP();
9124 store_data_byte(destoffset, imm);
9125 break;
9126 case 3: /* register to register */
9127 destreg = DECODE_RM_BYTE_REGISTER(rl);
9128 imm = fetch_byte_imm();
9129 DECODE_PRINTF2(",%2x\n", imm);
9130 TRACE_AND_STEP();
9131 *destreg = imm;
9132 break;
9133 }
9134 DECODE_CLEAR_SEGOVR();
9135 END_OF_INSTR();
9136 }
9137
9138 /****************************************************************************
9139 REMARKS:
9140 Handles opcode 0xc7
9141 ****************************************************************************/
9142 static void
x86emuOp_mov_word_RM_IMM(u8 X86EMU_UNUSED (op1))9143 x86emuOp_mov_word_RM_IMM(u8 X86EMU_UNUSED(op1))
9144 {
9145 int mod, rl, rh;
9146 uint destoffset;
9147
9148 START_OF_INSTR();
9149 DECODE_PRINTF("MOV\t");
9150 FETCH_DECODE_MODRM(mod, rh, rl);
9151 if (rh != 0) {
9152 DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n");
9153 HALT_SYS();
9154 }
9155 switch (mod) {
9156 case 0:
9157 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9158 u32 imm;
9159
9160 DECODE_PRINTF("DWORD PTR ");
9161 destoffset = decode_rm00_address(rl);
9162 imm = fetch_long_imm();
9163 DECODE_PRINTF2(",%x\n", imm);
9164 TRACE_AND_STEP();
9165 store_data_long(destoffset, imm);
9166 }
9167 else {
9168 u16 imm;
9169
9170 DECODE_PRINTF("WORD PTR ");
9171 destoffset = decode_rm00_address(rl);
9172 imm = fetch_word_imm();
9173 DECODE_PRINTF2(",%x\n", imm);
9174 TRACE_AND_STEP();
9175 store_data_word(destoffset, imm);
9176 }
9177 break;
9178 case 1:
9179 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9180 u32 imm;
9181
9182 DECODE_PRINTF("DWORD PTR ");
9183 destoffset = decode_rm01_address(rl);
9184 imm = fetch_long_imm();
9185 DECODE_PRINTF2(",%x\n", imm);
9186 TRACE_AND_STEP();
9187 store_data_long(destoffset, imm);
9188 }
9189 else {
9190 u16 imm;
9191
9192 DECODE_PRINTF("WORD PTR ");
9193 destoffset = decode_rm01_address(rl);
9194 imm = fetch_word_imm();
9195 DECODE_PRINTF2(",%x\n", imm);
9196 TRACE_AND_STEP();
9197 store_data_word(destoffset, imm);
9198 }
9199 break;
9200 case 2:
9201 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9202 u32 imm;
9203
9204 DECODE_PRINTF("DWORD PTR ");
9205 destoffset = decode_rm10_address(rl);
9206 imm = fetch_long_imm();
9207 DECODE_PRINTF2(",%x\n", imm);
9208 TRACE_AND_STEP();
9209 store_data_long(destoffset, imm);
9210 }
9211 else {
9212 u16 imm;
9213
9214 DECODE_PRINTF("WORD PTR ");
9215 destoffset = decode_rm10_address(rl);
9216 imm = fetch_word_imm();
9217 DECODE_PRINTF2(",%x\n", imm);
9218 TRACE_AND_STEP();
9219 store_data_word(destoffset, imm);
9220 }
9221 break;
9222 case 3: /* register to register */
9223 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9224 u32 *destreg;
9225 u32 imm;
9226
9227 destreg = DECODE_RM_LONG_REGISTER(rl);
9228 imm = fetch_long_imm();
9229 DECODE_PRINTF2(",%x\n", imm);
9230 TRACE_AND_STEP();
9231 *destreg = imm;
9232 }
9233 else {
9234 u16 *destreg;
9235 u16 imm;
9236
9237 destreg = DECODE_RM_WORD_REGISTER(rl);
9238 imm = fetch_word_imm();
9239 DECODE_PRINTF2(",%x\n", imm);
9240 TRACE_AND_STEP();
9241 *destreg = imm;
9242 }
9243 break;
9244 }
9245 DECODE_CLEAR_SEGOVR();
9246 END_OF_INSTR();
9247 }
9248
9249 /****************************************************************************
9250 REMARKS:
9251 Handles opcode 0xc8
9252 ****************************************************************************/
9253 static void
x86emuOp_enter(u8 X86EMU_UNUSED (op1))9254 x86emuOp_enter(u8 X86EMU_UNUSED(op1))
9255 {
9256 u16 local, frame_pointer;
9257 u8 nesting;
9258 int i;
9259
9260 START_OF_INSTR();
9261 local = fetch_word_imm();
9262 nesting = fetch_byte_imm();
9263 DECODE_PRINTF2("ENTER %x\n", local);
9264 DECODE_PRINTF2(",%x\n", nesting);
9265 TRACE_AND_STEP();
9266 push_word(M.x86.R_BP);
9267 frame_pointer = M.x86.R_SP;
9268 if (nesting > 0) {
9269 for (i = 1; i < nesting; i++) {
9270 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9271 M.x86.R_BP -= 4;
9272 push_long(fetch_data_long_abs(M.x86.R_SS, M.x86.R_BP));
9273 } else {
9274 M.x86.R_BP -= 2;
9275 push_word(fetch_data_word_abs(M.x86.R_SS, M.x86.R_BP));
9276 }
9277 }
9278 push_word(frame_pointer);
9279 }
9280 M.x86.R_BP = frame_pointer;
9281 M.x86.R_SP = (u16) (M.x86.R_SP - local);
9282 DECODE_CLEAR_SEGOVR();
9283 END_OF_INSTR();
9284 }
9285
9286 /****************************************************************************
9287 REMARKS:
9288 Handles opcode 0xc9
9289 ****************************************************************************/
9290 static void
x86emuOp_leave(u8 X86EMU_UNUSED (op1))9291 x86emuOp_leave(u8 X86EMU_UNUSED(op1))
9292 {
9293 START_OF_INSTR();
9294 DECODE_PRINTF("LEAVE\n");
9295 TRACE_AND_STEP();
9296 M.x86.R_SP = M.x86.R_BP;
9297 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9298 M.x86.R_EBP = pop_long();
9299 } else {
9300 M.x86.R_BP = pop_word();
9301 }
9302 DECODE_CLEAR_SEGOVR();
9303 END_OF_INSTR();
9304 }
9305
9306 /****************************************************************************
9307 REMARKS:
9308 Handles opcode 0xca
9309 ****************************************************************************/
9310 static void
x86emuOp_ret_far_IMM(u8 X86EMU_UNUSED (op1))9311 x86emuOp_ret_far_IMM(u8 X86EMU_UNUSED(op1))
9312 {
9313 u16 imm;
9314
9315 START_OF_INSTR();
9316 DECODE_PRINTF("RETF\t");
9317 imm = fetch_word_imm();
9318 DECODE_PRINTF2("%x\n", imm);
9319 RETURN_TRACE("RETF", M.x86.saved_cs, M.x86.saved_ip);
9320 TRACE_AND_STEP();
9321 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9322 M.x86.R_EIP = pop_long();
9323 M.x86.R_CS = pop_long() & 0xffff;
9324 } else {
9325 M.x86.R_IP = pop_word();
9326 M.x86.R_CS = pop_word();
9327 }
9328 M.x86.R_SP += imm;
9329 DECODE_CLEAR_SEGOVR();
9330 END_OF_INSTR();
9331 }
9332
9333 /****************************************************************************
9334 REMARKS:
9335 Handles opcode 0xcb
9336 ****************************************************************************/
9337 static void
x86emuOp_ret_far(u8 X86EMU_UNUSED (op1))9338 x86emuOp_ret_far(u8 X86EMU_UNUSED(op1))
9339 {
9340 START_OF_INSTR();
9341 DECODE_PRINTF("RETF\n");
9342 RETURN_TRACE("RETF", M.x86.saved_cs, M.x86.saved_ip);
9343 TRACE_AND_STEP();
9344 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9345 M.x86.R_EIP = pop_long();
9346 M.x86.R_CS = pop_long() & 0xffff;
9347 } else {
9348 M.x86.R_IP = pop_word();
9349 M.x86.R_CS = pop_word();
9350 }
9351 DECODE_CLEAR_SEGOVR();
9352 END_OF_INSTR();
9353 }
9354
9355 /****************************************************************************
9356 REMARKS:
9357 Handles opcode 0xcc
9358 ****************************************************************************/
9359 static void
x86emuOp_int3(u8 X86EMU_UNUSED (op1))9360 x86emuOp_int3(u8 X86EMU_UNUSED(op1))
9361 {
9362 START_OF_INSTR();
9363 DECODE_PRINTF("INT 3\n");
9364 TRACE_AND_STEP();
9365 if (_X86EMU_intrTab[3]) {
9366 (*_X86EMU_intrTab[3]) (3);
9367 }
9368 else {
9369 push_word((u16) M.x86.R_FLG);
9370 CLEAR_FLAG(F_IF);
9371 CLEAR_FLAG(F_TF);
9372 push_word(M.x86.R_CS);
9373 M.x86.R_CS = mem_access_word(3 * 4 + 2);
9374 push_word(M.x86.R_IP);
9375 M.x86.R_IP = mem_access_word(3 * 4);
9376 }
9377 DECODE_CLEAR_SEGOVR();
9378 END_OF_INSTR();
9379 }
9380
9381 /****************************************************************************
9382 REMARKS:
9383 Handles opcode 0xcd
9384 ****************************************************************************/
9385 static void
x86emuOp_int_IMM(u8 X86EMU_UNUSED (op1))9386 x86emuOp_int_IMM(u8 X86EMU_UNUSED(op1))
9387 {
9388 u8 intnum;
9389
9390 START_OF_INSTR();
9391 DECODE_PRINTF("INT\t");
9392 intnum = fetch_byte_imm();
9393 DECODE_PRINTF2("%x\n", intnum);
9394 TRACE_AND_STEP();
9395 if (_X86EMU_intrTab[intnum]) {
9396 (*_X86EMU_intrTab[intnum]) (intnum);
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(intnum * 4 + 2);
9404 push_word(M.x86.R_IP);
9405 M.x86.R_IP = mem_access_word(intnum * 4);
9406 }
9407 DECODE_CLEAR_SEGOVR();
9408 END_OF_INSTR();
9409 }
9410
9411 /****************************************************************************
9412 REMARKS:
9413 Handles opcode 0xce
9414 ****************************************************************************/
9415 static void
x86emuOp_into(u8 X86EMU_UNUSED (op1))9416 x86emuOp_into(u8 X86EMU_UNUSED(op1))
9417 {
9418 START_OF_INSTR();
9419 DECODE_PRINTF("INTO\n");
9420 TRACE_AND_STEP();
9421 if (ACCESS_FLAG(F_OF)) {
9422 if (_X86EMU_intrTab[4]) {
9423 (*_X86EMU_intrTab[4]) (4);
9424 }
9425 else {
9426 push_word((u16) M.x86.R_FLG);
9427 CLEAR_FLAG(F_IF);
9428 CLEAR_FLAG(F_TF);
9429 push_word(M.x86.R_CS);
9430 M.x86.R_CS = mem_access_word(4 * 4 + 2);
9431 push_word(M.x86.R_IP);
9432 M.x86.R_IP = mem_access_word(4 * 4);
9433 }
9434 }
9435 DECODE_CLEAR_SEGOVR();
9436 END_OF_INSTR();
9437 }
9438
9439 /****************************************************************************
9440 REMARKS:
9441 Handles opcode 0xcf
9442 ****************************************************************************/
9443 static void
x86emuOp_iret(u8 X86EMU_UNUSED (op1))9444 x86emuOp_iret(u8 X86EMU_UNUSED(op1))
9445 {
9446 START_OF_INSTR();
9447 DECODE_PRINTF("IRET\n");
9448
9449 TRACE_AND_STEP();
9450
9451 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9452 M.x86.R_EIP = pop_long();
9453 M.x86.R_CS = pop_long() & 0xffff;
9454 M.x86.R_EFLG = (pop_long() & 0x257FD5) | (M.x86.R_EFLG & 0x1A0000);
9455 } else {
9456 M.x86.R_IP = pop_word();
9457 M.x86.R_CS = pop_word();
9458 M.x86.R_FLG = pop_word();
9459 }
9460 DECODE_CLEAR_SEGOVR();
9461 END_OF_INSTR();
9462 }
9463
9464 /****************************************************************************
9465 REMARKS:
9466 Handles opcode 0xd0
9467 ****************************************************************************/
9468 static void
x86emuOp_opcD0_byte_RM_1(u8 X86EMU_UNUSED (op1))9469 x86emuOp_opcD0_byte_RM_1(u8 X86EMU_UNUSED(op1))
9470 {
9471 int mod, rl, rh;
9472 u8 *destreg;
9473 uint destoffset;
9474 u8 destval;
9475
9476 /*
9477 * Yet another weirdo special case instruction format. Part of
9478 * the opcode held below in "RH". Doubly nested case would
9479 * result, except that the decoded instruction
9480 */
9481 START_OF_INSTR();
9482 FETCH_DECODE_MODRM(mod, rh, rl);
9483 #ifdef DEBUG
9484 if (DEBUG_DECODE()) {
9485 /* XXX DECODE_PRINTF may be changed to something more
9486 general, so that it is important to leave the strings
9487 in the same format, even though the result is that the
9488 above test is done twice. */
9489 switch (rh) {
9490 case 0:
9491 DECODE_PRINTF("ROL\t");
9492 break;
9493 case 1:
9494 DECODE_PRINTF("ROR\t");
9495 break;
9496 case 2:
9497 DECODE_PRINTF("RCL\t");
9498 break;
9499 case 3:
9500 DECODE_PRINTF("RCR\t");
9501 break;
9502 case 4:
9503 DECODE_PRINTF("SHL\t");
9504 break;
9505 case 5:
9506 DECODE_PRINTF("SHR\t");
9507 break;
9508 case 6:
9509 DECODE_PRINTF("SAL\t");
9510 break;
9511 case 7:
9512 DECODE_PRINTF("SAR\t");
9513 break;
9514 }
9515 }
9516 #endif
9517 /* know operation, decode the mod byte to find the addressing
9518 mode. */
9519 switch (mod) {
9520 case 0:
9521 DECODE_PRINTF("BYTE PTR ");
9522 destoffset = decode_rm00_address(rl);
9523 DECODE_PRINTF(",1\n");
9524 destval = fetch_data_byte(destoffset);
9525 TRACE_AND_STEP();
9526 destval = (*opcD0_byte_operation[rh]) (destval, 1);
9527 store_data_byte(destoffset, destval);
9528 break;
9529 case 1:
9530 DECODE_PRINTF("BYTE PTR ");
9531 destoffset = decode_rm01_address(rl);
9532 DECODE_PRINTF(",1\n");
9533 destval = fetch_data_byte(destoffset);
9534 TRACE_AND_STEP();
9535 destval = (*opcD0_byte_operation[rh]) (destval, 1);
9536 store_data_byte(destoffset, destval);
9537 break;
9538 case 2:
9539 DECODE_PRINTF("BYTE PTR ");
9540 destoffset = decode_rm10_address(rl);
9541 DECODE_PRINTF(",1\n");
9542 destval = fetch_data_byte(destoffset);
9543 TRACE_AND_STEP();
9544 destval = (*opcD0_byte_operation[rh]) (destval, 1);
9545 store_data_byte(destoffset, destval);
9546 break;
9547 case 3: /* register to register */
9548 destreg = DECODE_RM_BYTE_REGISTER(rl);
9549 DECODE_PRINTF(",1\n");
9550 TRACE_AND_STEP();
9551 destval = (*opcD0_byte_operation[rh]) (*destreg, 1);
9552 *destreg = destval;
9553 break;
9554 }
9555 DECODE_CLEAR_SEGOVR();
9556 END_OF_INSTR();
9557 }
9558
9559 /****************************************************************************
9560 REMARKS:
9561 Handles opcode 0xd1
9562 ****************************************************************************/
9563 static void
x86emuOp_opcD1_word_RM_1(u8 X86EMU_UNUSED (op1))9564 x86emuOp_opcD1_word_RM_1(u8 X86EMU_UNUSED(op1))
9565 {
9566 int mod, rl, rh;
9567 uint destoffset;
9568
9569 /*
9570 * Yet another weirdo special case instruction format. Part of
9571 * the opcode held below in "RH". Doubly nested case would
9572 * result, except that the decoded instruction
9573 */
9574 START_OF_INSTR();
9575 FETCH_DECODE_MODRM(mod, rh, rl);
9576 #ifdef DEBUG
9577 if (DEBUG_DECODE()) {
9578 /* XXX DECODE_PRINTF may be changed to something more
9579 general, so that it is important to leave the strings
9580 in the same format, even though the result is that the
9581 above test is done twice. */
9582 switch (rh) {
9583 case 0:
9584 DECODE_PRINTF("ROL\t");
9585 break;
9586 case 1:
9587 DECODE_PRINTF("ROR\t");
9588 break;
9589 case 2:
9590 DECODE_PRINTF("RCL\t");
9591 break;
9592 case 3:
9593 DECODE_PRINTF("RCR\t");
9594 break;
9595 case 4:
9596 DECODE_PRINTF("SHL\t");
9597 break;
9598 case 5:
9599 DECODE_PRINTF("SHR\t");
9600 break;
9601 case 6:
9602 DECODE_PRINTF("SAL\t");
9603 break;
9604 case 7:
9605 DECODE_PRINTF("SAR\t");
9606 break;
9607 }
9608 }
9609 #endif
9610 /* know operation, decode the mod byte to find the addressing
9611 mode. */
9612 switch (mod) {
9613 case 0:
9614 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9615 u32 destval;
9616
9617 DECODE_PRINTF("DWORD PTR ");
9618 destoffset = decode_rm00_address(rl);
9619 DECODE_PRINTF(",1\n");
9620 destval = fetch_data_long(destoffset);
9621 TRACE_AND_STEP();
9622 destval = (*opcD1_long_operation[rh]) (destval, 1);
9623 store_data_long(destoffset, destval);
9624 }
9625 else {
9626 u16 destval;
9627
9628 DECODE_PRINTF("WORD PTR ");
9629 destoffset = decode_rm00_address(rl);
9630 DECODE_PRINTF(",1\n");
9631 destval = fetch_data_word(destoffset);
9632 TRACE_AND_STEP();
9633 destval = (*opcD1_word_operation[rh]) (destval, 1);
9634 store_data_word(destoffset, destval);
9635 }
9636 break;
9637 case 1:
9638 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9639 u32 destval;
9640
9641 DECODE_PRINTF("DWORD PTR ");
9642 destoffset = decode_rm01_address(rl);
9643 DECODE_PRINTF(",1\n");
9644 destval = fetch_data_long(destoffset);
9645 TRACE_AND_STEP();
9646 destval = (*opcD1_long_operation[rh]) (destval, 1);
9647 store_data_long(destoffset, destval);
9648 }
9649 else {
9650 u16 destval;
9651
9652 DECODE_PRINTF("WORD PTR ");
9653 destoffset = decode_rm01_address(rl);
9654 DECODE_PRINTF(",1\n");
9655 destval = fetch_data_word(destoffset);
9656 TRACE_AND_STEP();
9657 destval = (*opcD1_word_operation[rh]) (destval, 1);
9658 store_data_word(destoffset, destval);
9659 }
9660 break;
9661 case 2:
9662 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9663 u32 destval;
9664
9665 DECODE_PRINTF("DWORD PTR ");
9666 destoffset = decode_rm10_address(rl);
9667 DECODE_PRINTF(",1\n");
9668 destval = fetch_data_long(destoffset);
9669 TRACE_AND_STEP();
9670 destval = (*opcD1_long_operation[rh]) (destval, 1);
9671 store_data_long(destoffset, destval);
9672 }
9673 else {
9674 u16 destval;
9675
9676 DECODE_PRINTF("BYTE PTR ");
9677 destoffset = decode_rm10_address(rl);
9678 DECODE_PRINTF(",1\n");
9679 destval = fetch_data_word(destoffset);
9680 TRACE_AND_STEP();
9681 destval = (*opcD1_word_operation[rh]) (destval, 1);
9682 store_data_word(destoffset, destval);
9683 }
9684 break;
9685 case 3: /* register to register */
9686 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9687 u32 destval;
9688 u32 *destreg;
9689
9690 destreg = DECODE_RM_LONG_REGISTER(rl);
9691 DECODE_PRINTF(",1\n");
9692 TRACE_AND_STEP();
9693 destval = (*opcD1_long_operation[rh]) (*destreg, 1);
9694 *destreg = destval;
9695 }
9696 else {
9697 u16 destval;
9698 u16 *destreg;
9699
9700 destreg = DECODE_RM_WORD_REGISTER(rl);
9701 DECODE_PRINTF(",1\n");
9702 TRACE_AND_STEP();
9703 destval = (*opcD1_word_operation[rh]) (*destreg, 1);
9704 *destreg = destval;
9705 }
9706 break;
9707 }
9708 DECODE_CLEAR_SEGOVR();
9709 END_OF_INSTR();
9710 }
9711
9712 /****************************************************************************
9713 REMARKS:
9714 Handles opcode 0xd2
9715 ****************************************************************************/
9716 static void
x86emuOp_opcD2_byte_RM_CL(u8 X86EMU_UNUSED (op1))9717 x86emuOp_opcD2_byte_RM_CL(u8 X86EMU_UNUSED(op1))
9718 {
9719 int mod, rl, rh;
9720 u8 *destreg;
9721 uint destoffset;
9722 u8 destval;
9723 u8 amt;
9724
9725 /*
9726 * Yet another weirdo special case instruction format. Part of
9727 * the opcode held below in "RH". Doubly nested case would
9728 * result, except that the decoded instruction
9729 */
9730 START_OF_INSTR();
9731 FETCH_DECODE_MODRM(mod, rh, rl);
9732 #ifdef DEBUG
9733 if (DEBUG_DECODE()) {
9734 /* XXX DECODE_PRINTF may be changed to something more
9735 general, so that it is important to leave the strings
9736 in the same format, even though the result is that the
9737 above test is done twice. */
9738 switch (rh) {
9739 case 0:
9740 DECODE_PRINTF("ROL\t");
9741 break;
9742 case 1:
9743 DECODE_PRINTF("ROR\t");
9744 break;
9745 case 2:
9746 DECODE_PRINTF("RCL\t");
9747 break;
9748 case 3:
9749 DECODE_PRINTF("RCR\t");
9750 break;
9751 case 4:
9752 DECODE_PRINTF("SHL\t");
9753 break;
9754 case 5:
9755 DECODE_PRINTF("SHR\t");
9756 break;
9757 case 6:
9758 DECODE_PRINTF("SAL\t");
9759 break;
9760 case 7:
9761 DECODE_PRINTF("SAR\t");
9762 break;
9763 }
9764 }
9765 #endif
9766 /* know operation, decode the mod byte to find the addressing
9767 mode. */
9768 amt = M.x86.R_CL;
9769 switch (mod) {
9770 case 0:
9771 DECODE_PRINTF("BYTE PTR ");
9772 destoffset = decode_rm00_address(rl);
9773 DECODE_PRINTF(",CL\n");
9774 destval = fetch_data_byte(destoffset);
9775 TRACE_AND_STEP();
9776 destval = (*opcD0_byte_operation[rh]) (destval, amt);
9777 store_data_byte(destoffset, destval);
9778 break;
9779 case 1:
9780 DECODE_PRINTF("BYTE PTR ");
9781 destoffset = decode_rm01_address(rl);
9782 DECODE_PRINTF(",CL\n");
9783 destval = fetch_data_byte(destoffset);
9784 TRACE_AND_STEP();
9785 destval = (*opcD0_byte_operation[rh]) (destval, amt);
9786 store_data_byte(destoffset, destval);
9787 break;
9788 case 2:
9789 DECODE_PRINTF("BYTE PTR ");
9790 destoffset = decode_rm10_address(rl);
9791 DECODE_PRINTF(",CL\n");
9792 destval = fetch_data_byte(destoffset);
9793 TRACE_AND_STEP();
9794 destval = (*opcD0_byte_operation[rh]) (destval, amt);
9795 store_data_byte(destoffset, destval);
9796 break;
9797 case 3: /* register to register */
9798 destreg = DECODE_RM_BYTE_REGISTER(rl);
9799 DECODE_PRINTF(",CL\n");
9800 TRACE_AND_STEP();
9801 destval = (*opcD0_byte_operation[rh]) (*destreg, amt);
9802 *destreg = destval;
9803 break;
9804 }
9805 DECODE_CLEAR_SEGOVR();
9806 END_OF_INSTR();
9807 }
9808
9809 /****************************************************************************
9810 REMARKS:
9811 Handles opcode 0xd3
9812 ****************************************************************************/
9813 static void
x86emuOp_opcD3_word_RM_CL(u8 X86EMU_UNUSED (op1))9814 x86emuOp_opcD3_word_RM_CL(u8 X86EMU_UNUSED(op1))
9815 {
9816 int mod, rl, rh;
9817 uint destoffset;
9818 u8 amt;
9819
9820 /*
9821 * Yet another weirdo special case instruction format. Part of
9822 * the opcode held below in "RH". Doubly nested case would
9823 * result, except that the decoded instruction
9824 */
9825 START_OF_INSTR();
9826 FETCH_DECODE_MODRM(mod, rh, rl);
9827 #ifdef DEBUG
9828 if (DEBUG_DECODE()) {
9829 /* XXX DECODE_PRINTF may be changed to something more
9830 general, so that it is important to leave the strings
9831 in the same format, even though the result is that the
9832 above test is done twice. */
9833 switch (rh) {
9834 case 0:
9835 DECODE_PRINTF("ROL\t");
9836 break;
9837 case 1:
9838 DECODE_PRINTF("ROR\t");
9839 break;
9840 case 2:
9841 DECODE_PRINTF("RCL\t");
9842 break;
9843 case 3:
9844 DECODE_PRINTF("RCR\t");
9845 break;
9846 case 4:
9847 DECODE_PRINTF("SHL\t");
9848 break;
9849 case 5:
9850 DECODE_PRINTF("SHR\t");
9851 break;
9852 case 6:
9853 DECODE_PRINTF("SAL\t");
9854 break;
9855 case 7:
9856 DECODE_PRINTF("SAR\t");
9857 break;
9858 }
9859 }
9860 #endif
9861 /* know operation, decode the mod byte to find the addressing
9862 mode. */
9863 amt = M.x86.R_CL;
9864 switch (mod) {
9865 case 0:
9866 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9867 u32 destval;
9868
9869 DECODE_PRINTF("DWORD PTR ");
9870 destoffset = decode_rm00_address(rl);
9871 DECODE_PRINTF(",CL\n");
9872 destval = fetch_data_long(destoffset);
9873 TRACE_AND_STEP();
9874 destval = (*opcD1_long_operation[rh]) (destval, amt);
9875 store_data_long(destoffset, destval);
9876 }
9877 else {
9878 u16 destval;
9879
9880 DECODE_PRINTF("WORD PTR ");
9881 destoffset = decode_rm00_address(rl);
9882 DECODE_PRINTF(",CL\n");
9883 destval = fetch_data_word(destoffset);
9884 TRACE_AND_STEP();
9885 destval = (*opcD1_word_operation[rh]) (destval, amt);
9886 store_data_word(destoffset, destval);
9887 }
9888 break;
9889 case 1:
9890 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9891 u32 destval;
9892
9893 DECODE_PRINTF("DWORD PTR ");
9894 destoffset = decode_rm01_address(rl);
9895 DECODE_PRINTF(",CL\n");
9896 destval = fetch_data_long(destoffset);
9897 TRACE_AND_STEP();
9898 destval = (*opcD1_long_operation[rh]) (destval, amt);
9899 store_data_long(destoffset, destval);
9900 }
9901 else {
9902 u16 destval;
9903
9904 DECODE_PRINTF("WORD PTR ");
9905 destoffset = decode_rm01_address(rl);
9906 DECODE_PRINTF(",CL\n");
9907 destval = fetch_data_word(destoffset);
9908 TRACE_AND_STEP();
9909 destval = (*opcD1_word_operation[rh]) (destval, amt);
9910 store_data_word(destoffset, destval);
9911 }
9912 break;
9913 case 2:
9914 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9915 u32 destval;
9916
9917 DECODE_PRINTF("DWORD PTR ");
9918 destoffset = decode_rm10_address(rl);
9919 DECODE_PRINTF(",CL\n");
9920 destval = fetch_data_long(destoffset);
9921 TRACE_AND_STEP();
9922 destval = (*opcD1_long_operation[rh]) (destval, amt);
9923 store_data_long(destoffset, destval);
9924 }
9925 else {
9926 u16 destval;
9927
9928 DECODE_PRINTF("WORD PTR ");
9929 destoffset = decode_rm10_address(rl);
9930 DECODE_PRINTF(",CL\n");
9931 destval = fetch_data_word(destoffset);
9932 TRACE_AND_STEP();
9933 destval = (*opcD1_word_operation[rh]) (destval, amt);
9934 store_data_word(destoffset, destval);
9935 }
9936 break;
9937 case 3: /* register to register */
9938 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9939 u32 *destreg;
9940
9941 destreg = DECODE_RM_LONG_REGISTER(rl);
9942 DECODE_PRINTF(",CL\n");
9943 TRACE_AND_STEP();
9944 *destreg = (*opcD1_long_operation[rh]) (*destreg, amt);
9945 }
9946 else {
9947 u16 *destreg;
9948
9949 destreg = DECODE_RM_WORD_REGISTER(rl);
9950 DECODE_PRINTF(",CL\n");
9951 TRACE_AND_STEP();
9952 *destreg = (*opcD1_word_operation[rh]) (*destreg, amt);
9953 }
9954 break;
9955 }
9956 DECODE_CLEAR_SEGOVR();
9957 END_OF_INSTR();
9958 }
9959
9960 /****************************************************************************
9961 REMARKS:
9962 Handles opcode 0xd4
9963 ****************************************************************************/
9964 static void
x86emuOp_aam(u8 X86EMU_UNUSED (op1))9965 x86emuOp_aam(u8 X86EMU_UNUSED(op1))
9966 {
9967 u8 a;
9968
9969 START_OF_INSTR();
9970 DECODE_PRINTF("AAM\n");
9971 a = fetch_byte_imm(); /* this is a stupid encoding. */
9972 if (a != 10) {
9973 /* fix: add base decoding
9974 aam_word(u8 val, int base a) */
9975 DECODE_PRINTF("ERROR DECODING AAM\n");
9976 TRACE_REGS();
9977 HALT_SYS();
9978 }
9979 TRACE_AND_STEP();
9980 /* note the type change here --- returning AL and AH in AX. */
9981 M.x86.R_AX = aam_word(M.x86.R_AL);
9982 DECODE_CLEAR_SEGOVR();
9983 END_OF_INSTR();
9984 }
9985
9986 /****************************************************************************
9987 REMARKS:
9988 Handles opcode 0xd5
9989 ****************************************************************************/
9990 static void
x86emuOp_aad(u8 X86EMU_UNUSED (op1))9991 x86emuOp_aad(u8 X86EMU_UNUSED(op1))
9992 {
9993 u8 a;
9994
9995 START_OF_INSTR();
9996 DECODE_PRINTF("AAD\n");
9997 a = fetch_byte_imm();
9998 if (a != 10) {
9999 /* fix: add base decoding
10000 aad_word(u16 val, int base a) */
10001 DECODE_PRINTF("ERROR DECODING AAM\n");
10002 TRACE_REGS();
10003 HALT_SYS();
10004 }
10005 TRACE_AND_STEP();
10006 M.x86.R_AX = aad_word(M.x86.R_AX);
10007 DECODE_CLEAR_SEGOVR();
10008 END_OF_INSTR();
10009 }
10010
10011 /* opcode 0xd6 ILLEGAL OPCODE */
10012
10013 /****************************************************************************
10014 REMARKS:
10015 Handles opcode 0xd7
10016 ****************************************************************************/
10017 static void
x86emuOp_xlat(u8 X86EMU_UNUSED (op1))10018 x86emuOp_xlat(u8 X86EMU_UNUSED(op1))
10019 {
10020 u16 addr;
10021
10022 START_OF_INSTR();
10023 DECODE_PRINTF("XLAT\n");
10024 TRACE_AND_STEP();
10025 addr = (u16) (M.x86.R_BX + (u8) M.x86.R_AL);
10026 M.x86.R_AL = fetch_data_byte(addr);
10027 DECODE_CLEAR_SEGOVR();
10028 END_OF_INSTR();
10029 }
10030
10031 /* instuctions D8 .. DF are in i87_ops.c */
10032
10033 /****************************************************************************
10034 REMARKS:
10035 Handles opcode 0xe0
10036 ****************************************************************************/
10037 static void
x86emuOp_loopne(u8 X86EMU_UNUSED (op1))10038 x86emuOp_loopne(u8 X86EMU_UNUSED(op1))
10039 {
10040 s16 ip;
10041
10042 START_OF_INSTR();
10043 DECODE_PRINTF("LOOPNE\t");
10044 ip = (s8) fetch_byte_imm();
10045 ip += (s16) M.x86.R_IP;
10046 DECODE_PRINTF2("%04x\n", ip);
10047 TRACE_AND_STEP();
10048 M.x86.R_CX -= 1;
10049 if (M.x86.R_CX != 0 && !ACCESS_FLAG(F_ZF)) /* CX != 0 and !ZF */
10050 M.x86.R_IP = ip;
10051 DECODE_CLEAR_SEGOVR();
10052 END_OF_INSTR();
10053 }
10054
10055 /****************************************************************************
10056 REMARKS:
10057 Handles opcode 0xe1
10058 ****************************************************************************/
10059 static void
x86emuOp_loope(u8 X86EMU_UNUSED (op1))10060 x86emuOp_loope(u8 X86EMU_UNUSED(op1))
10061 {
10062 s16 ip;
10063
10064 START_OF_INSTR();
10065 DECODE_PRINTF("LOOPE\t");
10066 ip = (s8) fetch_byte_imm();
10067 ip += (s16) M.x86.R_IP;
10068 DECODE_PRINTF2("%04x\n", ip);
10069 TRACE_AND_STEP();
10070 M.x86.R_CX -= 1;
10071 if (M.x86.R_CX != 0 && ACCESS_FLAG(F_ZF)) /* CX != 0 and ZF */
10072 M.x86.R_IP = ip;
10073 DECODE_CLEAR_SEGOVR();
10074 END_OF_INSTR();
10075 }
10076
10077 /****************************************************************************
10078 REMARKS:
10079 Handles opcode 0xe2
10080 ****************************************************************************/
10081 static void
x86emuOp_loop(u8 X86EMU_UNUSED (op1))10082 x86emuOp_loop(u8 X86EMU_UNUSED(op1))
10083 {
10084 s16 ip;
10085
10086 START_OF_INSTR();
10087 DECODE_PRINTF("LOOP\t");
10088 ip = (s8) fetch_byte_imm();
10089 ip += (s16) M.x86.R_IP;
10090 DECODE_PRINTF2("%04x\n", ip);
10091 TRACE_AND_STEP();
10092 M.x86.R_CX -= 1;
10093 if (M.x86.R_CX != 0)
10094 M.x86.R_IP = ip;
10095 DECODE_CLEAR_SEGOVR();
10096 END_OF_INSTR();
10097 }
10098
10099 /****************************************************************************
10100 REMARKS:
10101 Handles opcode 0xe3
10102 ****************************************************************************/
10103 static void
x86emuOp_jcxz(u8 X86EMU_UNUSED (op1))10104 x86emuOp_jcxz(u8 X86EMU_UNUSED(op1))
10105 {
10106 u16 target;
10107 s8 offset;
10108
10109 /* jump to byte offset if overflow flag is set */
10110 START_OF_INSTR();
10111 DECODE_PRINTF("JCXZ\t");
10112 offset = (s8) fetch_byte_imm();
10113 target = (u16) (M.x86.R_IP + offset);
10114 DECODE_PRINTF2("%x\n", target);
10115 TRACE_AND_STEP();
10116 if (M.x86.R_CX == 0)
10117 M.x86.R_IP = target;
10118 DECODE_CLEAR_SEGOVR();
10119 END_OF_INSTR();
10120 }
10121
10122 /****************************************************************************
10123 REMARKS:
10124 Handles opcode 0xe4
10125 ****************************************************************************/
10126 static void
x86emuOp_in_byte_AL_IMM(u8 X86EMU_UNUSED (op1))10127 x86emuOp_in_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
10128 {
10129 u8 port;
10130
10131 START_OF_INSTR();
10132 DECODE_PRINTF("IN\t");
10133 port = (u8) fetch_byte_imm();
10134 DECODE_PRINTF2("%x,AL\n", port);
10135 TRACE_AND_STEP();
10136 M.x86.R_AL = (*sys_inb) (port);
10137 DECODE_CLEAR_SEGOVR();
10138 END_OF_INSTR();
10139 }
10140
10141 /****************************************************************************
10142 REMARKS:
10143 Handles opcode 0xe5
10144 ****************************************************************************/
10145 static void
x86emuOp_in_word_AX_IMM(u8 X86EMU_UNUSED (op1))10146 x86emuOp_in_word_AX_IMM(u8 X86EMU_UNUSED(op1))
10147 {
10148 u8 port;
10149
10150 START_OF_INSTR();
10151 DECODE_PRINTF("IN\t");
10152 port = (u8) fetch_byte_imm();
10153 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10154 DECODE_PRINTF2("EAX,%x\n", port);
10155 }
10156 else {
10157 DECODE_PRINTF2("AX,%x\n", port);
10158 }
10159 TRACE_AND_STEP();
10160 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10161 M.x86.R_EAX = (*sys_inl) (port);
10162 }
10163 else {
10164 M.x86.R_AX = (*sys_inw) (port);
10165 }
10166 DECODE_CLEAR_SEGOVR();
10167 END_OF_INSTR();
10168 }
10169
10170 /****************************************************************************
10171 REMARKS:
10172 Handles opcode 0xe6
10173 ****************************************************************************/
10174 static void
x86emuOp_out_byte_IMM_AL(u8 X86EMU_UNUSED (op1))10175 x86emuOp_out_byte_IMM_AL(u8 X86EMU_UNUSED(op1))
10176 {
10177 u8 port;
10178
10179 START_OF_INSTR();
10180 DECODE_PRINTF("OUT\t");
10181 port = (u8) fetch_byte_imm();
10182 DECODE_PRINTF2("%x,AL\n", port);
10183 TRACE_AND_STEP();
10184 (*sys_outb) (port, M.x86.R_AL);
10185 DECODE_CLEAR_SEGOVR();
10186 END_OF_INSTR();
10187 }
10188
10189 /****************************************************************************
10190 REMARKS:
10191 Handles opcode 0xe7
10192 ****************************************************************************/
10193 static void
x86emuOp_out_word_IMM_AX(u8 X86EMU_UNUSED (op1))10194 x86emuOp_out_word_IMM_AX(u8 X86EMU_UNUSED(op1))
10195 {
10196 u8 port;
10197
10198 START_OF_INSTR();
10199 DECODE_PRINTF("OUT\t");
10200 port = (u8) fetch_byte_imm();
10201 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10202 DECODE_PRINTF2("%x,EAX\n", port);
10203 }
10204 else {
10205 DECODE_PRINTF2("%x,AX\n", port);
10206 }
10207 TRACE_AND_STEP();
10208 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10209 (*sys_outl) (port, M.x86.R_EAX);
10210 }
10211 else {
10212 (*sys_outw) (port, M.x86.R_AX);
10213 }
10214 DECODE_CLEAR_SEGOVR();
10215 END_OF_INSTR();
10216 }
10217
10218 /****************************************************************************
10219 REMARKS:
10220 Handles opcode 0xe8
10221 ****************************************************************************/
10222 static void
x86emuOp_call_near_IMM(u8 X86EMU_UNUSED (op1))10223 x86emuOp_call_near_IMM(u8 X86EMU_UNUSED(op1))
10224 {
10225 s16 ip16 = 0;
10226 s32 ip32 = 0;
10227
10228 START_OF_INSTR();
10229 DECODE_PRINTF("CALL\t");
10230 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10231 ip32 = (s32) fetch_long_imm();
10232 ip32 += (s16) M.x86.R_IP; /* CHECK SIGN */
10233 DECODE_PRINTF2("%04x\n", (u16) ip32);
10234 CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, M.x86.R_CS, ip32, "");
10235 }
10236 else {
10237 ip16 = (s16) fetch_word_imm();
10238 ip16 += (s16) M.x86.R_IP; /* CHECK SIGN */
10239 DECODE_PRINTF2("%04x\n", (u16) ip16);
10240 CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, M.x86.R_CS, ip16, "");
10241 }
10242 TRACE_AND_STEP();
10243 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10244 push_long(M.x86.R_EIP);
10245 M.x86.R_EIP = ip32 & 0xffff;
10246 }
10247 else {
10248 push_word(M.x86.R_IP);
10249 M.x86.R_EIP = ip16;
10250 }
10251 DECODE_CLEAR_SEGOVR();
10252 END_OF_INSTR();
10253 }
10254
10255 /****************************************************************************
10256 REMARKS:
10257 Handles opcode 0xe9
10258 ****************************************************************************/
10259 static void
x86emuOp_jump_near_IMM(u8 X86EMU_UNUSED (op1))10260 x86emuOp_jump_near_IMM(u8 X86EMU_UNUSED(op1))
10261 {
10262 u32 ip;
10263
10264 START_OF_INSTR();
10265 DECODE_PRINTF("JMP\t");
10266 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10267 ip = (u32) fetch_long_imm();
10268 ip += (u32) M.x86.R_EIP;
10269 DECODE_PRINTF2("%08x\n", (u32) ip);
10270 TRACE_AND_STEP();
10271 M.x86.R_EIP = (u32) ip;
10272 }
10273 else {
10274 ip = (s16) fetch_word_imm();
10275 ip += (s16) M.x86.R_IP;
10276 DECODE_PRINTF2("%04x\n", (u16) ip);
10277 TRACE_AND_STEP();
10278 M.x86.R_IP = (u16) ip;
10279 }
10280 DECODE_CLEAR_SEGOVR();
10281 END_OF_INSTR();
10282 }
10283
10284 /****************************************************************************
10285 REMARKS:
10286 Handles opcode 0xea
10287 ****************************************************************************/
10288 static void
x86emuOp_jump_far_IMM(u8 X86EMU_UNUSED (op1))10289 x86emuOp_jump_far_IMM(u8 X86EMU_UNUSED(op1))
10290 {
10291 u16 cs;
10292 u32 ip;
10293
10294 START_OF_INSTR();
10295 DECODE_PRINTF("JMP\tFAR ");
10296 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10297 ip = fetch_long_imm();
10298 }
10299 else {
10300 ip = fetch_word_imm();
10301 }
10302 cs = fetch_word_imm();
10303 DECODE_PRINTF2("%04x:", cs);
10304 DECODE_PRINTF2("%04x\n", ip);
10305 TRACE_AND_STEP();
10306 M.x86.R_EIP = ip & 0xffff;
10307 M.x86.R_CS = cs;
10308 DECODE_CLEAR_SEGOVR();
10309 END_OF_INSTR();
10310 }
10311
10312 /****************************************************************************
10313 REMARKS:
10314 Handles opcode 0xeb
10315 ****************************************************************************/
10316 static void
x86emuOp_jump_byte_IMM(u8 X86EMU_UNUSED (op1))10317 x86emuOp_jump_byte_IMM(u8 X86EMU_UNUSED(op1))
10318 {
10319 u16 target;
10320 s8 offset;
10321
10322 START_OF_INSTR();
10323 DECODE_PRINTF("JMP\t");
10324 offset = (s8) fetch_byte_imm();
10325 target = (u16) (M.x86.R_IP + offset);
10326 DECODE_PRINTF2("%x\n", target);
10327 TRACE_AND_STEP();
10328 M.x86.R_IP = target;
10329 DECODE_CLEAR_SEGOVR();
10330 END_OF_INSTR();
10331 }
10332
10333 /****************************************************************************
10334 REMARKS:
10335 Handles opcode 0xec
10336 ****************************************************************************/
10337 static void
x86emuOp_in_byte_AL_DX(u8 X86EMU_UNUSED (op1))10338 x86emuOp_in_byte_AL_DX(u8 X86EMU_UNUSED(op1))
10339 {
10340 START_OF_INSTR();
10341 DECODE_PRINTF("IN\tAL,DX\n");
10342 TRACE_AND_STEP();
10343 M.x86.R_AL = (*sys_inb) (M.x86.R_DX);
10344 DECODE_CLEAR_SEGOVR();
10345 END_OF_INSTR();
10346 }
10347
10348 /****************************************************************************
10349 REMARKS:
10350 Handles opcode 0xed
10351 ****************************************************************************/
10352 static void
x86emuOp_in_word_AX_DX(u8 X86EMU_UNUSED (op1))10353 x86emuOp_in_word_AX_DX(u8 X86EMU_UNUSED(op1))
10354 {
10355 START_OF_INSTR();
10356 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10357 DECODE_PRINTF("IN\tEAX,DX\n");
10358 }
10359 else {
10360 DECODE_PRINTF("IN\tAX,DX\n");
10361 }
10362 TRACE_AND_STEP();
10363 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10364 M.x86.R_EAX = (*sys_inl) (M.x86.R_DX);
10365 }
10366 else {
10367 M.x86.R_AX = (*sys_inw) (M.x86.R_DX);
10368 }
10369 DECODE_CLEAR_SEGOVR();
10370 END_OF_INSTR();
10371 }
10372
10373 /****************************************************************************
10374 REMARKS:
10375 Handles opcode 0xee
10376 ****************************************************************************/
10377 static void
x86emuOp_out_byte_DX_AL(u8 X86EMU_UNUSED (op1))10378 x86emuOp_out_byte_DX_AL(u8 X86EMU_UNUSED(op1))
10379 {
10380 START_OF_INSTR();
10381 DECODE_PRINTF("OUT\tDX,AL\n");
10382 TRACE_AND_STEP();
10383 (*sys_outb) (M.x86.R_DX, M.x86.R_AL);
10384 DECODE_CLEAR_SEGOVR();
10385 END_OF_INSTR();
10386 }
10387
10388 /****************************************************************************
10389 REMARKS:
10390 Handles opcode 0xef
10391 ****************************************************************************/
10392 static void
x86emuOp_out_word_DX_AX(u8 X86EMU_UNUSED (op1))10393 x86emuOp_out_word_DX_AX(u8 X86EMU_UNUSED(op1))
10394 {
10395 START_OF_INSTR();
10396 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10397 DECODE_PRINTF("OUT\tDX,EAX\n");
10398 }
10399 else {
10400 DECODE_PRINTF("OUT\tDX,AX\n");
10401 }
10402 TRACE_AND_STEP();
10403 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10404 (*sys_outl) (M.x86.R_DX, M.x86.R_EAX);
10405 }
10406 else {
10407 (*sys_outw) (M.x86.R_DX, M.x86.R_AX);
10408 }
10409 DECODE_CLEAR_SEGOVR();
10410 END_OF_INSTR();
10411 }
10412
10413 /****************************************************************************
10414 REMARKS:
10415 Handles opcode 0xf0
10416 ****************************************************************************/
10417 static void
x86emuOp_lock(u8 X86EMU_UNUSED (op1))10418 x86emuOp_lock(u8 X86EMU_UNUSED(op1))
10419 {
10420 START_OF_INSTR();
10421 DECODE_PRINTF("LOCK:\n");
10422 TRACE_AND_STEP();
10423 DECODE_CLEAR_SEGOVR();
10424 END_OF_INSTR();
10425 }
10426
10427 /*opcode 0xf1 ILLEGAL OPERATION */
10428
10429 /****************************************************************************
10430 REMARKS:
10431 Handles opcode 0xf2
10432 ****************************************************************************/
10433 static void
x86emuOp_repne(u8 X86EMU_UNUSED (op1))10434 x86emuOp_repne(u8 X86EMU_UNUSED(op1))
10435 {
10436 START_OF_INSTR();
10437 DECODE_PRINTF("REPNE\n");
10438 TRACE_AND_STEP();
10439 M.x86.mode |= SYSMODE_PREFIX_REPNE;
10440 DECODE_CLEAR_SEGOVR();
10441 END_OF_INSTR();
10442 }
10443
10444 /****************************************************************************
10445 REMARKS:
10446 Handles opcode 0xf3
10447 ****************************************************************************/
10448 static void
x86emuOp_repe(u8 X86EMU_UNUSED (op1))10449 x86emuOp_repe(u8 X86EMU_UNUSED(op1))
10450 {
10451 START_OF_INSTR();
10452 DECODE_PRINTF("REPE\n");
10453 TRACE_AND_STEP();
10454 M.x86.mode |= SYSMODE_PREFIX_REPE;
10455 DECODE_CLEAR_SEGOVR();
10456 END_OF_INSTR();
10457 }
10458
10459 /****************************************************************************
10460 REMARKS:
10461 Handles opcode 0xf4
10462 ****************************************************************************/
10463 static void
x86emuOp_halt(u8 X86EMU_UNUSED (op1))10464 x86emuOp_halt(u8 X86EMU_UNUSED(op1))
10465 {
10466 START_OF_INSTR();
10467 DECODE_PRINTF("HALT\n");
10468 TRACE_AND_STEP();
10469 HALT_SYS();
10470 DECODE_CLEAR_SEGOVR();
10471 END_OF_INSTR();
10472 }
10473
10474 /****************************************************************************
10475 REMARKS:
10476 Handles opcode 0xf5
10477 ****************************************************************************/
10478 static void
x86emuOp_cmc(u8 X86EMU_UNUSED (op1))10479 x86emuOp_cmc(u8 X86EMU_UNUSED(op1))
10480 {
10481 /* complement the carry flag. */
10482 START_OF_INSTR();
10483 DECODE_PRINTF("CMC\n");
10484 TRACE_AND_STEP();
10485 TOGGLE_FLAG(F_CF);
10486 DECODE_CLEAR_SEGOVR();
10487 END_OF_INSTR();
10488 }
10489
10490 /****************************************************************************
10491 REMARKS:
10492 Handles opcode 0xf6
10493 ****************************************************************************/
10494 static void
x86emuOp_opcF6_byte_RM(u8 X86EMU_UNUSED (op1))10495 x86emuOp_opcF6_byte_RM(u8 X86EMU_UNUSED(op1))
10496 {
10497 int mod, rl, rh;
10498 u8 *destreg;
10499 uint destoffset;
10500 u8 destval, srcval;
10501
10502 /* long, drawn out code follows. Double switch for a total
10503 of 32 cases. */
10504 START_OF_INSTR();
10505 FETCH_DECODE_MODRM(mod, rh, rl);
10506 switch (mod) {
10507 case 0: /* mod=00 */
10508 switch (rh) {
10509 case 0: /* test byte imm */
10510 DECODE_PRINTF("TEST\tBYTE PTR ");
10511 destoffset = decode_rm00_address(rl);
10512 DECODE_PRINTF(",");
10513 srcval = fetch_byte_imm();
10514 DECODE_PRINTF2("%02x\n", srcval);
10515 destval = fetch_data_byte(destoffset);
10516 TRACE_AND_STEP();
10517 test_byte(destval, srcval);
10518 break;
10519 case 1:
10520 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
10521 HALT_SYS();
10522 break;
10523 case 2:
10524 DECODE_PRINTF("NOT\tBYTE PTR ");
10525 destoffset = decode_rm00_address(rl);
10526 DECODE_PRINTF("\n");
10527 destval = fetch_data_byte(destoffset);
10528 TRACE_AND_STEP();
10529 destval = not_byte(destval);
10530 store_data_byte(destoffset, destval);
10531 break;
10532 case 3:
10533 DECODE_PRINTF("NEG\tBYTE PTR ");
10534 destoffset = decode_rm00_address(rl);
10535 DECODE_PRINTF("\n");
10536 destval = fetch_data_byte(destoffset);
10537 TRACE_AND_STEP();
10538 destval = neg_byte(destval);
10539 store_data_byte(destoffset, destval);
10540 break;
10541 case 4:
10542 DECODE_PRINTF("MUL\tBYTE PTR ");
10543 destoffset = decode_rm00_address(rl);
10544 DECODE_PRINTF("\n");
10545 destval = fetch_data_byte(destoffset);
10546 TRACE_AND_STEP();
10547 mul_byte(destval);
10548 break;
10549 case 5:
10550 DECODE_PRINTF("IMUL\tBYTE PTR ");
10551 destoffset = decode_rm00_address(rl);
10552 DECODE_PRINTF("\n");
10553 destval = fetch_data_byte(destoffset);
10554 TRACE_AND_STEP();
10555 imul_byte(destval);
10556 break;
10557 case 6:
10558 DECODE_PRINTF("DIV\tBYTE PTR ");
10559 destoffset = decode_rm00_address(rl);
10560 DECODE_PRINTF("\n");
10561 destval = fetch_data_byte(destoffset);
10562 TRACE_AND_STEP();
10563 div_byte(destval);
10564 break;
10565 case 7:
10566 DECODE_PRINTF("IDIV\tBYTE PTR ");
10567 destoffset = decode_rm00_address(rl);
10568 DECODE_PRINTF("\n");
10569 destval = fetch_data_byte(destoffset);
10570 TRACE_AND_STEP();
10571 idiv_byte(destval);
10572 break;
10573 }
10574 break; /* end mod==00 */
10575 case 1: /* mod=01 */
10576 switch (rh) {
10577 case 0: /* test byte imm */
10578 DECODE_PRINTF("TEST\tBYTE PTR ");
10579 destoffset = decode_rm01_address(rl);
10580 DECODE_PRINTF(",");
10581 srcval = fetch_byte_imm();
10582 DECODE_PRINTF2("%02x\n", srcval);
10583 destval = fetch_data_byte(destoffset);
10584 TRACE_AND_STEP();
10585 test_byte(destval, srcval);
10586 break;
10587 case 1:
10588 DECODE_PRINTF("ILLEGAL OP MOD=01 RH=01 OP=F6\n");
10589 HALT_SYS();
10590 break;
10591 case 2:
10592 DECODE_PRINTF("NOT\tBYTE PTR ");
10593 destoffset = decode_rm01_address(rl);
10594 DECODE_PRINTF("\n");
10595 destval = fetch_data_byte(destoffset);
10596 TRACE_AND_STEP();
10597 destval = not_byte(destval);
10598 store_data_byte(destoffset, destval);
10599 break;
10600 case 3:
10601 DECODE_PRINTF("NEG\tBYTE PTR ");
10602 destoffset = decode_rm01_address(rl);
10603 DECODE_PRINTF("\n");
10604 destval = fetch_data_byte(destoffset);
10605 TRACE_AND_STEP();
10606 destval = neg_byte(destval);
10607 store_data_byte(destoffset, destval);
10608 break;
10609 case 4:
10610 DECODE_PRINTF("MUL\tBYTE PTR ");
10611 destoffset = decode_rm01_address(rl);
10612 DECODE_PRINTF("\n");
10613 destval = fetch_data_byte(destoffset);
10614 TRACE_AND_STEP();
10615 mul_byte(destval);
10616 break;
10617 case 5:
10618 DECODE_PRINTF("IMUL\tBYTE PTR ");
10619 destoffset = decode_rm01_address(rl);
10620 DECODE_PRINTF("\n");
10621 destval = fetch_data_byte(destoffset);
10622 TRACE_AND_STEP();
10623 imul_byte(destval);
10624 break;
10625 case 6:
10626 DECODE_PRINTF("DIV\tBYTE PTR ");
10627 destoffset = decode_rm01_address(rl);
10628 DECODE_PRINTF("\n");
10629 destval = fetch_data_byte(destoffset);
10630 TRACE_AND_STEP();
10631 div_byte(destval);
10632 break;
10633 case 7:
10634 DECODE_PRINTF("IDIV\tBYTE PTR ");
10635 destoffset = decode_rm01_address(rl);
10636 DECODE_PRINTF("\n");
10637 destval = fetch_data_byte(destoffset);
10638 TRACE_AND_STEP();
10639 idiv_byte(destval);
10640 break;
10641 }
10642 break; /* end mod==01 */
10643 case 2: /* mod=10 */
10644 switch (rh) {
10645 case 0: /* test byte imm */
10646 DECODE_PRINTF("TEST\tBYTE PTR ");
10647 destoffset = decode_rm10_address(rl);
10648 DECODE_PRINTF(",");
10649 srcval = fetch_byte_imm();
10650 DECODE_PRINTF2("%02x\n", srcval);
10651 destval = fetch_data_byte(destoffset);
10652 TRACE_AND_STEP();
10653 test_byte(destval, srcval);
10654 break;
10655 case 1:
10656 DECODE_PRINTF("ILLEGAL OP MOD=10 RH=01 OP=F6\n");
10657 HALT_SYS();
10658 break;
10659 case 2:
10660 DECODE_PRINTF("NOT\tBYTE PTR ");
10661 destoffset = decode_rm10_address(rl);
10662 DECODE_PRINTF("\n");
10663 destval = fetch_data_byte(destoffset);
10664 TRACE_AND_STEP();
10665 destval = not_byte(destval);
10666 store_data_byte(destoffset, destval);
10667 break;
10668 case 3:
10669 DECODE_PRINTF("NEG\tBYTE PTR ");
10670 destoffset = decode_rm10_address(rl);
10671 DECODE_PRINTF("\n");
10672 destval = fetch_data_byte(destoffset);
10673 TRACE_AND_STEP();
10674 destval = neg_byte(destval);
10675 store_data_byte(destoffset, destval);
10676 break;
10677 case 4:
10678 DECODE_PRINTF("MUL\tBYTE PTR ");
10679 destoffset = decode_rm10_address(rl);
10680 DECODE_PRINTF("\n");
10681 destval = fetch_data_byte(destoffset);
10682 TRACE_AND_STEP();
10683 mul_byte(destval);
10684 break;
10685 case 5:
10686 DECODE_PRINTF("IMUL\tBYTE PTR ");
10687 destoffset = decode_rm10_address(rl);
10688 DECODE_PRINTF("\n");
10689 destval = fetch_data_byte(destoffset);
10690 TRACE_AND_STEP();
10691 imul_byte(destval);
10692 break;
10693 case 6:
10694 DECODE_PRINTF("DIV\tBYTE PTR ");
10695 destoffset = decode_rm10_address(rl);
10696 DECODE_PRINTF("\n");
10697 destval = fetch_data_byte(destoffset);
10698 TRACE_AND_STEP();
10699 div_byte(destval);
10700 break;
10701 case 7:
10702 DECODE_PRINTF("IDIV\tBYTE PTR ");
10703 destoffset = decode_rm10_address(rl);
10704 DECODE_PRINTF("\n");
10705 destval = fetch_data_byte(destoffset);
10706 TRACE_AND_STEP();
10707 idiv_byte(destval);
10708 break;
10709 }
10710 break; /* end mod==10 */
10711 case 3: /* mod=11 */
10712 switch (rh) {
10713 case 0: /* test byte imm */
10714 DECODE_PRINTF("TEST\t");
10715 destreg = DECODE_RM_BYTE_REGISTER(rl);
10716 DECODE_PRINTF(",");
10717 srcval = fetch_byte_imm();
10718 DECODE_PRINTF2("%02x\n", srcval);
10719 TRACE_AND_STEP();
10720 test_byte(*destreg, srcval);
10721 break;
10722 case 1:
10723 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
10724 HALT_SYS();
10725 break;
10726 case 2:
10727 DECODE_PRINTF("NOT\t");
10728 destreg = DECODE_RM_BYTE_REGISTER(rl);
10729 DECODE_PRINTF("\n");
10730 TRACE_AND_STEP();
10731 *destreg = not_byte(*destreg);
10732 break;
10733 case 3:
10734 DECODE_PRINTF("NEG\t");
10735 destreg = DECODE_RM_BYTE_REGISTER(rl);
10736 DECODE_PRINTF("\n");
10737 TRACE_AND_STEP();
10738 *destreg = neg_byte(*destreg);
10739 break;
10740 case 4:
10741 DECODE_PRINTF("MUL\t");
10742 destreg = DECODE_RM_BYTE_REGISTER(rl);
10743 DECODE_PRINTF("\n");
10744 TRACE_AND_STEP();
10745 mul_byte(*destreg); /*!!! */
10746 break;
10747 case 5:
10748 DECODE_PRINTF("IMUL\t");
10749 destreg = DECODE_RM_BYTE_REGISTER(rl);
10750 DECODE_PRINTF("\n");
10751 TRACE_AND_STEP();
10752 imul_byte(*destreg);
10753 break;
10754 case 6:
10755 DECODE_PRINTF("DIV\t");
10756 destreg = DECODE_RM_BYTE_REGISTER(rl);
10757 DECODE_PRINTF("\n");
10758 TRACE_AND_STEP();
10759 div_byte(*destreg);
10760 break;
10761 case 7:
10762 DECODE_PRINTF("IDIV\t");
10763 destreg = DECODE_RM_BYTE_REGISTER(rl);
10764 DECODE_PRINTF("\n");
10765 TRACE_AND_STEP();
10766 idiv_byte(*destreg);
10767 break;
10768 }
10769 break; /* end mod==11 */
10770 }
10771 DECODE_CLEAR_SEGOVR();
10772 END_OF_INSTR();
10773 }
10774
10775 /****************************************************************************
10776 REMARKS:
10777 Handles opcode 0xf7
10778 ****************************************************************************/
10779 static void
x86emuOp_opcF7_word_RM(u8 X86EMU_UNUSED (op1))10780 x86emuOp_opcF7_word_RM(u8 X86EMU_UNUSED(op1))
10781 {
10782 int mod, rl, rh;
10783 uint destoffset;
10784
10785 /* long, drawn out code follows. Double switch for a total
10786 of 32 cases. */
10787 START_OF_INSTR();
10788 FETCH_DECODE_MODRM(mod, rh, rl);
10789 switch (mod) {
10790 case 0: /* mod=00 */
10791 switch (rh) {
10792 case 0: /* test word imm */
10793 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10794 u32 destval, srcval;
10795
10796 DECODE_PRINTF("TEST\tDWORD PTR ");
10797 destoffset = decode_rm00_address(rl);
10798 DECODE_PRINTF(",");
10799 srcval = fetch_long_imm();
10800 DECODE_PRINTF2("%x\n", srcval);
10801 destval = fetch_data_long(destoffset);
10802 TRACE_AND_STEP();
10803 test_long(destval, srcval);
10804 }
10805 else {
10806 u16 destval, srcval;
10807
10808 DECODE_PRINTF("TEST\tWORD PTR ");
10809 destoffset = decode_rm00_address(rl);
10810 DECODE_PRINTF(",");
10811 srcval = fetch_word_imm();
10812 DECODE_PRINTF2("%x\n", srcval);
10813 destval = fetch_data_word(destoffset);
10814 TRACE_AND_STEP();
10815 test_word(destval, srcval);
10816 }
10817 break;
10818 case 1:
10819 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F7\n");
10820 HALT_SYS();
10821 break;
10822 case 2:
10823 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10824 u32 destval;
10825
10826 DECODE_PRINTF("NOT\tDWORD PTR ");
10827 destoffset = decode_rm00_address(rl);
10828 DECODE_PRINTF("\n");
10829 destval = fetch_data_long(destoffset);
10830 TRACE_AND_STEP();
10831 destval = not_long(destval);
10832 store_data_long(destoffset, destval);
10833 }
10834 else {
10835 u16 destval;
10836
10837 DECODE_PRINTF("NOT\tWORD PTR ");
10838 destoffset = decode_rm00_address(rl);
10839 DECODE_PRINTF("\n");
10840 destval = fetch_data_word(destoffset);
10841 TRACE_AND_STEP();
10842 destval = not_word(destval);
10843 store_data_word(destoffset, destval);
10844 }
10845 break;
10846 case 3:
10847 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10848 u32 destval;
10849
10850 DECODE_PRINTF("NEG\tDWORD PTR ");
10851 destoffset = decode_rm00_address(rl);
10852 DECODE_PRINTF("\n");
10853 destval = fetch_data_long(destoffset);
10854 TRACE_AND_STEP();
10855 destval = neg_long(destval);
10856 store_data_long(destoffset, destval);
10857 }
10858 else {
10859 u16 destval;
10860
10861 DECODE_PRINTF("NEG\tWORD PTR ");
10862 destoffset = decode_rm00_address(rl);
10863 DECODE_PRINTF("\n");
10864 destval = fetch_data_word(destoffset);
10865 TRACE_AND_STEP();
10866 destval = neg_word(destval);
10867 store_data_word(destoffset, destval);
10868 }
10869 break;
10870 case 4:
10871 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10872 u32 destval;
10873
10874 DECODE_PRINTF("MUL\tDWORD PTR ");
10875 destoffset = decode_rm00_address(rl);
10876 DECODE_PRINTF("\n");
10877 destval = fetch_data_long(destoffset);
10878 TRACE_AND_STEP();
10879 mul_long(destval);
10880 }
10881 else {
10882 u16 destval;
10883
10884 DECODE_PRINTF("MUL\tWORD PTR ");
10885 destoffset = decode_rm00_address(rl);
10886 DECODE_PRINTF("\n");
10887 destval = fetch_data_word(destoffset);
10888 TRACE_AND_STEP();
10889 mul_word(destval);
10890 }
10891 break;
10892 case 5:
10893 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10894 u32 destval;
10895
10896 DECODE_PRINTF("IMUL\tDWORD PTR ");
10897 destoffset = decode_rm00_address(rl);
10898 DECODE_PRINTF("\n");
10899 destval = fetch_data_long(destoffset);
10900 TRACE_AND_STEP();
10901 imul_long(destval);
10902 }
10903 else {
10904 u16 destval;
10905
10906 DECODE_PRINTF("IMUL\tWORD PTR ");
10907 destoffset = decode_rm00_address(rl);
10908 DECODE_PRINTF("\n");
10909 destval = fetch_data_word(destoffset);
10910 TRACE_AND_STEP();
10911 imul_word(destval);
10912 }
10913 break;
10914 case 6:
10915 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10916 u32 destval;
10917
10918 DECODE_PRINTF("DIV\tDWORD PTR ");
10919 destoffset = decode_rm00_address(rl);
10920 DECODE_PRINTF("\n");
10921 destval = fetch_data_long(destoffset);
10922 TRACE_AND_STEP();
10923 div_long(destval);
10924 }
10925 else {
10926 u16 destval;
10927
10928 DECODE_PRINTF("DIV\tWORD PTR ");
10929 destoffset = decode_rm00_address(rl);
10930 DECODE_PRINTF("\n");
10931 destval = fetch_data_word(destoffset);
10932 TRACE_AND_STEP();
10933 div_word(destval);
10934 }
10935 break;
10936 case 7:
10937 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10938 u32 destval;
10939
10940 DECODE_PRINTF("IDIV\tDWORD PTR ");
10941 destoffset = decode_rm00_address(rl);
10942 DECODE_PRINTF("\n");
10943 destval = fetch_data_long(destoffset);
10944 TRACE_AND_STEP();
10945 idiv_long(destval);
10946 }
10947 else {
10948 u16 destval;
10949
10950 DECODE_PRINTF("IDIV\tWORD PTR ");
10951 destoffset = decode_rm00_address(rl);
10952 DECODE_PRINTF("\n");
10953 destval = fetch_data_word(destoffset);
10954 TRACE_AND_STEP();
10955 idiv_word(destval);
10956 }
10957 break;
10958 }
10959 break; /* end mod==00 */
10960 case 1: /* mod=01 */
10961 switch (rh) {
10962 case 0: /* test word imm */
10963 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10964 u32 destval, srcval;
10965
10966 DECODE_PRINTF("TEST\tDWORD PTR ");
10967 destoffset = decode_rm01_address(rl);
10968 DECODE_PRINTF(",");
10969 srcval = fetch_long_imm();
10970 DECODE_PRINTF2("%x\n", srcval);
10971 destval = fetch_data_long(destoffset);
10972 TRACE_AND_STEP();
10973 test_long(destval, srcval);
10974 }
10975 else {
10976 u16 destval, srcval;
10977
10978 DECODE_PRINTF("TEST\tWORD PTR ");
10979 destoffset = decode_rm01_address(rl);
10980 DECODE_PRINTF(",");
10981 srcval = fetch_word_imm();
10982 DECODE_PRINTF2("%x\n", srcval);
10983 destval = fetch_data_word(destoffset);
10984 TRACE_AND_STEP();
10985 test_word(destval, srcval);
10986 }
10987 break;
10988 case 1:
10989 DECODE_PRINTF("ILLEGAL OP MOD=01 RH=01 OP=F6\n");
10990 HALT_SYS();
10991 break;
10992 case 2:
10993 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10994 u32 destval;
10995
10996 DECODE_PRINTF("NOT\tDWORD PTR ");
10997 destoffset = decode_rm01_address(rl);
10998 DECODE_PRINTF("\n");
10999 destval = fetch_data_long(destoffset);
11000 TRACE_AND_STEP();
11001 destval = not_long(destval);
11002 store_data_long(destoffset, destval);
11003 }
11004 else {
11005 u16 destval;
11006
11007 DECODE_PRINTF("NOT\tWORD PTR ");
11008 destoffset = decode_rm01_address(rl);
11009 DECODE_PRINTF("\n");
11010 destval = fetch_data_word(destoffset);
11011 TRACE_AND_STEP();
11012 destval = not_word(destval);
11013 store_data_word(destoffset, destval);
11014 }
11015 break;
11016 case 3:
11017 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11018 u32 destval;
11019
11020 DECODE_PRINTF("NEG\tDWORD PTR ");
11021 destoffset = decode_rm01_address(rl);
11022 DECODE_PRINTF("\n");
11023 destval = fetch_data_long(destoffset);
11024 TRACE_AND_STEP();
11025 destval = neg_long(destval);
11026 store_data_long(destoffset, destval);
11027 }
11028 else {
11029 u16 destval;
11030
11031 DECODE_PRINTF("NEG\tWORD PTR ");
11032 destoffset = decode_rm01_address(rl);
11033 DECODE_PRINTF("\n");
11034 destval = fetch_data_word(destoffset);
11035 TRACE_AND_STEP();
11036 destval = neg_word(destval);
11037 store_data_word(destoffset, destval);
11038 }
11039 break;
11040 case 4:
11041 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11042 u32 destval;
11043
11044 DECODE_PRINTF("MUL\tDWORD PTR ");
11045 destoffset = decode_rm01_address(rl);
11046 DECODE_PRINTF("\n");
11047 destval = fetch_data_long(destoffset);
11048 TRACE_AND_STEP();
11049 mul_long(destval);
11050 }
11051 else {
11052 u16 destval;
11053
11054 DECODE_PRINTF("MUL\tWORD PTR ");
11055 destoffset = decode_rm01_address(rl);
11056 DECODE_PRINTF("\n");
11057 destval = fetch_data_word(destoffset);
11058 TRACE_AND_STEP();
11059 mul_word(destval);
11060 }
11061 break;
11062 case 5:
11063 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11064 u32 destval;
11065
11066 DECODE_PRINTF("IMUL\tDWORD PTR ");
11067 destoffset = decode_rm01_address(rl);
11068 DECODE_PRINTF("\n");
11069 destval = fetch_data_long(destoffset);
11070 TRACE_AND_STEP();
11071 imul_long(destval);
11072 }
11073 else {
11074 u16 destval;
11075
11076 DECODE_PRINTF("IMUL\tWORD PTR ");
11077 destoffset = decode_rm01_address(rl);
11078 DECODE_PRINTF("\n");
11079 destval = fetch_data_word(destoffset);
11080 TRACE_AND_STEP();
11081 imul_word(destval);
11082 }
11083 break;
11084 case 6:
11085 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11086 u32 destval;
11087
11088 DECODE_PRINTF("DIV\tDWORD PTR ");
11089 destoffset = decode_rm01_address(rl);
11090 DECODE_PRINTF("\n");
11091 destval = fetch_data_long(destoffset);
11092 TRACE_AND_STEP();
11093 div_long(destval);
11094 }
11095 else {
11096 u16 destval;
11097
11098 DECODE_PRINTF("DIV\tWORD PTR ");
11099 destoffset = decode_rm01_address(rl);
11100 DECODE_PRINTF("\n");
11101 destval = fetch_data_word(destoffset);
11102 TRACE_AND_STEP();
11103 div_word(destval);
11104 }
11105 break;
11106 case 7:
11107 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11108 u32 destval;
11109
11110 DECODE_PRINTF("IDIV\tDWORD PTR ");
11111 destoffset = decode_rm01_address(rl);
11112 DECODE_PRINTF("\n");
11113 destval = fetch_data_long(destoffset);
11114 TRACE_AND_STEP();
11115 idiv_long(destval);
11116 }
11117 else {
11118 u16 destval;
11119
11120 DECODE_PRINTF("IDIV\tWORD PTR ");
11121 destoffset = decode_rm01_address(rl);
11122 DECODE_PRINTF("\n");
11123 destval = fetch_data_word(destoffset);
11124 TRACE_AND_STEP();
11125 idiv_word(destval);
11126 }
11127 break;
11128 }
11129 break; /* end mod==01 */
11130 case 2: /* mod=10 */
11131 switch (rh) {
11132 case 0: /* test word imm */
11133 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11134 u32 destval, srcval;
11135
11136 DECODE_PRINTF("TEST\tDWORD PTR ");
11137 destoffset = decode_rm10_address(rl);
11138 DECODE_PRINTF(",");
11139 srcval = fetch_long_imm();
11140 DECODE_PRINTF2("%x\n", srcval);
11141 destval = fetch_data_long(destoffset);
11142 TRACE_AND_STEP();
11143 test_long(destval, srcval);
11144 }
11145 else {
11146 u16 destval, srcval;
11147
11148 DECODE_PRINTF("TEST\tWORD PTR ");
11149 destoffset = decode_rm10_address(rl);
11150 DECODE_PRINTF(",");
11151 srcval = fetch_word_imm();
11152 DECODE_PRINTF2("%x\n", srcval);
11153 destval = fetch_data_word(destoffset);
11154 TRACE_AND_STEP();
11155 test_word(destval, srcval);
11156 }
11157 break;
11158 case 1:
11159 DECODE_PRINTF("ILLEGAL OP MOD=10 RH=01 OP=F6\n");
11160 HALT_SYS();
11161 break;
11162 case 2:
11163 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11164 u32 destval;
11165
11166 DECODE_PRINTF("NOT\tDWORD PTR ");
11167 destoffset = decode_rm10_address(rl);
11168 DECODE_PRINTF("\n");
11169 destval = fetch_data_long(destoffset);
11170 TRACE_AND_STEP();
11171 destval = not_long(destval);
11172 store_data_long(destoffset, destval);
11173 }
11174 else {
11175 u16 destval;
11176
11177 DECODE_PRINTF("NOT\tWORD PTR ");
11178 destoffset = decode_rm10_address(rl);
11179 DECODE_PRINTF("\n");
11180 destval = fetch_data_word(destoffset);
11181 TRACE_AND_STEP();
11182 destval = not_word(destval);
11183 store_data_word(destoffset, destval);
11184 }
11185 break;
11186 case 3:
11187 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11188 u32 destval;
11189
11190 DECODE_PRINTF("NEG\tDWORD PTR ");
11191 destoffset = decode_rm10_address(rl);
11192 DECODE_PRINTF("\n");
11193 destval = fetch_data_long(destoffset);
11194 TRACE_AND_STEP();
11195 destval = neg_long(destval);
11196 store_data_long(destoffset, destval);
11197 }
11198 else {
11199 u16 destval;
11200
11201 DECODE_PRINTF("NEG\tWORD PTR ");
11202 destoffset = decode_rm10_address(rl);
11203 DECODE_PRINTF("\n");
11204 destval = fetch_data_word(destoffset);
11205 TRACE_AND_STEP();
11206 destval = neg_word(destval);
11207 store_data_word(destoffset, destval);
11208 }
11209 break;
11210 case 4:
11211 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11212 u32 destval;
11213
11214 DECODE_PRINTF("MUL\tDWORD PTR ");
11215 destoffset = decode_rm10_address(rl);
11216 DECODE_PRINTF("\n");
11217 destval = fetch_data_long(destoffset);
11218 TRACE_AND_STEP();
11219 mul_long(destval);
11220 }
11221 else {
11222 u16 destval;
11223
11224 DECODE_PRINTF("MUL\tWORD PTR ");
11225 destoffset = decode_rm10_address(rl);
11226 DECODE_PRINTF("\n");
11227 destval = fetch_data_word(destoffset);
11228 TRACE_AND_STEP();
11229 mul_word(destval);
11230 }
11231 break;
11232 case 5:
11233 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11234 u32 destval;
11235
11236 DECODE_PRINTF("IMUL\tDWORD PTR ");
11237 destoffset = decode_rm10_address(rl);
11238 DECODE_PRINTF("\n");
11239 destval = fetch_data_long(destoffset);
11240 TRACE_AND_STEP();
11241 imul_long(destval);
11242 }
11243 else {
11244 u16 destval;
11245
11246 DECODE_PRINTF("IMUL\tWORD PTR ");
11247 destoffset = decode_rm10_address(rl);
11248 DECODE_PRINTF("\n");
11249 destval = fetch_data_word(destoffset);
11250 TRACE_AND_STEP();
11251 imul_word(destval);
11252 }
11253 break;
11254 case 6:
11255 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11256 u32 destval;
11257
11258 DECODE_PRINTF("DIV\tDWORD PTR ");
11259 destoffset = decode_rm10_address(rl);
11260 DECODE_PRINTF("\n");
11261 destval = fetch_data_long(destoffset);
11262 TRACE_AND_STEP();
11263 div_long(destval);
11264 }
11265 else {
11266 u16 destval;
11267
11268 DECODE_PRINTF("DIV\tWORD PTR ");
11269 destoffset = decode_rm10_address(rl);
11270 DECODE_PRINTF("\n");
11271 destval = fetch_data_word(destoffset);
11272 TRACE_AND_STEP();
11273 div_word(destval);
11274 }
11275 break;
11276 case 7:
11277 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11278 u32 destval;
11279
11280 DECODE_PRINTF("IDIV\tDWORD PTR ");
11281 destoffset = decode_rm10_address(rl);
11282 DECODE_PRINTF("\n");
11283 destval = fetch_data_long(destoffset);
11284 TRACE_AND_STEP();
11285 idiv_long(destval);
11286 }
11287 else {
11288 u16 destval;
11289
11290 DECODE_PRINTF("IDIV\tWORD PTR ");
11291 destoffset = decode_rm10_address(rl);
11292 DECODE_PRINTF("\n");
11293 destval = fetch_data_word(destoffset);
11294 TRACE_AND_STEP();
11295 idiv_word(destval);
11296 }
11297 break;
11298 }
11299 break; /* end mod==10 */
11300 case 3: /* mod=11 */
11301 switch (rh) {
11302 case 0: /* test word imm */
11303 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11304 u32 *destreg;
11305 u32 srcval;
11306
11307 DECODE_PRINTF("TEST\t");
11308 destreg = DECODE_RM_LONG_REGISTER(rl);
11309 DECODE_PRINTF(",");
11310 srcval = fetch_long_imm();
11311 DECODE_PRINTF2("%x\n", srcval);
11312 TRACE_AND_STEP();
11313 test_long(*destreg, srcval);
11314 }
11315 else {
11316 u16 *destreg;
11317 u16 srcval;
11318
11319 DECODE_PRINTF("TEST\t");
11320 destreg = DECODE_RM_WORD_REGISTER(rl);
11321 DECODE_PRINTF(",");
11322 srcval = fetch_word_imm();
11323 DECODE_PRINTF2("%x\n", srcval);
11324 TRACE_AND_STEP();
11325 test_word(*destreg, srcval);
11326 }
11327 break;
11328 case 1:
11329 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
11330 HALT_SYS();
11331 break;
11332 case 2:
11333 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11334 u32 *destreg;
11335
11336 DECODE_PRINTF("NOT\t");
11337 destreg = DECODE_RM_LONG_REGISTER(rl);
11338 DECODE_PRINTF("\n");
11339 TRACE_AND_STEP();
11340 *destreg = not_long(*destreg);
11341 }
11342 else {
11343 u16 *destreg;
11344
11345 DECODE_PRINTF("NOT\t");
11346 destreg = DECODE_RM_WORD_REGISTER(rl);
11347 DECODE_PRINTF("\n");
11348 TRACE_AND_STEP();
11349 *destreg = not_word(*destreg);
11350 }
11351 break;
11352 case 3:
11353 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11354 u32 *destreg;
11355
11356 DECODE_PRINTF("NEG\t");
11357 destreg = DECODE_RM_LONG_REGISTER(rl);
11358 DECODE_PRINTF("\n");
11359 TRACE_AND_STEP();
11360 *destreg = neg_long(*destreg);
11361 }
11362 else {
11363 u16 *destreg;
11364
11365 DECODE_PRINTF("NEG\t");
11366 destreg = DECODE_RM_WORD_REGISTER(rl);
11367 DECODE_PRINTF("\n");
11368 TRACE_AND_STEP();
11369 *destreg = neg_word(*destreg);
11370 }
11371 break;
11372 case 4:
11373 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11374 u32 *destreg;
11375
11376 DECODE_PRINTF("MUL\t");
11377 destreg = DECODE_RM_LONG_REGISTER(rl);
11378 DECODE_PRINTF("\n");
11379 TRACE_AND_STEP();
11380 mul_long(*destreg); /*!!! */
11381 }
11382 else {
11383 u16 *destreg;
11384
11385 DECODE_PRINTF("MUL\t");
11386 destreg = DECODE_RM_WORD_REGISTER(rl);
11387 DECODE_PRINTF("\n");
11388 TRACE_AND_STEP();
11389 mul_word(*destreg); /*!!! */
11390 }
11391 break;
11392 case 5:
11393 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11394 u32 *destreg;
11395
11396 DECODE_PRINTF("IMUL\t");
11397 destreg = DECODE_RM_LONG_REGISTER(rl);
11398 DECODE_PRINTF("\n");
11399 TRACE_AND_STEP();
11400 imul_long(*destreg);
11401 }
11402 else {
11403 u16 *destreg;
11404
11405 DECODE_PRINTF("IMUL\t");
11406 destreg = DECODE_RM_WORD_REGISTER(rl);
11407 DECODE_PRINTF("\n");
11408 TRACE_AND_STEP();
11409 imul_word(*destreg);
11410 }
11411 break;
11412 case 6:
11413 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11414 u32 *destreg;
11415
11416 DECODE_PRINTF("DIV\t");
11417 destreg = DECODE_RM_LONG_REGISTER(rl);
11418 DECODE_PRINTF("\n");
11419 TRACE_AND_STEP();
11420 div_long(*destreg);
11421 }
11422 else {
11423 u16 *destreg;
11424
11425 DECODE_PRINTF("DIV\t");
11426 destreg = DECODE_RM_WORD_REGISTER(rl);
11427 DECODE_PRINTF("\n");
11428 TRACE_AND_STEP();
11429 div_word(*destreg);
11430 }
11431 break;
11432 case 7:
11433 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11434 u32 *destreg;
11435
11436 DECODE_PRINTF("IDIV\t");
11437 destreg = DECODE_RM_LONG_REGISTER(rl);
11438 DECODE_PRINTF("\n");
11439 TRACE_AND_STEP();
11440 idiv_long(*destreg);
11441 }
11442 else {
11443 u16 *destreg;
11444
11445 DECODE_PRINTF("IDIV\t");
11446 destreg = DECODE_RM_WORD_REGISTER(rl);
11447 DECODE_PRINTF("\n");
11448 TRACE_AND_STEP();
11449 idiv_word(*destreg);
11450 }
11451 break;
11452 }
11453 break; /* end mod==11 */
11454 }
11455 DECODE_CLEAR_SEGOVR();
11456 END_OF_INSTR();
11457 }
11458
11459 /****************************************************************************
11460 REMARKS:
11461 Handles opcode 0xf8
11462 ****************************************************************************/
11463 static void
x86emuOp_clc(u8 X86EMU_UNUSED (op1))11464 x86emuOp_clc(u8 X86EMU_UNUSED(op1))
11465 {
11466 /* clear the carry flag. */
11467 START_OF_INSTR();
11468 DECODE_PRINTF("CLC\n");
11469 TRACE_AND_STEP();
11470 CLEAR_FLAG(F_CF);
11471 DECODE_CLEAR_SEGOVR();
11472 END_OF_INSTR();
11473 }
11474
11475 /****************************************************************************
11476 REMARKS:
11477 Handles opcode 0xf9
11478 ****************************************************************************/
11479 static void
x86emuOp_stc(u8 X86EMU_UNUSED (op1))11480 x86emuOp_stc(u8 X86EMU_UNUSED(op1))
11481 {
11482 /* set the carry flag. */
11483 START_OF_INSTR();
11484 DECODE_PRINTF("STC\n");
11485 TRACE_AND_STEP();
11486 SET_FLAG(F_CF);
11487 DECODE_CLEAR_SEGOVR();
11488 END_OF_INSTR();
11489 }
11490
11491 /****************************************************************************
11492 REMARKS:
11493 Handles opcode 0xfa
11494 ****************************************************************************/
11495 static void
x86emuOp_cli(u8 X86EMU_UNUSED (op1))11496 x86emuOp_cli(u8 X86EMU_UNUSED(op1))
11497 {
11498 /* clear interrupts. */
11499 START_OF_INSTR();
11500 DECODE_PRINTF("CLI\n");
11501 TRACE_AND_STEP();
11502 CLEAR_FLAG(F_IF);
11503 DECODE_CLEAR_SEGOVR();
11504 END_OF_INSTR();
11505 }
11506
11507 /****************************************************************************
11508 REMARKS:
11509 Handles opcode 0xfb
11510 ****************************************************************************/
11511 static void
x86emuOp_sti(u8 X86EMU_UNUSED (op1))11512 x86emuOp_sti(u8 X86EMU_UNUSED(op1))
11513 {
11514 /* enable interrupts. */
11515 START_OF_INSTR();
11516 DECODE_PRINTF("STI\n");
11517 TRACE_AND_STEP();
11518 SET_FLAG(F_IF);
11519 DECODE_CLEAR_SEGOVR();
11520 END_OF_INSTR();
11521 }
11522
11523 /****************************************************************************
11524 REMARKS:
11525 Handles opcode 0xfc
11526 ****************************************************************************/
11527 static void
x86emuOp_cld(u8 X86EMU_UNUSED (op1))11528 x86emuOp_cld(u8 X86EMU_UNUSED(op1))
11529 {
11530 /* clear interrupts. */
11531 START_OF_INSTR();
11532 DECODE_PRINTF("CLD\n");
11533 TRACE_AND_STEP();
11534 CLEAR_FLAG(F_DF);
11535 DECODE_CLEAR_SEGOVR();
11536 END_OF_INSTR();
11537 }
11538
11539 /****************************************************************************
11540 REMARKS:
11541 Handles opcode 0xfd
11542 ****************************************************************************/
11543 static void
x86emuOp_std(u8 X86EMU_UNUSED (op1))11544 x86emuOp_std(u8 X86EMU_UNUSED(op1))
11545 {
11546 /* clear interrupts. */
11547 START_OF_INSTR();
11548 DECODE_PRINTF("STD\n");
11549 TRACE_AND_STEP();
11550 SET_FLAG(F_DF);
11551 DECODE_CLEAR_SEGOVR();
11552 END_OF_INSTR();
11553 }
11554
11555 /****************************************************************************
11556 REMARKS:
11557 Handles opcode 0xfe
11558 ****************************************************************************/
11559 static void
x86emuOp_opcFE_byte_RM(u8 X86EMU_UNUSED (op1))11560 x86emuOp_opcFE_byte_RM(u8 X86EMU_UNUSED(op1))
11561 {
11562 int mod, rh, rl;
11563 u8 destval;
11564 uint destoffset;
11565 u8 *destreg;
11566
11567 /* Yet another special case instruction. */
11568 START_OF_INSTR();
11569 FETCH_DECODE_MODRM(mod, rh, rl);
11570 #ifdef DEBUG
11571 if (DEBUG_DECODE()) {
11572 /* XXX DECODE_PRINTF may be changed to something more
11573 general, so that it is important to leave the strings
11574 in the same format, even though the result is that the
11575 above test is done twice. */
11576
11577 switch (rh) {
11578 case 0:
11579 DECODE_PRINTF("INC\t");
11580 break;
11581 case 1:
11582 DECODE_PRINTF("DEC\t");
11583 break;
11584 case 2:
11585 case 3:
11586 case 4:
11587 case 5:
11588 case 6:
11589 case 7:
11590 DECODE_PRINTF2("ILLEGAL OP MAJOR OP 0xFE MINOR OP %x \n", mod);
11591 HALT_SYS();
11592 break;
11593 }
11594 }
11595 #endif
11596 switch (mod) {
11597 case 0:
11598 DECODE_PRINTF("BYTE PTR ");
11599 destoffset = decode_rm00_address(rl);
11600 DECODE_PRINTF("\n");
11601 switch (rh) {
11602 case 0: /* inc word ptr ... */
11603 destval = fetch_data_byte(destoffset);
11604 TRACE_AND_STEP();
11605 destval = inc_byte(destval);
11606 store_data_byte(destoffset, destval);
11607 break;
11608 case 1: /* dec word ptr ... */
11609 destval = fetch_data_byte(destoffset);
11610 TRACE_AND_STEP();
11611 destval = dec_byte(destval);
11612 store_data_byte(destoffset, destval);
11613 break;
11614 }
11615 break;
11616 case 1:
11617 DECODE_PRINTF("BYTE PTR ");
11618 destoffset = decode_rm01_address(rl);
11619 DECODE_PRINTF("\n");
11620 switch (rh) {
11621 case 0:
11622 destval = fetch_data_byte(destoffset);
11623 TRACE_AND_STEP();
11624 destval = inc_byte(destval);
11625 store_data_byte(destoffset, destval);
11626 break;
11627 case 1:
11628 destval = fetch_data_byte(destoffset);
11629 TRACE_AND_STEP();
11630 destval = dec_byte(destval);
11631 store_data_byte(destoffset, destval);
11632 break;
11633 }
11634 break;
11635 case 2:
11636 DECODE_PRINTF("BYTE PTR ");
11637 destoffset = decode_rm10_address(rl);
11638 DECODE_PRINTF("\n");
11639 switch (rh) {
11640 case 0:
11641 destval = fetch_data_byte(destoffset);
11642 TRACE_AND_STEP();
11643 destval = inc_byte(destval);
11644 store_data_byte(destoffset, destval);
11645 break;
11646 case 1:
11647 destval = fetch_data_byte(destoffset);
11648 TRACE_AND_STEP();
11649 destval = dec_byte(destval);
11650 store_data_byte(destoffset, destval);
11651 break;
11652 }
11653 break;
11654 case 3:
11655 destreg = DECODE_RM_BYTE_REGISTER(rl);
11656 DECODE_PRINTF("\n");
11657 switch (rh) {
11658 case 0:
11659 TRACE_AND_STEP();
11660 *destreg = inc_byte(*destreg);
11661 break;
11662 case 1:
11663 TRACE_AND_STEP();
11664 *destreg = dec_byte(*destreg);
11665 break;
11666 }
11667 break;
11668 }
11669 DECODE_CLEAR_SEGOVR();
11670 END_OF_INSTR();
11671 }
11672
11673 /****************************************************************************
11674 REMARKS:
11675 Handles opcode 0xff
11676 ****************************************************************************/
11677 static void
x86emuOp_opcFF_word_RM(u8 X86EMU_UNUSED (op1))11678 x86emuOp_opcFF_word_RM(u8 X86EMU_UNUSED(op1))
11679 {
11680 int mod, rh, rl;
11681 uint destoffset = 0;
11682 u16 *destreg;
11683 u16 destval, destval2;
11684
11685 /* Yet another special case instruction. */
11686 START_OF_INSTR();
11687 FETCH_DECODE_MODRM(mod, rh, rl);
11688 #ifdef DEBUG
11689 if (DEBUG_DECODE()) {
11690 /* XXX DECODE_PRINTF may be changed to something more
11691 general, so that it is important to leave the strings
11692 in the same format, even though the result is that the
11693 above test is done twice. */
11694
11695 switch (rh) {
11696 case 0:
11697 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11698 DECODE_PRINTF("INC\tDWORD PTR ");
11699 }
11700 else {
11701 DECODE_PRINTF("INC\tWORD PTR ");
11702 }
11703 break;
11704 case 1:
11705 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11706 DECODE_PRINTF("DEC\tDWORD PTR ");
11707 }
11708 else {
11709 DECODE_PRINTF("DEC\tWORD PTR ");
11710 }
11711 break;
11712 case 2:
11713 DECODE_PRINTF("CALL\t");
11714 break;
11715 case 3:
11716 DECODE_PRINTF("CALL\tFAR ");
11717 break;
11718 case 4:
11719 DECODE_PRINTF("JMP\t");
11720 break;
11721 case 5:
11722 DECODE_PRINTF("JMP\tFAR ");
11723 break;
11724 case 6:
11725 DECODE_PRINTF("PUSH\t");
11726 break;
11727 case 7:
11728 DECODE_PRINTF("ILLEGAL DECODING OF OPCODE FF\t");
11729 HALT_SYS();
11730 break;
11731 }
11732 }
11733 #endif
11734 switch (mod) {
11735 case 0:
11736 destoffset = decode_rm00_address(rl);
11737 DECODE_PRINTF("\n");
11738 switch (rh) {
11739 case 0: /* inc word ptr ... */
11740 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11741 u32 destval32;
11742
11743 destval32 = fetch_data_long(destoffset);
11744 TRACE_AND_STEP();
11745 destval32 = inc_long(destval32);
11746 store_data_long(destoffset, destval32);
11747 }
11748 else {
11749 u16 destval16;
11750
11751 destval16 = fetch_data_word(destoffset);
11752 TRACE_AND_STEP();
11753 destval16 = inc_word(destval16);
11754 store_data_word(destoffset, destval16);
11755 }
11756 break;
11757 case 1: /* dec word ptr ... */
11758 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11759 u32 destval32;
11760
11761 destval32 = fetch_data_long(destoffset);
11762 TRACE_AND_STEP();
11763 destval32 = dec_long(destval32);
11764 store_data_long(destoffset, destval32);
11765 }
11766 else {
11767 u16 destval16;
11768
11769 destval16 = fetch_data_word(destoffset);
11770 TRACE_AND_STEP();
11771 destval16 = dec_word(destval16);
11772 store_data_word(destoffset, destval16);
11773 }
11774 break;
11775 case 2: /* call word ptr ... */
11776 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11777 destval = fetch_data_long(destoffset);
11778 TRACE_AND_STEP();
11779 push_long(M.x86.R_EIP);
11780 M.x86.R_EIP = destval;
11781 } else {
11782 destval = fetch_data_word(destoffset);
11783 TRACE_AND_STEP();
11784 push_word(M.x86.R_IP);
11785 M.x86.R_IP = destval;
11786 }
11787 break;
11788 case 3: /* call far ptr ... */
11789 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11790 destval = fetch_data_long(destoffset);
11791 destval2 = fetch_data_word(destoffset + 4);
11792 TRACE_AND_STEP();
11793 push_long(M.x86.R_CS);
11794 M.x86.R_CS = destval2;
11795 push_long(M.x86.R_EIP);
11796 M.x86.R_EIP = destval;
11797 } else {
11798 destval = fetch_data_word(destoffset);
11799 destval2 = fetch_data_word(destoffset + 2);
11800 TRACE_AND_STEP();
11801 push_word(M.x86.R_CS);
11802 M.x86.R_CS = destval2;
11803 push_word(M.x86.R_IP);
11804 M.x86.R_IP = destval;
11805 }
11806 break;
11807 case 4: /* jmp word ptr ... */
11808 destval = fetch_data_word(destoffset);
11809 TRACE_AND_STEP();
11810 M.x86.R_IP = destval;
11811 break;
11812 case 5: /* jmp far ptr ... */
11813 destval = fetch_data_word(destoffset);
11814 destval2 = fetch_data_word(destoffset + 2);
11815 TRACE_AND_STEP();
11816 M.x86.R_IP = destval;
11817 M.x86.R_CS = destval2;
11818 break;
11819 case 6: /* push word ptr ... */
11820 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11821 u32 destval32;
11822
11823 destval32 = fetch_data_long(destoffset);
11824 TRACE_AND_STEP();
11825 push_long(destval32);
11826 }
11827 else {
11828 u16 destval16;
11829
11830 destval16 = fetch_data_word(destoffset);
11831 TRACE_AND_STEP();
11832 push_word(destval16);
11833 }
11834 break;
11835 }
11836 break;
11837 case 1:
11838 destoffset = decode_rm01_address(rl);
11839 DECODE_PRINTF("\n");
11840 switch (rh) {
11841 case 0:
11842 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11843 u32 destval32;
11844
11845 destval32 = fetch_data_long(destoffset);
11846 TRACE_AND_STEP();
11847 destval32 = inc_long(destval32);
11848 store_data_long(destoffset, destval32);
11849 }
11850 else {
11851 u16 destval16;
11852
11853 destval16 = fetch_data_word(destoffset);
11854 TRACE_AND_STEP();
11855 destval16 = inc_word(destval16);
11856 store_data_word(destoffset, destval16);
11857 }
11858 break;
11859 case 1:
11860 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11861 u32 destval32;
11862
11863 destval32 = fetch_data_long(destoffset);
11864 TRACE_AND_STEP();
11865 destval32 = dec_long(destval32);
11866 store_data_long(destoffset, destval32);
11867 }
11868 else {
11869 u16 destval16;
11870
11871 destval16 = fetch_data_word(destoffset);
11872 TRACE_AND_STEP();
11873 destval16 = dec_word(destval16);
11874 store_data_word(destoffset, destval16);
11875 }
11876 break;
11877 case 2: /* call word ptr ... */
11878 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11879 destval = fetch_data_long(destoffset);
11880 TRACE_AND_STEP();
11881 push_long(M.x86.R_EIP);
11882 M.x86.R_EIP = destval;
11883 } else {
11884 destval = fetch_data_word(destoffset);
11885 TRACE_AND_STEP();
11886 push_word(M.x86.R_IP);
11887 M.x86.R_IP = destval;
11888 }
11889 break;
11890 case 3: /* call far ptr ... */
11891 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11892 destval = fetch_data_long(destoffset);
11893 destval2 = fetch_data_word(destoffset + 4);
11894 TRACE_AND_STEP();
11895 push_long(M.x86.R_CS);
11896 M.x86.R_CS = destval2;
11897 push_long(M.x86.R_EIP);
11898 M.x86.R_EIP = destval;
11899 } else {
11900 destval = fetch_data_word(destoffset);
11901 destval2 = fetch_data_word(destoffset + 2);
11902 TRACE_AND_STEP();
11903 push_word(M.x86.R_CS);
11904 M.x86.R_CS = destval2;
11905 push_word(M.x86.R_IP);
11906 M.x86.R_IP = destval;
11907 }
11908 break;
11909 case 4: /* jmp word ptr ... */
11910 destval = fetch_data_word(destoffset);
11911 TRACE_AND_STEP();
11912 M.x86.R_IP = destval;
11913 break;
11914 case 5: /* jmp far ptr ... */
11915 destval = fetch_data_word(destoffset);
11916 destval2 = fetch_data_word(destoffset + 2);
11917 TRACE_AND_STEP();
11918 M.x86.R_IP = destval;
11919 M.x86.R_CS = destval2;
11920 break;
11921 case 6: /* push word ptr ... */
11922 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11923 u32 destval32;
11924
11925 destval32 = fetch_data_long(destoffset);
11926 TRACE_AND_STEP();
11927 push_long(destval32);
11928 }
11929 else {
11930 u16 destval16;
11931
11932 destval16 = fetch_data_word(destoffset);
11933 TRACE_AND_STEP();
11934 push_word(destval16);
11935 }
11936 break;
11937 }
11938 break;
11939 case 2:
11940 destoffset = decode_rm10_address(rl);
11941 DECODE_PRINTF("\n");
11942 switch (rh) {
11943 case 0:
11944 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11945 u32 destval32;
11946
11947 destval32 = fetch_data_long(destoffset);
11948 TRACE_AND_STEP();
11949 destval32 = inc_long(destval32);
11950 store_data_long(destoffset, destval32);
11951 }
11952 else {
11953 u16 destval16;
11954
11955 destval16 = fetch_data_word(destoffset);
11956 TRACE_AND_STEP();
11957 destval16 = inc_word(destval16);
11958 store_data_word(destoffset, destval16);
11959 }
11960 break;
11961 case 1:
11962 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11963 u32 destval32;
11964
11965 destval32 = fetch_data_long(destoffset);
11966 TRACE_AND_STEP();
11967 destval32 = dec_long(destval32);
11968 store_data_long(destoffset, destval32);
11969 }
11970 else {
11971 u16 destval16;
11972
11973 destval16 = fetch_data_word(destoffset);
11974 TRACE_AND_STEP();
11975 destval16 = dec_word(destval16);
11976 store_data_word(destoffset, destval16);
11977 }
11978 break;
11979 case 2: /* call word ptr ... */
11980 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11981 destval = fetch_data_long(destoffset);
11982 TRACE_AND_STEP();
11983 push_long(M.x86.R_EIP);
11984 M.x86.R_EIP = destval;
11985 } else {
11986 destval = fetch_data_word(destoffset);
11987 TRACE_AND_STEP();
11988 push_word(M.x86.R_IP);
11989 M.x86.R_IP = destval;
11990 }
11991 break;
11992 case 3: /* call far ptr ... */
11993 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11994 destval = fetch_data_long(destoffset);
11995 destval2 = fetch_data_word(destoffset + 4);
11996 TRACE_AND_STEP();
11997 push_long(M.x86.R_CS);
11998 M.x86.R_CS = destval2;
11999 push_long(M.x86.R_EIP);
12000 M.x86.R_EIP = destval;
12001 } else {
12002 destval = fetch_data_word(destoffset);
12003 destval2 = fetch_data_word(destoffset + 2);
12004 TRACE_AND_STEP();
12005 push_word(M.x86.R_CS);
12006 M.x86.R_CS = destval2;
12007 push_word(M.x86.R_IP);
12008 M.x86.R_IP = destval;
12009 }
12010 break;
12011 case 4: /* jmp word ptr ... */
12012 destval = fetch_data_word(destoffset);
12013 TRACE_AND_STEP();
12014 M.x86.R_IP = destval;
12015 break;
12016 case 5: /* jmp far ptr ... */
12017 destval = fetch_data_word(destoffset);
12018 destval2 = fetch_data_word(destoffset + 2);
12019 TRACE_AND_STEP();
12020 M.x86.R_IP = destval;
12021 M.x86.R_CS = destval2;
12022 break;
12023 case 6: /* push word ptr ... */
12024 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
12025 u32 destval32;
12026
12027 destval32 = fetch_data_long(destoffset);
12028 TRACE_AND_STEP();
12029 push_long(destval32);
12030 }
12031 else {
12032 u16 destval16;
12033
12034 destval16 = fetch_data_word(destoffset);
12035 TRACE_AND_STEP();
12036 push_word(destval16);
12037 }
12038 break;
12039 }
12040 break;
12041 case 3:
12042 switch (rh) {
12043 case 0:
12044 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
12045 u32 *destreg32;
12046
12047 destreg32 = DECODE_RM_LONG_REGISTER(rl);
12048 DECODE_PRINTF("\n");
12049 TRACE_AND_STEP();
12050 *destreg32 = inc_long(*destreg32);
12051 }
12052 else {
12053 u16 *destreg16;
12054
12055 destreg16 = DECODE_RM_WORD_REGISTER(rl);
12056 DECODE_PRINTF("\n");
12057 TRACE_AND_STEP();
12058 *destreg16 = inc_word(*destreg16);
12059 }
12060 break;
12061 case 1:
12062 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
12063 u32 *destreg32;
12064
12065 destreg32 = DECODE_RM_LONG_REGISTER(rl);
12066 DECODE_PRINTF("\n");
12067 TRACE_AND_STEP();
12068 *destreg32 = dec_long(*destreg32);
12069 }
12070 else {
12071 u16 *destreg16;
12072
12073 destreg16 = DECODE_RM_WORD_REGISTER(rl);
12074 DECODE_PRINTF("\n");
12075 TRACE_AND_STEP();
12076 *destreg16 = dec_word(*destreg16);
12077 }
12078 break;
12079 case 2: /* call word ptr ... */
12080 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
12081 destreg = (u16 *)DECODE_RM_LONG_REGISTER(rl);
12082 DECODE_PRINTF("\n");
12083 TRACE_AND_STEP();
12084 push_long(M.x86.R_EIP);
12085 M.x86.R_EIP = *destreg;
12086 } else {
12087 destreg = DECODE_RM_WORD_REGISTER(rl);
12088 DECODE_PRINTF("\n");
12089 TRACE_AND_STEP();
12090 push_word(M.x86.R_IP);
12091 M.x86.R_IP = *destreg;
12092 }
12093 break;
12094 case 3: /* jmp far ptr ... */
12095 DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n");
12096 TRACE_AND_STEP();
12097 HALT_SYS();
12098 break;
12099
12100 case 4: /* jmp ... */
12101 destreg = DECODE_RM_WORD_REGISTER(rl);
12102 DECODE_PRINTF("\n");
12103 TRACE_AND_STEP();
12104 M.x86.R_IP = (u16) (*destreg);
12105 break;
12106 case 5: /* jmp far ptr ... */
12107 DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n");
12108 TRACE_AND_STEP();
12109 HALT_SYS();
12110 break;
12111 case 6:
12112 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
12113 u32 *destreg32;
12114
12115 destreg32 = DECODE_RM_LONG_REGISTER(rl);
12116 DECODE_PRINTF("\n");
12117 TRACE_AND_STEP();
12118 push_long(*destreg32);
12119 }
12120 else {
12121 u16 *destreg16;
12122
12123 destreg16 = DECODE_RM_WORD_REGISTER(rl);
12124 DECODE_PRINTF("\n");
12125 TRACE_AND_STEP();
12126 push_word(*destreg16);
12127 }
12128 break;
12129 }
12130 break;
12131 }
12132 DECODE_CLEAR_SEGOVR();
12133 END_OF_INSTR();
12134 }
12135
12136 /***************************************************************************
12137 * Single byte operation code table:
12138 **************************************************************************/
12139 void (*x86emu_optab[256]) (u8) = {
12140 /* 0x00 */ x86emuOp_add_byte_RM_R,
12141 /* 0x01 */ x86emuOp_add_word_RM_R,
12142 /* 0x02 */ x86emuOp_add_byte_R_RM,
12143 /* 0x03 */ x86emuOp_add_word_R_RM,
12144 /* 0x04 */ x86emuOp_add_byte_AL_IMM,
12145 /* 0x05 */ x86emuOp_add_word_AX_IMM,
12146 /* 0x06 */ x86emuOp_push_ES,
12147 /* 0x07 */ x86emuOp_pop_ES,
12148 /* 0x08 */ x86emuOp_or_byte_RM_R,
12149 /* 0x09 */ x86emuOp_or_word_RM_R,
12150 /* 0x0a */ x86emuOp_or_byte_R_RM,
12151 /* 0x0b */ x86emuOp_or_word_R_RM,
12152 /* 0x0c */ x86emuOp_or_byte_AL_IMM,
12153 /* 0x0d */ x86emuOp_or_word_AX_IMM,
12154 /* 0x0e */ x86emuOp_push_CS,
12155 /* 0x0f */ x86emuOp_two_byte,
12156 /* 0x10 */ x86emuOp_adc_byte_RM_R,
12157 /* 0x11 */ x86emuOp_adc_word_RM_R,
12158 /* 0x12 */ x86emuOp_adc_byte_R_RM,
12159 /* 0x13 */ x86emuOp_adc_word_R_RM,
12160 /* 0x14 */ x86emuOp_adc_byte_AL_IMM,
12161 /* 0x15 */ x86emuOp_adc_word_AX_IMM,
12162 /* 0x16 */ x86emuOp_push_SS,
12163 /* 0x17 */ x86emuOp_pop_SS,
12164 /* 0x18 */ x86emuOp_sbb_byte_RM_R,
12165 /* 0x19 */ x86emuOp_sbb_word_RM_R,
12166 /* 0x1a */ x86emuOp_sbb_byte_R_RM,
12167 /* 0x1b */ x86emuOp_sbb_word_R_RM,
12168 /* 0x1c */ x86emuOp_sbb_byte_AL_IMM,
12169 /* 0x1d */ x86emuOp_sbb_word_AX_IMM,
12170 /* 0x1e */ x86emuOp_push_DS,
12171 /* 0x1f */ x86emuOp_pop_DS,
12172 /* 0x20 */ x86emuOp_and_byte_RM_R,
12173 /* 0x21 */ x86emuOp_and_word_RM_R,
12174 /* 0x22 */ x86emuOp_and_byte_R_RM,
12175 /* 0x23 */ x86emuOp_and_word_R_RM,
12176 /* 0x24 */ x86emuOp_and_byte_AL_IMM,
12177 /* 0x25 */ x86emuOp_and_word_AX_IMM,
12178 /* 0x26 */ x86emuOp_segovr_ES,
12179 /* 0x27 */ x86emuOp_daa,
12180 /* 0x28 */ x86emuOp_sub_byte_RM_R,
12181 /* 0x29 */ x86emuOp_sub_word_RM_R,
12182 /* 0x2a */ x86emuOp_sub_byte_R_RM,
12183 /* 0x2b */ x86emuOp_sub_word_R_RM,
12184 /* 0x2c */ x86emuOp_sub_byte_AL_IMM,
12185 /* 0x2d */ x86emuOp_sub_word_AX_IMM,
12186 /* 0x2e */ x86emuOp_segovr_CS,
12187 /* 0x2f */ x86emuOp_das,
12188 /* 0x30 */ x86emuOp_xor_byte_RM_R,
12189 /* 0x31 */ x86emuOp_xor_word_RM_R,
12190 /* 0x32 */ x86emuOp_xor_byte_R_RM,
12191 /* 0x33 */ x86emuOp_xor_word_R_RM,
12192 /* 0x34 */ x86emuOp_xor_byte_AL_IMM,
12193 /* 0x35 */ x86emuOp_xor_word_AX_IMM,
12194 /* 0x36 */ x86emuOp_segovr_SS,
12195 /* 0x37 */ x86emuOp_aaa,
12196 /* 0x38 */ x86emuOp_cmp_byte_RM_R,
12197 /* 0x39 */ x86emuOp_cmp_word_RM_R,
12198 /* 0x3a */ x86emuOp_cmp_byte_R_RM,
12199 /* 0x3b */ x86emuOp_cmp_word_R_RM,
12200 /* 0x3c */ x86emuOp_cmp_byte_AL_IMM,
12201 /* 0x3d */ x86emuOp_cmp_word_AX_IMM,
12202 /* 0x3e */ x86emuOp_segovr_DS,
12203 /* 0x3f */ x86emuOp_aas,
12204 /* 0x40 */ x86emuOp_inc_AX,
12205 /* 0x41 */ x86emuOp_inc_CX,
12206 /* 0x42 */ x86emuOp_inc_DX,
12207 /* 0x43 */ x86emuOp_inc_BX,
12208 /* 0x44 */ x86emuOp_inc_SP,
12209 /* 0x45 */ x86emuOp_inc_BP,
12210 /* 0x46 */ x86emuOp_inc_SI,
12211 /* 0x47 */ x86emuOp_inc_DI,
12212 /* 0x48 */ x86emuOp_dec_AX,
12213 /* 0x49 */ x86emuOp_dec_CX,
12214 /* 0x4a */ x86emuOp_dec_DX,
12215 /* 0x4b */ x86emuOp_dec_BX,
12216 /* 0x4c */ x86emuOp_dec_SP,
12217 /* 0x4d */ x86emuOp_dec_BP,
12218 /* 0x4e */ x86emuOp_dec_SI,
12219 /* 0x4f */ x86emuOp_dec_DI,
12220 /* 0x50 */ x86emuOp_push_AX,
12221 /* 0x51 */ x86emuOp_push_CX,
12222 /* 0x52 */ x86emuOp_push_DX,
12223 /* 0x53 */ x86emuOp_push_BX,
12224 /* 0x54 */ x86emuOp_push_SP,
12225 /* 0x55 */ x86emuOp_push_BP,
12226 /* 0x56 */ x86emuOp_push_SI,
12227 /* 0x57 */ x86emuOp_push_DI,
12228 /* 0x58 */ x86emuOp_pop_AX,
12229 /* 0x59 */ x86emuOp_pop_CX,
12230 /* 0x5a */ x86emuOp_pop_DX,
12231 /* 0x5b */ x86emuOp_pop_BX,
12232 /* 0x5c */ x86emuOp_pop_SP,
12233 /* 0x5d */ x86emuOp_pop_BP,
12234 /* 0x5e */ x86emuOp_pop_SI,
12235 /* 0x5f */ x86emuOp_pop_DI,
12236 /* 0x60 */ x86emuOp_push_all,
12237 /* 0x61 */ x86emuOp_pop_all,
12238 /* 0x62 */ x86emuOp_illegal_op,
12239 /* bound */
12240 /* 0x63 */ x86emuOp_illegal_op,
12241 /* arpl */
12242 /* 0x64 */ x86emuOp_segovr_FS,
12243 /* 0x65 */ x86emuOp_segovr_GS,
12244 /* 0x66 */ x86emuOp_prefix_data,
12245 /* 0x67 */ x86emuOp_prefix_addr,
12246 /* 0x68 */ x86emuOp_push_word_IMM,
12247 /* 0x69 */ x86emuOp_imul_word_IMM,
12248 /* 0x6a */ x86emuOp_push_byte_IMM,
12249 /* 0x6b */ x86emuOp_imul_byte_IMM,
12250 /* 0x6c */ x86emuOp_ins_byte,
12251 /* 0x6d */ x86emuOp_ins_word,
12252 /* 0x6e */ x86emuOp_outs_byte,
12253 /* 0x6f */ x86emuOp_outs_word,
12254 /* 0x70 */ x86emuOp_jump_near_O,
12255 /* 0x71 */ x86emuOp_jump_near_NO,
12256 /* 0x72 */ x86emuOp_jump_near_B,
12257 /* 0x73 */ x86emuOp_jump_near_NB,
12258 /* 0x74 */ x86emuOp_jump_near_Z,
12259 /* 0x75 */ x86emuOp_jump_near_NZ,
12260 /* 0x76 */ x86emuOp_jump_near_BE,
12261 /* 0x77 */ x86emuOp_jump_near_NBE,
12262 /* 0x78 */ x86emuOp_jump_near_S,
12263 /* 0x79 */ x86emuOp_jump_near_NS,
12264 /* 0x7a */ x86emuOp_jump_near_P,
12265 /* 0x7b */ x86emuOp_jump_near_NP,
12266 /* 0x7c */ x86emuOp_jump_near_L,
12267 /* 0x7d */ x86emuOp_jump_near_NL,
12268 /* 0x7e */ x86emuOp_jump_near_LE,
12269 /* 0x7f */ x86emuOp_jump_near_NLE,
12270 /* 0x80 */ x86emuOp_opc80_byte_RM_IMM,
12271 /* 0x81 */ x86emuOp_opc81_word_RM_IMM,
12272 /* 0x82 */ x86emuOp_opc82_byte_RM_IMM,
12273 /* 0x83 */ x86emuOp_opc83_word_RM_IMM,
12274 /* 0x84 */ x86emuOp_test_byte_RM_R,
12275 /* 0x85 */ x86emuOp_test_word_RM_R,
12276 /* 0x86 */ x86emuOp_xchg_byte_RM_R,
12277 /* 0x87 */ x86emuOp_xchg_word_RM_R,
12278 /* 0x88 */ x86emuOp_mov_byte_RM_R,
12279 /* 0x89 */ x86emuOp_mov_word_RM_R,
12280 /* 0x8a */ x86emuOp_mov_byte_R_RM,
12281 /* 0x8b */ x86emuOp_mov_word_R_RM,
12282 /* 0x8c */ x86emuOp_mov_word_RM_SR,
12283 /* 0x8d */ x86emuOp_lea_word_R_M,
12284 /* 0x8e */ x86emuOp_mov_word_SR_RM,
12285 /* 0x8f */ x86emuOp_pop_RM,
12286 /* 0x90 */ x86emuOp_nop,
12287 /* 0x91 */ x86emuOp_xchg_word_AX_CX,
12288 /* 0x92 */ x86emuOp_xchg_word_AX_DX,
12289 /* 0x93 */ x86emuOp_xchg_word_AX_BX,
12290 /* 0x94 */ x86emuOp_xchg_word_AX_SP,
12291 /* 0x95 */ x86emuOp_xchg_word_AX_BP,
12292 /* 0x96 */ x86emuOp_xchg_word_AX_SI,
12293 /* 0x97 */ x86emuOp_xchg_word_AX_DI,
12294 /* 0x98 */ x86emuOp_cbw,
12295 /* 0x99 */ x86emuOp_cwd,
12296 /* 0x9a */ x86emuOp_call_far_IMM,
12297 /* 0x9b */ x86emuOp_wait,
12298 /* 0x9c */ x86emuOp_pushf_word,
12299 /* 0x9d */ x86emuOp_popf_word,
12300 /* 0x9e */ x86emuOp_sahf,
12301 /* 0x9f */ x86emuOp_lahf,
12302 /* 0xa0 */ x86emuOp_mov_AL_M_IMM,
12303 /* 0xa1 */ x86emuOp_mov_AX_M_IMM,
12304 /* 0xa2 */ x86emuOp_mov_M_AL_IMM,
12305 /* 0xa3 */ x86emuOp_mov_M_AX_IMM,
12306 /* 0xa4 */ x86emuOp_movs_byte,
12307 /* 0xa5 */ x86emuOp_movs_word,
12308 /* 0xa6 */ x86emuOp_cmps_byte,
12309 /* 0xa7 */ x86emuOp_cmps_word,
12310 /* 0xa8 */ x86emuOp_test_AL_IMM,
12311 /* 0xa9 */ x86emuOp_test_AX_IMM,
12312 /* 0xaa */ x86emuOp_stos_byte,
12313 /* 0xab */ x86emuOp_stos_word,
12314 /* 0xac */ x86emuOp_lods_byte,
12315 /* 0xad */ x86emuOp_lods_word,
12316 /* 0xac */ x86emuOp_scas_byte,
12317 /* 0xad */ x86emuOp_scas_word,
12318 /* 0xb0 */ x86emuOp_mov_byte_AL_IMM,
12319 /* 0xb1 */ x86emuOp_mov_byte_CL_IMM,
12320 /* 0xb2 */ x86emuOp_mov_byte_DL_IMM,
12321 /* 0xb3 */ x86emuOp_mov_byte_BL_IMM,
12322 /* 0xb4 */ x86emuOp_mov_byte_AH_IMM,
12323 /* 0xb5 */ x86emuOp_mov_byte_CH_IMM,
12324 /* 0xb6 */ x86emuOp_mov_byte_DH_IMM,
12325 /* 0xb7 */ x86emuOp_mov_byte_BH_IMM,
12326 /* 0xb8 */ x86emuOp_mov_word_AX_IMM,
12327 /* 0xb9 */ x86emuOp_mov_word_CX_IMM,
12328 /* 0xba */ x86emuOp_mov_word_DX_IMM,
12329 /* 0xbb */ x86emuOp_mov_word_BX_IMM,
12330 /* 0xbc */ x86emuOp_mov_word_SP_IMM,
12331 /* 0xbd */ x86emuOp_mov_word_BP_IMM,
12332 /* 0xbe */ x86emuOp_mov_word_SI_IMM,
12333 /* 0xbf */ x86emuOp_mov_word_DI_IMM,
12334 /* 0xc0 */ x86emuOp_opcC0_byte_RM_MEM,
12335 /* 0xc1 */ x86emuOp_opcC1_word_RM_MEM,
12336 /* 0xc2 */ x86emuOp_ret_near_IMM,
12337 /* 0xc3 */ x86emuOp_ret_near,
12338 /* 0xc4 */ x86emuOp_les_R_IMM,
12339 /* 0xc5 */ x86emuOp_lds_R_IMM,
12340 /* 0xc6 */ x86emuOp_mov_byte_RM_IMM,
12341 /* 0xc7 */ x86emuOp_mov_word_RM_IMM,
12342 /* 0xc8 */ x86emuOp_enter,
12343 /* 0xc9 */ x86emuOp_leave,
12344 /* 0xca */ x86emuOp_ret_far_IMM,
12345 /* 0xcb */ x86emuOp_ret_far,
12346 /* 0xcc */ x86emuOp_int3,
12347 /* 0xcd */ x86emuOp_int_IMM,
12348 /* 0xce */ x86emuOp_into,
12349 /* 0xcf */ x86emuOp_iret,
12350 /* 0xd0 */ x86emuOp_opcD0_byte_RM_1,
12351 /* 0xd1 */ x86emuOp_opcD1_word_RM_1,
12352 /* 0xd2 */ x86emuOp_opcD2_byte_RM_CL,
12353 /* 0xd3 */ x86emuOp_opcD3_word_RM_CL,
12354 /* 0xd4 */ x86emuOp_aam,
12355 /* 0xd5 */ x86emuOp_aad,
12356 /* 0xd6 */ x86emuOp_illegal_op,
12357 /* Undocumented SETALC instruction */
12358 /* 0xd7 */ x86emuOp_xlat,
12359 /* 0xd8 */ x86emuOp_esc_coprocess_d8,
12360 /* 0xd9 */ x86emuOp_esc_coprocess_d9,
12361 /* 0xda */ x86emuOp_esc_coprocess_da,
12362 /* 0xdb */ x86emuOp_esc_coprocess_db,
12363 /* 0xdc */ x86emuOp_esc_coprocess_dc,
12364 /* 0xdd */ x86emuOp_esc_coprocess_dd,
12365 /* 0xde */ x86emuOp_esc_coprocess_de,
12366 /* 0xdf */ x86emuOp_esc_coprocess_df,
12367 /* 0xe0 */ x86emuOp_loopne,
12368 /* 0xe1 */ x86emuOp_loope,
12369 /* 0xe2 */ x86emuOp_loop,
12370 /* 0xe3 */ x86emuOp_jcxz,
12371 /* 0xe4 */ x86emuOp_in_byte_AL_IMM,
12372 /* 0xe5 */ x86emuOp_in_word_AX_IMM,
12373 /* 0xe6 */ x86emuOp_out_byte_IMM_AL,
12374 /* 0xe7 */ x86emuOp_out_word_IMM_AX,
12375 /* 0xe8 */ x86emuOp_call_near_IMM,
12376 /* 0xe9 */ x86emuOp_jump_near_IMM,
12377 /* 0xea */ x86emuOp_jump_far_IMM,
12378 /* 0xeb */ x86emuOp_jump_byte_IMM,
12379 /* 0xec */ x86emuOp_in_byte_AL_DX,
12380 /* 0xed */ x86emuOp_in_word_AX_DX,
12381 /* 0xee */ x86emuOp_out_byte_DX_AL,
12382 /* 0xef */ x86emuOp_out_word_DX_AX,
12383 /* 0xf0 */ x86emuOp_lock,
12384 /* 0xf1 */ x86emuOp_illegal_op,
12385 /* 0xf2 */ x86emuOp_repne,
12386 /* 0xf3 */ x86emuOp_repe,
12387 /* 0xf4 */ x86emuOp_halt,
12388 /* 0xf5 */ x86emuOp_cmc,
12389 /* 0xf6 */ x86emuOp_opcF6_byte_RM,
12390 /* 0xf7 */ x86emuOp_opcF7_word_RM,
12391 /* 0xf8 */ x86emuOp_clc,
12392 /* 0xf9 */ x86emuOp_stc,
12393 /* 0xfa */ x86emuOp_cli,
12394 /* 0xfb */ x86emuOp_sti,
12395 /* 0xfc */ x86emuOp_cld,
12396 /* 0xfd */ x86emuOp_std,
12397 /* 0xfe */ x86emuOp_opcFE_byte_RM,
12398 /* 0xff */ x86emuOp_opcFF_word_RM,
12399 };
12400