~ubuntu-branches/ubuntu/edgy/hwinfo/edgy

« back to all changes in this revision

Viewing changes to src/x86emu/ops.c

  • Committer: Bazaar Package Importer
  • Author(s): James Vega
  • Date: 2006-09-28 20:56:06 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20060928205606-bgxl69hts04xbx51
Tags: 13.4-1
* New upstream version.
* Switch from dbs to quilt
  - Revamp debian/rules
  - Add quilt and remove dbs from Build-Depends in debian/control
* Remove reference to hwscan(8) from manpage. (closes: #388245)
* Re-wrote manpage from scratch.  Drop docbook-to-man from Build-Depends.
* Remove NEWS.Debian since it is no longer applicable.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
*
 
3
*                                               Realmode X86 Emulator Library
 
4
*
 
5
*               Copyright (C) 1996-1999 SciTech Software, Inc.
 
6
*                                    Copyright (C) David Mosberger-Tang
 
7
*                                          Copyright (C) 1999 Egbert Eich
 
8
*
 
9
*  ========================================================================
 
10
*
 
11
*  Permission to use, copy, modify, distribute, and sell this software and
 
12
*  its documentation for any purpose is hereby granted without fee,
 
13
*  provided that the above copyright notice appear in all copies and that
 
14
*  both that copyright notice and this permission notice appear in
 
15
*  supporting documentation, and that the name of the authors not be used
 
16
*  in advertising or publicity pertaining to distribution of the software
 
17
*  without specific, written prior permission.  The authors makes no
 
18
*  representations about the suitability of this software for any purpose.
 
19
*  It is provided "as is" without express or implied warranty.
 
20
*
 
21
*  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 
22
*  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 
23
*  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 
24
*  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
 
25
*  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
 
26
*  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 
27
*  PERFORMANCE OF THIS SOFTWARE.
 
28
*
 
29
*  ========================================================================
 
30
*
 
31
* Language:             ANSI C
 
32
* Environment:  Any
 
33
* Developer:    Kendall Bennett
 
34
*
 
35
* Description:  This file includes subroutines to implement the decoding
 
36
*               and emulation of all the x86 processor instructions.
 
37
*
 
38
* There are approximately 250 subroutines in here, which correspond
 
39
* to the 256 byte-"opcodes" found on the 8086.  The table which
 
40
* dispatches this is found in the files optab.[ch].
 
41
*
 
42
* Each opcode proc has a comment preceeding it which gives it's table
 
43
* address.  Several opcodes are missing (undefined) in the table.
 
44
*
 
45
* Each proc includes information for decoding (DECODE_PRINTF and
 
46
* DECODE_PRINTF2), debugging (TRACE_REGS, SINGLE_STEP), and misc
 
47
* functions (START_OF_INSTR, END_OF_INSTR).
 
48
*
 
49
* Many of the procedures are *VERY* similar in coding.  This has
 
50
* allowed for a very large amount of code to be generated in a fairly
 
51
* short amount of time (i.e. cut, paste, and modify).  The result is
 
52
* that much of the code below could have been folded into subroutines
 
53
* for a large reduction in size of this file.  The downside would be
 
54
* that there would be a penalty in execution speed.  The file could
 
55
* also have been *MUCH* larger by inlining certain functions which
 
56
* were called.  This could have resulted even faster execution.  The
 
57
* prime directive I used to decide whether to inline the code or to
 
58
* modularize it, was basically: 1) no unnecessary subroutine calls,
 
59
* 2) no routines more than about 200 lines in size, and 3) modularize
 
60
* any code that I might not get right the first time.  The fetch_*
 
61
* subroutines fall into the latter category.  The The decode_* fall
 
62
* into the second category.  The coding of the "switch(mod){ .... }"
 
63
* in many of the subroutines below falls into the first category.
 
64
* Especially, the coding of {add,and,or,sub,...}_{byte,word}
 
65
* subroutines are an especially glaring case of the third guideline.
 
66
* Since so much of the code is cloned from other modules (compare
 
67
* opcode #00 to opcode #01), making the basic operations subroutine
 
68
* calls is especially important; otherwise mistakes in coding an
 
69
* "add" would represent a nightmare in maintenance.
 
70
*
 
71
****************************************************************************/
 
72
 
 
73
/* $XFree86: xc/extras/x86emu/src/x86emu/ops.c,v 1.8tsi Exp $ */
 
74
 
 
75
#include "x86emu/x86emui.h"
 
76
 
 
77
/*----------------------------- Implementation ----------------------------*/
 
78
 
 
79
/****************************************************************************
 
80
PARAMETERS:
 
81
op1 - Instruction op code
 
82
 
 
83
REMARKS:
 
84
Handles illegal opcodes.
 
85
****************************************************************************/
 
86
static void x86emuOp_illegal_op(
 
87
    u8 op1)
 
88
{
 
89
    START_OF_INSTR();
 
90
    if (M.x86.R_SP != 0) {
 
91
    DECODE_PRINTF("ILLEGAL X86 OPCODE\n");
 
92
    TRACE_REGS();
 
93
    printk("%04x:%04x: %02X ILLEGAL X86 OPCODE!\n",
 
94
        M.x86.R_CS, M.x86.R_IP-1,op1);
 
95
    HALT_SYS();
 
96
        }
 
97
    else {
 
98
        /* If we get here, it means the stack pointer is back to zero
 
99
         * so we are just returning from an emulator service call
 
100
         * so therte is no need to display an error message. We trap
 
101
         * the emulator with an 0xF1 opcode to finish the service
 
102
         * call.
 
103
         */
 
104
        X86EMU_halt_sys();
 
105
        }
 
106
    END_OF_INSTR();
 
107
}
 
108
 
 
109
/****************************************************************************
 
110
REMARKS:
 
111
Handles opcode 0x00
 
112
****************************************************************************/
 
113
static void x86emuOp_add_byte_RM_R(u8 X86EMU_UNUSED(op1))
 
114
{
 
115
    int mod, rl, rh;
 
116
    uint destoffset;
 
117
    u8 *destreg, *srcreg;
 
118
    u8 destval;
 
119
 
 
120
    START_OF_INSTR();
 
121
    DECODE_PRINTF("ADD\t");
 
122
    FETCH_DECODE_MODRM(mod, rh, rl);
 
123
    switch (mod) {
 
124
    case 0:
 
125
        destoffset = decode_rm00_address(rl);
 
126
        DECODE_PRINTF(",");
 
127
        destval = fetch_data_byte(destoffset);
 
128
        srcreg = DECODE_RM_BYTE_REGISTER(rh);
 
129
        DECODE_PRINTF("\n");
 
130
        TRACE_AND_STEP();
 
131
        destval = add_byte(destval, *srcreg);
 
132
        store_data_byte(destoffset, destval);
 
133
        break;
 
134
    case 1:
 
135
        destoffset = decode_rm01_address(rl);
 
136
        DECODE_PRINTF(",");
 
137
        destval = fetch_data_byte(destoffset);
 
138
        srcreg = DECODE_RM_BYTE_REGISTER(rh);
 
139
        DECODE_PRINTF("\n");
 
140
        TRACE_AND_STEP();
 
141
        destval = add_byte(destval, *srcreg);
 
142
        store_data_byte(destoffset, destval);
 
143
        break;
 
144
    case 2:
 
145
        destoffset = decode_rm10_address(rl);
 
146
        DECODE_PRINTF(",");
 
147
        destval = fetch_data_byte(destoffset);
 
148
        srcreg = DECODE_RM_BYTE_REGISTER(rh);
 
149
        DECODE_PRINTF("\n");
 
150
        TRACE_AND_STEP();
 
151
        destval = add_byte(destval, *srcreg);
 
152
        store_data_byte(destoffset, destval);
 
153
        break;
 
154
    case 3:                     /* register to register */
 
155
        destreg = DECODE_RM_BYTE_REGISTER(rl);
 
156
        DECODE_PRINTF(",");
 
157
        srcreg = DECODE_RM_BYTE_REGISTER(rh);
 
158
        DECODE_PRINTF("\n");
 
159
        TRACE_AND_STEP();
 
160
        *destreg = add_byte(*destreg, *srcreg);
 
161
        break;
 
162
    }
 
163
    DECODE_CLEAR_SEGOVR();
 
164
    END_OF_INSTR();
 
165
}
 
166
 
 
167
/****************************************************************************
 
168
REMARKS:
 
169
Handles opcode 0x01
 
170
****************************************************************************/
 
171
static void x86emuOp_add_word_RM_R(u8 X86EMU_UNUSED(op1))
 
172
{
 
173
    int mod, rl, rh;
 
174
    uint destoffset;
 
175
 
 
176
    START_OF_INSTR();
 
177
    DECODE_PRINTF("ADD\t");
 
178
    FETCH_DECODE_MODRM(mod, rh, rl);
 
179
    switch (mod) {
 
180
    case 0:
 
181
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
182
            u32 destval;
 
183
            u32 *srcreg;
 
184
 
 
185
            destoffset = decode_rm00_address(rl);
 
186
            DECODE_PRINTF(",");
 
187
            destval = fetch_data_long(destoffset);
 
188
            srcreg = DECODE_RM_LONG_REGISTER(rh);
 
189
            DECODE_PRINTF("\n");
 
190
            TRACE_AND_STEP();
 
191
            destval = add_long(destval, *srcreg);
 
192
            store_data_long(destoffset, destval);
 
193
        } else {
 
194
            u16 destval;
 
195
            u16 *srcreg;
 
196
 
 
197
            destoffset = decode_rm00_address(rl);
 
198
            DECODE_PRINTF(",");
 
199
            destval = fetch_data_word(destoffset);
 
200
            srcreg = DECODE_RM_WORD_REGISTER(rh);
 
201
            DECODE_PRINTF("\n");
 
202
            TRACE_AND_STEP();
 
203
            destval = add_word(destval, *srcreg);
 
204
            store_data_word(destoffset, destval);
 
205
        }
 
206
        break;
 
207
    case 1:
 
208
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
209
            u32 destval;
 
210
            u32 *srcreg;
 
211
 
 
212
            destoffset = decode_rm01_address(rl);
 
213
            DECODE_PRINTF(",");
 
214
            destval = fetch_data_long(destoffset);
 
215
            srcreg = DECODE_RM_LONG_REGISTER(rh);
 
216
            DECODE_PRINTF("\n");
 
217
            TRACE_AND_STEP();
 
218
            destval = add_long(destval, *srcreg);
 
219
            store_data_long(destoffset, destval);
 
220
        } else {
 
221
            u16 destval;
 
222
            u16 *srcreg;
 
223
 
 
224
            destoffset = decode_rm01_address(rl);
 
225
            DECODE_PRINTF(",");
 
226
            destval = fetch_data_word(destoffset);
 
227
            srcreg = DECODE_RM_WORD_REGISTER(rh);
 
228
            DECODE_PRINTF("\n");
 
229
            TRACE_AND_STEP();
 
230
            destval = add_word(destval, *srcreg);
 
231
            store_data_word(destoffset, destval);
 
232
        }
 
233
        break;
 
234
    case 2:
 
235
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
236
            u32 destval;
 
237
            u32 *srcreg;
 
238
 
 
239
            destoffset = decode_rm10_address(rl);
 
240
            DECODE_PRINTF(",");
 
241
            destval = fetch_data_long(destoffset);
 
242
            srcreg = DECODE_RM_LONG_REGISTER(rh);
 
243
            DECODE_PRINTF("\n");
 
244
            TRACE_AND_STEP();
 
245
            destval = add_long(destval, *srcreg);
 
246
            store_data_long(destoffset, destval);
 
247
        } else {
 
248
            u16 destval;
 
249
            u16 *srcreg;
 
250
 
 
251
            destoffset = decode_rm10_address(rl);
 
252
            DECODE_PRINTF(",");
 
253
            destval = fetch_data_word(destoffset);
 
254
            srcreg = DECODE_RM_WORD_REGISTER(rh);
 
255
            DECODE_PRINTF("\n");
 
256
            TRACE_AND_STEP();
 
257
            destval = add_word(destval, *srcreg);
 
258
            store_data_word(destoffset, destval);
 
259
        }
 
260
        break;
 
261
    case 3:                     /* register to register */
 
262
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
263
            u32 *destreg,*srcreg;
 
264
 
 
265
            destreg = DECODE_RM_LONG_REGISTER(rl);
 
266
            DECODE_PRINTF(",");
 
267
            srcreg = DECODE_RM_LONG_REGISTER(rh);
 
268
            DECODE_PRINTF("\n");
 
269
            TRACE_AND_STEP();
 
270
            *destreg = add_long(*destreg, *srcreg);
 
271
        } else {
 
272
            u16 *destreg,*srcreg;
 
273
 
 
274
            destreg = DECODE_RM_WORD_REGISTER(rl);
 
275
            DECODE_PRINTF(",");
 
276
            srcreg = DECODE_RM_WORD_REGISTER(rh);
 
277
            DECODE_PRINTF("\n");
 
278
            TRACE_AND_STEP();
 
279
            *destreg = add_word(*destreg, *srcreg);
 
280
        }
 
281
        break;
 
282
    }
 
283
    DECODE_CLEAR_SEGOVR();
 
284
    END_OF_INSTR();
 
285
}
 
286
 
 
287
/****************************************************************************
 
288
REMARKS:
 
289
Handles opcode 0x02
 
290
****************************************************************************/
 
291
static void x86emuOp_add_byte_R_RM(u8 X86EMU_UNUSED(op1))
 
292
{
 
293
    int mod, rl, rh;
 
294
    u8 *destreg, *srcreg;
 
295
    uint srcoffset;
 
296
    u8 srcval;
 
297
 
 
298
    START_OF_INSTR();
 
299
    DECODE_PRINTF("ADD\t");
 
300
    FETCH_DECODE_MODRM(mod, rh, rl);
 
301
    switch (mod) {
 
302
    case 0:
 
303
        destreg = DECODE_RM_BYTE_REGISTER(rh);
 
304
        DECODE_PRINTF(",");
 
305
        srcoffset = decode_rm00_address(rl);
 
306
        srcval = fetch_data_byte(srcoffset);
 
307
        DECODE_PRINTF("\n");
 
308
        TRACE_AND_STEP();
 
309
        *destreg = add_byte(*destreg, srcval);
 
310
        break;
 
311
    case 1:
 
312
        destreg = DECODE_RM_BYTE_REGISTER(rh);
 
313
        DECODE_PRINTF(",");
 
314
        srcoffset = decode_rm01_address(rl);
 
315
        srcval = fetch_data_byte(srcoffset);
 
316
        DECODE_PRINTF("\n");
 
317
        TRACE_AND_STEP();
 
318
        *destreg = add_byte(*destreg, srcval);
 
319
        break;
 
320
    case 2:
 
321
        destreg = DECODE_RM_BYTE_REGISTER(rh);
 
322
        DECODE_PRINTF(",");
 
323
        srcoffset = decode_rm10_address(rl);
 
324
        srcval = fetch_data_byte(srcoffset);
 
325
        DECODE_PRINTF("\n");
 
326
        TRACE_AND_STEP();
 
327
        *destreg = add_byte(*destreg, srcval);
 
328
        break;
 
329
    case 3:                     /* register to register */
 
330
        destreg = DECODE_RM_BYTE_REGISTER(rh);
 
331
        DECODE_PRINTF(",");
 
332
        srcreg = DECODE_RM_BYTE_REGISTER(rl);
 
333
        DECODE_PRINTF("\n");
 
334
        TRACE_AND_STEP();
 
335
        *destreg = add_byte(*destreg, *srcreg);
 
336
        break;
 
337
    }
 
338
    DECODE_CLEAR_SEGOVR();
 
339
    END_OF_INSTR();
 
340
}
 
341
 
 
342
/****************************************************************************
 
343
REMARKS:
 
344
Handles opcode 0x03
 
345
****************************************************************************/
 
346
static void x86emuOp_add_word_R_RM(u8 X86EMU_UNUSED(op1))
 
347
{
 
348
    int mod, rl, rh;
 
349
    uint srcoffset;
 
350
 
 
351
    START_OF_INSTR();
 
352
    DECODE_PRINTF("ADD\t");
 
353
    FETCH_DECODE_MODRM(mod, rh, rl);
 
354
    switch (mod) {
 
355
    case 0:
 
356
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
357
            u32 *destreg;
 
358
            u32 srcval;
 
359
 
 
360
            destreg = DECODE_RM_LONG_REGISTER(rh);
 
361
            DECODE_PRINTF(",");
 
362
            srcoffset = decode_rm00_address(rl);
 
363
            srcval = fetch_data_long(srcoffset);
 
364
            DECODE_PRINTF("\n");
 
365
            TRACE_AND_STEP();
 
366
            *destreg = add_long(*destreg, srcval);
 
367
        } else {
 
368
            u16 *destreg;
 
369
            u16 srcval;
 
370
 
 
371
            destreg = DECODE_RM_WORD_REGISTER(rh);
 
372
            DECODE_PRINTF(",");
 
373
            srcoffset = decode_rm00_address(rl);
 
374
            srcval = fetch_data_word(srcoffset);
 
375
            DECODE_PRINTF("\n");
 
376
            TRACE_AND_STEP();
 
377
            *destreg = add_word(*destreg, srcval);
 
378
        }
 
379
        break;
 
380
    case 1:
 
381
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
382
            u32 *destreg;
 
383
            u32 srcval;
 
384
 
 
385
            destreg = DECODE_RM_LONG_REGISTER(rh);
 
386
            DECODE_PRINTF(",");
 
387
            srcoffset = decode_rm01_address(rl);
 
388
            srcval = fetch_data_long(srcoffset);
 
389
            DECODE_PRINTF("\n");
 
390
            TRACE_AND_STEP();
 
391
            *destreg = add_long(*destreg, srcval);
 
392
        } else {
 
393
            u16 *destreg;
 
394
            u16 srcval;
 
395
 
 
396
            destreg = DECODE_RM_WORD_REGISTER(rh);
 
397
            DECODE_PRINTF(",");
 
398
            srcoffset = decode_rm01_address(rl);
 
399
            srcval = fetch_data_word(srcoffset);
 
400
            DECODE_PRINTF("\n");
 
401
            TRACE_AND_STEP();
 
402
            *destreg = add_word(*destreg, srcval);
 
403
        }
 
404
        break;
 
405
    case 2:
 
406
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
407
            u32 *destreg;
 
408
            u32 srcval;
 
409
 
 
410
            destreg = DECODE_RM_LONG_REGISTER(rh);
 
411
            DECODE_PRINTF(",");
 
412
            srcoffset = decode_rm10_address(rl);
 
413
            srcval = fetch_data_long(srcoffset);
 
414
            DECODE_PRINTF("\n");
 
415
            TRACE_AND_STEP();
 
416
            *destreg = add_long(*destreg, srcval);
 
417
        } else {
 
418
            u16 *destreg;
 
419
            u16 srcval;
 
420
 
 
421
            destreg = DECODE_RM_WORD_REGISTER(rh);
 
422
            DECODE_PRINTF(",");
 
423
            srcoffset = decode_rm10_address(rl);
 
424
            srcval = fetch_data_word(srcoffset);
 
425
            DECODE_PRINTF("\n");
 
426
            TRACE_AND_STEP();
 
427
            *destreg = add_word(*destreg, srcval);
 
428
        }
 
429
        break;
 
430
    case 3:                     /* register to register */
 
431
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
432
            u32 *destreg,*srcreg;
 
433
 
 
434
            destreg = DECODE_RM_LONG_REGISTER(rh);
 
435
            DECODE_PRINTF(",");
 
436
            srcreg = DECODE_RM_LONG_REGISTER(rl);
 
437
            DECODE_PRINTF("\n");
 
438
            TRACE_AND_STEP();
 
439
            *destreg = add_long(*destreg, *srcreg);
 
440
        } else {
 
441
            u16 *destreg,*srcreg;
 
442
 
 
443
            destreg = DECODE_RM_WORD_REGISTER(rh);
 
444
            DECODE_PRINTF(",");
 
445
            srcreg = DECODE_RM_WORD_REGISTER(rl);
 
446
            DECODE_PRINTF("\n");
 
447
            TRACE_AND_STEP();
 
448
            *destreg = add_word(*destreg, *srcreg);
 
449
        }
 
450
        break;
 
451
    }
 
452
    DECODE_CLEAR_SEGOVR();
 
453
    END_OF_INSTR();
 
454
}
 
455
 
 
456
/****************************************************************************
 
457
REMARKS:
 
458
Handles opcode 0x04
 
459
****************************************************************************/
 
460
static void x86emuOp_add_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
 
461
{
 
462
    u8 srcval;
 
463
 
 
464
    START_OF_INSTR();
 
465
    DECODE_PRINTF("ADD\tAL,");
 
466
    srcval = fetch_byte_imm();
 
467
    DECODE_PRINTF2("%x\n", srcval);
 
468
    TRACE_AND_STEP();
 
469
    M.x86.R_AL = add_byte(M.x86.R_AL, srcval);
 
470
    DECODE_CLEAR_SEGOVR();
 
471
    END_OF_INSTR();
 
472
}
 
473
 
 
474
/****************************************************************************
 
475
REMARKS:
 
476
Handles opcode 0x05
 
477
****************************************************************************/
 
478
static void x86emuOp_add_word_AX_IMM(u8 X86EMU_UNUSED(op1))
 
479
{
 
480
    u32 srcval;
 
481
 
 
482
    START_OF_INSTR();
 
483
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
484
        DECODE_PRINTF("ADD\tEAX,");
 
485
        srcval = fetch_long_imm();
 
486
    } else {
 
487
        DECODE_PRINTF("ADD\tAX,");
 
488
        srcval = fetch_word_imm();
 
489
    }
 
490
    DECODE_PRINTF2("%x\n", srcval);
 
491
    TRACE_AND_STEP();
 
492
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
493
        M.x86.R_EAX = add_long(M.x86.R_EAX, srcval);
 
494
    } else {
 
495
        M.x86.R_AX = add_word(M.x86.R_AX, (u16)srcval);
 
496
    }
 
497
    DECODE_CLEAR_SEGOVR();
 
498
    END_OF_INSTR();
 
499
}
 
500
 
 
501
/****************************************************************************
 
502
REMARKS:
 
503
Handles opcode 0x06
 
504
****************************************************************************/
 
505
static void x86emuOp_push_ES(u8 X86EMU_UNUSED(op1))
 
506
{
 
507
    START_OF_INSTR();
 
508
    DECODE_PRINTF("PUSH\tES\n");
 
509
    TRACE_AND_STEP();
 
510
    push_word(M.x86.R_ES);
 
511
    DECODE_CLEAR_SEGOVR();
 
512
    END_OF_INSTR();
 
513
}
 
514
 
 
515
/****************************************************************************
 
516
REMARKS:
 
517
Handles opcode 0x07
 
518
****************************************************************************/
 
519
static void x86emuOp_pop_ES(u8 X86EMU_UNUSED(op1))
 
520
{
 
521
    START_OF_INSTR();
 
522
    DECODE_PRINTF("POP\tES\n");
 
523
    TRACE_AND_STEP();
 
524
    M.x86.R_ES = pop_word();
 
525
    DECODE_CLEAR_SEGOVR();
 
526
    END_OF_INSTR();
 
527
}
 
528
 
 
529
/****************************************************************************
 
530
REMARKS:
 
531
Handles opcode 0x08
 
532
****************************************************************************/
 
533
static void x86emuOp_or_byte_RM_R(u8 X86EMU_UNUSED(op1))
 
534
{
 
535
    int mod, rl, rh;
 
536
    u8 *destreg, *srcreg;
 
537
    uint destoffset;
 
538
    u8 destval;
 
539
 
 
540
    START_OF_INSTR();
 
541
    DECODE_PRINTF("OR\t");
 
542
    FETCH_DECODE_MODRM(mod, rh, rl);
 
543
    switch (mod) {
 
544
    case 0:
 
545
        destoffset = decode_rm00_address(rl);
 
546
        DECODE_PRINTF(",");
 
547
        destval = fetch_data_byte(destoffset);
 
548
        srcreg = DECODE_RM_BYTE_REGISTER(rh);
 
549
        DECODE_PRINTF("\n");
 
550
        TRACE_AND_STEP();
 
551
        destval = or_byte(destval, *srcreg);
 
552
        store_data_byte(destoffset, destval);
 
553
        break;
 
554
    case 1:
 
555
        destoffset = decode_rm01_address(rl);
 
556
        DECODE_PRINTF(",");
 
557
        destval = fetch_data_byte(destoffset);
 
558
        srcreg = DECODE_RM_BYTE_REGISTER(rh);
 
559
        DECODE_PRINTF("\n");
 
560
        TRACE_AND_STEP();
 
561
        destval = or_byte(destval, *srcreg);
 
562
        store_data_byte(destoffset, destval);
 
563
        break;
 
564
    case 2:
 
565
        destoffset = decode_rm10_address(rl);
 
566
        DECODE_PRINTF(",");
 
567
        destval = fetch_data_byte(destoffset);
 
568
        srcreg = DECODE_RM_BYTE_REGISTER(rh);
 
569
        DECODE_PRINTF("\n");
 
570
        TRACE_AND_STEP();
 
571
        destval = or_byte(destval, *srcreg);
 
572
        store_data_byte(destoffset, destval);
 
573
        break;
 
574
    case 3:                     /* register to register */
 
575
        destreg = DECODE_RM_BYTE_REGISTER(rl);
 
576
        DECODE_PRINTF(",");
 
577
        srcreg = DECODE_RM_BYTE_REGISTER(rh);
 
578
        DECODE_PRINTF("\n");
 
579
        TRACE_AND_STEP();
 
580
        *destreg = or_byte(*destreg, *srcreg);
 
581
        break;
 
582
    }
 
583
    DECODE_CLEAR_SEGOVR();
 
584
    END_OF_INSTR();
 
585
}
 
586
 
 
587
/****************************************************************************
 
588
REMARKS:
 
589
Handles opcode 0x09
 
590
****************************************************************************/
 
591
static void x86emuOp_or_word_RM_R(u8 X86EMU_UNUSED(op1))
 
592
{
 
593
    int mod, rl, rh;
 
594
    uint destoffset;
 
595
 
 
596
    START_OF_INSTR();
 
597
    DECODE_PRINTF("OR\t");
 
598
    FETCH_DECODE_MODRM(mod, rh, rl);
 
599
    switch (mod) {
 
600
    case 0:
 
601
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
602
            u32 destval;
 
603
            u32 *srcreg;
 
604
 
 
605
            destoffset = decode_rm00_address(rl);
 
606
            DECODE_PRINTF(",");
 
607
            destval = fetch_data_long(destoffset);
 
608
            srcreg = DECODE_RM_LONG_REGISTER(rh);
 
609
            DECODE_PRINTF("\n");
 
610
            TRACE_AND_STEP();
 
611
            destval = or_long(destval, *srcreg);
 
612
            store_data_long(destoffset, destval);
 
613
        } else {
 
614
            u16 destval;
 
615
            u16 *srcreg;
 
616
 
 
617
            destoffset = decode_rm00_address(rl);
 
618
            DECODE_PRINTF(",");
 
619
            destval = fetch_data_word(destoffset);
 
620
            srcreg = DECODE_RM_WORD_REGISTER(rh);
 
621
            DECODE_PRINTF("\n");
 
622
            TRACE_AND_STEP();
 
623
            destval = or_word(destval, *srcreg);
 
624
            store_data_word(destoffset, destval);
 
625
        }
 
626
        break;
 
627
    case 1:
 
628
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
629
            u32 destval;
 
630
            u32 *srcreg;
 
631
 
 
632
            destoffset = decode_rm01_address(rl);
 
633
            DECODE_PRINTF(",");
 
634
            destval = fetch_data_long(destoffset);
 
635
            srcreg = DECODE_RM_LONG_REGISTER(rh);
 
636
            DECODE_PRINTF("\n");
 
637
            TRACE_AND_STEP();
 
638
            destval = or_long(destval, *srcreg);
 
639
            store_data_long(destoffset, destval);
 
640
        } else {
 
641
            u16 destval;
 
642
            u16 *srcreg;
 
643
 
 
644
            destoffset = decode_rm01_address(rl);
 
645
            DECODE_PRINTF(",");
 
646
            destval = fetch_data_word(destoffset);
 
647
            srcreg = DECODE_RM_WORD_REGISTER(rh);
 
648
            DECODE_PRINTF("\n");
 
649
            TRACE_AND_STEP();
 
650
            destval = or_word(destval, *srcreg);
 
651
            store_data_word(destoffset, destval);
 
652
        }
 
653
        break;
 
654
    case 2:
 
655
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
656
            u32 destval;
 
657
            u32 *srcreg;
 
658
 
 
659
            destoffset = decode_rm10_address(rl);
 
660
            DECODE_PRINTF(",");
 
661
            destval = fetch_data_long(destoffset);
 
662
            srcreg = DECODE_RM_LONG_REGISTER(rh);
 
663
            DECODE_PRINTF("\n");
 
664
            TRACE_AND_STEP();
 
665
            destval = or_long(destval, *srcreg);
 
666
            store_data_long(destoffset, destval);
 
667
        } else {
 
668
            u16 destval;
 
669
            u16 *srcreg;
 
670
 
 
671
            destoffset = decode_rm10_address(rl);
 
672
            DECODE_PRINTF(",");
 
673
            destval = fetch_data_word(destoffset);
 
674
            srcreg = DECODE_RM_WORD_REGISTER(rh);
 
675
            DECODE_PRINTF("\n");
 
676
            TRACE_AND_STEP();
 
677
            destval = or_word(destval, *srcreg);
 
678
            store_data_word(destoffset, destval);
 
679
        }
 
680
        break;
 
681
    case 3:                     /* register to register */
 
682
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
683
            u32 *destreg,*srcreg;
 
684
 
 
685
            destreg = DECODE_RM_LONG_REGISTER(rl);
 
686
            DECODE_PRINTF(",");
 
687
            srcreg = DECODE_RM_LONG_REGISTER(rh);
 
688
            DECODE_PRINTF("\n");
 
689
            TRACE_AND_STEP();
 
690
            *destreg = or_long(*destreg, *srcreg);
 
691
        } else {
 
692
            u16 *destreg,*srcreg;
 
693
 
 
694
            destreg = DECODE_RM_WORD_REGISTER(rl);
 
695
            DECODE_PRINTF(",");
 
696
            srcreg = DECODE_RM_WORD_REGISTER(rh);
 
697
            DECODE_PRINTF("\n");
 
698
            TRACE_AND_STEP();
 
699
            *destreg = or_word(*destreg, *srcreg);
 
700
        }
 
701
        break;
 
702
    }
 
703
    DECODE_CLEAR_SEGOVR();
 
704
    END_OF_INSTR();
 
705
}
 
706
 
 
707
/****************************************************************************
 
708
REMARKS:
 
709
Handles opcode 0x0a
 
710
****************************************************************************/
 
711
static void x86emuOp_or_byte_R_RM(u8 X86EMU_UNUSED(op1))
 
712
{
 
713
    int mod, rl, rh;
 
714
    u8 *destreg, *srcreg;
 
715
    uint srcoffset;
 
716
    u8 srcval;
 
717
 
 
718
    START_OF_INSTR();
 
719
    DECODE_PRINTF("OR\t");
 
720
    FETCH_DECODE_MODRM(mod, rh, rl);
 
721
    switch (mod) {
 
722
    case 0:
 
723
        destreg = DECODE_RM_BYTE_REGISTER(rh);
 
724
        DECODE_PRINTF(",");
 
725
        srcoffset = decode_rm00_address(rl);
 
726
        srcval = fetch_data_byte(srcoffset);
 
727
        DECODE_PRINTF("\n");
 
728
        TRACE_AND_STEP();
 
729
        *destreg = or_byte(*destreg, srcval);
 
730
        break;
 
731
    case 1:
 
732
        destreg = DECODE_RM_BYTE_REGISTER(rh);
 
733
        DECODE_PRINTF(",");
 
734
        srcoffset = decode_rm01_address(rl);
 
735
        srcval = fetch_data_byte(srcoffset);
 
736
        DECODE_PRINTF("\n");
 
737
        TRACE_AND_STEP();
 
738
        *destreg = or_byte(*destreg, srcval);
 
739
        break;
 
740
    case 2:
 
741
        destreg = DECODE_RM_BYTE_REGISTER(rh);
 
742
        DECODE_PRINTF(",");
 
743
        srcoffset = decode_rm10_address(rl);
 
744
        srcval = fetch_data_byte(srcoffset);
 
745
        DECODE_PRINTF("\n");
 
746
        TRACE_AND_STEP();
 
747
        *destreg = or_byte(*destreg, srcval);
 
748
        break;
 
749
    case 3:                     /* register to register */
 
750
        destreg = DECODE_RM_BYTE_REGISTER(rh);
 
751
        DECODE_PRINTF(",");
 
752
        srcreg = DECODE_RM_BYTE_REGISTER(rl);
 
753
        DECODE_PRINTF("\n");
 
754
        TRACE_AND_STEP();
 
755
        *destreg = or_byte(*destreg, *srcreg);
 
756
        break;
 
757
    }
 
758
    DECODE_CLEAR_SEGOVR();
 
759
    END_OF_INSTR();
 
760
}
 
761
 
 
762
/****************************************************************************
 
763
REMARKS:
 
764
Handles opcode 0x0b
 
765
****************************************************************************/
 
766
static void x86emuOp_or_word_R_RM(u8 X86EMU_UNUSED(op1))
 
767
{
 
768
    int mod, rl, rh;
 
769
    uint srcoffset;
 
770
 
 
771
    START_OF_INSTR();
 
772
    DECODE_PRINTF("OR\t");
 
773
    FETCH_DECODE_MODRM(mod, rh, rl);
 
774
    switch (mod) {
 
775
    case 0:
 
776
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
777
            u32 *destreg;
 
778
            u32 srcval;
 
779
 
 
780
            destreg = DECODE_RM_LONG_REGISTER(rh);
 
781
            DECODE_PRINTF(",");
 
782
            srcoffset = decode_rm00_address(rl);
 
783
            srcval = fetch_data_long(srcoffset);
 
784
            DECODE_PRINTF("\n");
 
785
            TRACE_AND_STEP();
 
786
            *destreg = or_long(*destreg, srcval);
 
787
        } else {
 
788
            u16 *destreg;
 
789
            u16 srcval;
 
790
 
 
791
            destreg = DECODE_RM_WORD_REGISTER(rh);
 
792
            DECODE_PRINTF(",");
 
793
            srcoffset = decode_rm00_address(rl);
 
794
            srcval = fetch_data_word(srcoffset);
 
795
            DECODE_PRINTF("\n");
 
796
            TRACE_AND_STEP();
 
797
            *destreg = or_word(*destreg, srcval);
 
798
        }
 
799
        break;
 
800
    case 1:
 
801
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
802
            u32 *destreg;
 
803
            u32 srcval;
 
804
 
 
805
            destreg = DECODE_RM_LONG_REGISTER(rh);
 
806
            DECODE_PRINTF(",");
 
807
            srcoffset = decode_rm01_address(rl);
 
808
            srcval = fetch_data_long(srcoffset);
 
809
            DECODE_PRINTF("\n");
 
810
            TRACE_AND_STEP();
 
811
            *destreg = or_long(*destreg, srcval);
 
812
        } else {
 
813
            u16 *destreg;
 
814
            u16 srcval;
 
815
 
 
816
            destreg = DECODE_RM_WORD_REGISTER(rh);
 
817
            DECODE_PRINTF(",");
 
818
            srcoffset = decode_rm01_address(rl);
 
819
            srcval = fetch_data_word(srcoffset);
 
820
            DECODE_PRINTF("\n");
 
821
            TRACE_AND_STEP();
 
822
            *destreg = or_word(*destreg, srcval);
 
823
        }
 
824
        break;
 
825
    case 2:
 
826
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
827
            u32 *destreg;
 
828
            u32 srcval;
 
829
 
 
830
            destreg = DECODE_RM_LONG_REGISTER(rh);
 
831
            DECODE_PRINTF(",");
 
832
            srcoffset = decode_rm10_address(rl);
 
833
            srcval = fetch_data_long(srcoffset);
 
834
            DECODE_PRINTF("\n");
 
835
            TRACE_AND_STEP();
 
836
            *destreg = or_long(*destreg, srcval);
 
837
        } else {
 
838
            u16 *destreg;
 
839
            u16 srcval;
 
840
 
 
841
            destreg = DECODE_RM_WORD_REGISTER(rh);
 
842
            DECODE_PRINTF(",");
 
843
            srcoffset = decode_rm10_address(rl);
 
844
            srcval = fetch_data_word(srcoffset);
 
845
            DECODE_PRINTF("\n");
 
846
            TRACE_AND_STEP();
 
847
            *destreg = or_word(*destreg, srcval);
 
848
        }
 
849
        break;
 
850
    case 3:                     /* register to register */
 
851
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
852
            u32 *destreg,*srcreg;
 
853
 
 
854
            destreg = DECODE_RM_LONG_REGISTER(rh);
 
855
            DECODE_PRINTF(",");
 
856
            srcreg = DECODE_RM_LONG_REGISTER(rl);
 
857
            DECODE_PRINTF("\n");
 
858
            TRACE_AND_STEP();
 
859
            *destreg = or_long(*destreg, *srcreg);
 
860
        } else {
 
861
            u16 *destreg,*srcreg;
 
862
 
 
863
            destreg = DECODE_RM_WORD_REGISTER(rh);
 
864
            DECODE_PRINTF(",");
 
865
            srcreg = DECODE_RM_WORD_REGISTER(rl);
 
866
            DECODE_PRINTF("\n");
 
867
            TRACE_AND_STEP();
 
868
            *destreg = or_word(*destreg, *srcreg);
 
869
        }
 
870
        break;
 
871
    }
 
872
    DECODE_CLEAR_SEGOVR();
 
873
    END_OF_INSTR();
 
874
}
 
875
 
 
876
/****************************************************************************
 
877
REMARKS:
 
878
Handles opcode 0x0c
 
879
****************************************************************************/
 
880
static void x86emuOp_or_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
 
881
{
 
882
    u8 srcval;
 
883
 
 
884
    START_OF_INSTR();
 
885
    DECODE_PRINTF("OR\tAL,");
 
886
    srcval = fetch_byte_imm();
 
887
    DECODE_PRINTF2("%x\n", srcval);
 
888
    TRACE_AND_STEP();
 
889
    M.x86.R_AL = or_byte(M.x86.R_AL, srcval);
 
890
    DECODE_CLEAR_SEGOVR();
 
891
    END_OF_INSTR();
 
892
}
 
893
 
 
894
/****************************************************************************
 
895
REMARKS:
 
896
Handles opcode 0x0d
 
897
****************************************************************************/
 
898
static void x86emuOp_or_word_AX_IMM(u8 X86EMU_UNUSED(op1))
 
899
{
 
900
    u32 srcval;
 
901
 
 
902
    START_OF_INSTR();
 
903
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
904
        DECODE_PRINTF("OR\tEAX,");
 
905
        srcval = fetch_long_imm();
 
906
    } else {
 
907
        DECODE_PRINTF("OR\tAX,");
 
908
        srcval = fetch_word_imm();
 
909
    }
 
910
    DECODE_PRINTF2("%x\n", srcval);
 
911
    TRACE_AND_STEP();
 
912
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
913
        M.x86.R_EAX = or_long(M.x86.R_EAX, srcval);
 
914
    } else {
 
915
        M.x86.R_AX = or_word(M.x86.R_AX, (u16)srcval);
 
916
    }
 
917
    DECODE_CLEAR_SEGOVR();
 
918
    END_OF_INSTR();
 
919
}
 
920
 
 
921
/****************************************************************************
 
922
REMARKS:
 
923
Handles opcode 0x0e
 
924
****************************************************************************/
 
925
static void x86emuOp_push_CS(u8 X86EMU_UNUSED(op1))
 
926
{
 
927
    START_OF_INSTR();
 
928
    DECODE_PRINTF("PUSH\tCS\n");
 
929
    TRACE_AND_STEP();
 
930
    push_word(M.x86.R_CS);
 
931
    DECODE_CLEAR_SEGOVR();
 
932
    END_OF_INSTR();
 
933
}
 
934
 
 
935
/****************************************************************************
 
936
REMARKS:
 
937
Handles opcode 0x0f. Escape for two-byte opcode (286 or better)
 
938
****************************************************************************/
 
939
static void x86emuOp_two_byte(u8 X86EMU_UNUSED(op1))
 
940
{
 
941
    u8 op2 = (*sys_rdb)(((u32)M.x86.R_CS << 4) + (M.x86.R_IP++));
 
942
    INC_DECODED_INST_LEN(1);
 
943
    (*x86emu_optab2[op2])(op2);
 
944
}
 
945
 
 
946
/****************************************************************************
 
947
REMARKS:
 
948
Handles opcode 0x10
 
949
****************************************************************************/
 
950
static void x86emuOp_adc_byte_RM_R(u8 X86EMU_UNUSED(op1))
 
951
{
 
952
    int mod, rl, rh;
 
953
    u8 *destreg, *srcreg;
 
954
    uint destoffset;
 
955
    u8 destval;
 
956
 
 
957
    START_OF_INSTR();
 
958
    DECODE_PRINTF("ADC\t");
 
959
    FETCH_DECODE_MODRM(mod, rh, rl);
 
960
    switch (mod) {
 
961
    case 0:
 
962
        destoffset = decode_rm00_address(rl);
 
963
        DECODE_PRINTF(",");
 
964
        destval = fetch_data_byte(destoffset);
 
965
        srcreg = DECODE_RM_BYTE_REGISTER(rh);
 
966
        DECODE_PRINTF("\n");
 
967
        TRACE_AND_STEP();
 
968
        destval = adc_byte(destval, *srcreg);
 
969
        store_data_byte(destoffset, destval);
 
970
        break;
 
971
    case 1:
 
972
        destoffset = decode_rm01_address(rl);
 
973
        DECODE_PRINTF(",");
 
974
        destval = fetch_data_byte(destoffset);
 
975
        srcreg = DECODE_RM_BYTE_REGISTER(rh);
 
976
        DECODE_PRINTF("\n");
 
977
        TRACE_AND_STEP();
 
978
        destval = adc_byte(destval, *srcreg);
 
979
        store_data_byte(destoffset, destval);
 
980
        break;
 
981
    case 2:
 
982
        destoffset = decode_rm10_address(rl);
 
983
        DECODE_PRINTF(",");
 
984
        destval = fetch_data_byte(destoffset);
 
985
        srcreg = DECODE_RM_BYTE_REGISTER(rh);
 
986
        DECODE_PRINTF("\n");
 
987
        TRACE_AND_STEP();
 
988
        destval = adc_byte(destval, *srcreg);
 
989
        store_data_byte(destoffset, destval);
 
990
        break;
 
991
    case 3:                     /* register to register */
 
992
        destreg = DECODE_RM_BYTE_REGISTER(rl);
 
993
        DECODE_PRINTF(",");
 
994
        srcreg = DECODE_RM_BYTE_REGISTER(rh);
 
995
        DECODE_PRINTF("\n");
 
996
        TRACE_AND_STEP();
 
997
        *destreg = adc_byte(*destreg, *srcreg);
 
998
        break;
 
999
    }
 
1000
    DECODE_CLEAR_SEGOVR();
 
1001
    END_OF_INSTR();
 
1002
}
 
1003
 
 
1004
/****************************************************************************
 
1005
REMARKS:
 
1006
Handles opcode 0x11
 
1007
****************************************************************************/
 
1008
static void x86emuOp_adc_word_RM_R(u8 X86EMU_UNUSED(op1))
 
1009
{
 
1010
    int mod, rl, rh;
 
1011
    uint destoffset;
 
1012
 
 
1013
    START_OF_INSTR();
 
1014
    DECODE_PRINTF("ADC\t");
 
1015
    FETCH_DECODE_MODRM(mod, rh, rl);
 
1016
    switch (mod) {
 
1017
    case 0:
 
1018
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
1019
            u32 destval;
 
1020
            u32 *srcreg;
 
1021
 
 
1022
            destoffset = decode_rm00_address(rl);
 
1023
            DECODE_PRINTF(",");
 
1024
            destval = fetch_data_long(destoffset);
 
1025
            srcreg = DECODE_RM_LONG_REGISTER(rh);
 
1026
            DECODE_PRINTF("\n");
 
1027
            TRACE_AND_STEP();
 
1028
            destval = adc_long(destval, *srcreg);
 
1029
            store_data_long(destoffset, destval);
 
1030
        } else {
 
1031
            u16 destval;
 
1032
            u16 *srcreg;
 
1033
 
 
1034
            destoffset = decode_rm00_address(rl);
 
1035
            DECODE_PRINTF(",");
 
1036
            destval = fetch_data_word(destoffset);
 
1037
            srcreg = DECODE_RM_WORD_REGISTER(rh);
 
1038
            DECODE_PRINTF("\n");
 
1039
            TRACE_AND_STEP();
 
1040
            destval = adc_word(destval, *srcreg);
 
1041
            store_data_word(destoffset, destval);
 
1042
        }
 
1043
        break;
 
1044
    case 1:
 
1045
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
1046
            u32 destval;
 
1047
            u32 *srcreg;
 
1048
 
 
1049
            destoffset = decode_rm01_address(rl);
 
1050
            DECODE_PRINTF(",");
 
1051
            destval = fetch_data_long(destoffset);
 
1052
            srcreg = DECODE_RM_LONG_REGISTER(rh);
 
1053
            DECODE_PRINTF("\n");
 
1054
            TRACE_AND_STEP();
 
1055
            destval = adc_long(destval, *srcreg);
 
1056
            store_data_long(destoffset, destval);
 
1057
        } else {
 
1058
            u16 destval;
 
1059
            u16 *srcreg;
 
1060
 
 
1061
            destoffset = decode_rm01_address(rl);
 
1062
            DECODE_PRINTF(",");
 
1063
            destval = fetch_data_word(destoffset);
 
1064
            srcreg = DECODE_RM_WORD_REGISTER(rh);
 
1065
            DECODE_PRINTF("\n");
 
1066
            TRACE_AND_STEP();
 
1067
            destval = adc_word(destval, *srcreg);
 
1068
            store_data_word(destoffset, destval);
 
1069
        }
 
1070
        break;
 
1071
    case 2:
 
1072
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
1073
            u32 destval;
 
1074
            u32 *srcreg;
 
1075
 
 
1076
            destoffset = decode_rm10_address(rl);
 
1077
            DECODE_PRINTF(",");
 
1078
            destval = fetch_data_long(destoffset);
 
1079
            srcreg = DECODE_RM_LONG_REGISTER(rh);
 
1080
            DECODE_PRINTF("\n");
 
1081
            TRACE_AND_STEP();
 
1082
            destval = adc_long(destval, *srcreg);
 
1083
            store_data_long(destoffset, destval);
 
1084
        } else {
 
1085
            u16 destval;
 
1086
            u16 *srcreg;
 
1087
 
 
1088
            destoffset = decode_rm10_address(rl);
 
1089
            DECODE_PRINTF(",");
 
1090
            destval = fetch_data_word(destoffset);
 
1091
            srcreg = DECODE_RM_WORD_REGISTER(rh);
 
1092
            DECODE_PRINTF("\n");
 
1093
            TRACE_AND_STEP();
 
1094
            destval = adc_word(destval, *srcreg);
 
1095
            store_data_word(destoffset, destval);
 
1096
        }
 
1097
        break;
 
1098
    case 3:                     /* register to register */
 
1099
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
1100
            u32 *destreg,*srcreg;
 
1101
 
 
1102
            destreg = DECODE_RM_LONG_REGISTER(rl);
 
1103
            DECODE_PRINTF(",");
 
1104
            srcreg = DECODE_RM_LONG_REGISTER(rh);
 
1105
            DECODE_PRINTF("\n");
 
1106
            TRACE_AND_STEP();
 
1107
            *destreg = adc_long(*destreg, *srcreg);
 
1108
        } else {
 
1109
            u16 *destreg,*srcreg;
 
1110
 
 
1111
            destreg = DECODE_RM_WORD_REGISTER(rl);
 
1112
            DECODE_PRINTF(",");
 
1113
            srcreg = DECODE_RM_WORD_REGISTER(rh);
 
1114
            DECODE_PRINTF("\n");
 
1115
            TRACE_AND_STEP();
 
1116
            *destreg = adc_word(*destreg, *srcreg);
 
1117
        }
 
1118
        break;
 
1119
    }
 
1120
    DECODE_CLEAR_SEGOVR();
 
1121
    END_OF_INSTR();
 
1122
}
 
1123
 
 
1124
/****************************************************************************
 
1125
REMARKS:
 
1126
Handles opcode 0x12
 
1127
****************************************************************************/
 
1128
static void x86emuOp_adc_byte_R_RM(u8 X86EMU_UNUSED(op1))
 
1129
{
 
1130
    int mod, rl, rh;
 
1131
    u8 *destreg, *srcreg;
 
1132
    uint srcoffset;
 
1133
    u8 srcval;
 
1134
 
 
1135
    START_OF_INSTR();
 
1136
    DECODE_PRINTF("ADC\t");
 
1137
    FETCH_DECODE_MODRM(mod, rh, rl);
 
1138
    switch (mod) {
 
1139
    case 0:
 
1140
        destreg = DECODE_RM_BYTE_REGISTER(rh);
 
1141
        DECODE_PRINTF(",");
 
1142
        srcoffset = decode_rm00_address(rl);
 
1143
        srcval = fetch_data_byte(srcoffset);
 
1144
        DECODE_PRINTF("\n");
 
1145
        TRACE_AND_STEP();
 
1146
        *destreg = adc_byte(*destreg, srcval);
 
1147
        break;
 
1148
    case 1:
 
1149
        destreg = DECODE_RM_BYTE_REGISTER(rh);
 
1150
        DECODE_PRINTF(",");
 
1151
        srcoffset = decode_rm01_address(rl);
 
1152
        srcval = fetch_data_byte(srcoffset);
 
1153
        DECODE_PRINTF("\n");
 
1154
        TRACE_AND_STEP();
 
1155
        *destreg = adc_byte(*destreg, srcval);
 
1156
        break;
 
1157
    case 2:
 
1158
        destreg = DECODE_RM_BYTE_REGISTER(rh);
 
1159
        DECODE_PRINTF(",");
 
1160
        srcoffset = decode_rm10_address(rl);
 
1161
        srcval = fetch_data_byte(srcoffset);
 
1162
        DECODE_PRINTF("\n");
 
1163
        TRACE_AND_STEP();
 
1164
        *destreg = adc_byte(*destreg, srcval);
 
1165
        break;
 
1166
    case 3:                     /* register to register */
 
1167
        destreg = DECODE_RM_BYTE_REGISTER(rh);
 
1168
        DECODE_PRINTF(",");
 
1169
        srcreg = DECODE_RM_BYTE_REGISTER(rl);
 
1170
        DECODE_PRINTF("\n");
 
1171
        TRACE_AND_STEP();
 
1172
        *destreg = adc_byte(*destreg, *srcreg);
 
1173
        break;
 
1174
    }
 
1175
    DECODE_CLEAR_SEGOVR();
 
1176
    END_OF_INSTR();
 
1177
}
 
1178
 
 
1179
/****************************************************************************
 
1180
REMARKS:
 
1181
Handles opcode 0x13
 
1182
****************************************************************************/
 
1183
static void x86emuOp_adc_word_R_RM(u8 X86EMU_UNUSED(op1))
 
1184
{
 
1185
    int mod, rl, rh;
 
1186
    uint srcoffset;
 
1187
 
 
1188
    START_OF_INSTR();
 
1189
    DECODE_PRINTF("ADC\t");
 
1190
    FETCH_DECODE_MODRM(mod, rh, rl);
 
1191
    switch (mod) {
 
1192
    case 0:
 
1193
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
1194
            u32 *destreg;
 
1195
            u32 srcval;
 
1196
 
 
1197
            destreg = DECODE_RM_LONG_REGISTER(rh);
 
1198
            DECODE_PRINTF(",");
 
1199
            srcoffset = decode_rm00_address(rl);
 
1200
            srcval = fetch_data_long(srcoffset);
 
1201
            DECODE_PRINTF("\n");
 
1202
            TRACE_AND_STEP();
 
1203
            *destreg = adc_long(*destreg, srcval);
 
1204
        } else {
 
1205
            u16 *destreg;
 
1206
            u16 srcval;
 
1207
 
 
1208
            destreg = DECODE_RM_WORD_REGISTER(rh);
 
1209
            DECODE_PRINTF(",");
 
1210
            srcoffset = decode_rm00_address(rl);
 
1211
            srcval = fetch_data_word(srcoffset);
 
1212
            DECODE_PRINTF("\n");
 
1213
            TRACE_AND_STEP();
 
1214
            *destreg = adc_word(*destreg, srcval);
 
1215
        }
 
1216
        break;
 
1217
    case 1:
 
1218
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
1219
            u32 *destreg;
 
1220
            u32 srcval;
 
1221
 
 
1222
            destreg = DECODE_RM_LONG_REGISTER(rh);
 
1223
            DECODE_PRINTF(",");
 
1224
            srcoffset = decode_rm01_address(rl);
 
1225
            srcval = fetch_data_long(srcoffset);
 
1226
            DECODE_PRINTF("\n");
 
1227
            TRACE_AND_STEP();
 
1228
            *destreg = adc_long(*destreg, srcval);
 
1229
        } else {
 
1230
            u16 *destreg;
 
1231
            u16 srcval;
 
1232
 
 
1233
            destreg = DECODE_RM_WORD_REGISTER(rh);
 
1234
            DECODE_PRINTF(",");
 
1235
            srcoffset = decode_rm01_address(rl);
 
1236
            srcval = fetch_data_word(srcoffset);
 
1237
            DECODE_PRINTF("\n");
 
1238
            TRACE_AND_STEP();
 
1239
            *destreg = adc_word(*destreg, srcval);
 
1240
        }
 
1241
        break;
 
1242
    case 2:
 
1243
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
1244
            u32 *destreg;
 
1245
            u32 srcval;
 
1246
 
 
1247
            destreg = DECODE_RM_LONG_REGISTER(rh);
 
1248
            DECODE_PRINTF(",");
 
1249
            srcoffset = decode_rm10_address(rl);
 
1250
            srcval = fetch_data_long(srcoffset);
 
1251
            DECODE_PRINTF("\n");
 
1252
            TRACE_AND_STEP();
 
1253
            *destreg = adc_long(*destreg, srcval);
 
1254
        } else {
 
1255
            u16 *destreg;
 
1256
            u16 srcval;
 
1257
 
 
1258
            destreg = DECODE_RM_WORD_REGISTER(rh);
 
1259
            DECODE_PRINTF(",");
 
1260
            srcoffset = decode_rm10_address(rl);
 
1261
            srcval = fetch_data_word(srcoffset);
 
1262
            DECODE_PRINTF("\n");
 
1263
            TRACE_AND_STEP();
 
1264
            *destreg = adc_word(*destreg, srcval);
 
1265
        }
 
1266
        break;
 
1267
    case 3:                     /* register to register */
 
1268
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
1269
            u32 *destreg,*srcreg;
 
1270
 
 
1271
            destreg = DECODE_RM_LONG_REGISTER(rh);
 
1272
            DECODE_PRINTF(",");
 
1273
            srcreg = DECODE_RM_LONG_REGISTER(rl);
 
1274
            DECODE_PRINTF("\n");
 
1275
            TRACE_AND_STEP();
 
1276
            *destreg = adc_long(*destreg, *srcreg);
 
1277
        } else {
 
1278
            u16 *destreg,*srcreg;
 
1279
 
 
1280
            destreg = DECODE_RM_WORD_REGISTER(rh);
 
1281
            DECODE_PRINTF(",");
 
1282
            srcreg = DECODE_RM_WORD_REGISTER(rl);
 
1283
            DECODE_PRINTF("\n");
 
1284
            TRACE_AND_STEP();
 
1285
            *destreg = adc_word(*destreg, *srcreg);
 
1286
        }
 
1287
        break;
 
1288
    }
 
1289
    DECODE_CLEAR_SEGOVR();
 
1290
    END_OF_INSTR();
 
1291
}
 
1292
 
 
1293
/****************************************************************************
 
1294
REMARKS:
 
1295
Handles opcode 0x14
 
1296
****************************************************************************/
 
1297
static void x86emuOp_adc_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
 
1298
{
 
1299
    u8 srcval;
 
1300
 
 
1301
    START_OF_INSTR();
 
1302
    DECODE_PRINTF("ADC\tAL,");
 
1303
    srcval = fetch_byte_imm();
 
1304
    DECODE_PRINTF2("%x\n", srcval);
 
1305
    TRACE_AND_STEP();
 
1306
    M.x86.R_AL = adc_byte(M.x86.R_AL, srcval);
 
1307
    DECODE_CLEAR_SEGOVR();
 
1308
    END_OF_INSTR();
 
1309
}
 
1310
 
 
1311
/****************************************************************************
 
1312
REMARKS:
 
1313
Handles opcode 0x15
 
1314
****************************************************************************/
 
1315
static void x86emuOp_adc_word_AX_IMM(u8 X86EMU_UNUSED(op1))
 
1316
{
 
1317
    u32 srcval;
 
1318
 
 
1319
    START_OF_INSTR();
 
1320
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
1321
        DECODE_PRINTF("ADC\tEAX,");
 
1322
        srcval = fetch_long_imm();
 
1323
    } else {
 
1324
        DECODE_PRINTF("ADC\tAX,");
 
1325
        srcval = fetch_word_imm();
 
1326
    }
 
1327
    DECODE_PRINTF2("%x\n", srcval);
 
1328
    TRACE_AND_STEP();
 
1329
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
1330
        M.x86.R_EAX = adc_long(M.x86.R_EAX, srcval);
 
1331
    } else {
 
1332
        M.x86.R_AX = adc_word(M.x86.R_AX, (u16)srcval);
 
1333
    }
 
1334
    DECODE_CLEAR_SEGOVR();
 
1335
    END_OF_INSTR();
 
1336
}
 
1337
 
 
1338
/****************************************************************************
 
1339
REMARKS:
 
1340
Handles opcode 0x16
 
1341
****************************************************************************/
 
1342
static void x86emuOp_push_SS(u8 X86EMU_UNUSED(op1))
 
1343
{
 
1344
    START_OF_INSTR();
 
1345
    DECODE_PRINTF("PUSH\tSS\n");
 
1346
    TRACE_AND_STEP();
 
1347
    push_word(M.x86.R_SS);
 
1348
    DECODE_CLEAR_SEGOVR();
 
1349
    END_OF_INSTR();
 
1350
}
 
1351
 
 
1352
/****************************************************************************
 
1353
REMARKS:
 
1354
Handles opcode 0x17
 
1355
****************************************************************************/
 
1356
static void x86emuOp_pop_SS(u8 X86EMU_UNUSED(op1))
 
1357
{
 
1358
    START_OF_INSTR();
 
1359
    DECODE_PRINTF("POP\tSS\n");
 
1360
    TRACE_AND_STEP();
 
1361
    M.x86.R_SS = pop_word();
 
1362
    DECODE_CLEAR_SEGOVR();
 
1363
    END_OF_INSTR();
 
1364
}
 
1365
 
 
1366
/****************************************************************************
 
1367
REMARKS:
 
1368
Handles opcode 0x18
 
1369
****************************************************************************/
 
1370
static void x86emuOp_sbb_byte_RM_R(u8 X86EMU_UNUSED(op1))
 
1371
{
 
1372
    int mod, rl, rh;
 
1373
    u8 *destreg, *srcreg;
 
1374
    uint destoffset;
 
1375
    u8 destval;
 
1376
 
 
1377
    START_OF_INSTR();
 
1378
    DECODE_PRINTF("SBB\t");
 
1379
    FETCH_DECODE_MODRM(mod, rh, rl);
 
1380
    switch (mod) {
 
1381
    case 0:
 
1382
        destoffset = decode_rm00_address(rl);
 
1383
        DECODE_PRINTF(",");
 
1384
        destval = fetch_data_byte(destoffset);
 
1385
        srcreg = DECODE_RM_BYTE_REGISTER(rh);
 
1386
        DECODE_PRINTF("\n");
 
1387
        TRACE_AND_STEP();
 
1388
        destval = sbb_byte(destval, *srcreg);
 
1389
        store_data_byte(destoffset, destval);
 
1390
        break;
 
1391
    case 1:
 
1392
        destoffset = decode_rm01_address(rl);
 
1393
        DECODE_PRINTF(",");
 
1394
        destval = fetch_data_byte(destoffset);
 
1395
        srcreg = DECODE_RM_BYTE_REGISTER(rh);
 
1396
        DECODE_PRINTF("\n");
 
1397
        TRACE_AND_STEP();
 
1398
        destval = sbb_byte(destval, *srcreg);
 
1399
        store_data_byte(destoffset, destval);
 
1400
        break;
 
1401
    case 2:
 
1402
        destoffset = decode_rm10_address(rl);
 
1403
        DECODE_PRINTF(",");
 
1404
        destval = fetch_data_byte(destoffset);
 
1405
        srcreg = DECODE_RM_BYTE_REGISTER(rh);
 
1406
        DECODE_PRINTF("\n");
 
1407
        TRACE_AND_STEP();
 
1408
        destval = sbb_byte(destval, *srcreg);
 
1409
        store_data_byte(destoffset, destval);
 
1410
        break;
 
1411
    case 3:                     /* register to register */
 
1412
        destreg = DECODE_RM_BYTE_REGISTER(rl);
 
1413
        DECODE_PRINTF(",");
 
1414
        srcreg = DECODE_RM_BYTE_REGISTER(rh);
 
1415
        DECODE_PRINTF("\n");
 
1416
        TRACE_AND_STEP();
 
1417
        *destreg = sbb_byte(*destreg, *srcreg);
 
1418
        break;
 
1419
    }
 
1420
    DECODE_CLEAR_SEGOVR();
 
1421
    END_OF_INSTR();
 
1422
}
 
1423
 
 
1424
/****************************************************************************
 
1425
REMARKS:
 
1426
Handles opcode 0x19
 
1427
****************************************************************************/
 
1428
static void x86emuOp_sbb_word_RM_R(u8 X86EMU_UNUSED(op1))
 
1429
{
 
1430
    int mod, rl, rh;
 
1431
    uint destoffset;
 
1432
 
 
1433
    START_OF_INSTR();
 
1434
    DECODE_PRINTF("SBB\t");
 
1435
    FETCH_DECODE_MODRM(mod, rh, rl);
 
1436
    switch (mod) {
 
1437
    case 0:
 
1438
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
1439
            u32 destval;
 
1440
            u32 *srcreg;
 
1441
 
 
1442
            destoffset = decode_rm00_address(rl);
 
1443
            DECODE_PRINTF(",");
 
1444
            destval = fetch_data_long(destoffset);
 
1445
            srcreg = DECODE_RM_LONG_REGISTER(rh);
 
1446
            DECODE_PRINTF("\n");
 
1447
            TRACE_AND_STEP();
 
1448
            destval = sbb_long(destval, *srcreg);
 
1449
            store_data_long(destoffset, destval);
 
1450
        } else {
 
1451
            u16 destval;
 
1452
            u16 *srcreg;
 
1453
 
 
1454
            destoffset = decode_rm00_address(rl);
 
1455
            DECODE_PRINTF(",");
 
1456
            destval = fetch_data_word(destoffset);
 
1457
            srcreg = DECODE_RM_WORD_REGISTER(rh);
 
1458
            DECODE_PRINTF("\n");
 
1459
            TRACE_AND_STEP();
 
1460
            destval = sbb_word(destval, *srcreg);
 
1461
            store_data_word(destoffset, destval);
 
1462
        }
 
1463
        break;
 
1464
    case 1:
 
1465
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
1466
            u32 destval;
 
1467
            u32 *srcreg;
 
1468
 
 
1469
            destoffset = decode_rm01_address(rl);
 
1470
            DECODE_PRINTF(",");
 
1471
            destval = fetch_data_long(destoffset);
 
1472
            srcreg = DECODE_RM_LONG_REGISTER(rh);
 
1473
            DECODE_PRINTF("\n");
 
1474
            TRACE_AND_STEP();
 
1475
            destval = sbb_long(destval, *srcreg);
 
1476
            store_data_long(destoffset, destval);
 
1477
        } else {
 
1478
            u16 destval;
 
1479
            u16 *srcreg;
 
1480
 
 
1481
            destoffset = decode_rm01_address(rl);
 
1482
            DECODE_PRINTF(",");
 
1483
            destval = fetch_data_word(destoffset);
 
1484
            srcreg = DECODE_RM_WORD_REGISTER(rh);
 
1485
            DECODE_PRINTF("\n");
 
1486
            TRACE_AND_STEP();
 
1487
            destval = sbb_word(destval, *srcreg);
 
1488
            store_data_word(destoffset, destval);
 
1489
        }
 
1490
        break;
 
1491
    case 2:
 
1492
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
1493
            u32 destval;
 
1494
            u32 *srcreg;
 
1495
 
 
1496
            destoffset = decode_rm10_address(rl);
 
1497
            DECODE_PRINTF(",");
 
1498
            destval = fetch_data_long(destoffset);
 
1499
            srcreg = DECODE_RM_LONG_REGISTER(rh);
 
1500
            DECODE_PRINTF("\n");
 
1501
            TRACE_AND_STEP();
 
1502
            destval = sbb_long(destval, *srcreg);
 
1503
            store_data_long(destoffset, destval);
 
1504
        } else {
 
1505
            u16 destval;
 
1506
            u16 *srcreg;
 
1507
 
 
1508
            destoffset = decode_rm10_address(rl);
 
1509
            DECODE_PRINTF(",");
 
1510
            destval = fetch_data_word(destoffset);
 
1511
            srcreg = DECODE_RM_WORD_REGISTER(rh);
 
1512
            DECODE_PRINTF("\n");
 
1513
            TRACE_AND_STEP();
 
1514
            destval = sbb_word(destval, *srcreg);
 
1515
            store_data_word(destoffset, destval);
 
1516
        }
 
1517
        break;
 
1518
    case 3:                     /* register to register */
 
1519
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
1520
            u32 *destreg,*srcreg;
 
1521
 
 
1522
            destreg = DECODE_RM_LONG_REGISTER(rl);
 
1523
            DECODE_PRINTF(",");
 
1524
            srcreg = DECODE_RM_LONG_REGISTER(rh);
 
1525
            DECODE_PRINTF("\n");
 
1526
            TRACE_AND_STEP();
 
1527
            *destreg = sbb_long(*destreg, *srcreg);
 
1528
        } else {
 
1529
            u16 *destreg,*srcreg;
 
1530
 
 
1531
            destreg = DECODE_RM_WORD_REGISTER(rl);
 
1532
            DECODE_PRINTF(",");
 
1533
            srcreg = DECODE_RM_WORD_REGISTER(rh);
 
1534
            DECODE_PRINTF("\n");
 
1535
            TRACE_AND_STEP();
 
1536
            *destreg = sbb_word(*destreg, *srcreg);
 
1537
        }
 
1538
        break;
 
1539
    }
 
1540
    DECODE_CLEAR_SEGOVR();
 
1541
    END_OF_INSTR();
 
1542
}
 
1543
 
 
1544
/****************************************************************************
 
1545
REMARKS:
 
1546
Handles opcode 0x1a
 
1547
****************************************************************************/
 
1548
static void x86emuOp_sbb_byte_R_RM(u8 X86EMU_UNUSED(op1))
 
1549
{
 
1550
    int mod, rl, rh;
 
1551
    u8 *destreg, *srcreg;
 
1552
    uint srcoffset;
 
1553
    u8 srcval;
 
1554
 
 
1555
    START_OF_INSTR();
 
1556
    DECODE_PRINTF("SBB\t");
 
1557
    FETCH_DECODE_MODRM(mod, rh, rl);
 
1558
    switch (mod) {
 
1559
    case 0:
 
1560
        destreg = DECODE_RM_BYTE_REGISTER(rh);
 
1561
        DECODE_PRINTF(",");
 
1562
        srcoffset = decode_rm00_address(rl);
 
1563
        srcval = fetch_data_byte(srcoffset);
 
1564
        DECODE_PRINTF("\n");
 
1565
        TRACE_AND_STEP();
 
1566
        *destreg = sbb_byte(*destreg, srcval);
 
1567
        break;
 
1568
    case 1:
 
1569
        destreg = DECODE_RM_BYTE_REGISTER(rh);
 
1570
        DECODE_PRINTF(",");
 
1571
        srcoffset = decode_rm01_address(rl);
 
1572
        srcval = fetch_data_byte(srcoffset);
 
1573
        DECODE_PRINTF("\n");
 
1574
        TRACE_AND_STEP();
 
1575
        *destreg = sbb_byte(*destreg, srcval);
 
1576
        break;
 
1577
    case 2:
 
1578
        destreg = DECODE_RM_BYTE_REGISTER(rh);
 
1579
        DECODE_PRINTF(",");
 
1580
        srcoffset = decode_rm10_address(rl);
 
1581
        srcval = fetch_data_byte(srcoffset);
 
1582
        DECODE_PRINTF("\n");
 
1583
        TRACE_AND_STEP();
 
1584
        *destreg = sbb_byte(*destreg, srcval);
 
1585
        break;
 
1586
    case 3:                     /* register to register */
 
1587
        destreg = DECODE_RM_BYTE_REGISTER(rh);
 
1588
        DECODE_PRINTF(",");
 
1589
        srcreg = DECODE_RM_BYTE_REGISTER(rl);
 
1590
        DECODE_PRINTF("\n");
 
1591
        TRACE_AND_STEP();
 
1592
        *destreg = sbb_byte(*destreg, *srcreg);
 
1593
        break;
 
1594
    }
 
1595
    DECODE_CLEAR_SEGOVR();
 
1596
    END_OF_INSTR();
 
1597
}
 
1598
 
 
1599
/****************************************************************************
 
1600
REMARKS:
 
1601
Handles opcode 0x1b
 
1602
****************************************************************************/
 
1603
static void x86emuOp_sbb_word_R_RM(u8 X86EMU_UNUSED(op1))
 
1604
{
 
1605
    int mod, rl, rh;
 
1606
    uint srcoffset;
 
1607
 
 
1608
    START_OF_INSTR();
 
1609
    DECODE_PRINTF("SBB\t");
 
1610
    FETCH_DECODE_MODRM(mod, rh, rl);
 
1611
    switch (mod) {
 
1612
    case 0:
 
1613
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
1614
            u32 *destreg;
 
1615
            u32 srcval;
 
1616
 
 
1617
            destreg = DECODE_RM_LONG_REGISTER(rh);
 
1618
            DECODE_PRINTF(",");
 
1619
            srcoffset = decode_rm00_address(rl);
 
1620
            srcval = fetch_data_long(srcoffset);
 
1621
            DECODE_PRINTF("\n");
 
1622
            TRACE_AND_STEP();
 
1623
            *destreg = sbb_long(*destreg, srcval);
 
1624
        } else {
 
1625
            u16 *destreg;
 
1626
            u16 srcval;
 
1627
 
 
1628
            destreg = DECODE_RM_WORD_REGISTER(rh);
 
1629
            DECODE_PRINTF(",");
 
1630
            srcoffset = decode_rm00_address(rl);
 
1631
            srcval = fetch_data_word(srcoffset);
 
1632
            DECODE_PRINTF("\n");
 
1633
            TRACE_AND_STEP();
 
1634
            *destreg = sbb_word(*destreg, srcval);
 
1635
        }
 
1636
        break;
 
1637
    case 1:
 
1638
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
1639
            u32 *destreg;
 
1640
            u32 srcval;
 
1641
 
 
1642
            destreg = DECODE_RM_LONG_REGISTER(rh);
 
1643
            DECODE_PRINTF(",");
 
1644
            srcoffset = decode_rm01_address(rl);
 
1645
            srcval = fetch_data_long(srcoffset);
 
1646
            DECODE_PRINTF("\n");
 
1647
            TRACE_AND_STEP();
 
1648
            *destreg = sbb_long(*destreg, srcval);
 
1649
        } else {
 
1650
            u16 *destreg;
 
1651
            u16 srcval;
 
1652
 
 
1653
            destreg = DECODE_RM_WORD_REGISTER(rh);
 
1654
            DECODE_PRINTF(",");
 
1655
            srcoffset = decode_rm01_address(rl);
 
1656
            srcval = fetch_data_word(srcoffset);
 
1657
            DECODE_PRINTF("\n");
 
1658
            TRACE_AND_STEP();
 
1659
            *destreg = sbb_word(*destreg, srcval);
 
1660
        }
 
1661
        break;
 
1662
    case 2:
 
1663
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
1664
            u32 *destreg;
 
1665
            u32 srcval;
 
1666
 
 
1667
            destreg = DECODE_RM_LONG_REGISTER(rh);
 
1668
            DECODE_PRINTF(",");
 
1669
            srcoffset = decode_rm10_address(rl);
 
1670
            srcval = fetch_data_long(srcoffset);
 
1671
            DECODE_PRINTF("\n");
 
1672
            TRACE_AND_STEP();
 
1673
            *destreg = sbb_long(*destreg, srcval);
 
1674
        } else {
 
1675
            u16 *destreg;
 
1676
            u16 srcval;
 
1677
 
 
1678
            destreg = DECODE_RM_WORD_REGISTER(rh);
 
1679
            DECODE_PRINTF(",");
 
1680
            srcoffset = decode_rm10_address(rl);
 
1681
            srcval = fetch_data_word(srcoffset);
 
1682
            DECODE_PRINTF("\n");
 
1683
            TRACE_AND_STEP();
 
1684
            *destreg = sbb_word(*destreg, srcval);
 
1685
        }
 
1686
        break;
 
1687
    case 3:                     /* register to register */
 
1688
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
1689
            u32 *destreg,*srcreg;
 
1690
 
 
1691
            destreg = DECODE_RM_LONG_REGISTER(rh);
 
1692
            DECODE_PRINTF(",");
 
1693
            srcreg = DECODE_RM_LONG_REGISTER(rl);
 
1694
            DECODE_PRINTF("\n");
 
1695
            TRACE_AND_STEP();
 
1696
            *destreg = sbb_long(*destreg, *srcreg);
 
1697
        } else {
 
1698
            u16 *destreg,*srcreg;
 
1699
 
 
1700
            destreg = DECODE_RM_WORD_REGISTER(rh);
 
1701
            DECODE_PRINTF(",");
 
1702
            srcreg = DECODE_RM_WORD_REGISTER(rl);
 
1703
            DECODE_PRINTF("\n");
 
1704
            TRACE_AND_STEP();
 
1705
            *destreg = sbb_word(*destreg, *srcreg);
 
1706
        }
 
1707
        break;
 
1708
    }
 
1709
    DECODE_CLEAR_SEGOVR();
 
1710
    END_OF_INSTR();
 
1711
}
 
1712
 
 
1713
/****************************************************************************
 
1714
REMARKS:
 
1715
Handles opcode 0x1c
 
1716
****************************************************************************/
 
1717
static void x86emuOp_sbb_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
 
1718
{
 
1719
    u8 srcval;
 
1720
 
 
1721
    START_OF_INSTR();
 
1722
    DECODE_PRINTF("SBB\tAL,");
 
1723
    srcval = fetch_byte_imm();
 
1724
    DECODE_PRINTF2("%x\n", srcval);
 
1725
    TRACE_AND_STEP();
 
1726
    M.x86.R_AL = sbb_byte(M.x86.R_AL, srcval);
 
1727
    DECODE_CLEAR_SEGOVR();
 
1728
    END_OF_INSTR();
 
1729
}
 
1730
 
 
1731
/****************************************************************************
 
1732
REMARKS:
 
1733
Handles opcode 0x1d
 
1734
****************************************************************************/
 
1735
static void x86emuOp_sbb_word_AX_IMM(u8 X86EMU_UNUSED(op1))
 
1736
{
 
1737
    u32 srcval;
 
1738
 
 
1739
    START_OF_INSTR();
 
1740
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
1741
        DECODE_PRINTF("SBB\tEAX,");
 
1742
        srcval = fetch_long_imm();
 
1743
    } else {
 
1744
        DECODE_PRINTF("SBB\tAX,");
 
1745
        srcval = fetch_word_imm();
 
1746
    }
 
1747
    DECODE_PRINTF2("%x\n", srcval);
 
1748
    TRACE_AND_STEP();
 
1749
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
1750
        M.x86.R_EAX = sbb_long(M.x86.R_EAX, srcval);
 
1751
    } else {
 
1752
        M.x86.R_AX = sbb_word(M.x86.R_AX, (u16)srcval);
 
1753
    }
 
1754
    DECODE_CLEAR_SEGOVR();
 
1755
    END_OF_INSTR();
 
1756
}
 
1757
 
 
1758
/****************************************************************************
 
1759
REMARKS:
 
1760
Handles opcode 0x1e
 
1761
****************************************************************************/
 
1762
static void x86emuOp_push_DS(u8 X86EMU_UNUSED(op1))
 
1763
{
 
1764
    START_OF_INSTR();
 
1765
    DECODE_PRINTF("PUSH\tDS\n");
 
1766
    TRACE_AND_STEP();
 
1767
    push_word(M.x86.R_DS);
 
1768
    DECODE_CLEAR_SEGOVR();
 
1769
    END_OF_INSTR();
 
1770
}
 
1771
 
 
1772
/****************************************************************************
 
1773
REMARKS:
 
1774
Handles opcode 0x1f
 
1775
****************************************************************************/
 
1776
static void x86emuOp_pop_DS(u8 X86EMU_UNUSED(op1))
 
1777
{
 
1778
    START_OF_INSTR();
 
1779
    DECODE_PRINTF("POP\tDS\n");
 
1780
    TRACE_AND_STEP();
 
1781
    M.x86.R_DS = pop_word();
 
1782
    DECODE_CLEAR_SEGOVR();
 
1783
    END_OF_INSTR();
 
1784
}
 
1785
 
 
1786
/****************************************************************************
 
1787
REMARKS:
 
1788
Handles opcode 0x20
 
1789
****************************************************************************/
 
1790
static void x86emuOp_and_byte_RM_R(u8 X86EMU_UNUSED(op1))
 
1791
{
 
1792
    int mod, rl, rh;
 
1793
    u8 *destreg, *srcreg;
 
1794
    uint destoffset;
 
1795
    u8 destval;
 
1796
 
 
1797
    START_OF_INSTR();
 
1798
    DECODE_PRINTF("AND\t");
 
1799
    FETCH_DECODE_MODRM(mod, rh, rl);
 
1800
 
 
1801
    switch (mod) {
 
1802
    case 0:
 
1803
        destoffset = decode_rm00_address(rl);
 
1804
        DECODE_PRINTF(",");
 
1805
        destval = fetch_data_byte(destoffset);
 
1806
        srcreg = DECODE_RM_BYTE_REGISTER(rh);
 
1807
        DECODE_PRINTF("\n");
 
1808
        TRACE_AND_STEP();
 
1809
        destval = and_byte(destval, *srcreg);
 
1810
        store_data_byte(destoffset, destval);
 
1811
        break;
 
1812
 
 
1813
    case 1:
 
1814
        destoffset = decode_rm01_address(rl);
 
1815
        DECODE_PRINTF(",");
 
1816
        destval = fetch_data_byte(destoffset);
 
1817
        srcreg = DECODE_RM_BYTE_REGISTER(rh);
 
1818
        DECODE_PRINTF("\n");
 
1819
        TRACE_AND_STEP();
 
1820
        destval = and_byte(destval, *srcreg);
 
1821
        store_data_byte(destoffset, destval);
 
1822
        break;
 
1823
 
 
1824
    case 2:
 
1825
        destoffset = decode_rm10_address(rl);
 
1826
        DECODE_PRINTF(",");
 
1827
        destval = fetch_data_byte(destoffset);
 
1828
        srcreg = DECODE_RM_BYTE_REGISTER(rh);
 
1829
        DECODE_PRINTF("\n");
 
1830
        TRACE_AND_STEP();
 
1831
        destval = and_byte(destval, *srcreg);
 
1832
        store_data_byte(destoffset, destval);
 
1833
        break;
 
1834
 
 
1835
    case 3:                     /* register to register */
 
1836
        destreg = DECODE_RM_BYTE_REGISTER(rl);
 
1837
        DECODE_PRINTF(",");
 
1838
        srcreg = DECODE_RM_BYTE_REGISTER(rh);
 
1839
        DECODE_PRINTF("\n");
 
1840
        TRACE_AND_STEP();
 
1841
        *destreg = and_byte(*destreg, *srcreg);
 
1842
        break;
 
1843
    }
 
1844
    DECODE_CLEAR_SEGOVR();
 
1845
    END_OF_INSTR();
 
1846
}
 
1847
 
 
1848
/****************************************************************************
 
1849
REMARKS:
 
1850
Handles opcode 0x21
 
1851
****************************************************************************/
 
1852
static void x86emuOp_and_word_RM_R(u8 X86EMU_UNUSED(op1))
 
1853
{
 
1854
    int mod, rl, rh;
 
1855
    uint destoffset;
 
1856
 
 
1857
    START_OF_INSTR();
 
1858
    DECODE_PRINTF("AND\t");
 
1859
    FETCH_DECODE_MODRM(mod, rh, rl);
 
1860
    switch (mod) {
 
1861
    case 0:
 
1862
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
1863
            u32 destval;
 
1864
            u32 *srcreg;
 
1865
 
 
1866
            destoffset = decode_rm00_address(rl);
 
1867
            DECODE_PRINTF(",");
 
1868
            destval = fetch_data_long(destoffset);
 
1869
            srcreg = DECODE_RM_LONG_REGISTER(rh);
 
1870
            DECODE_PRINTF("\n");
 
1871
            TRACE_AND_STEP();
 
1872
            destval = and_long(destval, *srcreg);
 
1873
            store_data_long(destoffset, destval);
 
1874
        } else {
 
1875
            u16 destval;
 
1876
            u16 *srcreg;
 
1877
 
 
1878
            destoffset = decode_rm00_address(rl);
 
1879
            DECODE_PRINTF(",");
 
1880
            destval = fetch_data_word(destoffset);
 
1881
            srcreg = DECODE_RM_WORD_REGISTER(rh);
 
1882
            DECODE_PRINTF("\n");
 
1883
            TRACE_AND_STEP();
 
1884
            destval = and_word(destval, *srcreg);
 
1885
            store_data_word(destoffset, destval);
 
1886
        }
 
1887
        break;
 
1888
    case 1:
 
1889
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
1890
            u32 destval;
 
1891
            u32 *srcreg;
 
1892
 
 
1893
            destoffset = decode_rm01_address(rl);
 
1894
            DECODE_PRINTF(",");
 
1895
            destval = fetch_data_long(destoffset);
 
1896
            srcreg = DECODE_RM_LONG_REGISTER(rh);
 
1897
            DECODE_PRINTF("\n");
 
1898
            TRACE_AND_STEP();
 
1899
            destval = and_long(destval, *srcreg);
 
1900
            store_data_long(destoffset, destval);
 
1901
        } else {
 
1902
            u16 destval;
 
1903
            u16 *srcreg;
 
1904
 
 
1905
            destoffset = decode_rm01_address(rl);
 
1906
            DECODE_PRINTF(",");
 
1907
            destval = fetch_data_word(destoffset);
 
1908
            srcreg = DECODE_RM_WORD_REGISTER(rh);
 
1909
            DECODE_PRINTF("\n");
 
1910
            TRACE_AND_STEP();
 
1911
            destval = and_word(destval, *srcreg);
 
1912
            store_data_word(destoffset, destval);
 
1913
        }
 
1914
        break;
 
1915
    case 2:
 
1916
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
1917
            u32 destval;
 
1918
            u32 *srcreg;
 
1919
 
 
1920
            destoffset = decode_rm10_address(rl);
 
1921
            DECODE_PRINTF(",");
 
1922
            destval = fetch_data_long(destoffset);
 
1923
            srcreg = DECODE_RM_LONG_REGISTER(rh);
 
1924
            DECODE_PRINTF("\n");
 
1925
            TRACE_AND_STEP();
 
1926
            destval = and_long(destval, *srcreg);
 
1927
            store_data_long(destoffset, destval);
 
1928
        } else {
 
1929
            u16 destval;
 
1930
            u16 *srcreg;
 
1931
 
 
1932
            destoffset = decode_rm10_address(rl);
 
1933
            DECODE_PRINTF(",");
 
1934
            destval = fetch_data_word(destoffset);
 
1935
            srcreg = DECODE_RM_WORD_REGISTER(rh);
 
1936
            DECODE_PRINTF("\n");
 
1937
            TRACE_AND_STEP();
 
1938
            destval = and_word(destval, *srcreg);
 
1939
            store_data_word(destoffset, destval);
 
1940
        }
 
1941
        break;
 
1942
    case 3:                     /* register to register */
 
1943
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
1944
            u32 *destreg,*srcreg;
 
1945
 
 
1946
            destreg = DECODE_RM_LONG_REGISTER(rl);
 
1947
            DECODE_PRINTF(",");
 
1948
            srcreg = DECODE_RM_LONG_REGISTER(rh);
 
1949
            DECODE_PRINTF("\n");
 
1950
            TRACE_AND_STEP();
 
1951
            *destreg = and_long(*destreg, *srcreg);
 
1952
        } else {
 
1953
            u16 *destreg,*srcreg;
 
1954
 
 
1955
            destreg = DECODE_RM_WORD_REGISTER(rl);
 
1956
            DECODE_PRINTF(",");
 
1957
            srcreg = DECODE_RM_WORD_REGISTER(rh);
 
1958
            DECODE_PRINTF("\n");
 
1959
            TRACE_AND_STEP();
 
1960
            *destreg = and_word(*destreg, *srcreg);
 
1961
        }
 
1962
        break;
 
1963
    }
 
1964
    DECODE_CLEAR_SEGOVR();
 
1965
    END_OF_INSTR();
 
1966
}
 
1967
 
 
1968
/****************************************************************************
 
1969
REMARKS:
 
1970
Handles opcode 0x22
 
1971
****************************************************************************/
 
1972
static void x86emuOp_and_byte_R_RM(u8 X86EMU_UNUSED(op1))
 
1973
{
 
1974
    int mod, rl, rh;
 
1975
    u8 *destreg, *srcreg;
 
1976
    uint srcoffset;
 
1977
    u8 srcval;
 
1978
 
 
1979
    START_OF_INSTR();
 
1980
    DECODE_PRINTF("AND\t");
 
1981
    FETCH_DECODE_MODRM(mod, rh, rl);
 
1982
    switch (mod) {
 
1983
    case 0:
 
1984
        destreg = DECODE_RM_BYTE_REGISTER(rh);
 
1985
        DECODE_PRINTF(",");
 
1986
        srcoffset = decode_rm00_address(rl);
 
1987
        srcval = fetch_data_byte(srcoffset);
 
1988
        DECODE_PRINTF("\n");
 
1989
        TRACE_AND_STEP();
 
1990
        *destreg = and_byte(*destreg, srcval);
 
1991
        break;
 
1992
    case 1:
 
1993
        destreg = DECODE_RM_BYTE_REGISTER(rh);
 
1994
        DECODE_PRINTF(",");
 
1995
        srcoffset = decode_rm01_address(rl);
 
1996
        srcval = fetch_data_byte(srcoffset);
 
1997
        DECODE_PRINTF("\n");
 
1998
        TRACE_AND_STEP();
 
1999
        *destreg = and_byte(*destreg, srcval);
 
2000
        break;
 
2001
    case 2:
 
2002
        destreg = DECODE_RM_BYTE_REGISTER(rh);
 
2003
        DECODE_PRINTF(",");
 
2004
        srcoffset = decode_rm10_address(rl);
 
2005
        srcval = fetch_data_byte(srcoffset);
 
2006
        DECODE_PRINTF("\n");
 
2007
        TRACE_AND_STEP();
 
2008
        *destreg = and_byte(*destreg, srcval);
 
2009
        break;
 
2010
    case 3:                     /* register to register */
 
2011
        destreg = DECODE_RM_BYTE_REGISTER(rh);
 
2012
        DECODE_PRINTF(",");
 
2013
        srcreg = DECODE_RM_BYTE_REGISTER(rl);
 
2014
        DECODE_PRINTF("\n");
 
2015
        TRACE_AND_STEP();
 
2016
        *destreg = and_byte(*destreg, *srcreg);
 
2017
        break;
 
2018
    }
 
2019
    DECODE_CLEAR_SEGOVR();
 
2020
    END_OF_INSTR();
 
2021
}
 
2022
 
 
2023
/****************************************************************************
 
2024
REMARKS:
 
2025
Handles opcode 0x23
 
2026
****************************************************************************/
 
2027
static void x86emuOp_and_word_R_RM(u8 X86EMU_UNUSED(op1))
 
2028
{
 
2029
    int mod, rl, rh;
 
2030
    uint srcoffset;
 
2031
 
 
2032
    START_OF_INSTR();
 
2033
    DECODE_PRINTF("AND\t");
 
2034
    FETCH_DECODE_MODRM(mod, rh, rl);
 
2035
    switch (mod) {
 
2036
    case 0:
 
2037
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
2038
            u32 *destreg;
 
2039
            u32 srcval;
 
2040
 
 
2041
            destreg = DECODE_RM_LONG_REGISTER(rh);
 
2042
            DECODE_PRINTF(",");
 
2043
            srcoffset = decode_rm00_address(rl);
 
2044
            srcval = fetch_data_long(srcoffset);
 
2045
            DECODE_PRINTF("\n");
 
2046
            TRACE_AND_STEP();
 
2047
            *destreg = and_long(*destreg, srcval);
 
2048
        } else {
 
2049
            u16 *destreg;
 
2050
            u16 srcval;
 
2051
 
 
2052
            destreg = DECODE_RM_WORD_REGISTER(rh);
 
2053
            DECODE_PRINTF(",");
 
2054
            srcoffset = decode_rm00_address(rl);
 
2055
            srcval = fetch_data_word(srcoffset);
 
2056
            DECODE_PRINTF("\n");
 
2057
            TRACE_AND_STEP();
 
2058
            *destreg = and_word(*destreg, srcval);
 
2059
        }
 
2060
        break;
 
2061
    case 1:
 
2062
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
2063
            u32 *destreg;
 
2064
            u32 srcval;
 
2065
 
 
2066
            destreg = DECODE_RM_LONG_REGISTER(rh);
 
2067
            DECODE_PRINTF(",");
 
2068
            srcoffset = decode_rm01_address(rl);
 
2069
            srcval = fetch_data_long(srcoffset);
 
2070
            DECODE_PRINTF("\n");
 
2071
            TRACE_AND_STEP();
 
2072
            *destreg = and_long(*destreg, srcval);
 
2073
            break;
 
2074
        } else {
 
2075
            u16 *destreg;
 
2076
            u16 srcval;
 
2077
 
 
2078
            destreg = DECODE_RM_WORD_REGISTER(rh);
 
2079
            DECODE_PRINTF(",");
 
2080
            srcoffset = decode_rm01_address(rl);
 
2081
            srcval = fetch_data_word(srcoffset);
 
2082
            DECODE_PRINTF("\n");
 
2083
            TRACE_AND_STEP();
 
2084
            *destreg = and_word(*destreg, srcval);
 
2085
            break;
 
2086
        }
 
2087
    case 2:
 
2088
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
2089
            u32 *destreg;
 
2090
            u32 srcval;
 
2091
 
 
2092
            destreg = DECODE_RM_LONG_REGISTER(rh);
 
2093
            DECODE_PRINTF(",");
 
2094
            srcoffset = decode_rm10_address(rl);
 
2095
            srcval = fetch_data_long(srcoffset);
 
2096
            DECODE_PRINTF("\n");
 
2097
            TRACE_AND_STEP();
 
2098
            *destreg = and_long(*destreg, srcval);
 
2099
        } else {
 
2100
            u16 *destreg;
 
2101
            u16 srcval;
 
2102
 
 
2103
            destreg = DECODE_RM_WORD_REGISTER(rh);
 
2104
            DECODE_PRINTF(",");
 
2105
            srcoffset = decode_rm10_address(rl);
 
2106
            srcval = fetch_data_word(srcoffset);
 
2107
            DECODE_PRINTF("\n");
 
2108
            TRACE_AND_STEP();
 
2109
            *destreg = and_word(*destreg, srcval);
 
2110
        }
 
2111
        break;
 
2112
    case 3:                     /* register to register */
 
2113
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
2114
            u32 *destreg,*srcreg;
 
2115
 
 
2116
            destreg = DECODE_RM_LONG_REGISTER(rh);
 
2117
            DECODE_PRINTF(",");
 
2118
            srcreg = DECODE_RM_LONG_REGISTER(rl);
 
2119
            DECODE_PRINTF("\n");
 
2120
            TRACE_AND_STEP();
 
2121
            *destreg = and_long(*destreg, *srcreg);
 
2122
        } else {
 
2123
            u16 *destreg,*srcreg;
 
2124
 
 
2125
            destreg = DECODE_RM_WORD_REGISTER(rh);
 
2126
            DECODE_PRINTF(",");
 
2127
            srcreg = DECODE_RM_WORD_REGISTER(rl);
 
2128
            DECODE_PRINTF("\n");
 
2129
            TRACE_AND_STEP();
 
2130
            *destreg = and_word(*destreg, *srcreg);
 
2131
        }
 
2132
        break;
 
2133
    }
 
2134
    DECODE_CLEAR_SEGOVR();
 
2135
    END_OF_INSTR();
 
2136
}
 
2137
 
 
2138
/****************************************************************************
 
2139
REMARKS:
 
2140
Handles opcode 0x24
 
2141
****************************************************************************/
 
2142
static void x86emuOp_and_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
 
2143
{
 
2144
    u8 srcval;
 
2145
 
 
2146
    START_OF_INSTR();
 
2147
    DECODE_PRINTF("AND\tAL,");
 
2148
    srcval = fetch_byte_imm();
 
2149
    DECODE_PRINTF2("%x\n", srcval);
 
2150
    TRACE_AND_STEP();
 
2151
    M.x86.R_AL = and_byte(M.x86.R_AL, srcval);
 
2152
    DECODE_CLEAR_SEGOVR();
 
2153
    END_OF_INSTR();
 
2154
}
 
2155
 
 
2156
/****************************************************************************
 
2157
REMARKS:
 
2158
Handles opcode 0x25
 
2159
****************************************************************************/
 
2160
static void x86emuOp_and_word_AX_IMM(u8 X86EMU_UNUSED(op1))
 
2161
{
 
2162
    u32 srcval;
 
2163
 
 
2164
    START_OF_INSTR();
 
2165
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
2166
        DECODE_PRINTF("AND\tEAX,");
 
2167
        srcval = fetch_long_imm();
 
2168
    } else {
 
2169
        DECODE_PRINTF("AND\tAX,");
 
2170
        srcval = fetch_word_imm();
 
2171
    }
 
2172
    DECODE_PRINTF2("%x\n", srcval);
 
2173
    TRACE_AND_STEP();
 
2174
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
2175
        M.x86.R_EAX = and_long(M.x86.R_EAX, srcval);
 
2176
    } else {
 
2177
        M.x86.R_AX = and_word(M.x86.R_AX, (u16)srcval);
 
2178
    }
 
2179
    DECODE_CLEAR_SEGOVR();
 
2180
    END_OF_INSTR();
 
2181
}
 
2182
 
 
2183
/****************************************************************************
 
2184
REMARKS:
 
2185
Handles opcode 0x26
 
2186
****************************************************************************/
 
2187
static void x86emuOp_segovr_ES(u8 X86EMU_UNUSED(op1))
 
2188
{
 
2189
    START_OF_INSTR();
 
2190
    DECODE_PRINTF("ES:\n");
 
2191
    TRACE_AND_STEP();
 
2192
    M.x86.mode |= SYSMODE_SEGOVR_ES;
 
2193
    /*
 
2194
     * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
 
2195
     * opcode subroutines we do not want to do this.
 
2196
     */
 
2197
    END_OF_INSTR();
 
2198
}
 
2199
 
 
2200
/****************************************************************************
 
2201
REMARKS:
 
2202
Handles opcode 0x27
 
2203
****************************************************************************/
 
2204
static void x86emuOp_daa(u8 X86EMU_UNUSED(op1))
 
2205
{
 
2206
    START_OF_INSTR();
 
2207
    DECODE_PRINTF("DAA\n");
 
2208
    TRACE_AND_STEP();
 
2209
    M.x86.R_AL = daa_byte(M.x86.R_AL);
 
2210
    DECODE_CLEAR_SEGOVR();
 
2211
    END_OF_INSTR();
 
2212
}
 
2213
 
 
2214
/****************************************************************************
 
2215
REMARKS:
 
2216
Handles opcode 0x28
 
2217
****************************************************************************/
 
2218
static void x86emuOp_sub_byte_RM_R(u8 X86EMU_UNUSED(op1))
 
2219
{
 
2220
    int mod, rl, rh;
 
2221
    u8 *destreg, *srcreg;
 
2222
    uint destoffset;
 
2223
    u8 destval;
 
2224
 
 
2225
    START_OF_INSTR();
 
2226
    DECODE_PRINTF("SUB\t");
 
2227
    FETCH_DECODE_MODRM(mod, rh, rl);
 
2228
    switch (mod) {
 
2229
    case 0:
 
2230
        destoffset = decode_rm00_address(rl);
 
2231
        DECODE_PRINTF(",");
 
2232
        destval = fetch_data_byte(destoffset);
 
2233
        srcreg = DECODE_RM_BYTE_REGISTER(rh);
 
2234
        DECODE_PRINTF("\n");
 
2235
        TRACE_AND_STEP();
 
2236
        destval = sub_byte(destval, *srcreg);
 
2237
        store_data_byte(destoffset, destval);
 
2238
        break;
 
2239
    case 1:
 
2240
        destoffset = decode_rm01_address(rl);
 
2241
        DECODE_PRINTF(",");
 
2242
        destval = fetch_data_byte(destoffset);
 
2243
        srcreg = DECODE_RM_BYTE_REGISTER(rh);
 
2244
        DECODE_PRINTF("\n");
 
2245
        TRACE_AND_STEP();
 
2246
        destval = sub_byte(destval, *srcreg);
 
2247
        store_data_byte(destoffset, destval);
 
2248
        break;
 
2249
    case 2:
 
2250
        destoffset = decode_rm10_address(rl);
 
2251
        DECODE_PRINTF(",");
 
2252
        destval = fetch_data_byte(destoffset);
 
2253
        srcreg = DECODE_RM_BYTE_REGISTER(rh);
 
2254
        DECODE_PRINTF("\n");
 
2255
        TRACE_AND_STEP();
 
2256
        destval = sub_byte(destval, *srcreg);
 
2257
        store_data_byte(destoffset, destval);
 
2258
        break;
 
2259
    case 3:                     /* register to register */
 
2260
        destreg = DECODE_RM_BYTE_REGISTER(rl);
 
2261
        DECODE_PRINTF(",");
 
2262
        srcreg = DECODE_RM_BYTE_REGISTER(rh);
 
2263
        DECODE_PRINTF("\n");
 
2264
        TRACE_AND_STEP();
 
2265
        *destreg = sub_byte(*destreg, *srcreg);
 
2266
        break;
 
2267
    }
 
2268
    DECODE_CLEAR_SEGOVR();
 
2269
    END_OF_INSTR();
 
2270
}
 
2271
 
 
2272
/****************************************************************************
 
2273
REMARKS:
 
2274
Handles opcode 0x29
 
2275
****************************************************************************/
 
2276
static void x86emuOp_sub_word_RM_R(u8 X86EMU_UNUSED(op1))
 
2277
{
 
2278
    int mod, rl, rh;
 
2279
    uint destoffset;
 
2280
 
 
2281
    START_OF_INSTR();
 
2282
    DECODE_PRINTF("SUB\t");
 
2283
    FETCH_DECODE_MODRM(mod, rh, rl);
 
2284
    switch (mod) {
 
2285
    case 0:
 
2286
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
2287
            u32 destval;
 
2288
            u32 *srcreg;
 
2289
 
 
2290
            destoffset = decode_rm00_address(rl);
 
2291
            DECODE_PRINTF(",");
 
2292
            destval = fetch_data_long(destoffset);
 
2293
            srcreg = DECODE_RM_LONG_REGISTER(rh);
 
2294
            DECODE_PRINTF("\n");
 
2295
            TRACE_AND_STEP();
 
2296
            destval = sub_long(destval, *srcreg);
 
2297
            store_data_long(destoffset, destval);
 
2298
        } else {
 
2299
            u16 destval;
 
2300
            u16 *srcreg;
 
2301
 
 
2302
            destoffset = decode_rm00_address(rl);
 
2303
            DECODE_PRINTF(",");
 
2304
            destval = fetch_data_word(destoffset);
 
2305
            srcreg = DECODE_RM_WORD_REGISTER(rh);
 
2306
            DECODE_PRINTF("\n");
 
2307
            TRACE_AND_STEP();
 
2308
            destval = sub_word(destval, *srcreg);
 
2309
            store_data_word(destoffset, destval);
 
2310
        }
 
2311
        break;
 
2312
    case 1:
 
2313
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
2314
            u32 destval;
 
2315
            u32 *srcreg;
 
2316
 
 
2317
            destoffset = decode_rm01_address(rl);
 
2318
            DECODE_PRINTF(",");
 
2319
            destval = fetch_data_long(destoffset);
 
2320
            srcreg = DECODE_RM_LONG_REGISTER(rh);
 
2321
            DECODE_PRINTF("\n");
 
2322
            TRACE_AND_STEP();
 
2323
            destval = sub_long(destval, *srcreg);
 
2324
            store_data_long(destoffset, destval);
 
2325
        } else {
 
2326
            u16 destval;
 
2327
            u16 *srcreg;
 
2328
 
 
2329
            destoffset = decode_rm01_address(rl);
 
2330
            DECODE_PRINTF(",");
 
2331
            destval = fetch_data_word(destoffset);
 
2332
            srcreg = DECODE_RM_WORD_REGISTER(rh);
 
2333
            DECODE_PRINTF("\n");
 
2334
            TRACE_AND_STEP();
 
2335
            destval = sub_word(destval, *srcreg);
 
2336
            store_data_word(destoffset, destval);
 
2337
        }
 
2338
        break;
 
2339
    case 2:
 
2340
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
2341
            u32 destval;
 
2342
            u32 *srcreg;
 
2343
 
 
2344
            destoffset = decode_rm10_address(rl);
 
2345
            DECODE_PRINTF(",");
 
2346
            destval = fetch_data_long(destoffset);
 
2347
            srcreg = DECODE_RM_LONG_REGISTER(rh);
 
2348
            DECODE_PRINTF("\n");
 
2349
            TRACE_AND_STEP();
 
2350
            destval = sub_long(destval, *srcreg);
 
2351
            store_data_long(destoffset, destval);
 
2352
        } else {
 
2353
            u16 destval;
 
2354
            u16 *srcreg;
 
2355
 
 
2356
            destoffset = decode_rm10_address(rl);
 
2357
            DECODE_PRINTF(",");
 
2358
            destval = fetch_data_word(destoffset);
 
2359
            srcreg = DECODE_RM_WORD_REGISTER(rh);
 
2360
            DECODE_PRINTF("\n");
 
2361
            TRACE_AND_STEP();
 
2362
            destval = sub_word(destval, *srcreg);
 
2363
            store_data_word(destoffset, destval);
 
2364
        }
 
2365
        break;
 
2366
    case 3:                     /* register to register */
 
2367
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
2368
            u32 *destreg,*srcreg;
 
2369
 
 
2370
            destreg = DECODE_RM_LONG_REGISTER(rl);
 
2371
            DECODE_PRINTF(",");
 
2372
            srcreg = DECODE_RM_LONG_REGISTER(rh);
 
2373
            DECODE_PRINTF("\n");
 
2374
            TRACE_AND_STEP();
 
2375
            *destreg = sub_long(*destreg, *srcreg);
 
2376
        } else {
 
2377
            u16 *destreg,*srcreg;
 
2378
 
 
2379
            destreg = DECODE_RM_WORD_REGISTER(rl);
 
2380
            DECODE_PRINTF(",");
 
2381
            srcreg = DECODE_RM_WORD_REGISTER(rh);
 
2382
            DECODE_PRINTF("\n");
 
2383
            TRACE_AND_STEP();
 
2384
            *destreg = sub_word(*destreg, *srcreg);
 
2385
        }
 
2386
        break;
 
2387
    }
 
2388
    DECODE_CLEAR_SEGOVR();
 
2389
    END_OF_INSTR();
 
2390
}
 
2391
 
 
2392
/****************************************************************************
 
2393
REMARKS:
 
2394
Handles opcode 0x2a
 
2395
****************************************************************************/
 
2396
static void x86emuOp_sub_byte_R_RM(u8 X86EMU_UNUSED(op1))
 
2397
{
 
2398
    int mod, rl, rh;
 
2399
    u8 *destreg, *srcreg;
 
2400
    uint srcoffset;
 
2401
    u8 srcval;
 
2402
 
 
2403
    START_OF_INSTR();
 
2404
    DECODE_PRINTF("SUB\t");
 
2405
    FETCH_DECODE_MODRM(mod, rh, rl);
 
2406
    switch (mod) {
 
2407
    case 0:
 
2408
        destreg = DECODE_RM_BYTE_REGISTER(rh);
 
2409
        DECODE_PRINTF(",");
 
2410
        srcoffset = decode_rm00_address(rl);
 
2411
        srcval = fetch_data_byte(srcoffset);
 
2412
        DECODE_PRINTF("\n");
 
2413
        TRACE_AND_STEP();
 
2414
        *destreg = sub_byte(*destreg, srcval);
 
2415
        break;
 
2416
    case 1:
 
2417
        destreg = DECODE_RM_BYTE_REGISTER(rh);
 
2418
        DECODE_PRINTF(",");
 
2419
        srcoffset = decode_rm01_address(rl);
 
2420
        srcval = fetch_data_byte(srcoffset);
 
2421
        DECODE_PRINTF("\n");
 
2422
        TRACE_AND_STEP();
 
2423
        *destreg = sub_byte(*destreg, srcval);
 
2424
        break;
 
2425
    case 2:
 
2426
        destreg = DECODE_RM_BYTE_REGISTER(rh);
 
2427
        DECODE_PRINTF(",");
 
2428
        srcoffset = decode_rm10_address(rl);
 
2429
        srcval = fetch_data_byte(srcoffset);
 
2430
        DECODE_PRINTF("\n");
 
2431
        TRACE_AND_STEP();
 
2432
        *destreg = sub_byte(*destreg, srcval);
 
2433
        break;
 
2434
    case 3:                     /* register to register */
 
2435
        destreg = DECODE_RM_BYTE_REGISTER(rh);
 
2436
        DECODE_PRINTF(",");
 
2437
        srcreg = DECODE_RM_BYTE_REGISTER(rl);
 
2438
        DECODE_PRINTF("\n");
 
2439
        TRACE_AND_STEP();
 
2440
        *destreg = sub_byte(*destreg, *srcreg);
 
2441
        break;
 
2442
    }
 
2443
    DECODE_CLEAR_SEGOVR();
 
2444
    END_OF_INSTR();
 
2445
}
 
2446
 
 
2447
/****************************************************************************
 
2448
REMARKS:
 
2449
Handles opcode 0x2b
 
2450
****************************************************************************/
 
2451
static void x86emuOp_sub_word_R_RM(u8 X86EMU_UNUSED(op1))
 
2452
{
 
2453
    int mod, rl, rh;
 
2454
    uint srcoffset;
 
2455
 
 
2456
    START_OF_INSTR();
 
2457
    DECODE_PRINTF("SUB\t");
 
2458
    FETCH_DECODE_MODRM(mod, rh, rl);
 
2459
    switch (mod) {
 
2460
    case 0:
 
2461
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
2462
            u32 *destreg;
 
2463
            u32 srcval;
 
2464
 
 
2465
            destreg = DECODE_RM_LONG_REGISTER(rh);
 
2466
            DECODE_PRINTF(",");
 
2467
            srcoffset = decode_rm00_address(rl);
 
2468
            srcval = fetch_data_long(srcoffset);
 
2469
            DECODE_PRINTF("\n");
 
2470
            TRACE_AND_STEP();
 
2471
            *destreg = sub_long(*destreg, srcval);
 
2472
        } else {
 
2473
            u16 *destreg;
 
2474
            u16 srcval;
 
2475
 
 
2476
            destreg = DECODE_RM_WORD_REGISTER(rh);
 
2477
            DECODE_PRINTF(",");
 
2478
            srcoffset = decode_rm00_address(rl);
 
2479
            srcval = fetch_data_word(srcoffset);
 
2480
            DECODE_PRINTF("\n");
 
2481
            TRACE_AND_STEP();
 
2482
            *destreg = sub_word(*destreg, srcval);
 
2483
        }
 
2484
        break;
 
2485
    case 1:
 
2486
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
2487
            u32 *destreg;
 
2488
            u32 srcval;
 
2489
 
 
2490
            destreg = DECODE_RM_LONG_REGISTER(rh);
 
2491
            DECODE_PRINTF(",");
 
2492
            srcoffset = decode_rm01_address(rl);
 
2493
            srcval = fetch_data_long(srcoffset);
 
2494
            DECODE_PRINTF("\n");
 
2495
            TRACE_AND_STEP();
 
2496
            *destreg = sub_long(*destreg, srcval);
 
2497
        } else {
 
2498
            u16 *destreg;
 
2499
            u16 srcval;
 
2500
 
 
2501
            destreg = DECODE_RM_WORD_REGISTER(rh);
 
2502
            DECODE_PRINTF(",");
 
2503
            srcoffset = decode_rm01_address(rl);
 
2504
            srcval = fetch_data_word(srcoffset);
 
2505
            DECODE_PRINTF("\n");
 
2506
            TRACE_AND_STEP();
 
2507
            *destreg = sub_word(*destreg, srcval);
 
2508
        }
 
2509
        break;
 
2510
    case 2:
 
2511
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
2512
            u32 *destreg;
 
2513
            u32 srcval;
 
2514
 
 
2515
            destreg = DECODE_RM_LONG_REGISTER(rh);
 
2516
            DECODE_PRINTF(",");
 
2517
            srcoffset = decode_rm10_address(rl);
 
2518
            srcval = fetch_data_long(srcoffset);
 
2519
            DECODE_PRINTF("\n");
 
2520
            TRACE_AND_STEP();
 
2521
            *destreg = sub_long(*destreg, srcval);
 
2522
        } else {
 
2523
            u16 *destreg;
 
2524
            u16 srcval;
 
2525
 
 
2526
            destreg = DECODE_RM_WORD_REGISTER(rh);
 
2527
            DECODE_PRINTF(",");
 
2528
            srcoffset = decode_rm10_address(rl);
 
2529
            srcval = fetch_data_word(srcoffset);
 
2530
            DECODE_PRINTF("\n");
 
2531
            TRACE_AND_STEP();
 
2532
            *destreg = sub_word(*destreg, srcval);
 
2533
        }
 
2534
        break;
 
2535
    case 3:                     /* register to register */
 
2536
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
2537
            u32 *destreg,*srcreg;
 
2538
 
 
2539
            destreg = DECODE_RM_LONG_REGISTER(rh);
 
2540
            DECODE_PRINTF(",");
 
2541
            srcreg = DECODE_RM_LONG_REGISTER(rl);
 
2542
            DECODE_PRINTF("\n");
 
2543
            TRACE_AND_STEP();
 
2544
            *destreg = sub_long(*destreg, *srcreg);
 
2545
        } else {
 
2546
            u16 *destreg,*srcreg;
 
2547
 
 
2548
            destreg = DECODE_RM_WORD_REGISTER(rh);
 
2549
            DECODE_PRINTF(",");
 
2550
            srcreg = DECODE_RM_WORD_REGISTER(rl);
 
2551
            DECODE_PRINTF("\n");
 
2552
            TRACE_AND_STEP();
 
2553
            *destreg = sub_word(*destreg, *srcreg);
 
2554
        }
 
2555
        break;
 
2556
    }
 
2557
    DECODE_CLEAR_SEGOVR();
 
2558
    END_OF_INSTR();
 
2559
}
 
2560
 
 
2561
/****************************************************************************
 
2562
REMARKS:
 
2563
Handles opcode 0x2c
 
2564
****************************************************************************/
 
2565
static void x86emuOp_sub_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
 
2566
{
 
2567
    u8 srcval;
 
2568
 
 
2569
    START_OF_INSTR();
 
2570
    DECODE_PRINTF("SUB\tAL,");
 
2571
    srcval = fetch_byte_imm();
 
2572
    DECODE_PRINTF2("%x\n", srcval);
 
2573
    TRACE_AND_STEP();
 
2574
    M.x86.R_AL = sub_byte(M.x86.R_AL, srcval);
 
2575
    DECODE_CLEAR_SEGOVR();
 
2576
    END_OF_INSTR();
 
2577
}
 
2578
 
 
2579
/****************************************************************************
 
2580
REMARKS:
 
2581
Handles opcode 0x2d
 
2582
****************************************************************************/
 
2583
static void x86emuOp_sub_word_AX_IMM(u8 X86EMU_UNUSED(op1))
 
2584
{
 
2585
    u32 srcval;
 
2586
 
 
2587
    START_OF_INSTR();
 
2588
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
2589
        DECODE_PRINTF("SUB\tEAX,");
 
2590
        srcval = fetch_long_imm();
 
2591
    } else {
 
2592
        DECODE_PRINTF("SUB\tAX,");
 
2593
        srcval = fetch_word_imm();
 
2594
    }
 
2595
    DECODE_PRINTF2("%x\n", srcval);
 
2596
    TRACE_AND_STEP();
 
2597
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
2598
        M.x86.R_EAX = sub_long(M.x86.R_EAX, srcval);
 
2599
    } else {
 
2600
        M.x86.R_AX = sub_word(M.x86.R_AX, (u16)srcval);
 
2601
    }
 
2602
    DECODE_CLEAR_SEGOVR();
 
2603
    END_OF_INSTR();
 
2604
}
 
2605
 
 
2606
/****************************************************************************
 
2607
REMARKS:
 
2608
Handles opcode 0x2e
 
2609
****************************************************************************/
 
2610
static void x86emuOp_segovr_CS(u8 X86EMU_UNUSED(op1))
 
2611
{
 
2612
    START_OF_INSTR();
 
2613
    DECODE_PRINTF("CS:\n");
 
2614
    TRACE_AND_STEP();
 
2615
    M.x86.mode |= SYSMODE_SEGOVR_CS;
 
2616
    /* note no DECODE_CLEAR_SEGOVR here. */
 
2617
    END_OF_INSTR();
 
2618
}
 
2619
 
 
2620
/****************************************************************************
 
2621
REMARKS:
 
2622
Handles opcode 0x2f
 
2623
****************************************************************************/
 
2624
static void x86emuOp_das(u8 X86EMU_UNUSED(op1))
 
2625
{
 
2626
    START_OF_INSTR();
 
2627
    DECODE_PRINTF("DAS\n");
 
2628
    TRACE_AND_STEP();
 
2629
    M.x86.R_AL = das_byte(M.x86.R_AL);
 
2630
    DECODE_CLEAR_SEGOVR();
 
2631
    END_OF_INSTR();
 
2632
}
 
2633
 
 
2634
/****************************************************************************
 
2635
REMARKS:
 
2636
Handles opcode 0x30
 
2637
****************************************************************************/
 
2638
static void x86emuOp_xor_byte_RM_R(u8 X86EMU_UNUSED(op1))
 
2639
{
 
2640
    int mod, rl, rh;
 
2641
    u8 *destreg, *srcreg;
 
2642
    uint destoffset;
 
2643
    u8 destval;
 
2644
 
 
2645
    START_OF_INSTR();
 
2646
    DECODE_PRINTF("XOR\t");
 
2647
    FETCH_DECODE_MODRM(mod, rh, rl);
 
2648
    switch (mod) {
 
2649
    case 0:
 
2650
        destoffset = decode_rm00_address(rl);
 
2651
        DECODE_PRINTF(",");
 
2652
        destval = fetch_data_byte(destoffset);
 
2653
        srcreg = DECODE_RM_BYTE_REGISTER(rh);
 
2654
        DECODE_PRINTF("\n");
 
2655
        TRACE_AND_STEP();
 
2656
        destval = xor_byte(destval, *srcreg);
 
2657
        store_data_byte(destoffset, destval);
 
2658
        break;
 
2659
    case 1:
 
2660
        destoffset = decode_rm01_address(rl);
 
2661
        DECODE_PRINTF(",");
 
2662
        destval = fetch_data_byte(destoffset);
 
2663
        srcreg = DECODE_RM_BYTE_REGISTER(rh);
 
2664
        DECODE_PRINTF("\n");
 
2665
        TRACE_AND_STEP();
 
2666
        destval = xor_byte(destval, *srcreg);
 
2667
        store_data_byte(destoffset, destval);
 
2668
        break;
 
2669
    case 2:
 
2670
        destoffset = decode_rm10_address(rl);
 
2671
        DECODE_PRINTF(",");
 
2672
        destval = fetch_data_byte(destoffset);
 
2673
        srcreg = DECODE_RM_BYTE_REGISTER(rh);
 
2674
        DECODE_PRINTF("\n");
 
2675
        TRACE_AND_STEP();
 
2676
        destval = xor_byte(destval, *srcreg);
 
2677
        store_data_byte(destoffset, destval);
 
2678
        break;
 
2679
    case 3:                     /* register to register */
 
2680
        destreg = DECODE_RM_BYTE_REGISTER(rl);
 
2681
        DECODE_PRINTF(",");
 
2682
        srcreg = DECODE_RM_BYTE_REGISTER(rh);
 
2683
        DECODE_PRINTF("\n");
 
2684
        TRACE_AND_STEP();
 
2685
        *destreg = xor_byte(*destreg, *srcreg);
 
2686
        break;
 
2687
    }
 
2688
    DECODE_CLEAR_SEGOVR();
 
2689
    END_OF_INSTR();
 
2690
}
 
2691
 
 
2692
/****************************************************************************
 
2693
REMARKS:
 
2694
Handles opcode 0x31
 
2695
****************************************************************************/
 
2696
static void x86emuOp_xor_word_RM_R(u8 X86EMU_UNUSED(op1))
 
2697
{
 
2698
    int mod, rl, rh;
 
2699
    uint destoffset;
 
2700
 
 
2701
    START_OF_INSTR();
 
2702
    DECODE_PRINTF("XOR\t");
 
2703
    FETCH_DECODE_MODRM(mod, rh, rl);
 
2704
    switch (mod) {
 
2705
    case 0:
 
2706
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
2707
            u32 destval;
 
2708
            u32 *srcreg;
 
2709
 
 
2710
            destoffset = decode_rm00_address(rl);
 
2711
            DECODE_PRINTF(",");
 
2712
            destval = fetch_data_long(destoffset);
 
2713
            srcreg = DECODE_RM_LONG_REGISTER(rh);
 
2714
            DECODE_PRINTF("\n");
 
2715
            TRACE_AND_STEP();
 
2716
            destval = xor_long(destval, *srcreg);
 
2717
            store_data_long(destoffset, destval);
 
2718
        } else {
 
2719
            u16 destval;
 
2720
            u16 *srcreg;
 
2721
 
 
2722
            destoffset = decode_rm00_address(rl);
 
2723
            DECODE_PRINTF(",");
 
2724
            destval = fetch_data_word(destoffset);
 
2725
            srcreg = DECODE_RM_WORD_REGISTER(rh);
 
2726
            DECODE_PRINTF("\n");
 
2727
            TRACE_AND_STEP();
 
2728
            destval = xor_word(destval, *srcreg);
 
2729
            store_data_word(destoffset, destval);
 
2730
        }
 
2731
        break;
 
2732
    case 1:
 
2733
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
2734
            u32 destval;
 
2735
            u32 *srcreg;
 
2736
 
 
2737
            destoffset = decode_rm01_address(rl);
 
2738
            DECODE_PRINTF(",");
 
2739
            destval = fetch_data_long(destoffset);
 
2740
            srcreg = DECODE_RM_LONG_REGISTER(rh);
 
2741
            DECODE_PRINTF("\n");
 
2742
            TRACE_AND_STEP();
 
2743
            destval = xor_long(destval, *srcreg);
 
2744
            store_data_long(destoffset, destval);
 
2745
        } else {
 
2746
            u16 destval;
 
2747
            u16 *srcreg;
 
2748
 
 
2749
            destoffset = decode_rm01_address(rl);
 
2750
            DECODE_PRINTF(",");
 
2751
            destval = fetch_data_word(destoffset);
 
2752
            srcreg = DECODE_RM_WORD_REGISTER(rh);
 
2753
            DECODE_PRINTF("\n");
 
2754
            TRACE_AND_STEP();
 
2755
            destval = xor_word(destval, *srcreg);
 
2756
            store_data_word(destoffset, destval);
 
2757
        }
 
2758
        break;
 
2759
    case 2:
 
2760
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
2761
            u32 destval;
 
2762
            u32 *srcreg;
 
2763
 
 
2764
            destoffset = decode_rm10_address(rl);
 
2765
            DECODE_PRINTF(",");
 
2766
            destval = fetch_data_long(destoffset);
 
2767
            srcreg = DECODE_RM_LONG_REGISTER(rh);
 
2768
            DECODE_PRINTF("\n");
 
2769
            TRACE_AND_STEP();
 
2770
            destval = xor_long(destval, *srcreg);
 
2771
            store_data_long(destoffset, destval);
 
2772
        } else {
 
2773
            u16 destval;
 
2774
            u16 *srcreg;
 
2775
 
 
2776
            destoffset = decode_rm10_address(rl);
 
2777
            DECODE_PRINTF(",");
 
2778
            destval = fetch_data_word(destoffset);
 
2779
            srcreg = DECODE_RM_WORD_REGISTER(rh);
 
2780
            DECODE_PRINTF("\n");
 
2781
            TRACE_AND_STEP();
 
2782
            destval = xor_word(destval, *srcreg);
 
2783
            store_data_word(destoffset, destval);
 
2784
        }
 
2785
        break;
 
2786
    case 3:                     /* register to register */
 
2787
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
2788
            u32 *destreg,*srcreg;
 
2789
 
 
2790
            destreg = DECODE_RM_LONG_REGISTER(rl);
 
2791
            DECODE_PRINTF(",");
 
2792
            srcreg = DECODE_RM_LONG_REGISTER(rh);
 
2793
            DECODE_PRINTF("\n");
 
2794
            TRACE_AND_STEP();
 
2795
            *destreg = xor_long(*destreg, *srcreg);
 
2796
        } else {
 
2797
            u16 *destreg,*srcreg;
 
2798
 
 
2799
            destreg = DECODE_RM_WORD_REGISTER(rl);
 
2800
            DECODE_PRINTF(",");
 
2801
            srcreg = DECODE_RM_WORD_REGISTER(rh);
 
2802
            DECODE_PRINTF("\n");
 
2803
            TRACE_AND_STEP();
 
2804
            *destreg = xor_word(*destreg, *srcreg);
 
2805
        }
 
2806
        break;
 
2807
    }
 
2808
    DECODE_CLEAR_SEGOVR();
 
2809
    END_OF_INSTR();
 
2810
}
 
2811
 
 
2812
/****************************************************************************
 
2813
REMARKS:
 
2814
Handles opcode 0x32
 
2815
****************************************************************************/
 
2816
static void x86emuOp_xor_byte_R_RM(u8 X86EMU_UNUSED(op1))
 
2817
{
 
2818
    int mod, rl, rh;
 
2819
    u8 *destreg, *srcreg;
 
2820
    uint srcoffset;
 
2821
    u8 srcval;
 
2822
 
 
2823
    START_OF_INSTR();
 
2824
    DECODE_PRINTF("XOR\t");
 
2825
    FETCH_DECODE_MODRM(mod, rh, rl);
 
2826
    switch (mod) {
 
2827
    case 0:
 
2828
        destreg = DECODE_RM_BYTE_REGISTER(rh);
 
2829
        DECODE_PRINTF(",");
 
2830
        srcoffset = decode_rm00_address(rl);
 
2831
        srcval = fetch_data_byte(srcoffset);
 
2832
        DECODE_PRINTF("\n");
 
2833
        TRACE_AND_STEP();
 
2834
        *destreg = xor_byte(*destreg, srcval);
 
2835
        break;
 
2836
    case 1:
 
2837
        destreg = DECODE_RM_BYTE_REGISTER(rh);
 
2838
        DECODE_PRINTF(",");
 
2839
        srcoffset = decode_rm01_address(rl);
 
2840
        srcval = fetch_data_byte(srcoffset);
 
2841
        DECODE_PRINTF("\n");
 
2842
        TRACE_AND_STEP();
 
2843
        *destreg = xor_byte(*destreg, srcval);
 
2844
        break;
 
2845
    case 2:
 
2846
        destreg = DECODE_RM_BYTE_REGISTER(rh);
 
2847
        DECODE_PRINTF(",");
 
2848
        srcoffset = decode_rm10_address(rl);
 
2849
        srcval = fetch_data_byte(srcoffset);
 
2850
        DECODE_PRINTF("\n");
 
2851
        TRACE_AND_STEP();
 
2852
        *destreg = xor_byte(*destreg, srcval);
 
2853
        break;
 
2854
    case 3:                     /* register to register */
 
2855
        destreg = DECODE_RM_BYTE_REGISTER(rh);
 
2856
        DECODE_PRINTF(",");
 
2857
        srcreg = DECODE_RM_BYTE_REGISTER(rl);
 
2858
        DECODE_PRINTF("\n");
 
2859
        TRACE_AND_STEP();
 
2860
        *destreg = xor_byte(*destreg, *srcreg);
 
2861
        break;
 
2862
    }
 
2863
    DECODE_CLEAR_SEGOVR();
 
2864
    END_OF_INSTR();
 
2865
}
 
2866
 
 
2867
/****************************************************************************
 
2868
REMARKS:
 
2869
Handles opcode 0x33
 
2870
****************************************************************************/
 
2871
static void x86emuOp_xor_word_R_RM(u8 X86EMU_UNUSED(op1))
 
2872
{
 
2873
    int mod, rl, rh;
 
2874
    uint srcoffset;
 
2875
 
 
2876
    START_OF_INSTR();
 
2877
    DECODE_PRINTF("XOR\t");
 
2878
    FETCH_DECODE_MODRM(mod, rh, rl);
 
2879
    switch (mod) {
 
2880
    case 0:
 
2881
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
2882
            u32 *destreg;
 
2883
            u32 srcval;
 
2884
 
 
2885
            destreg = DECODE_RM_LONG_REGISTER(rh);
 
2886
            DECODE_PRINTF(",");
 
2887
            srcoffset = decode_rm00_address(rl);
 
2888
            srcval = fetch_data_long(srcoffset);
 
2889
            DECODE_PRINTF("\n");
 
2890
            TRACE_AND_STEP();
 
2891
            *destreg = xor_long(*destreg, srcval);
 
2892
        } else {
 
2893
            u16 *destreg;
 
2894
            u16 srcval;
 
2895
 
 
2896
            destreg = DECODE_RM_WORD_REGISTER(rh);
 
2897
            DECODE_PRINTF(",");
 
2898
            srcoffset = decode_rm00_address(rl);
 
2899
            srcval = fetch_data_word(srcoffset);
 
2900
            DECODE_PRINTF("\n");
 
2901
            TRACE_AND_STEP();
 
2902
            *destreg = xor_word(*destreg, srcval);
 
2903
        }
 
2904
        break;
 
2905
    case 1:
 
2906
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
2907
            u32 *destreg;
 
2908
            u32 srcval;
 
2909
 
 
2910
            destreg = DECODE_RM_LONG_REGISTER(rh);
 
2911
            DECODE_PRINTF(",");
 
2912
            srcoffset = decode_rm01_address(rl);
 
2913
            srcval = fetch_data_long(srcoffset);
 
2914
            DECODE_PRINTF("\n");
 
2915
            TRACE_AND_STEP();
 
2916
            *destreg = xor_long(*destreg, srcval);
 
2917
        } else {
 
2918
            u16 *destreg;
 
2919
            u16 srcval;
 
2920
 
 
2921
            destreg = DECODE_RM_WORD_REGISTER(rh);
 
2922
            DECODE_PRINTF(",");
 
2923
            srcoffset = decode_rm01_address(rl);
 
2924
            srcval = fetch_data_word(srcoffset);
 
2925
            DECODE_PRINTF("\n");
 
2926
            TRACE_AND_STEP();
 
2927
            *destreg = xor_word(*destreg, srcval);
 
2928
        }
 
2929
        break;
 
2930
    case 2:
 
2931
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
2932
            u32 *destreg;
 
2933
            u32 srcval;
 
2934
 
 
2935
            destreg = DECODE_RM_LONG_REGISTER(rh);
 
2936
            DECODE_PRINTF(",");
 
2937
            srcoffset = decode_rm10_address(rl);
 
2938
            srcval = fetch_data_long(srcoffset);
 
2939
            DECODE_PRINTF("\n");
 
2940
            TRACE_AND_STEP();
 
2941
            *destreg = xor_long(*destreg, srcval);
 
2942
        } else {
 
2943
            u16 *destreg;
 
2944
            u16 srcval;
 
2945
 
 
2946
            destreg = DECODE_RM_WORD_REGISTER(rh);
 
2947
            DECODE_PRINTF(",");
 
2948
            srcoffset = decode_rm10_address(rl);
 
2949
            srcval = fetch_data_word(srcoffset);
 
2950
            DECODE_PRINTF("\n");
 
2951
            TRACE_AND_STEP();
 
2952
            *destreg = xor_word(*destreg, srcval);
 
2953
        }
 
2954
        break;
 
2955
    case 3:                     /* register to register */
 
2956
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
2957
            u32 *destreg,*srcreg;
 
2958
 
 
2959
            destreg = DECODE_RM_LONG_REGISTER(rh);
 
2960
            DECODE_PRINTF(",");
 
2961
            srcreg = DECODE_RM_LONG_REGISTER(rl);
 
2962
            DECODE_PRINTF("\n");
 
2963
            TRACE_AND_STEP();
 
2964
            *destreg = xor_long(*destreg, *srcreg);
 
2965
        } else {
 
2966
            u16 *destreg,*srcreg;
 
2967
 
 
2968
            destreg = DECODE_RM_WORD_REGISTER(rh);
 
2969
            DECODE_PRINTF(",");
 
2970
            srcreg = DECODE_RM_WORD_REGISTER(rl);
 
2971
            DECODE_PRINTF("\n");
 
2972
            TRACE_AND_STEP();
 
2973
            *destreg = xor_word(*destreg, *srcreg);
 
2974
        }
 
2975
        break;
 
2976
    }
 
2977
    DECODE_CLEAR_SEGOVR();
 
2978
    END_OF_INSTR();
 
2979
}
 
2980
 
 
2981
/****************************************************************************
 
2982
REMARKS:
 
2983
Handles opcode 0x34
 
2984
****************************************************************************/
 
2985
static void x86emuOp_xor_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
 
2986
{
 
2987
    u8 srcval;
 
2988
 
 
2989
    START_OF_INSTR();
 
2990
    DECODE_PRINTF("XOR\tAL,");
 
2991
    srcval = fetch_byte_imm();
 
2992
    DECODE_PRINTF2("%x\n", srcval);
 
2993
    TRACE_AND_STEP();
 
2994
    M.x86.R_AL = xor_byte(M.x86.R_AL, srcval);
 
2995
    DECODE_CLEAR_SEGOVR();
 
2996
    END_OF_INSTR();
 
2997
}
 
2998
 
 
2999
/****************************************************************************
 
3000
REMARKS:
 
3001
Handles opcode 0x35
 
3002
****************************************************************************/
 
3003
static void x86emuOp_xor_word_AX_IMM(u8 X86EMU_UNUSED(op1))
 
3004
{
 
3005
    u32 srcval;
 
3006
 
 
3007
    START_OF_INSTR();
 
3008
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
3009
        DECODE_PRINTF("XOR\tEAX,");
 
3010
        srcval = fetch_long_imm();
 
3011
    } else {
 
3012
        DECODE_PRINTF("XOR\tAX,");
 
3013
        srcval = fetch_word_imm();
 
3014
    }
 
3015
    DECODE_PRINTF2("%x\n", srcval);
 
3016
    TRACE_AND_STEP();
 
3017
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
3018
        M.x86.R_EAX = xor_long(M.x86.R_EAX, srcval);
 
3019
    } else {
 
3020
        M.x86.R_AX = xor_word(M.x86.R_AX, (u16)srcval);
 
3021
    }
 
3022
    DECODE_CLEAR_SEGOVR();
 
3023
    END_OF_INSTR();
 
3024
}
 
3025
 
 
3026
/****************************************************************************
 
3027
REMARKS:
 
3028
Handles opcode 0x36
 
3029
****************************************************************************/
 
3030
static void x86emuOp_segovr_SS(u8 X86EMU_UNUSED(op1))
 
3031
{
 
3032
    START_OF_INSTR();
 
3033
    DECODE_PRINTF("SS:\n");
 
3034
    TRACE_AND_STEP();
 
3035
    M.x86.mode |= SYSMODE_SEGOVR_SS;
 
3036
    /* no DECODE_CLEAR_SEGOVR ! */
 
3037
    END_OF_INSTR();
 
3038
}
 
3039
 
 
3040
/****************************************************************************
 
3041
REMARKS:
 
3042
Handles opcode 0x37
 
3043
****************************************************************************/
 
3044
static void x86emuOp_aaa(u8 X86EMU_UNUSED(op1))
 
3045
{
 
3046
    START_OF_INSTR();
 
3047
    DECODE_PRINTF("AAA\n");
 
3048
    TRACE_AND_STEP();
 
3049
    M.x86.R_AX = aaa_word(M.x86.R_AX);
 
3050
    DECODE_CLEAR_SEGOVR();
 
3051
    END_OF_INSTR();
 
3052
}
 
3053
 
 
3054
/****************************************************************************
 
3055
REMARKS:
 
3056
Handles opcode 0x38
 
3057
****************************************************************************/
 
3058
static void x86emuOp_cmp_byte_RM_R(u8 X86EMU_UNUSED(op1))
 
3059
{
 
3060
    int mod, rl, rh;
 
3061
    uint destoffset;
 
3062
    u8 *destreg, *srcreg;
 
3063
    u8 destval;
 
3064
 
 
3065
    START_OF_INSTR();
 
3066
    DECODE_PRINTF("CMP\t");
 
3067
    FETCH_DECODE_MODRM(mod, rh, rl);
 
3068
    switch (mod) {
 
3069
    case 0:
 
3070
        destoffset = decode_rm00_address(rl);
 
3071
        DECODE_PRINTF(",");
 
3072
        destval = fetch_data_byte(destoffset);
 
3073
        srcreg = DECODE_RM_BYTE_REGISTER(rh);
 
3074
        DECODE_PRINTF("\n");
 
3075
        TRACE_AND_STEP();
 
3076
        cmp_byte(destval, *srcreg);
 
3077
        break;
 
3078
    case 1:
 
3079
        destoffset = decode_rm01_address(rl);
 
3080
        DECODE_PRINTF(",");
 
3081
        destval = fetch_data_byte(destoffset);
 
3082
        srcreg = DECODE_RM_BYTE_REGISTER(rh);
 
3083
        DECODE_PRINTF("\n");
 
3084
        TRACE_AND_STEP();
 
3085
        cmp_byte(destval, *srcreg);
 
3086
        break;
 
3087
    case 2:
 
3088
        destoffset = decode_rm10_address(rl);
 
3089
        DECODE_PRINTF(",");
 
3090
        destval = fetch_data_byte(destoffset);
 
3091
        srcreg = DECODE_RM_BYTE_REGISTER(rh);
 
3092
        DECODE_PRINTF("\n");
 
3093
        TRACE_AND_STEP();
 
3094
        cmp_byte(destval, *srcreg);
 
3095
        break;
 
3096
    case 3:                     /* register to register */
 
3097
        destreg = DECODE_RM_BYTE_REGISTER(rl);
 
3098
        DECODE_PRINTF(",");
 
3099
        srcreg = DECODE_RM_BYTE_REGISTER(rh);
 
3100
        DECODE_PRINTF("\n");
 
3101
        TRACE_AND_STEP();
 
3102
        cmp_byte(*destreg, *srcreg);
 
3103
        break;
 
3104
    }
 
3105
    DECODE_CLEAR_SEGOVR();
 
3106
    END_OF_INSTR();
 
3107
}
 
3108
 
 
3109
/****************************************************************************
 
3110
REMARKS:
 
3111
Handles opcode 0x39
 
3112
****************************************************************************/
 
3113
static void x86emuOp_cmp_word_RM_R(u8 X86EMU_UNUSED(op1))
 
3114
{
 
3115
    int mod, rl, rh;
 
3116
    uint destoffset;
 
3117
 
 
3118
    START_OF_INSTR();
 
3119
    DECODE_PRINTF("CMP\t");
 
3120
    FETCH_DECODE_MODRM(mod, rh, rl);
 
3121
    switch (mod) {
 
3122
    case 0:
 
3123
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
3124
            u32 destval;
 
3125
            u32 *srcreg;
 
3126
 
 
3127
            destoffset = decode_rm00_address(rl);
 
3128
            DECODE_PRINTF(",");
 
3129
            destval = fetch_data_long(destoffset);
 
3130
            srcreg = DECODE_RM_LONG_REGISTER(rh);
 
3131
            DECODE_PRINTF("\n");
 
3132
            TRACE_AND_STEP();
 
3133
            cmp_long(destval, *srcreg);
 
3134
        } else {
 
3135
            u16 destval;
 
3136
            u16 *srcreg;
 
3137
 
 
3138
            destoffset = decode_rm00_address(rl);
 
3139
            DECODE_PRINTF(",");
 
3140
            destval = fetch_data_word(destoffset);
 
3141
            srcreg = DECODE_RM_WORD_REGISTER(rh);
 
3142
            DECODE_PRINTF("\n");
 
3143
            TRACE_AND_STEP();
 
3144
            cmp_word(destval, *srcreg);
 
3145
        }
 
3146
        break;
 
3147
    case 1:
 
3148
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
3149
            u32 destval;
 
3150
            u32 *srcreg;
 
3151
 
 
3152
            destoffset = decode_rm01_address(rl);
 
3153
            DECODE_PRINTF(",");
 
3154
            destval = fetch_data_long(destoffset);
 
3155
            srcreg = DECODE_RM_LONG_REGISTER(rh);
 
3156
            DECODE_PRINTF("\n");
 
3157
            TRACE_AND_STEP();
 
3158
            cmp_long(destval, *srcreg);
 
3159
        } else {
 
3160
            u16 destval;
 
3161
            u16 *srcreg;
 
3162
 
 
3163
            destoffset = decode_rm01_address(rl);
 
3164
            DECODE_PRINTF(",");
 
3165
            destval = fetch_data_word(destoffset);
 
3166
            srcreg = DECODE_RM_WORD_REGISTER(rh);
 
3167
            DECODE_PRINTF("\n");
 
3168
            TRACE_AND_STEP();
 
3169
            cmp_word(destval, *srcreg);
 
3170
        }
 
3171
        break;
 
3172
    case 2:
 
3173
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
3174
            u32 destval;
 
3175
            u32 *srcreg;
 
3176
 
 
3177
            destoffset = decode_rm10_address(rl);
 
3178
            DECODE_PRINTF(",");
 
3179
            destval = fetch_data_long(destoffset);
 
3180
            srcreg = DECODE_RM_LONG_REGISTER(rh);
 
3181
            DECODE_PRINTF("\n");
 
3182
            TRACE_AND_STEP();
 
3183
            cmp_long(destval, *srcreg);
 
3184
        } else {
 
3185
            u16 destval;
 
3186
            u16 *srcreg;
 
3187
 
 
3188
            destoffset = decode_rm10_address(rl);
 
3189
            DECODE_PRINTF(",");
 
3190
            destval = fetch_data_word(destoffset);
 
3191
            srcreg = DECODE_RM_WORD_REGISTER(rh);
 
3192
            DECODE_PRINTF("\n");
 
3193
            TRACE_AND_STEP();
 
3194
            cmp_word(destval, *srcreg);
 
3195
        }
 
3196
        break;
 
3197
    case 3:                     /* register to register */
 
3198
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
3199
            u32 *destreg,*srcreg;
 
3200
 
 
3201
            destreg = DECODE_RM_LONG_REGISTER(rl);
 
3202
            DECODE_PRINTF(",");
 
3203
            srcreg = DECODE_RM_LONG_REGISTER(rh);
 
3204
            DECODE_PRINTF("\n");
 
3205
            TRACE_AND_STEP();
 
3206
            cmp_long(*destreg, *srcreg);
 
3207
        } else {
 
3208
            u16 *destreg,*srcreg;
 
3209
 
 
3210
            destreg = DECODE_RM_WORD_REGISTER(rl);
 
3211
            DECODE_PRINTF(",");
 
3212
            srcreg = DECODE_RM_WORD_REGISTER(rh);
 
3213
            DECODE_PRINTF("\n");
 
3214
            TRACE_AND_STEP();
 
3215
            cmp_word(*destreg, *srcreg);
 
3216
        }
 
3217
        break;
 
3218
    }
 
3219
    DECODE_CLEAR_SEGOVR();
 
3220
    END_OF_INSTR();
 
3221
}
 
3222
 
 
3223
/****************************************************************************
 
3224
REMARKS:
 
3225
Handles opcode 0x3a
 
3226
****************************************************************************/
 
3227
static void x86emuOp_cmp_byte_R_RM(u8 X86EMU_UNUSED(op1))
 
3228
{
 
3229
    int mod, rl, rh;
 
3230
    u8 *destreg, *srcreg;
 
3231
    uint srcoffset;
 
3232
    u8 srcval;
 
3233
 
 
3234
    START_OF_INSTR();
 
3235
    DECODE_PRINTF("CMP\t");
 
3236
    FETCH_DECODE_MODRM(mod, rh, rl);
 
3237
    switch (mod) {
 
3238
    case 0:
 
3239
        destreg = DECODE_RM_BYTE_REGISTER(rh);
 
3240
        DECODE_PRINTF(",");
 
3241
        srcoffset = decode_rm00_address(rl);
 
3242
        srcval = fetch_data_byte(srcoffset);
 
3243
        DECODE_PRINTF("\n");
 
3244
        TRACE_AND_STEP();
 
3245
        cmp_byte(*destreg, srcval);
 
3246
        break;
 
3247
    case 1:
 
3248
        destreg = DECODE_RM_BYTE_REGISTER(rh);
 
3249
        DECODE_PRINTF(",");
 
3250
        srcoffset = decode_rm01_address(rl);
 
3251
        srcval = fetch_data_byte(srcoffset);
 
3252
        DECODE_PRINTF("\n");
 
3253
        TRACE_AND_STEP();
 
3254
        cmp_byte(*destreg, srcval);
 
3255
        break;
 
3256
    case 2:
 
3257
        destreg = DECODE_RM_BYTE_REGISTER(rh);
 
3258
        DECODE_PRINTF(",");
 
3259
        srcoffset = decode_rm10_address(rl);
 
3260
        srcval = fetch_data_byte(srcoffset);
 
3261
        DECODE_PRINTF("\n");
 
3262
        TRACE_AND_STEP();
 
3263
        cmp_byte(*destreg, srcval);
 
3264
        break;
 
3265
    case 3:                     /* register to register */
 
3266
        destreg = DECODE_RM_BYTE_REGISTER(rh);
 
3267
        DECODE_PRINTF(",");
 
3268
        srcreg = DECODE_RM_BYTE_REGISTER(rl);
 
3269
        DECODE_PRINTF("\n");
 
3270
        TRACE_AND_STEP();
 
3271
        cmp_byte(*destreg, *srcreg);
 
3272
        break;
 
3273
    }
 
3274
    DECODE_CLEAR_SEGOVR();
 
3275
    END_OF_INSTR();
 
3276
}
 
3277
 
 
3278
/****************************************************************************
 
3279
REMARKS:
 
3280
Handles opcode 0x3b
 
3281
****************************************************************************/
 
3282
static void x86emuOp_cmp_word_R_RM(u8 X86EMU_UNUSED(op1))
 
3283
{
 
3284
    int mod, rl, rh;
 
3285
    uint srcoffset;
 
3286
 
 
3287
    START_OF_INSTR();
 
3288
    DECODE_PRINTF("CMP\t");
 
3289
    FETCH_DECODE_MODRM(mod, rh, rl);
 
3290
    switch (mod) {
 
3291
    case 0:
 
3292
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
3293
            u32 *destreg;
 
3294
            u32 srcval;
 
3295
 
 
3296
            destreg = DECODE_RM_LONG_REGISTER(rh);
 
3297
            DECODE_PRINTF(",");
 
3298
            srcoffset = decode_rm00_address(rl);
 
3299
            srcval = fetch_data_long(srcoffset);
 
3300
            DECODE_PRINTF("\n");
 
3301
            TRACE_AND_STEP();
 
3302
            cmp_long(*destreg, srcval);
 
3303
        } else {
 
3304
            u16 *destreg;
 
3305
            u16 srcval;
 
3306
 
 
3307
            destreg = DECODE_RM_WORD_REGISTER(rh);
 
3308
            DECODE_PRINTF(",");
 
3309
            srcoffset = decode_rm00_address(rl);
 
3310
            srcval = fetch_data_word(srcoffset);
 
3311
            DECODE_PRINTF("\n");
 
3312
            TRACE_AND_STEP();
 
3313
            cmp_word(*destreg, srcval);
 
3314
        }
 
3315
        break;
 
3316
    case 1:
 
3317
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
3318
            u32 *destreg;
 
3319
            u32 srcval;
 
3320
 
 
3321
            destreg = DECODE_RM_LONG_REGISTER(rh);
 
3322
            DECODE_PRINTF(",");
 
3323
            srcoffset = decode_rm01_address(rl);
 
3324
            srcval = fetch_data_long(srcoffset);
 
3325
            DECODE_PRINTF("\n");
 
3326
            TRACE_AND_STEP();
 
3327
            cmp_long(*destreg, srcval);
 
3328
        } else {
 
3329
            u16 *destreg;
 
3330
            u16 srcval;
 
3331
 
 
3332
            destreg = DECODE_RM_WORD_REGISTER(rh);
 
3333
            DECODE_PRINTF(",");
 
3334
            srcoffset = decode_rm01_address(rl);
 
3335
            srcval = fetch_data_word(srcoffset);
 
3336
            DECODE_PRINTF("\n");
 
3337
            TRACE_AND_STEP();
 
3338
            cmp_word(*destreg, srcval);
 
3339
        }
 
3340
        break;
 
3341
    case 2:
 
3342
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
3343
            u32 *destreg;
 
3344
            u32 srcval;
 
3345
 
 
3346
            destreg = DECODE_RM_LONG_REGISTER(rh);
 
3347
            DECODE_PRINTF(",");
 
3348
            srcoffset = decode_rm10_address(rl);
 
3349
            srcval = fetch_data_long(srcoffset);
 
3350
            DECODE_PRINTF("\n");
 
3351
            TRACE_AND_STEP();
 
3352
            cmp_long(*destreg, srcval);
 
3353
        } else {
 
3354
            u16 *destreg;
 
3355
            u16 srcval;
 
3356
 
 
3357
            destreg = DECODE_RM_WORD_REGISTER(rh);
 
3358
            DECODE_PRINTF(",");
 
3359
            srcoffset = decode_rm10_address(rl);
 
3360
            srcval = fetch_data_word(srcoffset);
 
3361
            DECODE_PRINTF("\n");
 
3362
            TRACE_AND_STEP();
 
3363
            cmp_word(*destreg, srcval);
 
3364
        }
 
3365
        break;
 
3366
    case 3:                     /* register to register */
 
3367
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
3368
            u32 *destreg,*srcreg;
 
3369
 
 
3370
            destreg = DECODE_RM_LONG_REGISTER(rh);
 
3371
            DECODE_PRINTF(",");
 
3372
            srcreg = DECODE_RM_LONG_REGISTER(rl);
 
3373
            DECODE_PRINTF("\n");
 
3374
            TRACE_AND_STEP();
 
3375
            cmp_long(*destreg, *srcreg);
 
3376
        } else {
 
3377
            u16 *destreg,*srcreg;
 
3378
 
 
3379
            destreg = DECODE_RM_WORD_REGISTER(rh);
 
3380
            DECODE_PRINTF(",");
 
3381
            srcreg = DECODE_RM_WORD_REGISTER(rl);
 
3382
            DECODE_PRINTF("\n");
 
3383
            TRACE_AND_STEP();
 
3384
            cmp_word(*destreg, *srcreg);
 
3385
        }
 
3386
        break;
 
3387
    }
 
3388
    DECODE_CLEAR_SEGOVR();
 
3389
    END_OF_INSTR();
 
3390
}
 
3391
 
 
3392
/****************************************************************************
 
3393
REMARKS:
 
3394
Handles opcode 0x3c
 
3395
****************************************************************************/
 
3396
static void x86emuOp_cmp_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
 
3397
{
 
3398
    u8 srcval;
 
3399
 
 
3400
    START_OF_INSTR();
 
3401
    DECODE_PRINTF("CMP\tAL,");
 
3402
    srcval = fetch_byte_imm();
 
3403
    DECODE_PRINTF2("%x\n", srcval);
 
3404
    TRACE_AND_STEP();
 
3405
    cmp_byte(M.x86.R_AL, srcval);
 
3406
    DECODE_CLEAR_SEGOVR();
 
3407
    END_OF_INSTR();
 
3408
}
 
3409
 
 
3410
/****************************************************************************
 
3411
REMARKS:
 
3412
Handles opcode 0x3d
 
3413
****************************************************************************/
 
3414
static void x86emuOp_cmp_word_AX_IMM(u8 X86EMU_UNUSED(op1))
 
3415
{
 
3416
    u32 srcval;
 
3417
 
 
3418
    START_OF_INSTR();
 
3419
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
3420
        DECODE_PRINTF("CMP\tEAX,");
 
3421
        srcval = fetch_long_imm();
 
3422
    } else {
 
3423
        DECODE_PRINTF("CMP\tAX,");
 
3424
        srcval = fetch_word_imm();
 
3425
    }
 
3426
    DECODE_PRINTF2("%x\n", srcval);
 
3427
    TRACE_AND_STEP();
 
3428
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
3429
        cmp_long(M.x86.R_EAX, srcval);
 
3430
    } else {
 
3431
        cmp_word(M.x86.R_AX, (u16)srcval);
 
3432
    }
 
3433
    DECODE_CLEAR_SEGOVR();
 
3434
    END_OF_INSTR();
 
3435
}
 
3436
 
 
3437
/****************************************************************************
 
3438
REMARKS:
 
3439
Handles opcode 0x3e
 
3440
****************************************************************************/
 
3441
static void x86emuOp_segovr_DS(u8 X86EMU_UNUSED(op1))
 
3442
{
 
3443
    START_OF_INSTR();
 
3444
    DECODE_PRINTF("DS:\n");
 
3445
    TRACE_AND_STEP();
 
3446
    M.x86.mode |= SYSMODE_SEGOVR_DS;
 
3447
    /* NO DECODE_CLEAR_SEGOVR! */
 
3448
    END_OF_INSTR();
 
3449
}
 
3450
 
 
3451
/****************************************************************************
 
3452
REMARKS:
 
3453
Handles opcode 0x3f
 
3454
****************************************************************************/
 
3455
static void x86emuOp_aas(u8 X86EMU_UNUSED(op1))
 
3456
{
 
3457
    START_OF_INSTR();
 
3458
    DECODE_PRINTF("AAS\n");
 
3459
    TRACE_AND_STEP();
 
3460
    M.x86.R_AX = aas_word(M.x86.R_AX);
 
3461
    DECODE_CLEAR_SEGOVR();
 
3462
    END_OF_INSTR();
 
3463
}
 
3464
 
 
3465
/****************************************************************************
 
3466
REMARKS:
 
3467
Handles opcode 0x40
 
3468
****************************************************************************/
 
3469
static void x86emuOp_inc_AX(u8 X86EMU_UNUSED(op1))
 
3470
{
 
3471
    START_OF_INSTR();
 
3472
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
3473
        DECODE_PRINTF("INC\tEAX\n");
 
3474
    } else {
 
3475
        DECODE_PRINTF("INC\tAX\n");
 
3476
    }
 
3477
    TRACE_AND_STEP();
 
3478
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
3479
        M.x86.R_EAX = inc_long(M.x86.R_EAX);
 
3480
    } else {
 
3481
        M.x86.R_AX = inc_word(M.x86.R_AX);
 
3482
    }
 
3483
    DECODE_CLEAR_SEGOVR();
 
3484
    END_OF_INSTR();
 
3485
}
 
3486
 
 
3487
/****************************************************************************
 
3488
REMARKS:
 
3489
Handles opcode 0x41
 
3490
****************************************************************************/
 
3491
static void x86emuOp_inc_CX(u8 X86EMU_UNUSED(op1))
 
3492
{
 
3493
    START_OF_INSTR();
 
3494
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
3495
        DECODE_PRINTF("INC\tECX\n");
 
3496
    } else {
 
3497
        DECODE_PRINTF("INC\tCX\n");
 
3498
    }
 
3499
    TRACE_AND_STEP();
 
3500
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
3501
        M.x86.R_ECX = inc_long(M.x86.R_ECX);
 
3502
    } else {
 
3503
        M.x86.R_CX = inc_word(M.x86.R_CX);
 
3504
    }
 
3505
    DECODE_CLEAR_SEGOVR();
 
3506
    END_OF_INSTR();
 
3507
}
 
3508
 
 
3509
/****************************************************************************
 
3510
REMARKS:
 
3511
Handles opcode 0x42
 
3512
****************************************************************************/
 
3513
static void x86emuOp_inc_DX(u8 X86EMU_UNUSED(op1))
 
3514
{
 
3515
    START_OF_INSTR();
 
3516
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
3517
        DECODE_PRINTF("INC\tEDX\n");
 
3518
    } else {
 
3519
        DECODE_PRINTF("INC\tDX\n");
 
3520
    }
 
3521
    TRACE_AND_STEP();
 
3522
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
3523
        M.x86.R_EDX = inc_long(M.x86.R_EDX);
 
3524
    } else {
 
3525
        M.x86.R_DX = inc_word(M.x86.R_DX);
 
3526
    }
 
3527
    DECODE_CLEAR_SEGOVR();
 
3528
    END_OF_INSTR();
 
3529
}
 
3530
 
 
3531
/****************************************************************************
 
3532
REMARKS:
 
3533
Handles opcode 0x43
 
3534
****************************************************************************/
 
3535
static void x86emuOp_inc_BX(u8 X86EMU_UNUSED(op1))
 
3536
{
 
3537
    START_OF_INSTR();
 
3538
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
3539
        DECODE_PRINTF("INC\tEBX\n");
 
3540
    } else {
 
3541
        DECODE_PRINTF("INC\tBX\n");
 
3542
    }
 
3543
    TRACE_AND_STEP();
 
3544
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
3545
        M.x86.R_EBX = inc_long(M.x86.R_EBX);
 
3546
    } else {
 
3547
        M.x86.R_BX = inc_word(M.x86.R_BX);
 
3548
    }
 
3549
    DECODE_CLEAR_SEGOVR();
 
3550
    END_OF_INSTR();
 
3551
}
 
3552
 
 
3553
/****************************************************************************
 
3554
REMARKS:
 
3555
Handles opcode 0x44
 
3556
****************************************************************************/
 
3557
static void x86emuOp_inc_SP(u8 X86EMU_UNUSED(op1))
 
3558
{
 
3559
    START_OF_INSTR();
 
3560
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
3561
        DECODE_PRINTF("INC\tESP\n");
 
3562
    } else {
 
3563
        DECODE_PRINTF("INC\tSP\n");
 
3564
    }
 
3565
    TRACE_AND_STEP();
 
3566
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
3567
        M.x86.R_ESP = inc_long(M.x86.R_ESP);
 
3568
    } else {
 
3569
        M.x86.R_SP = inc_word(M.x86.R_SP);
 
3570
    }
 
3571
    DECODE_CLEAR_SEGOVR();
 
3572
    END_OF_INSTR();
 
3573
}
 
3574
 
 
3575
/****************************************************************************
 
3576
REMARKS:
 
3577
Handles opcode 0x45
 
3578
****************************************************************************/
 
3579
static void x86emuOp_inc_BP(u8 X86EMU_UNUSED(op1))
 
3580
{
 
3581
    START_OF_INSTR();
 
3582
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
3583
        DECODE_PRINTF("INC\tEBP\n");
 
3584
    } else {
 
3585
        DECODE_PRINTF("INC\tBP\n");
 
3586
    }
 
3587
    TRACE_AND_STEP();
 
3588
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
3589
        M.x86.R_EBP = inc_long(M.x86.R_EBP);
 
3590
    } else {
 
3591
        M.x86.R_BP = inc_word(M.x86.R_BP);
 
3592
    }
 
3593
    DECODE_CLEAR_SEGOVR();
 
3594
    END_OF_INSTR();
 
3595
}
 
3596
 
 
3597
/****************************************************************************
 
3598
REMARKS:
 
3599
Handles opcode 0x46
 
3600
****************************************************************************/
 
3601
static void x86emuOp_inc_SI(u8 X86EMU_UNUSED(op1))
 
3602
{
 
3603
    START_OF_INSTR();
 
3604
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
3605
        DECODE_PRINTF("INC\tESI\n");
 
3606
    } else {
 
3607
        DECODE_PRINTF("INC\tSI\n");
 
3608
    }
 
3609
    TRACE_AND_STEP();
 
3610
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
3611
        M.x86.R_ESI = inc_long(M.x86.R_ESI);
 
3612
    } else {
 
3613
        M.x86.R_SI = inc_word(M.x86.R_SI);
 
3614
    }
 
3615
    DECODE_CLEAR_SEGOVR();
 
3616
    END_OF_INSTR();
 
3617
}
 
3618
 
 
3619
/****************************************************************************
 
3620
REMARKS:
 
3621
Handles opcode 0x47
 
3622
****************************************************************************/
 
3623
static void x86emuOp_inc_DI(u8 X86EMU_UNUSED(op1))
 
3624
{
 
3625
    START_OF_INSTR();
 
3626
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
3627
        DECODE_PRINTF("INC\tEDI\n");
 
3628
    } else {
 
3629
        DECODE_PRINTF("INC\tDI\n");
 
3630
    }
 
3631
    TRACE_AND_STEP();
 
3632
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
3633
        M.x86.R_EDI = inc_long(M.x86.R_EDI);
 
3634
    } else {
 
3635
        M.x86.R_DI = inc_word(M.x86.R_DI);
 
3636
    }
 
3637
    DECODE_CLEAR_SEGOVR();
 
3638
    END_OF_INSTR();
 
3639
}
 
3640
 
 
3641
/****************************************************************************
 
3642
REMARKS:
 
3643
Handles opcode 0x48
 
3644
****************************************************************************/
 
3645
static void x86emuOp_dec_AX(u8 X86EMU_UNUSED(op1))
 
3646
{
 
3647
    START_OF_INSTR();
 
3648
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
3649
        DECODE_PRINTF("DEC\tEAX\n");
 
3650
    } else {
 
3651
        DECODE_PRINTF("DEC\tAX\n");
 
3652
    }
 
3653
    TRACE_AND_STEP();
 
3654
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
3655
        M.x86.R_EAX = dec_long(M.x86.R_EAX);
 
3656
    } else {
 
3657
        M.x86.R_AX = dec_word(M.x86.R_AX);
 
3658
    }
 
3659
    DECODE_CLEAR_SEGOVR();
 
3660
    END_OF_INSTR();
 
3661
}
 
3662
 
 
3663
/****************************************************************************
 
3664
REMARKS:
 
3665
Handles opcode 0x49
 
3666
****************************************************************************/
 
3667
static void x86emuOp_dec_CX(u8 X86EMU_UNUSED(op1))
 
3668
{
 
3669
    START_OF_INSTR();
 
3670
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
3671
        DECODE_PRINTF("DEC\tECX\n");
 
3672
    } else {
 
3673
        DECODE_PRINTF("DEC\tCX\n");
 
3674
    }
 
3675
    TRACE_AND_STEP();
 
3676
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
3677
        M.x86.R_ECX = dec_long(M.x86.R_ECX);
 
3678
    } else {
 
3679
        M.x86.R_CX = dec_word(M.x86.R_CX);
 
3680
    }
 
3681
    DECODE_CLEAR_SEGOVR();
 
3682
    END_OF_INSTR();
 
3683
}
 
3684
 
 
3685
/****************************************************************************
 
3686
REMARKS:
 
3687
Handles opcode 0x4a
 
3688
****************************************************************************/
 
3689
static void x86emuOp_dec_DX(u8 X86EMU_UNUSED(op1))
 
3690
{
 
3691
    START_OF_INSTR();
 
3692
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
3693
        DECODE_PRINTF("DEC\tEDX\n");
 
3694
    } else {
 
3695
        DECODE_PRINTF("DEC\tDX\n");
 
3696
    }
 
3697
    TRACE_AND_STEP();
 
3698
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
3699
        M.x86.R_EDX = dec_long(M.x86.R_EDX);
 
3700
    } else {
 
3701
        M.x86.R_DX = dec_word(M.x86.R_DX);
 
3702
    }
 
3703
    DECODE_CLEAR_SEGOVR();
 
3704
    END_OF_INSTR();
 
3705
}
 
3706
 
 
3707
/****************************************************************************
 
3708
REMARKS:
 
3709
Handles opcode 0x4b
 
3710
****************************************************************************/
 
3711
static void x86emuOp_dec_BX(u8 X86EMU_UNUSED(op1))
 
3712
{
 
3713
    START_OF_INSTR();
 
3714
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
3715
        DECODE_PRINTF("DEC\tEBX\n");
 
3716
    } else {
 
3717
        DECODE_PRINTF("DEC\tBX\n");
 
3718
    }
 
3719
    TRACE_AND_STEP();
 
3720
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
3721
        M.x86.R_EBX = dec_long(M.x86.R_EBX);
 
3722
    } else {
 
3723
        M.x86.R_BX = dec_word(M.x86.R_BX);
 
3724
    }
 
3725
    DECODE_CLEAR_SEGOVR();
 
3726
    END_OF_INSTR();
 
3727
}
 
3728
 
 
3729
/****************************************************************************
 
3730
REMARKS:
 
3731
Handles opcode 0x4c
 
3732
****************************************************************************/
 
3733
static void x86emuOp_dec_SP(u8 X86EMU_UNUSED(op1))
 
3734
{
 
3735
    START_OF_INSTR();
 
3736
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
3737
        DECODE_PRINTF("DEC\tESP\n");
 
3738
    } else {
 
3739
        DECODE_PRINTF("DEC\tSP\n");
 
3740
    }
 
3741
    TRACE_AND_STEP();
 
3742
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
3743
        M.x86.R_ESP = dec_long(M.x86.R_ESP);
 
3744
    } else {
 
3745
        M.x86.R_SP = dec_word(M.x86.R_SP);
 
3746
    }
 
3747
    DECODE_CLEAR_SEGOVR();
 
3748
    END_OF_INSTR();
 
3749
}
 
3750
 
 
3751
/****************************************************************************
 
3752
REMARKS:
 
3753
Handles opcode 0x4d
 
3754
****************************************************************************/
 
3755
static void x86emuOp_dec_BP(u8 X86EMU_UNUSED(op1))
 
3756
{
 
3757
    START_OF_INSTR();
 
3758
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
3759
        DECODE_PRINTF("DEC\tEBP\n");
 
3760
    } else {
 
3761
        DECODE_PRINTF("DEC\tBP\n");
 
3762
    }
 
3763
    TRACE_AND_STEP();
 
3764
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
3765
        M.x86.R_EBP = dec_long(M.x86.R_EBP);
 
3766
    } else {
 
3767
        M.x86.R_BP = dec_word(M.x86.R_BP);
 
3768
    }
 
3769
    DECODE_CLEAR_SEGOVR();
 
3770
    END_OF_INSTR();
 
3771
}
 
3772
 
 
3773
/****************************************************************************
 
3774
REMARKS:
 
3775
Handles opcode 0x4e
 
3776
****************************************************************************/
 
3777
static void x86emuOp_dec_SI(u8 X86EMU_UNUSED(op1))
 
3778
{
 
3779
    START_OF_INSTR();
 
3780
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
3781
        DECODE_PRINTF("DEC\tESI\n");
 
3782
    } else {
 
3783
        DECODE_PRINTF("DEC\tSI\n");
 
3784
    }
 
3785
    TRACE_AND_STEP();
 
3786
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
3787
        M.x86.R_ESI = dec_long(M.x86.R_ESI);
 
3788
    } else {
 
3789
        M.x86.R_SI = dec_word(M.x86.R_SI);
 
3790
    }
 
3791
    DECODE_CLEAR_SEGOVR();
 
3792
    END_OF_INSTR();
 
3793
}
 
3794
 
 
3795
/****************************************************************************
 
3796
REMARKS:
 
3797
Handles opcode 0x4f
 
3798
****************************************************************************/
 
3799
static void x86emuOp_dec_DI(u8 X86EMU_UNUSED(op1))
 
3800
{
 
3801
    START_OF_INSTR();
 
3802
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
3803
        DECODE_PRINTF("DEC\tEDI\n");
 
3804
    } else {
 
3805
        DECODE_PRINTF("DEC\tDI\n");
 
3806
    }
 
3807
    TRACE_AND_STEP();
 
3808
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
3809
        M.x86.R_EDI = dec_long(M.x86.R_EDI);
 
3810
    } else {
 
3811
        M.x86.R_DI = dec_word(M.x86.R_DI);
 
3812
    }
 
3813
    DECODE_CLEAR_SEGOVR();
 
3814
    END_OF_INSTR();
 
3815
}
 
3816
 
 
3817
/****************************************************************************
 
3818
REMARKS:
 
3819
Handles opcode 0x50
 
3820
****************************************************************************/
 
3821
static void x86emuOp_push_AX(u8 X86EMU_UNUSED(op1))
 
3822
{
 
3823
    START_OF_INSTR();
 
3824
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
3825
        DECODE_PRINTF("PUSH\tEAX\n");
 
3826
    } else {
 
3827
        DECODE_PRINTF("PUSH\tAX\n");
 
3828
    }
 
3829
    TRACE_AND_STEP();
 
3830
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
3831
        push_long(M.x86.R_EAX);
 
3832
    } else {
 
3833
        push_word(M.x86.R_AX);
 
3834
    }
 
3835
    DECODE_CLEAR_SEGOVR();
 
3836
    END_OF_INSTR();
 
3837
}
 
3838
 
 
3839
/****************************************************************************
 
3840
REMARKS:
 
3841
Handles opcode 0x51
 
3842
****************************************************************************/
 
3843
static void x86emuOp_push_CX(u8 X86EMU_UNUSED(op1))
 
3844
{
 
3845
    START_OF_INSTR();
 
3846
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
3847
        DECODE_PRINTF("PUSH\tECX\n");
 
3848
    } else {
 
3849
        DECODE_PRINTF("PUSH\tCX\n");
 
3850
    }
 
3851
    TRACE_AND_STEP();
 
3852
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
3853
        push_long(M.x86.R_ECX);
 
3854
    } else {
 
3855
        push_word(M.x86.R_CX);
 
3856
    }
 
3857
    DECODE_CLEAR_SEGOVR();
 
3858
    END_OF_INSTR();
 
3859
}
 
3860
 
 
3861
/****************************************************************************
 
3862
REMARKS:
 
3863
Handles opcode 0x52
 
3864
****************************************************************************/
 
3865
static void x86emuOp_push_DX(u8 X86EMU_UNUSED(op1))
 
3866
{
 
3867
    START_OF_INSTR();
 
3868
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
3869
        DECODE_PRINTF("PUSH\tEDX\n");
 
3870
    } else {
 
3871
        DECODE_PRINTF("PUSH\tDX\n");
 
3872
    }
 
3873
    TRACE_AND_STEP();
 
3874
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
3875
        push_long(M.x86.R_EDX);
 
3876
    } else {
 
3877
        push_word(M.x86.R_DX);
 
3878
    }
 
3879
    DECODE_CLEAR_SEGOVR();
 
3880
    END_OF_INSTR();
 
3881
}
 
3882
 
 
3883
/****************************************************************************
 
3884
REMARKS:
 
3885
Handles opcode 0x53
 
3886
****************************************************************************/
 
3887
static void x86emuOp_push_BX(u8 X86EMU_UNUSED(op1))
 
3888
{
 
3889
    START_OF_INSTR();
 
3890
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
3891
        DECODE_PRINTF("PUSH\tEBX\n");
 
3892
    } else {
 
3893
        DECODE_PRINTF("PUSH\tBX\n");
 
3894
    }
 
3895
    TRACE_AND_STEP();
 
3896
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
3897
        push_long(M.x86.R_EBX);
 
3898
    } else {
 
3899
        push_word(M.x86.R_BX);
 
3900
    }
 
3901
    DECODE_CLEAR_SEGOVR();
 
3902
    END_OF_INSTR();
 
3903
}
 
3904
 
 
3905
/****************************************************************************
 
3906
REMARKS:
 
3907
Handles opcode 0x54
 
3908
****************************************************************************/
 
3909
static void x86emuOp_push_SP(u8 X86EMU_UNUSED(op1))
 
3910
{
 
3911
    START_OF_INSTR();
 
3912
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
3913
        DECODE_PRINTF("PUSH\tESP\n");
 
3914
    } else {
 
3915
        DECODE_PRINTF("PUSH\tSP\n");
 
3916
    }
 
3917
    TRACE_AND_STEP();
 
3918
        /* Always push (E)SP, since we are emulating an i386 and above
 
3919
         * processor. This is necessary as some BIOS'es use this to check
 
3920
         * what type of processor is in the system.
 
3921
         */
 
3922
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
3923
                push_long(M.x86.R_ESP);
 
3924
        } else {
 
3925
                push_word((u16)(M.x86.R_SP));
 
3926
    }
 
3927
    DECODE_CLEAR_SEGOVR();
 
3928
    END_OF_INSTR();
 
3929
}
 
3930
 
 
3931
/****************************************************************************
 
3932
REMARKS:
 
3933
Handles opcode 0x55
 
3934
****************************************************************************/
 
3935
static void x86emuOp_push_BP(u8 X86EMU_UNUSED(op1))
 
3936
{
 
3937
    START_OF_INSTR();
 
3938
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
3939
        DECODE_PRINTF("PUSH\tEBP\n");
 
3940
    } else {
 
3941
        DECODE_PRINTF("PUSH\tBP\n");
 
3942
    }
 
3943
    TRACE_AND_STEP();
 
3944
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
3945
        push_long(M.x86.R_EBP);
 
3946
    } else {
 
3947
        push_word(M.x86.R_BP);
 
3948
    }
 
3949
    DECODE_CLEAR_SEGOVR();
 
3950
    END_OF_INSTR();
 
3951
}
 
3952
 
 
3953
/****************************************************************************
 
3954
REMARKS:
 
3955
Handles opcode 0x56
 
3956
****************************************************************************/
 
3957
static void x86emuOp_push_SI(u8 X86EMU_UNUSED(op1))
 
3958
{
 
3959
    START_OF_INSTR();
 
3960
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
3961
        DECODE_PRINTF("PUSH\tESI\n");
 
3962
    } else {
 
3963
        DECODE_PRINTF("PUSH\tSI\n");
 
3964
    }
 
3965
    TRACE_AND_STEP();
 
3966
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
3967
        push_long(M.x86.R_ESI);
 
3968
    } else {
 
3969
        push_word(M.x86.R_SI);
 
3970
    }
 
3971
    DECODE_CLEAR_SEGOVR();
 
3972
    END_OF_INSTR();
 
3973
}
 
3974
 
 
3975
/****************************************************************************
 
3976
REMARKS:
 
3977
Handles opcode 0x57
 
3978
****************************************************************************/
 
3979
static void x86emuOp_push_DI(u8 X86EMU_UNUSED(op1))
 
3980
{
 
3981
    START_OF_INSTR();
 
3982
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
3983
        DECODE_PRINTF("PUSH\tEDI\n");
 
3984
    } else {
 
3985
        DECODE_PRINTF("PUSH\tDI\n");
 
3986
    }
 
3987
    TRACE_AND_STEP();
 
3988
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
3989
        push_long(M.x86.R_EDI);
 
3990
    } else {
 
3991
        push_word(M.x86.R_DI);
 
3992
    }
 
3993
    DECODE_CLEAR_SEGOVR();
 
3994
    END_OF_INSTR();
 
3995
}
 
3996
 
 
3997
/****************************************************************************
 
3998
REMARKS:
 
3999
Handles opcode 0x58
 
4000
****************************************************************************/
 
4001
static void x86emuOp_pop_AX(u8 X86EMU_UNUSED(op1))
 
4002
{
 
4003
    START_OF_INSTR();
 
4004
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
4005
        DECODE_PRINTF("POP\tEAX\n");
 
4006
    } else {
 
4007
        DECODE_PRINTF("POP\tAX\n");
 
4008
    }
 
4009
    TRACE_AND_STEP();
 
4010
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
4011
        M.x86.R_EAX = pop_long();
 
4012
    } else {
 
4013
        M.x86.R_AX = pop_word();
 
4014
    }
 
4015
    DECODE_CLEAR_SEGOVR();
 
4016
    END_OF_INSTR();
 
4017
}
 
4018
 
 
4019
/****************************************************************************
 
4020
REMARKS:
 
4021
Handles opcode 0x59
 
4022
****************************************************************************/
 
4023
static void x86emuOp_pop_CX(u8 X86EMU_UNUSED(op1))
 
4024
{
 
4025
    START_OF_INSTR();
 
4026
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
4027
        DECODE_PRINTF("POP\tECX\n");
 
4028
    } else {
 
4029
        DECODE_PRINTF("POP\tCX\n");
 
4030
    }
 
4031
    TRACE_AND_STEP();
 
4032
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
4033
        M.x86.R_ECX = pop_long();
 
4034
    } else {
 
4035
        M.x86.R_CX = pop_word();
 
4036
    }
 
4037
    DECODE_CLEAR_SEGOVR();
 
4038
    END_OF_INSTR();
 
4039
}
 
4040
 
 
4041
/****************************************************************************
 
4042
REMARKS:
 
4043
Handles opcode 0x5a
 
4044
****************************************************************************/
 
4045
static void x86emuOp_pop_DX(u8 X86EMU_UNUSED(op1))
 
4046
{
 
4047
    START_OF_INSTR();
 
4048
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
4049
        DECODE_PRINTF("POP\tEDX\n");
 
4050
    } else {
 
4051
        DECODE_PRINTF("POP\tDX\n");
 
4052
    }
 
4053
    TRACE_AND_STEP();
 
4054
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
4055
        M.x86.R_EDX = pop_long();
 
4056
    } else {
 
4057
        M.x86.R_DX = pop_word();
 
4058
    }
 
4059
    DECODE_CLEAR_SEGOVR();
 
4060
    END_OF_INSTR();
 
4061
}
 
4062
 
 
4063
/****************************************************************************
 
4064
REMARKS:
 
4065
Handles opcode 0x5b
 
4066
****************************************************************************/
 
4067
static void x86emuOp_pop_BX(u8 X86EMU_UNUSED(op1))
 
4068
{
 
4069
    START_OF_INSTR();
 
4070
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
4071
        DECODE_PRINTF("POP\tEBX\n");
 
4072
    } else {
 
4073
        DECODE_PRINTF("POP\tBX\n");
 
4074
    }
 
4075
    TRACE_AND_STEP();
 
4076
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
4077
        M.x86.R_EBX = pop_long();
 
4078
    } else {
 
4079
        M.x86.R_BX = pop_word();
 
4080
    }
 
4081
    DECODE_CLEAR_SEGOVR();
 
4082
    END_OF_INSTR();
 
4083
}
 
4084
 
 
4085
/****************************************************************************
 
4086
REMARKS:
 
4087
Handles opcode 0x5c
 
4088
****************************************************************************/
 
4089
static void x86emuOp_pop_SP(u8 X86EMU_UNUSED(op1))
 
4090
{
 
4091
    START_OF_INSTR();
 
4092
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
4093
        DECODE_PRINTF("POP\tESP\n");
 
4094
    } else {
 
4095
        DECODE_PRINTF("POP\tSP\n");
 
4096
    }
 
4097
    TRACE_AND_STEP();
 
4098
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
4099
        M.x86.R_ESP = pop_long();
 
4100
    } else {
 
4101
        M.x86.R_SP = pop_word();
 
4102
    }
 
4103
    DECODE_CLEAR_SEGOVR();
 
4104
    END_OF_INSTR();
 
4105
}
 
4106
 
 
4107
/****************************************************************************
 
4108
REMARKS:
 
4109
Handles opcode 0x5d
 
4110
****************************************************************************/
 
4111
static void x86emuOp_pop_BP(u8 X86EMU_UNUSED(op1))
 
4112
{
 
4113
    START_OF_INSTR();
 
4114
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
4115
        DECODE_PRINTF("POP\tEBP\n");
 
4116
    } else {
 
4117
        DECODE_PRINTF("POP\tBP\n");
 
4118
    }
 
4119
    TRACE_AND_STEP();
 
4120
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
4121
        M.x86.R_EBP = pop_long();
 
4122
    } else {
 
4123
        M.x86.R_BP = pop_word();
 
4124
    }
 
4125
    DECODE_CLEAR_SEGOVR();
 
4126
    END_OF_INSTR();
 
4127
}
 
4128
 
 
4129
/****************************************************************************
 
4130
REMARKS:
 
4131
Handles opcode 0x5e
 
4132
****************************************************************************/
 
4133
static void x86emuOp_pop_SI(u8 X86EMU_UNUSED(op1))
 
4134
{
 
4135
    START_OF_INSTR();
 
4136
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
4137
        DECODE_PRINTF("POP\tESI\n");
 
4138
    } else {
 
4139
        DECODE_PRINTF("POP\tSI\n");
 
4140
    }
 
4141
    TRACE_AND_STEP();
 
4142
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
4143
        M.x86.R_ESI = pop_long();
 
4144
    } else {
 
4145
        M.x86.R_SI = pop_word();
 
4146
    }
 
4147
    DECODE_CLEAR_SEGOVR();
 
4148
    END_OF_INSTR();
 
4149
}
 
4150
 
 
4151
/****************************************************************************
 
4152
REMARKS:
 
4153
Handles opcode 0x5f
 
4154
****************************************************************************/
 
4155
static void x86emuOp_pop_DI(u8 X86EMU_UNUSED(op1))
 
4156
{
 
4157
    START_OF_INSTR();
 
4158
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
4159
        DECODE_PRINTF("POP\tEDI\n");
 
4160
    } else {
 
4161
        DECODE_PRINTF("POP\tDI\n");
 
4162
    }
 
4163
    TRACE_AND_STEP();
 
4164
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
4165
        M.x86.R_EDI = pop_long();
 
4166
    } else {
 
4167
        M.x86.R_DI = pop_word();
 
4168
    }
 
4169
    DECODE_CLEAR_SEGOVR();
 
4170
    END_OF_INSTR();
 
4171
}
 
4172
 
 
4173
/****************************************************************************
 
4174
REMARKS:
 
4175
Handles opcode 0x60
 
4176
****************************************************************************/
 
4177
static void x86emuOp_push_all(u8 X86EMU_UNUSED(op1))
 
4178
{
 
4179
    START_OF_INSTR();
 
4180
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
4181
        DECODE_PRINTF("PUSHAD\n");
 
4182
    } else {
 
4183
        DECODE_PRINTF("PUSHA\n");
 
4184
    }
 
4185
    TRACE_AND_STEP();
 
4186
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
4187
        u32 old_sp = M.x86.R_ESP;
 
4188
 
 
4189
        push_long(M.x86.R_EAX);
 
4190
        push_long(M.x86.R_ECX);
 
4191
        push_long(M.x86.R_EDX);
 
4192
        push_long(M.x86.R_EBX);
 
4193
        push_long(old_sp);
 
4194
        push_long(M.x86.R_EBP);
 
4195
        push_long(M.x86.R_ESI);
 
4196
        push_long(M.x86.R_EDI);
 
4197
    } else {
 
4198
        u16 old_sp = M.x86.R_SP;
 
4199
 
 
4200
        push_word(M.x86.R_AX);
 
4201
        push_word(M.x86.R_CX);
 
4202
        push_word(M.x86.R_DX);
 
4203
        push_word(M.x86.R_BX);
 
4204
        push_word(old_sp);
 
4205
        push_word(M.x86.R_BP);
 
4206
        push_word(M.x86.R_SI);
 
4207
        push_word(M.x86.R_DI);
 
4208
    }
 
4209
    DECODE_CLEAR_SEGOVR();
 
4210
    END_OF_INSTR();
 
4211
}
 
4212
 
 
4213
/****************************************************************************
 
4214
REMARKS:
 
4215
Handles opcode 0x61
 
4216
****************************************************************************/
 
4217
static void x86emuOp_pop_all(u8 X86EMU_UNUSED(op1))
 
4218
{
 
4219
    START_OF_INSTR();
 
4220
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
4221
        DECODE_PRINTF("POPAD\n");
 
4222
    } else {
 
4223
        DECODE_PRINTF("POPA\n");
 
4224
    }
 
4225
    TRACE_AND_STEP();
 
4226
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
4227
        M.x86.R_EDI = pop_long();
 
4228
        M.x86.R_ESI = pop_long();
 
4229
        M.x86.R_EBP = pop_long();
 
4230
        M.x86.R_ESP += 4;              /* skip ESP */
 
4231
        M.x86.R_EBX = pop_long();
 
4232
        M.x86.R_EDX = pop_long();
 
4233
        M.x86.R_ECX = pop_long();
 
4234
        M.x86.R_EAX = pop_long();
 
4235
    } else {
 
4236
        M.x86.R_DI = pop_word();
 
4237
        M.x86.R_SI = pop_word();
 
4238
        M.x86.R_BP = pop_word();
 
4239
        M.x86.R_SP += 2;               /* skip SP */
 
4240
        M.x86.R_BX = pop_word();
 
4241
        M.x86.R_DX = pop_word();
 
4242
        M.x86.R_CX = pop_word();
 
4243
        M.x86.R_AX = pop_word();
 
4244
    }
 
4245
    DECODE_CLEAR_SEGOVR();
 
4246
    END_OF_INSTR();
 
4247
}
 
4248
 
 
4249
/*opcode 0x62   ILLEGAL OP, calls x86emuOp_illegal_op() */
 
4250
/*opcode 0x63   ILLEGAL OP, calls x86emuOp_illegal_op() */
 
4251
 
 
4252
/****************************************************************************
 
4253
REMARKS:
 
4254
Handles opcode 0x64
 
4255
****************************************************************************/
 
4256
static void x86emuOp_segovr_FS(u8 X86EMU_UNUSED(op1))
 
4257
{
 
4258
    START_OF_INSTR();
 
4259
    DECODE_PRINTF("FS:\n");
 
4260
    TRACE_AND_STEP();
 
4261
    M.x86.mode |= SYSMODE_SEGOVR_FS;
 
4262
    /*
 
4263
     * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
 
4264
     * opcode subroutines we do not want to do this.
 
4265
     */
 
4266
    END_OF_INSTR();
 
4267
}
 
4268
 
 
4269
/****************************************************************************
 
4270
REMARKS:
 
4271
Handles opcode 0x65
 
4272
****************************************************************************/
 
4273
static void x86emuOp_segovr_GS(u8 X86EMU_UNUSED(op1))
 
4274
{
 
4275
    START_OF_INSTR();
 
4276
    DECODE_PRINTF("GS:\n");
 
4277
    TRACE_AND_STEP();
 
4278
    M.x86.mode |= SYSMODE_SEGOVR_GS;
 
4279
    /*
 
4280
     * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
 
4281
     * opcode subroutines we do not want to do this.
 
4282
     */
 
4283
    END_OF_INSTR();
 
4284
}
 
4285
 
 
4286
/****************************************************************************
 
4287
REMARKS:
 
4288
Handles opcode 0x66 - prefix for 32-bit register
 
4289
****************************************************************************/
 
4290
static void x86emuOp_prefix_data(u8 X86EMU_UNUSED(op1))
 
4291
{
 
4292
    START_OF_INSTR();
 
4293
    DECODE_PRINTF("DATA:\n");
 
4294
    TRACE_AND_STEP();
 
4295
    M.x86.mode |= SYSMODE_PREFIX_DATA;
 
4296
    /* note no DECODE_CLEAR_SEGOVR here. */
 
4297
    END_OF_INSTR();
 
4298
}
 
4299
 
 
4300
/****************************************************************************
 
4301
REMARKS:
 
4302
Handles opcode 0x67 - prefix for 32-bit address
 
4303
****************************************************************************/
 
4304
static void x86emuOp_prefix_addr(u8 X86EMU_UNUSED(op1))
 
4305
{
 
4306
    START_OF_INSTR();
 
4307
    DECODE_PRINTF("ADDR:\n");
 
4308
    TRACE_AND_STEP();
 
4309
    M.x86.mode |= SYSMODE_PREFIX_ADDR;
 
4310
    /* note no DECODE_CLEAR_SEGOVR here. */
 
4311
    END_OF_INSTR();
 
4312
}
 
4313
 
 
4314
/****************************************************************************
 
4315
REMARKS:
 
4316
Handles opcode 0x68
 
4317
****************************************************************************/
 
4318
static void x86emuOp_push_word_IMM(u8 X86EMU_UNUSED(op1))
 
4319
{
 
4320
    u32 imm;
 
4321
 
 
4322
    START_OF_INSTR();
 
4323
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
4324
        imm = fetch_long_imm();
 
4325
    } else {
 
4326
        imm = fetch_word_imm();
 
4327
    }
 
4328
    DECODE_PRINTF2("PUSH\t%x\n", imm);
 
4329
    TRACE_AND_STEP();
 
4330
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
4331
        push_long(imm);
 
4332
    } else {
 
4333
        push_word((u16)imm);
 
4334
    }
 
4335
    DECODE_CLEAR_SEGOVR();
 
4336
    END_OF_INSTR();
 
4337
}
 
4338
 
 
4339
/****************************************************************************
 
4340
REMARKS:
 
4341
Handles opcode 0x69
 
4342
****************************************************************************/
 
4343
static void x86emuOp_imul_word_IMM(u8 X86EMU_UNUSED(op1))
 
4344
{
 
4345
    int mod, rl, rh;
 
4346
    uint srcoffset;
 
4347
 
 
4348
    START_OF_INSTR();
 
4349
    DECODE_PRINTF("IMUL\t");
 
4350
    FETCH_DECODE_MODRM(mod, rh, rl);
 
4351
    switch (mod) {
 
4352
    case 0:
 
4353
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
4354
            u32 *destreg;
 
4355
            u32 srcval;
 
4356
            u32 res_lo,res_hi;
 
4357
            s32 imm;
 
4358
 
 
4359
            destreg = DECODE_RM_LONG_REGISTER(rh);
 
4360
            DECODE_PRINTF(",");
 
4361
            srcoffset = decode_rm00_address(rl);
 
4362
            srcval = fetch_data_long(srcoffset);
 
4363
            imm = fetch_long_imm();
 
4364
            DECODE_PRINTF2(",%d\n", (s32)imm);
 
4365
            TRACE_AND_STEP();
 
4366
            imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
 
4367
            if (res_hi != 0) {
 
4368
                SET_FLAG(F_CF);
 
4369
                SET_FLAG(F_OF);
 
4370
            } else {
 
4371
                CLEAR_FLAG(F_CF);
 
4372
                CLEAR_FLAG(F_OF);
 
4373
            }
 
4374
            *destreg = (u32)res_lo;
 
4375
        } else {
 
4376
            u16 *destreg;
 
4377
            u16 srcval;
 
4378
            u32 res;
 
4379
            s16 imm;
 
4380
 
 
4381
            destreg = DECODE_RM_WORD_REGISTER(rh);
 
4382
            DECODE_PRINTF(",");
 
4383
            srcoffset = decode_rm00_address(rl);
 
4384
            srcval = fetch_data_word(srcoffset);
 
4385
            imm = fetch_word_imm();
 
4386
            DECODE_PRINTF2(",%d\n", (s32)imm);
 
4387
            TRACE_AND_STEP();
 
4388
            res = (s16)srcval * (s16)imm;
 
4389
            if (res > 0xFFFF) {
 
4390
                SET_FLAG(F_CF);
 
4391
                SET_FLAG(F_OF);
 
4392
            } else {
 
4393
                CLEAR_FLAG(F_CF);
 
4394
                CLEAR_FLAG(F_OF);
 
4395
            }
 
4396
            *destreg = (u16)res;
 
4397
        }
 
4398
        break;
 
4399
    case 1:
 
4400
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
4401
            u32 *destreg;
 
4402
            u32 srcval;
 
4403
            u32 res_lo,res_hi;
 
4404
            s32 imm;
 
4405
 
 
4406
            destreg = DECODE_RM_LONG_REGISTER(rh);
 
4407
            DECODE_PRINTF(",");
 
4408
            srcoffset = decode_rm01_address(rl);
 
4409
            srcval = fetch_data_long(srcoffset);
 
4410
            imm = fetch_long_imm();
 
4411
            DECODE_PRINTF2(",%d\n", (s32)imm);
 
4412
            TRACE_AND_STEP();
 
4413
            imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
 
4414
            if (res_hi != 0) {
 
4415
                SET_FLAG(F_CF);
 
4416
                SET_FLAG(F_OF);
 
4417
            } else {
 
4418
                CLEAR_FLAG(F_CF);
 
4419
                CLEAR_FLAG(F_OF);
 
4420
            }
 
4421
            *destreg = (u32)res_lo;
 
4422
        } else {
 
4423
            u16 *destreg;
 
4424
            u16 srcval;
 
4425
            u32 res;
 
4426
            s16 imm;
 
4427
 
 
4428
            destreg = DECODE_RM_WORD_REGISTER(rh);
 
4429
            DECODE_PRINTF(",");
 
4430
            srcoffset = decode_rm01_address(rl);
 
4431
            srcval = fetch_data_word(srcoffset);
 
4432
            imm = fetch_word_imm();
 
4433
            DECODE_PRINTF2(",%d\n", (s32)imm);
 
4434
            TRACE_AND_STEP();
 
4435
            res = (s16)srcval * (s16)imm;
 
4436
            if (res > 0xFFFF) {
 
4437
                SET_FLAG(F_CF);
 
4438
                SET_FLAG(F_OF);
 
4439
            } else {
 
4440
                CLEAR_FLAG(F_CF);
 
4441
                CLEAR_FLAG(F_OF);
 
4442
            }
 
4443
            *destreg = (u16)res;
 
4444
        }
 
4445
        break;
 
4446
    case 2:
 
4447
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
4448
            u32 *destreg;
 
4449
            u32 srcval;
 
4450
            u32 res_lo,res_hi;
 
4451
            s32 imm;
 
4452
 
 
4453
            destreg = DECODE_RM_LONG_REGISTER(rh);
 
4454
            DECODE_PRINTF(",");
 
4455
            srcoffset = decode_rm10_address(rl);
 
4456
            srcval = fetch_data_long(srcoffset);
 
4457
            imm = fetch_long_imm();
 
4458
            DECODE_PRINTF2(",%d\n", (s32)imm);
 
4459
            TRACE_AND_STEP();
 
4460
            imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
 
4461
            if (res_hi != 0) {
 
4462
                SET_FLAG(F_CF);
 
4463
                SET_FLAG(F_OF);
 
4464
            } else {
 
4465
                CLEAR_FLAG(F_CF);
 
4466
                CLEAR_FLAG(F_OF);
 
4467
            }
 
4468
            *destreg = (u32)res_lo;
 
4469
        } else {
 
4470
            u16 *destreg;
 
4471
            u16 srcval;
 
4472
            u32 res;
 
4473
            s16 imm;
 
4474
 
 
4475
            destreg = DECODE_RM_WORD_REGISTER(rh);
 
4476
            DECODE_PRINTF(",");
 
4477
            srcoffset = decode_rm10_address(rl);
 
4478
            srcval = fetch_data_word(srcoffset);
 
4479
            imm = fetch_word_imm();
 
4480
            DECODE_PRINTF2(",%d\n", (s32)imm);
 
4481
            TRACE_AND_STEP();
 
4482
            res = (s16)srcval * (s16)imm;
 
4483
            if (res > 0xFFFF) {
 
4484
                SET_FLAG(F_CF);
 
4485
                SET_FLAG(F_OF);
 
4486
            } else {
 
4487
                CLEAR_FLAG(F_CF);
 
4488
                CLEAR_FLAG(F_OF);
 
4489
            }
 
4490
            *destreg = (u16)res;
 
4491
        }
 
4492
        break;
 
4493
    case 3:                     /* register to register */
 
4494
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
4495
            u32 *destreg,*srcreg;
 
4496
            u32 res_lo,res_hi;
 
4497
            s32 imm;
 
4498
 
 
4499
            destreg = DECODE_RM_LONG_REGISTER(rh);
 
4500
            DECODE_PRINTF(",");
 
4501
            srcreg = DECODE_RM_LONG_REGISTER(rl);
 
4502
            imm = fetch_long_imm();
 
4503
            DECODE_PRINTF2(",%d\n", (s32)imm);
 
4504
            TRACE_AND_STEP();
 
4505
            imul_long_direct(&res_lo,&res_hi,(s32)*srcreg,(s32)imm);
 
4506
            if (res_hi != 0) {
 
4507
                SET_FLAG(F_CF);
 
4508
                SET_FLAG(F_OF);
 
4509
            } else {
 
4510
                CLEAR_FLAG(F_CF);
 
4511
                CLEAR_FLAG(F_OF);
 
4512
            }
 
4513
            *destreg = (u32)res_lo;
 
4514
        } else {
 
4515
            u16 *destreg,*srcreg;
 
4516
            u32 res;
 
4517
            s16 imm;
 
4518
 
 
4519
            destreg = DECODE_RM_WORD_REGISTER(rh);
 
4520
            DECODE_PRINTF(",");
 
4521
            srcreg = DECODE_RM_WORD_REGISTER(rl);
 
4522
            imm = fetch_word_imm();
 
4523
            DECODE_PRINTF2(",%d\n", (s32)imm);
 
4524
            res = (s16)*srcreg * (s16)imm;
 
4525
            if (res > 0xFFFF) {
 
4526
                SET_FLAG(F_CF);
 
4527
                SET_FLAG(F_OF);
 
4528
            } else {
 
4529
                CLEAR_FLAG(F_CF);
 
4530
                CLEAR_FLAG(F_OF);
 
4531
            }
 
4532
            *destreg = (u16)res;
 
4533
        }
 
4534
        break;
 
4535
    }
 
4536
    DECODE_CLEAR_SEGOVR();
 
4537
    END_OF_INSTR();
 
4538
}
 
4539
 
 
4540
/****************************************************************************
 
4541
REMARKS:
 
4542
Handles opcode 0x6a
 
4543
****************************************************************************/
 
4544
static void x86emuOp_push_byte_IMM(u8 X86EMU_UNUSED(op1))
 
4545
{
 
4546
    s16 imm;
 
4547
 
 
4548
    START_OF_INSTR();
 
4549
    imm = (s8)fetch_byte_imm();
 
4550
    DECODE_PRINTF2("PUSH\t%d\n", imm);
 
4551
    TRACE_AND_STEP();
 
4552
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
4553
        push_long((s32)imm);
 
4554
    } else {
 
4555
        push_word(imm);
 
4556
    }
 
4557
    DECODE_CLEAR_SEGOVR();
 
4558
    END_OF_INSTR();
 
4559
}
 
4560
 
 
4561
/****************************************************************************
 
4562
REMARKS:
 
4563
Handles opcode 0x6b
 
4564
****************************************************************************/
 
4565
static void x86emuOp_imul_byte_IMM(u8 X86EMU_UNUSED(op1))
 
4566
{
 
4567
    int mod, rl, rh;
 
4568
    uint srcoffset;
 
4569
    s8  imm;
 
4570
 
 
4571
    START_OF_INSTR();
 
4572
    DECODE_PRINTF("IMUL\t");
 
4573
    FETCH_DECODE_MODRM(mod, rh, rl);
 
4574
    switch (mod) {
 
4575
    case 0:
 
4576
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
4577
            u32 *destreg;
 
4578
            u32 srcval;
 
4579
            u32 res_lo,res_hi;
 
4580
 
 
4581
            destreg = DECODE_RM_LONG_REGISTER(rh);
 
4582
            DECODE_PRINTF(",");
 
4583
            srcoffset = decode_rm00_address(rl);
 
4584
            srcval = fetch_data_long(srcoffset);
 
4585
            imm = fetch_byte_imm();
 
4586
            DECODE_PRINTF2(",%d\n", (s32)imm);
 
4587
            TRACE_AND_STEP();
 
4588
            imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
 
4589
            if (res_hi != 0) {
 
4590
                SET_FLAG(F_CF);
 
4591
                SET_FLAG(F_OF);
 
4592
            } else {
 
4593
                CLEAR_FLAG(F_CF);
 
4594
                CLEAR_FLAG(F_OF);
 
4595
            }
 
4596
            *destreg = (u32)res_lo;
 
4597
        } else {
 
4598
            u16 *destreg;
 
4599
            u16 srcval;
 
4600
            u32 res;
 
4601
 
 
4602
            destreg = DECODE_RM_WORD_REGISTER(rh);
 
4603
            DECODE_PRINTF(",");
 
4604
            srcoffset = decode_rm00_address(rl);
 
4605
            srcval = fetch_data_word(srcoffset);
 
4606
            imm = fetch_byte_imm();
 
4607
            DECODE_PRINTF2(",%d\n", (s32)imm);
 
4608
            TRACE_AND_STEP();
 
4609
            res = (s16)srcval * (s16)imm;
 
4610
            if (res > 0xFFFF) {
 
4611
                SET_FLAG(F_CF);
 
4612
                SET_FLAG(F_OF);
 
4613
            } else {
 
4614
                CLEAR_FLAG(F_CF);
 
4615
                CLEAR_FLAG(F_OF);
 
4616
            }
 
4617
            *destreg = (u16)res;
 
4618
        }
 
4619
        break;
 
4620
    case 1:
 
4621
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
4622
            u32 *destreg;
 
4623
            u32 srcval;
 
4624
            u32 res_lo,res_hi;
 
4625
 
 
4626
            destreg = DECODE_RM_LONG_REGISTER(rh);
 
4627
            DECODE_PRINTF(",");
 
4628
            srcoffset = decode_rm01_address(rl);
 
4629
            srcval = fetch_data_long(srcoffset);
 
4630
            imm = fetch_byte_imm();
 
4631
            DECODE_PRINTF2(",%d\n", (s32)imm);
 
4632
            TRACE_AND_STEP();
 
4633
            imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
 
4634
            if (res_hi != 0) {
 
4635
                SET_FLAG(F_CF);
 
4636
                SET_FLAG(F_OF);
 
4637
            } else {
 
4638
                CLEAR_FLAG(F_CF);
 
4639
                CLEAR_FLAG(F_OF);
 
4640
            }
 
4641
            *destreg = (u32)res_lo;
 
4642
        } else {
 
4643
            u16 *destreg;
 
4644
            u16 srcval;
 
4645
            u32 res;
 
4646
 
 
4647
            destreg = DECODE_RM_WORD_REGISTER(rh);
 
4648
            DECODE_PRINTF(",");
 
4649
            srcoffset = decode_rm01_address(rl);
 
4650
            srcval = fetch_data_word(srcoffset);
 
4651
            imm = fetch_byte_imm();
 
4652
            DECODE_PRINTF2(",%d\n", (s32)imm);
 
4653
            TRACE_AND_STEP();
 
4654
            res = (s16)srcval * (s16)imm;
 
4655
            if (res > 0xFFFF) {
 
4656
                SET_FLAG(F_CF);
 
4657
                SET_FLAG(F_OF);
 
4658
            } else {
 
4659
                CLEAR_FLAG(F_CF);
 
4660
                CLEAR_FLAG(F_OF);
 
4661
            }
 
4662
            *destreg = (u16)res;
 
4663
        }
 
4664
        break;
 
4665
    case 2:
 
4666
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
4667
            u32 *destreg;
 
4668
            u32 srcval;
 
4669
            u32 res_lo,res_hi;
 
4670
 
 
4671
            destreg = DECODE_RM_LONG_REGISTER(rh);
 
4672
            DECODE_PRINTF(",");
 
4673
            srcoffset = decode_rm10_address(rl);
 
4674
            srcval = fetch_data_long(srcoffset);
 
4675
            imm = fetch_byte_imm();
 
4676
            DECODE_PRINTF2(",%d\n", (s32)imm);
 
4677
            TRACE_AND_STEP();
 
4678
            imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
 
4679
            if (res_hi != 0) {
 
4680
                SET_FLAG(F_CF);
 
4681
                SET_FLAG(F_OF);
 
4682
            } else {
 
4683
                CLEAR_FLAG(F_CF);
 
4684
                CLEAR_FLAG(F_OF);
 
4685
            }
 
4686
            *destreg = (u32)res_lo;
 
4687
        } else {
 
4688
            u16 *destreg;
 
4689
            u16 srcval;
 
4690
            u32 res;
 
4691
 
 
4692
            destreg = DECODE_RM_WORD_REGISTER(rh);
 
4693
            DECODE_PRINTF(",");
 
4694
            srcoffset = decode_rm10_address(rl);
 
4695
            srcval = fetch_data_word(srcoffset);
 
4696
            imm = fetch_byte_imm();
 
4697
            DECODE_PRINTF2(",%d\n", (s32)imm);
 
4698
            TRACE_AND_STEP();
 
4699
            res = (s16)srcval * (s16)imm;
 
4700
            if (res > 0xFFFF) {
 
4701
                SET_FLAG(F_CF);
 
4702
                SET_FLAG(F_OF);
 
4703
            } else {
 
4704
                CLEAR_FLAG(F_CF);
 
4705
                CLEAR_FLAG(F_OF);
 
4706
            }
 
4707
            *destreg = (u16)res;
 
4708
        }
 
4709
        break;
 
4710
    case 3:                     /* register to register */
 
4711
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
4712
            u32 *destreg,*srcreg;
 
4713
            u32 res_lo,res_hi;
 
4714
 
 
4715
            destreg = DECODE_RM_LONG_REGISTER(rh);
 
4716
            DECODE_PRINTF(",");
 
4717
            srcreg = DECODE_RM_LONG_REGISTER(rl);
 
4718
            imm = fetch_byte_imm();
 
4719
            DECODE_PRINTF2(",%d\n", (s32)imm);
 
4720
            TRACE_AND_STEP();
 
4721
            imul_long_direct(&res_lo,&res_hi,(s32)*srcreg,(s32)imm);
 
4722
            if (res_hi != 0) {
 
4723
                SET_FLAG(F_CF);
 
4724
                SET_FLAG(F_OF);
 
4725
            } else {
 
4726
                CLEAR_FLAG(F_CF);
 
4727
                CLEAR_FLAG(F_OF);
 
4728
            }
 
4729
            *destreg = (u32)res_lo;
 
4730
        } else {
 
4731
            u16 *destreg,*srcreg;
 
4732
            u32 res;
 
4733
 
 
4734
            destreg = DECODE_RM_WORD_REGISTER(rh);
 
4735
            DECODE_PRINTF(",");
 
4736
            srcreg = DECODE_RM_WORD_REGISTER(rl);
 
4737
            imm = fetch_byte_imm();
 
4738
            DECODE_PRINTF2(",%d\n", (s32)imm);
 
4739
            res = (s16)*srcreg * (s16)imm;
 
4740
            if (res > 0xFFFF) {
 
4741
                SET_FLAG(F_CF);
 
4742
                SET_FLAG(F_OF);
 
4743
            } else {
 
4744
                CLEAR_FLAG(F_CF);
 
4745
                CLEAR_FLAG(F_OF);
 
4746
            }
 
4747
            *destreg = (u16)res;
 
4748
        }
 
4749
        break;
 
4750
    }
 
4751
    DECODE_CLEAR_SEGOVR();
 
4752
    END_OF_INSTR();
 
4753
}
 
4754
 
 
4755
/****************************************************************************
 
4756
REMARKS:
 
4757
Handles opcode 0x6c
 
4758
****************************************************************************/
 
4759
static void x86emuOp_ins_byte(u8 X86EMU_UNUSED(op1))
 
4760
{
 
4761
    START_OF_INSTR();
 
4762
    DECODE_PRINTF("INSB\n");
 
4763
    ins(1);
 
4764
    TRACE_AND_STEP();
 
4765
    DECODE_CLEAR_SEGOVR();
 
4766
    END_OF_INSTR();
 
4767
}
 
4768
 
 
4769
/****************************************************************************
 
4770
REMARKS:
 
4771
Handles opcode 0x6d
 
4772
****************************************************************************/
 
4773
static void x86emuOp_ins_word(u8 X86EMU_UNUSED(op1))
 
4774
{
 
4775
    START_OF_INSTR();
 
4776
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
4777
        DECODE_PRINTF("INSD\n");
 
4778
        ins(4);
 
4779
    } else {
 
4780
        DECODE_PRINTF("INSW\n");
 
4781
        ins(2);
 
4782
    }
 
4783
    TRACE_AND_STEP();
 
4784
    DECODE_CLEAR_SEGOVR();
 
4785
    END_OF_INSTR();
 
4786
}
 
4787
 
 
4788
/****************************************************************************
 
4789
REMARKS:
 
4790
Handles opcode 0x6e
 
4791
****************************************************************************/
 
4792
static void x86emuOp_outs_byte(u8 X86EMU_UNUSED(op1))
 
4793
{
 
4794
    START_OF_INSTR();
 
4795
    DECODE_PRINTF("OUTSB\n");
 
4796
    outs(1);
 
4797
    TRACE_AND_STEP();
 
4798
    DECODE_CLEAR_SEGOVR();
 
4799
    END_OF_INSTR();
 
4800
}
 
4801
 
 
4802
/****************************************************************************
 
4803
REMARKS:
 
4804
Handles opcode 0x6f
 
4805
****************************************************************************/
 
4806
static void x86emuOp_outs_word(u8 X86EMU_UNUSED(op1))
 
4807
{
 
4808
    START_OF_INSTR();
 
4809
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
4810
        DECODE_PRINTF("OUTSD\n");
 
4811
        outs(4);
 
4812
    } else {
 
4813
        DECODE_PRINTF("OUTSW\n");
 
4814
        outs(2);
 
4815
    }
 
4816
    TRACE_AND_STEP();
 
4817
    DECODE_CLEAR_SEGOVR();
 
4818
    END_OF_INSTR();
 
4819
}
 
4820
 
 
4821
/****************************************************************************
 
4822
REMARKS:
 
4823
Handles opcode 0x70
 
4824
****************************************************************************/
 
4825
static void x86emuOp_jump_near_O(u8 X86EMU_UNUSED(op1))
 
4826
{
 
4827
    s8 offset;
 
4828
    u16 target;
 
4829
 
 
4830
    /* jump to byte offset if overflow flag is set */
 
4831
    START_OF_INSTR();
 
4832
    DECODE_PRINTF("JO\t");
 
4833
    offset = (s8)fetch_byte_imm();
 
4834
    target = (u16)(M.x86.R_IP + (s16)offset);
 
4835
    DECODE_PRINTF2("%x\n", target);
 
4836
    TRACE_AND_STEP();
 
4837
    if (ACCESS_FLAG(F_OF))
 
4838
        M.x86.R_IP = target;
 
4839
    DECODE_CLEAR_SEGOVR();
 
4840
    END_OF_INSTR();
 
4841
}
 
4842
 
 
4843
/****************************************************************************
 
4844
REMARKS:
 
4845
Handles opcode 0x71
 
4846
****************************************************************************/
 
4847
static void x86emuOp_jump_near_NO(u8 X86EMU_UNUSED(op1))
 
4848
{
 
4849
    s8 offset;
 
4850
    u16 target;
 
4851
 
 
4852
    /* jump to byte offset if overflow is not set */
 
4853
    START_OF_INSTR();
 
4854
    DECODE_PRINTF("JNO\t");
 
4855
    offset = (s8)fetch_byte_imm();
 
4856
    target = (u16)(M.x86.R_IP + (s16)offset);
 
4857
    DECODE_PRINTF2("%x\n", target);
 
4858
    TRACE_AND_STEP();
 
4859
    if (!ACCESS_FLAG(F_OF))
 
4860
        M.x86.R_IP = target;
 
4861
    DECODE_CLEAR_SEGOVR();
 
4862
    END_OF_INSTR();
 
4863
}
 
4864
 
 
4865
/****************************************************************************
 
4866
REMARKS:
 
4867
Handles opcode 0x72
 
4868
****************************************************************************/
 
4869
static void x86emuOp_jump_near_B(u8 X86EMU_UNUSED(op1))
 
4870
{
 
4871
    s8 offset;
 
4872
    u16 target;
 
4873
 
 
4874
    /* jump to byte offset if carry flag is set. */
 
4875
    START_OF_INSTR();
 
4876
    DECODE_PRINTF("JB\t");
 
4877
    offset = (s8)fetch_byte_imm();
 
4878
    target = (u16)(M.x86.R_IP + (s16)offset);
 
4879
    DECODE_PRINTF2("%x\n", target);
 
4880
    TRACE_AND_STEP();
 
4881
    if (ACCESS_FLAG(F_CF))
 
4882
        M.x86.R_IP = target;
 
4883
    DECODE_CLEAR_SEGOVR();
 
4884
    END_OF_INSTR();
 
4885
}
 
4886
 
 
4887
/****************************************************************************
 
4888
REMARKS:
 
4889
Handles opcode 0x73
 
4890
****************************************************************************/
 
4891
static void x86emuOp_jump_near_NB(u8 X86EMU_UNUSED(op1))
 
4892
{
 
4893
    s8 offset;
 
4894
    u16 target;
 
4895
 
 
4896
    /* jump to byte offset if carry flag is clear. */
 
4897
    START_OF_INSTR();
 
4898
    DECODE_PRINTF("JNB\t");
 
4899
    offset = (s8)fetch_byte_imm();
 
4900
    target = (u16)(M.x86.R_IP + (s16)offset);
 
4901
    DECODE_PRINTF2("%x\n", target);
 
4902
    TRACE_AND_STEP();
 
4903
    if (!ACCESS_FLAG(F_CF))
 
4904
        M.x86.R_IP = target;
 
4905
    DECODE_CLEAR_SEGOVR();
 
4906
    END_OF_INSTR();
 
4907
}
 
4908
 
 
4909
/****************************************************************************
 
4910
REMARKS:
 
4911
Handles opcode 0x74
 
4912
****************************************************************************/
 
4913
static void x86emuOp_jump_near_Z(u8 X86EMU_UNUSED(op1))
 
4914
{
 
4915
    s8 offset;
 
4916
    u16 target;
 
4917
 
 
4918
    /* jump to byte offset if zero flag is set. */
 
4919
    START_OF_INSTR();
 
4920
    DECODE_PRINTF("JZ\t");
 
4921
    offset = (s8)fetch_byte_imm();
 
4922
    target = (u16)(M.x86.R_IP + (s16)offset);
 
4923
    DECODE_PRINTF2("%x\n", target);
 
4924
    TRACE_AND_STEP();
 
4925
    if (ACCESS_FLAG(F_ZF))
 
4926
        M.x86.R_IP = target;
 
4927
    DECODE_CLEAR_SEGOVR();
 
4928
    END_OF_INSTR();
 
4929
}
 
4930
 
 
4931
/****************************************************************************
 
4932
REMARKS:
 
4933
Handles opcode 0x75
 
4934
****************************************************************************/
 
4935
static void x86emuOp_jump_near_NZ(u8 X86EMU_UNUSED(op1))
 
4936
{
 
4937
    s8 offset;
 
4938
    u16 target;
 
4939
 
 
4940
    /* jump to byte offset if zero flag is clear. */
 
4941
    START_OF_INSTR();
 
4942
    DECODE_PRINTF("JNZ\t");
 
4943
    offset = (s8)fetch_byte_imm();
 
4944
    target = (u16)(M.x86.R_IP + (s16)offset);
 
4945
    DECODE_PRINTF2("%x\n", target);
 
4946
    TRACE_AND_STEP();
 
4947
    if (!ACCESS_FLAG(F_ZF))
 
4948
        M.x86.R_IP = target;
 
4949
    DECODE_CLEAR_SEGOVR();
 
4950
    END_OF_INSTR();
 
4951
}
 
4952
 
 
4953
/****************************************************************************
 
4954
REMARKS:
 
4955
Handles opcode 0x76
 
4956
****************************************************************************/
 
4957
static void x86emuOp_jump_near_BE(u8 X86EMU_UNUSED(op1))
 
4958
{
 
4959
    s8 offset;
 
4960
    u16 target;
 
4961
 
 
4962
    /* jump to byte offset if carry flag is set or if the zero
 
4963
       flag is set. */
 
4964
    START_OF_INSTR();
 
4965
    DECODE_PRINTF("JBE\t");
 
4966
    offset = (s8)fetch_byte_imm();
 
4967
    target = (u16)(M.x86.R_IP + (s16)offset);
 
4968
    DECODE_PRINTF2("%x\n", target);
 
4969
    TRACE_AND_STEP();
 
4970
    if (ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF))
 
4971
        M.x86.R_IP = target;
 
4972
    DECODE_CLEAR_SEGOVR();
 
4973
    END_OF_INSTR();
 
4974
}
 
4975
 
 
4976
/****************************************************************************
 
4977
REMARKS:
 
4978
Handles opcode 0x77
 
4979
****************************************************************************/
 
4980
static void x86emuOp_jump_near_NBE(u8 X86EMU_UNUSED(op1))
 
4981
{
 
4982
    s8 offset;
 
4983
    u16 target;
 
4984
 
 
4985
    /* jump to byte offset if carry flag is clear and if the zero
 
4986
       flag is clear */
 
4987
    START_OF_INSTR();
 
4988
    DECODE_PRINTF("JNBE\t");
 
4989
    offset = (s8)fetch_byte_imm();
 
4990
    target = (u16)(M.x86.R_IP + (s16)offset);
 
4991
    DECODE_PRINTF2("%x\n", target);
 
4992
    TRACE_AND_STEP();
 
4993
    if (!(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF)))
 
4994
        M.x86.R_IP = target;
 
4995
    DECODE_CLEAR_SEGOVR();
 
4996
    END_OF_INSTR();
 
4997
}
 
4998
 
 
4999
/****************************************************************************
 
5000
REMARKS:
 
5001
Handles opcode 0x78
 
5002
****************************************************************************/
 
5003
static void x86emuOp_jump_near_S(u8 X86EMU_UNUSED(op1))
 
5004
{
 
5005
    s8 offset;
 
5006
    u16 target;
 
5007
 
 
5008
    /* jump to byte offset if sign flag is set */
 
5009
    START_OF_INSTR();
 
5010
    DECODE_PRINTF("JS\t");
 
5011
    offset = (s8)fetch_byte_imm();
 
5012
    target = (u16)(M.x86.R_IP + (s16)offset);
 
5013
    DECODE_PRINTF2("%x\n", target);
 
5014
    TRACE_AND_STEP();
 
5015
    if (ACCESS_FLAG(F_SF))
 
5016
        M.x86.R_IP = target;
 
5017
    DECODE_CLEAR_SEGOVR();
 
5018
    END_OF_INSTR();
 
5019
}
 
5020
 
 
5021
/****************************************************************************
 
5022
REMARKS:
 
5023
Handles opcode 0x79
 
5024
****************************************************************************/
 
5025
static void x86emuOp_jump_near_NS(u8 X86EMU_UNUSED(op1))
 
5026
{
 
5027
    s8 offset;
 
5028
    u16 target;
 
5029
 
 
5030
    /* jump to byte offset if sign flag is clear */
 
5031
    START_OF_INSTR();
 
5032
    DECODE_PRINTF("JNS\t");
 
5033
    offset = (s8)fetch_byte_imm();
 
5034
    target = (u16)(M.x86.R_IP + (s16)offset);
 
5035
    DECODE_PRINTF2("%x\n", target);
 
5036
    TRACE_AND_STEP();
 
5037
    if (!ACCESS_FLAG(F_SF))
 
5038
        M.x86.R_IP = target;
 
5039
    DECODE_CLEAR_SEGOVR();
 
5040
    END_OF_INSTR();
 
5041
}
 
5042
 
 
5043
/****************************************************************************
 
5044
REMARKS:
 
5045
Handles opcode 0x7a
 
5046
****************************************************************************/
 
5047
static void x86emuOp_jump_near_P(u8 X86EMU_UNUSED(op1))
 
5048
{
 
5049
    s8 offset;
 
5050
    u16 target;
 
5051
 
 
5052
    /* jump to byte offset if parity flag is set (even parity) */
 
5053
    START_OF_INSTR();
 
5054
    DECODE_PRINTF("JP\t");
 
5055
    offset = (s8)fetch_byte_imm();
 
5056
    target = (u16)(M.x86.R_IP + (s16)offset);
 
5057
    DECODE_PRINTF2("%x\n", target);
 
5058
    TRACE_AND_STEP();
 
5059
    if (ACCESS_FLAG(F_PF))
 
5060
        M.x86.R_IP = target;
 
5061
    DECODE_CLEAR_SEGOVR();
 
5062
    END_OF_INSTR();
 
5063
}
 
5064
 
 
5065
/****************************************************************************
 
5066
REMARKS:
 
5067
Handles opcode 0x7b
 
5068
****************************************************************************/
 
5069
static void x86emuOp_jump_near_NP(u8 X86EMU_UNUSED(op1))
 
5070
{
 
5071
    s8 offset;
 
5072
    u16 target;
 
5073
 
 
5074
    /* jump to byte offset if parity flag is clear (odd parity) */
 
5075
    START_OF_INSTR();
 
5076
    DECODE_PRINTF("JNP\t");
 
5077
    offset = (s8)fetch_byte_imm();
 
5078
    target = (u16)(M.x86.R_IP + (s16)offset);
 
5079
    DECODE_PRINTF2("%x\n", target);
 
5080
    TRACE_AND_STEP();
 
5081
    if (!ACCESS_FLAG(F_PF))
 
5082
        M.x86.R_IP = target;
 
5083
    DECODE_CLEAR_SEGOVR();
 
5084
    END_OF_INSTR();
 
5085
}
 
5086
 
 
5087
/****************************************************************************
 
5088
REMARKS:
 
5089
Handles opcode 0x7c
 
5090
****************************************************************************/
 
5091
static void x86emuOp_jump_near_L(u8 X86EMU_UNUSED(op1))
 
5092
{
 
5093
    s8 offset;
 
5094
    u16 target;
 
5095
    int sf, of;
 
5096
 
 
5097
    /* jump to byte offset if sign flag not equal to overflow flag. */
 
5098
    START_OF_INSTR();
 
5099
    DECODE_PRINTF("JL\t");
 
5100
    offset = (s8)fetch_byte_imm();
 
5101
    target = (u16)(M.x86.R_IP + (s16)offset);
 
5102
    DECODE_PRINTF2("%x\n", target);
 
5103
    TRACE_AND_STEP();
 
5104
    sf = ACCESS_FLAG(F_SF) != 0;
 
5105
    of = ACCESS_FLAG(F_OF) != 0;
 
5106
    if (sf ^ of)
 
5107
        M.x86.R_IP = target;
 
5108
    DECODE_CLEAR_SEGOVR();
 
5109
    END_OF_INSTR();
 
5110
}
 
5111
 
 
5112
/****************************************************************************
 
5113
REMARKS:
 
5114
Handles opcode 0x7d
 
5115
****************************************************************************/
 
5116
static void x86emuOp_jump_near_NL(u8 X86EMU_UNUSED(op1))
 
5117
{
 
5118
    s8 offset;
 
5119
    u16 target;
 
5120
    int sf, of;
 
5121
 
 
5122
    /* jump to byte offset if sign flag not equal to overflow flag. */
 
5123
    START_OF_INSTR();
 
5124
    DECODE_PRINTF("JNL\t");
 
5125
    offset = (s8)fetch_byte_imm();
 
5126
    target = (u16)(M.x86.R_IP + (s16)offset);
 
5127
    DECODE_PRINTF2("%x\n", target);
 
5128
    TRACE_AND_STEP();
 
5129
    sf = ACCESS_FLAG(F_SF) != 0;
 
5130
    of = ACCESS_FLAG(F_OF) != 0;
 
5131
    /* note: inverse of above, but using == instead of xor. */
 
5132
    if (sf == of)
 
5133
        M.x86.R_IP = target;
 
5134
    DECODE_CLEAR_SEGOVR();
 
5135
    END_OF_INSTR();
 
5136
}
 
5137
 
 
5138
/****************************************************************************
 
5139
REMARKS:
 
5140
Handles opcode 0x7e
 
5141
****************************************************************************/
 
5142
static void x86emuOp_jump_near_LE(u8 X86EMU_UNUSED(op1))
 
5143
{
 
5144
    s8 offset;
 
5145
    u16 target;
 
5146
    int sf, of;
 
5147
 
 
5148
    /* jump to byte offset if sign flag not equal to overflow flag
 
5149
       or the zero flag is set */
 
5150
    START_OF_INSTR();
 
5151
    DECODE_PRINTF("JLE\t");
 
5152
    offset = (s8)fetch_byte_imm();
 
5153
    target = (u16)(M.x86.R_IP + (s16)offset);
 
5154
    DECODE_PRINTF2("%x\n", target);
 
5155
    TRACE_AND_STEP();
 
5156
    sf = ACCESS_FLAG(F_SF) != 0;
 
5157
    of = ACCESS_FLAG(F_OF) != 0;
 
5158
    if ((sf ^ of) || ACCESS_FLAG(F_ZF))
 
5159
        M.x86.R_IP = target;
 
5160
    DECODE_CLEAR_SEGOVR();
 
5161
    END_OF_INSTR();
 
5162
}
 
5163
 
 
5164
/****************************************************************************
 
5165
REMARKS:
 
5166
Handles opcode 0x7f
 
5167
****************************************************************************/
 
5168
static void x86emuOp_jump_near_NLE(u8 X86EMU_UNUSED(op1))
 
5169
{
 
5170
    s8 offset;
 
5171
    u16 target;
 
5172
    int sf, of;
 
5173
 
 
5174
    /* jump to byte offset if sign flag equal to overflow flag.
 
5175
       and the zero flag is clear */
 
5176
    START_OF_INSTR();
 
5177
    DECODE_PRINTF("JNLE\t");
 
5178
    offset = (s8)fetch_byte_imm();
 
5179
    target = (u16)(M.x86.R_IP + (s16)offset);
 
5180
    DECODE_PRINTF2("%x\n", target);
 
5181
    TRACE_AND_STEP();
 
5182
    sf = ACCESS_FLAG(F_SF) != 0;
 
5183
    of = ACCESS_FLAG(F_OF) != 0;
 
5184
    if ((sf == of) && !ACCESS_FLAG(F_ZF))
 
5185
        M.x86.R_IP = target;
 
5186
    DECODE_CLEAR_SEGOVR();
 
5187
    END_OF_INSTR();
 
5188
}
 
5189
 
 
5190
static u8 (*opc80_byte_operation[])(u8 d, u8 s) =
 
5191
{
 
5192
    add_byte,           /* 00 */
 
5193
    or_byte,            /* 01 */
 
5194
    adc_byte,           /* 02 */
 
5195
    sbb_byte,           /* 03 */
 
5196
    and_byte,           /* 04 */
 
5197
    sub_byte,           /* 05 */
 
5198
    xor_byte,           /* 06 */
 
5199
    cmp_byte,           /* 07 */
 
5200
};
 
5201
 
 
5202
/****************************************************************************
 
5203
REMARKS:
 
5204
Handles opcode 0x80
 
5205
****************************************************************************/
 
5206
static void x86emuOp_opc80_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
 
5207
{
 
5208
    int mod, rl, rh;
 
5209
    u8 *destreg;
 
5210
    uint destoffset;
 
5211
    u8 imm;
 
5212
    u8 destval;
 
5213
 
 
5214
    /*
 
5215
     * Weirdo special case instruction format.  Part of the opcode
 
5216
     * held below in "RH".  Doubly nested case would result, except
 
5217
     * that the decoded instruction
 
5218
     */
 
5219
    START_OF_INSTR();
 
5220
    FETCH_DECODE_MODRM(mod, rh, rl);
 
5221
#ifdef DEBUG
 
5222
    if (DEBUG_DECODE()) {
 
5223
        /* XXX DECODE_PRINTF may be changed to something more
 
5224
           general, so that it is important to leave the strings
 
5225
           in the same format, even though the result is that the 
 
5226
           above test is done twice. */
 
5227
 
 
5228
        switch (rh) {
 
5229
        case 0:
 
5230
            DECODE_PRINTF("ADD\t");
 
5231
            break;
 
5232
        case 1:
 
5233
            DECODE_PRINTF("OR\t");
 
5234
            break;
 
5235
        case 2:
 
5236
            DECODE_PRINTF("ADC\t");
 
5237
            break;
 
5238
        case 3:
 
5239
            DECODE_PRINTF("SBB\t");
 
5240
            break;
 
5241
        case 4:
 
5242
            DECODE_PRINTF("AND\t");
 
5243
            break;
 
5244
        case 5:
 
5245
            DECODE_PRINTF("SUB\t");
 
5246
            break;
 
5247
        case 6:
 
5248
            DECODE_PRINTF("XOR\t");
 
5249
            break;
 
5250
        case 7:
 
5251
            DECODE_PRINTF("CMP\t");
 
5252
            break;
 
5253
        }
 
5254
    }
 
5255
#endif
 
5256
    /* know operation, decode the mod byte to find the addressing
 
5257
       mode. */
 
5258
    switch (mod) {
 
5259
    case 0:
 
5260
        DECODE_PRINTF("BYTE PTR ");
 
5261
        destoffset = decode_rm00_address(rl);
 
5262
        DECODE_PRINTF(",");
 
5263
        destval = fetch_data_byte(destoffset);
 
5264
        imm = fetch_byte_imm();
 
5265
        DECODE_PRINTF2("%x\n", imm);
 
5266
        TRACE_AND_STEP();
 
5267
        destval = (*opc80_byte_operation[rh]) (destval, imm);
 
5268
        if (rh != 7)
 
5269
            store_data_byte(destoffset, destval);
 
5270
        break;
 
5271
    case 1:
 
5272
        DECODE_PRINTF("BYTE PTR ");
 
5273
        destoffset = decode_rm01_address(rl);
 
5274
        DECODE_PRINTF(",");
 
5275
        destval = fetch_data_byte(destoffset);
 
5276
        imm = fetch_byte_imm();
 
5277
        DECODE_PRINTF2("%x\n", imm);
 
5278
        TRACE_AND_STEP();
 
5279
        destval = (*opc80_byte_operation[rh]) (destval, imm);
 
5280
        if (rh != 7)
 
5281
            store_data_byte(destoffset, destval);
 
5282
        break;
 
5283
    case 2:
 
5284
        DECODE_PRINTF("BYTE PTR ");
 
5285
        destoffset = decode_rm10_address(rl);
 
5286
        DECODE_PRINTF(",");
 
5287
        destval = fetch_data_byte(destoffset);
 
5288
        imm = fetch_byte_imm();
 
5289
        DECODE_PRINTF2("%x\n", imm);
 
5290
        TRACE_AND_STEP();
 
5291
        destval = (*opc80_byte_operation[rh]) (destval, imm);
 
5292
        if (rh != 7)
 
5293
            store_data_byte(destoffset, destval);
 
5294
        break;
 
5295
    case 3:                     /* register to register */
 
5296
        destreg = DECODE_RM_BYTE_REGISTER(rl);
 
5297
        DECODE_PRINTF(",");
 
5298
        imm = fetch_byte_imm();
 
5299
        DECODE_PRINTF2("%x\n", imm);
 
5300
        TRACE_AND_STEP();
 
5301
        destval = (*opc80_byte_operation[rh]) (*destreg, imm);
 
5302
        if (rh != 7)
 
5303
            *destreg = destval;
 
5304
        break;
 
5305
    }
 
5306
    DECODE_CLEAR_SEGOVR();
 
5307
    END_OF_INSTR();
 
5308
}
 
5309
 
 
5310
static u16 (*opc81_word_operation[])(u16 d, u16 s) =
 
5311
{
 
5312
    add_word,           /*00 */
 
5313
    or_word,            /*01 */
 
5314
    adc_word,           /*02 */
 
5315
    sbb_word,           /*03 */
 
5316
    and_word,           /*04 */
 
5317
    sub_word,           /*05 */
 
5318
    xor_word,           /*06 */
 
5319
    cmp_word,           /*07 */
 
5320
};
 
5321
 
 
5322
static u32 (*opc81_long_operation[])(u32 d, u32 s) =
 
5323
{
 
5324
    add_long,           /*00 */
 
5325
    or_long,            /*01 */
 
5326
    adc_long,           /*02 */
 
5327
    sbb_long,           /*03 */
 
5328
    and_long,           /*04 */
 
5329
    sub_long,           /*05 */
 
5330
    xor_long,           /*06 */
 
5331
    cmp_long,           /*07 */
 
5332
};
 
5333
 
 
5334
/****************************************************************************
 
5335
REMARKS:
 
5336
Handles opcode 0x81
 
5337
****************************************************************************/
 
5338
static void x86emuOp_opc81_word_RM_IMM(u8 X86EMU_UNUSED(op1))
 
5339
{
 
5340
    int mod, rl, rh;
 
5341
    uint destoffset;
 
5342
 
 
5343
    /*
 
5344
     * Weirdo special case instruction format.  Part of the opcode
 
5345
     * held below in "RH".  Doubly nested case would result, except
 
5346
     * that the decoded instruction
 
5347
     */
 
5348
    START_OF_INSTR();
 
5349
    FETCH_DECODE_MODRM(mod, rh, rl);
 
5350
#ifdef DEBUG
 
5351
    if (DEBUG_DECODE()) {
 
5352
        /* XXX DECODE_PRINTF may be changed to something more
 
5353
           general, so that it is important to leave the strings
 
5354
           in the same format, even though the result is that the 
 
5355
           above test is done twice. */
 
5356
 
 
5357
        switch (rh) {
 
5358
        case 0:
 
5359
            DECODE_PRINTF("ADD\t");
 
5360
            break;
 
5361
        case 1:
 
5362
            DECODE_PRINTF("OR\t");
 
5363
            break;
 
5364
        case 2:
 
5365
            DECODE_PRINTF("ADC\t");
 
5366
            break;
 
5367
        case 3:
 
5368
            DECODE_PRINTF("SBB\t");
 
5369
            break;
 
5370
        case 4:
 
5371
            DECODE_PRINTF("AND\t");
 
5372
            break;
 
5373
        case 5:
 
5374
            DECODE_PRINTF("SUB\t");
 
5375
            break;
 
5376
        case 6:
 
5377
            DECODE_PRINTF("XOR\t");
 
5378
            break;
 
5379
        case 7:
 
5380
            DECODE_PRINTF("CMP\t");
 
5381
            break;
 
5382
        }
 
5383
    }
 
5384
#endif
 
5385
    /*
 
5386
     * Know operation, decode the mod byte to find the addressing 
 
5387
     * mode.
 
5388
     */
 
5389
    switch (mod) {
 
5390
    case 0:
 
5391
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
5392
            u32 destval,imm;
 
5393
 
 
5394
            DECODE_PRINTF("DWORD PTR ");
 
5395
            destoffset = decode_rm00_address(rl);
 
5396
            DECODE_PRINTF(",");
 
5397
            destval = fetch_data_long(destoffset);
 
5398
            imm = fetch_long_imm();
 
5399
            DECODE_PRINTF2("%x\n", imm);
 
5400
            TRACE_AND_STEP();
 
5401
            destval = (*opc81_long_operation[rh]) (destval, imm);
 
5402
            if (rh != 7)
 
5403
                store_data_long(destoffset, destval);
 
5404
        } else {
 
5405
            u16 destval,imm;
 
5406
 
 
5407
            DECODE_PRINTF("WORD PTR ");
 
5408
            destoffset = decode_rm00_address(rl);
 
5409
            DECODE_PRINTF(",");
 
5410
            destval = fetch_data_word(destoffset);
 
5411
            imm = fetch_word_imm();
 
5412
            DECODE_PRINTF2("%x\n", imm);
 
5413
            TRACE_AND_STEP();
 
5414
            destval = (*opc81_word_operation[rh]) (destval, imm);
 
5415
            if (rh != 7)
 
5416
                store_data_word(destoffset, destval);
 
5417
        }
 
5418
        break;
 
5419
    case 1:
 
5420
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
5421
            u32 destval,imm;
 
5422
 
 
5423
            DECODE_PRINTF("DWORD PTR ");
 
5424
            destoffset = decode_rm01_address(rl);
 
5425
            DECODE_PRINTF(",");
 
5426
            destval = fetch_data_long(destoffset);
 
5427
            imm = fetch_long_imm();
 
5428
            DECODE_PRINTF2("%x\n", imm);
 
5429
            TRACE_AND_STEP();
 
5430
            destval = (*opc81_long_operation[rh]) (destval, imm);
 
5431
            if (rh != 7)
 
5432
                store_data_long(destoffset, destval);
 
5433
        } else {
 
5434
            u16 destval,imm;
 
5435
 
 
5436
            DECODE_PRINTF("WORD PTR ");
 
5437
            destoffset = decode_rm01_address(rl);
 
5438
            DECODE_PRINTF(",");
 
5439
            destval = fetch_data_word(destoffset);
 
5440
            imm = fetch_word_imm();
 
5441
            DECODE_PRINTF2("%x\n", imm);
 
5442
            TRACE_AND_STEP();
 
5443
            destval = (*opc81_word_operation[rh]) (destval, imm);
 
5444
            if (rh != 7)
 
5445
                store_data_word(destoffset, destval);
 
5446
        }
 
5447
        break;
 
5448
    case 2:
 
5449
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
5450
            u32 destval,imm;
 
5451
 
 
5452
            DECODE_PRINTF("DWORD PTR ");
 
5453
            destoffset = decode_rm10_address(rl);
 
5454
            DECODE_PRINTF(",");
 
5455
            destval = fetch_data_long(destoffset);
 
5456
            imm = fetch_long_imm();
 
5457
            DECODE_PRINTF2("%x\n", imm);
 
5458
            TRACE_AND_STEP();
 
5459
            destval = (*opc81_long_operation[rh]) (destval, imm);
 
5460
            if (rh != 7)
 
5461
                store_data_long(destoffset, destval);
 
5462
        } else {
 
5463
            u16 destval,imm;
 
5464
 
 
5465
            DECODE_PRINTF("WORD PTR ");
 
5466
            destoffset = decode_rm10_address(rl);
 
5467
            DECODE_PRINTF(",");
 
5468
            destval = fetch_data_word(destoffset);
 
5469
            imm = fetch_word_imm();
 
5470
            DECODE_PRINTF2("%x\n", imm);
 
5471
            TRACE_AND_STEP();
 
5472
            destval = (*opc81_word_operation[rh]) (destval, imm);
 
5473
            if (rh != 7)
 
5474
                store_data_word(destoffset, destval);
 
5475
        }
 
5476
        break;
 
5477
    case 3:                     /* register to register */
 
5478
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
5479
            u32 *destreg;
 
5480
            u32 destval,imm;
 
5481
 
 
5482
            destreg = DECODE_RM_LONG_REGISTER(rl);
 
5483
            DECODE_PRINTF(",");
 
5484
            imm = fetch_long_imm();
 
5485
            DECODE_PRINTF2("%x\n", imm);
 
5486
            TRACE_AND_STEP();
 
5487
            destval = (*opc81_long_operation[rh]) (*destreg, imm);
 
5488
            if (rh != 7)
 
5489
                *destreg = destval;
 
5490
        } else {
 
5491
            u16 *destreg;
 
5492
            u16 destval,imm;
 
5493
 
 
5494
            destreg = DECODE_RM_WORD_REGISTER(rl);
 
5495
            DECODE_PRINTF(",");
 
5496
            imm = fetch_word_imm();
 
5497
            DECODE_PRINTF2("%x\n", imm);
 
5498
            TRACE_AND_STEP();
 
5499
            destval = (*opc81_word_operation[rh]) (*destreg, imm);
 
5500
            if (rh != 7)
 
5501
                *destreg = destval;
 
5502
        }
 
5503
        break;
 
5504
    }
 
5505
    DECODE_CLEAR_SEGOVR();
 
5506
    END_OF_INSTR();
 
5507
}
 
5508
 
 
5509
static u8 (*opc82_byte_operation[])(u8 s, u8 d) =
 
5510
{
 
5511
    add_byte,           /*00 */
 
5512
    or_byte,            /*01 *//*YYY UNUSED ???? */
 
5513
    adc_byte,           /*02 */
 
5514
    sbb_byte,           /*03 */
 
5515
    and_byte,           /*04 *//*YYY UNUSED ???? */
 
5516
    sub_byte,           /*05 */
 
5517
    xor_byte,           /*06 *//*YYY UNUSED ???? */
 
5518
    cmp_byte,           /*07 */
 
5519
};
 
5520
 
 
5521
/****************************************************************************
 
5522
REMARKS:
 
5523
Handles opcode 0x82
 
5524
****************************************************************************/
 
5525
static void x86emuOp_opc82_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
 
5526
{
 
5527
    int mod, rl, rh;
 
5528
    u8 *destreg;
 
5529
    uint destoffset;
 
5530
    u8 imm;
 
5531
    u8 destval;
 
5532
 
 
5533
    /*
 
5534
     * Weirdo special case instruction format.  Part of the opcode
 
5535
     * held below in "RH".  Doubly nested case would result, except
 
5536
     * that the decoded instruction Similar to opcode 81, except that
 
5537
     * the immediate byte is sign extended to a word length.
 
5538
     */
 
5539
    START_OF_INSTR();
 
5540
    FETCH_DECODE_MODRM(mod, rh, rl);
 
5541
#ifdef DEBUG
 
5542
    if (DEBUG_DECODE()) {
 
5543
        /* XXX DECODE_PRINTF may be changed to something more
 
5544
           general, so that it is important to leave the strings
 
5545
           in the same format, even though the result is that the 
 
5546
           above test is done twice. */
 
5547
        switch (rh) {
 
5548
        case 0:
 
5549
            DECODE_PRINTF("ADD\t");
 
5550
            break;
 
5551
        case 1:
 
5552
            DECODE_PRINTF("OR\t");
 
5553
            break;
 
5554
        case 2:
 
5555
            DECODE_PRINTF("ADC\t");
 
5556
            break;
 
5557
        case 3:
 
5558
            DECODE_PRINTF("SBB\t");
 
5559
            break;
 
5560
        case 4:
 
5561
            DECODE_PRINTF("AND\t");
 
5562
            break;
 
5563
        case 5:
 
5564
            DECODE_PRINTF("SUB\t");
 
5565
            break;
 
5566
        case 6:
 
5567
            DECODE_PRINTF("XOR\t");
 
5568
            break;
 
5569
        case 7:
 
5570
            DECODE_PRINTF("CMP\t");
 
5571
            break;
 
5572
        }
 
5573
    }
 
5574
#endif
 
5575
    /* know operation, decode the mod byte to find the addressing
 
5576
       mode. */
 
5577
    switch (mod) {
 
5578
    case 0:
 
5579
        DECODE_PRINTF("BYTE PTR ");
 
5580
        destoffset = decode_rm00_address(rl);
 
5581
        destval = fetch_data_byte(destoffset);
 
5582
        imm = fetch_byte_imm();
 
5583
        DECODE_PRINTF2(",%x\n", imm);
 
5584
        TRACE_AND_STEP();
 
5585
        destval = (*opc82_byte_operation[rh]) (destval, imm);
 
5586
        if (rh != 7)
 
5587
            store_data_byte(destoffset, destval);
 
5588
        break;
 
5589
    case 1:
 
5590
        DECODE_PRINTF("BYTE PTR ");
 
5591
        destoffset = decode_rm01_address(rl);
 
5592
        destval = fetch_data_byte(destoffset);
 
5593
        imm = fetch_byte_imm();
 
5594
        DECODE_PRINTF2(",%x\n", imm);
 
5595
        TRACE_AND_STEP();
 
5596
        destval = (*opc82_byte_operation[rh]) (destval, imm);
 
5597
        if (rh != 7)
 
5598
            store_data_byte(destoffset, destval);
 
5599
        break;
 
5600
    case 2:
 
5601
        DECODE_PRINTF("BYTE PTR ");
 
5602
        destoffset = decode_rm10_address(rl);
 
5603
        destval = fetch_data_byte(destoffset);
 
5604
        imm = fetch_byte_imm();
 
5605
        DECODE_PRINTF2(",%x\n", imm);
 
5606
        TRACE_AND_STEP();
 
5607
        destval = (*opc82_byte_operation[rh]) (destval, imm);
 
5608
        if (rh != 7)
 
5609
            store_data_byte(destoffset, destval);
 
5610
        break;
 
5611
    case 3:                     /* register to register */
 
5612
        destreg = DECODE_RM_BYTE_REGISTER(rl);
 
5613
        imm = fetch_byte_imm();
 
5614
        DECODE_PRINTF2(",%x\n", imm);
 
5615
        TRACE_AND_STEP();
 
5616
        destval = (*opc82_byte_operation[rh]) (*destreg, imm);
 
5617
        if (rh != 7)
 
5618
            *destreg = destval;
 
5619
        break;
 
5620
    }
 
5621
    DECODE_CLEAR_SEGOVR();
 
5622
    END_OF_INSTR();
 
5623
}
 
5624
 
 
5625
static u16 (*opc83_word_operation[])(u16 s, u16 d) =
 
5626
{
 
5627
    add_word,           /*00 */
 
5628
    or_word,            /*01 *//*YYY UNUSED ???? */
 
5629
    adc_word,           /*02 */
 
5630
    sbb_word,           /*03 */
 
5631
    and_word,           /*04 *//*YYY UNUSED ???? */
 
5632
    sub_word,           /*05 */
 
5633
    xor_word,           /*06 *//*YYY UNUSED ???? */
 
5634
    cmp_word,           /*07 */
 
5635
};
 
5636
 
 
5637
static u32 (*opc83_long_operation[])(u32 s, u32 d) =
 
5638
{
 
5639
    add_long,           /*00 */
 
5640
    or_long,            /*01 *//*YYY UNUSED ???? */
 
5641
    adc_long,           /*02 */
 
5642
    sbb_long,           /*03 */
 
5643
    and_long,           /*04 *//*YYY UNUSED ???? */
 
5644
    sub_long,           /*05 */
 
5645
    xor_long,           /*06 *//*YYY UNUSED ???? */
 
5646
    cmp_long,           /*07 */
 
5647
};
 
5648
 
 
5649
/****************************************************************************
 
5650
REMARKS:
 
5651
Handles opcode 0x83
 
5652
****************************************************************************/
 
5653
static void x86emuOp_opc83_word_RM_IMM(u8 X86EMU_UNUSED(op1))
 
5654
{
 
5655
    int mod, rl, rh;
 
5656
    uint destoffset;
 
5657
 
 
5658
    /*
 
5659
     * Weirdo special case instruction format.  Part of the opcode
 
5660
     * held below in "RH".  Doubly nested case would result, except
 
5661
     * that the decoded instruction Similar to opcode 81, except that
 
5662
     * the immediate byte is sign extended to a word length.
 
5663
     */
 
5664
    START_OF_INSTR();
 
5665
    FETCH_DECODE_MODRM(mod, rh, rl);
 
5666
#ifdef DEBUG
 
5667
    if (DEBUG_DECODE()) {
 
5668
        /* XXX DECODE_PRINTF may be changed to something more
 
5669
           general, so that it is important to leave the strings
 
5670
           in the same format, even though the result is that the 
 
5671
           above test is done twice. */
 
5672
       switch (rh) {
 
5673
        case 0:
 
5674
            DECODE_PRINTF("ADD\t");
 
5675
            break;
 
5676
        case 1:
 
5677
            DECODE_PRINTF("OR\t");
 
5678
            break;
 
5679
        case 2:
 
5680
            DECODE_PRINTF("ADC\t");
 
5681
            break;
 
5682
        case 3:
 
5683
            DECODE_PRINTF("SBB\t");
 
5684
            break;
 
5685
        case 4:
 
5686
            DECODE_PRINTF("AND\t");
 
5687
            break;
 
5688
        case 5:
 
5689
            DECODE_PRINTF("SUB\t");
 
5690
            break;
 
5691
        case 6:
 
5692
            DECODE_PRINTF("XOR\t");
 
5693
            break;
 
5694
        case 7:
 
5695
            DECODE_PRINTF("CMP\t");
 
5696
            break;
 
5697
        }
 
5698
    }
 
5699
#endif
 
5700
    /* know operation, decode the mod byte to find the addressing
 
5701
       mode. */
 
5702
    switch (mod) {
 
5703
    case 0:
 
5704
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
5705
            u32 destval,imm;
 
5706
 
 
5707
            DECODE_PRINTF("DWORD PTR ");
 
5708
            destoffset = decode_rm00_address(rl);
 
5709
            destval = fetch_data_long(destoffset);
 
5710
            imm = (s8) fetch_byte_imm();
 
5711
            DECODE_PRINTF2(",%x\n", imm);
 
5712
            TRACE_AND_STEP();
 
5713
            destval = (*opc83_long_operation[rh]) (destval, imm);
 
5714
            if (rh != 7)
 
5715
                store_data_long(destoffset, destval);
 
5716
        } else {
 
5717
            u16 destval,imm;
 
5718
 
 
5719
            DECODE_PRINTF("WORD PTR ");
 
5720
            destoffset = decode_rm00_address(rl);
 
5721
            destval = fetch_data_word(destoffset);
 
5722
            imm = (s8) fetch_byte_imm();
 
5723
            DECODE_PRINTF2(",%x\n", imm);
 
5724
            TRACE_AND_STEP();
 
5725
            destval = (*opc83_word_operation[rh]) (destval, imm);
 
5726
            if (rh != 7)
 
5727
                store_data_word(destoffset, destval);
 
5728
        }
 
5729
        break;
 
5730
    case 1:
 
5731
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
5732
            u32 destval,imm;
 
5733
 
 
5734
            DECODE_PRINTF("DWORD PTR ");
 
5735
            destoffset = decode_rm01_address(rl);
 
5736
            destval = fetch_data_long(destoffset);
 
5737
            imm = (s8) fetch_byte_imm();
 
5738
            DECODE_PRINTF2(",%x\n", imm);
 
5739
            TRACE_AND_STEP();
 
5740
            destval = (*opc83_long_operation[rh]) (destval, imm);
 
5741
            if (rh != 7)
 
5742
                store_data_long(destoffset, destval);
 
5743
        } else {
 
5744
            u16 destval,imm;
 
5745
 
 
5746
            DECODE_PRINTF("WORD PTR ");
 
5747
            destoffset = decode_rm01_address(rl);
 
5748
            destval = fetch_data_word(destoffset);
 
5749
            imm = (s8) fetch_byte_imm();
 
5750
            DECODE_PRINTF2(",%x\n", imm);
 
5751
            TRACE_AND_STEP();
 
5752
            destval = (*opc83_word_operation[rh]) (destval, imm);
 
5753
            if (rh != 7)
 
5754
                store_data_word(destoffset, destval);
 
5755
        }
 
5756
        break;
 
5757
    case 2:
 
5758
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
5759
            u32 destval,imm;
 
5760
 
 
5761
            DECODE_PRINTF("DWORD PTR ");
 
5762
            destoffset = decode_rm10_address(rl);
 
5763
            destval = fetch_data_long(destoffset);
 
5764
            imm = (s8) fetch_byte_imm();
 
5765
            DECODE_PRINTF2(",%x\n", imm);
 
5766
            TRACE_AND_STEP();
 
5767
            destval = (*opc83_long_operation[rh]) (destval, imm);
 
5768
            if (rh != 7)
 
5769
                store_data_long(destoffset, destval);
 
5770
        } else {
 
5771
            u16 destval,imm;
 
5772
 
 
5773
            DECODE_PRINTF("WORD PTR ");
 
5774
            destoffset = decode_rm10_address(rl);
 
5775
            destval = fetch_data_word(destoffset);
 
5776
            imm = (s8) fetch_byte_imm();
 
5777
            DECODE_PRINTF2(",%x\n", imm);
 
5778
            TRACE_AND_STEP();
 
5779
            destval = (*opc83_word_operation[rh]) (destval, imm);
 
5780
            if (rh != 7)
 
5781
                store_data_word(destoffset, destval);
 
5782
        }
 
5783
        break;
 
5784
    case 3:                     /* register to register */
 
5785
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
5786
            u32 *destreg;
 
5787
            u32 destval,imm;
 
5788
 
 
5789
            destreg = DECODE_RM_LONG_REGISTER(rl);
 
5790
            imm = (s8) fetch_byte_imm();
 
5791
            DECODE_PRINTF2(",%x\n", imm);
 
5792
            TRACE_AND_STEP();
 
5793
            destval = (*opc83_long_operation[rh]) (*destreg, imm);
 
5794
            if (rh != 7)
 
5795
                *destreg = destval;
 
5796
        } else {
 
5797
            u16 *destreg;
 
5798
            u16 destval,imm;
 
5799
 
 
5800
            destreg = DECODE_RM_WORD_REGISTER(rl);
 
5801
            imm = (s8) fetch_byte_imm();
 
5802
            DECODE_PRINTF2(",%x\n", imm);
 
5803
            TRACE_AND_STEP();
 
5804
            destval = (*opc83_word_operation[rh]) (*destreg, imm);
 
5805
            if (rh != 7)
 
5806
                *destreg = destval;
 
5807
        }
 
5808
        break;
 
5809
    }
 
5810
    DECODE_CLEAR_SEGOVR();
 
5811
    END_OF_INSTR();
 
5812
}
 
5813
 
 
5814
/****************************************************************************
 
5815
REMARKS:
 
5816
Handles opcode 0x84
 
5817
****************************************************************************/
 
5818
static void x86emuOp_test_byte_RM_R(u8 X86EMU_UNUSED(op1))
 
5819
{
 
5820
    int mod, rl, rh;
 
5821
    u8 *destreg, *srcreg;
 
5822
    uint destoffset;
 
5823
    u8 destval;
 
5824
 
 
5825
    START_OF_INSTR();
 
5826
    DECODE_PRINTF("TEST\t");
 
5827
    FETCH_DECODE_MODRM(mod, rh, rl);
 
5828
    switch (mod) {
 
5829
    case 0:
 
5830
        destoffset = decode_rm00_address(rl);
 
5831
        DECODE_PRINTF(",");
 
5832
        destval = fetch_data_byte(destoffset);
 
5833
        srcreg = DECODE_RM_BYTE_REGISTER(rh);
 
5834
        DECODE_PRINTF("\n");
 
5835
        TRACE_AND_STEP();
 
5836
        test_byte(destval, *srcreg);
 
5837
        break;
 
5838
    case 1:
 
5839
        destoffset = decode_rm01_address(rl);
 
5840
        DECODE_PRINTF(",");
 
5841
        destval = fetch_data_byte(destoffset);
 
5842
        srcreg = DECODE_RM_BYTE_REGISTER(rh);
 
5843
        DECODE_PRINTF("\n");
 
5844
        TRACE_AND_STEP();
 
5845
        test_byte(destval, *srcreg);
 
5846
        break;
 
5847
    case 2:
 
5848
        destoffset = decode_rm10_address(rl);
 
5849
        DECODE_PRINTF(",");
 
5850
        destval = fetch_data_byte(destoffset);
 
5851
        srcreg = DECODE_RM_BYTE_REGISTER(rh);
 
5852
        DECODE_PRINTF("\n");
 
5853
        TRACE_AND_STEP();
 
5854
        test_byte(destval, *srcreg);
 
5855
        break;
 
5856
    case 3:                     /* register to register */
 
5857
        destreg = DECODE_RM_BYTE_REGISTER(rl);
 
5858
        DECODE_PRINTF(",");
 
5859
        srcreg = DECODE_RM_BYTE_REGISTER(rh);
 
5860
        DECODE_PRINTF("\n");
 
5861
        TRACE_AND_STEP();
 
5862
        test_byte(*destreg, *srcreg);
 
5863
        break;
 
5864
    }
 
5865
    DECODE_CLEAR_SEGOVR();
 
5866
    END_OF_INSTR();
 
5867
}
 
5868
 
 
5869
/****************************************************************************
 
5870
REMARKS:
 
5871
Handles opcode 0x85
 
5872
****************************************************************************/
 
5873
static void x86emuOp_test_word_RM_R(u8 X86EMU_UNUSED(op1))
 
5874
{
 
5875
    int mod, rl, rh;
 
5876
    uint destoffset;
 
5877
 
 
5878
    START_OF_INSTR();
 
5879
    DECODE_PRINTF("TEST\t");
 
5880
    FETCH_DECODE_MODRM(mod, rh, rl);
 
5881
    switch (mod) {
 
5882
    case 0:
 
5883
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
5884
            u32 destval;
 
5885
            u32 *srcreg;
 
5886
 
 
5887
            destoffset = decode_rm00_address(rl);
 
5888
            DECODE_PRINTF(",");
 
5889
            destval = fetch_data_long(destoffset);
 
5890
            srcreg = DECODE_RM_LONG_REGISTER(rh);
 
5891
            DECODE_PRINTF("\n");
 
5892
            TRACE_AND_STEP();
 
5893
            test_long(destval, *srcreg);
 
5894
        } else {
 
5895
            u16 destval;
 
5896
            u16 *srcreg;
 
5897
 
 
5898
            destoffset = decode_rm00_address(rl);
 
5899
            DECODE_PRINTF(",");
 
5900
            destval = fetch_data_word(destoffset);
 
5901
            srcreg = DECODE_RM_WORD_REGISTER(rh);
 
5902
            DECODE_PRINTF("\n");
 
5903
            TRACE_AND_STEP();
 
5904
            test_word(destval, *srcreg);
 
5905
        }
 
5906
        break;
 
5907
    case 1:
 
5908
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
5909
            u32 destval;
 
5910
            u32 *srcreg;
 
5911
 
 
5912
            destoffset = decode_rm01_address(rl);
 
5913
            DECODE_PRINTF(",");
 
5914
            destval = fetch_data_long(destoffset);
 
5915
            srcreg = DECODE_RM_LONG_REGISTER(rh);
 
5916
            DECODE_PRINTF("\n");
 
5917
            TRACE_AND_STEP();
 
5918
            test_long(destval, *srcreg);
 
5919
        } else {
 
5920
            u16 destval;
 
5921
            u16 *srcreg;
 
5922
 
 
5923
            destoffset = decode_rm01_address(rl);
 
5924
            DECODE_PRINTF(",");
 
5925
            destval = fetch_data_word(destoffset);
 
5926
            srcreg = DECODE_RM_WORD_REGISTER(rh);
 
5927
            DECODE_PRINTF("\n");
 
5928
            TRACE_AND_STEP();
 
5929
            test_word(destval, *srcreg);
 
5930
        }
 
5931
        break;
 
5932
    case 2:
 
5933
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
5934
            u32 destval;
 
5935
            u32 *srcreg;
 
5936
 
 
5937
            destoffset = decode_rm10_address(rl);
 
5938
            DECODE_PRINTF(",");
 
5939
            destval = fetch_data_long(destoffset);
 
5940
            srcreg = DECODE_RM_LONG_REGISTER(rh);
 
5941
            DECODE_PRINTF("\n");
 
5942
            TRACE_AND_STEP();
 
5943
            test_long(destval, *srcreg);
 
5944
        } else {
 
5945
            u16 destval;
 
5946
            u16 *srcreg;
 
5947
 
 
5948
            destoffset = decode_rm10_address(rl);
 
5949
            DECODE_PRINTF(",");
 
5950
            destval = fetch_data_word(destoffset);
 
5951
            srcreg = DECODE_RM_WORD_REGISTER(rh);
 
5952
            DECODE_PRINTF("\n");
 
5953
            TRACE_AND_STEP();
 
5954
            test_word(destval, *srcreg);
 
5955
        }
 
5956
        break;
 
5957
    case 3:                     /* register to register */
 
5958
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
5959
            u32 *destreg,*srcreg;
 
5960
 
 
5961
            destreg = DECODE_RM_LONG_REGISTER(rl);
 
5962
            DECODE_PRINTF(",");
 
5963
            srcreg = DECODE_RM_LONG_REGISTER(rh);
 
5964
            DECODE_PRINTF("\n");
 
5965
            TRACE_AND_STEP();
 
5966
            test_long(*destreg, *srcreg);
 
5967
        } else {
 
5968
            u16 *destreg,*srcreg;
 
5969
 
 
5970
            destreg = DECODE_RM_WORD_REGISTER(rl);
 
5971
            DECODE_PRINTF(",");
 
5972
            srcreg = DECODE_RM_WORD_REGISTER(rh);
 
5973
            DECODE_PRINTF("\n");
 
5974
            TRACE_AND_STEP();
 
5975
            test_word(*destreg, *srcreg);
 
5976
        }
 
5977
        break;
 
5978
    }
 
5979
    DECODE_CLEAR_SEGOVR();
 
5980
    END_OF_INSTR();
 
5981
}
 
5982
 
 
5983
/****************************************************************************
 
5984
REMARKS:
 
5985
Handles opcode 0x86
 
5986
****************************************************************************/
 
5987
static void x86emuOp_xchg_byte_RM_R(u8 X86EMU_UNUSED(op1))
 
5988
{
 
5989
    int mod, rl, rh;
 
5990
    u8 *destreg, *srcreg;
 
5991
    uint destoffset;
 
5992
    u8 destval;
 
5993
    u8 tmp;
 
5994
 
 
5995
    START_OF_INSTR();
 
5996
    DECODE_PRINTF("XCHG\t");
 
5997
    FETCH_DECODE_MODRM(mod, rh, rl);
 
5998
    switch (mod) {
 
5999
    case 0:
 
6000
        destoffset = decode_rm00_address(rl);
 
6001
        DECODE_PRINTF(",");
 
6002
        destval = fetch_data_byte(destoffset);
 
6003
        srcreg = DECODE_RM_BYTE_REGISTER(rh);
 
6004
        DECODE_PRINTF("\n");
 
6005
        TRACE_AND_STEP();
 
6006
        tmp = *srcreg;
 
6007
        *srcreg = destval;
 
6008
        destval = tmp;
 
6009
        store_data_byte(destoffset, destval);
 
6010
        break;
 
6011
    case 1:
 
6012
        destoffset = decode_rm01_address(rl);
 
6013
        DECODE_PRINTF(",");
 
6014
        destval = fetch_data_byte(destoffset);
 
6015
        srcreg = DECODE_RM_BYTE_REGISTER(rh);
 
6016
        DECODE_PRINTF("\n");
 
6017
        TRACE_AND_STEP();
 
6018
        tmp = *srcreg;
 
6019
        *srcreg = destval;
 
6020
        destval = tmp;
 
6021
        store_data_byte(destoffset, destval);
 
6022
        break;
 
6023
    case 2:
 
6024
        destoffset = decode_rm10_address(rl);
 
6025
        DECODE_PRINTF(",");
 
6026
        destval = fetch_data_byte(destoffset);
 
6027
        srcreg = DECODE_RM_BYTE_REGISTER(rh);
 
6028
        DECODE_PRINTF("\n");
 
6029
        TRACE_AND_STEP();
 
6030
        tmp = *srcreg;
 
6031
        *srcreg = destval;
 
6032
        destval = tmp;
 
6033
        store_data_byte(destoffset, destval);
 
6034
        break;
 
6035
    case 3:                     /* register to register */
 
6036
        destreg = DECODE_RM_BYTE_REGISTER(rl);
 
6037
        DECODE_PRINTF(",");
 
6038
        srcreg = DECODE_RM_BYTE_REGISTER(rh);
 
6039
        DECODE_PRINTF("\n");
 
6040
        TRACE_AND_STEP();
 
6041
        tmp = *srcreg;
 
6042
        *srcreg = *destreg;
 
6043
        *destreg = tmp;
 
6044
        break;
 
6045
    }
 
6046
    DECODE_CLEAR_SEGOVR();
 
6047
    END_OF_INSTR();
 
6048
}
 
6049
 
 
6050
/****************************************************************************
 
6051
REMARKS:
 
6052
Handles opcode 0x87
 
6053
****************************************************************************/
 
6054
static void x86emuOp_xchg_word_RM_R(u8 X86EMU_UNUSED(op1))
 
6055
{
 
6056
    int mod, rl, rh;
 
6057
    uint destoffset;
 
6058
 
 
6059
    START_OF_INSTR();
 
6060
    DECODE_PRINTF("XCHG\t");
 
6061
    FETCH_DECODE_MODRM(mod, rh, rl);
 
6062
    switch (mod) {
 
6063
    case 0:
 
6064
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
6065
            u32 *srcreg;
 
6066
            u32 destval,tmp;
 
6067
 
 
6068
            destoffset = decode_rm00_address(rl);
 
6069
            DECODE_PRINTF(",");
 
6070
            destval = fetch_data_long(destoffset);
 
6071
            srcreg = DECODE_RM_LONG_REGISTER(rh);
 
6072
            DECODE_PRINTF("\n");
 
6073
            TRACE_AND_STEP();
 
6074
            tmp = *srcreg;
 
6075
            *srcreg = destval;
 
6076
            destval = tmp;
 
6077
            store_data_long(destoffset, destval);
 
6078
        } else {
 
6079
            u16 *srcreg;
 
6080
            u16 destval,tmp;
 
6081
 
 
6082
            destoffset = decode_rm00_address(rl);
 
6083
            DECODE_PRINTF(",");
 
6084
            destval = fetch_data_word(destoffset);
 
6085
            srcreg = DECODE_RM_WORD_REGISTER(rh);
 
6086
            DECODE_PRINTF("\n");
 
6087
            TRACE_AND_STEP();
 
6088
            tmp = *srcreg;
 
6089
            *srcreg = destval;
 
6090
            destval = tmp;
 
6091
            store_data_word(destoffset, destval);
 
6092
        }
 
6093
        break;
 
6094
    case 1:
 
6095
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
6096
            u32 *srcreg;
 
6097
            u32 destval,tmp;
 
6098
 
 
6099
            destoffset = decode_rm01_address(rl);
 
6100
            DECODE_PRINTF(",");
 
6101
            destval = fetch_data_long(destoffset);
 
6102
            srcreg = DECODE_RM_LONG_REGISTER(rh);
 
6103
            DECODE_PRINTF("\n");
 
6104
            TRACE_AND_STEP();
 
6105
            tmp = *srcreg;
 
6106
            *srcreg = destval;
 
6107
            destval = tmp;
 
6108
            store_data_long(destoffset, destval);
 
6109
        } else {
 
6110
            u16 *srcreg;
 
6111
            u16 destval,tmp;
 
6112
 
 
6113
            destoffset = decode_rm01_address(rl);
 
6114
            DECODE_PRINTF(",");
 
6115
            destval = fetch_data_word(destoffset);
 
6116
            srcreg = DECODE_RM_WORD_REGISTER(rh);
 
6117
            DECODE_PRINTF("\n");
 
6118
            TRACE_AND_STEP();
 
6119
            tmp = *srcreg;
 
6120
            *srcreg = destval;
 
6121
            destval = tmp;
 
6122
            store_data_word(destoffset, destval);
 
6123
        }
 
6124
        break;
 
6125
    case 2:
 
6126
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
6127
            u32 *srcreg;
 
6128
            u32 destval,tmp;
 
6129
 
 
6130
            destoffset = decode_rm10_address(rl);
 
6131
            DECODE_PRINTF(",");
 
6132
            destval = fetch_data_long(destoffset);
 
6133
            srcreg = DECODE_RM_LONG_REGISTER(rh);
 
6134
            DECODE_PRINTF("\n");
 
6135
            TRACE_AND_STEP();
 
6136
            tmp = *srcreg;
 
6137
            *srcreg = destval;
 
6138
            destval = tmp;
 
6139
            store_data_long(destoffset, destval);
 
6140
        } else {
 
6141
            u16 *srcreg;
 
6142
            u16 destval,tmp;
 
6143
 
 
6144
            destoffset = decode_rm10_address(rl);
 
6145
            DECODE_PRINTF(",");
 
6146
            destval = fetch_data_word(destoffset);
 
6147
            srcreg = DECODE_RM_WORD_REGISTER(rh);
 
6148
            DECODE_PRINTF("\n");
 
6149
            TRACE_AND_STEP();
 
6150
            tmp = *srcreg;
 
6151
            *srcreg = destval;
 
6152
            destval = tmp;
 
6153
            store_data_word(destoffset, destval);
 
6154
        }
 
6155
        break;
 
6156
    case 3:                     /* register to register */
 
6157
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
6158
            u32 *destreg,*srcreg;
 
6159
            u32 tmp;
 
6160
 
 
6161
            destreg = DECODE_RM_LONG_REGISTER(rl);
 
6162
            DECODE_PRINTF(",");
 
6163
            srcreg = DECODE_RM_LONG_REGISTER(rh);
 
6164
            DECODE_PRINTF("\n");
 
6165
            TRACE_AND_STEP();
 
6166
            tmp = *srcreg;
 
6167
            *srcreg = *destreg;
 
6168
            *destreg = tmp;
 
6169
        } else {
 
6170
            u16 *destreg,*srcreg;
 
6171
            u16 tmp;
 
6172
 
 
6173
            destreg = DECODE_RM_WORD_REGISTER(rl);
 
6174
            DECODE_PRINTF(",");
 
6175
            srcreg = DECODE_RM_WORD_REGISTER(rh);
 
6176
            DECODE_PRINTF("\n");
 
6177
            TRACE_AND_STEP();
 
6178
            tmp = *srcreg;
 
6179
            *srcreg = *destreg;
 
6180
            *destreg = tmp;
 
6181
        }
 
6182
        break;
 
6183
    }
 
6184
    DECODE_CLEAR_SEGOVR();
 
6185
    END_OF_INSTR();
 
6186
}
 
6187
 
 
6188
/****************************************************************************
 
6189
REMARKS:
 
6190
Handles opcode 0x88
 
6191
****************************************************************************/
 
6192
static void x86emuOp_mov_byte_RM_R(u8 X86EMU_UNUSED(op1))
 
6193
{
 
6194
    int mod, rl, rh;
 
6195
    u8 *destreg, *srcreg;
 
6196
    uint destoffset;
 
6197
 
 
6198
    START_OF_INSTR();
 
6199
    DECODE_PRINTF("MOV\t");
 
6200
    FETCH_DECODE_MODRM(mod, rh, rl);
 
6201
    switch (mod) {
 
6202
    case 0:
 
6203
        destoffset = decode_rm00_address(rl);
 
6204
        DECODE_PRINTF(",");
 
6205
        srcreg = DECODE_RM_BYTE_REGISTER(rh);
 
6206
        DECODE_PRINTF("\n");
 
6207
        TRACE_AND_STEP();
 
6208
        store_data_byte(destoffset, *srcreg);
 
6209
        break;
 
6210
    case 1:
 
6211
        destoffset = decode_rm01_address(rl);
 
6212
        DECODE_PRINTF(",");
 
6213
        srcreg = DECODE_RM_BYTE_REGISTER(rh);
 
6214
        DECODE_PRINTF("\n");
 
6215
        TRACE_AND_STEP();
 
6216
        store_data_byte(destoffset, *srcreg);
 
6217
        break;
 
6218
    case 2:
 
6219
        destoffset = decode_rm10_address(rl);
 
6220
        DECODE_PRINTF(",");
 
6221
        srcreg = DECODE_RM_BYTE_REGISTER(rh);
 
6222
        DECODE_PRINTF("\n");
 
6223
        TRACE_AND_STEP();
 
6224
        store_data_byte(destoffset, *srcreg);
 
6225
        break;
 
6226
    case 3:                     /* register to register */
 
6227
        destreg = DECODE_RM_BYTE_REGISTER(rl);
 
6228
        DECODE_PRINTF(",");
 
6229
        srcreg = DECODE_RM_BYTE_REGISTER(rh);
 
6230
        DECODE_PRINTF("\n");
 
6231
        TRACE_AND_STEP();
 
6232
        *destreg = *srcreg;
 
6233
        break;
 
6234
    }
 
6235
    DECODE_CLEAR_SEGOVR();
 
6236
    END_OF_INSTR();
 
6237
}
 
6238
 
 
6239
/****************************************************************************
 
6240
REMARKS:
 
6241
Handles opcode 0x89
 
6242
****************************************************************************/
 
6243
static void x86emuOp_mov_word_RM_R(u8 X86EMU_UNUSED(op1))
 
6244
{
 
6245
    int mod, rl, rh;
 
6246
    u32 destoffset;
 
6247
 
 
6248
    START_OF_INSTR();
 
6249
    DECODE_PRINTF("MOV\t");
 
6250
    FETCH_DECODE_MODRM(mod, rh, rl);
 
6251
    switch (mod) {
 
6252
    case 0:
 
6253
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
6254
            u32 *srcreg;
 
6255
 
 
6256
            destoffset = decode_rm00_address(rl);
 
6257
            DECODE_PRINTF(",");
 
6258
            srcreg = DECODE_RM_LONG_REGISTER(rh);
 
6259
            DECODE_PRINTF("\n");
 
6260
            TRACE_AND_STEP();
 
6261
            store_data_long(destoffset, *srcreg);
 
6262
        } else {
 
6263
            u16 *srcreg;
 
6264
 
 
6265
            destoffset = decode_rm00_address(rl);
 
6266
            DECODE_PRINTF(",");
 
6267
            srcreg = DECODE_RM_WORD_REGISTER(rh);
 
6268
            DECODE_PRINTF("\n");
 
6269
            TRACE_AND_STEP();
 
6270
            store_data_word(destoffset, *srcreg);
 
6271
        }
 
6272
        break;
 
6273
    case 1:
 
6274
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
6275
            u32 *srcreg;
 
6276
 
 
6277
            destoffset = decode_rm01_address(rl);
 
6278
            DECODE_PRINTF(",");
 
6279
            srcreg = DECODE_RM_LONG_REGISTER(rh);
 
6280
            DECODE_PRINTF("\n");
 
6281
            TRACE_AND_STEP();
 
6282
            store_data_long(destoffset, *srcreg);
 
6283
        } else {
 
6284
            u16 *srcreg;
 
6285
 
 
6286
            destoffset = decode_rm01_address(rl);
 
6287
            DECODE_PRINTF(",");
 
6288
            srcreg = DECODE_RM_WORD_REGISTER(rh);
 
6289
            DECODE_PRINTF("\n");
 
6290
            TRACE_AND_STEP();
 
6291
            store_data_word(destoffset, *srcreg);
 
6292
        }
 
6293
        break;
 
6294
    case 2:
 
6295
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
6296
            u32 *srcreg;
 
6297
 
 
6298
            destoffset = decode_rm10_address(rl);
 
6299
            DECODE_PRINTF(",");
 
6300
            srcreg = DECODE_RM_LONG_REGISTER(rh);
 
6301
            DECODE_PRINTF("\n");
 
6302
            TRACE_AND_STEP();
 
6303
            store_data_long(destoffset, *srcreg);
 
6304
        } else {
 
6305
            u16 *srcreg;
 
6306
 
 
6307
            destoffset = decode_rm10_address(rl);
 
6308
            DECODE_PRINTF(",");
 
6309
            srcreg = DECODE_RM_WORD_REGISTER(rh);
 
6310
            DECODE_PRINTF("\n");
 
6311
            TRACE_AND_STEP();
 
6312
            store_data_word(destoffset, *srcreg);
 
6313
        }
 
6314
        break;
 
6315
    case 3:                     /* register to register */
 
6316
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
6317
            u32 *destreg,*srcreg;
 
6318
 
 
6319
            destreg = DECODE_RM_LONG_REGISTER(rl);
 
6320
            DECODE_PRINTF(",");
 
6321
            srcreg = DECODE_RM_LONG_REGISTER(rh);
 
6322
            DECODE_PRINTF("\n");
 
6323
            TRACE_AND_STEP();
 
6324
            *destreg = *srcreg;
 
6325
        } else {
 
6326
            u16 *destreg,*srcreg;
 
6327
 
 
6328
            destreg = DECODE_RM_WORD_REGISTER(rl);
 
6329
            DECODE_PRINTF(",");
 
6330
            srcreg = DECODE_RM_WORD_REGISTER(rh);
 
6331
            DECODE_PRINTF("\n");
 
6332
            TRACE_AND_STEP();
 
6333
            *destreg = *srcreg;
 
6334
        }
 
6335
        break;
 
6336
    }
 
6337
    DECODE_CLEAR_SEGOVR();
 
6338
    END_OF_INSTR();
 
6339
}
 
6340
 
 
6341
/****************************************************************************
 
6342
REMARKS:
 
6343
Handles opcode 0x8a
 
6344
****************************************************************************/
 
6345
static void x86emuOp_mov_byte_R_RM(u8 X86EMU_UNUSED(op1))
 
6346
{
 
6347
    int mod, rl, rh;
 
6348
    u8 *destreg, *srcreg;
 
6349
    uint srcoffset;
 
6350
    u8 srcval;
 
6351
 
 
6352
    START_OF_INSTR();
 
6353
    DECODE_PRINTF("MOV\t");
 
6354
    FETCH_DECODE_MODRM(mod, rh, rl);
 
6355
    switch (mod) {
 
6356
    case 0:
 
6357
        destreg = DECODE_RM_BYTE_REGISTER(rh);
 
6358
        DECODE_PRINTF(",");
 
6359
        srcoffset = decode_rm00_address(rl);
 
6360
        srcval = fetch_data_byte(srcoffset);
 
6361
        DECODE_PRINTF("\n");
 
6362
        TRACE_AND_STEP();
 
6363
        *destreg = srcval;
 
6364
        break;
 
6365
    case 1:
 
6366
        destreg = DECODE_RM_BYTE_REGISTER(rh);
 
6367
        DECODE_PRINTF(",");
 
6368
        srcoffset = decode_rm01_address(rl);
 
6369
        srcval = fetch_data_byte(srcoffset);
 
6370
        DECODE_PRINTF("\n");
 
6371
        TRACE_AND_STEP();
 
6372
        *destreg = srcval;
 
6373
        break;
 
6374
    case 2:
 
6375
        destreg = DECODE_RM_BYTE_REGISTER(rh);
 
6376
        DECODE_PRINTF(",");
 
6377
        srcoffset = decode_rm10_address(rl);
 
6378
        srcval = fetch_data_byte(srcoffset);
 
6379
        DECODE_PRINTF("\n");
 
6380
        TRACE_AND_STEP();
 
6381
        *destreg = srcval;
 
6382
        break;
 
6383
    case 3:                     /* register to register */
 
6384
        destreg = DECODE_RM_BYTE_REGISTER(rh);
 
6385
        DECODE_PRINTF(",");
 
6386
        srcreg = DECODE_RM_BYTE_REGISTER(rl);
 
6387
        DECODE_PRINTF("\n");
 
6388
        TRACE_AND_STEP();
 
6389
        *destreg = *srcreg;
 
6390
        break;
 
6391
    }
 
6392
    DECODE_CLEAR_SEGOVR();
 
6393
    END_OF_INSTR();
 
6394
}
 
6395
 
 
6396
/****************************************************************************
 
6397
REMARKS:
 
6398
Handles opcode 0x8b
 
6399
****************************************************************************/
 
6400
static void x86emuOp_mov_word_R_RM(u8 X86EMU_UNUSED(op1))
 
6401
{
 
6402
    int mod, rl, rh;
 
6403
    uint srcoffset;
 
6404
 
 
6405
    START_OF_INSTR();
 
6406
    DECODE_PRINTF("MOV\t");
 
6407
    FETCH_DECODE_MODRM(mod, rh, rl);
 
6408
    switch (mod) {
 
6409
    case 0:
 
6410
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
6411
            u32 *destreg;
 
6412
            u32 srcval;
 
6413
 
 
6414
            destreg = DECODE_RM_LONG_REGISTER(rh);
 
6415
            DECODE_PRINTF(",");
 
6416
            srcoffset = decode_rm00_address(rl);
 
6417
            srcval = fetch_data_long(srcoffset);
 
6418
            DECODE_PRINTF("\n");
 
6419
            TRACE_AND_STEP();
 
6420
            *destreg = srcval;
 
6421
        } else {
 
6422
            u16 *destreg;
 
6423
            u16 srcval;
 
6424
 
 
6425
            destreg = DECODE_RM_WORD_REGISTER(rh);
 
6426
            DECODE_PRINTF(",");
 
6427
            srcoffset = decode_rm00_address(rl);
 
6428
            srcval = fetch_data_word(srcoffset);
 
6429
            DECODE_PRINTF("\n");
 
6430
            TRACE_AND_STEP();
 
6431
            *destreg = srcval;
 
6432
        }
 
6433
        break;
 
6434
    case 1:
 
6435
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
6436
            u32 *destreg;
 
6437
            u32 srcval;
 
6438
 
 
6439
            destreg = DECODE_RM_LONG_REGISTER(rh);
 
6440
            DECODE_PRINTF(",");
 
6441
            srcoffset = decode_rm01_address(rl);
 
6442
            srcval = fetch_data_long(srcoffset);
 
6443
            DECODE_PRINTF("\n");
 
6444
            TRACE_AND_STEP();
 
6445
            *destreg = srcval;
 
6446
        } else {
 
6447
            u16 *destreg;
 
6448
            u16 srcval;
 
6449
 
 
6450
            destreg = DECODE_RM_WORD_REGISTER(rh);
 
6451
            DECODE_PRINTF(",");
 
6452
            srcoffset = decode_rm01_address(rl);
 
6453
            srcval = fetch_data_word(srcoffset);
 
6454
            DECODE_PRINTF("\n");
 
6455
            TRACE_AND_STEP();
 
6456
            *destreg = srcval;
 
6457
        }
 
6458
        break;
 
6459
    case 2:
 
6460
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
6461
            u32 *destreg;
 
6462
            u32 srcval;
 
6463
 
 
6464
            destreg = DECODE_RM_LONG_REGISTER(rh);
 
6465
            DECODE_PRINTF(",");
 
6466
            srcoffset = decode_rm10_address(rl);
 
6467
            srcval = fetch_data_long(srcoffset);
 
6468
            DECODE_PRINTF("\n");
 
6469
            TRACE_AND_STEP();
 
6470
            *destreg = srcval;
 
6471
        } else {
 
6472
            u16 *destreg;
 
6473
            u16 srcval;
 
6474
 
 
6475
            destreg = DECODE_RM_WORD_REGISTER(rh);
 
6476
            DECODE_PRINTF(",");
 
6477
            srcoffset = decode_rm10_address(rl);
 
6478
            srcval = fetch_data_word(srcoffset);
 
6479
            DECODE_PRINTF("\n");
 
6480
            TRACE_AND_STEP();
 
6481
            *destreg = srcval;
 
6482
        }
 
6483
        break;
 
6484
    case 3:                     /* register to register */
 
6485
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
6486
            u32 *destreg, *srcreg;
 
6487
 
 
6488
            destreg = DECODE_RM_LONG_REGISTER(rh);
 
6489
            DECODE_PRINTF(",");
 
6490
            srcreg = DECODE_RM_LONG_REGISTER(rl);
 
6491
            DECODE_PRINTF("\n");
 
6492
            TRACE_AND_STEP();
 
6493
            *destreg = *srcreg;
 
6494
        } else {
 
6495
            u16 *destreg, *srcreg;
 
6496
 
 
6497
            destreg = DECODE_RM_WORD_REGISTER(rh);
 
6498
            DECODE_PRINTF(",");
 
6499
            srcreg = DECODE_RM_WORD_REGISTER(rl);
 
6500
            DECODE_PRINTF("\n");
 
6501
            TRACE_AND_STEP();
 
6502
            *destreg = *srcreg;
 
6503
        }
 
6504
        break;
 
6505
    }
 
6506
    DECODE_CLEAR_SEGOVR();
 
6507
    END_OF_INSTR();
 
6508
}
 
6509
 
 
6510
/****************************************************************************
 
6511
REMARKS:
 
6512
Handles opcode 0x8c
 
6513
****************************************************************************/
 
6514
static void x86emuOp_mov_word_RM_SR(u8 X86EMU_UNUSED(op1))
 
6515
{
 
6516
    int mod, rl, rh;
 
6517
    u16 *destreg, *srcreg;
 
6518
    uint destoffset;
 
6519
    u16 destval;
 
6520
 
 
6521
    START_OF_INSTR();
 
6522
    DECODE_PRINTF("MOV\t");
 
6523
    FETCH_DECODE_MODRM(mod, rh, rl);
 
6524
    switch (mod) {
 
6525
    case 0:
 
6526
        destoffset = decode_rm00_address(rl);
 
6527
        DECODE_PRINTF(",");
 
6528
        srcreg = decode_rm_seg_register(rh);
 
6529
        DECODE_PRINTF("\n");
 
6530
        TRACE_AND_STEP();
 
6531
        destval = *srcreg;
 
6532
        store_data_word(destoffset, destval);
 
6533
        break;
 
6534
    case 1:
 
6535
        destoffset = decode_rm01_address(rl);
 
6536
        DECODE_PRINTF(",");
 
6537
        srcreg = decode_rm_seg_register(rh);
 
6538
        DECODE_PRINTF("\n");
 
6539
        TRACE_AND_STEP();
 
6540
        destval = *srcreg;
 
6541
        store_data_word(destoffset, destval);
 
6542
        break;
 
6543
    case 2:
 
6544
        destoffset = decode_rm10_address(rl);
 
6545
        DECODE_PRINTF(",");
 
6546
        srcreg = decode_rm_seg_register(rh);
 
6547
        DECODE_PRINTF("\n");
 
6548
        TRACE_AND_STEP();
 
6549
        destval = *srcreg;
 
6550
        store_data_word(destoffset, destval);
 
6551
        break;
 
6552
    case 3:                     /* register to register */
 
6553
        destreg = DECODE_RM_WORD_REGISTER(rl);
 
6554
        DECODE_PRINTF(",");
 
6555
        srcreg = decode_rm_seg_register(rh);
 
6556
        DECODE_PRINTF("\n");
 
6557
        TRACE_AND_STEP();
 
6558
        *destreg = *srcreg;
 
6559
        break;
 
6560
    }
 
6561
    DECODE_CLEAR_SEGOVR();
 
6562
    END_OF_INSTR();
 
6563
}
 
6564
 
 
6565
/****************************************************************************
 
6566
REMARKS:
 
6567
Handles opcode 0x8d
 
6568
****************************************************************************/
 
6569
static void x86emuOp_lea_word_R_M(u8 X86EMU_UNUSED(op1))
 
6570
{
 
6571
    int mod, rl, rh;
 
6572
    u16 *srcreg;
 
6573
    uint destoffset;
 
6574
 
 
6575
/*
 
6576
 * TODO: Need to handle address size prefix!
 
6577
 *
 
6578
 * lea  eax,[eax+ebx*2] ??
 
6579
 */
 
6580
    
 
6581
    START_OF_INSTR();
 
6582
    DECODE_PRINTF("LEA\t");
 
6583
    FETCH_DECODE_MODRM(mod, rh, rl);
 
6584
    switch (mod) {
 
6585
    case 0:
 
6586
        srcreg = DECODE_RM_WORD_REGISTER(rh);
 
6587
        DECODE_PRINTF(",");
 
6588
        destoffset = decode_rm00_address(rl);
 
6589
        DECODE_PRINTF("\n");
 
6590
        TRACE_AND_STEP();
 
6591
        *srcreg = (u16)destoffset;
 
6592
        break;
 
6593
    case 1:
 
6594
        srcreg = DECODE_RM_WORD_REGISTER(rh);
 
6595
        DECODE_PRINTF(",");
 
6596
        destoffset = decode_rm01_address(rl);
 
6597
        DECODE_PRINTF("\n");
 
6598
        TRACE_AND_STEP();
 
6599
        *srcreg = (u16)destoffset;
 
6600
        break;
 
6601
    case 2:
 
6602
        srcreg = DECODE_RM_WORD_REGISTER(rh);
 
6603
        DECODE_PRINTF(",");
 
6604
        destoffset = decode_rm10_address(rl);
 
6605
        DECODE_PRINTF("\n");
 
6606
        TRACE_AND_STEP();
 
6607
        *srcreg = (u16)destoffset;
 
6608
        break;
 
6609
    case 3:                     /* register to register */
 
6610
        /* undefined.  Do nothing. */
 
6611
        break;
 
6612
    }
 
6613
    DECODE_CLEAR_SEGOVR();
 
6614
    END_OF_INSTR();
 
6615
}
 
6616
 
 
6617
/****************************************************************************
 
6618
REMARKS:
 
6619
Handles opcode 0x8e
 
6620
****************************************************************************/
 
6621
static void x86emuOp_mov_word_SR_RM(u8 X86EMU_UNUSED(op1))
 
6622
{
 
6623
    int mod, rl, rh;
 
6624
    u16 *destreg, *srcreg;
 
6625
    uint srcoffset;
 
6626
    u16 srcval;
 
6627
 
 
6628
    START_OF_INSTR();
 
6629
    DECODE_PRINTF("MOV\t");
 
6630
    FETCH_DECODE_MODRM(mod, rh, rl);
 
6631
    switch (mod) {
 
6632
    case 0:
 
6633
        destreg = decode_rm_seg_register(rh);
 
6634
        DECODE_PRINTF(",");
 
6635
        srcoffset = decode_rm00_address(rl);
 
6636
        srcval = fetch_data_word(srcoffset);
 
6637
        DECODE_PRINTF("\n");
 
6638
        TRACE_AND_STEP();
 
6639
        *destreg = srcval;
 
6640
        break;
 
6641
    case 1:
 
6642
        destreg = decode_rm_seg_register(rh);
 
6643
        DECODE_PRINTF(",");
 
6644
        srcoffset = decode_rm01_address(rl);
 
6645
        srcval = fetch_data_word(srcoffset);
 
6646
        DECODE_PRINTF("\n");
 
6647
        TRACE_AND_STEP();
 
6648
        *destreg = srcval;
 
6649
        break;
 
6650
    case 2:
 
6651
        destreg = decode_rm_seg_register(rh);
 
6652
        DECODE_PRINTF(",");
 
6653
        srcoffset = decode_rm10_address(rl);
 
6654
        srcval = fetch_data_word(srcoffset);
 
6655
        DECODE_PRINTF("\n");
 
6656
        TRACE_AND_STEP();
 
6657
        *destreg = srcval;
 
6658
        break;
 
6659
    case 3:                     /* register to register */
 
6660
        destreg = decode_rm_seg_register(rh);
 
6661
        DECODE_PRINTF(",");
 
6662
        srcreg = DECODE_RM_WORD_REGISTER(rl);
 
6663
        DECODE_PRINTF("\n");
 
6664
        TRACE_AND_STEP();
 
6665
        *destreg = *srcreg;
 
6666
        break;
 
6667
    }
 
6668
    /*
 
6669
     * Clean up, and reset all the R_xSP pointers to the correct
 
6670
     * locations.  This is about 3x too much overhead (doing all the
 
6671
     * segreg ptrs when only one is needed, but this instruction
 
6672
     * *cannot* be that common, and this isn't too much work anyway.
 
6673
     */
 
6674
    DECODE_CLEAR_SEGOVR();
 
6675
    END_OF_INSTR();
 
6676
}
 
6677
 
 
6678
/****************************************************************************
 
6679
REMARKS:
 
6680
Handles opcode 0x8f
 
6681
****************************************************************************/
 
6682
static void x86emuOp_pop_RM(u8 X86EMU_UNUSED(op1))
 
6683
{
 
6684
    int mod, rl, rh;
 
6685
    uint destoffset;
 
6686
 
 
6687
    START_OF_INSTR();
 
6688
    DECODE_PRINTF("POP\t");
 
6689
    FETCH_DECODE_MODRM(mod, rh, rl);
 
6690
    if (rh != 0) {
 
6691
        DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n");
 
6692
        HALT_SYS();
 
6693
    }
 
6694
    switch (mod) {
 
6695
    case 0:
 
6696
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
6697
            u32 destval;
 
6698
 
 
6699
            destoffset = decode_rm00_address(rl);
 
6700
            DECODE_PRINTF("\n");
 
6701
            TRACE_AND_STEP();
 
6702
            destval = pop_long();
 
6703
            store_data_long(destoffset, destval);
 
6704
        } else {
 
6705
            u16 destval;
 
6706
 
 
6707
            destoffset = decode_rm00_address(rl);
 
6708
            DECODE_PRINTF("\n");
 
6709
            TRACE_AND_STEP();
 
6710
            destval = pop_word();
 
6711
            store_data_word(destoffset, destval);
 
6712
        }
 
6713
        break;
 
6714
    case 1:
 
6715
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
6716
            u32 destval;
 
6717
 
 
6718
            destoffset = decode_rm01_address(rl);
 
6719
            DECODE_PRINTF("\n");
 
6720
            TRACE_AND_STEP();
 
6721
            destval = pop_long();
 
6722
            store_data_long(destoffset, destval);
 
6723
        } else {
 
6724
            u16 destval;
 
6725
 
 
6726
            destoffset = decode_rm01_address(rl);
 
6727
            DECODE_PRINTF("\n");
 
6728
            TRACE_AND_STEP();
 
6729
            destval = pop_word();
 
6730
            store_data_word(destoffset, destval);
 
6731
        }
 
6732
        break;
 
6733
    case 2:
 
6734
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
6735
            u32 destval;
 
6736
 
 
6737
            destoffset = decode_rm10_address(rl);
 
6738
            DECODE_PRINTF("\n");
 
6739
            TRACE_AND_STEP();
 
6740
            destval = pop_long();
 
6741
            store_data_long(destoffset, destval);
 
6742
        } else {
 
6743
            u16 destval;
 
6744
 
 
6745
            destoffset = decode_rm10_address(rl);
 
6746
            DECODE_PRINTF("\n");
 
6747
            TRACE_AND_STEP();
 
6748
            destval = pop_word();
 
6749
            store_data_word(destoffset, destval);
 
6750
        }
 
6751
        break;
 
6752
    case 3:                     /* register to register */
 
6753
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
6754
            u32 *destreg;
 
6755
 
 
6756
            destreg = DECODE_RM_LONG_REGISTER(rl);
 
6757
            DECODE_PRINTF("\n");
 
6758
            TRACE_AND_STEP();
 
6759
            *destreg = pop_long();
 
6760
        } else {
 
6761
            u16 *destreg;
 
6762
 
 
6763
            destreg = DECODE_RM_WORD_REGISTER(rl);
 
6764
            DECODE_PRINTF("\n");
 
6765
            TRACE_AND_STEP();
 
6766
            *destreg = pop_word();
 
6767
        }
 
6768
        break;
 
6769
    }
 
6770
    DECODE_CLEAR_SEGOVR();
 
6771
    END_OF_INSTR();
 
6772
}
 
6773
 
 
6774
/****************************************************************************
 
6775
REMARKS:
 
6776
Handles opcode 0x90
 
6777
****************************************************************************/
 
6778
static void x86emuOp_nop(u8 X86EMU_UNUSED(op1))
 
6779
{
 
6780
    START_OF_INSTR();
 
6781
    DECODE_PRINTF("NOP\n");
 
6782
    TRACE_AND_STEP();
 
6783
    DECODE_CLEAR_SEGOVR();
 
6784
    END_OF_INSTR();
 
6785
}
 
6786
 
 
6787
/****************************************************************************
 
6788
REMARKS:
 
6789
Handles opcode 0x91
 
6790
****************************************************************************/
 
6791
static void x86emuOp_xchg_word_AX_CX(u8 X86EMU_UNUSED(op1))
 
6792
{
 
6793
    u32 tmp;
 
6794
 
 
6795
    START_OF_INSTR();
 
6796
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
6797
        DECODE_PRINTF("XCHG\tEAX,ECX\n");
 
6798
    } else {
 
6799
        DECODE_PRINTF("XCHG\tAX,CX\n");
 
6800
    }
 
6801
    TRACE_AND_STEP();
 
6802
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
6803
        tmp = M.x86.R_EAX;
 
6804
        M.x86.R_EAX = M.x86.R_ECX;
 
6805
        M.x86.R_ECX = tmp;
 
6806
    } else {
 
6807
        tmp = M.x86.R_AX;
 
6808
        M.x86.R_AX = M.x86.R_CX;
 
6809
        M.x86.R_CX = (u16)tmp;
 
6810
    }
 
6811
    DECODE_CLEAR_SEGOVR();
 
6812
    END_OF_INSTR();
 
6813
}
 
6814
 
 
6815
/****************************************************************************
 
6816
REMARKS:
 
6817
Handles opcode 0x92
 
6818
****************************************************************************/
 
6819
static void x86emuOp_xchg_word_AX_DX(u8 X86EMU_UNUSED(op1))
 
6820
{
 
6821
    u32 tmp;
 
6822
 
 
6823
    START_OF_INSTR();
 
6824
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
6825
        DECODE_PRINTF("XCHG\tEAX,EDX\n");
 
6826
    } else {
 
6827
        DECODE_PRINTF("XCHG\tAX,DX\n");
 
6828
    }
 
6829
    TRACE_AND_STEP();
 
6830
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
6831
        tmp = M.x86.R_EAX;
 
6832
        M.x86.R_EAX = M.x86.R_EDX;
 
6833
        M.x86.R_EDX = tmp;
 
6834
    } else {
 
6835
        tmp = M.x86.R_AX;
 
6836
        M.x86.R_AX = M.x86.R_DX;
 
6837
        M.x86.R_DX = (u16)tmp;
 
6838
    }
 
6839
    DECODE_CLEAR_SEGOVR();
 
6840
    END_OF_INSTR();
 
6841
}
 
6842
 
 
6843
/****************************************************************************
 
6844
REMARKS:
 
6845
Handles opcode 0x93
 
6846
****************************************************************************/
 
6847
static void x86emuOp_xchg_word_AX_BX(u8 X86EMU_UNUSED(op1))
 
6848
{
 
6849
    u32 tmp;
 
6850
 
 
6851
    START_OF_INSTR();
 
6852
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
6853
        DECODE_PRINTF("XCHG\tEAX,EBX\n");
 
6854
    } else {
 
6855
        DECODE_PRINTF("XCHG\tAX,BX\n");
 
6856
    }
 
6857
    TRACE_AND_STEP();
 
6858
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
6859
        tmp = M.x86.R_EAX;
 
6860
        M.x86.R_EAX = M.x86.R_EBX;
 
6861
        M.x86.R_EBX = tmp;
 
6862
    } else {
 
6863
        tmp = M.x86.R_AX;
 
6864
        M.x86.R_AX = M.x86.R_BX;
 
6865
        M.x86.R_BX = (u16)tmp;
 
6866
    }
 
6867
    DECODE_CLEAR_SEGOVR();
 
6868
    END_OF_INSTR();
 
6869
}
 
6870
 
 
6871
/****************************************************************************
 
6872
REMARKS:
 
6873
Handles opcode 0x94
 
6874
****************************************************************************/
 
6875
static void x86emuOp_xchg_word_AX_SP(u8 X86EMU_UNUSED(op1))
 
6876
{
 
6877
    u32 tmp;
 
6878
 
 
6879
    START_OF_INSTR();
 
6880
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
6881
        DECODE_PRINTF("XCHG\tEAX,ESP\n");
 
6882
    } else {
 
6883
        DECODE_PRINTF("XCHG\tAX,SP\n");
 
6884
    }
 
6885
    TRACE_AND_STEP();
 
6886
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
6887
        tmp = M.x86.R_EAX;
 
6888
        M.x86.R_EAX = M.x86.R_ESP;
 
6889
        M.x86.R_ESP = tmp;
 
6890
    } else {
 
6891
        tmp = M.x86.R_AX;
 
6892
        M.x86.R_AX = M.x86.R_SP;
 
6893
        M.x86.R_SP = (u16)tmp;
 
6894
    }
 
6895
    DECODE_CLEAR_SEGOVR();
 
6896
    END_OF_INSTR();
 
6897
}
 
6898
 
 
6899
/****************************************************************************
 
6900
REMARKS:
 
6901
Handles opcode 0x95
 
6902
****************************************************************************/
 
6903
static void x86emuOp_xchg_word_AX_BP(u8 X86EMU_UNUSED(op1))
 
6904
{
 
6905
    u32 tmp;
 
6906
 
 
6907
    START_OF_INSTR();
 
6908
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
6909
        DECODE_PRINTF("XCHG\tEAX,EBP\n");
 
6910
    } else {
 
6911
        DECODE_PRINTF("XCHG\tAX,BP\n");
 
6912
    }
 
6913
    TRACE_AND_STEP();
 
6914
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
6915
        tmp = M.x86.R_EAX;
 
6916
        M.x86.R_EAX = M.x86.R_EBP;
 
6917
        M.x86.R_EBP = tmp;
 
6918
    } else {
 
6919
        tmp = M.x86.R_AX;
 
6920
        M.x86.R_AX = M.x86.R_BP;
 
6921
        M.x86.R_BP = (u16)tmp;
 
6922
    }
 
6923
    DECODE_CLEAR_SEGOVR();
 
6924
    END_OF_INSTR();
 
6925
}
 
6926
 
 
6927
/****************************************************************************
 
6928
REMARKS:
 
6929
Handles opcode 0x96
 
6930
****************************************************************************/
 
6931
static void x86emuOp_xchg_word_AX_SI(u8 X86EMU_UNUSED(op1))
 
6932
{
 
6933
    u32 tmp;
 
6934
 
 
6935
    START_OF_INSTR();
 
6936
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
6937
        DECODE_PRINTF("XCHG\tEAX,ESI\n");
 
6938
    } else {
 
6939
        DECODE_PRINTF("XCHG\tAX,SI\n");
 
6940
    }
 
6941
    TRACE_AND_STEP();
 
6942
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
6943
        tmp = M.x86.R_EAX;
 
6944
        M.x86.R_EAX = M.x86.R_ESI;
 
6945
        M.x86.R_ESI = tmp;
 
6946
    } else {
 
6947
        tmp = M.x86.R_AX;
 
6948
        M.x86.R_AX = M.x86.R_SI;
 
6949
        M.x86.R_SI = (u16)tmp;
 
6950
    }
 
6951
    DECODE_CLEAR_SEGOVR();
 
6952
    END_OF_INSTR();
 
6953
}
 
6954
 
 
6955
/****************************************************************************
 
6956
REMARKS:
 
6957
Handles opcode 0x97
 
6958
****************************************************************************/
 
6959
static void x86emuOp_xchg_word_AX_DI(u8 X86EMU_UNUSED(op1))
 
6960
{
 
6961
    u32 tmp;
 
6962
 
 
6963
    START_OF_INSTR();
 
6964
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
6965
        DECODE_PRINTF("XCHG\tEAX,EDI\n");
 
6966
    } else {
 
6967
        DECODE_PRINTF("XCHG\tAX,DI\n");
 
6968
    }
 
6969
    TRACE_AND_STEP();
 
6970
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
6971
        tmp = M.x86.R_EAX;
 
6972
        M.x86.R_EAX = M.x86.R_EDI;
 
6973
        M.x86.R_EDI = tmp;
 
6974
    } else {
 
6975
        tmp = M.x86.R_AX;
 
6976
        M.x86.R_AX = M.x86.R_DI;
 
6977
        M.x86.R_DI = (u16)tmp;
 
6978
    }
 
6979
    DECODE_CLEAR_SEGOVR();
 
6980
    END_OF_INSTR();
 
6981
}
 
6982
 
 
6983
/****************************************************************************
 
6984
REMARKS:
 
6985
Handles opcode 0x98
 
6986
****************************************************************************/
 
6987
static void x86emuOp_cbw(u8 X86EMU_UNUSED(op1))
 
6988
{
 
6989
    START_OF_INSTR();
 
6990
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
6991
        DECODE_PRINTF("CWDE\n");
 
6992
    } else {
 
6993
        DECODE_PRINTF("CBW\n");
 
6994
    }
 
6995
    TRACE_AND_STEP();
 
6996
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
6997
        if (M.x86.R_AX & 0x8000) {
 
6998
            M.x86.R_EAX |= 0xffff0000;
 
6999
        } else {
 
7000
            M.x86.R_EAX &= 0x0000ffff;
 
7001
        }
 
7002
    } else {
 
7003
        if (M.x86.R_AL & 0x80) {
 
7004
            M.x86.R_AH = 0xff;
 
7005
        } else {
 
7006
            M.x86.R_AH = 0x0;
 
7007
        }
 
7008
    }
 
7009
    DECODE_CLEAR_SEGOVR();
 
7010
    END_OF_INSTR();
 
7011
}
 
7012
 
 
7013
/****************************************************************************
 
7014
REMARKS:
 
7015
Handles opcode 0x99
 
7016
****************************************************************************/
 
7017
static void x86emuOp_cwd(u8 X86EMU_UNUSED(op1))
 
7018
{
 
7019
    START_OF_INSTR();
 
7020
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
7021
        DECODE_PRINTF("CDQ\n");
 
7022
    } else {
 
7023
        DECODE_PRINTF("CWD\n");
 
7024
    }
 
7025
    DECODE_PRINTF("CWD\n");
 
7026
    TRACE_AND_STEP();
 
7027
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
7028
        if (M.x86.R_EAX & 0x80000000) {
 
7029
            M.x86.R_EDX = 0xffffffff;
 
7030
        } else {
 
7031
            M.x86.R_EDX = 0x0;
 
7032
        }
 
7033
    } else {
 
7034
        if (M.x86.R_AX & 0x8000) {
 
7035
            M.x86.R_DX = 0xffff;
 
7036
        } else {
 
7037
            M.x86.R_DX = 0x0;
 
7038
        }
 
7039
    }
 
7040
    DECODE_CLEAR_SEGOVR();
 
7041
    END_OF_INSTR();
 
7042
}
 
7043
 
 
7044
/****************************************************************************
 
7045
REMARKS:
 
7046
Handles opcode 0x9a
 
7047
****************************************************************************/
 
7048
static void x86emuOp_call_far_IMM(u8 X86EMU_UNUSED(op1))
 
7049
{
 
7050
    u16 farseg, faroff;
 
7051
 
 
7052
    START_OF_INSTR();
 
7053
        DECODE_PRINTF("CALL\t");
 
7054
        faroff = fetch_word_imm();
 
7055
        farseg = fetch_word_imm();
 
7056
        DECODE_PRINTF2("%04x:", farseg);
 
7057
        DECODE_PRINTF2("%04x\n", faroff);
 
7058
        CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, farseg, faroff, "FAR ");
 
7059
 
 
7060
    /* XXX
 
7061
     * 
 
7062
     * Hooked interrupt vectors calling into our "BIOS" will cause
 
7063
     * problems unless all intersegment stuff is checked for BIOS
 
7064
     * access.  Check needed here.  For moment, let it alone.
 
7065
     */
 
7066
    TRACE_AND_STEP();
 
7067
    push_word(M.x86.R_CS);
 
7068
    M.x86.R_CS = farseg;
 
7069
    push_word(M.x86.R_IP);
 
7070
    M.x86.R_IP = faroff;
 
7071
    DECODE_CLEAR_SEGOVR();
 
7072
    END_OF_INSTR();
 
7073
}
 
7074
 
 
7075
/****************************************************************************
 
7076
REMARKS:
 
7077
Handles opcode 0x9b
 
7078
****************************************************************************/
 
7079
static void x86emuOp_wait(u8 X86EMU_UNUSED(op1))
 
7080
{
 
7081
    START_OF_INSTR();
 
7082
    DECODE_PRINTF("WAIT");
 
7083
    TRACE_AND_STEP();
 
7084
    /* NADA.  */
 
7085
    DECODE_CLEAR_SEGOVR();
 
7086
    END_OF_INSTR();
 
7087
}
 
7088
 
 
7089
/****************************************************************************
 
7090
REMARKS:
 
7091
Handles opcode 0x9c
 
7092
****************************************************************************/
 
7093
static void x86emuOp_pushf_word(u8 X86EMU_UNUSED(op1))
 
7094
{
 
7095
    u32 flags;
 
7096
 
 
7097
    START_OF_INSTR();
 
7098
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
7099
        DECODE_PRINTF("PUSHFD\n");
 
7100
    } else {
 
7101
        DECODE_PRINTF("PUSHF\n");
 
7102
    }
 
7103
    TRACE_AND_STEP();
 
7104
 
 
7105
    /* clear out *all* bits not representing flags, and turn on real bits */
 
7106
    flags = (M.x86.R_EFLG & F_MSK) | F_ALWAYS_ON;
 
7107
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
7108
        push_long(flags);
 
7109
    } else {
 
7110
        push_word((u16)flags);
 
7111
    }
 
7112
    DECODE_CLEAR_SEGOVR();
 
7113
    END_OF_INSTR();
 
7114
}
 
7115
 
 
7116
/****************************************************************************
 
7117
REMARKS:
 
7118
Handles opcode 0x9d
 
7119
****************************************************************************/
 
7120
static void x86emuOp_popf_word(u8 X86EMU_UNUSED(op1))
 
7121
{
 
7122
    START_OF_INSTR();
 
7123
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
7124
        DECODE_PRINTF("POPFD\n");
 
7125
    } else {
 
7126
        DECODE_PRINTF("POPF\n");
 
7127
    }
 
7128
    TRACE_AND_STEP();
 
7129
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
7130
        M.x86.R_EFLG = pop_long();
 
7131
    } else {
 
7132
        M.x86.R_FLG = pop_word();
 
7133
    }
 
7134
    DECODE_CLEAR_SEGOVR();
 
7135
    END_OF_INSTR();
 
7136
}
 
7137
 
 
7138
/****************************************************************************
 
7139
REMARKS:
 
7140
Handles opcode 0x9e
 
7141
****************************************************************************/
 
7142
static void x86emuOp_sahf(u8 X86EMU_UNUSED(op1))
 
7143
{
 
7144
    START_OF_INSTR();
 
7145
    DECODE_PRINTF("SAHF\n");
 
7146
    TRACE_AND_STEP();
 
7147
    /* clear the lower bits of the flag register */
 
7148
    M.x86.R_FLG &= 0xffffff00;
 
7149
    /* or in the AH register into the flags register */
 
7150
    M.x86.R_FLG |= M.x86.R_AH;
 
7151
    DECODE_CLEAR_SEGOVR();
 
7152
    END_OF_INSTR();
 
7153
}
 
7154
 
 
7155
/****************************************************************************
 
7156
REMARKS:
 
7157
Handles opcode 0x9f
 
7158
****************************************************************************/
 
7159
static void x86emuOp_lahf(u8 X86EMU_UNUSED(op1))
 
7160
{
 
7161
    START_OF_INSTR();
 
7162
    DECODE_PRINTF("LAHF\n");
 
7163
    TRACE_AND_STEP();
 
7164
        M.x86.R_AH = (u8)(M.x86.R_FLG & 0xff);
 
7165
    /*undocumented TC++ behavior??? Nope.  It's documented, but
 
7166
       you have too look real hard to notice it. */
 
7167
    M.x86.R_AH |= 0x2;
 
7168
    DECODE_CLEAR_SEGOVR();
 
7169
    END_OF_INSTR();
 
7170
}
 
7171
 
 
7172
/****************************************************************************
 
7173
REMARKS:
 
7174
Handles opcode 0xa0
 
7175
****************************************************************************/
 
7176
static void x86emuOp_mov_AL_M_IMM(u8 X86EMU_UNUSED(op1))
 
7177
{
 
7178
    u16 offset;
 
7179
 
 
7180
    START_OF_INSTR();
 
7181
    DECODE_PRINTF("MOV\tAL,");
 
7182
    offset = fetch_word_imm();
 
7183
    DECODE_PRINTF2("[%04x]\n", offset);
 
7184
    TRACE_AND_STEP();
 
7185
    M.x86.R_AL = fetch_data_byte(offset);
 
7186
    DECODE_CLEAR_SEGOVR();
 
7187
    END_OF_INSTR();
 
7188
}
 
7189
 
 
7190
/****************************************************************************
 
7191
REMARKS:
 
7192
Handles opcode 0xa1
 
7193
****************************************************************************/
 
7194
static void x86emuOp_mov_AX_M_IMM(u8 X86EMU_UNUSED(op1))
 
7195
{
 
7196
    u16 offset;
 
7197
 
 
7198
    START_OF_INSTR();
 
7199
    offset = fetch_word_imm();
 
7200
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
7201
        DECODE_PRINTF2("MOV\tEAX,[%04x]\n", offset);
 
7202
    } else {
 
7203
        DECODE_PRINTF2("MOV\tAX,[%04x]\n", offset);
 
7204
    }
 
7205
    TRACE_AND_STEP();
 
7206
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
7207
        M.x86.R_EAX = fetch_data_long(offset);
 
7208
    } else {
 
7209
        M.x86.R_AX = fetch_data_word(offset);
 
7210
    }
 
7211
    DECODE_CLEAR_SEGOVR();
 
7212
    END_OF_INSTR();
 
7213
}
 
7214
 
 
7215
/****************************************************************************
 
7216
REMARKS:
 
7217
Handles opcode 0xa2
 
7218
****************************************************************************/
 
7219
static void x86emuOp_mov_M_AL_IMM(u8 X86EMU_UNUSED(op1))
 
7220
{
 
7221
    u16 offset;
 
7222
 
 
7223
    START_OF_INSTR();
 
7224
    DECODE_PRINTF("MOV\t");
 
7225
    offset = fetch_word_imm();
 
7226
    DECODE_PRINTF2("[%04x],AL\n", offset);
 
7227
    TRACE_AND_STEP();
 
7228
    store_data_byte(offset, M.x86.R_AL);
 
7229
    DECODE_CLEAR_SEGOVR();
 
7230
    END_OF_INSTR();
 
7231
}
 
7232
 
 
7233
/****************************************************************************
 
7234
REMARKS:
 
7235
Handles opcode 0xa3
 
7236
****************************************************************************/
 
7237
static void x86emuOp_mov_M_AX_IMM(u8 X86EMU_UNUSED(op1))
 
7238
{
 
7239
    u16 offset;
 
7240
 
 
7241
    START_OF_INSTR();
 
7242
    offset = fetch_word_imm();
 
7243
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
7244
        DECODE_PRINTF2("MOV\t[%04x],EAX\n", offset);
 
7245
    } else {
 
7246
        DECODE_PRINTF2("MOV\t[%04x],AX\n", offset);
 
7247
    }
 
7248
    TRACE_AND_STEP();
 
7249
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
7250
        store_data_long(offset, M.x86.R_EAX);
 
7251
    } else {
 
7252
        store_data_word(offset, M.x86.R_AX);
 
7253
    }
 
7254
    DECODE_CLEAR_SEGOVR();
 
7255
    END_OF_INSTR();
 
7256
}
 
7257
 
 
7258
/****************************************************************************
 
7259
REMARKS:
 
7260
Handles opcode 0xa4
 
7261
****************************************************************************/
 
7262
static void x86emuOp_movs_byte(u8 X86EMU_UNUSED(op1))
 
7263
{
 
7264
    u8  val;
 
7265
    u32 count;
 
7266
    int inc;
 
7267
 
 
7268
    START_OF_INSTR();
 
7269
    DECODE_PRINTF("MOVS\tBYTE\n");
 
7270
    if (ACCESS_FLAG(F_DF))   /* down */
 
7271
        inc = -1;
 
7272
    else
 
7273
        inc = 1;
 
7274
    TRACE_AND_STEP();
 
7275
    count = 1;
 
7276
    if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
 
7277
        /* dont care whether REPE or REPNE */
 
7278
        /* move them until CX is ZERO. */
 
7279
        count = M.x86.R_CX;
 
7280
        M.x86.R_CX = 0;
 
7281
        M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
 
7282
    }
 
7283
    while (count--) {
 
7284
        val = fetch_data_byte(M.x86.R_SI);
 
7285
        store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, val);
 
7286
        M.x86.R_SI += inc;
 
7287
        M.x86.R_DI += inc;
 
7288
    }
 
7289
    DECODE_CLEAR_SEGOVR();
 
7290
    END_OF_INSTR();
 
7291
}
 
7292
 
 
7293
/****************************************************************************
 
7294
REMARKS:
 
7295
Handles opcode 0xa5
 
7296
****************************************************************************/
 
7297
static void x86emuOp_movs_word(u8 X86EMU_UNUSED(op1))
 
7298
{
 
7299
    u32 val;
 
7300
    int inc;
 
7301
    u32 count;
 
7302
 
 
7303
    START_OF_INSTR();
 
7304
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
7305
        DECODE_PRINTF("MOVS\tDWORD\n");
 
7306
        if (ACCESS_FLAG(F_DF))      /* down */
 
7307
            inc = -4;
 
7308
        else
 
7309
            inc = 4;
 
7310
    } else {
 
7311
        DECODE_PRINTF("MOVS\tWORD\n");
 
7312
        if (ACCESS_FLAG(F_DF))      /* down */
 
7313
            inc = -2;
 
7314
        else
 
7315
            inc = 2;
 
7316
    }
 
7317
    TRACE_AND_STEP();
 
7318
    count = 1;
 
7319
    if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
 
7320
        /* dont care whether REPE or REPNE */
 
7321
        /* move them until CX is ZERO. */
 
7322
        count = M.x86.R_CX;
 
7323
        M.x86.R_CX = 0;
 
7324
        M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
 
7325
    }
 
7326
    while (count--) {
 
7327
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
7328
            val = fetch_data_long(M.x86.R_SI);
 
7329
            store_data_long_abs(M.x86.R_ES, M.x86.R_DI, val);
 
7330
        } else {
 
7331
            val = fetch_data_word(M.x86.R_SI);
 
7332
            store_data_word_abs(M.x86.R_ES, M.x86.R_DI, (u16)val);
 
7333
        }
 
7334
        M.x86.R_SI += inc;
 
7335
        M.x86.R_DI += inc;
 
7336
    }
 
7337
    DECODE_CLEAR_SEGOVR();
 
7338
    END_OF_INSTR();
 
7339
}
 
7340
 
 
7341
/****************************************************************************
 
7342
REMARKS:
 
7343
Handles opcode 0xa6
 
7344
****************************************************************************/
 
7345
static void x86emuOp_cmps_byte(u8 X86EMU_UNUSED(op1))
 
7346
{
 
7347
    s8 val1, val2;
 
7348
    int inc;
 
7349
 
 
7350
    START_OF_INSTR();
 
7351
    DECODE_PRINTF("CMPS\tBYTE\n");
 
7352
    TRACE_AND_STEP();
 
7353
    if (ACCESS_FLAG(F_DF))   /* down */
 
7354
        inc = -1;
 
7355
    else
 
7356
        inc = 1;
 
7357
 
 
7358
    if (M.x86.mode & SYSMODE_PREFIX_REPE) {
 
7359
        /* REPE  */
 
7360
        /* move them until CX is ZERO. */
 
7361
        while (M.x86.R_CX != 0) {
 
7362
            val1 = fetch_data_byte(M.x86.R_SI);
 
7363
            val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
 
7364
                     cmp_byte(val1, val2);
 
7365
            M.x86.R_CX -= 1;
 
7366
            M.x86.R_SI += inc;
 
7367
            M.x86.R_DI += inc;
 
7368
            if (ACCESS_FLAG(F_ZF) == 0)
 
7369
                break;
 
7370
        }
 
7371
        M.x86.mode &= ~SYSMODE_PREFIX_REPE;
 
7372
    } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
 
7373
        /* REPNE  */
 
7374
        /* move them until CX is ZERO. */
 
7375
        while (M.x86.R_CX != 0) {
 
7376
            val1 = fetch_data_byte(M.x86.R_SI);
 
7377
            val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
 
7378
            cmp_byte(val1, val2);
 
7379
            M.x86.R_CX -= 1;
 
7380
            M.x86.R_SI += inc;
 
7381
            M.x86.R_DI += inc;
 
7382
            if (ACCESS_FLAG(F_ZF))
 
7383
                break;          /* zero flag set means equal */
 
7384
        }
 
7385
        M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
 
7386
    } else {
 
7387
        val1 = fetch_data_byte(M.x86.R_SI);
 
7388
        val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
 
7389
        cmp_byte(val1, val2);
 
7390
        M.x86.R_SI += inc;
 
7391
        M.x86.R_DI += inc;
 
7392
    }
 
7393
    DECODE_CLEAR_SEGOVR();
 
7394
    END_OF_INSTR();
 
7395
}
 
7396
 
 
7397
/****************************************************************************
 
7398
REMARKS:
 
7399
Handles opcode 0xa7
 
7400
****************************************************************************/
 
7401
static void x86emuOp_cmps_word(u8 X86EMU_UNUSED(op1))
 
7402
{
 
7403
    u32 val1,val2;
 
7404
    int inc;
 
7405
 
 
7406
    START_OF_INSTR();
 
7407
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
7408
        DECODE_PRINTF("CMPS\tDWORD\n");
 
7409
        if (ACCESS_FLAG(F_DF))   /* down */
 
7410
            inc = -4;
 
7411
        else
 
7412
            inc = 4;
 
7413
    } else {
 
7414
        DECODE_PRINTF("CMPS\tWORD\n");
 
7415
        if (ACCESS_FLAG(F_DF))   /* down */
 
7416
            inc = -2;
 
7417
        else
 
7418
            inc = 2;
 
7419
    }
 
7420
    TRACE_AND_STEP();
 
7421
    if (M.x86.mode & SYSMODE_PREFIX_REPE) {
 
7422
        /* REPE  */
 
7423
        /* move them until CX is ZERO. */
 
7424
        while (M.x86.R_CX != 0) {
 
7425
            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
7426
                val1 = fetch_data_long(M.x86.R_SI);
 
7427
                val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
 
7428
                cmp_long(val1, val2);
 
7429
            } else {
 
7430
                val1 = fetch_data_word(M.x86.R_SI);
 
7431
                val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
 
7432
                cmp_word((u16)val1, (u16)val2);
 
7433
            }
 
7434
            M.x86.R_CX -= 1;
 
7435
            M.x86.R_SI += inc;
 
7436
            M.x86.R_DI += inc;
 
7437
            if (ACCESS_FLAG(F_ZF) == 0)
 
7438
                break;
 
7439
        }
 
7440
        M.x86.mode &= ~SYSMODE_PREFIX_REPE;
 
7441
    } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
 
7442
        /* REPNE  */
 
7443
        /* move them until CX is ZERO. */
 
7444
        while (M.x86.R_CX != 0) {
 
7445
            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
7446
                val1 = fetch_data_long(M.x86.R_SI);
 
7447
                val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
 
7448
                cmp_long(val1, val2);
 
7449
            } else {
 
7450
                val1 = fetch_data_word(M.x86.R_SI);
 
7451
                val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
 
7452
                cmp_word((u16)val1, (u16)val2);
 
7453
            }
 
7454
            M.x86.R_CX -= 1;
 
7455
            M.x86.R_SI += inc;
 
7456
            M.x86.R_DI += inc;
 
7457
            if (ACCESS_FLAG(F_ZF))
 
7458
                break;          /* zero flag set means equal */
 
7459
        }
 
7460
        M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
 
7461
    } else {
 
7462
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
7463
            val1 = fetch_data_long(M.x86.R_SI);
 
7464
            val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
 
7465
            cmp_long(val1, val2);
 
7466
        } else {
 
7467
            val1 = fetch_data_word(M.x86.R_SI);
 
7468
            val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
 
7469
            cmp_word((u16)val1, (u16)val2);
 
7470
        }
 
7471
        M.x86.R_SI += inc;
 
7472
        M.x86.R_DI += inc;
 
7473
    }
 
7474
    DECODE_CLEAR_SEGOVR();
 
7475
    END_OF_INSTR();
 
7476
}
 
7477
 
 
7478
/****************************************************************************
 
7479
REMARKS:
 
7480
Handles opcode 0xa8
 
7481
****************************************************************************/
 
7482
static void x86emuOp_test_AL_IMM(u8 X86EMU_UNUSED(op1))
 
7483
{
 
7484
    int imm;
 
7485
 
 
7486
    START_OF_INSTR();
 
7487
    DECODE_PRINTF("TEST\tAL,");
 
7488
    imm = fetch_byte_imm();
 
7489
    DECODE_PRINTF2("%04x\n", imm);
 
7490
    TRACE_AND_STEP();
 
7491
        test_byte(M.x86.R_AL, (u8)imm);
 
7492
    DECODE_CLEAR_SEGOVR();
 
7493
    END_OF_INSTR();
 
7494
}
 
7495
 
 
7496
/****************************************************************************
 
7497
REMARKS:
 
7498
Handles opcode 0xa9
 
7499
****************************************************************************/
 
7500
static void x86emuOp_test_AX_IMM(u8 X86EMU_UNUSED(op1))
 
7501
{
 
7502
    u32 srcval;
 
7503
 
 
7504
    START_OF_INSTR();
 
7505
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
7506
        DECODE_PRINTF("TEST\tEAX,");
 
7507
        srcval = fetch_long_imm();
 
7508
    } else {
 
7509
        DECODE_PRINTF("TEST\tAX,");
 
7510
        srcval = fetch_word_imm();
 
7511
    }
 
7512
    DECODE_PRINTF2("%x\n", srcval);
 
7513
    TRACE_AND_STEP();
 
7514
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
7515
        test_long(M.x86.R_EAX, srcval);
 
7516
    } else {
 
7517
        test_word(M.x86.R_AX, (u16)srcval);
 
7518
    }
 
7519
    DECODE_CLEAR_SEGOVR();
 
7520
    END_OF_INSTR();
 
7521
}
 
7522
 
 
7523
/****************************************************************************
 
7524
REMARKS:
 
7525
Handles opcode 0xaa
 
7526
****************************************************************************/
 
7527
static void x86emuOp_stos_byte(u8 X86EMU_UNUSED(op1))
 
7528
{
 
7529
    int inc;
 
7530
 
 
7531
    START_OF_INSTR();
 
7532
    DECODE_PRINTF("STOS\tBYTE\n");
 
7533
    if (ACCESS_FLAG(F_DF))   /* down */
 
7534
        inc = -1;
 
7535
    else
 
7536
        inc = 1;
 
7537
    TRACE_AND_STEP();
 
7538
    if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
 
7539
        /* dont care whether REPE or REPNE */
 
7540
        /* move them until CX is ZERO. */
 
7541
        while (M.x86.R_CX != 0) {
 
7542
            store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL);
 
7543
            M.x86.R_CX -= 1;
 
7544
            M.x86.R_DI += inc;
 
7545
        }
 
7546
        M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
 
7547
    } else {
 
7548
        store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL);
 
7549
        M.x86.R_DI += inc;
 
7550
    }
 
7551
    DECODE_CLEAR_SEGOVR();
 
7552
    END_OF_INSTR();
 
7553
}
 
7554
 
 
7555
/****************************************************************************
 
7556
REMARKS:
 
7557
Handles opcode 0xab
 
7558
****************************************************************************/
 
7559
static void x86emuOp_stos_word(u8 X86EMU_UNUSED(op1))
 
7560
{
 
7561
    int inc;
 
7562
    u32 count;
 
7563
 
 
7564
    START_OF_INSTR();
 
7565
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
7566
        DECODE_PRINTF("STOS\tDWORD\n");
 
7567
        if (ACCESS_FLAG(F_DF))   /* down */
 
7568
            inc = -4;
 
7569
        else
 
7570
            inc = 4;
 
7571
    } else {
 
7572
        DECODE_PRINTF("STOS\tWORD\n");
 
7573
        if (ACCESS_FLAG(F_DF))   /* down */
 
7574
            inc = -2;
 
7575
        else
 
7576
            inc = 2;
 
7577
    }
 
7578
    TRACE_AND_STEP();
 
7579
    count = 1;
 
7580
    if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
 
7581
        /* dont care whether REPE or REPNE */
 
7582
        /* move them until CX is ZERO. */
 
7583
        count = M.x86.R_CX;
 
7584
        M.x86.R_CX = 0;
 
7585
        M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
 
7586
    }
 
7587
    while (count--) {
 
7588
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
7589
            store_data_long_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_EAX);
 
7590
        } else {
 
7591
            store_data_word_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AX);
 
7592
        }
 
7593
        M.x86.R_DI += inc;
 
7594
    }
 
7595
    DECODE_CLEAR_SEGOVR();
 
7596
    END_OF_INSTR();
 
7597
}
 
7598
 
 
7599
/****************************************************************************
 
7600
REMARKS:
 
7601
Handles opcode 0xac
 
7602
****************************************************************************/
 
7603
static void x86emuOp_lods_byte(u8 X86EMU_UNUSED(op1))
 
7604
{
 
7605
    int inc;
 
7606
 
 
7607
    START_OF_INSTR();
 
7608
    DECODE_PRINTF("LODS\tBYTE\n");
 
7609
    TRACE_AND_STEP();
 
7610
    if (ACCESS_FLAG(F_DF))   /* down */
 
7611
        inc = -1;
 
7612
    else
 
7613
        inc = 1;
 
7614
    if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
 
7615
        /* dont care whether REPE or REPNE */
 
7616
        /* move them until CX is ZERO. */
 
7617
        while (M.x86.R_CX != 0) {
 
7618
            M.x86.R_AL = fetch_data_byte(M.x86.R_SI);
 
7619
            M.x86.R_CX -= 1;
 
7620
            M.x86.R_SI += inc;
 
7621
        }
 
7622
        M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
 
7623
    } else {
 
7624
        M.x86.R_AL = fetch_data_byte(M.x86.R_SI);
 
7625
        M.x86.R_SI += inc;
 
7626
    }
 
7627
    DECODE_CLEAR_SEGOVR();
 
7628
    END_OF_INSTR();
 
7629
}
 
7630
 
 
7631
/****************************************************************************
 
7632
REMARKS:
 
7633
Handles opcode 0xad
 
7634
****************************************************************************/
 
7635
static void x86emuOp_lods_word(u8 X86EMU_UNUSED(op1))
 
7636
{
 
7637
    int inc;
 
7638
    u32 count;
 
7639
 
 
7640
    START_OF_INSTR();
 
7641
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
7642
        DECODE_PRINTF("LODS\tDWORD\n");
 
7643
        if (ACCESS_FLAG(F_DF))   /* down */
 
7644
            inc = -4;
 
7645
        else
 
7646
            inc = 4;
 
7647
    } else {
 
7648
        DECODE_PRINTF("LODS\tWORD\n");
 
7649
        if (ACCESS_FLAG(F_DF))   /* down */
 
7650
            inc = -2;
 
7651
        else
 
7652
            inc = 2;
 
7653
    }
 
7654
    TRACE_AND_STEP();
 
7655
    count = 1;
 
7656
    if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
 
7657
        /* dont care whether REPE or REPNE */
 
7658
        /* move them until CX is ZERO. */
 
7659
        count = M.x86.R_CX;
 
7660
        M.x86.R_CX = 0;
 
7661
        M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
 
7662
    }
 
7663
    while (count--) {
 
7664
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
7665
            M.x86.R_EAX = fetch_data_long(M.x86.R_SI);
 
7666
        } else {
 
7667
            M.x86.R_AX = fetch_data_word(M.x86.R_SI);
 
7668
        }
 
7669
        M.x86.R_SI += inc;
 
7670
    }
 
7671
    DECODE_CLEAR_SEGOVR();
 
7672
    END_OF_INSTR();
 
7673
}
 
7674
 
 
7675
/****************************************************************************
 
7676
REMARKS:
 
7677
Handles opcode 0xae
 
7678
****************************************************************************/
 
7679
static void x86emuOp_scas_byte(u8 X86EMU_UNUSED(op1))
 
7680
{
 
7681
    s8 val2;
 
7682
    int inc;
 
7683
 
 
7684
    START_OF_INSTR();
 
7685
    DECODE_PRINTF("SCAS\tBYTE\n");
 
7686
    TRACE_AND_STEP();
 
7687
    if (ACCESS_FLAG(F_DF))   /* down */
 
7688
        inc = -1;
 
7689
    else
 
7690
        inc = 1;
 
7691
    if (M.x86.mode & SYSMODE_PREFIX_REPE) {
 
7692
        /* REPE  */
 
7693
        /* move them until CX is ZERO. */
 
7694
        while (M.x86.R_CX != 0) {
 
7695
            val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
 
7696
            cmp_byte(M.x86.R_AL, val2);
 
7697
            M.x86.R_CX -= 1;
 
7698
            M.x86.R_DI += inc;
 
7699
            if (ACCESS_FLAG(F_ZF) == 0)
 
7700
                break;
 
7701
        }
 
7702
        M.x86.mode &= ~SYSMODE_PREFIX_REPE;
 
7703
    } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
 
7704
        /* REPNE  */
 
7705
        /* move them until CX is ZERO. */
 
7706
        while (M.x86.R_CX != 0) {
 
7707
            val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
 
7708
            cmp_byte(M.x86.R_AL, val2);
 
7709
            M.x86.R_CX -= 1;
 
7710
            M.x86.R_DI += inc;
 
7711
            if (ACCESS_FLAG(F_ZF))
 
7712
                break;          /* zero flag set means equal */
 
7713
        }
 
7714
        M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
 
7715
    } else {
 
7716
        val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
 
7717
        cmp_byte(M.x86.R_AL, val2);
 
7718
        M.x86.R_DI += inc;
 
7719
    }
 
7720
    DECODE_CLEAR_SEGOVR();
 
7721
    END_OF_INSTR();
 
7722
}
 
7723
 
 
7724
/****************************************************************************
 
7725
REMARKS:
 
7726
Handles opcode 0xaf
 
7727
****************************************************************************/
 
7728
static void x86emuOp_scas_word(u8 X86EMU_UNUSED(op1))
 
7729
{
 
7730
    int inc;
 
7731
    u32 val;
 
7732
 
 
7733
    START_OF_INSTR();
 
7734
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
7735
        DECODE_PRINTF("SCAS\tDWORD\n");
 
7736
        if (ACCESS_FLAG(F_DF))   /* down */
 
7737
            inc = -4;
 
7738
        else
 
7739
            inc = 4;
 
7740
    } else {
 
7741
        DECODE_PRINTF("SCAS\tWORD\n");
 
7742
        if (ACCESS_FLAG(F_DF))   /* down */
 
7743
            inc = -2;
 
7744
        else
 
7745
            inc = 2;
 
7746
    }
 
7747
    TRACE_AND_STEP();
 
7748
    if (M.x86.mode & SYSMODE_PREFIX_REPE) {
 
7749
        /* REPE  */
 
7750
        /* move them until CX is ZERO. */
 
7751
        while (M.x86.R_CX != 0) {
 
7752
            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
7753
                val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
 
7754
                cmp_long(M.x86.R_EAX, val);
 
7755
            } else {
 
7756
                val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
 
7757
                cmp_word(M.x86.R_AX, (u16)val);
 
7758
            }
 
7759
            M.x86.R_CX -= 1;
 
7760
            M.x86.R_DI += inc;
 
7761
            if (ACCESS_FLAG(F_ZF) == 0)
 
7762
                break;
 
7763
        }
 
7764
        M.x86.mode &= ~SYSMODE_PREFIX_REPE;
 
7765
    } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
 
7766
        /* REPNE  */
 
7767
        /* move them until CX is ZERO. */
 
7768
        while (M.x86.R_CX != 0) {
 
7769
            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
7770
                val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
 
7771
                cmp_long(M.x86.R_EAX, val);
 
7772
            } else {
 
7773
                val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
 
7774
                cmp_word(M.x86.R_AX, (u16)val);
 
7775
            }
 
7776
            M.x86.R_CX -= 1;
 
7777
            M.x86.R_DI += inc;
 
7778
            if (ACCESS_FLAG(F_ZF))
 
7779
                break;          /* zero flag set means equal */
 
7780
        }
 
7781
        M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
 
7782
    } else {
 
7783
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
7784
            val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
 
7785
            cmp_long(M.x86.R_EAX, val);
 
7786
        } else {
 
7787
            val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
 
7788
            cmp_word(M.x86.R_AX, (u16)val);
 
7789
        }
 
7790
        M.x86.R_DI += inc;
 
7791
    }
 
7792
    DECODE_CLEAR_SEGOVR();
 
7793
    END_OF_INSTR();
 
7794
}
 
7795
 
 
7796
/****************************************************************************
 
7797
REMARKS:
 
7798
Handles opcode 0xb0
 
7799
****************************************************************************/
 
7800
static void x86emuOp_mov_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
 
7801
{
 
7802
    u8 imm;
 
7803
 
 
7804
    START_OF_INSTR();
 
7805
    DECODE_PRINTF("MOV\tAL,");
 
7806
    imm = fetch_byte_imm();
 
7807
    DECODE_PRINTF2("%x\n", imm);
 
7808
    TRACE_AND_STEP();
 
7809
    M.x86.R_AL = imm;
 
7810
    DECODE_CLEAR_SEGOVR();
 
7811
    END_OF_INSTR();
 
7812
}
 
7813
 
 
7814
/****************************************************************************
 
7815
REMARKS:
 
7816
Handles opcode 0xb1
 
7817
****************************************************************************/
 
7818
static void x86emuOp_mov_byte_CL_IMM(u8 X86EMU_UNUSED(op1))
 
7819
{
 
7820
    u8 imm;
 
7821
 
 
7822
    START_OF_INSTR();
 
7823
    DECODE_PRINTF("MOV\tCL,");
 
7824
    imm = fetch_byte_imm();
 
7825
    DECODE_PRINTF2("%x\n", imm);
 
7826
    TRACE_AND_STEP();
 
7827
    M.x86.R_CL = imm;
 
7828
    DECODE_CLEAR_SEGOVR();
 
7829
    END_OF_INSTR();
 
7830
}
 
7831
 
 
7832
/****************************************************************************
 
7833
REMARKS:
 
7834
Handles opcode 0xb2
 
7835
****************************************************************************/
 
7836
static void x86emuOp_mov_byte_DL_IMM(u8 X86EMU_UNUSED(op1))
 
7837
{
 
7838
    u8 imm;
 
7839
 
 
7840
    START_OF_INSTR();
 
7841
    DECODE_PRINTF("MOV\tDL,");
 
7842
    imm = fetch_byte_imm();
 
7843
    DECODE_PRINTF2("%x\n", imm);
 
7844
    TRACE_AND_STEP();
 
7845
    M.x86.R_DL = imm;
 
7846
    DECODE_CLEAR_SEGOVR();
 
7847
    END_OF_INSTR();
 
7848
}
 
7849
 
 
7850
/****************************************************************************
 
7851
REMARKS:
 
7852
Handles opcode 0xb3
 
7853
****************************************************************************/
 
7854
static void x86emuOp_mov_byte_BL_IMM(u8 X86EMU_UNUSED(op1))
 
7855
{
 
7856
    u8 imm;
 
7857
 
 
7858
    START_OF_INSTR();
 
7859
    DECODE_PRINTF("MOV\tBL,");
 
7860
    imm = fetch_byte_imm();
 
7861
    DECODE_PRINTF2("%x\n", imm);
 
7862
    TRACE_AND_STEP();
 
7863
    M.x86.R_BL = imm;
 
7864
    DECODE_CLEAR_SEGOVR();
 
7865
    END_OF_INSTR();
 
7866
}
 
7867
 
 
7868
/****************************************************************************
 
7869
REMARKS:
 
7870
Handles opcode 0xb4
 
7871
****************************************************************************/
 
7872
static void x86emuOp_mov_byte_AH_IMM(u8 X86EMU_UNUSED(op1))
 
7873
{
 
7874
    u8 imm;
 
7875
 
 
7876
    START_OF_INSTR();
 
7877
    DECODE_PRINTF("MOV\tAH,");
 
7878
    imm = fetch_byte_imm();
 
7879
    DECODE_PRINTF2("%x\n", imm);
 
7880
    TRACE_AND_STEP();
 
7881
    M.x86.R_AH = imm;
 
7882
    DECODE_CLEAR_SEGOVR();
 
7883
    END_OF_INSTR();
 
7884
}
 
7885
 
 
7886
/****************************************************************************
 
7887
REMARKS:
 
7888
Handles opcode 0xb5
 
7889
****************************************************************************/
 
7890
static void x86emuOp_mov_byte_CH_IMM(u8 X86EMU_UNUSED(op1))
 
7891
{
 
7892
    u8 imm;
 
7893
 
 
7894
    START_OF_INSTR();
 
7895
    DECODE_PRINTF("MOV\tCH,");
 
7896
    imm = fetch_byte_imm();
 
7897
    DECODE_PRINTF2("%x\n", imm);
 
7898
    TRACE_AND_STEP();
 
7899
    M.x86.R_CH = imm;
 
7900
    DECODE_CLEAR_SEGOVR();
 
7901
    END_OF_INSTR();
 
7902
}
 
7903
 
 
7904
/****************************************************************************
 
7905
REMARKS:
 
7906
Handles opcode 0xb6
 
7907
****************************************************************************/
 
7908
static void x86emuOp_mov_byte_DH_IMM(u8 X86EMU_UNUSED(op1))
 
7909
{
 
7910
    u8 imm;
 
7911
 
 
7912
    START_OF_INSTR();
 
7913
    DECODE_PRINTF("MOV\tDH,");
 
7914
    imm = fetch_byte_imm();
 
7915
    DECODE_PRINTF2("%x\n", imm);
 
7916
    TRACE_AND_STEP();
 
7917
    M.x86.R_DH = imm;
 
7918
    DECODE_CLEAR_SEGOVR();
 
7919
    END_OF_INSTR();
 
7920
}
 
7921
 
 
7922
/****************************************************************************
 
7923
REMARKS:
 
7924
Handles opcode 0xb7
 
7925
****************************************************************************/
 
7926
static void x86emuOp_mov_byte_BH_IMM(u8 X86EMU_UNUSED(op1))
 
7927
{
 
7928
    u8 imm;
 
7929
 
 
7930
    START_OF_INSTR();
 
7931
    DECODE_PRINTF("MOV\tBH,");
 
7932
    imm = fetch_byte_imm();
 
7933
    DECODE_PRINTF2("%x\n", imm);
 
7934
    TRACE_AND_STEP();
 
7935
    M.x86.R_BH = imm;
 
7936
    DECODE_CLEAR_SEGOVR();
 
7937
    END_OF_INSTR();
 
7938
}
 
7939
 
 
7940
/****************************************************************************
 
7941
REMARKS:
 
7942
Handles opcode 0xb8
 
7943
****************************************************************************/
 
7944
static void x86emuOp_mov_word_AX_IMM(u8 X86EMU_UNUSED(op1))
 
7945
{
 
7946
    u32 srcval;
 
7947
 
 
7948
    START_OF_INSTR();
 
7949
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
7950
        DECODE_PRINTF("MOV\tEAX,");
 
7951
        srcval = fetch_long_imm();
 
7952
    } else {
 
7953
        DECODE_PRINTF("MOV\tAX,");
 
7954
        srcval = fetch_word_imm();
 
7955
    }
 
7956
    DECODE_PRINTF2("%x\n", srcval);
 
7957
    TRACE_AND_STEP();
 
7958
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
7959
        M.x86.R_EAX = srcval;
 
7960
    } else {
 
7961
        M.x86.R_AX = (u16)srcval;
 
7962
    }
 
7963
    DECODE_CLEAR_SEGOVR();
 
7964
    END_OF_INSTR();
 
7965
}
 
7966
 
 
7967
/****************************************************************************
 
7968
REMARKS:
 
7969
Handles opcode 0xb9
 
7970
****************************************************************************/
 
7971
static void x86emuOp_mov_word_CX_IMM(u8 X86EMU_UNUSED(op1))
 
7972
{
 
7973
    u32 srcval;
 
7974
 
 
7975
    START_OF_INSTR();
 
7976
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
7977
        DECODE_PRINTF("MOV\tECX,");
 
7978
        srcval = fetch_long_imm();
 
7979
    } else {
 
7980
        DECODE_PRINTF("MOV\tCX,");
 
7981
        srcval = fetch_word_imm();
 
7982
    }
 
7983
    DECODE_PRINTF2("%x\n", srcval);
 
7984
    TRACE_AND_STEP();
 
7985
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
7986
        M.x86.R_ECX = srcval;
 
7987
    } else {
 
7988
        M.x86.R_CX = (u16)srcval;
 
7989
    }
 
7990
    DECODE_CLEAR_SEGOVR();
 
7991
    END_OF_INSTR();
 
7992
}
 
7993
 
 
7994
/****************************************************************************
 
7995
REMARKS:
 
7996
Handles opcode 0xba
 
7997
****************************************************************************/
 
7998
static void x86emuOp_mov_word_DX_IMM(u8 X86EMU_UNUSED(op1))
 
7999
{
 
8000
    u32 srcval;
 
8001
 
 
8002
    START_OF_INSTR();
 
8003
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
8004
        DECODE_PRINTF("MOV\tEDX,");
 
8005
        srcval = fetch_long_imm();
 
8006
    } else {
 
8007
        DECODE_PRINTF("MOV\tDX,");
 
8008
        srcval = fetch_word_imm();
 
8009
    }
 
8010
    DECODE_PRINTF2("%x\n", srcval);
 
8011
    TRACE_AND_STEP();
 
8012
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
8013
        M.x86.R_EDX = srcval;
 
8014
    } else {
 
8015
        M.x86.R_DX = (u16)srcval;
 
8016
    }
 
8017
    DECODE_CLEAR_SEGOVR();
 
8018
    END_OF_INSTR();
 
8019
}
 
8020
 
 
8021
/****************************************************************************
 
8022
REMARKS:
 
8023
Handles opcode 0xbb
 
8024
****************************************************************************/
 
8025
static void x86emuOp_mov_word_BX_IMM(u8 X86EMU_UNUSED(op1))
 
8026
{
 
8027
    u32 srcval;
 
8028
 
 
8029
    START_OF_INSTR();
 
8030
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
8031
        DECODE_PRINTF("MOV\tEBX,");
 
8032
        srcval = fetch_long_imm();
 
8033
    } else {
 
8034
        DECODE_PRINTF("MOV\tBX,");
 
8035
        srcval = fetch_word_imm();
 
8036
    }
 
8037
    DECODE_PRINTF2("%x\n", srcval);
 
8038
    TRACE_AND_STEP();
 
8039
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
8040
        M.x86.R_EBX = srcval;
 
8041
    } else {
 
8042
        M.x86.R_BX = (u16)srcval;
 
8043
    }
 
8044
    DECODE_CLEAR_SEGOVR();
 
8045
    END_OF_INSTR();
 
8046
}
 
8047
 
 
8048
/****************************************************************************
 
8049
REMARKS:
 
8050
Handles opcode 0xbc
 
8051
****************************************************************************/
 
8052
static void x86emuOp_mov_word_SP_IMM(u8 X86EMU_UNUSED(op1))
 
8053
{
 
8054
    u32 srcval;
 
8055
 
 
8056
    START_OF_INSTR();
 
8057
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
8058
        DECODE_PRINTF("MOV\tESP,");
 
8059
        srcval = fetch_long_imm();
 
8060
    } else {
 
8061
        DECODE_PRINTF("MOV\tSP,");
 
8062
        srcval = fetch_word_imm();
 
8063
    }
 
8064
    DECODE_PRINTF2("%x\n", srcval);
 
8065
    TRACE_AND_STEP();
 
8066
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
8067
        M.x86.R_ESP = srcval;
 
8068
    } else {
 
8069
        M.x86.R_SP = (u16)srcval;
 
8070
    }
 
8071
    DECODE_CLEAR_SEGOVR();
 
8072
    END_OF_INSTR();
 
8073
}
 
8074
 
 
8075
/****************************************************************************
 
8076
REMARKS:
 
8077
Handles opcode 0xbd
 
8078
****************************************************************************/
 
8079
static void x86emuOp_mov_word_BP_IMM(u8 X86EMU_UNUSED(op1))
 
8080
{
 
8081
    u32 srcval;
 
8082
 
 
8083
    START_OF_INSTR();
 
8084
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
8085
        DECODE_PRINTF("MOV\tEBP,");
 
8086
        srcval = fetch_long_imm();
 
8087
    } else {
 
8088
        DECODE_PRINTF("MOV\tBP,");
 
8089
        srcval = fetch_word_imm();
 
8090
    }
 
8091
    DECODE_PRINTF2("%x\n", srcval);
 
8092
    TRACE_AND_STEP();
 
8093
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
8094
        M.x86.R_EBP = srcval;
 
8095
    } else {
 
8096
        M.x86.R_BP = (u16)srcval;
 
8097
    }
 
8098
    DECODE_CLEAR_SEGOVR();
 
8099
    END_OF_INSTR();
 
8100
}
 
8101
 
 
8102
/****************************************************************************
 
8103
REMARKS:
 
8104
Handles opcode 0xbe
 
8105
****************************************************************************/
 
8106
static void x86emuOp_mov_word_SI_IMM(u8 X86EMU_UNUSED(op1))
 
8107
{
 
8108
    u32 srcval;
 
8109
 
 
8110
    START_OF_INSTR();
 
8111
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
8112
        DECODE_PRINTF("MOV\tESI,");
 
8113
        srcval = fetch_long_imm();
 
8114
    } else {
 
8115
        DECODE_PRINTF("MOV\tSI,");
 
8116
        srcval = fetch_word_imm();
 
8117
    }
 
8118
    DECODE_PRINTF2("%x\n", srcval);
 
8119
    TRACE_AND_STEP();
 
8120
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
8121
        M.x86.R_ESI = srcval;
 
8122
    } else {
 
8123
        M.x86.R_SI = (u16)srcval;
 
8124
    }
 
8125
    DECODE_CLEAR_SEGOVR();
 
8126
    END_OF_INSTR();
 
8127
}
 
8128
 
 
8129
/****************************************************************************
 
8130
REMARKS:
 
8131
Handles opcode 0xbf
 
8132
****************************************************************************/
 
8133
static void x86emuOp_mov_word_DI_IMM(u8 X86EMU_UNUSED(op1))
 
8134
{
 
8135
    u32 srcval;
 
8136
 
 
8137
    START_OF_INSTR();
 
8138
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
8139
        DECODE_PRINTF("MOV\tEDI,");
 
8140
        srcval = fetch_long_imm();
 
8141
    } else {
 
8142
        DECODE_PRINTF("MOV\tDI,");
 
8143
        srcval = fetch_word_imm();
 
8144
    }
 
8145
    DECODE_PRINTF2("%x\n", srcval);
 
8146
    TRACE_AND_STEP();
 
8147
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
8148
        M.x86.R_EDI = srcval;
 
8149
    } else {
 
8150
        M.x86.R_DI = (u16)srcval;
 
8151
    }
 
8152
    DECODE_CLEAR_SEGOVR();
 
8153
    END_OF_INSTR();
 
8154
}
 
8155
 
 
8156
/* used by opcodes c0, d0, and d2. */
 
8157
static u8(*opcD0_byte_operation[])(u8 d, u8 s) =
 
8158
{
 
8159
    rol_byte,
 
8160
    ror_byte,
 
8161
    rcl_byte,
 
8162
    rcr_byte,
 
8163
    shl_byte,
 
8164
    shr_byte,
 
8165
    shl_byte,           /* sal_byte === shl_byte  by definition */
 
8166
    sar_byte,
 
8167
};
 
8168
 
 
8169
/****************************************************************************
 
8170
REMARKS:
 
8171
Handles opcode 0xc0
 
8172
****************************************************************************/
 
8173
static void x86emuOp_opcC0_byte_RM_MEM(u8 X86EMU_UNUSED(op1))
 
8174
{
 
8175
    int mod, rl, rh;
 
8176
    u8 *destreg;
 
8177
    uint destoffset;
 
8178
    u8 destval;
 
8179
    u8 amt;
 
8180
 
 
8181
    /*
 
8182
     * Yet another weirdo special case instruction format.  Part of
 
8183
     * the opcode held below in "RH".  Doubly nested case would
 
8184
     * result, except that the decoded instruction
 
8185
     */
 
8186
    START_OF_INSTR();
 
8187
    FETCH_DECODE_MODRM(mod, rh, rl);
 
8188
#ifdef DEBUG
 
8189
    if (DEBUG_DECODE()) {
 
8190
        /* XXX DECODE_PRINTF may be changed to something more
 
8191
           general, so that it is important to leave the strings
 
8192
           in the same format, even though the result is that the 
 
8193
           above test is done twice. */
 
8194
 
 
8195
        switch (rh) {
 
8196
        case 0:
 
8197
            DECODE_PRINTF("ROL\t");
 
8198
            break;
 
8199
        case 1:
 
8200
            DECODE_PRINTF("ROR\t");
 
8201
            break;
 
8202
        case 2:
 
8203
            DECODE_PRINTF("RCL\t");
 
8204
            break;
 
8205
        case 3:
 
8206
            DECODE_PRINTF("RCR\t");
 
8207
            break;
 
8208
        case 4:
 
8209
            DECODE_PRINTF("SHL\t");
 
8210
            break;
 
8211
        case 5:
 
8212
            DECODE_PRINTF("SHR\t");
 
8213
            break;
 
8214
        case 6:
 
8215
            DECODE_PRINTF("SAL\t");
 
8216
            break;
 
8217
        case 7:
 
8218
            DECODE_PRINTF("SAR\t");
 
8219
            break;
 
8220
        }
 
8221
    }
 
8222
#endif
 
8223
    /* know operation, decode the mod byte to find the addressing
 
8224
       mode. */
 
8225
    switch (mod) {
 
8226
    case 0:
 
8227
        DECODE_PRINTF("BYTE PTR ");
 
8228
        destoffset = decode_rm00_address(rl);
 
8229
        amt = fetch_byte_imm();
 
8230
        DECODE_PRINTF2(",%x\n", amt);
 
8231
        destval = fetch_data_byte(destoffset);
 
8232
        TRACE_AND_STEP();
 
8233
        destval = (*opcD0_byte_operation[rh]) (destval, amt);
 
8234
        store_data_byte(destoffset, destval);
 
8235
        break;
 
8236
    case 1:
 
8237
        DECODE_PRINTF("BYTE PTR ");
 
8238
        destoffset = decode_rm01_address(rl);
 
8239
        amt = fetch_byte_imm();
 
8240
        DECODE_PRINTF2(",%x\n", amt);
 
8241
        destval = fetch_data_byte(destoffset);
 
8242
        TRACE_AND_STEP();
 
8243
        destval = (*opcD0_byte_operation[rh]) (destval, amt);
 
8244
        store_data_byte(destoffset, destval);
 
8245
        break;
 
8246
    case 2:
 
8247
        DECODE_PRINTF("BYTE PTR ");
 
8248
        destoffset = decode_rm10_address(rl);
 
8249
        amt = fetch_byte_imm();
 
8250
        DECODE_PRINTF2(",%x\n", amt);
 
8251
        destval = fetch_data_byte(destoffset);
 
8252
        TRACE_AND_STEP();
 
8253
        destval = (*opcD0_byte_operation[rh]) (destval, amt);
 
8254
        store_data_byte(destoffset, destval);
 
8255
        break;
 
8256
    case 3:                     /* register to register */
 
8257
        destreg = DECODE_RM_BYTE_REGISTER(rl);
 
8258
        amt = fetch_byte_imm();
 
8259
        DECODE_PRINTF2(",%x\n", amt);
 
8260
        TRACE_AND_STEP();
 
8261
        destval = (*opcD0_byte_operation[rh]) (*destreg, amt);
 
8262
        *destreg = destval;
 
8263
        break;
 
8264
    }
 
8265
    DECODE_CLEAR_SEGOVR();
 
8266
    END_OF_INSTR();
 
8267
}
 
8268
 
 
8269
/* used by opcodes c1, d1, and d3. */
 
8270
static u16(*opcD1_word_operation[])(u16 s, u8 d) =
 
8271
{
 
8272
    rol_word,
 
8273
    ror_word,
 
8274
    rcl_word,
 
8275
    rcr_word,
 
8276
    shl_word,
 
8277
    shr_word,
 
8278
    shl_word,           /* sal_byte === shl_byte  by definition */
 
8279
    sar_word,
 
8280
};
 
8281
 
 
8282
/* used by opcodes c1, d1, and d3. */
 
8283
static u32 (*opcD1_long_operation[])(u32 s, u8 d) =
 
8284
{
 
8285
    rol_long,
 
8286
    ror_long,
 
8287
    rcl_long,
 
8288
    rcr_long,
 
8289
    shl_long,
 
8290
    shr_long,
 
8291
    shl_long,           /* sal_byte === shl_byte  by definition */
 
8292
    sar_long,
 
8293
};
 
8294
 
 
8295
/****************************************************************************
 
8296
REMARKS:
 
8297
Handles opcode 0xc1
 
8298
****************************************************************************/
 
8299
static void x86emuOp_opcC1_word_RM_MEM(u8 X86EMU_UNUSED(op1))
 
8300
{
 
8301
    int mod, rl, rh;
 
8302
    uint destoffset;
 
8303
    u8 amt;
 
8304
 
 
8305
    /*
 
8306
     * Yet another weirdo special case instruction format.  Part of
 
8307
     * the opcode held below in "RH".  Doubly nested case would
 
8308
     * result, except that the decoded instruction
 
8309
     */
 
8310
    START_OF_INSTR();
 
8311
    FETCH_DECODE_MODRM(mod, rh, rl);
 
8312
#ifdef DEBUG
 
8313
    if (DEBUG_DECODE()) {
 
8314
        /* XXX DECODE_PRINTF may be changed to something more
 
8315
           general, so that it is important to leave the strings
 
8316
           in the same format, even though the result is that the 
 
8317
           above test is done twice. */
 
8318
 
 
8319
        switch (rh) {
 
8320
        case 0:
 
8321
            DECODE_PRINTF("ROL\t");
 
8322
            break;
 
8323
        case 1:
 
8324
            DECODE_PRINTF("ROR\t");
 
8325
            break;
 
8326
        case 2:
 
8327
            DECODE_PRINTF("RCL\t");
 
8328
            break;
 
8329
        case 3:
 
8330
            DECODE_PRINTF("RCR\t");
 
8331
            break;
 
8332
        case 4:
 
8333
            DECODE_PRINTF("SHL\t");
 
8334
            break;
 
8335
        case 5:
 
8336
            DECODE_PRINTF("SHR\t");
 
8337
            break;
 
8338
        case 6:
 
8339
            DECODE_PRINTF("SAL\t");
 
8340
            break;
 
8341
        case 7:
 
8342
            DECODE_PRINTF("SAR\t");
 
8343
            break;
 
8344
        }
 
8345
    }
 
8346
#endif
 
8347
    /* know operation, decode the mod byte to find the addressing
 
8348
       mode. */
 
8349
    switch (mod) {
 
8350
    case 0:
 
8351
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
8352
            u32 destval;
 
8353
 
 
8354
            DECODE_PRINTF("DWORD PTR ");
 
8355
            destoffset = decode_rm00_address(rl);
 
8356
            amt = fetch_byte_imm();
 
8357
            DECODE_PRINTF2(",%x\n", amt);
 
8358
            destval = fetch_data_long(destoffset);
 
8359
            TRACE_AND_STEP();
 
8360
            destval = (*opcD1_long_operation[rh]) (destval, amt);
 
8361
            store_data_long(destoffset, destval);
 
8362
        } else {
 
8363
            u16 destval;
 
8364
 
 
8365
            DECODE_PRINTF("WORD PTR ");
 
8366
            destoffset = decode_rm00_address(rl);
 
8367
            amt = fetch_byte_imm();
 
8368
            DECODE_PRINTF2(",%x\n", amt);
 
8369
            destval = fetch_data_word(destoffset);
 
8370
            TRACE_AND_STEP();
 
8371
            destval = (*opcD1_word_operation[rh]) (destval, amt);
 
8372
            store_data_word(destoffset, destval);
 
8373
        }
 
8374
        break;
 
8375
    case 1:
 
8376
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
8377
            u32 destval;
 
8378
 
 
8379
            DECODE_PRINTF("DWORD PTR ");
 
8380
            destoffset = decode_rm01_address(rl);
 
8381
            amt = fetch_byte_imm();
 
8382
            DECODE_PRINTF2(",%x\n", amt);
 
8383
            destval = fetch_data_long(destoffset);
 
8384
            TRACE_AND_STEP();
 
8385
            destval = (*opcD1_long_operation[rh]) (destval, amt);
 
8386
            store_data_long(destoffset, destval);
 
8387
        } else {
 
8388
            u16 destval;
 
8389
 
 
8390
            DECODE_PRINTF("WORD PTR ");
 
8391
            destoffset = decode_rm01_address(rl);
 
8392
            amt = fetch_byte_imm();
 
8393
            DECODE_PRINTF2(",%x\n", amt);
 
8394
            destval = fetch_data_word(destoffset);
 
8395
            TRACE_AND_STEP();
 
8396
            destval = (*opcD1_word_operation[rh]) (destval, amt);
 
8397
            store_data_word(destoffset, destval);
 
8398
        }
 
8399
        break;
 
8400
    case 2:
 
8401
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
8402
            u32 destval;
 
8403
 
 
8404
            DECODE_PRINTF("DWORD PTR ");
 
8405
            destoffset = decode_rm10_address(rl);
 
8406
            amt = fetch_byte_imm();
 
8407
            DECODE_PRINTF2(",%x\n", amt);
 
8408
            destval = fetch_data_long(destoffset);
 
8409
            TRACE_AND_STEP();
 
8410
            destval = (*opcD1_long_operation[rh]) (destval, amt);
 
8411
            store_data_long(destoffset, destval);
 
8412
        } else {
 
8413
            u16 destval;
 
8414
 
 
8415
            DECODE_PRINTF("WORD PTR ");
 
8416
            destoffset = decode_rm10_address(rl);
 
8417
            amt = fetch_byte_imm();
 
8418
            DECODE_PRINTF2(",%x\n", amt);
 
8419
            destval = fetch_data_word(destoffset);
 
8420
            TRACE_AND_STEP();
 
8421
            destval = (*opcD1_word_operation[rh]) (destval, amt);
 
8422
            store_data_word(destoffset, destval);
 
8423
        }
 
8424
        break;
 
8425
    case 3:                     /* register to register */
 
8426
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
8427
            u32 *destreg;
 
8428
 
 
8429
            destreg = DECODE_RM_LONG_REGISTER(rl);
 
8430
            amt = fetch_byte_imm();
 
8431
            DECODE_PRINTF2(",%x\n", amt);
 
8432
            TRACE_AND_STEP();
 
8433
            *destreg = (*opcD1_long_operation[rh]) (*destreg, amt);
 
8434
        } else {
 
8435
            u16 *destreg;
 
8436
 
 
8437
            destreg = DECODE_RM_WORD_REGISTER(rl);
 
8438
            amt = fetch_byte_imm();
 
8439
            DECODE_PRINTF2(",%x\n", amt);
 
8440
            TRACE_AND_STEP();
 
8441
            *destreg = (*opcD1_word_operation[rh]) (*destreg, amt);
 
8442
        }
 
8443
        break;
 
8444
    }
 
8445
    DECODE_CLEAR_SEGOVR();
 
8446
    END_OF_INSTR();
 
8447
}
 
8448
 
 
8449
/****************************************************************************
 
8450
REMARKS:
 
8451
Handles opcode 0xc2
 
8452
****************************************************************************/
 
8453
static void x86emuOp_ret_near_IMM(u8 X86EMU_UNUSED(op1))
 
8454
{
 
8455
    u16 imm;
 
8456
 
 
8457
    START_OF_INSTR();
 
8458
    DECODE_PRINTF("RET\t");
 
8459
    imm = fetch_word_imm();
 
8460
    DECODE_PRINTF2("%x\n", imm);
 
8461
        RETURN_TRACE("RET",M.x86.saved_cs,M.x86.saved_ip);
 
8462
        TRACE_AND_STEP();
 
8463
    M.x86.R_IP = pop_word();
 
8464
    M.x86.R_SP += imm;
 
8465
    DECODE_CLEAR_SEGOVR();
 
8466
    END_OF_INSTR();
 
8467
}
 
8468
 
 
8469
/****************************************************************************
 
8470
REMARKS:
 
8471
Handles opcode 0xc3
 
8472
****************************************************************************/
 
8473
static void x86emuOp_ret_near(u8 X86EMU_UNUSED(op1))
 
8474
{
 
8475
    START_OF_INSTR();
 
8476
    DECODE_PRINTF("RET\n");
 
8477
        RETURN_TRACE("RET",M.x86.saved_cs,M.x86.saved_ip);
 
8478
        TRACE_AND_STEP();
 
8479
    M.x86.R_IP = pop_word();
 
8480
    DECODE_CLEAR_SEGOVR();
 
8481
    END_OF_INSTR();
 
8482
}
 
8483
 
 
8484
/****************************************************************************
 
8485
REMARKS:
 
8486
Handles opcode 0xc4
 
8487
****************************************************************************/
 
8488
static void x86emuOp_les_R_IMM(u8 X86EMU_UNUSED(op1))
 
8489
{
 
8490
    int mod, rh, rl;
 
8491
    u16 *dstreg;
 
8492
    uint srcoffset;
 
8493
 
 
8494
    START_OF_INSTR();
 
8495
    DECODE_PRINTF("LES\t");
 
8496
    FETCH_DECODE_MODRM(mod, rh, rl);
 
8497
    switch (mod) {
 
8498
    case 0:
 
8499
        dstreg = DECODE_RM_WORD_REGISTER(rh);
 
8500
        DECODE_PRINTF(",");
 
8501
        srcoffset = decode_rm00_address(rl);
 
8502
        DECODE_PRINTF("\n");
 
8503
        TRACE_AND_STEP();
 
8504
        *dstreg = fetch_data_word(srcoffset);
 
8505
        M.x86.R_ES = fetch_data_word(srcoffset + 2);
 
8506
        break;
 
8507
    case 1:
 
8508
        dstreg = DECODE_RM_WORD_REGISTER(rh);
 
8509
        DECODE_PRINTF(",");
 
8510
        srcoffset = decode_rm01_address(rl);
 
8511
        DECODE_PRINTF("\n");
 
8512
        TRACE_AND_STEP();
 
8513
        *dstreg = fetch_data_word(srcoffset);
 
8514
        M.x86.R_ES = fetch_data_word(srcoffset + 2);
 
8515
        break;
 
8516
    case 2:
 
8517
        dstreg = DECODE_RM_WORD_REGISTER(rh);
 
8518
        DECODE_PRINTF(",");
 
8519
        srcoffset = decode_rm10_address(rl);
 
8520
        DECODE_PRINTF("\n");
 
8521
        TRACE_AND_STEP();
 
8522
        *dstreg = fetch_data_word(srcoffset);
 
8523
        M.x86.R_ES = fetch_data_word(srcoffset + 2);
 
8524
        break;
 
8525
    case 3:                     /* register to register */
 
8526
        /* UNDEFINED! */
 
8527
        TRACE_AND_STEP();
 
8528
    }
 
8529
    DECODE_CLEAR_SEGOVR();
 
8530
    END_OF_INSTR();
 
8531
}
 
8532
 
 
8533
/****************************************************************************
 
8534
REMARKS:
 
8535
Handles opcode 0xc5
 
8536
****************************************************************************/
 
8537
static void x86emuOp_lds_R_IMM(u8 X86EMU_UNUSED(op1))
 
8538
{
 
8539
    int mod, rh, rl;
 
8540
    u16 *dstreg;
 
8541
    uint srcoffset;
 
8542
 
 
8543
    START_OF_INSTR();
 
8544
    DECODE_PRINTF("LDS\t");
 
8545
    FETCH_DECODE_MODRM(mod, rh, rl);
 
8546
    switch (mod) {
 
8547
    case 0:
 
8548
        dstreg = DECODE_RM_WORD_REGISTER(rh);
 
8549
        DECODE_PRINTF(",");
 
8550
        srcoffset = decode_rm00_address(rl);
 
8551
        DECODE_PRINTF("\n");
 
8552
        TRACE_AND_STEP();
 
8553
        *dstreg = fetch_data_word(srcoffset);
 
8554
        M.x86.R_DS = fetch_data_word(srcoffset + 2);
 
8555
        break;
 
8556
    case 1:
 
8557
        dstreg = DECODE_RM_WORD_REGISTER(rh);
 
8558
        DECODE_PRINTF(",");
 
8559
        srcoffset = decode_rm01_address(rl);
 
8560
        DECODE_PRINTF("\n");
 
8561
        TRACE_AND_STEP();
 
8562
        *dstreg = fetch_data_word(srcoffset);
 
8563
        M.x86.R_DS = fetch_data_word(srcoffset + 2);
 
8564
        break;
 
8565
    case 2:
 
8566
        dstreg = DECODE_RM_WORD_REGISTER(rh);
 
8567
        DECODE_PRINTF(",");
 
8568
        srcoffset = decode_rm10_address(rl);
 
8569
        DECODE_PRINTF("\n");
 
8570
        TRACE_AND_STEP();
 
8571
        *dstreg = fetch_data_word(srcoffset);
 
8572
        M.x86.R_DS = fetch_data_word(srcoffset + 2);
 
8573
        break;
 
8574
    case 3:                     /* register to register */
 
8575
        /* UNDEFINED! */
 
8576
        TRACE_AND_STEP();
 
8577
    }
 
8578
    DECODE_CLEAR_SEGOVR();
 
8579
    END_OF_INSTR();
 
8580
}
 
8581
 
 
8582
/****************************************************************************
 
8583
REMARKS:
 
8584
Handles opcode 0xc6
 
8585
****************************************************************************/
 
8586
static void x86emuOp_mov_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
 
8587
{
 
8588
    int mod, rl, rh;
 
8589
    u8 *destreg;
 
8590
    uint destoffset;
 
8591
    u8 imm;
 
8592
 
 
8593
    START_OF_INSTR();
 
8594
    DECODE_PRINTF("MOV\t");
 
8595
    FETCH_DECODE_MODRM(mod, rh, rl);
 
8596
    if (rh != 0) {
 
8597
        DECODE_PRINTF("ILLEGAL DECODE OF OPCODE c6\n");
 
8598
        HALT_SYS();
 
8599
    }
 
8600
    switch (mod) {
 
8601
    case 0:
 
8602
        DECODE_PRINTF("BYTE PTR ");
 
8603
        destoffset = decode_rm00_address(rl);
 
8604
        imm = fetch_byte_imm();
 
8605
        DECODE_PRINTF2(",%2x\n", imm);
 
8606
        TRACE_AND_STEP();
 
8607
        store_data_byte(destoffset, imm);
 
8608
        break;
 
8609
    case 1:
 
8610
        DECODE_PRINTF("BYTE PTR ");
 
8611
        destoffset = decode_rm01_address(rl);
 
8612
        imm = fetch_byte_imm();
 
8613
        DECODE_PRINTF2(",%2x\n", imm);
 
8614
        TRACE_AND_STEP();
 
8615
        store_data_byte(destoffset, imm);
 
8616
        break;
 
8617
    case 2:
 
8618
        DECODE_PRINTF("BYTE PTR ");
 
8619
        destoffset = decode_rm10_address(rl);
 
8620
        imm = fetch_byte_imm();
 
8621
        DECODE_PRINTF2(",%2x\n", imm);
 
8622
        TRACE_AND_STEP();
 
8623
        store_data_byte(destoffset, imm);
 
8624
        break;
 
8625
    case 3:                     /* register to register */
 
8626
        destreg = DECODE_RM_BYTE_REGISTER(rl);
 
8627
        imm = fetch_byte_imm();
 
8628
        DECODE_PRINTF2(",%2x\n", imm);
 
8629
        TRACE_AND_STEP();
 
8630
        *destreg = imm;
 
8631
        break;
 
8632
    }
 
8633
    DECODE_CLEAR_SEGOVR();
 
8634
    END_OF_INSTR();
 
8635
}
 
8636
 
 
8637
/****************************************************************************
 
8638
REMARKS:
 
8639
Handles opcode 0xc7
 
8640
****************************************************************************/
 
8641
static void x86emuOp_mov_word_RM_IMM(u8 X86EMU_UNUSED(op1))
 
8642
{
 
8643
    int mod, rl, rh;
 
8644
    uint destoffset;
 
8645
 
 
8646
    START_OF_INSTR();
 
8647
    DECODE_PRINTF("MOV\t");
 
8648
    FETCH_DECODE_MODRM(mod, rh, rl);
 
8649
    if (rh != 0) {
 
8650
        DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n");
 
8651
        HALT_SYS();
 
8652
    }
 
8653
    switch (mod) {
 
8654
    case 0:
 
8655
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
8656
            u32 imm;
 
8657
 
 
8658
            DECODE_PRINTF("DWORD PTR ");
 
8659
            destoffset = decode_rm00_address(rl);
 
8660
            imm = fetch_long_imm();
 
8661
            DECODE_PRINTF2(",%x\n", imm);
 
8662
            TRACE_AND_STEP();
 
8663
            store_data_long(destoffset, imm);
 
8664
        } else {
 
8665
            u16 imm;
 
8666
 
 
8667
            DECODE_PRINTF("WORD PTR ");
 
8668
            destoffset = decode_rm00_address(rl);
 
8669
            imm = fetch_word_imm();
 
8670
            DECODE_PRINTF2(",%x\n", imm);
 
8671
            TRACE_AND_STEP();
 
8672
            store_data_word(destoffset, imm);
 
8673
        }
 
8674
        break;
 
8675
    case 1:
 
8676
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
8677
            u32 imm;
 
8678
 
 
8679
            DECODE_PRINTF("DWORD PTR ");
 
8680
            destoffset = decode_rm01_address(rl);
 
8681
            imm = fetch_long_imm();
 
8682
            DECODE_PRINTF2(",%x\n", imm);
 
8683
            TRACE_AND_STEP();
 
8684
            store_data_long(destoffset, imm);
 
8685
        } else {
 
8686
            u16 imm;
 
8687
 
 
8688
            DECODE_PRINTF("WORD PTR ");
 
8689
            destoffset = decode_rm01_address(rl);
 
8690
            imm = fetch_word_imm();
 
8691
            DECODE_PRINTF2(",%x\n", imm);
 
8692
            TRACE_AND_STEP();
 
8693
            store_data_word(destoffset, imm);
 
8694
        }
 
8695
        break;
 
8696
    case 2:
 
8697
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
8698
            u32 imm;
 
8699
 
 
8700
            DECODE_PRINTF("DWORD PTR ");
 
8701
            destoffset = decode_rm10_address(rl);
 
8702
            imm = fetch_long_imm();
 
8703
            DECODE_PRINTF2(",%x\n", imm);
 
8704
            TRACE_AND_STEP();
 
8705
            store_data_long(destoffset, imm);
 
8706
        } else {
 
8707
            u16 imm;
 
8708
 
 
8709
            DECODE_PRINTF("WORD PTR ");
 
8710
            destoffset = decode_rm10_address(rl);
 
8711
            imm = fetch_word_imm();
 
8712
            DECODE_PRINTF2(",%x\n", imm);
 
8713
            TRACE_AND_STEP();
 
8714
            store_data_word(destoffset, imm);
 
8715
        }
 
8716
        break;
 
8717
    case 3:                     /* register to register */
 
8718
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
8719
                        u32 *destreg;
 
8720
                        u32 imm;
 
8721
 
 
8722
            destreg = DECODE_RM_LONG_REGISTER(rl);
 
8723
            imm = fetch_long_imm();
 
8724
            DECODE_PRINTF2(",%x\n", imm);
 
8725
            TRACE_AND_STEP();
 
8726
            *destreg = imm;
 
8727
        } else {
 
8728
                        u16 *destreg;
 
8729
                        u16 imm;
 
8730
 
 
8731
            destreg = DECODE_RM_WORD_REGISTER(rl);
 
8732
            imm = fetch_word_imm();
 
8733
            DECODE_PRINTF2(",%x\n", imm);
 
8734
            TRACE_AND_STEP();
 
8735
            *destreg = imm;
 
8736
        }
 
8737
        break;
 
8738
    }
 
8739
    DECODE_CLEAR_SEGOVR();
 
8740
    END_OF_INSTR();
 
8741
}
 
8742
 
 
8743
/****************************************************************************
 
8744
REMARKS:
 
8745
Handles opcode 0xc8
 
8746
****************************************************************************/
 
8747
static void x86emuOp_enter(u8 X86EMU_UNUSED(op1))
 
8748
{
 
8749
    u16 local,frame_pointer;
 
8750
    u8  nesting;
 
8751
    int i;
 
8752
 
 
8753
    START_OF_INSTR();
 
8754
    local = fetch_word_imm();
 
8755
    nesting = fetch_byte_imm();
 
8756
    DECODE_PRINTF2("ENTER %x\n", local);
 
8757
    DECODE_PRINTF2(",%x\n", nesting);
 
8758
    TRACE_AND_STEP();
 
8759
    push_word(M.x86.R_BP);
 
8760
    frame_pointer = M.x86.R_SP;
 
8761
    if (nesting > 0) {
 
8762
        for (i = 1; i < nesting; i++) {
 
8763
            M.x86.R_BP -= 2;
 
8764
            push_word(fetch_data_word_abs(M.x86.R_SS, M.x86.R_BP));
 
8765
            }
 
8766
        push_word(frame_pointer);
 
8767
        }
 
8768
    M.x86.R_BP = frame_pointer;
 
8769
    M.x86.R_SP = (u16)(M.x86.R_SP - local);
 
8770
    DECODE_CLEAR_SEGOVR();
 
8771
    END_OF_INSTR();
 
8772
}
 
8773
 
 
8774
/****************************************************************************
 
8775
REMARKS:
 
8776
Handles opcode 0xc9
 
8777
****************************************************************************/
 
8778
static void x86emuOp_leave(u8 X86EMU_UNUSED(op1))
 
8779
{
 
8780
    START_OF_INSTR();
 
8781
    DECODE_PRINTF("LEAVE\n");
 
8782
    TRACE_AND_STEP();
 
8783
    M.x86.R_SP = M.x86.R_BP;
 
8784
    M.x86.R_BP = pop_word();
 
8785
    DECODE_CLEAR_SEGOVR();
 
8786
    END_OF_INSTR();
 
8787
}
 
8788
 
 
8789
/****************************************************************************
 
8790
REMARKS:
 
8791
Handles opcode 0xca
 
8792
****************************************************************************/
 
8793
static void x86emuOp_ret_far_IMM(u8 X86EMU_UNUSED(op1))
 
8794
{
 
8795
    u16 imm;
 
8796
 
 
8797
    START_OF_INSTR();
 
8798
    DECODE_PRINTF("RETF\t");
 
8799
    imm = fetch_word_imm();
 
8800
    DECODE_PRINTF2("%x\n", imm);
 
8801
        RETURN_TRACE("RETF",M.x86.saved_cs,M.x86.saved_ip);
 
8802
        TRACE_AND_STEP();
 
8803
    M.x86.R_IP = pop_word();
 
8804
    M.x86.R_CS = pop_word();
 
8805
    M.x86.R_SP += imm;
 
8806
    DECODE_CLEAR_SEGOVR();
 
8807
    END_OF_INSTR();
 
8808
}
 
8809
 
 
8810
/****************************************************************************
 
8811
REMARKS:
 
8812
Handles opcode 0xcb
 
8813
****************************************************************************/
 
8814
static void x86emuOp_ret_far(u8 X86EMU_UNUSED(op1))
 
8815
{
 
8816
    START_OF_INSTR();
 
8817
    DECODE_PRINTF("RETF\n");
 
8818
        RETURN_TRACE("RETF",M.x86.saved_cs,M.x86.saved_ip);
 
8819
        TRACE_AND_STEP();
 
8820
    M.x86.R_IP = pop_word();
 
8821
    M.x86.R_CS = pop_word();
 
8822
    DECODE_CLEAR_SEGOVR();
 
8823
    END_OF_INSTR();
 
8824
}
 
8825
 
 
8826
/****************************************************************************
 
8827
REMARKS:
 
8828
Handles opcode 0xcc
 
8829
****************************************************************************/
 
8830
static void x86emuOp_int3(u8 X86EMU_UNUSED(op1))
 
8831
{
 
8832
    START_OF_INSTR();
 
8833
    DECODE_PRINTF("INT 3\n");
 
8834
    TRACE_AND_STEP();
 
8835
    if (_X86EMU_intrTab[3]) {
 
8836
        (*_X86EMU_intrTab[3])(3);
 
8837
    } else {
 
8838
        push_word((u16)M.x86.R_FLG);
 
8839
        CLEAR_FLAG(F_IF);
 
8840
        CLEAR_FLAG(F_TF);
 
8841
        push_word(M.x86.R_CS);
 
8842
        M.x86.R_CS = mem_access_word(3 * 4 + 2);
 
8843
        push_word(M.x86.R_IP);
 
8844
        M.x86.R_IP = mem_access_word(3 * 4);
 
8845
    }
 
8846
    DECODE_CLEAR_SEGOVR();
 
8847
    END_OF_INSTR();
 
8848
}
 
8849
 
 
8850
/****************************************************************************
 
8851
REMARKS:
 
8852
Handles opcode 0xcd
 
8853
****************************************************************************/
 
8854
static void x86emuOp_int_IMM(u8 X86EMU_UNUSED(op1))
 
8855
{
 
8856
    u8 intnum;
 
8857
 
 
8858
    START_OF_INSTR();
 
8859
    DECODE_PRINTF("INT\t");
 
8860
    intnum = fetch_byte_imm();
 
8861
    DECODE_PRINTF2("%x\n", intnum);
 
8862
    TRACE_AND_STEP();
 
8863
    if (_X86EMU_intrTab[intnum]) {
 
8864
        (*_X86EMU_intrTab[intnum])(intnum);
 
8865
    } else {
 
8866
        push_word((u16)M.x86.R_FLG);
 
8867
        CLEAR_FLAG(F_IF);
 
8868
        CLEAR_FLAG(F_TF);
 
8869
        push_word(M.x86.R_CS);
 
8870
        M.x86.R_CS = mem_access_word(intnum * 4 + 2);
 
8871
        push_word(M.x86.R_IP);
 
8872
        M.x86.R_IP = mem_access_word(intnum * 4);
 
8873
    }
 
8874
    DECODE_CLEAR_SEGOVR();
 
8875
    END_OF_INSTR();
 
8876
}
 
8877
 
 
8878
/****************************************************************************
 
8879
REMARKS:
 
8880
Handles opcode 0xce
 
8881
****************************************************************************/
 
8882
static void x86emuOp_into(u8 X86EMU_UNUSED(op1))
 
8883
{
 
8884
    START_OF_INSTR();
 
8885
    DECODE_PRINTF("INTO\n");
 
8886
    TRACE_AND_STEP();
 
8887
    if (ACCESS_FLAG(F_OF)) {
 
8888
        if (_X86EMU_intrTab[4]) {
 
8889
            (*_X86EMU_intrTab[4])(4);
 
8890
        } else {
 
8891
            push_word((u16)M.x86.R_FLG);
 
8892
            CLEAR_FLAG(F_IF);
 
8893
            CLEAR_FLAG(F_TF);
 
8894
            push_word(M.x86.R_CS);
 
8895
            M.x86.R_CS = mem_access_word(4 * 4 + 2);
 
8896
            push_word(M.x86.R_IP);
 
8897
            M.x86.R_IP = mem_access_word(4 * 4);
 
8898
        }
 
8899
    }
 
8900
    DECODE_CLEAR_SEGOVR();
 
8901
    END_OF_INSTR();
 
8902
}
 
8903
 
 
8904
/****************************************************************************
 
8905
REMARKS:
 
8906
Handles opcode 0xcf
 
8907
****************************************************************************/
 
8908
static void x86emuOp_iret(u8 X86EMU_UNUSED(op1))
 
8909
{
 
8910
    START_OF_INSTR();
 
8911
    DECODE_PRINTF("IRET\n");
 
8912
 
 
8913
    TRACE_AND_STEP();
 
8914
 
 
8915
    M.x86.R_IP = pop_word();
 
8916
    M.x86.R_CS = pop_word();
 
8917
    M.x86.R_FLG = pop_word();
 
8918
    DECODE_CLEAR_SEGOVR();
 
8919
    END_OF_INSTR();
 
8920
}
 
8921
 
 
8922
/****************************************************************************
 
8923
REMARKS:
 
8924
Handles opcode 0xd0
 
8925
****************************************************************************/
 
8926
static void x86emuOp_opcD0_byte_RM_1(u8 X86EMU_UNUSED(op1))
 
8927
{
 
8928
    int mod, rl, rh;
 
8929
    u8 *destreg;
 
8930
    uint destoffset;
 
8931
    u8 destval;
 
8932
 
 
8933
    /*
 
8934
     * Yet another weirdo special case instruction format.  Part of
 
8935
     * the opcode held below in "RH".  Doubly nested case would
 
8936
     * result, except that the decoded instruction
 
8937
     */
 
8938
    START_OF_INSTR();
 
8939
    FETCH_DECODE_MODRM(mod, rh, rl);
 
8940
#ifdef DEBUG
 
8941
    if (DEBUG_DECODE()) {
 
8942
        /* XXX DECODE_PRINTF may be changed to something more
 
8943
           general, so that it is important to leave the strings
 
8944
           in the same format, even though the result is that the
 
8945
           above test is done twice. */
 
8946
        switch (rh) {
 
8947
        case 0:
 
8948
            DECODE_PRINTF("ROL\t");
 
8949
            break;
 
8950
        case 1:
 
8951
            DECODE_PRINTF("ROR\t");
 
8952
            break;
 
8953
        case 2:
 
8954
            DECODE_PRINTF("RCL\t");
 
8955
            break;
 
8956
        case 3:
 
8957
            DECODE_PRINTF("RCR\t");
 
8958
            break;
 
8959
        case 4:
 
8960
            DECODE_PRINTF("SHL\t");
 
8961
            break;
 
8962
        case 5:
 
8963
            DECODE_PRINTF("SHR\t");
 
8964
            break;
 
8965
        case 6:
 
8966
            DECODE_PRINTF("SAL\t");
 
8967
            break;
 
8968
        case 7:
 
8969
            DECODE_PRINTF("SAR\t");
 
8970
            break;
 
8971
        }
 
8972
    }
 
8973
#endif
 
8974
    /* know operation, decode the mod byte to find the addressing
 
8975
       mode. */
 
8976
    switch (mod) {
 
8977
    case 0:
 
8978
        DECODE_PRINTF("BYTE PTR ");
 
8979
        destoffset = decode_rm00_address(rl);
 
8980
        DECODE_PRINTF(",1\n");
 
8981
        destval = fetch_data_byte(destoffset);
 
8982
        TRACE_AND_STEP();
 
8983
        destval = (*opcD0_byte_operation[rh]) (destval, 1);
 
8984
        store_data_byte(destoffset, destval);
 
8985
        break;
 
8986
    case 1:
 
8987
        DECODE_PRINTF("BYTE PTR ");
 
8988
        destoffset = decode_rm01_address(rl);
 
8989
        DECODE_PRINTF(",1\n");
 
8990
        destval = fetch_data_byte(destoffset);
 
8991
        TRACE_AND_STEP();
 
8992
        destval = (*opcD0_byte_operation[rh]) (destval, 1);
 
8993
        store_data_byte(destoffset, destval);
 
8994
        break;
 
8995
    case 2:
 
8996
        DECODE_PRINTF("BYTE PTR ");
 
8997
        destoffset = decode_rm10_address(rl);
 
8998
        DECODE_PRINTF(",1\n");
 
8999
        destval = fetch_data_byte(destoffset);
 
9000
        TRACE_AND_STEP();
 
9001
        destval = (*opcD0_byte_operation[rh]) (destval, 1);
 
9002
        store_data_byte(destoffset, destval);
 
9003
        break;
 
9004
    case 3:                     /* register to register */
 
9005
        destreg = DECODE_RM_BYTE_REGISTER(rl);
 
9006
        DECODE_PRINTF(",1\n");
 
9007
        TRACE_AND_STEP();
 
9008
        destval = (*opcD0_byte_operation[rh]) (*destreg, 1);
 
9009
        *destreg = destval;
 
9010
        break;
 
9011
    }
 
9012
    DECODE_CLEAR_SEGOVR();
 
9013
    END_OF_INSTR();
 
9014
}
 
9015
 
 
9016
/****************************************************************************
 
9017
REMARKS:
 
9018
Handles opcode 0xd1
 
9019
****************************************************************************/
 
9020
static void x86emuOp_opcD1_word_RM_1(u8 X86EMU_UNUSED(op1))
 
9021
{
 
9022
    int mod, rl, rh;
 
9023
    uint destoffset;
 
9024
 
 
9025
    /*
 
9026
     * Yet another weirdo special case instruction format.  Part of
 
9027
     * the opcode held below in "RH".  Doubly nested case would
 
9028
     * result, except that the decoded instruction
 
9029
     */
 
9030
    START_OF_INSTR();
 
9031
    FETCH_DECODE_MODRM(mod, rh, rl);
 
9032
#ifdef DEBUG
 
9033
    if (DEBUG_DECODE()) {
 
9034
        /* XXX DECODE_PRINTF may be changed to something more
 
9035
           general, so that it is important to leave the strings
 
9036
           in the same format, even though the result is that the
 
9037
           above test is done twice. */
 
9038
        switch (rh) {
 
9039
        case 0:
 
9040
            DECODE_PRINTF("ROL\t");
 
9041
            break;
 
9042
        case 1:
 
9043
            DECODE_PRINTF("ROR\t");
 
9044
            break;
 
9045
        case 2:
 
9046
            DECODE_PRINTF("RCL\t");
 
9047
            break;
 
9048
        case 3:
 
9049
            DECODE_PRINTF("RCR\t");
 
9050
            break;
 
9051
        case 4:
 
9052
            DECODE_PRINTF("SHL\t");
 
9053
            break;
 
9054
        case 5:
 
9055
            DECODE_PRINTF("SHR\t");
 
9056
            break;
 
9057
        case 6:
 
9058
            DECODE_PRINTF("SAL\t");
 
9059
            break;
 
9060
        case 7:
 
9061
            DECODE_PRINTF("SAR\t");
 
9062
            break;
 
9063
        }
 
9064
    }
 
9065
#endif
 
9066
    /* know operation, decode the mod byte to find the addressing
 
9067
       mode. */
 
9068
    switch (mod) {
 
9069
    case 0:
 
9070
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
9071
            u32 destval;
 
9072
 
 
9073
            DECODE_PRINTF("DWORD PTR ");
 
9074
            destoffset = decode_rm00_address(rl);
 
9075
            DECODE_PRINTF(",1\n");
 
9076
            destval = fetch_data_long(destoffset);
 
9077
            TRACE_AND_STEP();
 
9078
            destval = (*opcD1_long_operation[rh]) (destval, 1);
 
9079
            store_data_long(destoffset, destval);
 
9080
        } else {
 
9081
            u16 destval;
 
9082
 
 
9083
            DECODE_PRINTF("WORD PTR ");
 
9084
            destoffset = decode_rm00_address(rl);
 
9085
            DECODE_PRINTF(",1\n");
 
9086
            destval = fetch_data_word(destoffset);
 
9087
            TRACE_AND_STEP();
 
9088
            destval = (*opcD1_word_operation[rh]) (destval, 1);
 
9089
            store_data_word(destoffset, destval);
 
9090
        }
 
9091
        break;
 
9092
    case 1:
 
9093
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
9094
            u32 destval;
 
9095
 
 
9096
            DECODE_PRINTF("DWORD PTR ");
 
9097
            destoffset = decode_rm01_address(rl);
 
9098
            DECODE_PRINTF(",1\n");
 
9099
            destval = fetch_data_long(destoffset);
 
9100
            TRACE_AND_STEP();
 
9101
            destval = (*opcD1_long_operation[rh]) (destval, 1);
 
9102
            store_data_long(destoffset, destval);
 
9103
        } else {
 
9104
            u16 destval;
 
9105
 
 
9106
            DECODE_PRINTF("WORD PTR ");
 
9107
            destoffset = decode_rm01_address(rl);
 
9108
            DECODE_PRINTF(",1\n");
 
9109
            destval = fetch_data_word(destoffset);
 
9110
            TRACE_AND_STEP();
 
9111
            destval = (*opcD1_word_operation[rh]) (destval, 1);
 
9112
            store_data_word(destoffset, destval);
 
9113
        }
 
9114
        break;
 
9115
    case 2:
 
9116
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
9117
            u32 destval;
 
9118
 
 
9119
            DECODE_PRINTF("DWORD PTR ");
 
9120
            destoffset = decode_rm10_address(rl);
 
9121
            DECODE_PRINTF(",1\n");
 
9122
            destval = fetch_data_long(destoffset);
 
9123
            TRACE_AND_STEP();
 
9124
            destval = (*opcD1_long_operation[rh]) (destval, 1);
 
9125
            store_data_long(destoffset, destval);
 
9126
        } else {
 
9127
            u16 destval;
 
9128
 
 
9129
            DECODE_PRINTF("BYTE PTR ");
 
9130
            destoffset = decode_rm10_address(rl);
 
9131
            DECODE_PRINTF(",1\n");
 
9132
            destval = fetch_data_word(destoffset);
 
9133
            TRACE_AND_STEP();
 
9134
            destval = (*opcD1_word_operation[rh]) (destval, 1);
 
9135
            store_data_word(destoffset, destval);
 
9136
        }
 
9137
        break;
 
9138
    case 3:                     /* register to register */
 
9139
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
9140
                        u32 destval;
 
9141
                        u32 *destreg;
 
9142
 
 
9143
            destreg = DECODE_RM_LONG_REGISTER(rl);
 
9144
            DECODE_PRINTF(",1\n");
 
9145
            TRACE_AND_STEP();
 
9146
            destval = (*opcD1_long_operation[rh]) (*destreg, 1);
 
9147
            *destreg = destval;
 
9148
        } else {
 
9149
                        u16 destval;
 
9150
                        u16 *destreg;
 
9151
 
 
9152
            destreg = DECODE_RM_WORD_REGISTER(rl);
 
9153
            DECODE_PRINTF(",1\n");
 
9154
            TRACE_AND_STEP();
 
9155
            destval = (*opcD1_word_operation[rh]) (*destreg, 1);
 
9156
            *destreg = destval;
 
9157
        }
 
9158
        break;
 
9159
    }
 
9160
    DECODE_CLEAR_SEGOVR();
 
9161
    END_OF_INSTR();
 
9162
}
 
9163
 
 
9164
/****************************************************************************
 
9165
REMARKS:
 
9166
Handles opcode 0xd2
 
9167
****************************************************************************/
 
9168
static void x86emuOp_opcD2_byte_RM_CL(u8 X86EMU_UNUSED(op1))
 
9169
{
 
9170
    int mod, rl, rh;
 
9171
    u8 *destreg;
 
9172
    uint destoffset;
 
9173
    u8 destval;
 
9174
    u8 amt;
 
9175
 
 
9176
    /*
 
9177
     * Yet another weirdo special case instruction format.  Part of
 
9178
     * the opcode held below in "RH".  Doubly nested case would
 
9179
     * result, except that the decoded instruction
 
9180
     */
 
9181
    START_OF_INSTR();
 
9182
    FETCH_DECODE_MODRM(mod, rh, rl);
 
9183
#ifdef DEBUG
 
9184
    if (DEBUG_DECODE()) {
 
9185
        /* XXX DECODE_PRINTF may be changed to something more
 
9186
           general, so that it is important to leave the strings
 
9187
           in the same format, even though the result is that the 
 
9188
           above test is done twice. */
 
9189
        switch (rh) {
 
9190
        case 0:
 
9191
            DECODE_PRINTF("ROL\t");
 
9192
            break;
 
9193
        case 1:
 
9194
            DECODE_PRINTF("ROR\t");
 
9195
            break;
 
9196
        case 2:
 
9197
            DECODE_PRINTF("RCL\t");
 
9198
            break;
 
9199
        case 3:
 
9200
            DECODE_PRINTF("RCR\t");
 
9201
            break;
 
9202
        case 4:
 
9203
            DECODE_PRINTF("SHL\t");
 
9204
            break;
 
9205
        case 5:
 
9206
            DECODE_PRINTF("SHR\t");
 
9207
            break;
 
9208
        case 6:
 
9209
            DECODE_PRINTF("SAL\t");
 
9210
            break;
 
9211
        case 7:
 
9212
            DECODE_PRINTF("SAR\t");
 
9213
            break;
 
9214
        }
 
9215
    }
 
9216
#endif
 
9217
    /* know operation, decode the mod byte to find the addressing
 
9218
       mode. */
 
9219
    amt = M.x86.R_CL;
 
9220
    switch (mod) {
 
9221
    case 0:
 
9222
        DECODE_PRINTF("BYTE PTR ");
 
9223
        destoffset = decode_rm00_address(rl);
 
9224
        DECODE_PRINTF(",CL\n");
 
9225
        destval = fetch_data_byte(destoffset);
 
9226
        TRACE_AND_STEP();
 
9227
        destval = (*opcD0_byte_operation[rh]) (destval, amt);
 
9228
        store_data_byte(destoffset, destval);
 
9229
        break;
 
9230
    case 1:
 
9231
        DECODE_PRINTF("BYTE PTR ");
 
9232
        destoffset = decode_rm01_address(rl);
 
9233
        DECODE_PRINTF(",CL\n");
 
9234
        destval = fetch_data_byte(destoffset);
 
9235
        TRACE_AND_STEP();
 
9236
        destval = (*opcD0_byte_operation[rh]) (destval, amt);
 
9237
        store_data_byte(destoffset, destval);
 
9238
        break;
 
9239
    case 2:
 
9240
        DECODE_PRINTF("BYTE PTR ");
 
9241
        destoffset = decode_rm10_address(rl);
 
9242
        DECODE_PRINTF(",CL\n");
 
9243
        destval = fetch_data_byte(destoffset);
 
9244
        TRACE_AND_STEP();
 
9245
        destval = (*opcD0_byte_operation[rh]) (destval, amt);
 
9246
        store_data_byte(destoffset, destval);
 
9247
        break;
 
9248
    case 3:                     /* register to register */
 
9249
        destreg = DECODE_RM_BYTE_REGISTER(rl);
 
9250
        DECODE_PRINTF(",CL\n");
 
9251
        TRACE_AND_STEP();
 
9252
        destval = (*opcD0_byte_operation[rh]) (*destreg, amt);
 
9253
        *destreg = destval;
 
9254
        break;
 
9255
    }
 
9256
    DECODE_CLEAR_SEGOVR();
 
9257
    END_OF_INSTR();
 
9258
}
 
9259
 
 
9260
/****************************************************************************
 
9261
REMARKS:
 
9262
Handles opcode 0xd3
 
9263
****************************************************************************/
 
9264
static void x86emuOp_opcD3_word_RM_CL(u8 X86EMU_UNUSED(op1))
 
9265
{
 
9266
    int mod, rl, rh;
 
9267
    uint destoffset;
 
9268
    u8 amt;
 
9269
 
 
9270
    /*
 
9271
     * Yet another weirdo special case instruction format.  Part of
 
9272
     * the opcode held below in "RH".  Doubly nested case would
 
9273
     * result, except that the decoded instruction
 
9274
     */
 
9275
    START_OF_INSTR();
 
9276
    FETCH_DECODE_MODRM(mod, rh, rl);
 
9277
#ifdef DEBUG
 
9278
    if (DEBUG_DECODE()) {
 
9279
        /* XXX DECODE_PRINTF may be changed to something more
 
9280
           general, so that it is important to leave the strings
 
9281
           in the same format, even though the result is that the 
 
9282
           above test is done twice. */
 
9283
        switch (rh) {
 
9284
        case 0:
 
9285
            DECODE_PRINTF("ROL\t");
 
9286
            break;
 
9287
        case 1:
 
9288
            DECODE_PRINTF("ROR\t");
 
9289
            break;
 
9290
        case 2:
 
9291
            DECODE_PRINTF("RCL\t");
 
9292
            break;
 
9293
        case 3:
 
9294
            DECODE_PRINTF("RCR\t");
 
9295
            break;
 
9296
        case 4:
 
9297
            DECODE_PRINTF("SHL\t");
 
9298
            break;
 
9299
        case 5:
 
9300
            DECODE_PRINTF("SHR\t");
 
9301
            break;
 
9302
        case 6:
 
9303
            DECODE_PRINTF("SAL\t");
 
9304
            break;
 
9305
        case 7:
 
9306
            DECODE_PRINTF("SAR\t");
 
9307
            break;
 
9308
        }
 
9309
    }
 
9310
#endif
 
9311
    /* know operation, decode the mod byte to find the addressing
 
9312
       mode. */
 
9313
    amt = M.x86.R_CL;
 
9314
    switch (mod) {
 
9315
    case 0:
 
9316
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
9317
            u32 destval;
 
9318
 
 
9319
            DECODE_PRINTF("DWORD PTR ");
 
9320
            destoffset = decode_rm00_address(rl);
 
9321
            DECODE_PRINTF(",CL\n");
 
9322
            destval = fetch_data_long(destoffset);
 
9323
            TRACE_AND_STEP();
 
9324
            destval = (*opcD1_long_operation[rh]) (destval, amt);
 
9325
            store_data_long(destoffset, destval);
 
9326
        } else {
 
9327
            u16 destval;
 
9328
 
 
9329
            DECODE_PRINTF("WORD PTR ");
 
9330
            destoffset = decode_rm00_address(rl);
 
9331
            DECODE_PRINTF(",CL\n");
 
9332
            destval = fetch_data_word(destoffset);
 
9333
            TRACE_AND_STEP();
 
9334
            destval = (*opcD1_word_operation[rh]) (destval, amt);
 
9335
            store_data_word(destoffset, destval);
 
9336
        }
 
9337
        break;
 
9338
    case 1:
 
9339
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
9340
            u32 destval;
 
9341
 
 
9342
            DECODE_PRINTF("DWORD PTR ");
 
9343
            destoffset = decode_rm01_address(rl);
 
9344
            DECODE_PRINTF(",CL\n");
 
9345
            destval = fetch_data_long(destoffset);
 
9346
            TRACE_AND_STEP();
 
9347
            destval = (*opcD1_long_operation[rh]) (destval, amt);
 
9348
            store_data_long(destoffset, destval);
 
9349
        } else {
 
9350
            u16 destval;
 
9351
 
 
9352
            DECODE_PRINTF("WORD PTR ");
 
9353
            destoffset = decode_rm01_address(rl);
 
9354
            DECODE_PRINTF(",CL\n");
 
9355
            destval = fetch_data_word(destoffset);
 
9356
            TRACE_AND_STEP();
 
9357
            destval = (*opcD1_word_operation[rh]) (destval, amt);
 
9358
            store_data_word(destoffset, destval);
 
9359
        }
 
9360
        break;
 
9361
    case 2:
 
9362
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
9363
            u32 destval;
 
9364
 
 
9365
            DECODE_PRINTF("DWORD PTR ");
 
9366
            destoffset = decode_rm10_address(rl);
 
9367
            DECODE_PRINTF(",CL\n");
 
9368
            destval = fetch_data_long(destoffset);
 
9369
            TRACE_AND_STEP();
 
9370
            destval = (*opcD1_long_operation[rh]) (destval, amt);
 
9371
            store_data_long(destoffset, destval);
 
9372
        } else {
 
9373
            u16 destval;
 
9374
 
 
9375
            DECODE_PRINTF("WORD PTR ");
 
9376
            destoffset = decode_rm10_address(rl);
 
9377
            DECODE_PRINTF(",CL\n");
 
9378
            destval = fetch_data_word(destoffset);
 
9379
            TRACE_AND_STEP();
 
9380
            destval = (*opcD1_word_operation[rh]) (destval, amt);
 
9381
            store_data_word(destoffset, destval);
 
9382
        }
 
9383
        break;
 
9384
    case 3:                     /* register to register */
 
9385
        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
9386
            u32 *destreg;
 
9387
 
 
9388
            destreg = DECODE_RM_LONG_REGISTER(rl);
 
9389
            DECODE_PRINTF(",CL\n");
 
9390
            TRACE_AND_STEP();
 
9391
            *destreg = (*opcD1_long_operation[rh]) (*destreg, amt);
 
9392
        } else {
 
9393
            u16 *destreg;
 
9394
 
 
9395
            destreg = DECODE_RM_WORD_REGISTER(rl);
 
9396
            DECODE_PRINTF(",CL\n");
 
9397
            TRACE_AND_STEP();
 
9398
            *destreg = (*opcD1_word_operation[rh]) (*destreg, amt);
 
9399
        }
 
9400
        break;
 
9401
    }
 
9402
    DECODE_CLEAR_SEGOVR();
 
9403
    END_OF_INSTR();
 
9404
}
 
9405
 
 
9406
/****************************************************************************
 
9407
REMARKS:
 
9408
Handles opcode 0xd4
 
9409
****************************************************************************/
 
9410
static void x86emuOp_aam(u8 X86EMU_UNUSED(op1))
 
9411
{
 
9412
    u8 a;
 
9413
 
 
9414
    START_OF_INSTR();
 
9415
    DECODE_PRINTF("AAM\n");
 
9416
    a = fetch_byte_imm();      /* this is a stupid encoding. */
 
9417
    if (a != 10) {
 
9418
        /* fix: add base decoding
 
9419
           aam_word(u8 val, int base a) */
 
9420
        DECODE_PRINTF("ERROR DECODING AAM\n");
 
9421
        TRACE_REGS();
 
9422
        HALT_SYS();
 
9423
    }
 
9424
    TRACE_AND_STEP();
 
9425
    /* note the type change here --- returning AL and AH in AX. */
 
9426
    M.x86.R_AX = aam_word(M.x86.R_AL);
 
9427
    DECODE_CLEAR_SEGOVR();
 
9428
    END_OF_INSTR();
 
9429
}
 
9430
 
 
9431
/****************************************************************************
 
9432
REMARKS:
 
9433
Handles opcode 0xd5
 
9434
****************************************************************************/
 
9435
static void x86emuOp_aad(u8 X86EMU_UNUSED(op1))
 
9436
{
 
9437
    u8 a;
 
9438
 
 
9439
    START_OF_INSTR();
 
9440
    DECODE_PRINTF("AAD\n");
 
9441
    a = fetch_byte_imm();
 
9442
    if (a != 10) {
 
9443
        /* fix: add base decoding
 
9444
           aad_word(u16 val, int base a) */
 
9445
        DECODE_PRINTF("ERROR DECODING AAM\n");
 
9446
        TRACE_REGS();
 
9447
        HALT_SYS();
 
9448
    }
 
9449
    TRACE_AND_STEP();
 
9450
    M.x86.R_AX = aad_word(M.x86.R_AX);
 
9451
    DECODE_CLEAR_SEGOVR();
 
9452
    END_OF_INSTR();
 
9453
}
 
9454
 
 
9455
/* opcode 0xd6 ILLEGAL OPCODE */
 
9456
 
 
9457
/****************************************************************************
 
9458
REMARKS:
 
9459
Handles opcode 0xd7
 
9460
****************************************************************************/
 
9461
static void x86emuOp_xlat(u8 X86EMU_UNUSED(op1))
 
9462
{
 
9463
    u16 addr;
 
9464
 
 
9465
    START_OF_INSTR();
 
9466
    DECODE_PRINTF("XLAT\n");
 
9467
    TRACE_AND_STEP();
 
9468
        addr = (u16)(M.x86.R_BX + (u8)M.x86.R_AL);
 
9469
    M.x86.R_AL = fetch_data_byte(addr);
 
9470
    DECODE_CLEAR_SEGOVR();
 
9471
    END_OF_INSTR();
 
9472
}
 
9473
 
 
9474
/* instuctions  D8 .. DF are in i87_ops.c */
 
9475
 
 
9476
/****************************************************************************
 
9477
REMARKS:
 
9478
Handles opcode 0xe0
 
9479
****************************************************************************/
 
9480
static void x86emuOp_loopne(u8 X86EMU_UNUSED(op1))
 
9481
{
 
9482
    s16 ip;
 
9483
 
 
9484
    START_OF_INSTR();
 
9485
    DECODE_PRINTF("LOOPNE\t");
 
9486
    ip = (s8) fetch_byte_imm();
 
9487
    ip += (s16) M.x86.R_IP;
 
9488
    DECODE_PRINTF2("%04x\n", ip);
 
9489
    TRACE_AND_STEP();
 
9490
    M.x86.R_CX -= 1;
 
9491
    if (M.x86.R_CX != 0 && !ACCESS_FLAG(F_ZF))      /* CX != 0 and !ZF */
 
9492
        M.x86.R_IP = ip;
 
9493
    DECODE_CLEAR_SEGOVR();
 
9494
    END_OF_INSTR();
 
9495
}
 
9496
 
 
9497
/****************************************************************************
 
9498
REMARKS:
 
9499
Handles opcode 0xe1
 
9500
****************************************************************************/
 
9501
static void x86emuOp_loope(u8 X86EMU_UNUSED(op1))
 
9502
{
 
9503
    s16 ip;
 
9504
 
 
9505
    START_OF_INSTR();
 
9506
    DECODE_PRINTF("LOOPE\t");
 
9507
    ip = (s8) fetch_byte_imm();
 
9508
    ip += (s16) M.x86.R_IP;
 
9509
    DECODE_PRINTF2("%04x\n", ip);
 
9510
    TRACE_AND_STEP();
 
9511
    M.x86.R_CX -= 1;
 
9512
    if (M.x86.R_CX != 0 && ACCESS_FLAG(F_ZF))       /* CX != 0 and ZF */
 
9513
        M.x86.R_IP = ip;
 
9514
    DECODE_CLEAR_SEGOVR();
 
9515
    END_OF_INSTR();
 
9516
}
 
9517
 
 
9518
/****************************************************************************
 
9519
REMARKS:
 
9520
Handles opcode 0xe2
 
9521
****************************************************************************/
 
9522
static void x86emuOp_loop(u8 X86EMU_UNUSED(op1))
 
9523
{
 
9524
    s16 ip;
 
9525
 
 
9526
    START_OF_INSTR();
 
9527
    DECODE_PRINTF("LOOP\t");
 
9528
    ip = (s8) fetch_byte_imm();
 
9529
    ip += (s16) M.x86.R_IP;
 
9530
    DECODE_PRINTF2("%04x\n", ip);
 
9531
    TRACE_AND_STEP();
 
9532
    M.x86.R_CX -= 1;
 
9533
    if (M.x86.R_CX != 0)
 
9534
        M.x86.R_IP = ip;
 
9535
    DECODE_CLEAR_SEGOVR();
 
9536
    END_OF_INSTR();
 
9537
}
 
9538
 
 
9539
/****************************************************************************
 
9540
REMARKS:
 
9541
Handles opcode 0xe3
 
9542
****************************************************************************/
 
9543
static void x86emuOp_jcxz(u8 X86EMU_UNUSED(op1))
 
9544
{
 
9545
    u16 target;
 
9546
    s8  offset;
 
9547
 
 
9548
    /* jump to byte offset if overflow flag is set */
 
9549
    START_OF_INSTR();
 
9550
    DECODE_PRINTF("JCXZ\t");
 
9551
    offset = (s8)fetch_byte_imm();
 
9552
    target = (u16)(M.x86.R_IP + offset);
 
9553
    DECODE_PRINTF2("%x\n", target);
 
9554
    TRACE_AND_STEP();
 
9555
    if (M.x86.R_CX == 0)
 
9556
        M.x86.R_IP = target;
 
9557
    DECODE_CLEAR_SEGOVR();
 
9558
    END_OF_INSTR();
 
9559
}
 
9560
 
 
9561
/****************************************************************************
 
9562
REMARKS:
 
9563
Handles opcode 0xe4
 
9564
****************************************************************************/
 
9565
static void x86emuOp_in_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
 
9566
{
 
9567
    u8 port;
 
9568
 
 
9569
    START_OF_INSTR();
 
9570
    DECODE_PRINTF("IN\t");
 
9571
        port = (u8) fetch_byte_imm();
 
9572
    DECODE_PRINTF2("%x,AL\n", port);
 
9573
    TRACE_AND_STEP();
 
9574
    M.x86.R_AL = (*sys_inb)(port);
 
9575
    DECODE_CLEAR_SEGOVR();
 
9576
    END_OF_INSTR();
 
9577
}
 
9578
 
 
9579
/****************************************************************************
 
9580
REMARKS:
 
9581
Handles opcode 0xe5
 
9582
****************************************************************************/
 
9583
static void x86emuOp_in_word_AX_IMM(u8 X86EMU_UNUSED(op1))
 
9584
{
 
9585
    u8 port;
 
9586
 
 
9587
    START_OF_INSTR();
 
9588
    DECODE_PRINTF("IN\t");
 
9589
        port = (u8) fetch_byte_imm();
 
9590
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
9591
        DECODE_PRINTF2("EAX,%x\n", port);
 
9592
    } else {
 
9593
        DECODE_PRINTF2("AX,%x\n", port);
 
9594
    }
 
9595
    TRACE_AND_STEP();
 
9596
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
9597
        M.x86.R_EAX = (*sys_inl)(port);
 
9598
    } else {
 
9599
        M.x86.R_AX = (*sys_inw)(port);
 
9600
    }
 
9601
    DECODE_CLEAR_SEGOVR();
 
9602
    END_OF_INSTR();
 
9603
}
 
9604
 
 
9605
/****************************************************************************
 
9606
REMARKS:
 
9607
Handles opcode 0xe6
 
9608
****************************************************************************/
 
9609
static void x86emuOp_out_byte_IMM_AL(u8 X86EMU_UNUSED(op1))
 
9610
{
 
9611
    u8 port;
 
9612
 
 
9613
    START_OF_INSTR();
 
9614
    DECODE_PRINTF("OUT\t");
 
9615
        port = (u8) fetch_byte_imm();
 
9616
    DECODE_PRINTF2("%x,AL\n", port);
 
9617
    TRACE_AND_STEP();
 
9618
    (*sys_outb)(port, M.x86.R_AL);
 
9619
    DECODE_CLEAR_SEGOVR();
 
9620
    END_OF_INSTR();
 
9621
}
 
9622
 
 
9623
/****************************************************************************
 
9624
REMARKS:
 
9625
Handles opcode 0xe7
 
9626
****************************************************************************/
 
9627
static void x86emuOp_out_word_IMM_AX(u8 X86EMU_UNUSED(op1))
 
9628
{
 
9629
    u8 port;
 
9630
 
 
9631
    START_OF_INSTR();
 
9632
    DECODE_PRINTF("OUT\t");
 
9633
        port = (u8) fetch_byte_imm();
 
9634
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
9635
        DECODE_PRINTF2("%x,EAX\n", port);
 
9636
    } else {
 
9637
        DECODE_PRINTF2("%x,AX\n", port);
 
9638
    }
 
9639
    TRACE_AND_STEP();
 
9640
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
9641
        (*sys_outl)(port, M.x86.R_EAX);
 
9642
    } else {
 
9643
        (*sys_outw)(port, M.x86.R_AX);
 
9644
    }
 
9645
    DECODE_CLEAR_SEGOVR();
 
9646
    END_OF_INSTR();
 
9647
}
 
9648
 
 
9649
/****************************************************************************
 
9650
REMARKS:
 
9651
Handles opcode 0xe8
 
9652
****************************************************************************/
 
9653
static void x86emuOp_call_near_IMM(u8 X86EMU_UNUSED(op1))
 
9654
{
 
9655
    s16 ip;
 
9656
 
 
9657
    START_OF_INSTR();
 
9658
        DECODE_PRINTF("CALL\t");
 
9659
        ip = (s16) fetch_word_imm();
 
9660
        ip += (s16) M.x86.R_IP;    /* CHECK SIGN */
 
9661
        DECODE_PRINTF2("%04x\n", (u16)ip);
 
9662
        CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, M.x86.R_CS, ip, "");
 
9663
    TRACE_AND_STEP();
 
9664
    push_word(M.x86.R_IP);
 
9665
    M.x86.R_IP = ip;
 
9666
    DECODE_CLEAR_SEGOVR();
 
9667
    END_OF_INSTR();
 
9668
}
 
9669
 
 
9670
/****************************************************************************
 
9671
REMARKS:
 
9672
Handles opcode 0xe9
 
9673
****************************************************************************/
 
9674
static void x86emuOp_jump_near_IMM(u8 X86EMU_UNUSED(op1))
 
9675
{
 
9676
    int ip;
 
9677
 
 
9678
    START_OF_INSTR();
 
9679
    DECODE_PRINTF("JMP\t");
 
9680
    ip = (s16)fetch_word_imm();
 
9681
    ip += (s16)M.x86.R_IP;
 
9682
    DECODE_PRINTF2("%04x\n", (u16)ip);
 
9683
    TRACE_AND_STEP();
 
9684
    M.x86.R_IP = (u16)ip;
 
9685
    DECODE_CLEAR_SEGOVR();
 
9686
    END_OF_INSTR();
 
9687
}
 
9688
 
 
9689
/****************************************************************************
 
9690
REMARKS:
 
9691
Handles opcode 0xea
 
9692
****************************************************************************/
 
9693
static void x86emuOp_jump_far_IMM(u8 X86EMU_UNUSED(op1))
 
9694
{
 
9695
    u16 cs, ip;
 
9696
 
 
9697
    START_OF_INSTR();
 
9698
    DECODE_PRINTF("JMP\tFAR ");
 
9699
    ip = fetch_word_imm();
 
9700
    cs = fetch_word_imm();
 
9701
    DECODE_PRINTF2("%04x:", cs);
 
9702
    DECODE_PRINTF2("%04x\n", ip);
 
9703
    TRACE_AND_STEP();
 
9704
    M.x86.R_IP = ip;
 
9705
    M.x86.R_CS = cs;
 
9706
    DECODE_CLEAR_SEGOVR();
 
9707
    END_OF_INSTR();
 
9708
}
 
9709
 
 
9710
/****************************************************************************
 
9711
REMARKS:
 
9712
Handles opcode 0xeb
 
9713
****************************************************************************/
 
9714
static void x86emuOp_jump_byte_IMM(u8 X86EMU_UNUSED(op1))
 
9715
{
 
9716
    u16 target;
 
9717
    s8 offset;
 
9718
 
 
9719
    START_OF_INSTR();
 
9720
    DECODE_PRINTF("JMP\t");
 
9721
    offset = (s8)fetch_byte_imm();
 
9722
    target = (u16)(M.x86.R_IP + offset);
 
9723
    DECODE_PRINTF2("%x\n", target);
 
9724
    TRACE_AND_STEP();
 
9725
    M.x86.R_IP = target;
 
9726
    DECODE_CLEAR_SEGOVR();
 
9727
    END_OF_INSTR();
 
9728
}
 
9729
 
 
9730
/****************************************************************************
 
9731
REMARKS:
 
9732
Handles opcode 0xec
 
9733
****************************************************************************/
 
9734
static void x86emuOp_in_byte_AL_DX(u8 X86EMU_UNUSED(op1))
 
9735
{
 
9736
    START_OF_INSTR();
 
9737
    DECODE_PRINTF("IN\tAL,DX\n");
 
9738
    TRACE_AND_STEP();
 
9739
    M.x86.R_AL = (*sys_inb)(M.x86.R_DX);
 
9740
    DECODE_CLEAR_SEGOVR();
 
9741
    END_OF_INSTR();
 
9742
}
 
9743
 
 
9744
/****************************************************************************
 
9745
REMARKS:
 
9746
Handles opcode 0xed
 
9747
****************************************************************************/
 
9748
static void x86emuOp_in_word_AX_DX(u8 X86EMU_UNUSED(op1))
 
9749
{
 
9750
    START_OF_INSTR();
 
9751
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
9752
        DECODE_PRINTF("IN\tEAX,DX\n");
 
9753
    } else {
 
9754
        DECODE_PRINTF("IN\tAX,DX\n");
 
9755
    }
 
9756
    TRACE_AND_STEP();
 
9757
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
9758
        M.x86.R_EAX = (*sys_inl)(M.x86.R_DX);
 
9759
    } else {
 
9760
        M.x86.R_AX = (*sys_inw)(M.x86.R_DX);
 
9761
    }
 
9762
    DECODE_CLEAR_SEGOVR();
 
9763
    END_OF_INSTR();
 
9764
}
 
9765
 
 
9766
/****************************************************************************
 
9767
REMARKS:
 
9768
Handles opcode 0xee
 
9769
****************************************************************************/
 
9770
static void x86emuOp_out_byte_DX_AL(u8 X86EMU_UNUSED(op1))
 
9771
{
 
9772
    START_OF_INSTR();
 
9773
    DECODE_PRINTF("OUT\tDX,AL\n");
 
9774
    TRACE_AND_STEP();
 
9775
    (*sys_outb)(M.x86.R_DX, M.x86.R_AL);
 
9776
    DECODE_CLEAR_SEGOVR();
 
9777
    END_OF_INSTR();
 
9778
}
 
9779
 
 
9780
/****************************************************************************
 
9781
REMARKS:
 
9782
Handles opcode 0xef
 
9783
****************************************************************************/
 
9784
static void x86emuOp_out_word_DX_AX(u8 X86EMU_UNUSED(op1))
 
9785
{
 
9786
    START_OF_INSTR();
 
9787
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
9788
        DECODE_PRINTF("OUT\tDX,EAX\n");
 
9789
    } else {
 
9790
        DECODE_PRINTF("OUT\tDX,AX\n");
 
9791
    }
 
9792
    TRACE_AND_STEP();
 
9793
    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
9794
        (*sys_outl)(M.x86.R_DX, M.x86.R_EAX);
 
9795
    } else {
 
9796
        (*sys_outw)(M.x86.R_DX, M.x86.R_AX);
 
9797
    }
 
9798
    DECODE_CLEAR_SEGOVR();
 
9799
    END_OF_INSTR();
 
9800
}
 
9801
 
 
9802
/****************************************************************************
 
9803
REMARKS:
 
9804
Handles opcode 0xf0
 
9805
****************************************************************************/
 
9806
static void x86emuOp_lock(u8 X86EMU_UNUSED(op1))
 
9807
{
 
9808
    START_OF_INSTR();
 
9809
    DECODE_PRINTF("LOCK:\n");
 
9810
    TRACE_AND_STEP();
 
9811
    DECODE_CLEAR_SEGOVR();
 
9812
    END_OF_INSTR();
 
9813
}
 
9814
 
 
9815
/*opcode 0xf1 ILLEGAL OPERATION */
 
9816
 
 
9817
/****************************************************************************
 
9818
REMARKS:
 
9819
Handles opcode 0xf2
 
9820
****************************************************************************/
 
9821
static void x86emuOp_repne(u8 X86EMU_UNUSED(op1))
 
9822
{
 
9823
    START_OF_INSTR();
 
9824
    DECODE_PRINTF("REPNE\n");
 
9825
    TRACE_AND_STEP();
 
9826
    M.x86.mode |= SYSMODE_PREFIX_REPNE;
 
9827
    DECODE_CLEAR_SEGOVR();
 
9828
    END_OF_INSTR();
 
9829
}
 
9830
 
 
9831
/****************************************************************************
 
9832
REMARKS:
 
9833
Handles opcode 0xf3
 
9834
****************************************************************************/
 
9835
static void x86emuOp_repe(u8 X86EMU_UNUSED(op1))
 
9836
{
 
9837
    START_OF_INSTR();
 
9838
    DECODE_PRINTF("REPE\n");
 
9839
    TRACE_AND_STEP();
 
9840
    M.x86.mode |= SYSMODE_PREFIX_REPE;
 
9841
    DECODE_CLEAR_SEGOVR();
 
9842
    END_OF_INSTR();
 
9843
}
 
9844
 
 
9845
/****************************************************************************
 
9846
REMARKS:
 
9847
Handles opcode 0xf4
 
9848
****************************************************************************/
 
9849
static void x86emuOp_halt(u8 X86EMU_UNUSED(op1))
 
9850
{
 
9851
    START_OF_INSTR();
 
9852
    DECODE_PRINTF("HALT\n");
 
9853
    TRACE_AND_STEP();
 
9854
    HALT_SYS();
 
9855
    DECODE_CLEAR_SEGOVR();
 
9856
    END_OF_INSTR();
 
9857
}
 
9858
 
 
9859
/****************************************************************************
 
9860
REMARKS:
 
9861
Handles opcode 0xf5
 
9862
****************************************************************************/
 
9863
static void x86emuOp_cmc(u8 X86EMU_UNUSED(op1))
 
9864
{
 
9865
    /* complement the carry flag. */
 
9866
    START_OF_INSTR();
 
9867
    DECODE_PRINTF("CMC\n");
 
9868
    TRACE_AND_STEP();
 
9869
    TOGGLE_FLAG(F_CF);
 
9870
    DECODE_CLEAR_SEGOVR();
 
9871
    END_OF_INSTR();
 
9872
}
 
9873
 
 
9874
/****************************************************************************
 
9875
REMARKS:
 
9876
Handles opcode 0xf6
 
9877
****************************************************************************/
 
9878
static void x86emuOp_opcF6_byte_RM(u8 X86EMU_UNUSED(op1))
 
9879
{
 
9880
    int mod, rl, rh;
 
9881
    u8 *destreg;
 
9882
    uint destoffset;
 
9883
    u8 destval, srcval;
 
9884
 
 
9885
    /* long, drawn out code follows.  Double switch for a total
 
9886
       of 32 cases.  */
 
9887
    START_OF_INSTR();
 
9888
    FETCH_DECODE_MODRM(mod, rh, rl);
 
9889
    switch (mod) {
 
9890
    case 0:                     /* mod=00 */
 
9891
        switch (rh) {
 
9892
        case 0:         /* test byte imm */
 
9893
            DECODE_PRINTF("TEST\tBYTE PTR ");
 
9894
            destoffset = decode_rm00_address(rl);
 
9895
            DECODE_PRINTF(",");
 
9896
            srcval = fetch_byte_imm();
 
9897
            DECODE_PRINTF2("%02x\n", srcval);
 
9898
            destval = fetch_data_byte(destoffset);
 
9899
            TRACE_AND_STEP();
 
9900
            test_byte(destval, srcval);
 
9901
            break;
 
9902
        case 1:
 
9903
            DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
 
9904
            HALT_SYS();
 
9905
            break;
 
9906
        case 2:
 
9907
            DECODE_PRINTF("NOT\tBYTE PTR ");
 
9908
            destoffset = decode_rm00_address(rl);
 
9909
            DECODE_PRINTF("\n");
 
9910
            destval = fetch_data_byte(destoffset);
 
9911
            TRACE_AND_STEP();
 
9912
            destval = not_byte(destval);
 
9913
            store_data_byte(destoffset, destval);
 
9914
            break;
 
9915
        case 3:
 
9916
            DECODE_PRINTF("NEG\tBYTE PTR ");
 
9917
            destoffset = decode_rm00_address(rl);
 
9918
            DECODE_PRINTF("\n");
 
9919
            destval = fetch_data_byte(destoffset);
 
9920
            TRACE_AND_STEP();
 
9921
            destval = neg_byte(destval);
 
9922
            store_data_byte(destoffset, destval);
 
9923
            break;
 
9924
        case 4:
 
9925
            DECODE_PRINTF("MUL\tBYTE PTR ");
 
9926
            destoffset = decode_rm00_address(rl);
 
9927
            DECODE_PRINTF("\n");
 
9928
            destval = fetch_data_byte(destoffset);
 
9929
            TRACE_AND_STEP();
 
9930
            mul_byte(destval);
 
9931
            break;
 
9932
        case 5:
 
9933
            DECODE_PRINTF("IMUL\tBYTE PTR ");
 
9934
            destoffset = decode_rm00_address(rl);
 
9935
            DECODE_PRINTF("\n");
 
9936
            destval = fetch_data_byte(destoffset);
 
9937
            TRACE_AND_STEP();
 
9938
            imul_byte(destval);
 
9939
            break;
 
9940
        case 6:
 
9941
            DECODE_PRINTF("DIV\tBYTE PTR ");
 
9942
            destoffset = decode_rm00_address(rl);
 
9943
            DECODE_PRINTF("\n");
 
9944
            destval = fetch_data_byte(destoffset);
 
9945
            TRACE_AND_STEP();
 
9946
            div_byte(destval);
 
9947
            break;
 
9948
        case 7:
 
9949
            DECODE_PRINTF("IDIV\tBYTE PTR ");
 
9950
            destoffset = decode_rm00_address(rl);
 
9951
            DECODE_PRINTF("\n");
 
9952
            destval = fetch_data_byte(destoffset);
 
9953
            TRACE_AND_STEP();
 
9954
            idiv_byte(destval);
 
9955
            break;
 
9956
        }
 
9957
        break;                  /* end mod==00 */
 
9958
    case 1:                     /* mod=01 */
 
9959
        switch (rh) {
 
9960
        case 0:         /* test byte imm */
 
9961
            DECODE_PRINTF("TEST\tBYTE PTR ");
 
9962
            destoffset = decode_rm01_address(rl);
 
9963
            DECODE_PRINTF(",");
 
9964
            srcval = fetch_byte_imm();
 
9965
            DECODE_PRINTF2("%02x\n", srcval);
 
9966
            destval = fetch_data_byte(destoffset);
 
9967
            TRACE_AND_STEP();
 
9968
            test_byte(destval, srcval);
 
9969
            break;
 
9970
        case 1:
 
9971
            DECODE_PRINTF("ILLEGAL OP MOD=01 RH=01 OP=F6\n");
 
9972
            HALT_SYS();
 
9973
            break;
 
9974
        case 2:
 
9975
            DECODE_PRINTF("NOT\tBYTE PTR ");
 
9976
            destoffset = decode_rm01_address(rl);
 
9977
            DECODE_PRINTF("\n");
 
9978
            destval = fetch_data_byte(destoffset);
 
9979
            TRACE_AND_STEP();
 
9980
            destval = not_byte(destval);
 
9981
            store_data_byte(destoffset, destval);
 
9982
            break;
 
9983
        case 3:
 
9984
            DECODE_PRINTF("NEG\tBYTE PTR ");
 
9985
            destoffset = decode_rm01_address(rl);
 
9986
            DECODE_PRINTF("\n");
 
9987
            destval = fetch_data_byte(destoffset);
 
9988
            TRACE_AND_STEP();
 
9989
            destval = neg_byte(destval);
 
9990
            store_data_byte(destoffset, destval);
 
9991
            break;
 
9992
        case 4:
 
9993
            DECODE_PRINTF("MUL\tBYTE PTR ");
 
9994
            destoffset = decode_rm01_address(rl);
 
9995
            DECODE_PRINTF("\n");
 
9996
            destval = fetch_data_byte(destoffset);
 
9997
            TRACE_AND_STEP();
 
9998
            mul_byte(destval);
 
9999
            break;
 
10000
        case 5:
 
10001
            DECODE_PRINTF("IMUL\tBYTE PTR ");
 
10002
            destoffset = decode_rm01_address(rl);
 
10003
            DECODE_PRINTF("\n");
 
10004
            destval = fetch_data_byte(destoffset);
 
10005
            TRACE_AND_STEP();
 
10006
            imul_byte(destval);
 
10007
            break;
 
10008
        case 6:
 
10009
            DECODE_PRINTF("DIV\tBYTE PTR ");
 
10010
            destoffset = decode_rm01_address(rl);
 
10011
            DECODE_PRINTF("\n");
 
10012
            destval = fetch_data_byte(destoffset);
 
10013
            TRACE_AND_STEP();
 
10014
            div_byte(destval);
 
10015
            break;
 
10016
        case 7:
 
10017
            DECODE_PRINTF("IDIV\tBYTE PTR ");
 
10018
            destoffset = decode_rm01_address(rl);
 
10019
            DECODE_PRINTF("\n");
 
10020
            destval = fetch_data_byte(destoffset);
 
10021
            TRACE_AND_STEP();
 
10022
            idiv_byte(destval);
 
10023
            break;
 
10024
        }
 
10025
        break;                  /* end mod==01 */
 
10026
    case 2:                     /* mod=10 */
 
10027
        switch (rh) {
 
10028
        case 0:         /* test byte imm */
 
10029
            DECODE_PRINTF("TEST\tBYTE PTR ");
 
10030
            destoffset = decode_rm10_address(rl);
 
10031
            DECODE_PRINTF(",");
 
10032
            srcval = fetch_byte_imm();
 
10033
            DECODE_PRINTF2("%02x\n", srcval);
 
10034
            destval = fetch_data_byte(destoffset);
 
10035
            TRACE_AND_STEP();
 
10036
            test_byte(destval, srcval);
 
10037
            break;
 
10038
        case 1:
 
10039
            DECODE_PRINTF("ILLEGAL OP MOD=10 RH=01 OP=F6\n");
 
10040
            HALT_SYS();
 
10041
            break;
 
10042
        case 2:
 
10043
            DECODE_PRINTF("NOT\tBYTE PTR ");
 
10044
            destoffset = decode_rm10_address(rl);
 
10045
            DECODE_PRINTF("\n");
 
10046
            destval = fetch_data_byte(destoffset);
 
10047
            TRACE_AND_STEP();
 
10048
            destval = not_byte(destval);
 
10049
            store_data_byte(destoffset, destval);
 
10050
            break;
 
10051
        case 3:
 
10052
            DECODE_PRINTF("NEG\tBYTE PTR ");
 
10053
            destoffset = decode_rm10_address(rl);
 
10054
            DECODE_PRINTF("\n");
 
10055
            destval = fetch_data_byte(destoffset);
 
10056
            TRACE_AND_STEP();
 
10057
            destval = neg_byte(destval);
 
10058
            store_data_byte(destoffset, destval);
 
10059
            break;
 
10060
        case 4:
 
10061
            DECODE_PRINTF("MUL\tBYTE PTR ");
 
10062
            destoffset = decode_rm10_address(rl);
 
10063
            DECODE_PRINTF("\n");
 
10064
            destval = fetch_data_byte(destoffset);
 
10065
            TRACE_AND_STEP();
 
10066
            mul_byte(destval);
 
10067
            break;
 
10068
        case 5:
 
10069
            DECODE_PRINTF("IMUL\tBYTE PTR ");
 
10070
            destoffset = decode_rm10_address(rl);
 
10071
            DECODE_PRINTF("\n");
 
10072
            destval = fetch_data_byte(destoffset);
 
10073
            TRACE_AND_STEP();
 
10074
            imul_byte(destval);
 
10075
            break;
 
10076
        case 6:
 
10077
            DECODE_PRINTF("DIV\tBYTE PTR ");
 
10078
            destoffset = decode_rm10_address(rl);
 
10079
            DECODE_PRINTF("\n");
 
10080
            destval = fetch_data_byte(destoffset);
 
10081
            TRACE_AND_STEP();
 
10082
            div_byte(destval);
 
10083
            break;
 
10084
        case 7:
 
10085
            DECODE_PRINTF("IDIV\tBYTE PTR ");
 
10086
            destoffset = decode_rm10_address(rl);
 
10087
            DECODE_PRINTF("\n");
 
10088
            destval = fetch_data_byte(destoffset);
 
10089
            TRACE_AND_STEP();
 
10090
            idiv_byte(destval);
 
10091
            break;
 
10092
        }
 
10093
        break;                  /* end mod==10 */
 
10094
    case 3:                     /* mod=11 */
 
10095
        switch (rh) {
 
10096
        case 0:         /* test byte imm */
 
10097
            DECODE_PRINTF("TEST\t");
 
10098
            destreg = DECODE_RM_BYTE_REGISTER(rl);
 
10099
            DECODE_PRINTF(",");
 
10100
            srcval = fetch_byte_imm();
 
10101
            DECODE_PRINTF2("%02x\n", srcval);
 
10102
            TRACE_AND_STEP();
 
10103
            test_byte(*destreg, srcval);
 
10104
            break;
 
10105
        case 1:
 
10106
            DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
 
10107
            HALT_SYS();
 
10108
            break;
 
10109
        case 2:
 
10110
            DECODE_PRINTF("NOT\t");
 
10111
            destreg = DECODE_RM_BYTE_REGISTER(rl);
 
10112
            DECODE_PRINTF("\n");
 
10113
            TRACE_AND_STEP();
 
10114
            *destreg = not_byte(*destreg);
 
10115
            break;
 
10116
        case 3:
 
10117
            DECODE_PRINTF("NEG\t");
 
10118
            destreg = DECODE_RM_BYTE_REGISTER(rl);
 
10119
            DECODE_PRINTF("\n");
 
10120
            TRACE_AND_STEP();
 
10121
            *destreg = neg_byte(*destreg);
 
10122
            break;
 
10123
        case 4:
 
10124
            DECODE_PRINTF("MUL\t");
 
10125
            destreg = DECODE_RM_BYTE_REGISTER(rl);
 
10126
            DECODE_PRINTF("\n");
 
10127
            TRACE_AND_STEP();
 
10128
            mul_byte(*destreg);      /*!!!  */
 
10129
            break;
 
10130
        case 5:
 
10131
            DECODE_PRINTF("IMUL\t");
 
10132
            destreg = DECODE_RM_BYTE_REGISTER(rl);
 
10133
            DECODE_PRINTF("\n");
 
10134
            TRACE_AND_STEP();
 
10135
            imul_byte(*destreg);
 
10136
            break;
 
10137
        case 6:
 
10138
            DECODE_PRINTF("DIV\t");
 
10139
            destreg = DECODE_RM_BYTE_REGISTER(rl);
 
10140
            DECODE_PRINTF("\n");
 
10141
            TRACE_AND_STEP();
 
10142
            div_byte(*destreg);
 
10143
            break;
 
10144
        case 7:
 
10145
            DECODE_PRINTF("IDIV\t");
 
10146
            destreg = DECODE_RM_BYTE_REGISTER(rl);
 
10147
            DECODE_PRINTF("\n");
 
10148
            TRACE_AND_STEP();
 
10149
            idiv_byte(*destreg);
 
10150
            break;
 
10151
        }
 
10152
        break;                  /* end mod==11 */
 
10153
    }
 
10154
    DECODE_CLEAR_SEGOVR();
 
10155
    END_OF_INSTR();
 
10156
}
 
10157
 
 
10158
/****************************************************************************
 
10159
REMARKS:
 
10160
Handles opcode 0xf7
 
10161
****************************************************************************/
 
10162
static void x86emuOp_opcF7_word_RM(u8 X86EMU_UNUSED(op1))
 
10163
{
 
10164
    int mod, rl, rh;
 
10165
    uint destoffset;
 
10166
 
 
10167
    /* long, drawn out code follows.  Double switch for a total
 
10168
       of 32 cases.  */
 
10169
    START_OF_INSTR();
 
10170
    FETCH_DECODE_MODRM(mod, rh, rl);
 
10171
    switch (mod) {
 
10172
    case 0:                     /* mod=00 */
 
10173
        switch (rh) {
 
10174
        case 0:         /* test word imm */
 
10175
            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
10176
                u32 destval,srcval;
 
10177
 
 
10178
                DECODE_PRINTF("TEST\tDWORD PTR ");
 
10179
                destoffset = decode_rm00_address(rl);
 
10180
                DECODE_PRINTF(",");
 
10181
                srcval = fetch_long_imm();
 
10182
                DECODE_PRINTF2("%x\n", srcval);
 
10183
                destval = fetch_data_long(destoffset);
 
10184
                TRACE_AND_STEP();
 
10185
                test_long(destval, srcval);
 
10186
            } else {
 
10187
                u16 destval,srcval;
 
10188
 
 
10189
                DECODE_PRINTF("TEST\tWORD PTR ");
 
10190
                destoffset = decode_rm00_address(rl);
 
10191
                DECODE_PRINTF(",");
 
10192
                srcval = fetch_word_imm();
 
10193
                DECODE_PRINTF2("%x\n", srcval);
 
10194
                destval = fetch_data_word(destoffset);
 
10195
                TRACE_AND_STEP();
 
10196
                test_word(destval, srcval);
 
10197
            }
 
10198
            break;
 
10199
        case 1:
 
10200
            DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F7\n");
 
10201
            HALT_SYS();
 
10202
            break;
 
10203
        case 2:
 
10204
            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
10205
                u32 destval;
 
10206
 
 
10207
                DECODE_PRINTF("NOT\tDWORD PTR ");
 
10208
                destoffset = decode_rm00_address(rl);
 
10209
                DECODE_PRINTF("\n");
 
10210
                destval = fetch_data_long(destoffset);
 
10211
                TRACE_AND_STEP();
 
10212
                destval = not_long(destval);
 
10213
                store_data_long(destoffset, destval);
 
10214
            } else {
 
10215
                u16 destval;
 
10216
 
 
10217
                DECODE_PRINTF("NOT\tWORD PTR ");
 
10218
                destoffset = decode_rm00_address(rl);
 
10219
                DECODE_PRINTF("\n");
 
10220
                destval = fetch_data_word(destoffset);
 
10221
                TRACE_AND_STEP();
 
10222
                destval = not_word(destval);
 
10223
                store_data_word(destoffset, destval);
 
10224
            }
 
10225
            break;
 
10226
        case 3:
 
10227
            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
10228
                u32 destval;
 
10229
 
 
10230
                DECODE_PRINTF("NEG\tDWORD PTR ");
 
10231
                destoffset = decode_rm00_address(rl);
 
10232
                DECODE_PRINTF("\n");
 
10233
                destval = fetch_data_long(destoffset);
 
10234
                TRACE_AND_STEP();
 
10235
                destval = neg_long(destval);
 
10236
                store_data_long(destoffset, destval);
 
10237
            } else {
 
10238
                u16 destval;
 
10239
 
 
10240
                DECODE_PRINTF("NEG\tWORD PTR ");
 
10241
                destoffset = decode_rm00_address(rl);
 
10242
                DECODE_PRINTF("\n");
 
10243
                destval = fetch_data_word(destoffset);
 
10244
                TRACE_AND_STEP();
 
10245
                destval = neg_word(destval);
 
10246
                store_data_word(destoffset, destval);
 
10247
            }
 
10248
            break;
 
10249
        case 4:
 
10250
            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
10251
                u32 destval;
 
10252
 
 
10253
                DECODE_PRINTF("MUL\tDWORD PTR ");
 
10254
                destoffset = decode_rm00_address(rl);
 
10255
                DECODE_PRINTF("\n");
 
10256
                destval = fetch_data_long(destoffset);
 
10257
                TRACE_AND_STEP();
 
10258
                mul_long(destval);
 
10259
            } else {
 
10260
                u16 destval;
 
10261
 
 
10262
                DECODE_PRINTF("MUL\tWORD PTR ");
 
10263
                destoffset = decode_rm00_address(rl);
 
10264
                DECODE_PRINTF("\n");
 
10265
                destval = fetch_data_word(destoffset);
 
10266
                TRACE_AND_STEP();
 
10267
                mul_word(destval);
 
10268
            }
 
10269
            break;
 
10270
        case 5:
 
10271
            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
10272
                u32 destval;
 
10273
 
 
10274
                DECODE_PRINTF("IMUL\tDWORD PTR ");
 
10275
                destoffset = decode_rm00_address(rl);
 
10276
                DECODE_PRINTF("\n");
 
10277
                destval = fetch_data_long(destoffset);
 
10278
                TRACE_AND_STEP();
 
10279
                imul_long(destval);
 
10280
            } else {
 
10281
                u16 destval;
 
10282
 
 
10283
                DECODE_PRINTF("IMUL\tWORD PTR ");
 
10284
                destoffset = decode_rm00_address(rl);
 
10285
                DECODE_PRINTF("\n");
 
10286
                destval = fetch_data_word(destoffset);
 
10287
                TRACE_AND_STEP();
 
10288
                imul_word(destval);
 
10289
            }
 
10290
            break;
 
10291
        case 6:
 
10292
            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
10293
                u32 destval;
 
10294
 
 
10295
                DECODE_PRINTF("DIV\tDWORD PTR ");
 
10296
                destoffset = decode_rm00_address(rl);
 
10297
                DECODE_PRINTF("\n");
 
10298
                destval = fetch_data_long(destoffset);
 
10299
                TRACE_AND_STEP();
 
10300
                div_long(destval);
 
10301
            } else {
 
10302
                u16 destval;
 
10303
 
 
10304
                DECODE_PRINTF("DIV\tWORD PTR ");
 
10305
                destoffset = decode_rm00_address(rl);
 
10306
                DECODE_PRINTF("\n");
 
10307
                destval = fetch_data_word(destoffset);
 
10308
                TRACE_AND_STEP();
 
10309
                div_word(destval);
 
10310
            }
 
10311
            break;
 
10312
        case 7:
 
10313
            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
10314
                u32 destval;
 
10315
 
 
10316
                DECODE_PRINTF("IDIV\tDWORD PTR ");
 
10317
                destoffset = decode_rm00_address(rl);
 
10318
                DECODE_PRINTF("\n");
 
10319
                destval = fetch_data_long(destoffset);
 
10320
                TRACE_AND_STEP();
 
10321
                idiv_long(destval);
 
10322
            } else {
 
10323
                u16 destval;
 
10324
 
 
10325
                DECODE_PRINTF("IDIV\tWORD PTR ");
 
10326
                destoffset = decode_rm00_address(rl);
 
10327
                DECODE_PRINTF("\n");
 
10328
                destval = fetch_data_word(destoffset);
 
10329
                TRACE_AND_STEP();
 
10330
                idiv_word(destval);
 
10331
            }
 
10332
            break;
 
10333
        }
 
10334
        break;                  /* end mod==00 */
 
10335
    case 1:                     /* mod=01 */
 
10336
        switch (rh) {
 
10337
        case 0:         /* test word imm */
 
10338
            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
10339
                u32 destval,srcval;
 
10340
 
 
10341
                DECODE_PRINTF("TEST\tDWORD PTR ");
 
10342
                destoffset = decode_rm01_address(rl);
 
10343
                DECODE_PRINTF(",");
 
10344
                srcval = fetch_long_imm();
 
10345
                DECODE_PRINTF2("%x\n", srcval);
 
10346
                destval = fetch_data_long(destoffset);
 
10347
                TRACE_AND_STEP();
 
10348
                test_long(destval, srcval);
 
10349
            } else {
 
10350
                u16 destval,srcval;
 
10351
 
 
10352
                DECODE_PRINTF("TEST\tWORD PTR ");
 
10353
                destoffset = decode_rm01_address(rl);
 
10354
                DECODE_PRINTF(",");
 
10355
                srcval = fetch_word_imm();
 
10356
                DECODE_PRINTF2("%x\n", srcval);
 
10357
                destval = fetch_data_word(destoffset);
 
10358
                TRACE_AND_STEP();
 
10359
                test_word(destval, srcval);
 
10360
            }
 
10361
            break;
 
10362
        case 1:
 
10363
            DECODE_PRINTF("ILLEGAL OP MOD=01 RH=01 OP=F6\n");
 
10364
            HALT_SYS();
 
10365
            break;
 
10366
        case 2:
 
10367
            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
10368
                u32 destval;
 
10369
 
 
10370
                DECODE_PRINTF("NOT\tDWORD PTR ");
 
10371
                destoffset = decode_rm01_address(rl);
 
10372
                DECODE_PRINTF("\n");
 
10373
                destval = fetch_data_long(destoffset);
 
10374
                TRACE_AND_STEP();
 
10375
                destval = not_long(destval);
 
10376
                store_data_long(destoffset, destval);
 
10377
            } else {
 
10378
                u16 destval;
 
10379
 
 
10380
                DECODE_PRINTF("NOT\tWORD PTR ");
 
10381
                destoffset = decode_rm01_address(rl);
 
10382
                DECODE_PRINTF("\n");
 
10383
                destval = fetch_data_word(destoffset);
 
10384
                TRACE_AND_STEP();
 
10385
                destval = not_word(destval);
 
10386
                store_data_word(destoffset, destval);
 
10387
            }
 
10388
            break;
 
10389
        case 3:
 
10390
            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
10391
                u32 destval;
 
10392
 
 
10393
                DECODE_PRINTF("NEG\tDWORD PTR ");
 
10394
                destoffset = decode_rm01_address(rl);
 
10395
                DECODE_PRINTF("\n");
 
10396
                destval = fetch_data_long(destoffset);
 
10397
                TRACE_AND_STEP();
 
10398
                destval = neg_long(destval);
 
10399
                store_data_long(destoffset, destval);
 
10400
            } else {
 
10401
                u16 destval;
 
10402
 
 
10403
                DECODE_PRINTF("NEG\tWORD PTR ");
 
10404
                destoffset = decode_rm01_address(rl);
 
10405
                DECODE_PRINTF("\n");
 
10406
                destval = fetch_data_word(destoffset);
 
10407
                TRACE_AND_STEP();
 
10408
                destval = neg_word(destval);
 
10409
                store_data_word(destoffset, destval);
 
10410
            }
 
10411
            break;
 
10412
        case 4:
 
10413
            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
10414
                u32 destval;
 
10415
 
 
10416
                DECODE_PRINTF("MUL\tDWORD PTR ");
 
10417
                destoffset = decode_rm01_address(rl);
 
10418
                DECODE_PRINTF("\n");
 
10419
                destval = fetch_data_long(destoffset);
 
10420
                TRACE_AND_STEP();
 
10421
                mul_long(destval);
 
10422
            } else {
 
10423
                u16 destval;
 
10424
 
 
10425
                DECODE_PRINTF("MUL\tWORD PTR ");
 
10426
                destoffset = decode_rm01_address(rl);
 
10427
                DECODE_PRINTF("\n");
 
10428
                destval = fetch_data_word(destoffset);
 
10429
                TRACE_AND_STEP();
 
10430
                mul_word(destval);
 
10431
            }
 
10432
            break;
 
10433
        case 5:
 
10434
            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
10435
                u32 destval;
 
10436
 
 
10437
                DECODE_PRINTF("IMUL\tDWORD PTR ");
 
10438
                destoffset = decode_rm01_address(rl);
 
10439
                DECODE_PRINTF("\n");
 
10440
                destval = fetch_data_long(destoffset);
 
10441
                TRACE_AND_STEP();
 
10442
                imul_long(destval);
 
10443
            } else {
 
10444
                u16 destval;
 
10445
 
 
10446
                DECODE_PRINTF("IMUL\tWORD PTR ");
 
10447
                destoffset = decode_rm01_address(rl);
 
10448
                DECODE_PRINTF("\n");
 
10449
                destval = fetch_data_word(destoffset);
 
10450
                TRACE_AND_STEP();
 
10451
                imul_word(destval);
 
10452
            }
 
10453
            break;
 
10454
        case 6:
 
10455
            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
10456
                u32 destval;
 
10457
 
 
10458
                DECODE_PRINTF("DIV\tDWORD PTR ");
 
10459
                destoffset = decode_rm01_address(rl);
 
10460
                DECODE_PRINTF("\n");
 
10461
                destval = fetch_data_long(destoffset);
 
10462
                TRACE_AND_STEP();
 
10463
                div_long(destval);
 
10464
            } else {
 
10465
                u16 destval;
 
10466
 
 
10467
                DECODE_PRINTF("DIV\tWORD PTR ");
 
10468
                destoffset = decode_rm01_address(rl);
 
10469
                DECODE_PRINTF("\n");
 
10470
                destval = fetch_data_word(destoffset);
 
10471
                TRACE_AND_STEP();
 
10472
                div_word(destval);
 
10473
            }
 
10474
            break;
 
10475
        case 7:
 
10476
            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
10477
                u32 destval;
 
10478
 
 
10479
                DECODE_PRINTF("IDIV\tDWORD PTR ");
 
10480
                destoffset = decode_rm01_address(rl);
 
10481
                DECODE_PRINTF("\n");
 
10482
                destval = fetch_data_long(destoffset);
 
10483
                TRACE_AND_STEP();
 
10484
                idiv_long(destval);
 
10485
            } else {
 
10486
                u16 destval;
 
10487
 
 
10488
                DECODE_PRINTF("IDIV\tWORD PTR ");
 
10489
                destoffset = decode_rm01_address(rl);
 
10490
                DECODE_PRINTF("\n");
 
10491
                destval = fetch_data_word(destoffset);
 
10492
                TRACE_AND_STEP();
 
10493
                idiv_word(destval);
 
10494
            }
 
10495
            break;
 
10496
        }
 
10497
        break;                  /* end mod==01 */
 
10498
    case 2:                     /* mod=10 */
 
10499
        switch (rh) {
 
10500
        case 0:         /* test word imm */
 
10501
            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
10502
                u32 destval,srcval;
 
10503
 
 
10504
                DECODE_PRINTF("TEST\tDWORD PTR ");
 
10505
                destoffset = decode_rm10_address(rl);
 
10506
                DECODE_PRINTF(",");
 
10507
                srcval = fetch_long_imm();
 
10508
                DECODE_PRINTF2("%x\n", srcval);
 
10509
                destval = fetch_data_long(destoffset);
 
10510
                TRACE_AND_STEP();
 
10511
                test_long(destval, srcval);
 
10512
            } else {
 
10513
                u16 destval,srcval;
 
10514
 
 
10515
                DECODE_PRINTF("TEST\tWORD PTR ");
 
10516
                destoffset = decode_rm10_address(rl);
 
10517
                DECODE_PRINTF(",");
 
10518
                srcval = fetch_word_imm();
 
10519
                DECODE_PRINTF2("%x\n", srcval);
 
10520
                destval = fetch_data_word(destoffset);
 
10521
                TRACE_AND_STEP();
 
10522
                test_word(destval, srcval);
 
10523
            }
 
10524
            break;
 
10525
        case 1:
 
10526
            DECODE_PRINTF("ILLEGAL OP MOD=10 RH=01 OP=F6\n");
 
10527
            HALT_SYS();
 
10528
            break;
 
10529
        case 2:
 
10530
            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
10531
                u32 destval;
 
10532
 
 
10533
                DECODE_PRINTF("NOT\tDWORD PTR ");
 
10534
                destoffset = decode_rm10_address(rl);
 
10535
                DECODE_PRINTF("\n");
 
10536
                destval = fetch_data_long(destoffset);
 
10537
                TRACE_AND_STEP();
 
10538
                destval = not_long(destval);
 
10539
                store_data_long(destoffset, destval);
 
10540
            } else {
 
10541
                u16 destval;
 
10542
 
 
10543
                DECODE_PRINTF("NOT\tWORD PTR ");
 
10544
                destoffset = decode_rm10_address(rl);
 
10545
                DECODE_PRINTF("\n");
 
10546
                destval = fetch_data_word(destoffset);
 
10547
                TRACE_AND_STEP();
 
10548
                destval = not_word(destval);
 
10549
                store_data_word(destoffset, destval);
 
10550
            }
 
10551
            break;
 
10552
        case 3:
 
10553
            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
10554
                u32 destval;
 
10555
 
 
10556
                DECODE_PRINTF("NEG\tDWORD PTR ");
 
10557
                destoffset = decode_rm10_address(rl);
 
10558
                DECODE_PRINTF("\n");
 
10559
                destval = fetch_data_long(destoffset);
 
10560
                TRACE_AND_STEP();
 
10561
                destval = neg_long(destval);
 
10562
                store_data_long(destoffset, destval);
 
10563
            } else {
 
10564
                u16 destval;
 
10565
 
 
10566
                DECODE_PRINTF("NEG\tWORD PTR ");
 
10567
                destoffset = decode_rm10_address(rl);
 
10568
                DECODE_PRINTF("\n");
 
10569
                destval = fetch_data_word(destoffset);
 
10570
                TRACE_AND_STEP();
 
10571
                destval = neg_word(destval);
 
10572
                store_data_word(destoffset, destval);
 
10573
            }
 
10574
            break;
 
10575
        case 4:
 
10576
            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
10577
                u32 destval;
 
10578
 
 
10579
                DECODE_PRINTF("MUL\tDWORD PTR ");
 
10580
                destoffset = decode_rm10_address(rl);
 
10581
                DECODE_PRINTF("\n");
 
10582
                destval = fetch_data_long(destoffset);
 
10583
                TRACE_AND_STEP();
 
10584
                mul_long(destval);
 
10585
            } else {
 
10586
                u16 destval;
 
10587
 
 
10588
                DECODE_PRINTF("MUL\tWORD PTR ");
 
10589
                destoffset = decode_rm10_address(rl);
 
10590
                DECODE_PRINTF("\n");
 
10591
                destval = fetch_data_word(destoffset);
 
10592
                TRACE_AND_STEP();
 
10593
                mul_word(destval);
 
10594
            }
 
10595
            break;
 
10596
        case 5:
 
10597
            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
10598
                u32 destval;
 
10599
 
 
10600
                DECODE_PRINTF("IMUL\tDWORD PTR ");
 
10601
                destoffset = decode_rm10_address(rl);
 
10602
                DECODE_PRINTF("\n");
 
10603
                destval = fetch_data_long(destoffset);
 
10604
                TRACE_AND_STEP();
 
10605
                imul_long(destval);
 
10606
            } else {
 
10607
                u16 destval;
 
10608
 
 
10609
                DECODE_PRINTF("IMUL\tWORD PTR ");
 
10610
                destoffset = decode_rm10_address(rl);
 
10611
                DECODE_PRINTF("\n");
 
10612
                destval = fetch_data_word(destoffset);
 
10613
                TRACE_AND_STEP();
 
10614
                imul_word(destval);
 
10615
            }
 
10616
            break;
 
10617
        case 6:
 
10618
            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
10619
                u32 destval;
 
10620
 
 
10621
                DECODE_PRINTF("DIV\tDWORD PTR ");
 
10622
                destoffset = decode_rm10_address(rl);
 
10623
                DECODE_PRINTF("\n");
 
10624
                destval = fetch_data_long(destoffset);
 
10625
                TRACE_AND_STEP();
 
10626
                div_long(destval);
 
10627
            } else {
 
10628
                u16 destval;
 
10629
 
 
10630
                DECODE_PRINTF("DIV\tWORD PTR ");
 
10631
                destoffset = decode_rm10_address(rl);
 
10632
                DECODE_PRINTF("\n");
 
10633
                destval = fetch_data_word(destoffset);
 
10634
                TRACE_AND_STEP();
 
10635
                div_word(destval);
 
10636
            }
 
10637
            break;
 
10638
        case 7:
 
10639
            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
10640
                u32 destval;
 
10641
 
 
10642
                DECODE_PRINTF("IDIV\tDWORD PTR ");
 
10643
                destoffset = decode_rm10_address(rl);
 
10644
                DECODE_PRINTF("\n");
 
10645
                destval = fetch_data_long(destoffset);
 
10646
                TRACE_AND_STEP();
 
10647
                idiv_long(destval);
 
10648
            } else {
 
10649
                u16 destval;
 
10650
 
 
10651
                DECODE_PRINTF("IDIV\tWORD PTR ");
 
10652
                destoffset = decode_rm10_address(rl);
 
10653
                DECODE_PRINTF("\n");
 
10654
                destval = fetch_data_word(destoffset);
 
10655
                TRACE_AND_STEP();
 
10656
                idiv_word(destval);
 
10657
            }
 
10658
            break;
 
10659
        }
 
10660
        break;                  /* end mod==10 */
 
10661
    case 3:                     /* mod=11 */
 
10662
        switch (rh) {
 
10663
        case 0:         /* test word imm */
 
10664
            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
10665
                u32 *destreg;
 
10666
                u32 srcval;
 
10667
 
 
10668
                DECODE_PRINTF("TEST\t");
 
10669
                destreg = DECODE_RM_LONG_REGISTER(rl);
 
10670
                DECODE_PRINTF(",");
 
10671
                srcval = fetch_long_imm();
 
10672
                DECODE_PRINTF2("%x\n", srcval);
 
10673
                TRACE_AND_STEP();
 
10674
                test_long(*destreg, srcval);
 
10675
            } else {
 
10676
                u16 *destreg;
 
10677
                u16 srcval;
 
10678
 
 
10679
                DECODE_PRINTF("TEST\t");
 
10680
                destreg = DECODE_RM_WORD_REGISTER(rl);
 
10681
                DECODE_PRINTF(",");
 
10682
                srcval = fetch_word_imm();
 
10683
                DECODE_PRINTF2("%x\n", srcval);
 
10684
                TRACE_AND_STEP();
 
10685
                test_word(*destreg, srcval);
 
10686
            }
 
10687
            break;
 
10688
        case 1:
 
10689
            DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
 
10690
            HALT_SYS();
 
10691
            break;
 
10692
        case 2:
 
10693
            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
10694
                u32 *destreg;
 
10695
 
 
10696
                DECODE_PRINTF("NOT\t");
 
10697
                destreg = DECODE_RM_LONG_REGISTER(rl);
 
10698
                DECODE_PRINTF("\n");
 
10699
                TRACE_AND_STEP();
 
10700
                *destreg = not_long(*destreg);
 
10701
            } else {
 
10702
                u16 *destreg;
 
10703
 
 
10704
                DECODE_PRINTF("NOT\t");
 
10705
                destreg = DECODE_RM_WORD_REGISTER(rl);
 
10706
                DECODE_PRINTF("\n");
 
10707
                TRACE_AND_STEP();
 
10708
                *destreg = not_word(*destreg);
 
10709
            }
 
10710
            break;
 
10711
        case 3:
 
10712
            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
10713
                u32 *destreg;
 
10714
 
 
10715
                DECODE_PRINTF("NEG\t");
 
10716
                destreg = DECODE_RM_LONG_REGISTER(rl);
 
10717
                DECODE_PRINTF("\n");
 
10718
                TRACE_AND_STEP();
 
10719
                *destreg = neg_long(*destreg);
 
10720
            } else {
 
10721
                u16 *destreg;
 
10722
 
 
10723
                DECODE_PRINTF("NEG\t");
 
10724
                destreg = DECODE_RM_WORD_REGISTER(rl);
 
10725
                DECODE_PRINTF("\n");
 
10726
                TRACE_AND_STEP();
 
10727
                *destreg = neg_word(*destreg);
 
10728
            }
 
10729
            break;
 
10730
        case 4:
 
10731
            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
10732
                u32 *destreg;
 
10733
 
 
10734
                DECODE_PRINTF("MUL\t");
 
10735
                destreg = DECODE_RM_LONG_REGISTER(rl);
 
10736
                DECODE_PRINTF("\n");
 
10737
                TRACE_AND_STEP();
 
10738
                mul_long(*destreg);      /*!!!  */
 
10739
            } else {
 
10740
                u16 *destreg;
 
10741
 
 
10742
                DECODE_PRINTF("MUL\t");
 
10743
                destreg = DECODE_RM_WORD_REGISTER(rl);
 
10744
                DECODE_PRINTF("\n");
 
10745
                TRACE_AND_STEP();
 
10746
                mul_word(*destreg);      /*!!!  */
 
10747
            }
 
10748
            break;
 
10749
        case 5:
 
10750
            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
10751
                u32 *destreg;
 
10752
 
 
10753
                DECODE_PRINTF("IMUL\t");
 
10754
                destreg = DECODE_RM_LONG_REGISTER(rl);
 
10755
                DECODE_PRINTF("\n");
 
10756
                TRACE_AND_STEP();
 
10757
                imul_long(*destreg);
 
10758
            } else {
 
10759
                u16 *destreg;
 
10760
 
 
10761
                DECODE_PRINTF("IMUL\t");
 
10762
                destreg = DECODE_RM_WORD_REGISTER(rl);
 
10763
                DECODE_PRINTF("\n");
 
10764
                TRACE_AND_STEP();
 
10765
                imul_word(*destreg);
 
10766
            }
 
10767
            break;
 
10768
        case 6:
 
10769
            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
10770
                u32 *destreg;
 
10771
 
 
10772
                DECODE_PRINTF("DIV\t");
 
10773
                destreg = DECODE_RM_LONG_REGISTER(rl);
 
10774
                DECODE_PRINTF("\n");
 
10775
                TRACE_AND_STEP();
 
10776
                div_long(*destreg);
 
10777
            } else {
 
10778
                u16 *destreg;
 
10779
 
 
10780
                DECODE_PRINTF("DIV\t");
 
10781
                destreg = DECODE_RM_WORD_REGISTER(rl);
 
10782
                DECODE_PRINTF("\n");
 
10783
                TRACE_AND_STEP();
 
10784
                div_word(*destreg);
 
10785
            }
 
10786
            break;
 
10787
        case 7:
 
10788
            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
10789
                u32 *destreg;
 
10790
 
 
10791
                DECODE_PRINTF("IDIV\t");
 
10792
                destreg = DECODE_RM_LONG_REGISTER(rl);
 
10793
                DECODE_PRINTF("\n");
 
10794
                TRACE_AND_STEP();
 
10795
                idiv_long(*destreg);
 
10796
            } else {
 
10797
                u16 *destreg;
 
10798
 
 
10799
                DECODE_PRINTF("IDIV\t");
 
10800
                destreg = DECODE_RM_WORD_REGISTER(rl);
 
10801
                DECODE_PRINTF("\n");
 
10802
                TRACE_AND_STEP();
 
10803
                idiv_word(*destreg);
 
10804
            }
 
10805
            break;
 
10806
        }
 
10807
        break;                  /* end mod==11 */
 
10808
    }
 
10809
    DECODE_CLEAR_SEGOVR();
 
10810
    END_OF_INSTR();
 
10811
}
 
10812
 
 
10813
/****************************************************************************
 
10814
REMARKS:
 
10815
Handles opcode 0xf8
 
10816
****************************************************************************/
 
10817
static void x86emuOp_clc(u8 X86EMU_UNUSED(op1))
 
10818
{
 
10819
    /* clear the carry flag. */
 
10820
    START_OF_INSTR();
 
10821
    DECODE_PRINTF("CLC\n");
 
10822
    TRACE_AND_STEP();
 
10823
    CLEAR_FLAG(F_CF);
 
10824
    DECODE_CLEAR_SEGOVR();
 
10825
    END_OF_INSTR();
 
10826
}
 
10827
 
 
10828
/****************************************************************************
 
10829
REMARKS:
 
10830
Handles opcode 0xf9
 
10831
****************************************************************************/
 
10832
static void x86emuOp_stc(u8 X86EMU_UNUSED(op1))
 
10833
{
 
10834
    /* set the carry flag. */
 
10835
    START_OF_INSTR();
 
10836
    DECODE_PRINTF("STC\n");
 
10837
    TRACE_AND_STEP();
 
10838
    SET_FLAG(F_CF);
 
10839
    DECODE_CLEAR_SEGOVR();
 
10840
    END_OF_INSTR();
 
10841
}
 
10842
 
 
10843
/****************************************************************************
 
10844
REMARKS:
 
10845
Handles opcode 0xfa
 
10846
****************************************************************************/
 
10847
static void x86emuOp_cli(u8 X86EMU_UNUSED(op1))
 
10848
{
 
10849
    /* clear interrupts. */
 
10850
    START_OF_INSTR();
 
10851
    DECODE_PRINTF("CLI\n");
 
10852
    TRACE_AND_STEP();
 
10853
    CLEAR_FLAG(F_IF);
 
10854
    DECODE_CLEAR_SEGOVR();
 
10855
    END_OF_INSTR();
 
10856
}
 
10857
 
 
10858
/****************************************************************************
 
10859
REMARKS:
 
10860
Handles opcode 0xfb
 
10861
****************************************************************************/
 
10862
static void x86emuOp_sti(u8 X86EMU_UNUSED(op1))
 
10863
{
 
10864
    /* enable  interrupts. */
 
10865
    START_OF_INSTR();
 
10866
    DECODE_PRINTF("STI\n");
 
10867
    TRACE_AND_STEP();
 
10868
    SET_FLAG(F_IF);
 
10869
    DECODE_CLEAR_SEGOVR();
 
10870
    END_OF_INSTR();
 
10871
}
 
10872
 
 
10873
/****************************************************************************
 
10874
REMARKS:
 
10875
Handles opcode 0xfc
 
10876
****************************************************************************/
 
10877
static void x86emuOp_cld(u8 X86EMU_UNUSED(op1))
 
10878
{
 
10879
    /* clear interrupts. */
 
10880
    START_OF_INSTR();
 
10881
    DECODE_PRINTF("CLD\n");
 
10882
    TRACE_AND_STEP();
 
10883
    CLEAR_FLAG(F_DF);
 
10884
    DECODE_CLEAR_SEGOVR();
 
10885
    END_OF_INSTR();
 
10886
}
 
10887
 
 
10888
/****************************************************************************
 
10889
REMARKS:
 
10890
Handles opcode 0xfd
 
10891
****************************************************************************/
 
10892
static void x86emuOp_std(u8 X86EMU_UNUSED(op1))
 
10893
{
 
10894
    /* clear interrupts. */
 
10895
    START_OF_INSTR();
 
10896
    DECODE_PRINTF("STD\n");
 
10897
    TRACE_AND_STEP();
 
10898
    SET_FLAG(F_DF);
 
10899
    DECODE_CLEAR_SEGOVR();
 
10900
    END_OF_INSTR();
 
10901
}
 
10902
 
 
10903
/****************************************************************************
 
10904
REMARKS:
 
10905
Handles opcode 0xfe
 
10906
****************************************************************************/
 
10907
static void x86emuOp_opcFE_byte_RM(u8 X86EMU_UNUSED(op1))
 
10908
{
 
10909
    int mod, rh, rl;
 
10910
    u8 destval;
 
10911
    uint destoffset;
 
10912
    u8 *destreg;
 
10913
 
 
10914
    /* Yet another special case instruction. */
 
10915
    START_OF_INSTR();
 
10916
    FETCH_DECODE_MODRM(mod, rh, rl);
 
10917
#ifdef DEBUG
 
10918
    if (DEBUG_DECODE()) {
 
10919
        /* XXX DECODE_PRINTF may be changed to something more
 
10920
           general, so that it is important to leave the strings
 
10921
           in the same format, even though the result is that the 
 
10922
           above test is done twice. */
 
10923
 
 
10924
        switch (rh) {
 
10925
        case 0:
 
10926
            DECODE_PRINTF("INC\t");
 
10927
            break;
 
10928
        case 1:
 
10929
            DECODE_PRINTF("DEC\t");
 
10930
            break;
 
10931
        case 2:
 
10932
        case 3:
 
10933
        case 4:
 
10934
        case 5:
 
10935
        case 6:
 
10936
        case 7:
 
10937
            DECODE_PRINTF2("ILLEGAL OP MAJOR OP 0xFE MINOR OP %x \n", mod);
 
10938
            HALT_SYS();
 
10939
            break;
 
10940
        }
 
10941
    }
 
10942
#endif
 
10943
    switch (mod) {
 
10944
    case 0:
 
10945
        DECODE_PRINTF("BYTE PTR ");
 
10946
        destoffset = decode_rm00_address(rl);
 
10947
        DECODE_PRINTF("\n");
 
10948
        switch (rh) {
 
10949
        case 0:         /* inc word ptr ... */
 
10950
            destval = fetch_data_byte(destoffset);
 
10951
            TRACE_AND_STEP();
 
10952
            destval = inc_byte(destval);
 
10953
            store_data_byte(destoffset, destval);
 
10954
            break;
 
10955
        case 1:         /* dec word ptr ... */
 
10956
            destval = fetch_data_byte(destoffset);
 
10957
            TRACE_AND_STEP();
 
10958
            destval = dec_byte(destval);
 
10959
            store_data_byte(destoffset, destval);
 
10960
            break;
 
10961
        }
 
10962
        break;
 
10963
    case 1:
 
10964
        DECODE_PRINTF("BYTE PTR ");
 
10965
        destoffset = decode_rm01_address(rl);
 
10966
        DECODE_PRINTF("\n");
 
10967
        switch (rh) {
 
10968
        case 0:
 
10969
            destval = fetch_data_byte(destoffset);
 
10970
            TRACE_AND_STEP();
 
10971
            destval = inc_byte(destval);
 
10972
            store_data_byte(destoffset, destval);
 
10973
            break;
 
10974
        case 1:
 
10975
            destval = fetch_data_byte(destoffset);
 
10976
            TRACE_AND_STEP();
 
10977
            destval = dec_byte(destval);
 
10978
            store_data_byte(destoffset, destval);
 
10979
            break;
 
10980
        }
 
10981
        break;
 
10982
    case 2:
 
10983
        DECODE_PRINTF("BYTE PTR ");
 
10984
        destoffset = decode_rm10_address(rl);
 
10985
        DECODE_PRINTF("\n");
 
10986
        switch (rh) {
 
10987
        case 0:
 
10988
            destval = fetch_data_byte(destoffset);
 
10989
            TRACE_AND_STEP();
 
10990
            destval = inc_byte(destval);
 
10991
            store_data_byte(destoffset, destval);
 
10992
            break;
 
10993
        case 1:
 
10994
            destval = fetch_data_byte(destoffset);
 
10995
            TRACE_AND_STEP();
 
10996
            destval = dec_byte(destval);
 
10997
            store_data_byte(destoffset, destval);
 
10998
            break;
 
10999
        }
 
11000
        break;
 
11001
    case 3:
 
11002
        destreg = DECODE_RM_BYTE_REGISTER(rl);
 
11003
        DECODE_PRINTF("\n");
 
11004
        switch (rh) {
 
11005
        case 0:
 
11006
            TRACE_AND_STEP();
 
11007
            *destreg = inc_byte(*destreg);
 
11008
            break;
 
11009
        case 1:
 
11010
            TRACE_AND_STEP();
 
11011
            *destreg = dec_byte(*destreg);
 
11012
            break;
 
11013
        }
 
11014
        break;
 
11015
    }
 
11016
    DECODE_CLEAR_SEGOVR();
 
11017
    END_OF_INSTR();
 
11018
}
 
11019
 
 
11020
/****************************************************************************
 
11021
REMARKS:
 
11022
Handles opcode 0xff
 
11023
****************************************************************************/
 
11024
static void x86emuOp_opcFF_word_RM(u8 X86EMU_UNUSED(op1))
 
11025
{
 
11026
    int mod, rh, rl;
 
11027
    uint destoffset = 0;
 
11028
        u16 *destreg;
 
11029
        u16 destval,destval2;
 
11030
 
 
11031
    /* Yet another special case instruction. */
 
11032
    START_OF_INSTR();
 
11033
    FETCH_DECODE_MODRM(mod, rh, rl);
 
11034
#ifdef DEBUG
 
11035
    if (DEBUG_DECODE()) {
 
11036
        /* XXX DECODE_PRINTF may be changed to something more
 
11037
           general, so that it is important to leave the strings
 
11038
           in the same format, even though the result is that the
 
11039
           above test is done twice. */
 
11040
 
 
11041
        switch (rh) {
 
11042
        case 0:
 
11043
            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
11044
                DECODE_PRINTF("INC\tDWORD PTR ");
 
11045
            } else {
 
11046
                DECODE_PRINTF("INC\tWORD PTR ");
 
11047
            }
 
11048
            break;
 
11049
        case 1:
 
11050
            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
11051
                DECODE_PRINTF("DEC\tDWORD PTR ");
 
11052
            } else {
 
11053
                DECODE_PRINTF("DEC\tWORD PTR ");
 
11054
            }
 
11055
            break;
 
11056
        case 2:
 
11057
            DECODE_PRINTF("CALL\t");
 
11058
            break;
 
11059
        case 3:
 
11060
            DECODE_PRINTF("CALL\tFAR ");
 
11061
            break;
 
11062
        case 4:
 
11063
            DECODE_PRINTF("JMP\t");
 
11064
            break;
 
11065
        case 5:
 
11066
            DECODE_PRINTF("JMP\tFAR ");
 
11067
            break;
 
11068
        case 6:
 
11069
            DECODE_PRINTF("PUSH\t");
 
11070
            break;
 
11071
        case 7:
 
11072
            DECODE_PRINTF("ILLEGAL DECODING OF OPCODE FF\t");
 
11073
            HALT_SYS();
 
11074
            break;
 
11075
        }
 
11076
    }
 
11077
#endif
 
11078
    switch (mod) {
 
11079
    case 0:
 
11080
        destoffset = decode_rm00_address(rl);
 
11081
        DECODE_PRINTF("\n");
 
11082
        switch (rh) {
 
11083
        case 0:         /* inc word ptr ... */
 
11084
            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
11085
                u32 destval;
 
11086
 
 
11087
                destval = fetch_data_long(destoffset);
 
11088
                TRACE_AND_STEP();
 
11089
                destval = inc_long(destval);
 
11090
                store_data_long(destoffset, destval);
 
11091
            } else {
 
11092
                u16 destval;
 
11093
 
 
11094
                destval = fetch_data_word(destoffset);
 
11095
                TRACE_AND_STEP();
 
11096
                destval = inc_word(destval);
 
11097
                store_data_word(destoffset, destval);
 
11098
            }
 
11099
            break;
 
11100
        case 1:         /* dec word ptr ... */
 
11101
            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
11102
                u32 destval;
 
11103
 
 
11104
                destval = fetch_data_long(destoffset);
 
11105
                TRACE_AND_STEP();
 
11106
                destval = dec_long(destval);
 
11107
                store_data_long(destoffset, destval);
 
11108
            } else {
 
11109
                u16 destval;
 
11110
 
 
11111
                destval = fetch_data_word(destoffset);
 
11112
                TRACE_AND_STEP();
 
11113
                destval = dec_word(destval);
 
11114
                store_data_word(destoffset, destval);
 
11115
            }
 
11116
            break;
 
11117
        case 2:         /* call word ptr ... */
 
11118
            destval = fetch_data_word(destoffset);
 
11119
            TRACE_AND_STEP();
 
11120
            push_word(M.x86.R_IP);
 
11121
            M.x86.R_IP = destval;
 
11122
            break;
 
11123
        case 3:         /* call far ptr ... */
 
11124
            destval = fetch_data_word(destoffset);
 
11125
            destval2 = fetch_data_word(destoffset + 2);
 
11126
            TRACE_AND_STEP();
 
11127
            push_word(M.x86.R_CS);
 
11128
            M.x86.R_CS = destval2;
 
11129
            push_word(M.x86.R_IP);
 
11130
            M.x86.R_IP = destval;
 
11131
            break;
 
11132
        case 4:         /* jmp word ptr ... */
 
11133
            destval = fetch_data_word(destoffset);
 
11134
            TRACE_AND_STEP();
 
11135
            M.x86.R_IP = destval;
 
11136
            break;
 
11137
        case 5:         /* jmp far ptr ... */
 
11138
            destval = fetch_data_word(destoffset);
 
11139
            destval2 = fetch_data_word(destoffset + 2);
 
11140
            TRACE_AND_STEP();
 
11141
            M.x86.R_IP = destval;
 
11142
            M.x86.R_CS = destval2;
 
11143
            break;
 
11144
        case 6:         /*  push word ptr ... */
 
11145
            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
11146
                u32 destval;
 
11147
 
 
11148
                destval = fetch_data_long(destoffset);
 
11149
                TRACE_AND_STEP();
 
11150
                push_long(destval);
 
11151
            } else {
 
11152
                u16 destval;
 
11153
 
 
11154
                destval = fetch_data_word(destoffset);
 
11155
                TRACE_AND_STEP();
 
11156
                push_word(destval);
 
11157
            }
 
11158
            break;
 
11159
        }
 
11160
        break;
 
11161
    case 1:
 
11162
        destoffset = decode_rm01_address(rl);
 
11163
        DECODE_PRINTF("\n");
 
11164
        switch (rh) {
 
11165
        case 0:
 
11166
            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
11167
                u32 destval;
 
11168
 
 
11169
                destval = fetch_data_long(destoffset);
 
11170
                TRACE_AND_STEP();
 
11171
                destval = inc_long(destval);
 
11172
                store_data_long(destoffset, destval);
 
11173
            } else {
 
11174
                u16 destval;
 
11175
 
 
11176
                destval = fetch_data_word(destoffset);
 
11177
                TRACE_AND_STEP();
 
11178
                destval = inc_word(destval);
 
11179
                store_data_word(destoffset, destval);
 
11180
            }
 
11181
            break;
 
11182
        case 1:
 
11183
            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
11184
                u32 destval;
 
11185
 
 
11186
                destval = fetch_data_long(destoffset);
 
11187
                TRACE_AND_STEP();
 
11188
                destval = dec_long(destval);
 
11189
                store_data_long(destoffset, destval);
 
11190
            } else {
 
11191
                u16 destval;
 
11192
 
 
11193
                destval = fetch_data_word(destoffset);
 
11194
                TRACE_AND_STEP();
 
11195
                destval = dec_word(destval);
 
11196
                store_data_word(destoffset, destval);
 
11197
            }
 
11198
            break;
 
11199
        case 2:         /* call word ptr ... */
 
11200
            destval = fetch_data_word(destoffset);
 
11201
            TRACE_AND_STEP();
 
11202
            push_word(M.x86.R_IP);
 
11203
            M.x86.R_IP = destval;
 
11204
            break;
 
11205
        case 3:         /* call far ptr ... */
 
11206
            destval = fetch_data_word(destoffset);
 
11207
            destval2 = fetch_data_word(destoffset + 2);
 
11208
            TRACE_AND_STEP();
 
11209
            push_word(M.x86.R_CS);
 
11210
            M.x86.R_CS = destval2;
 
11211
            push_word(M.x86.R_IP);
 
11212
            M.x86.R_IP = destval;
 
11213
            break;
 
11214
        case 4:         /* jmp word ptr ... */
 
11215
            destval = fetch_data_word(destoffset);
 
11216
            TRACE_AND_STEP();
 
11217
            M.x86.R_IP = destval;
 
11218
            break;
 
11219
        case 5:         /* jmp far ptr ... */
 
11220
            destval = fetch_data_word(destoffset);
 
11221
            destval2 = fetch_data_word(destoffset + 2);
 
11222
            TRACE_AND_STEP();
 
11223
            M.x86.R_IP = destval;
 
11224
            M.x86.R_CS = destval2;
 
11225
            break;
 
11226
        case 6:         /*  push word ptr ... */
 
11227
            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
11228
                u32 destval;
 
11229
 
 
11230
                destval = fetch_data_long(destoffset);
 
11231
                TRACE_AND_STEP();
 
11232
                push_long(destval);
 
11233
            } else {
 
11234
                u16 destval;
 
11235
 
 
11236
                destval = fetch_data_word(destoffset);
 
11237
                TRACE_AND_STEP();
 
11238
                push_word(destval);
 
11239
            }
 
11240
            break;
 
11241
        }
 
11242
        break;
 
11243
    case 2:
 
11244
        destoffset = decode_rm10_address(rl);
 
11245
        DECODE_PRINTF("\n");
 
11246
        switch (rh) {
 
11247
        case 0:
 
11248
            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
11249
                u32 destval;
 
11250
 
 
11251
                destval = fetch_data_long(destoffset);
 
11252
                TRACE_AND_STEP();
 
11253
                destval = inc_long(destval);
 
11254
                store_data_long(destoffset, destval);
 
11255
            } else {
 
11256
                u16 destval;
 
11257
 
 
11258
                destval = fetch_data_word(destoffset);
 
11259
                TRACE_AND_STEP();
 
11260
                destval = inc_word(destval);
 
11261
                store_data_word(destoffset, destval);
 
11262
            }
 
11263
            break;
 
11264
        case 1:
 
11265
            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
11266
                u32 destval;
 
11267
 
 
11268
                destval = fetch_data_long(destoffset);
 
11269
                TRACE_AND_STEP();
 
11270
                destval = dec_long(destval);
 
11271
                store_data_long(destoffset, destval);
 
11272
            } else {
 
11273
                u16 destval;
 
11274
 
 
11275
                destval = fetch_data_word(destoffset);
 
11276
                TRACE_AND_STEP();
 
11277
                destval = dec_word(destval);
 
11278
                store_data_word(destoffset, destval);
 
11279
            }
 
11280
            break;
 
11281
        case 2:         /* call word ptr ... */
 
11282
            destval = fetch_data_word(destoffset);
 
11283
            TRACE_AND_STEP();
 
11284
            push_word(M.x86.R_IP);
 
11285
            M.x86.R_IP = destval;
 
11286
            break;
 
11287
        case 3:         /* call far ptr ... */
 
11288
            destval = fetch_data_word(destoffset);
 
11289
            destval2 = fetch_data_word(destoffset + 2);
 
11290
            TRACE_AND_STEP();
 
11291
            push_word(M.x86.R_CS);
 
11292
            M.x86.R_CS = destval2;
 
11293
            push_word(M.x86.R_IP);
 
11294
            M.x86.R_IP = destval;
 
11295
            break;
 
11296
        case 4:         /* jmp word ptr ... */
 
11297
            destval = fetch_data_word(destoffset);
 
11298
            TRACE_AND_STEP();
 
11299
            M.x86.R_IP = destval;
 
11300
            break;
 
11301
        case 5:         /* jmp far ptr ... */
 
11302
            destval = fetch_data_word(destoffset);
 
11303
            destval2 = fetch_data_word(destoffset + 2);
 
11304
            TRACE_AND_STEP();
 
11305
            M.x86.R_IP = destval;
 
11306
            M.x86.R_CS = destval2;
 
11307
            break;
 
11308
        case 6:         /*  push word ptr ... */
 
11309
            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
11310
                u32 destval;
 
11311
 
 
11312
                destval = fetch_data_long(destoffset);
 
11313
                TRACE_AND_STEP();
 
11314
                push_long(destval);
 
11315
            } else {
 
11316
                u16 destval;
 
11317
 
 
11318
                destval = fetch_data_word(destoffset);
 
11319
                TRACE_AND_STEP();
 
11320
                push_word(destval);
 
11321
            }
 
11322
            break;
 
11323
        }
 
11324
        break;
 
11325
    case 3:
 
11326
        switch (rh) {
 
11327
        case 0:
 
11328
            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
11329
                u32 *destreg;
 
11330
 
 
11331
                destreg = DECODE_RM_LONG_REGISTER(rl);
 
11332
                DECODE_PRINTF("\n");
 
11333
                TRACE_AND_STEP();
 
11334
                *destreg = inc_long(*destreg);
 
11335
            } else {
 
11336
                u16 *destreg;
 
11337
 
 
11338
                destreg = DECODE_RM_WORD_REGISTER(rl);
 
11339
                DECODE_PRINTF("\n");
 
11340
                TRACE_AND_STEP();
 
11341
                *destreg = inc_word(*destreg);
 
11342
            }
 
11343
            break;
 
11344
        case 1:
 
11345
            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
11346
                u32 *destreg;
 
11347
 
 
11348
                destreg = DECODE_RM_LONG_REGISTER(rl);
 
11349
                DECODE_PRINTF("\n");
 
11350
                TRACE_AND_STEP();
 
11351
                *destreg = dec_long(*destreg);
 
11352
            } else {
 
11353
                u16 *destreg;
 
11354
 
 
11355
                destreg = DECODE_RM_WORD_REGISTER(rl);
 
11356
                DECODE_PRINTF("\n");
 
11357
                TRACE_AND_STEP();
 
11358
                *destreg = dec_word(*destreg);
 
11359
            }
 
11360
            break;
 
11361
        case 2:         /* call word ptr ... */
 
11362
            destreg = DECODE_RM_WORD_REGISTER(rl);
 
11363
            DECODE_PRINTF("\n");
 
11364
            TRACE_AND_STEP();
 
11365
            push_word(M.x86.R_IP);
 
11366
            M.x86.R_IP = *destreg;
 
11367
            break;
 
11368
        case 3:         /* jmp far ptr ... */
 
11369
            DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n");
 
11370
            TRACE_AND_STEP();
 
11371
            HALT_SYS();
 
11372
            break;
 
11373
 
 
11374
        case 4:         /* jmp  ... */
 
11375
            destreg = DECODE_RM_WORD_REGISTER(rl);
 
11376
            DECODE_PRINTF("\n");
 
11377
            TRACE_AND_STEP();
 
11378
            M.x86.R_IP = (u16) (*destreg);
 
11379
            break;
 
11380
        case 5:         /* jmp far ptr ... */
 
11381
            DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n");
 
11382
            TRACE_AND_STEP();
 
11383
            HALT_SYS();
 
11384
            break;
 
11385
        case 6:
 
11386
            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
 
11387
                u32 *destreg;
 
11388
 
 
11389
                destreg = DECODE_RM_LONG_REGISTER(rl);
 
11390
                DECODE_PRINTF("\n");
 
11391
                TRACE_AND_STEP();
 
11392
                push_long(*destreg);
 
11393
            } else {
 
11394
                u16 *destreg;
 
11395
 
 
11396
                destreg = DECODE_RM_WORD_REGISTER(rl);
 
11397
                DECODE_PRINTF("\n");
 
11398
                TRACE_AND_STEP();
 
11399
                push_word(*destreg);
 
11400
            }
 
11401
            break;
 
11402
        }
 
11403
        break;
 
11404
    }
 
11405
    DECODE_CLEAR_SEGOVR();
 
11406
    END_OF_INSTR();
 
11407
}
 
11408
 
 
11409
/***************************************************************************
 
11410
 * Single byte operation code table:
 
11411
 **************************************************************************/
 
11412
void (*x86emu_optab[256])(u8) =
 
11413
{
 
11414
/*  0x00 */ x86emuOp_add_byte_RM_R,
 
11415
/*  0x01 */ x86emuOp_add_word_RM_R,
 
11416
/*  0x02 */ x86emuOp_add_byte_R_RM,
 
11417
/*  0x03 */ x86emuOp_add_word_R_RM,
 
11418
/*  0x04 */ x86emuOp_add_byte_AL_IMM,
 
11419
/*  0x05 */ x86emuOp_add_word_AX_IMM,
 
11420
/*  0x06 */ x86emuOp_push_ES,
 
11421
/*  0x07 */ x86emuOp_pop_ES,
 
11422
 
 
11423
/*  0x08 */ x86emuOp_or_byte_RM_R,
 
11424
/*  0x09 */ x86emuOp_or_word_RM_R,
 
11425
/*  0x0a */ x86emuOp_or_byte_R_RM,
 
11426
/*  0x0b */ x86emuOp_or_word_R_RM,
 
11427
/*  0x0c */ x86emuOp_or_byte_AL_IMM,
 
11428
/*  0x0d */ x86emuOp_or_word_AX_IMM,
 
11429
/*  0x0e */ x86emuOp_push_CS,
 
11430
/*  0x0f */ x86emuOp_two_byte,
 
11431
 
 
11432
/*  0x10 */ x86emuOp_adc_byte_RM_R,
 
11433
/*  0x11 */ x86emuOp_adc_word_RM_R,
 
11434
/*  0x12 */ x86emuOp_adc_byte_R_RM,
 
11435
/*  0x13 */ x86emuOp_adc_word_R_RM,
 
11436
/*  0x14 */ x86emuOp_adc_byte_AL_IMM,
 
11437
/*  0x15 */ x86emuOp_adc_word_AX_IMM,
 
11438
/*  0x16 */ x86emuOp_push_SS,
 
11439
/*  0x17 */ x86emuOp_pop_SS,
 
11440
 
 
11441
/*  0x18 */ x86emuOp_sbb_byte_RM_R,
 
11442
/*  0x19 */ x86emuOp_sbb_word_RM_R,
 
11443
/*  0x1a */ x86emuOp_sbb_byte_R_RM,
 
11444
/*  0x1b */ x86emuOp_sbb_word_R_RM,
 
11445
/*  0x1c */ x86emuOp_sbb_byte_AL_IMM,
 
11446
/*  0x1d */ x86emuOp_sbb_word_AX_IMM,
 
11447
/*  0x1e */ x86emuOp_push_DS,
 
11448
/*  0x1f */ x86emuOp_pop_DS,
 
11449
 
 
11450
/*  0x20 */ x86emuOp_and_byte_RM_R,
 
11451
/*  0x21 */ x86emuOp_and_word_RM_R,
 
11452
/*  0x22 */ x86emuOp_and_byte_R_RM,
 
11453
/*  0x23 */ x86emuOp_and_word_R_RM,
 
11454
/*  0x24 */ x86emuOp_and_byte_AL_IMM,
 
11455
/*  0x25 */ x86emuOp_and_word_AX_IMM,
 
11456
/*  0x26 */ x86emuOp_segovr_ES,
 
11457
/*  0x27 */ x86emuOp_daa,
 
11458
 
 
11459
/*  0x28 */ x86emuOp_sub_byte_RM_R,
 
11460
/*  0x29 */ x86emuOp_sub_word_RM_R,
 
11461
/*  0x2a */ x86emuOp_sub_byte_R_RM,
 
11462
/*  0x2b */ x86emuOp_sub_word_R_RM,
 
11463
/*  0x2c */ x86emuOp_sub_byte_AL_IMM,
 
11464
/*  0x2d */ x86emuOp_sub_word_AX_IMM,
 
11465
/*  0x2e */ x86emuOp_segovr_CS,
 
11466
/*  0x2f */ x86emuOp_das,
 
11467
 
 
11468
/*  0x30 */ x86emuOp_xor_byte_RM_R,
 
11469
/*  0x31 */ x86emuOp_xor_word_RM_R,
 
11470
/*  0x32 */ x86emuOp_xor_byte_R_RM,
 
11471
/*  0x33 */ x86emuOp_xor_word_R_RM,
 
11472
/*  0x34 */ x86emuOp_xor_byte_AL_IMM,
 
11473
/*  0x35 */ x86emuOp_xor_word_AX_IMM,
 
11474
/*  0x36 */ x86emuOp_segovr_SS,
 
11475
/*  0x37 */ x86emuOp_aaa,
 
11476
 
 
11477
/*  0x38 */ x86emuOp_cmp_byte_RM_R,
 
11478
/*  0x39 */ x86emuOp_cmp_word_RM_R,
 
11479
/*  0x3a */ x86emuOp_cmp_byte_R_RM,
 
11480
/*  0x3b */ x86emuOp_cmp_word_R_RM,
 
11481
/*  0x3c */ x86emuOp_cmp_byte_AL_IMM,
 
11482
/*  0x3d */ x86emuOp_cmp_word_AX_IMM,
 
11483
/*  0x3e */ x86emuOp_segovr_DS,
 
11484
/*  0x3f */ x86emuOp_aas,
 
11485
 
 
11486
/*  0x40 */ x86emuOp_inc_AX,
 
11487
/*  0x41 */ x86emuOp_inc_CX,
 
11488
/*  0x42 */ x86emuOp_inc_DX,
 
11489
/*  0x43 */ x86emuOp_inc_BX,
 
11490
/*  0x44 */ x86emuOp_inc_SP,
 
11491
/*  0x45 */ x86emuOp_inc_BP,
 
11492
/*  0x46 */ x86emuOp_inc_SI,
 
11493
/*  0x47 */ x86emuOp_inc_DI,
 
11494
 
 
11495
/*  0x48 */ x86emuOp_dec_AX,
 
11496
/*  0x49 */ x86emuOp_dec_CX,
 
11497
/*  0x4a */ x86emuOp_dec_DX,
 
11498
/*  0x4b */ x86emuOp_dec_BX,
 
11499
/*  0x4c */ x86emuOp_dec_SP,
 
11500
/*  0x4d */ x86emuOp_dec_BP,
 
11501
/*  0x4e */ x86emuOp_dec_SI,
 
11502
/*  0x4f */ x86emuOp_dec_DI,
 
11503
 
 
11504
/*  0x50 */ x86emuOp_push_AX,
 
11505
/*  0x51 */ x86emuOp_push_CX,
 
11506
/*  0x52 */ x86emuOp_push_DX,
 
11507
/*  0x53 */ x86emuOp_push_BX,
 
11508
/*  0x54 */ x86emuOp_push_SP,
 
11509
/*  0x55 */ x86emuOp_push_BP,
 
11510
/*  0x56 */ x86emuOp_push_SI,
 
11511
/*  0x57 */ x86emuOp_push_DI,
 
11512
 
 
11513
/*  0x58 */ x86emuOp_pop_AX,
 
11514
/*  0x59 */ x86emuOp_pop_CX,
 
11515
/*  0x5a */ x86emuOp_pop_DX,
 
11516
/*  0x5b */ x86emuOp_pop_BX,
 
11517
/*  0x5c */ x86emuOp_pop_SP,
 
11518
/*  0x5d */ x86emuOp_pop_BP,
 
11519
/*  0x5e */ x86emuOp_pop_SI,
 
11520
/*  0x5f */ x86emuOp_pop_DI,
 
11521
 
 
11522
/*  0x60 */ x86emuOp_push_all,
 
11523
/*  0x61 */ x86emuOp_pop_all,
 
11524
/*  0x62 */ x86emuOp_illegal_op,   /* bound */
 
11525
/*  0x63 */ x86emuOp_illegal_op,   /* arpl */
 
11526
/*  0x64 */ x86emuOp_segovr_FS,
 
11527
/*  0x65 */ x86emuOp_segovr_GS,
 
11528
/*  0x66 */ x86emuOp_prefix_data,
 
11529
/*  0x67 */ x86emuOp_prefix_addr,
 
11530
 
 
11531
/*  0x68 */ x86emuOp_push_word_IMM,
 
11532
/*  0x69 */ x86emuOp_imul_word_IMM,
 
11533
/*  0x6a */ x86emuOp_push_byte_IMM,
 
11534
/*  0x6b */ x86emuOp_imul_byte_IMM,
 
11535
/*  0x6c */ x86emuOp_ins_byte,
 
11536
/*  0x6d */ x86emuOp_ins_word,
 
11537
/*  0x6e */ x86emuOp_outs_byte,
 
11538
/*  0x6f */ x86emuOp_outs_word,
 
11539
 
 
11540
/*  0x70 */ x86emuOp_jump_near_O,
 
11541
/*  0x71 */ x86emuOp_jump_near_NO,
 
11542
/*  0x72 */ x86emuOp_jump_near_B,
 
11543
/*  0x73 */ x86emuOp_jump_near_NB,
 
11544
/*  0x74 */ x86emuOp_jump_near_Z,
 
11545
/*  0x75 */ x86emuOp_jump_near_NZ,
 
11546
/*  0x76 */ x86emuOp_jump_near_BE,
 
11547
/*  0x77 */ x86emuOp_jump_near_NBE,
 
11548
 
 
11549
/*  0x78 */ x86emuOp_jump_near_S,
 
11550
/*  0x79 */ x86emuOp_jump_near_NS,
 
11551
/*  0x7a */ x86emuOp_jump_near_P,
 
11552
/*  0x7b */ x86emuOp_jump_near_NP,
 
11553
/*  0x7c */ x86emuOp_jump_near_L,
 
11554
/*  0x7d */ x86emuOp_jump_near_NL,
 
11555
/*  0x7e */ x86emuOp_jump_near_LE,
 
11556
/*  0x7f */ x86emuOp_jump_near_NLE,
 
11557
 
 
11558
/*  0x80 */ x86emuOp_opc80_byte_RM_IMM,
 
11559
/*  0x81 */ x86emuOp_opc81_word_RM_IMM,
 
11560
/*  0x82 */ x86emuOp_opc82_byte_RM_IMM,
 
11561
/*  0x83 */ x86emuOp_opc83_word_RM_IMM,
 
11562
/*  0x84 */ x86emuOp_test_byte_RM_R,
 
11563
/*  0x85 */ x86emuOp_test_word_RM_R,
 
11564
/*  0x86 */ x86emuOp_xchg_byte_RM_R,
 
11565
/*  0x87 */ x86emuOp_xchg_word_RM_R,
 
11566
 
 
11567
/*  0x88 */ x86emuOp_mov_byte_RM_R,
 
11568
/*  0x89 */ x86emuOp_mov_word_RM_R,
 
11569
/*  0x8a */ x86emuOp_mov_byte_R_RM,
 
11570
/*  0x8b */ x86emuOp_mov_word_R_RM,
 
11571
/*  0x8c */ x86emuOp_mov_word_RM_SR,
 
11572
/*  0x8d */ x86emuOp_lea_word_R_M,
 
11573
/*  0x8e */ x86emuOp_mov_word_SR_RM,
 
11574
/*  0x8f */ x86emuOp_pop_RM,
 
11575
 
 
11576
/*  0x90 */ x86emuOp_nop,
 
11577
/*  0x91 */ x86emuOp_xchg_word_AX_CX,
 
11578
/*  0x92 */ x86emuOp_xchg_word_AX_DX,
 
11579
/*  0x93 */ x86emuOp_xchg_word_AX_BX,
 
11580
/*  0x94 */ x86emuOp_xchg_word_AX_SP,
 
11581
/*  0x95 */ x86emuOp_xchg_word_AX_BP,
 
11582
/*  0x96 */ x86emuOp_xchg_word_AX_SI,
 
11583
/*  0x97 */ x86emuOp_xchg_word_AX_DI,
 
11584
 
 
11585
/*  0x98 */ x86emuOp_cbw,
 
11586
/*  0x99 */ x86emuOp_cwd,
 
11587
/*  0x9a */ x86emuOp_call_far_IMM,
 
11588
/*  0x9b */ x86emuOp_wait,
 
11589
/*  0x9c */ x86emuOp_pushf_word,
 
11590
/*  0x9d */ x86emuOp_popf_word,
 
11591
/*  0x9e */ x86emuOp_sahf,
 
11592
/*  0x9f */ x86emuOp_lahf,
 
11593
 
 
11594
/*  0xa0 */ x86emuOp_mov_AL_M_IMM,
 
11595
/*  0xa1 */ x86emuOp_mov_AX_M_IMM,
 
11596
/*  0xa2 */ x86emuOp_mov_M_AL_IMM,
 
11597
/*  0xa3 */ x86emuOp_mov_M_AX_IMM,
 
11598
/*  0xa4 */ x86emuOp_movs_byte,
 
11599
/*  0xa5 */ x86emuOp_movs_word,
 
11600
/*  0xa6 */ x86emuOp_cmps_byte,
 
11601
/*  0xa7 */ x86emuOp_cmps_word,
 
11602
/*  0xa8 */ x86emuOp_test_AL_IMM,
 
11603
/*  0xa9 */ x86emuOp_test_AX_IMM,
 
11604
/*  0xaa */ x86emuOp_stos_byte,
 
11605
/*  0xab */ x86emuOp_stos_word,
 
11606
/*  0xac */ x86emuOp_lods_byte,
 
11607
/*  0xad */ x86emuOp_lods_word,
 
11608
/*  0xac */ x86emuOp_scas_byte,
 
11609
/*  0xad */ x86emuOp_scas_word,
 
11610
 
 
11611
 
 
11612
/*  0xb0 */ x86emuOp_mov_byte_AL_IMM,
 
11613
/*  0xb1 */ x86emuOp_mov_byte_CL_IMM,
 
11614
/*  0xb2 */ x86emuOp_mov_byte_DL_IMM,
 
11615
/*  0xb3 */ x86emuOp_mov_byte_BL_IMM,
 
11616
/*  0xb4 */ x86emuOp_mov_byte_AH_IMM,
 
11617
/*  0xb5 */ x86emuOp_mov_byte_CH_IMM,
 
11618
/*  0xb6 */ x86emuOp_mov_byte_DH_IMM,
 
11619
/*  0xb7 */ x86emuOp_mov_byte_BH_IMM,
 
11620
 
 
11621
/*  0xb8 */ x86emuOp_mov_word_AX_IMM,
 
11622
/*  0xb9 */ x86emuOp_mov_word_CX_IMM,
 
11623
/*  0xba */ x86emuOp_mov_word_DX_IMM,
 
11624
/*  0xbb */ x86emuOp_mov_word_BX_IMM,
 
11625
/*  0xbc */ x86emuOp_mov_word_SP_IMM,
 
11626
/*  0xbd */ x86emuOp_mov_word_BP_IMM,
 
11627
/*  0xbe */ x86emuOp_mov_word_SI_IMM,
 
11628
/*  0xbf */ x86emuOp_mov_word_DI_IMM,
 
11629
 
 
11630
/*  0xc0 */ x86emuOp_opcC0_byte_RM_MEM,
 
11631
/*  0xc1 */ x86emuOp_opcC1_word_RM_MEM,
 
11632
/*  0xc2 */ x86emuOp_ret_near_IMM,
 
11633
/*  0xc3 */ x86emuOp_ret_near,
 
11634
/*  0xc4 */ x86emuOp_les_R_IMM,
 
11635
/*  0xc5 */ x86emuOp_lds_R_IMM,
 
11636
/*  0xc6 */ x86emuOp_mov_byte_RM_IMM,
 
11637
/*  0xc7 */ x86emuOp_mov_word_RM_IMM,
 
11638
/*  0xc8 */ x86emuOp_enter,
 
11639
/*  0xc9 */ x86emuOp_leave,
 
11640
/*  0xca */ x86emuOp_ret_far_IMM,
 
11641
/*  0xcb */ x86emuOp_ret_far,
 
11642
/*  0xcc */ x86emuOp_int3,
 
11643
/*  0xcd */ x86emuOp_int_IMM,
 
11644
/*  0xce */ x86emuOp_into,
 
11645
/*  0xcf */ x86emuOp_iret,
 
11646
 
 
11647
/*  0xd0 */ x86emuOp_opcD0_byte_RM_1,
 
11648
/*  0xd1 */ x86emuOp_opcD1_word_RM_1,
 
11649
/*  0xd2 */ x86emuOp_opcD2_byte_RM_CL,
 
11650
/*  0xd3 */ x86emuOp_opcD3_word_RM_CL,
 
11651
/*  0xd4 */ x86emuOp_aam,
 
11652
/*  0xd5 */ x86emuOp_aad,
 
11653
/*  0xd6 */ x86emuOp_illegal_op,   /* Undocumented SETALC instruction */
 
11654
/*  0xd7 */ x86emuOp_xlat,
 
11655
/*  0xd8 */ x86emuOp_esc_coprocess_d8,
 
11656
/*  0xd9 */ x86emuOp_esc_coprocess_d9,
 
11657
/*  0xda */ x86emuOp_esc_coprocess_da,
 
11658
/*  0xdb */ x86emuOp_esc_coprocess_db,
 
11659
/*  0xdc */ x86emuOp_esc_coprocess_dc,
 
11660
/*  0xdd */ x86emuOp_esc_coprocess_dd,
 
11661
/*  0xde */ x86emuOp_esc_coprocess_de,
 
11662
/*  0xdf */ x86emuOp_esc_coprocess_df,
 
11663
 
 
11664
/*  0xe0 */ x86emuOp_loopne,
 
11665
/*  0xe1 */ x86emuOp_loope,
 
11666
/*  0xe2 */ x86emuOp_loop,
 
11667
/*  0xe3 */ x86emuOp_jcxz,
 
11668
/*  0xe4 */ x86emuOp_in_byte_AL_IMM,
 
11669
/*  0xe5 */ x86emuOp_in_word_AX_IMM,
 
11670
/*  0xe6 */ x86emuOp_out_byte_IMM_AL,
 
11671
/*  0xe7 */ x86emuOp_out_word_IMM_AX,
 
11672
 
 
11673
/*  0xe8 */ x86emuOp_call_near_IMM,
 
11674
/*  0xe9 */ x86emuOp_jump_near_IMM,
 
11675
/*  0xea */ x86emuOp_jump_far_IMM,
 
11676
/*  0xeb */ x86emuOp_jump_byte_IMM,
 
11677
/*  0xec */ x86emuOp_in_byte_AL_DX,
 
11678
/*  0xed */ x86emuOp_in_word_AX_DX,
 
11679
/*  0xee */ x86emuOp_out_byte_DX_AL,
 
11680
/*  0xef */ x86emuOp_out_word_DX_AX,
 
11681
 
 
11682
/*  0xf0 */ x86emuOp_lock,
 
11683
/*  0xf1 */ x86emuOp_illegal_op,
 
11684
/*  0xf2 */ x86emuOp_repne,
 
11685
/*  0xf3 */ x86emuOp_repe,
 
11686
/*  0xf4 */ x86emuOp_halt,
 
11687
/*  0xf5 */ x86emuOp_cmc,
 
11688
/*  0xf6 */ x86emuOp_opcF6_byte_RM,
 
11689
/*  0xf7 */ x86emuOp_opcF7_word_RM,
 
11690
 
 
11691
/*  0xf8 */ x86emuOp_clc,
 
11692
/*  0xf9 */ x86emuOp_stc,
 
11693
/*  0xfa */ x86emuOp_cli,
 
11694
/*  0xfb */ x86emuOp_sti,
 
11695
/*  0xfc */ x86emuOp_cld,
 
11696
/*  0xfd */ x86emuOp_std,
 
11697
/*  0xfe */ x86emuOp_opcFE_byte_RM,
 
11698
/*  0xff */ x86emuOp_opcFF_word_RM,
 
11699
};