OSDN Git Service

[COMMONDEV][I386] Fix breaks variable area when constructing cycle-tables.Seems to...
[csp-qt/common_source_project-fm7.git] / source / src / vm / libcpu_newdev / libcpu_i386 / i386_opdef.h
1
2 #ifndef __LIB_I386_OPDEF_H__
3 #define __LIB_I386_OPDEF_H__
4
5 #include "../../../common.h"
6 #ifndef __BIG_ENDIAN__
7 #define LSB_FIRST
8 #endif
9 #include "../../../fileio.h"
10 #include "../device.h"
11 #include "./i386priv.h"
12 #include "./i386ops.h"
13 #include "./vtlb.h"
14
15 #ifndef INLINE
16 #define INLINE inline
17 #endif
18
19 #define U64(v) UINT64(v)
20
21 #define fatalerror(...) exit(1)
22 #define logerror(...)
23 #define popmessage(...)
24
25 #define X86_NUM_CPUS        4
26 #define CPU_CYCLES_I386         0
27 #define CPU_CYCLES_I486         1
28 #define CPU_CYCLES_PENTIUM      2
29 #define CPU_CYCLES_MEDIAGX      3
30
31 enum X86_CYCLES
32 {
33         CYCLES_MOV_REG_REG,
34         CYCLES_MOV_REG_MEM,
35         CYCLES_MOV_MEM_REG,
36         CYCLES_MOV_IMM_REG,
37         CYCLES_MOV_IMM_MEM,
38         CYCLES_MOV_ACC_MEM,
39         CYCLES_MOV_MEM_ACC,
40         CYCLES_MOV_REG_SREG,
41         CYCLES_MOV_MEM_SREG,
42         CYCLES_MOV_SREG_REG,
43         CYCLES_MOV_SREG_MEM,
44         CYCLES_MOVSX_REG_REG,
45         CYCLES_MOVSX_MEM_REG,
46         CYCLES_MOVZX_REG_REG,
47         CYCLES_MOVZX_MEM_REG,
48         CYCLES_PUSH_RM,
49         CYCLES_PUSH_REG_SHORT,
50         CYCLES_PUSH_SREG,
51         CYCLES_PUSH_IMM,
52         CYCLES_PUSHA,
53         CYCLES_POP_RM,
54         CYCLES_POP_REG_SHORT,
55         CYCLES_POP_SREG,
56         CYCLES_POPA,
57         CYCLES_XCHG_REG_REG,
58         CYCLES_XCHG_REG_MEM,
59         CYCLES_IN,
60         CYCLES_IN_VAR,
61         CYCLES_OUT,
62         CYCLES_OUT_VAR,
63         CYCLES_LEA,
64         CYCLES_LDS,
65         CYCLES_LES,
66         CYCLES_LFS,
67         CYCLES_LGS,
68         CYCLES_LSS,
69         CYCLES_CLC,
70         CYCLES_CLD,
71         CYCLES_CLI,
72         CYCLES_CLTS,
73         CYCLES_CMC,
74         CYCLES_LAHF,
75         CYCLES_POPF,
76         CYCLES_PUSHF,
77         CYCLES_SAHF,
78         CYCLES_STC,
79         CYCLES_STD,
80         CYCLES_STI,
81         CYCLES_ALU_REG_REG,
82         CYCLES_ALU_REG_MEM,
83         CYCLES_ALU_MEM_REG,
84         CYCLES_ALU_IMM_REG,
85         CYCLES_ALU_IMM_MEM,
86         CYCLES_ALU_IMM_ACC,
87         CYCLES_INC_REG,
88         CYCLES_INC_MEM,
89         CYCLES_DEC_REG,
90         CYCLES_DEC_MEM,
91         CYCLES_CMP_REG_REG,
92         CYCLES_CMP_REG_MEM,
93         CYCLES_CMP_MEM_REG,
94         CYCLES_CMP_IMM_REG,
95         CYCLES_CMP_IMM_MEM,
96         CYCLES_CMP_IMM_ACC,
97         CYCLES_TEST_REG_REG,
98         CYCLES_TEST_REG_MEM,
99         CYCLES_TEST_IMM_REG,
100         CYCLES_TEST_IMM_MEM,
101         CYCLES_TEST_IMM_ACC,
102         CYCLES_NEG_REG,
103         CYCLES_NEG_MEM,
104         CYCLES_AAA,
105         CYCLES_AAS,
106         CYCLES_DAA,
107         CYCLES_DAS,
108         CYCLES_MUL8_ACC_REG,
109         CYCLES_MUL8_ACC_MEM,
110         CYCLES_MUL16_ACC_REG,
111         CYCLES_MUL16_ACC_MEM,
112         CYCLES_MUL32_ACC_REG,
113         CYCLES_MUL32_ACC_MEM,
114         CYCLES_IMUL8_ACC_REG,
115         CYCLES_IMUL8_ACC_MEM,
116         CYCLES_IMUL16_ACC_REG,
117         CYCLES_IMUL16_ACC_MEM,
118         CYCLES_IMUL32_ACC_REG,
119         CYCLES_IMUL32_ACC_MEM,
120         CYCLES_IMUL8_REG_REG,
121         CYCLES_IMUL8_REG_MEM,
122         CYCLES_IMUL16_REG_REG,
123         CYCLES_IMUL16_REG_MEM,
124         CYCLES_IMUL32_REG_REG,
125         CYCLES_IMUL32_REG_MEM,
126         CYCLES_IMUL16_REG_IMM_REG,
127         CYCLES_IMUL16_MEM_IMM_REG,
128         CYCLES_IMUL32_REG_IMM_REG,
129         CYCLES_IMUL32_MEM_IMM_REG,
130         CYCLES_DIV8_ACC_REG,
131         CYCLES_DIV8_ACC_MEM,
132         CYCLES_DIV16_ACC_REG,
133         CYCLES_DIV16_ACC_MEM,
134         CYCLES_DIV32_ACC_REG,
135         CYCLES_DIV32_ACC_MEM,
136         CYCLES_IDIV8_ACC_REG,
137         CYCLES_IDIV8_ACC_MEM,
138         CYCLES_IDIV16_ACC_REG,
139         CYCLES_IDIV16_ACC_MEM,
140         CYCLES_IDIV32_ACC_REG,
141         CYCLES_IDIV32_ACC_MEM,
142         CYCLES_AAD,
143         CYCLES_AAM,
144         CYCLES_CBW,
145         CYCLES_CWD,
146         CYCLES_ROTATE_REG,
147         CYCLES_ROTATE_MEM,
148         CYCLES_ROTATE_CARRY_REG,
149         CYCLES_ROTATE_CARRY_MEM,
150         CYCLES_SHLD_REG,
151         CYCLES_SHLD_MEM,
152         CYCLES_SHRD_REG,
153         CYCLES_SHRD_MEM,
154         CYCLES_NOT_REG,
155         CYCLES_NOT_MEM,
156         CYCLES_CMPS,
157         CYCLES_INS,
158         CYCLES_LODS,
159         CYCLES_MOVS,
160         CYCLES_OUTS,
161         CYCLES_SCAS,
162         CYCLES_STOS,
163         CYCLES_XLAT,
164         CYCLES_REP_CMPS_BASE,
165         CYCLES_REP_INS_BASE,
166         CYCLES_REP_LODS_BASE,
167         CYCLES_REP_MOVS_BASE,
168         CYCLES_REP_OUTS_BASE,
169         CYCLES_REP_SCAS_BASE,
170         CYCLES_REP_STOS_BASE,
171         CYCLES_REP_CMPS,
172         CYCLES_REP_INS,
173         CYCLES_REP_LODS,
174         CYCLES_REP_MOVS,
175         CYCLES_REP_OUTS,
176         CYCLES_REP_SCAS,
177         CYCLES_REP_STOS,
178         CYCLES_BSF_BASE,
179         CYCLES_BSF,
180         CYCLES_BSR_BASE,
181         CYCLES_BSR,
182         CYCLES_BT_IMM_REG,
183         CYCLES_BT_IMM_MEM,
184         CYCLES_BT_REG_REG,
185         CYCLES_BT_REG_MEM,
186         CYCLES_BTC_IMM_REG,
187         CYCLES_BTC_IMM_MEM,
188         CYCLES_BTC_REG_REG,
189         CYCLES_BTC_REG_MEM,
190         CYCLES_BTR_IMM_REG,
191         CYCLES_BTR_IMM_MEM,
192         CYCLES_BTR_REG_REG,
193         CYCLES_BTR_REG_MEM,
194         CYCLES_BTS_IMM_REG,
195         CYCLES_BTS_IMM_MEM,
196         CYCLES_BTS_REG_REG,
197         CYCLES_BTS_REG_MEM,
198         CYCLES_CALL,                // E8
199         CYCLES_CALL_REG,            // FF /2
200         CYCLES_CALL_MEM,            // FF /2
201         CYCLES_CALL_INTERSEG,       // 9A
202         CYCLES_CALL_REG_INTERSEG,   // FF /3
203         CYCLES_CALL_MEM_INTERSEG,   // FF /3
204         CYCLES_JMP_SHORT,           // EB
205         CYCLES_JMP,                 // E9
206         CYCLES_JMP_REG,             // FF /4
207         CYCLES_JMP_MEM,             // FF /4
208         CYCLES_JMP_INTERSEG,        // EA
209         CYCLES_JMP_REG_INTERSEG,    // FF /5
210         CYCLES_JMP_MEM_INTERSEG,    // FF /5
211         CYCLES_RET,                 // C3
212         CYCLES_RET_IMM,             // C2
213         CYCLES_RET_INTERSEG,        // CB
214         CYCLES_RET_IMM_INTERSEG,    // CA
215         CYCLES_JCC_DISP8,
216         CYCLES_JCC_FULL_DISP,
217         CYCLES_JCC_DISP8_NOBRANCH,
218         CYCLES_JCC_FULL_DISP_NOBRANCH,
219         CYCLES_JCXZ,
220         CYCLES_JCXZ_NOBRANCH,
221         CYCLES_LOOP,
222         CYCLES_LOOPZ,
223         CYCLES_LOOPNZ,
224         CYCLES_SETCC_REG,
225         CYCLES_SETCC_MEM,
226         CYCLES_ENTER,
227         CYCLES_LEAVE,
228         CYCLES_INT,
229         CYCLES_INT3,
230         CYCLES_INTO_OF1,
231         CYCLES_INTO_OF0,
232         CYCLES_BOUND_IN_RANGE,
233         CYCLES_BOUND_OUT_RANGE,
234         CYCLES_IRET,
235         CYCLES_HLT,
236         CYCLES_MOV_REG_CR0,
237         CYCLES_MOV_REG_CR2,
238         CYCLES_MOV_REG_CR3,
239         CYCLES_MOV_CR_REG,
240         CYCLES_MOV_REG_DR0_3,
241         CYCLES_MOV_REG_DR6_7,
242         CYCLES_MOV_DR6_7_REG,
243         CYCLES_MOV_DR0_3_REG,
244         CYCLES_MOV_REG_TR6_7,
245         CYCLES_MOV_TR6_7_REG,
246         CYCLES_NOP,
247         CYCLES_WAIT,
248         CYCLES_ARPL_REG,
249         CYCLES_ARPL_MEM,
250         CYCLES_LAR_REG,
251         CYCLES_LAR_MEM,
252         CYCLES_LGDT,
253         CYCLES_LIDT,
254         CYCLES_LLDT_REG,
255         CYCLES_LLDT_MEM,
256         CYCLES_LMSW_REG,
257         CYCLES_LMSW_MEM,
258         CYCLES_LSL_REG,
259         CYCLES_LSL_MEM,
260         CYCLES_LTR_REG,
261         CYCLES_LTR_MEM,
262         CYCLES_SGDT,
263         CYCLES_SIDT,
264         CYCLES_SLDT_REG,
265         CYCLES_SLDT_MEM,
266         CYCLES_SMSW_REG,
267         CYCLES_SMSW_MEM,
268         CYCLES_STR_REG,
269         CYCLES_STR_MEM,
270         CYCLES_VERR_REG,
271         CYCLES_VERR_MEM,
272         CYCLES_VERW_REG,
273         CYCLES_VERW_MEM,
274         CYCLES_LOCK,
275
276         CYCLES_BSWAP,
277         CYCLES_CMPXCHG8B,
278         CYCLES_CMPXCHG,
279         CYCLES_CPUID,
280         CYCLES_CPUID_EAX1,
281         CYCLES_INVD,
282         CYCLES_XADD,
283         CYCLES_RDTSC,
284         CYCLES_RSM,
285         CYCLES_RDMSR,
286
287         CYCLES_FABS,
288         CYCLES_FADD,
289         CYCLES_FBLD,
290         CYCLES_FBSTP,
291         CYCLES_FCHS,
292         CYCLES_FCLEX,
293         CYCLES_FCOM,
294         CYCLES_FCOS,
295         CYCLES_FDECSTP,
296         CYCLES_FDISI,
297         CYCLES_FDIV,
298         CYCLES_FDIVR,
299         CYCLES_FENI,
300         CYCLES_FFREE,
301         CYCLES_FIADD,
302         CYCLES_FICOM,
303         CYCLES_FIDIV,
304         CYCLES_FILD,
305         CYCLES_FIMUL,
306         CYCLES_FINCSTP,
307         CYCLES_FINIT,
308         CYCLES_FIST,
309         CYCLES_FISUB,
310         CYCLES_FLD,
311         CYCLES_FLDZ,
312         CYCLES_FLD1,
313         CYCLES_FLDL2E,
314         CYCLES_FLDL2T,
315         CYCLES_FLDLG2,
316         CYCLES_FLDLN2,
317         CYCLES_FLDPI,
318         CYCLES_FLDCW,
319         CYCLES_FLDENV,
320         CYCLES_FMUL,
321         CYCLES_FNOP,
322         CYCLES_FPATAN,
323         CYCLES_FPREM,
324         CYCLES_FPREM1,
325         CYCLES_FPTAN,
326         CYCLES_FRNDINT,
327         CYCLES_FRSTOR,
328         CYCLES_FSAVE,
329         CYCLES_FSCALE,
330         CYCLES_FSETPM,
331         CYCLES_FSIN,
332         CYCLES_FSINCOS,
333         CYCLES_FSQRT,
334         CYCLES_FST,
335         CYCLES_FSTCW,
336         CYCLES_FSTENV,
337         CYCLES_FSTSW,
338         CYCLES_FSUB,
339         CYCLES_FSUBR,
340         CYCLES_FTST,
341         CYCLES_FUCOM,
342         CYCLES_FXAM,
343         CYCLES_FXCH,
344         CYCLES_FXTRACT,
345         CYCLES_FYL2X,
346         CYCLES_FYL2XPI,
347         CYCLES_CMPXCHG_REG_REG_T,
348         CYCLES_CMPXCHG_REG_REG_F,
349         CYCLES_CMPXCHG_REG_MEM_T,
350         CYCLES_CMPXCHG_REG_MEM_F,
351         CYCLES_XADD_REG_REG,
352         CYCLES_XADD_REG_MEM,
353
354         CYCLES_NUM_OPCODES
355 };
356
357 struct X86_CYCLE_TABLE
358 {
359         X86_CYCLES op;
360         UINT8 cpu_cycles[X86_NUM_CPUS][2];
361 };
362
363 /*************************************
364  *
365  * Defines
366  *
367  *************************************/
368
369 #define X87_SW_IE               0x0001
370 #define X87_SW_DE               0x0002
371 #define X87_SW_ZE               0x0004
372 #define X87_SW_OE               0x0008
373 #define X87_SW_UE               0x0010
374 #define X87_SW_PE               0x0020
375 #define X87_SW_SF               0x0040
376 #define X87_SW_ES               0x0080
377 #define X87_SW_C0               0x0100
378 #define X87_SW_C1               0x0200
379 #define X87_SW_C2               0x0400
380 #define X87_SW_TOP_SHIFT        11
381 #define X87_SW_TOP_MASK         7
382 #define X87_SW_C3               0x4000
383 #define X87_SW_BUSY             0x8000
384
385 #define X87_CW_IM               0x0001
386 #define X87_CW_DM               0x0002
387 #define X87_CW_ZM               0x0004
388 #define X87_CW_OM               0x0008
389 #define X87_CW_UM               0x0010
390 #define X87_CW_PM               0x0020
391 #define X87_CW_PC_SHIFT         8
392 #define X87_CW_PC_MASK          3
393 #define X87_CW_PC_SINGLE        0
394 #define X87_CW_PC_DOUBLE        2
395 #define X87_CW_PC_EXTEND        3
396 #define X87_CW_RC_SHIFT         10
397 #define X87_CW_RC_MASK          3
398 #define X87_CW_RC_NEAREST       0
399 #define X87_CW_RC_DOWN          1
400 #define X87_CW_RC_UP            2
401 #define X87_CW_RC_ZERO          3
402
403 #define X87_TW_MASK             3
404 #define X87_TW_VALID            0
405 #define X87_TW_ZERO             1
406 #define X87_TW_SPECIAL          2
407 #define X87_TW_EMPTY            3
408
409
410 /*************************************
411  *
412  * Macros
413  *
414  *************************************/
415
416 #define ST_TO_PHYS(x)           (((cpustate->x87_sw >> X87_SW_TOP_SHIFT) + (x)) & X87_SW_TOP_MASK)
417 #define ST(x)                   (cpustate->x87_reg[ST_TO_PHYS(x)])
418 #define X87_TW_FIELD_SHIFT(x)   ((x) << 1)
419 #define X87_TAG(x)              ((cpustate->x87_tw >> X87_TW_FIELD_SHIFT(x)) & X87_TW_MASK)
420 #define X87_RC                  ((cpustate->x87_cw >> X87_CW_RC_SHIFT) & X87_CW_RC_MASK)
421 #define X87_IS_ST_EMPTY(x)      (X87_TAG(ST_TO_PHYS(x)) == X87_TW_EMPTY)
422 #define X87_SW_C3_0             X87_SW_C0
423
424 #define UNIMPLEMENTED           fatalerror("Unimplemented x87 op: %s (PC:%x)\n", __FUNCTION__, cpustate->pc)
425
426 /*****************************************************************************/
427 /* src/emu/devcpu.h */
428
429 // CPU interface functions
430 #define CPU_INIT_NAME(name)                     I386_OPS_BASE::cpu_init_##name
431 #define CPU_INIT(name)                          void* CPU_INIT_NAME(name)()
432 #define CPU_INIT_CALL_NAME(name)        cpu_init_##name
433 #define CPU_INIT_CALL(name)                     CPU_INIT_CALL_NAME(name)()
434
435 #define CPU_RESET_NAME(name)            I386_OPS_BASE::cpu_reset_##name
436 #define CPU_RESET(name)                         void CPU_RESET_NAME(name)()
437 #define CPU_RESET_CALL_NAME(name)       cpu_reset_##name
438 #define CPU_RESET_CALL(name)            CPU_RESET_CALL_NAME(name)()
439
440 #define CPU_EXECUTE_NAME(name)          I386_OPS_BASE::cpu_execute_##name
441 #define CPU_EXECUTE(name)                       int CPU_EXECUTE_NAME(name)(int cycles)
442 #define CPU_EXECUTE_CALL_NAME(name)     cpu_execute_##name
443 #define CPU_EXECUTE_CALL(name)          CPU_EXECUTE_CALL_NAME(name)(cycles)
444
445 #define CPU_TRANSLATE_NAME(name)        I386_OPS_BASE::cpu_translate_##name
446 #define CPU_TRANSLATE(name)                     int CPU_TRANSLATE_NAME(name)(void *cpudevice, address_spacenum space, int intention, offs_t *address)
447 #define CPU_TRANSLATE_CALL_NAME(name)   cpu_translate_##name
448 #define CPU_TRANSLATE_CALL(name)        CPU_TRANSLATE_CALL_NAME(name)(cpudevice, space, intention, address)
449
450 #define CPU_DISASSEMBLE_NAME(name)      I386_OPS_BASE::cpu_disassemble_##name
451 #define CPU_DISASSEMBLE(name)           int CPU_DISASSEMBLE_NAME(name)(_TCHAR *buffer, offs_t eip, const UINT8 *oprom)
452 #define CPU_DISASSEMBLE_CALL_NAME(name) cpu_disassemble_##name
453 #define CPU_DISASSEMBLE_CALL(name)      CPU_DISASSEMBLE_CALL_NAME(name)(buffer, eip, oprom)
454
455 /*****************************************************************************/
456 /* src/emu/didisasm.h */
457
458 // Disassembler constants
459 const UINT32 DASMFLAG_SUPPORTED     = 0x80000000;   // are disassembly flags supported?
460 const UINT32 DASMFLAG_STEP_OUT      = 0x40000000;   // this instruction should be the end of a step out sequence
461 const UINT32 DASMFLAG_STEP_OVER     = 0x20000000;   // this instruction should be stepped over by setting a breakpoint afterwards
462 const UINT32 DASMFLAG_OVERINSTMASK  = 0x18000000;   // number of extra instructions to skip when stepping over
463 const UINT32 DASMFLAG_OVERINSTSHIFT = 27;           // bits to shift after masking to get the value
464 const UINT32 DASMFLAG_LENGTHMASK    = 0x0000ffff;   // the low 16-bits contain the actual length
465
466 /*****************************************************************************/
467 /* src/emu/diexec.h */
468
469 // I/O line states
470 enum line_state
471 {
472         CLEAR_LINE = 0,                         // clear (a fired or held) line
473         ASSERT_LINE,                            // assert an interrupt immediately
474         HOLD_LINE,                              // hold interrupt line until acknowledged
475         PULSE_LINE                              // pulse interrupt line instantaneously (only for NMI, RESET)
476 };
477
478 enum
479 {
480         INPUT_LINE_IRQ = 0,
481         INPUT_LINE_NMI
482 };
483
484 /*****************************************************************************/
485 /* src/emu/dimemory.h */
486
487 enum {
488         I386_OPS_CPUTYPE_I386 = 0,
489         I386_OPS_CPUTYPE_I486,
490         I386_OPS_CPUTYPE_PENTIUM,
491         I386_OPS_CPUTYPE_MEDIAGX,
492         I386_OPS_CPUTYPE_PENTIUM_PRO,
493         I386_OPS_CPUTYPE_PENTIUM_MMX,
494         I386_OPS_CPUTYPE_PENTIUM2,
495         I386_OPS_CPUTYPE_PENTIUM3,
496         I386_OPS_CPUTYPE_PENTIUM4,
497         I386_OPS_CPUTYPE_IX87FPU,
498         I386_OPS_CPUTYPE_END
499 };
500
501 /************************************** vtlb.h ***************************************/
502
503 class DEBUG;
504 class I386_OPS_BASE {
505 protected:
506         i386_state *cpustate;
507         int _cputype;
508 // Parameters.
509         //const X86_CYCLE_TABLE *x86_cycle_table;
510         //const X86_OPCODE *x86_opcode_table;
511         //X86_OPCODE x86_opcode_table[];
512         
513         int i386_parity_table[256];
514         MODRM_TABLE i386_MODRM_table[256];
515         i386_state __cpustate;
516         UINT8 cycle_table_rm[X86_NUM_CPUS][CYCLES_NUM_OPCODES];
517         UINT8 cycle_table_pm[X86_NUM_CPUS][CYCLES_NUM_OPCODES];
518         const floatx80 fx80_zero =   { 0x0000, U64(0x0000000000000000) };
519         const floatx80 fx80_one =    { 0x3fff, U64(0x8000000000000000) };
520         const floatx80 fx80_ninf =   { 0xffff, U64(0x8000000000000000) };
521         const floatx80 fx80_inan =   { 0xffff, U64(0xc000000000000000) };
522 /* Maps x87 round modes to SoftFloat round modes */
523         const int x87_to_sf_rc[4] = {
524                 float_round_nearest_even,
525                 float_round_down,
526                 float_round_up,
527                 float_round_to_zero,
528         };
529         DEVICE *d_mem;
530         DEVICE *d_io;
531         DEVICE *d_pic;
532         DEVICE *d_bios;
533         DEVICE *d_dma;
534         
535         UINT32 i386_escape_ea;   // hack around GCC 4.6 error because we need the side effects of GetEA()
536 public:
537         I386_OPS_BASE(int cputypes = I386_OPS_CPUTYPE_I386)
538         {
539                 cpustate = NULL;
540                 _cputype = cputypes;
541         }
542         ~I386_OPS_BASE() {}
543         virtual void I386OP_D(decode_opcode)();
544         
545         int i386_translate_address(int intention, offs_t *address, vtlb_entry *entry);
546         virtual int cpu_translate_i386(void *cpudevice, address_spacenum space, int intention, offs_t *address);
547         virtual int cpu_execute_i386(int cycles);
548         virtual void i386_trap(int irq, int irq_gate, int trap_level);
549         virtual void i386_trap_with_error(int irq, int irq_gate, int trap_level, UINT32 error);
550         void i386_set_irq_line(int irqline, int state);
551         void i386_set_a20_line(int state);
552         int i386_limit_check( int seg, UINT32 offset);
553         void i386_vtlb_free(void);
554         void i386_free_state(void);
555
556         int get_extra_clock() { return cpustate->extra_cycles; }
557         void set_extra_clock(int n) { cpustate->extra_cycles += n; }
558
559         uint32_t get_pc() { return cpustate->pc; }
560         uint32_t get_prev_pc() { return cpustate->prev_pc; }
561         void set_address_mask(uint32_t mask) { cpustate->a20_mask = mask; }
562         uint32_t get_address_mask() { return cpustate->a20_mask; }
563         void  set_shutdown_flag(int n) { cpustate->shutdown = n; }
564         int get_shutdown_flag() { return cpustate->shutdown; }
565
566         void set_busreq(bool n) { cpustate->busreq = n ? 1 : 0; }
567         bool get_busreq() { return cpustate->busreq; }
568         INLINE void check_ioperm( offs_t port, UINT8 mask);
569
570         void set_context_pic(DEVICE *dev) {
571                 cpustate->pic = dev;
572                 d_pic = dev;
573         }
574         virtual void set_context_progmem_stored(DEVICE *dev) {
575                 //cpustate->program_stored = dev;
576         }
577         void set_context_progmem(DEVICE *dev) {
578                 cpustate->program = dev;
579                 d_mem = dev;
580         }
581
582         virtual void set_context_pseudo_bios(DEVICE *dev) {
583                 //cpustate->bios = dev;
584                 //d_bios = dev;
585         }
586
587         virtual void set_context_dma(DEVICE *dev) {
588                 //cpustate->dma = dev;
589                 //d_dma = dev;
590         }
591
592         void set_context_io(DEVICE *dev) {
593                 cpustate->io = dev;
594                 d_io = dev;
595         }
596         
597         virtual void set_context_io_stored(DEVICE *dev) {
598                 //cpustate->io_stored = dev;
599                 
600         }
601
602         virtual void set_context_emu(EMU *p_emu) {
603                 //cpustate->emu = p_emu;
604         }
605
606         virtual void set_context_debugger(DEBUGGER *debugger) {
607                 //cpustate->debugger = dev;
608         }
609         
610         virtual bool write_debug_reg(const _TCHAR *reg, uint32_t data) { return false; }
611         virtual void get_debug_regs_info(_TCHAR *buffer, size_t buffer_len) {};
612         virtual int debug_dasm(uint32_t pc, _TCHAR *buffer, size_t buffer_len) { return 0;}
613
614         void save_state(FILEIO *state_fio);
615         bool load_state(FILEIO *state_fio);
616         
617 protected:
618         // Utilities
619         void build_cycle_table();
620         virtual i386_state *i386_common_init(int tlbsize);
621         void build_opcode_table( UINT32 features);
622         void zero_state();
623         void pentium_smi();
624         
625         UINT32 i386_load_protected_mode_segment( I386_SREG *seg, UINT64 *desc );
626         void i386_load_call_gate(I386_CALL_GATE *gate);
627         void i386_set_descriptor_accessed( UINT16 selector);
628         void i386_load_segment_descriptor( int segment );
629         UINT32 i386_get_stack_segment(UINT8 privilege);
630         UINT32 i386_get_stack_ptr(UINT8 privilege);
631         
632         UINT32 get_flags();
633         void set_flags( UINT32 f );
634
635         void sib_byte(UINT8 mod, UINT32* out_ea, UINT8* out_segment);
636         void modrm_to_EA(UINT8 mod_rm, UINT32* out_ea, UINT8* out_segment);
637         
638         UINT32 GetNonTranslatedEA(UINT8 modrm,UINT8 *seg);
639         UINT32 GetEA(UINT8 modrm, int rwn);
640
641         // 
642         void i386_check_sreg_validity(int reg);
643         void i386_sreg_load( UINT16 selector, UINT8 reg, bool *fault);
644         void i286_task_switch( UINT16 selector, UINT8 nested);
645         void i386_task_switch( UINT16 selector, UINT8 nested);
646         void i386_check_irq_line();
647         
648         void i386_protected_mode_jump( UINT16 seg, UINT32 off, int indirect, int operand32);
649         void i386_protected_mode_call( UINT16 seg, UINT32 off, int indirect, int operand32);
650         void i386_protected_mode_retf(UINT8 count, UINT8 operand32);
651         void i386_protected_mode_iret(int operand32);
652
653         // Reporter.
654         void report_invalid_opcode();
655         void report_invalid_modrm(const char* opcode, UINT8 modrm);
656
657         //LINES
658         void i386_postload();
659
660         /* ----- initialization/teardown ----- */
661         /* allocate a new VTLB for the given CPU */
662         vtlb_state *vtlb_alloc(void *cpu, address_spacenum space, int fixed_entries, int dynamic_entries);
663         /* free an allocated VTLB */
664         void vtlb_free(vtlb_state *vtlb);
665         
666         /* called by the CPU core in response to an unmapped access */
667         int vtlb_fill(vtlb_state *vtlb, offs_t address, int intention);
668         /* load a fixed VTLB entry */
669         void vtlb_load(vtlb_state *vtlb, int entrynum, int numpages, offs_t address, vtlb_entry value);
670         /* load a dynamic VTLB entry */
671         void vtlb_dynload(vtlb_state *vtlb, UINT32 index, offs_t address, vtlb_entry value);
672         /* ----- flushing ----- */
673         /* flush all knowledge from the dynamic part of the VTLB */
674         void vtlb_flush_dynamic(vtlb_state *vtlb);
675         /* flush knowledge of a particular address from the VTLB */
676         void vtlb_flush_address(vtlb_state *vtlb, offs_t address);
677         /* ----- accessors ----- */
678         /* return a pointer to the base of the linear VTLB lookup table */
679         const vtlb_entry *vtlb_table(vtlb_state *vtlb);
680
681         virtual int cpu_disassemble_x86_16(_TCHAR *buffer, UINT64 eip, const UINT8 *oprom) { return 0; }
682         virtual int cpu_disassemble_x86_32(_TCHAR *buffer, UINT64 eip, const UINT8 *oprom) { return 0; }
683         virtual int cpu_disassemble_x86_64(_TCHAR *buffer, UINT64 eip, const UINT8 *oprom) { return 0; }
684 public:
685         // Init per vm..
686         void *cpu_init_i386(void);
687         void *cpu_init_i486(void);
688         void *cpu_init_pentium(void);
689         void *cpu_init_mediagx(void);
690         void *cpu_init_pentium_pro(void);
691         void *cpu_init_pentium_mmx(void);
692         void *cpu_init_pentium2(void);
693         void *cpu_init_pentium3(void);
694         void *cpu_init_pentium4(void);
695         // Reset pewr type.
696         void cpu_reset_i386(void);
697         void cpu_reset_i486(void);
698         void cpu_reset_pentium(void);
699         void cpu_reset_mediagx(void);
700         void cpu_reset_pentium_pro(void);
701         void cpu_reset_pentium_mmx(void);
702         void cpu_reset_pentium2(void);
703         void cpu_reset_pentium3(void);
704         void cpu_reset_pentium4(void);
705
706         // INSNs.
707         // i386/op16
708         void I386OP_D(adc_rm16_r16)();      // Opcode 0x11
709         void I386OP_D(adc_r16_rm16)();      // Opcode 0x13
710         void I386OP_D(adc_ax_i16)();        // Opcode 0x15
711         void I386OP_D(add_rm16_r16)();      // Opcode 0x01
712         void I386OP_D(add_r16_rm16)();      // Opcode 0x03
713         void I386OP_D(add_ax_i16)();        // Opcode 0x05
714         void I386OP_D(and_rm16_r16)();      // Opcode 0x21
715         void I386OP_D(and_r16_rm16)();      // Opcode 0x23
716         void I386OP_D(and_ax_i16)();        // Opcode 0x25
717         void I386OP_D(bsf_r16_rm16)();      // Opcode 0x0f bc
718         void I386OP_D(bsr_r16_rm16)();      // Opcode 0x0f bd
719         void I386OP_D(bt_rm16_r16)();       // Opcode 0x0f a3
720         void I386OP_D(btc_rm16_r16)();      // Opcode 0x0f bb
721         void I386OP_D(btr_rm16_r16)();      // Opcode 0x0f b3
722         void I386OP_D(bts_rm16_r16)();      // Opcode 0x0f ab
723         virtual void I386OP_D(call_abs16)();        // Opcode 0x9a
724         virtual void I386OP_D(call_rel16)();        // Opcode 0xe8
725         void I386OP_D(cbw)();               // Opcode 0x98
726         void I386OP_D(cmp_rm16_r16)();      // Opcode 0x39
727         void I386OP_D(cmp_r16_rm16)();      // Opcode 0x3b
728         void I386OP_D(cmp_ax_i16)();        // Opcode 0x3d
729         void I386OP_D(cmpsw)();             // Opcode 0xa7
730         void I386OP_D(cwd)();               // Opcode 0x99
731         void I386OP_D(dec_ax)();            // Opcode 0x48
732         void I386OP_D(dec_cx)();            // Opcode 0x49
733         void I386OP_D(dec_dx)();            // Opcode 0x4a
734         void I386OP_D(dec_bx)();            // Opcode 0x4b
735         void I386OP_D(dec_sp)();            // Opcode 0x4c
736         void I386OP_D(dec_bp)();            // Opcode 0x4d
737         void I386OP_D(dec_si)();            // Opcode 0x4e
738         void I386OP_D(dec_di)();            // Opcode 0x4f
739         void I386OP_D(imul_r16_rm16)();     // Opcode 0x0f af
740         void I386OP_D(imul_r16_rm16_i16)(); // Opcode 0x69
741         void I386OP_D(imul_r16_rm16_i8)();  // Opcode 0x6b
742         void I386OP_D(in_ax_i8)();          // Opcode 0xe5
743         void I386OP_D(in_ax_dx)();          // Opcode 0xed
744         void I386OP_D(inc_ax)();            // Opcode 0x40
745         void I386OP_D(inc_cx)();            // Opcode 0x41
746         void I386OP_D(inc_dx)();            // Opcode 0x42
747         void I386OP_D(inc_bx)();            // Opcode 0x43
748         void I386OP_D(inc_sp)();            // Opcode 0x44
749         void I386OP_D(inc_bp)();            // Opcode 0x45
750         void I386OP_D(inc_si)();            // Opcode 0x46
751         void I386OP_D(inc_di)();            // Opcode 0x47
752         void I386OP_D(iret16)();            // Opcode 0xcf
753         void I386OP_D(ja_rel16)();          // Opcode 0x0f 87
754         void I386OP_D(jbe_rel16)();         // Opcode 0x0f 86
755         void I386OP_D(jc_rel16)();          // Opcode 0x0f 82
756         void I386OP_D(jg_rel16)();          // Opcode 0x0f 8f
757         void I386OP_D(jge_rel16)();         // Opcode 0x0f 8d
758         void I386OP_D(jl_rel16)();          // Opcode 0x0f 8c
759         void I386OP_D(jle_rel16)();         // Opcode 0x0f 8e
760         void I386OP_D(jnc_rel16)();         // Opcode 0x0f 83
761         void I386OP_D(jno_rel16)();         // Opcode 0x0f 81
762         void I386OP_D(jnp_rel16)();         // Opcode 0x0f 8b
763         void I386OP_D(jns_rel16)();         // Opcode 0x0f 89
764         void I386OP_D(jnz_rel16)();         // Opcode 0x0f 85
765         void I386OP_D(jo_rel16)();          // Opcode 0x0f 80
766         void I386OP_D(jp_rel16)();          // Opcode 0x0f 8a
767         void I386OP_D(js_rel16)();          // Opcode 0x0f 88
768         void I386OP_D(jz_rel16)();          // Opcode 0x0f 84
769         void I386OP_D(jcxz16)();            // Opcode 0xe3
770         void I386OP_D(jmp_rel16)();         // Opcode 0xe9
771         void I386OP_D(jmp_abs16)();         // Opcode 0xea
772         void I386OP_D(lea16)();             // Opcode 0x8d
773         void I386OP_D(enter16)();           // Opcode 0xc8
774         void I386OP_D(leave16)();           // Opcode 0xc9
775         void I386OP_D(lodsw)();             // Opcode 0xad
776         void I386OP_D(loop16)();            // Opcode 0xe2
777         void I386OP_D(loopne16)();          // Opcode 0xe0
778         void I386OP_D(loopz16)();           // Opcode 0xe1
779         void I386OP_D(mov_rm16_r16)();      // Opcode 0x89
780         void I386OP_D(mov_r16_rm16)();      // Opcode 0x8b
781         void I386OP_D(mov_rm16_i16)();      // Opcode 0xc7
782         void I386OP_D(mov_ax_m16)();        // Opcode 0xa1
783         void I386OP_D(mov_m16_ax)();        // Opcode 0xa3
784         void I386OP_D(mov_ax_i16)();        // Opcode 0xb8
785         void I386OP_D(mov_cx_i16)();        // Opcode 0xb9
786         void I386OP_D(mov_dx_i16)();        // Opcode 0xba
787         void I386OP_D(mov_bx_i16)();        // Opcode 0xbb
788         void I386OP_D(mov_sp_i16)();        // Opcode 0xbc
789         void I386OP_D(mov_bp_i16)();        // Opcode 0xbd
790         void I386OP_D(mov_si_i16)();        // Opcode 0xbe
791         void I386OP_D(mov_di_i16)();        // Opcode 0xbf
792         void I386OP_D(movsw)();             // Opcode 0xa5
793         void I386OP_D(movsx_r16_rm8)();     // Opcode 0x0f be
794         void I386OP_D(movzx_r16_rm8)();     // Opcode 0x0f b6
795         void I386OP_D(or_rm16_r16)();       // Opcode 0x09
796         void I386OP_D(or_r16_rm16)();       // Opcode 0x0b
797         void I386OP_D(or_ax_i16)();         // Opcode 0x0d
798         void I386OP_D(out_ax_i8)();         // Opcode 0xe7
799         void I386OP_D(out_ax_dx)();         // Opcode 0xef
800         void I386OP_D(pop_ax)();            // Opcode 0x58
801         void I386OP_D(pop_cx)();            // Opcode 0x59
802         void I386OP_D(pop_dx)();            // Opcode 0x5a
803         void I386OP_D(pop_bx)();            // Opcode 0x5b
804         void I386OP_D(pop_sp)();            // Opcode 0x5c
805         void I386OP_D(pop_bp)();            // Opcode 0x5d
806         void I386OP_D(pop_si)();            // Opcode 0x5e
807         void I386OP_D(pop_di)();            // Opcode 0x5f
808         void I386OP_D(pop_ds16)();          // Opcode 0x1f
809         void I386OP_D(pop_es16)();          // Opcode 0x07
810         void I386OP_D(pop_fs16)();          // Opcode 0x0f a1
811         void I386OP_D(pop_gs16)();          // Opcode 0x0f a9
812         void I386OP_D(pop_ss16)();          // Opcode 0x17
813         void I386OP_D(pop_rm16)();          // Opcode 0x8f
814         void I386OP_D(popa)();              // Opcode 0x61
815         void I386OP_D(popf)();              // Opcode 0x9d
816         void I386OP_D(push_ax)();           // Opcode 0x50
817         void I386OP_D(push_cx)();           // Opcode 0x51
818         void I386OP_D(push_dx)();           // Opcode 0x52
819         void I386OP_D(push_bx)();           // Opcode 0x53
820         void I386OP_D(push_sp)();           // Opcode 0x54
821         void I386OP_D(push_bp)();           // Opcode 0x55
822         void I386OP_D(push_si)();           // Opcode 0x56
823         void I386OP_D(push_di)();           // Opcode 0x57
824         void I386OP_D(push_cs16)();         // Opcode 0x0e
825         void I386OP_D(push_ds16)();         // Opcode 0x1e
826         void I386OP_D(push_es16)();         // Opcode 0x06
827         void I386OP_D(push_fs16)();         // Opcode 0x0f a0
828         void I386OP_D(push_gs16)();         // Opcode 0x0f a8
829         void I386OP_D(push_ss16)();         // Opcode 0x16
830         void I386OP_D(push_i16)();          // Opcode 0x68
831         void I386OP_D(pusha)();             // Opcode 0x60
832         void I386OP_D(pushf)();             // Opcode 0x9c
833         void I386OP_D(ret_near16_i16)();    // Opcode 0xc2
834         void I386OP_D(ret_near16)();        // Opcode 0xc3
835         void I386OP_D(sbb_rm16_r16)();      // Opcode 0x19
836         void I386OP_D(sbb_r16_rm16)();      // Opcode 0x1b
837         void I386OP_D(sbb_ax_i16)();        // Opcode 0x1d
838         void I386OP_D(scasw)();             // Opcode 0xaf
839         void I386OP_D(shld16_i8)();         // Opcode 0x0f a4
840         void I386OP_D(shld16_cl)();         // Opcode 0x0f a5
841         void I386OP_D(shrd16_i8)();         // Opcode 0x0f ac
842         void I386OP_D(shrd16_cl)();         // Opcode 0x0f ad
843         void I386OP_D(stosw)();             // Opcode 0xab
844         void I386OP_D(sub_rm16_r16)();      // Opcode 0x29
845         void I386OP_D(sub_r16_rm16)();      // Opcode 0x2b
846         void I386OP_D(sub_ax_i16)();        // Opcode 0x2d
847         void I386OP_D(test_ax_i16)();       // Opcode 0xa9
848         void I386OP_D(test_rm16_r16)();     // Opcode 0x85
849         void I386OP_D(xchg_ax_cx)();        // Opcode 0x91
850         void I386OP_D(xchg_ax_dx)();        // Opcode 0x92
851         void I386OP_D(xchg_ax_bx)();        // Opcode 0x93
852         void I386OP_D(xchg_ax_sp)();        // Opcode 0x94
853         void I386OP_D(xchg_ax_bp)();        // Opcode 0x95
854         void I386OP_D(xchg_ax_si)();        // Opcode 0x96
855         void I386OP_D(xchg_ax_di)();        // Opcode 0x97
856         void I386OP_D(xchg_r16_rm16)();     // Opcode 0x87
857         void I386OP_D(xor_rm16_r16)();      // Opcode 0x31
858         void I386OP_D(xor_r16_rm16)();      // Opcode 0x33
859         void I386OP_D(xor_ax_i16)();        // Opcode 0x35
860         void I386OP_D(group81_16)();        // Opcode 0x81
861         void I386OP_D(group83_16)();        // Opcode 0x83
862         void I386OP_D(groupC1_16)();        // Opcode 0xc1
863         void I386OP_D(groupD1_16)();        // Opcode 0xd1
864         void I386OP_D(groupD3_16)();        // Opcode 0xd3
865         void I386OP_D(groupF7_16)();        // Opcode 0xf7
866         virtual void I386OP_D(groupFF_16)();        // Opcode 0xff
867         void I386OP_D(group0F00_16)();          // Opcode 0x0f 00
868         void I386OP_D(group0F01_16)();      // Opcode 0x0f 01
869         void I386OP_D(group0FBA_16)();      // Opcode 0x0f ba
870         void I386OP_D(lar_r16_rm16)();  // Opcode 0x0f 0x02
871         void I386OP_D(lsl_r16_rm16)();  // Opcode 0x0f 0x03
872         void I386OP_D(bound_r16_m16_m16)(); // Opcode 0x62
873         void I386OP_D(retf16)();            // Opcode 0xcb
874         void I386OP_D(retf_i16)();          // Opcode 0xca
875         void I386OP_D(lds16)();             // Opcode 0xc5
876         void I386OP_D(lss16)();             // Opcode 0x0f 0xb2
877         void I386OP_D(les16)();             // Opcode 0xc4
878         void I386OP_D(lfs16)();             // Opcode 0x0f 0xb4
879         void I386OP_D(lgs16)();             // Opcode 0x0f 0xb5
880         UINT16 I386OP_D(shift_rotate16)( UINT8 modrm, UINT32 value, UINT8 shift);
881         UINT8 I386OP_D(shift_rotate8)( UINT8 modrm, UINT32 value, UINT8 shift);
882         //i386/op32
883         void I386OP_D(adc_rm32_r32)();      // Opcode 0x11
884         void I386OP_D(adc_r32_rm32)();      // Opcode 0x13
885         void I386OP_D(adc_eax_i32)();       // Opcode 0x15
886         void I386OP_D(add_rm32_r32)();      // Opcode 0x01
887         void I386OP_D(add_r32_rm32)();      // Opcode 0x03
888         void I386OP_D(add_eax_i32)();       // Opcode 0x05
889         void I386OP_D(and_rm32_r32)();      // Opcode 0x21
890         void I386OP_D(and_r32_rm32)();      // Opcode 0x23
891         void I386OP_D(and_eax_i32)();       // Opcode 0x25
892         void I386OP_D(bsf_r32_rm32)();      // Opcode 0x0f bc
893         void I386OP_D(bsr_r32_rm32)();      // Opcode 0x0f bd
894         void I386OP_D(bt_rm32_r32)();       // Opcode 0x0f a3
895         void I386OP_D(btc_rm32_r32)();      // Opcode 0x0f bb
896         void I386OP_D(btr_rm32_r32)();      // Opcode 0x0f b3
897         void I386OP_D(bts_rm32_r32)();      // Opcode 0x0f ab
898         void I386OP_D(call_abs32)();        // Opcode 0x9a
899         void I386OP_D(call_rel32)();        // Opcode 0xe8
900         void I386OP_D(cdq)();               // Opcode 0x99
901         void I386OP_D(cmp_rm32_r32)();      // Opcode 0x39
902         void I386OP_D(cmp_r32_rm32)();      // Opcode 0x3b
903         void I386OP_D(cmp_eax_i32)();       // Opcode 0x3d
904         void I386OP_D(cmpsd)();             // Opcode 0xa7
905         void I386OP_D(cwde)();              // Opcode 0x98
906         void I386OP_D(dec_eax)();           // Opcode 0x48
907         void I386OP_D(dec_ecx)();           // Opcode 0x49
908         void I386OP_D(dec_edx)();           // Opcode 0x4a
909         void I386OP_D(dec_ebx)();           // Opcode 0x4b
910         void I386OP_D(dec_esp)();           // Opcode 0x4c
911         void I386OP_D(dec_ebp)();           // Opcode 0x4d
912         void I386OP_D(dec_esi)();           // Opcode 0x4e
913         void I386OP_D(dec_edi)();           // Opcode 0x4f
914         void I386OP_D(imul_r32_rm32)();     // Opcode 0x0f af
915         void I386OP_D(imul_r32_rm32_i32)(); // Opcode 0x69
916         void I386OP_D(imul_r32_rm32_i8)();  // Opcode 0x6b
917         void I386OP_D(in_eax_i8)();         // Opcode 0xe5
918         void I386OP_D(in_eax_dx)();         // Opcode 0xed
919         void I386OP_D(inc_eax)();           // Opcode 0x40
920         void I386OP_D(inc_ecx)();           // Opcode 0x41
921         void I386OP_D(inc_edx)();           // Opcode 0x42
922         void I386OP_D(inc_ebx)();           // Opcode 0x43
923         void I386OP_D(inc_esp)();           // Opcode 0x44
924         void I386OP_D(inc_ebp)();           // Opcode 0x45
925         void I386OP_D(inc_esi)();           // Opcode 0x46
926         void I386OP_D(inc_edi)();           // Opcode 0x47
927         void I386OP_D(iret32)();            // Opcode 0xcf
928         void I386OP_D(ja_rel32)();          // Opcode 0x0f 87
929         void I386OP_D(jbe_rel32)();         // Opcode 0x0f 86
930         void I386OP_D(jc_rel32)();          // Opcode 0x0f 82
931         void I386OP_D(jg_rel32)();          // Opcode 0x0f 8f
932         void I386OP_D(jge_rel32)();         // Opcode 0x0f 8d
933         void I386OP_D(jl_rel32)();          // Opcode 0x0f 8c
934         void I386OP_D(jle_rel32)();         // Opcode 0x0f 8e
935         void I386OP_D(jnc_rel32)();         // Opcode 0x0f 83
936         void I386OP_D(jno_rel32)();         // Opcode 0x0f 81
937         void I386OP_D(jnp_rel32)();         // Opcode 0x0f 8b
938         void I386OP_D(jns_rel32)();         // Opcode 0x0f 89
939         void I386OP_D(jnz_rel32)();         // Opcode 0x0f 85
940         void I386OP_D(jo_rel32)();          // Opcode 0x0f 80
941         void I386OP_D(jp_rel32)();          // Opcode 0x0f 8a
942         void I386OP_D(js_rel32)();          // Opcode 0x0f 88
943         void I386OP_D(jz_rel32)();          // Opcode 0x0f 84
944         void I386OP_D(jcxz32)();            // Opcode 0xe3
945         void I386OP_D(jmp_rel32)();         // Opcode 0xe9
946         void I386OP_D(jmp_abs32)();         // Opcode 0xea
947         void I386OP_D(lea32)();             // Opcode 0x8d
948         void I386OP_D(enter32)();           // Opcode 0xc8
949         void I386OP_D(leave32)();           // Opcode 0xc9
950         void I386OP_D(lodsd)();             // Opcode 0xad
951         void I386OP_D(loop32)();            // Opcode 0xe2
952         void I386OP_D(loopne32)();          // Opcode 0xe0
953         void I386OP_D(loopz32)();           // Opcode 0xe1
954         void I386OP_D(mov_rm32_r32)();      // Opcode 0x89
955         void I386OP_D(mov_r32_rm32)();      // Opcode 0x8b
956         void I386OP_D(mov_rm32_i32)();      // Opcode 0xc7
957         void I386OP_D(mov_eax_m32)();       // Opcode 0xa1
958         void I386OP_D(mov_m32_eax)();       // Opcode 0xa3
959         void I386OP_D(mov_eax_i32)();       // Opcode 0xb8
960         void I386OP_D(mov_ecx_i32)();       // Opcode 0xb9
961         void I386OP_D(mov_edx_i32)();       // Opcode 0xba
962         void I386OP_D(mov_ebx_i32)();       // Opcode 0xbb
963         void I386OP_D(mov_esp_i32)();       // Opcode 0xbc
964         void I386OP_D(mov_ebp_i32)();       // Opcode 0xbd
965         void I386OP_D(mov_esi_i32)();       // Opcode 0xbe
966         void I386OP_D(mov_edi_i32)();       // Opcode 0xbf
967         void I386OP_D(movsd)();             // Opcode 0xa5
968         void I386OP_D(movsx_r32_rm8)();     // Opcode 0x0f be
969         void I386OP_D(movsx_r32_rm16)();    // Opcode 0x0f bf
970         void I386OP_D(movzx_r32_rm8)();     // Opcode 0x0f b6
971         void I386OP_D(movzx_r32_rm16)();    // Opcode 0x0f b7
972         void I386OP_D(or_rm32_r32)();       // Opcode 0x09
973         void I386OP_D(or_r32_rm32)();       // Opcode 0x0b
974         void I386OP_D(or_eax_i32)();        // Opcode 0x0d
975         void I386OP_D(out_eax_i8)();        // Opcode 0xe7
976         void I386OP_D(out_eax_dx)();        // Opcode 0xef
977         void I386OP_D(pop_eax)();           // Opcode 0x58
978         void I386OP_D(pop_ecx)();           // Opcode 0x59
979         void I386OP_D(pop_edx)();           // Opcode 0x5a
980         void I386OP_D(pop_ebx)();           // Opcode 0x5b
981         void I386OP_D(pop_esp)();           // Opcode 0x5c
982         void I386OP_D(pop_ebp)();           // Opcode 0x5d
983         void I386OP_D(pop_esi)();           // Opcode 0x5e
984         void I386OP_D(pop_edi)();           // Opcode 0x5f
985         void I386OP_D(pop_ds32)();          // Opcode 0x1f
986         void I386OP_D(pop_es32)();          // Opcode 0x07
987         void I386OP_D(pop_fs32)();          // Opcode 0x0f a1
988         void I386OP_D(pop_gs32)();          // Opcode 0x0f a9
989         void I386OP_D(pop_ss32)();          // Opcode 0x17
990         void I386OP_D(pop_rm32)();          // Opcode 0x8f
991         void I386OP_D(popad)();             // Opcode 0x61
992         void I386OP_D(popfd)();             // Opcode 0x9d
993         void I386OP_D(push_eax)();          // Opcode 0x50
994         void I386OP_D(push_ecx)();          // Opcode 0x51
995         void I386OP_D(push_edx)();          // Opcode 0x52
996         void I386OP_D(push_ebx)();          // Opcode 0x53
997         void I386OP_D(push_esp)();          // Opcode 0x54
998         void I386OP_D(push_ebp)();          // Opcode 0x55
999         void I386OP_D(push_esi)();          // Opcode 0x56
1000         void I386OP_D(push_edi)();          // Opcode 0x57
1001         void I386OP_D(push_cs32)();         // Opcode 0x0e
1002         void I386OP_D(push_ds32)();         // Opcode 0x1e
1003         void I386OP_D(push_es32)();         // Opcode 0x06
1004         void I386OP_D(push_fs32)();         // Opcode 0x0f a0
1005         void I386OP_D(push_gs32)();         // Opcode 0x0f a8
1006         void I386OP_D(push_ss32)();         // Opcode 0x16
1007         void I386OP_D(push_i32)();          // Opcode 0x68
1008         void I386OP_D(pushad)();            // Opcode 0x60
1009         void I386OP_D(pushfd)();            // Opcode 0x9c
1010         void I386OP_D(ret_near32_i16)();    // Opcode 0xc2
1011         void I386OP_D(ret_near32)();        // Opcode 0xc3
1012         void I386OP_D(sbb_rm32_r32)();      // Opcode 0x19
1013         void I386OP_D(sbb_r32_rm32)();      // Opcode 0x1b
1014         void I386OP_D(sbb_eax_i32)();       // Opcode 0x1d
1015         void I386OP_D(scasd)();             // Opcode 0xaf
1016         void I386OP_D(shld32_i8)();         // Opcode 0x0f a4
1017         void I386OP_D(shld32_cl)();         // Opcode 0x0f a5
1018         void I386OP_D(shrd32_i8)();         // Opcode 0x0f ac
1019         void I386OP_D(shrd32_cl)();         // Opcode 0x0f ad
1020         void I386OP_D(stosd)();             // Opcode 0xab
1021         void I386OP_D(sub_rm32_r32)();      // Opcode 0x29
1022         void I386OP_D(sub_r32_rm32)();      // Opcode 0x2b
1023         void I386OP_D(sub_eax_i32)();       // Opcode 0x2d
1024         void I386OP_D(test_eax_i32)();      // Opcode 0xa9
1025         void I386OP_D(test_rm32_r32)();     // Opcode 0x85
1026         void I386OP_D(xchg_eax_ecx)();      // Opcode 0x91
1027         void I386OP_D(xchg_eax_edx)();      // Opcode 0x92
1028         void I386OP_D(xchg_eax_ebx)();      // Opcode 0x93
1029         void I386OP_D(xchg_eax_esp)();      // Opcode 0x94
1030         void I386OP_D(xchg_eax_ebp)();      // Opcode 0x95
1031         void I386OP_D(xchg_eax_esi)();      // Opcode 0x96
1032         void I386OP_D(xchg_eax_edi)();      // Opcode 0x97
1033         void I386OP_D(xchg_r32_rm32)();     // Opcode 0x87
1034         void I386OP_D(xor_rm32_r32)();      // Opcode 0x31
1035         void I386OP_D(xor_r32_rm32)();      // Opcode 0x33
1036         void I386OP_D(xor_eax_i32)();       // Opcode 0x35
1037         void I386OP_D(group81_32)();        // Opcode 0x81
1038         void I386OP_D(group83_32)();        // Opcode 0x83
1039         void I386OP_D(groupC1_32)();        // Opcode 0xc1
1040         void I386OP_D(groupD1_32)();        // Opcode 0xd1
1041         void I386OP_D(groupD3_32)();        // Opcode 0xd3
1042         void I386OP_D(groupF7_32)();        // Opcode 0xf7
1043         void I386OP_D(groupFF_32)();        // Opcode 0xff
1044         void I386OP_D(group0F00_32)();          // Opcode 0x0f 00
1045         void I386OP_D(group0F01_32)();      // Opcode 0x0f 01
1046         void I386OP_D(group0FBA_32)();      // Opcode 0x0f ba
1047         void I386OP_D(lar_r32_rm32)();  // Opcode 0x0f 0x02
1048         void I386OP_D(lsl_r32_rm32)();  // Opcode 0x0f 0x03
1049         void I386OP_D(bound_r32_m32_m32)(); // Opcode 0x62
1050         void I386OP_D(retf32)();            // Opcode 0xcb
1051         void I386OP_D(retf_i32)();          // Opcode 0xca
1052         void I386OP_D(load_far_pointer32)( int s);
1053         void I386OP_D(lds32)();             // Opcode 0xc5
1054         void I386OP_D(lss32)();             // Opcode 0x0f 0xb2
1055         void I386OP_D(les32)();             // Opcode 0xc4
1056         void I386OP_D(lfs32)();             // Opcode 0x0f 0xb4
1057         void I386OP_D(lgs32)();             // Opcode 0x0f 0xb5
1058 // i386 other OPS.
1059         void I386OP_D(adc_rm8_r8)();        // Opcode 0x10
1060         void I386OP_D(adc_r8_rm8)();        // Opcode 0x12
1061         void I386OP_D(adc_al_i8)();     // Opcode 0x14
1062         void I386OP_D(add_rm8_r8)();        // Opcode 0x00
1063         void I386OP_D(add_r8_rm8)();        // Opcode 0x02
1064         void I386OP_D(add_al_i8)();     // Opcode 0x04
1065         void I386OP_D(and_rm8_r8)();        // Opcode 0x20
1066         void I386OP_D(and_r8_rm8)();        // Opcode 0x22
1067         void I386OP_D(and_al_i8)();         // Opcode 0x24
1068         void I386OP_D(clc)();               // Opcode 0xf8
1069         void I386OP_D(cld)();               // Opcode 0xfc
1070         void I386OP_D(cli)();               // Opcode 0xfa
1071         void I386OP_D(cmc)();               // Opcode 0xf5
1072         void I386OP_D(cmp_rm8_r8)();        // Opcode 0x38
1073         void I386OP_D(cmp_r8_rm8)();        // Opcode 0x3a
1074         void I386OP_D(cmp_al_i8)();         // Opcode 0x3c
1075         void I386OP_D(cmpsb)();             // Opcode 0xa6
1076         void I386OP_D(in_al_i8)();          // Opcode 0xe4
1077         void I386OP_D(in_al_dx)();          // Opcode 0xec
1078         void I386OP_D(ja_rel8)();           // Opcode 0x77
1079         void I386OP_D(jbe_rel8)();          // Opcode 0x76
1080         void I386OP_D(jc_rel8)();           // Opcode 0x72
1081         void I386OP_D(jg_rel8)();           // Opcode 0x7f
1082         void I386OP_D(jge_rel8)();          // Opcode 0x7d
1083         void I386OP_D(jl_rel8)();           // Opcode 0x7c
1084         void I386OP_D(jle_rel8)();      // Opcode 0x7e
1085         void I386OP_D(jnc_rel8)();          // Opcode 0x73
1086         void I386OP_D(jno_rel8)();          // Opcode 0x71
1087         void I386OP_D(jnp_rel8)();          // Opcode 0x7b
1088         void I386OP_D(jns_rel8)();          // Opcode 0x79
1089         void I386OP_D(jnz_rel8)();          // Opcode 0x75
1090         void I386OP_D(jo_rel8)();           // Opcode 0x70
1091         void I386OP_D(jp_rel8)();           // Opcode 0x7a
1092         void I386OP_D(js_rel8)();           // Opcode 0x78
1093         void I386OP_D(jz_rel8)();           // Opcode 0x74
1094         void I386OP_D(jmp_rel8)();          // Opcode 0xeb
1095         void I386OP_D(lahf)();              // Opcode 0x9f
1096         void I386OP_D(lodsb)();             // Opcode 0xac
1097         void I386OP_D(mov_rm8_r8)();        // Opcode 0x88
1098         void I386OP_D(mov_r8_rm8)();        // Opcode 0x8a
1099         void I386OP_D(mov_rm8_i8)();        // Opcode 0xc6
1100         void I386OP_D(mov_r32_cr)();        // Opcode 0x0f 20
1101         void I386OP_D(mov_r32_dr)();        // Opcode 0x0f 21
1102         void I386OP_D(mov_cr_r32)();        // Opcode 0x0f 22
1103         void I386OP_D(mov_dr_r32)();        // Opcode 0x0f 23
1104         void I386OP_D(mov_al_m8)();         // Opcode 0xa0
1105         void I386OP_D(mov_m8_al)();         // Opcode 0xa2
1106         void I386OP_D(mov_rm16_sreg)();     // Opcode 0x8c
1107         void I386OP_D(mov_sreg_rm16)();     // Opcode 0x8e
1108         void I386OP_D(mov_al_i8)();         // Opcode 0xb0
1109         void I386OP_D(mov_cl_i8)();         // Opcode 0xb1
1110         void I386OP_D(mov_dl_i8)();         // Opcode 0xb2
1111         void I386OP_D(mov_bl_i8)();         // Opcode 0xb3
1112         void I386OP_D(mov_ah_i8)();         // Opcode 0xb4
1113         void I386OP_D(mov_ch_i8)();         // Opcode 0xb5
1114         void I386OP_D(mov_dh_i8)();         // Opcode 0xb6
1115         void I386OP_D(mov_bh_i8)();         // Opcode 0xb7
1116         void I386OP_D(movsb)();             // Opcode 0xa4
1117         void I386OP_D(or_rm8_r8)();         // Opcode 0x08
1118         void I386OP_D(or_r8_rm8)();         // Opcode 0x0a
1119         void I386OP_D(or_al_i8)();          // Opcode 0x0c
1120         void I386OP_D(out_al_i8)();         // Opcode 0xe6
1121         void I386OP_D(out_al_dx)();         // Opcode 0xee
1122         void I386OP_D(arpl)();           // Opcode 0x63
1123         void I386OP_D(push_i8)();           // Opcode 0x6a
1124         void I386OP_D(ins_generic)( int size);
1125         void I386OP_D(insb)();              // Opcode 0x6c
1126         void I386OP_D(insw)();              // Opcode 0x6d
1127         void I386OP_D(insd)();              // Opcode 0x6d
1128         void I386OP_D(outs_generic)( int size);
1129         void I386OP_D(outsb)();             // Opcode 0x6e
1130         void I386OP_D(outsw)();             // Opcode 0x6f
1131         void I386OP_D(outsd)();             // Opcode 0x6f
1132         void I386OP_D(repeat)( int invert_flag);
1133         void I386OP_D(rep)();               // Opcode 0xf3
1134         void I386OP_D(repne)();             // Opcode 0xf2
1135         void I386OP_D(sahf)();              // Opcode 0x9e
1136         void I386OP_D(sbb_rm8_r8)();        // Opcode 0x18
1137         void I386OP_D(sbb_r8_rm8)();        // Opcode 0x1a
1138         void I386OP_D(sbb_al_i8)();         // Opcode 0x1c
1139         void I386OP_D(scasb)();             // Opcode 0xae
1140         void I386OP_D(setalc)();            // Opcode 0xd6 (undocumented)
1141         void I386OP_D(seta_rm8)();          // Opcode 0x0f 97
1142         void I386OP_D(setbe_rm8)();         // Opcode 0x0f 96
1143         void I386OP_D(setc_rm8)();          // Opcode 0x0f 92
1144         void I386OP_D(setg_rm8)();          // Opcode 0x0f 9f
1145         void I386OP_D(setge_rm8)();         // Opcode 0x0f 9d
1146         void I386OP_D(setl_rm8)();          // Opcode 0x0f 9c
1147         void I386OP_D(setle_rm8)();         // Opcode 0x0f 9e
1148         void I386OP_D(setnc_rm8)();         // Opcode 0x0f 93
1149         void I386OP_D(setno_rm8)();         // Opcode 0x0f 91
1150         void I386OP_D(setnp_rm8)();         // Opcode 0x0f 9b
1151         void I386OP_D(setns_rm8)();         // Opcode 0x0f 99
1152         void I386OP_D(setnz_rm8)();         // Opcode 0x0f 95
1153         void I386OP_D(seto_rm8)();          // Opcode 0x0f 90
1154         void I386OP_D(setp_rm8)();          // Opcode 0x0f 9a
1155         void I386OP_D(sets_rm8)();          // Opcode 0x0f 98
1156         void I386OP_D(setz_rm8)();          // Opcode 0x0f 94
1157         void I386OP_D(stc)();               // Opcode 0xf9
1158         void I386OP_D(std)();               // Opcode 0xfd
1159         void I386OP_D(sti)();               // Opcode 0xfb
1160         void I386OP_D(stosb)();             // Opcode 0xaa
1161         void I386OP_D(sub_rm8_r8)();        // Opcode 0x28
1162         void I386OP_D(sub_r8_rm8)();        // Opcode 0x2a
1163         void I386OP_D(sub_al_i8)();         // Opcode 0x2c
1164         void I386OP_D(test_al_i8)();        // Opcode 0xa8
1165         void I386OP_D(test_rm8_r8)();       // Opcode 0x84
1166         void I386OP_D(xchg_r8_rm8)();       // Opcode 0x86
1167         void I386OP_D(xor_rm8_r8)();        // Opcode 0x30
1168         void I386OP_D(xor_r8_rm8)();        // Opcode 0x32
1169         void I386OP_D(xor_al_i8)();         // Opcode 0x34
1170         void I386OP_D(group80_8)();         // Opcode 0x80
1171         void I386OP_D(groupC0_8)();         // Opcode 0xc0
1172         void I386OP_D(groupD0_8)();         // Opcode 0xd0
1173         void I386OP_D(groupD2_8)();         // Opcode 0xd2
1174         void I386OP_D(groupF6_8)();         // Opcode 0xf6
1175         void I386OP_D(groupFE_8)();         // Opcode 0xfe
1176         void I386OP_D(segment_CS)();        // Opcode 0x2e
1177         void I386OP_D(segment_DS)();        // Opcode 0x3e
1178         void I386OP_D(segment_ES)();        // Opcode 0x26
1179         void I386OP_D(segment_FS)();        // Opcode 0x64
1180         void I386OP_D(segment_GS)();        // Opcode 0x65
1181         void I386OP_D(segment_SS)();        // Opcode 0x36
1182         void I386OP_D(operand_size)();      // Opcode prefix 0x66
1183         void I386OP_D(address_size)();      // Opcode 0x67
1184         void I386OP_D(nop)();               // Opcode 0x90
1185         void I386OP_D(int3)();              // Opcode 0xcc
1186         void I386OP_D(int)();               // Opcode 0xcd
1187         void I386OP_D(into)();              // Opcode 0xce
1188         void I386OP_D(escape)();            // Opcodes 0xd8 - 0xdf
1189         void I386OP_D(hlt)();               // Opcode 0xf4
1190         void I386OP_D(decimal_adjust)(int direction);
1191         void I386OP_D(daa)();               // Opcode 0x27
1192         void I386OP_D(das)();               // Opcode 0x2f
1193         void I386OP_D(aaa)();               // Opcode 0x37
1194         void I386OP_D(aas)();               // Opcode 0x3f
1195         void I386OP_D(aad)();               // Opcode 0xd5
1196         void I386OP_D(aam)();               // Opcode 0xd4
1197         void I386OP_D(clts)();              // Opcode 0x0f 0x06
1198         void I386OP_D(wait)();              // Opcode 0x9B
1199         void I386OP_D(lock)();              // Opcode 0xf0
1200         void I386OP_D(mov_r32_tr)();        // Opcode 0x0f 24
1201         void I386OP_D(mov_tr_r32)();        // Opcode 0x0f 26
1202         void I386OP_D(loadall)();       // Opcode 0x0f 0x07 (0x0f 0x05 on 80286), undocumented
1203         void I386OP_D(invalid)();
1204         void I386OP_D(xlat)();          // Opcode 0xd7
1205         bool I386OP_D(pop_seg16)( int segment);
1206         bool I386OP_D(load_far_pointer16)(int s);
1207         bool I386OP_D(pop_seg32)( int segment);
1208 //i486
1209         void I486OP_D(cpuid)();             // Opcode 0x0F A2
1210         void I486OP_D(invd)();              // Opcode 0x0f 08
1211         void I486OP_D(wbinvd)();            // Opcode 0x0f 09
1212         void I486OP_D(cmpxchg_rm8_r8)();    // Opcode 0x0f b0
1213         void I486OP_D(cmpxchg_rm16_r16)();  // Opcode 0x0f b1
1214         void I486OP_D(cmpxchg_rm32_r32)();  // Opcode 0x0f b1
1215         void I486OP_D(xadd_rm8_r8)();   // Opcode 0x0f c0
1216         void I486OP_D(xadd_rm16_r16)(); // Opcode 0x0f c1
1217         void I486OP_D(xadd_rm32_r32)(); // Opcode 0x0f c1
1218         void I486OP_D(group0F01_16)();      // Opcode 0x0f 01
1219         void I486OP_D(group0F01_32)();      // Opcode 0x0f 01
1220         void I486OP_D(bswap_eax)();     // Opcode 0x0f 38
1221         void I486OP_D(bswap_ecx)();     // Opcode 0x0f 39
1222         void I486OP_D(bswap_edx)();     // Opcode 0x0f 3A
1223         void I486OP_D(bswap_ebx)();     // Opcode 0x0f 3B
1224         void I486OP_D(bswap_esp)();     // Opcode 0x0f 3C
1225         void I486OP_D(bswap_ebp)();     // Opcode 0x0f 3D
1226         void I486OP_D(bswap_esi)();     // Opcode 0x0f 3E
1227         void I486OP_D(bswap_edi)();     // Opcode 0x0f 3F
1228         void I486OP_D(mov_cr_r32)();        // Opcode 0x0f 22
1229 //Pentium, MMX, SSE.
1230         void PENTIUMOP_D(rdmsr)();          // Opcode 0x0f 32
1231         void PENTIUMOP_D(wrmsr)();          // Opcode 0x0f 30
1232         void PENTIUMOP_D(rdtsc)();          // Opcode 0x0f 31
1233         void PENTIUMOP_D(ud2)();    // Opcode 0x0f 0b
1234         void PENTIUMOP_D(rsm)();
1235         void PENTIUMOP_D(prefetch_m8)();    // Opcode 0x0f 18
1236         void PENTIUMOP_D(cmovo_r16_rm16)();    // Opcode 0x0f 40
1237         void PENTIUMOP_D(cmovo_r32_rm32)();    // Opcode 0x0f 40
1238         void PENTIUMOP_D(cmovno_r16_rm16)();    // Opcode 0x0f 41
1239         void PENTIUMOP_D(cmovno_r32_rm32)();    // Opcode 0x0f 41
1240         void PENTIUMOP_D(cmovb_r16_rm16)();    // Opcode 0x0f 42
1241         void PENTIUMOP_D(cmovb_r32_rm32)();    // Opcode 0x0f 42
1242         void PENTIUMOP_D(cmovae_r16_rm16)();    // Opcode 0x0f 43
1243         void PENTIUMOP_D(cmovae_r32_rm32)();    // Opcode 0x0f 43
1244         void PENTIUMOP_D(cmove_r16_rm16)();    // Opcode 0x0f 44
1245         void PENTIUMOP_D(cmove_r32_rm32)();    // Opcode 0x0f 44
1246         void PENTIUMOP_D(cmovne_r16_rm16)();    // Opcode 0x0f 45
1247         void PENTIUMOP_D(cmovne_r32_rm32)();    // Opcode 0x0f 45
1248         void PENTIUMOP_D(cmovbe_r16_rm16)();    // Opcode 0x0f 46
1249         void PENTIUMOP_D(cmovbe_r32_rm32)();    // Opcode 0x0f 46
1250         void PENTIUMOP_D(cmova_r16_rm16)();    // Opcode 0x0f 47
1251         void PENTIUMOP_D(cmova_r32_rm32)();    // Opcode 0x0f 47
1252         void PENTIUMOP_D(cmovs_r16_rm16)();    // Opcode 0x0f 48
1253         void PENTIUMOP_D(cmovs_r32_rm32)();    // Opcode 0x0f 48
1254         void PENTIUMOP_D(cmovns_r16_rm16)();    // Opcode 0x0f 49
1255         void PENTIUMOP_D(cmovns_r32_rm32)();    // Opcode 0x0f 49
1256         void PENTIUMOP_D(cmovp_r16_rm16)();    // Opcode 0x0f 4a
1257         void PENTIUMOP_D(cmovp_r32_rm32)();    // Opcode 0x0f 4a
1258         void PENTIUMOP_D(cmovnp_r16_rm16)();    // Opcode 0x0f 4b
1259         void PENTIUMOP_D(cmovnp_r32_rm32)();    // Opcode 0x0f 4b
1260         void PENTIUMOP_D(cmovl_r16_rm16)();    // Opcode 0x0f 4c
1261         void PENTIUMOP_D(cmovl_r32_rm32)();    // Opcode 0x0f 4c
1262         void PENTIUMOP_D(cmovge_r16_rm16)();    // Opcode 0x0f 4d
1263         void PENTIUMOP_D(cmovge_r32_rm32)();    // Opcode 0x0f 4d
1264         void PENTIUMOP_D(cmovle_r16_rm16)();    // Opcode 0x0f 4e
1265         void PENTIUMOP_D(cmovle_r32_rm32)();    // Opcode 0x0f 4e
1266         void PENTIUMOP_D(cmovg_r16_rm16)();    // Opcode 0x0f 4f
1267         void PENTIUMOP_D(cmovg_r32_rm32)();    // Opcode 0x0f 4f
1268         void PENTIUMOP_D(movnti_m16_r16)(); // Opcode 0f c3
1269         void PENTIUMOP_D(movnti_m32_r32)(); // Opcode 0f c3
1270         void PENTIUMOP_D(cmpxchg8b_m64)();  // Opcode 0x0f c7
1271         void PENTIUMOP_D(movntq_m64_r64)(); // Opcode 0f e7
1272         void PENTIUMOP_D(maskmovq_r64_r64)();  // Opcode 0f f7
1273         void SSEOP_D(maskmovdqu_r128_r128)();  // Opcode 66 0f f7
1274         void PENTIUMOP_D(popcnt_r16_rm16)();    // Opcode f3 0f b8
1275         void PENTIUMOP_D(popcnt_r32_rm32)();    // Opcode f3 0f b8
1276         void PENTIUMOP_D(tzcnt_r16_rm16)();
1277         void PENTIUMOP_D(tzcnt_r32_rm32)();
1278         void I386OP_D(cyrix_special)();
1279         void I386OP_D(cyrix_unknown)();
1280         void I386OP_D(cyrix_svdc)();
1281         void I386OP_D(cyrix_rsdc)();
1282         void I386OP_D(cyrix_svldt)();
1283         void I386OP_D(cyrix_rsldt)();
1284         void I386OP_D(cyrix_svts)();
1285         void I386OP_D(cyrix_rsts)();
1286         
1287         void MMXOP_D(group_0f71)();  // Opcode 0f 71
1288         void SSEOP_D(group_660f71)();  // Opcode 66 0f 71
1289         void MMXOP_D(group_0f72)();  // Opcode 0f 72
1290         void SSEOP_D(group_660f72)();  // Opcode 66 0f 72
1291         void MMXOP_D(group_0f73)();  // Opcode 0f 73
1292         void SSEOP_D(group_660f73)();  // Opcode 66 0f 73
1293         void MMXOP_D(psrlw_r64_rm64)();  // Opcode 0f d1
1294         void MMXOP_D(psrld_r64_rm64)();  // Opcode 0f d2
1295         void MMXOP_D(psrlq_r64_rm64)();  // Opcode 0f d3
1296         void MMXOP_D(paddq_r64_rm64)();  // Opcode 0f d4
1297         void MMXOP_D(pmullw_r64_rm64)();  // Opcode 0f d5
1298         void MMXOP_D(psubusb_r64_rm64)();  // Opcode 0f d8
1299         void MMXOP_D(psubusw_r64_rm64)();  // Opcode 0f d9
1300         void MMXOP_D(pand_r64_rm64)();  // Opcode 0f db
1301         void MMXOP_D(paddusb_r64_rm64)();  // Opcode 0f dc
1302         void MMXOP_D(paddusw_r64_rm64)();  // Opcode 0f dd
1303         void MMXOP_D(pandn_r64_rm64)();  // Opcode 0f df
1304         void MMXOP_D(psraw_r64_rm64)();  // Opcode 0f e1
1305         void MMXOP_D(psrad_r64_rm64)();  // Opcode 0f e2
1306         void MMXOP_D(pmulhw_r64_rm64)();  // Opcode 0f e5
1307         void MMXOP_D(psubsb_r64_rm64)();  // Opcode 0f e8
1308         void MMXOP_D(psubsw_r64_rm64)();  // Opcode 0f e9
1309         void MMXOP_D(por_r64_rm64)();  // Opcode 0f eb
1310         void MMXOP_D(paddsb_r64_rm64)();  // Opcode 0f ec
1311         void MMXOP_D(paddsw_r64_rm64)();  // Opcode 0f ed
1312         void MMXOP_D(pxor_r64_rm64)();  // Opcode 0f ef
1313         void MMXOP_D(psllw_r64_rm64)();  // Opcode 0f f1
1314         void MMXOP_D(pslld_r64_rm64)();  // Opcode 0f f2
1315         void MMXOP_D(psllq_r64_rm64)();  // Opcode 0f f3
1316         void MMXOP_D(pmaddwd_r64_rm64)();  // Opcode 0f f5
1317         void MMXOP_D(psubb_r64_rm64)();  // Opcode 0f f8
1318         void MMXOP_D(psubw_r64_rm64)();  // Opcode 0f f9
1319         void MMXOP_D(psubd_r64_rm64)();  // Opcode 0f fa
1320         void MMXOP_D(paddb_r64_rm64)();  // Opcode 0f fc
1321         void MMXOP_D(paddw_r64_rm64)();  // Opcode 0f fd
1322         void MMXOP_D(paddd_r64_rm64)();  // Opcode 0f fe
1323         void MMXOP_D(emms)(); // Opcode 0f 77
1324         void MMXOP_D(movd_r64_rm32)(); // Opcode 0f 6e
1325         void MMXOP_D(movq_r64_rm64)(); // Opcode 0f 6f
1326         void MMXOP_D(movd_rm32_r64)(); // Opcode 0f 7e
1327         void MMXOP_D(movq_rm64_r64)(); // Opcode 0f 7f
1328         void MMXOP_D(pcmpeqb_r64_rm64)(); // Opcode 0f 74
1329         void MMXOP_D(pcmpeqw_r64_rm64)(); // Opcode 0f 75
1330         void MMXOP_D(pcmpeqd_r64_rm64)(); // Opcode 0f 76
1331         void MMXOP_D(pshufw_r64_rm64_i8)(); // Opcode 0f 70
1332         void SSEOP_D(punpcklbw_r128_rm128)(); // Opcode 66 0f 60
1333         void SSEOP_D(punpcklwd_r128_rm128)();
1334         void SSEOP_D(punpckldq_r128_rm128)();
1335         void SSEOP_D(punpcklqdq_r128_rm128)();
1336         void MMXOP_D(punpcklbw_r64_r64m32)(); // Opcode 0f 60
1337         void MMXOP_D(punpcklwd_r64_r64m32)(); // Opcode 0f 61
1338         void MMXOP_D(punpckldq_r64_r64m32)(); // Opcode 0f 62
1339         void MMXOP_D(packsswb_r64_rm64)(); // Opcode 0f 63
1340         void MMXOP_D(pcmpgtb_r64_rm64)(); // Opcode 0f 64
1341         void MMXOP_D(pcmpgtw_r64_rm64)(); // Opcode 0f 65
1342         void MMXOP_D(pcmpgtd_r64_rm64)(); // Opcode 0f 66
1343         void MMXOP_D(packuswb_r64_rm64)(); // Opcode 0f 67
1344         void MMXOP_D(punpckhbw_r64_rm64)(); // Opcode 0f 68
1345         void MMXOP_D(punpckhwd_r64_rm64)(); // Opcode 0f 69
1346         void MMXOP_D(punpckhdq_r64_rm64)(); // Opcode 0f 6a
1347         void MMXOP_D(packssdw_r64_rm64)(); // Opcode 0f 6b
1348         void SSEOP_D(group_0fae)();  // Opcode 0f ae
1349         void SSEOP_D(cvttps2dq_r128_rm128)(); // Opcode f3 0f 5b
1350         void SSEOP_D(cvtss2sd_r128_r128m32)(); // Opcode f3 0f 5a
1351         void SSEOP_D(cvttss2si_r32_r128m32)(); // Opcode f3 0f 2c
1352         void SSEOP_D(cvtss2si_r32_r128m32)(); // Opcode f3 0f 2d
1353         void SSEOP_D(cvtsi2ss_r128_rm32)(); // Opcode f3 0f 2a
1354         void SSEOP_D(cvtpi2ps_r128_rm64)(); // Opcode 0f 2a
1355         void SSEOP_D(cvttps2pi_r64_r128m64)(); // Opcode 0f 2c
1356         void SSEOP_D(cvtps2pi_r64_r128m64)(); // Opcode 0f 2d
1357         void SSEOP_D(cvtps2pd_r128_r128m64)(); // Opcode 0f 5a
1358         void SSEOP_D(cvtdq2ps_r128_rm128)(); // Opcode 0f 5b
1359         void SSEOP_D(cvtdq2pd_r128_r128m64)(); // Opcode f3 0f e6
1360         void SSEOP_D(movss_r128_rm128)(); // Opcode f3 0f 10
1361         void SSEOP_D(movss_rm128_r128)(); // Opcode f3 0f 11
1362         void SSEOP_D(movsldup_r128_rm128)(); // Opcode f3 0f 12
1363         void SSEOP_D(movshdup_r128_rm128)(); // Opcode f3 0f 16
1364         void SSEOP_D(movaps_r128_rm128)(); // Opcode 0f 28
1365         void SSEOP_D(movaps_rm128_r128)(); // Opcode 0f 29
1366         void SSEOP_D(movups_r128_rm128)(); // Opcode 0f 10
1367         void SSEOP_D(movupd_r128_rm128)(); // Opcode 66 0f 10
1368         void SSEOP_D(movups_rm128_r128)(); // Opcode 0f 11
1369         void SSEOP_D(movupd_rm128_r128)(); // Opcode 66 0f 11
1370         void SSEOP_D(movlps_r128_m64)(); // Opcode 0f 12
1371         void SSEOP_D(movlpd_r128_m64)(); // Opcode 66 0f 12
1372         void SSEOP_D(movlps_m64_r128)(); // Opcode 0f 13
1373         void SSEOP_D(movlpd_m64_r128)(); // Opcode 66 0f 13
1374         void SSEOP_D(movhps_r128_m64)(); // Opcode 0f 16
1375         void SSEOP_D(movhpd_r128_m64)(); // Opcode 66 0f 16
1376         void SSEOP_D(movhps_m64_r128)(); // Opcode 0f 17
1377         void SSEOP_D(movhpd_m64_r128)(); // Opcode 66 0f 17
1378         void SSEOP_D(movntps_m128_r128)(); // Opcode 0f 2b
1379         void SSEOP_D(movmskps_r16_r128)(); // Opcode 0f 50
1380         void SSEOP_D(movmskps_r32_r128)(); // Opcode 0f 50
1381         void SSEOP_D(movmskpd_r32_r128)(); // Opcode 66 0f 50
1382         void SSEOP_D(movq2dq_r128_r64)(); // Opcode f3 0f d6
1383         void SSEOP_D(movdqu_r128_rm128)(); // Opcode f3 0f 6f
1384         void SSEOP_D(movdqu_rm128_r128)(); // Opcode f3 0f 7f
1385         void SSEOP_D(movd_m128_rm32)(); // Opcode 66 0f 6e
1386         void SSEOP_D(movdqa_m128_rm128)(); // Opcode 66 0f 6f
1387         void SSEOP_D(movq_r128_r128m64)(); // Opcode f3 0f 7e
1388         void SSEOP_D(movd_rm32_r128)(); // Opcode 66 0f 7e
1389         void SSEOP_D(movdqa_rm128_r128)(); // Opcode 66 0f 7f
1390         void SSEOP_D(pmovmskb_r16_r64)(); // Opcode 0f d7
1391         void SSEOP_D(pmovmskb_r32_r64)(); // Opcode 0f d7
1392         void SSEOP_D(pmovmskb_r32_r128)(); // Opcode 66 0f d7
1393         void SSEOP_D(xorps)(); // Opcode 0f 57
1394         void SSEOP_D(xorpd_r128_rm128)(); // Opcode 66 0f 57
1395         void SSEOP_D(addps)(); // Opcode 0f 58
1396         void SSEOP_D(sqrtps_r128_rm128)(); // Opcode 0f 51
1397         void SSEOP_D(rsqrtps_r128_rm128)(); // Opcode 0f 52
1398         void SSEOP_D(rcpps_r128_rm128)(); // Opcode 0f 53
1399         void SSEOP_D(andps_r128_rm128)(); // Opcode 0f 54
1400         void SSEOP_D(andpd_r128_rm128)(); // Opcode 66 0f 54
1401         void SSEOP_D(andnps_r128_rm128)(); // Opcode 0f 55
1402         void SSEOP_D(andnpd_r128_rm128)(); // Opcode 66 0f 55
1403         void SSEOP_D(orps_r128_rm128)(); // Opcode 0f 56
1404         void SSEOP_D(orpd_r128_rm128)(); // Opcode 66 0f 56
1405         void SSEOP_D(mulps)(); // Opcode 0f 59 ????
1406         void SSEOP_D(subps)(); // Opcode 0f 5c
1407         void SSEOP_D(minps)(); // Opcode 0f 5d
1408         void SSEOP_D(divps)(); // Opcode 0f 5e
1409         void SSEOP_D(maxps)(); // Opcode 0f 5f
1410         void SSEOP_D(maxss_r128_r128m32)(); // Opcode f3 0f 5f
1411         void SSEOP_D(addss)(); // Opcode f3 0f 58
1412         void SSEOP_D(subss)(); // Opcode f3 0f 5c
1413         void SSEOP_D(mulss)(); // Opcode f3 0f 5e
1414         void SSEOP_D(divss)(); // Opcode 0f 59
1415         void SSEOP_D(rcpss_r128_r128m32)(); // Opcode f3 0f 53
1416         void SSEOP_D(sqrtss_r128_r128m32)(); // Opcode f3 0f 51
1417         void SSEOP_D(rsqrtss_r128_r128m32)(); // Opcode f3 0f 52
1418         void SSEOP_D(minss_r128_r128m32)(); // Opcode f3 0f 5d
1419         void SSEOP_D(comiss_r128_r128m32)(); // Opcode 0f 2f
1420         void SSEOP_D(comisd_r128_r128m64)(); // Opcode 66 0f 2f
1421         void SSEOP_D(ucomiss_r128_r128m32)(); // Opcode 0f 2e
1422         void SSEOP_D(ucomisd_r128_r128m64)(); // Opcode 66 0f 2e
1423         void SSEOP_D(shufps)(); // Opcode 0f c6
1424         void SSEOP_D(shufpd_r128_rm128_i8)(); // Opcode 66 0f c6
1425         void SSEOP_D(unpcklps_r128_rm128)(); // Opcode 0f 14
1426         void SSEOP_D(unpcklpd_r128_rm128)(); // Opcode 66 0f 14
1427         void SSEOP_D(unpckhps_r128_rm128)(); // Opcode 0f 15
1428         void SSEOP_D(unpckhpd_r128_rm128)(); // Opcode 66 0f 15
1429         void SSEOP_D(predicate_compare_single)(UINT8 imm8, XMM_REG d, XMM_REG s);
1430         void SSEOP_D(predicate_compare_double)(UINT8 imm8, XMM_REG d, XMM_REG s);
1431         void SSEOP_D(predicate_compare_single_scalar)(UINT8 imm8, XMM_REG d, XMM_REG s);
1432         void SSEOP_D(predicate_compare_double_scalar)(UINT8 imm8, XMM_REG d, XMM_REG s);
1433         void SSEOP_D(cmpps_r128_rm128_i8)(); // Opcode 0f c2
1434         void SSEOP_D(cmppd_r128_rm128_i8)(); // Opcode 66 0f c2
1435         void SSEOP_D(cmpss_r128_r128m32_i8)(); // Opcode f3 0f c2
1436         void SSEOP_D(pinsrw_r64_r16m16_i8)(); // Opcode 0f c4, 16bit register
1437         void SSEOP_D(pinsrw_r64_r32m16_i8)(); // Opcode 0f c4, 32bit register
1438         void SSEOP_D(pinsrw_r128_r32m16_i8)(); // Opcode 66 0f c4
1439         void SSEOP_D(pextrw_r16_r64_i8)(); // Opcode 0f c5
1440         void SSEOP_D(pextrw_r32_r64_i8)(); // Opcode 0f c5
1441         void SSEOP_D(pextrw_reg_r128_i8)(); // Opcode 66 0f c5
1442         void SSEOP_D(pminub_r64_rm64)(); // Opcode 0f da
1443         void SSEOP_D(pminub_r128_rm128)(); // Opcode 66 0f da
1444         void SSEOP_D(pmaxub_r64_rm64)(); // Opcode 0f de
1445         void SSEOP_D(pavgb_r64_rm64)(); // Opcode 0f e0
1446         void SSEOP_D(pavgw_r64_rm64)(); // Opcode 0f e3
1447         void SSEOP_D(pmulhuw_r64_rm64)();  // Opcode 0f e4
1448         void SSEOP_D(pminsw_r64_rm64)(); // Opcode 0f ea
1449         void SSEOP_D(pmaxsw_r64_rm64)(); // Opcode 0f ee
1450         void SSEOP_D(pmuludq_r64_rm64)(); // Opcode 0f f4
1451         void SSEOP_D(pmuludq_r128_rm128)(); // Opcode 66 0f f4
1452         void SSEOP_D(psadbw_r64_rm64)(); // Opcode 0f f6
1453         void SSEOP_D(psubq_r64_rm64)();  // Opcode 0f fb
1454         void SSEOP_D(psubq_r128_rm128)();  // Opcode 66 0f fb
1455         void SSEOP_D(pshufd_r128_rm128_i8)(); // Opcode 66 0f 70
1456         void SSEOP_D(pshuflw_r128_rm128_i8)(); // Opcode f2 0f 70
1457         void SSEOP_D(pshufhw_r128_rm128_i8)(); // Opcode f3 0f 70
1458         void SSEOP_D(packsswb_r128_rm128)(); // Opcode 66 0f 63
1459         void SSEOP_D(packssdw_r128_rm128)(); // Opcode 66 0f 6b
1460         void SSEOP_D(pcmpgtb_r128_rm128)(); // Opcode 66 0f 64
1461         void SSEOP_D(pcmpgtw_r128_rm128)(); // Opcode 66 0f 65
1462         void SSEOP_D(pcmpgtd_r128_rm128)(); // Opcode 66 0f 66
1463         void SSEOP_D(packuswb_r128_rm128)(); // Opcode 66 0f 67
1464         void SSEOP_D(punpckhbw_r128_rm128)(); // Opcode 66 0f 68
1465         void SSEOP_D(punpckhwd_r128_rm128)(); // Opcode 66 0f 69
1466         void SSEOP_D(unpckhdq_r128_rm128)(); // Opcode 66 0f 6a
1467         void SSEOP_D(punpckhqdq_r128_rm128)(); // Opcode 66 0f 6d
1468         void SSEOP_D(pcmpeqb_r128_rm128)(); // Opcode 66 0f 74
1469         void SSEOP_D(pcmpeqw_r128_rm128)(); // Opcode 66 0f 75
1470         void SSEOP_D(pcmpeqd_r128_rm128)(); // Opcode 66 0f 76
1471         void SSEOP_D(paddq_r128_rm128)();  // Opcode 66 0f d4
1472         void SSEOP_D(pmullw_r128_rm128)();  // Opcode 66 0f d5
1473         void SSEOP_D(paddb_r128_rm128)();  // Opcode 66 0f fc
1474         void SSEOP_D(paddw_r128_rm128)();  // Opcode 66 0f fd
1475         void SSEOP_D(paddd_r128_rm128)();  // Opcode 66 0f fe
1476         void SSEOP_D(psubusb_r128_rm128)();  // Opcode 66 0f d8
1477         void SSEOP_D(psubusw_r128_rm128)();  // Opcode 66 0f d9
1478         void SSEOP_D(pand_r128_rm128)();  // Opcode 66 0f db
1479         void SSEOP_D(pandn_r128_rm128)();  // Opcode 66 0f df
1480         void SSEOP_D(paddusb_r128_rm128)();  // Opcode 66 0f dc
1481         void SSEOP_D(paddusw_r128_rm128)();  // Opcode 66 0f dd
1482         void SSEOP_D(pmaxub_r128_rm128)(); // Opcode 66 0f de
1483         void SSEOP_D(pmulhuw_r128_rm128)();  // Opcode 66 0f e4
1484         void SSEOP_D(pmulhw_r128_rm128)();  // Opcode 66 0f e5
1485         void SSEOP_D(psubsb_r128_rm128)();  // Opcode 66 0f e8
1486         void SSEOP_D(psubsw_r128_rm128)();  // Opcode 66 0f e9
1487         void SSEOP_D(pminsw_r128_rm128)(); // Opcode 66 0f ea
1488         void SSEOP_D(pmaxsw_r128_rm128)(); // Opcode 66 0f ee
1489         void SSEOP_D(paddsb_r128_rm128)();  // Opcode 66 0f ec
1490         void SSEOP_D(paddsw_r128_rm128)();  // Opcode 66 0f ed
1491         void SSEOP_D(por_r128_rm128)();  // Opcode 66 0f eb
1492         void SSEOP_D(pxor_r128_rm128)();  // Opcode 66 0f ef
1493         void SSEOP_D(pmaddwd_r128_rm128)();  // Opcode 66 0f f5
1494         void SSEOP_D(psubb_r128_rm128)();  // Opcode 66 0f f8
1495         void SSEOP_D(psubw_r128_rm128)();  // Opcode 66 0f f9
1496         void SSEOP_D(psubd_r128_rm128)();  // Opcode 66 0f fa
1497         void SSEOP_D(psadbw_r128_rm128)(); // Opcode 66 0f f6
1498         void SSEOP_D(pavgb_r128_rm128)(); // Opcode 66 0f e0
1499         void SSEOP_D(pavgw_r128_rm128)(); // Opcode 66 0f e3
1500         void SSEOP_D(psrlw_r128_rm128)();  // Opcode 66 0f d1
1501         void SSEOP_D(psrld_r128_rm128)();  // Opcode 66 0f d2
1502         void SSEOP_D(psrlq_r128_rm128)();  // Opcode 66 0f d3
1503         void SSEOP_D(psllw_r128_rm128)();  // Opcode 66 0f f1
1504         void SSEOP_D(pslld_r128_rm128)();  // Opcode 66 0f f2
1505         void SSEOP_D(psllq_r128_rm128)();  // Opcode 66 0f f3
1506         void SSEOP_D(psraw_r128_rm128)();  // Opcode 66 0f e1
1507         void SSEOP_D(psrad_r128_rm128)();  // Opcode 66 0f e2
1508         void SSEOP_D(movntdq_m128_r128)();  // Opcode 66 0f e7
1509         void SSEOP_D(cvttpd2dq_r128_rm128)();  // Opcode 66 0f e6
1510         void SSEOP_D(movq_r128m64_r128)();  // Opcode 66 0f d6
1511         void SSEOP_D(addsubpd_r128_rm128)();  // Opcode 66 0f d0
1512         void SSEOP_D(haddpd_r128_rm128)();  // Opcode 66 0f 7c
1513         void SSEOP_D(hsubpd_r128_rm128)();  // Opcode 66 0f 7d
1514         void SSEOP_D(sqrtpd_r128_rm128)();  // Opcode 66 0f 51
1515         void SSEOP_D(cvtpi2pd_r128_rm64)();  // Opcode 66 0f 2a
1516         void SSEOP_D(cvttpd2pi_r64_rm128)();  // Opcode 66 0f 2c
1517         void SSEOP_D(cvtpd2pi_r64_rm128)();  // Opcode 66 0f 2d
1518         void SSEOP_D(cvtpd2ps_r128_rm128)();  // Opcode 66 0f 5a
1519         void SSEOP_D(cvtps2dq_r128_rm128)();  // Opcode 66 0f 5b
1520         void SSEOP_D(addpd_r128_rm128)();  // Opcode 66 0f 58
1521         void SSEOP_D(mulpd_r128_rm128)();  // Opcode 66 0f 59
1522         void SSEOP_D(subpd_r128_rm128)();  // Opcode 66 0f 5c
1523         void SSEOP_D(minpd_r128_rm128)();  // Opcode 66 0f 5d
1524         void SSEOP_D(divpd_r128_rm128)();  // Opcode 66 0f 5e
1525         void SSEOP_D(maxpd_r128_rm128)();  // Opcode 66 0f 5f
1526         void SSEOP_D(movntpd_m128_r128)();  // Opcode 66 0f 2b
1527         void SSEOP_D(movapd_r128_rm128)();  // Opcode 66 0f 28
1528         void SSEOP_D(movapd_rm128_r128)();  // Opcode 66 0f 29
1529         void SSEOP_D(movsd_r128_r128m64)(); // Opcode f2 0f 10
1530         void SSEOP_D(movsd_r128m64_r128)(); // Opcode f2 0f 11
1531         void SSEOP_D(movddup_r128_r128m64)(); // Opcode f2 0f 12
1532         void SSEOP_D(cvtsi2sd_r128_rm32)(); // Opcode f2 0f 2a
1533         void SSEOP_D(cvttsd2si_r32_r128m64)(); // Opcode f2 0f 2c
1534         void SSEOP_D(cvtsd2si_r32_r128m64)(); // Opcode f2 0f 2d
1535         void SSEOP_D(sqrtsd_r128_r128m64)(); // Opcode f2 0f 51
1536         void SSEOP_D(addsd_r128_r128m64)(); // Opcode f2 0f 58
1537         void SSEOP_D(mulsd_r128_r128m64)(); // Opcode f2 0f 59
1538         void SSEOP_D(cvtsd2ss_r128_r128m64)(); // Opcode f2 0f 5a
1539         void SSEOP_D(subsd_r128_r128m64)(); // Opcode f2 0f 5c
1540         void SSEOP_D(minsd_r128_r128m64)(); // Opcode f2 0f 5d
1541         void SSEOP_D(divsd_r128_r128m64)(); // Opcode f2 0f 5e
1542         void SSEOP_D(maxsd_r128_r128m64)(); // Opcode f2 0f 5f
1543         void SSEOP_D(haddps_r128_rm128)(); // Opcode f2 0f 7c
1544         void SSEOP_D(hsubps_r128_rm128)(); // Opcode f2 0f 7d
1545         void SSEOP_D(cmpsd_r128_r128m64_i8)(); // Opcode f2 0f c2
1546         void SSEOP_D(addsubps_r128_rm128)(); // Opcode f2 0f d0
1547         void SSEOP_D(movdq2q_r64_r128)(); // Opcode f2 0f d6
1548         void SSEOP_D(cvtpd2dq_r128_rm128)(); // Opcode f2 0f e6
1549         void SSEOP_D(lddqu_r128_m128)(); // Opcode f2 0f f0
1550         // x87 FPU
1551         void x87_write_stack( int i, floatx80 value, int update_tag);
1552         void x87_reset();
1553         void x87_fadd_m32real(UINT8 modrm);
1554         void x87_fadd_m64real(UINT8 modrm);
1555         void x87_fadd_st_sti(UINT8 modrm);
1556         void x87_fadd_sti_st(UINT8 modrm);
1557         void x87_faddp(UINT8 modrm);
1558         void x87_fiadd_m32int(UINT8 modrm);
1559         void x87_fiadd_m16int(UINT8 modrm);
1560         void x87_fsub_m32real(UINT8 modrm);
1561         void x87_fsub_m64real(UINT8 modrm);
1562         void x87_fsub_st_sti(UINT8 modrm);
1563         void x87_fsub_sti_st( UINT8 modrm);
1564         void x87_fsubp(UINT8 modrm);
1565         void x87_fisub_m32int(UINT8 modrm);
1566         void x87_fisub_m16int(UINT8 modrm);
1567         void x87_fsubr_m32real(UINT8 modrm);
1568         void x87_fsubr_m64real(UINT8 modrm);
1569         void x87_fsubr_st_sti(UINT8 modrm);
1570         void x87_fsubr_sti_st(UINT8 modrm);
1571         void x87_fsubrp(UINT8 modrm);
1572         void x87_fisubr_m32int(UINT8 modrm);
1573         void x87_fisubr_m16int(UINT8 modrm);
1574         void x87_fdiv_m32real(UINT8 modrm);
1575         void x87_fdiv_m64real(UINT8 modrm);
1576         void x87_fdiv_st_sti(UINT8 modrm);
1577         void x87_fdiv_sti_st(UINT8 modrm);
1578         void x87_fdivp(UINT8 modrm);
1579         void x87_fidiv_m32int(UINT8 modrm);
1580         void x87_fidiv_m16int(UINT8 modrm);
1581         void x87_fdivr_m32real(UINT8 modrm);
1582         void x87_fdivr_m64real(UINT8 modrm);
1583         void x87_fdivr_st_sti(UINT8 modrm);
1584         void x87_fdivr_sti_st(UINT8 modrm);
1585         void x87_fdivrp(UINT8 modrm);
1586         void x87_fidivr_m32int( UINT8 modrm);
1587         void x87_fidivr_m16int( UINT8 modrm);
1588         void x87_fmul_m32real( UINT8 modrm);
1589         void x87_fmul_m64real( UINT8 modrm);
1590         void x87_fmul_st_sti( UINT8 modrm);
1591         void x87_fmul_sti_st( UINT8 modrm);
1592         void x87_fmulp( UINT8 modrm);
1593         void x87_fimul_m32int( UINT8 modrm);
1594         void x87_fimul_m16int( UINT8 modrm);
1595         void x87_fcmovb_sti( UINT8 modrm);
1596         void x87_fcmove_sti( UINT8 modrm);
1597         void x87_fcmovbe_sti( UINT8 modrm);
1598         void x87_fcmovu_sti( UINT8 modrm);
1599         void x87_fcmovnb_sti( UINT8 modrm);
1600         void x87_fcmovne_sti( UINT8 modrm);
1601         void x87_fcmovnbe_sti( UINT8 modrm);
1602         void x87_fcmovnu_sti( UINT8 modrm);
1603         void x87_fprem( UINT8 modrm);
1604         void x87_fprem1( UINT8 modrm);
1605         void x87_fsqrt( UINT8 modrm);
1606         void x87_f2xm1( UINT8 modrm);
1607         void x87_fyl2x( UINT8 modrm);
1608         void x87_fyl2xp1( UINT8 modrm);
1609         void x87_fptan( UINT8 modrm);
1610         void x87_fpatan( UINT8 modrm);
1611         void x87_fsin( UINT8 modrm);
1612         void x87_fcos( UINT8 modrm);
1613         void x87_fsincos( UINT8 modrm);
1614         void x87_fld_m32real( UINT8 modrm);
1615         void x87_fld_m64real( UINT8 modrm);
1616         void x87_fld_m80real( UINT8 modrm);
1617         void x87_fld_sti( UINT8 modrm);
1618         void x87_fild_m16int( UINT8 modrm);
1619         void x87_fild_m32int( UINT8 modrm);
1620         void x87_fild_m64int( UINT8 modrm);
1621         void x87_fbld( UINT8 modrm);
1622         void x87_fst_m32real( UINT8 modrm);
1623         void x87_fst_m64real( UINT8 modrm);
1624         void x87_fst_sti( UINT8 modrm);
1625         void x87_fstp_m32real( UINT8 modrm);
1626         void x87_fstp_m64real( UINT8 modrm);
1627         void x87_fstp_m80real( UINT8 modrm);
1628         void x87_fstp_sti( UINT8 modrm);
1629         void x87_fist_m16int( UINT8 modrm);
1630         void x87_fist_m32int( UINT8 modrm);
1631         void x87_fistp_m16int( UINT8 modrm);
1632         void x87_fistp_m32int( UINT8 modrm);
1633         void x87_fistp_m64int( UINT8 modrm);
1634         void x87_fbstp( UINT8 modrm);
1635         void x87_fld1( UINT8 modrm);
1636         void x87_fldl2t( UINT8 modrm);
1637         void x87_fldl2e( UINT8 modrm);
1638         void x87_fldpi( UINT8 modrm);
1639         void x87_fldlg2( UINT8 modrm);
1640         void x87_fldln2( UINT8 modrm);
1641         void x87_fldz( UINT8 modrm);
1642         void x87_fnop( UINT8 modrm);
1643         void x87_fchs( UINT8 modrm);
1644         void x87_fabs( UINT8 modrm);
1645         void x87_fscale( UINT8 modrm);
1646         void x87_frndint( UINT8 modrm);
1647         void x87_fxtract( UINT8 modrm);
1648         void x87_ftst( UINT8 modrm);
1649         void x87_fxam( UINT8 modrm);
1650         void x87_ficom_m16int( UINT8 modrm);
1651         void x87_ficom_m32int( UINT8 modrm);
1652         void x87_ficomp_m16int( UINT8 modrm);
1653         void x87_ficomp_m32int( UINT8 modrm);
1654         void x87_fcom_m32real( UINT8 modrm);
1655         void x87_fcom_m64real( UINT8 modrm);
1656         void x87_fcom_sti( UINT8 modrm);
1657         void x87_fcomp_m32real( UINT8 modrm);
1658         void x87_fcomp_m64real( UINT8 modrm);
1659         void x87_fcomp_sti( UINT8 modrm);
1660         void x87_fcomi_sti( UINT8 modrm);
1661         void x87_fcomip_sti( UINT8 modrm);
1662         void x87_fucomi_sti( UINT8 modrm);
1663         void x87_fucomip_sti( UINT8 modrm);
1664         void x87_fcompp( UINT8 modrm);
1665         void x87_fucom_sti( UINT8 modrm);
1666         void x87_fucomp_sti( UINT8 modrm);
1667         void x87_fucompp( UINT8 modrm);
1668         void x87_fdecstp( UINT8 modrm);
1669         void x87_fincstp( UINT8 modrm);
1670         void x87_fclex( UINT8 modrm);
1671         void x87_ffree( UINT8 modrm);
1672         void x87_finit( UINT8 modrm);
1673         void x87_fldcw( UINT8 modrm);
1674         void x87_fstcw( UINT8 modrm);
1675         void x87_fldenv( UINT8 modrm);
1676         void x87_fstenv( UINT8 modrm);
1677         void x87_fsave( UINT8 modrm);
1678         void x87_frstor( UINT8 modrm);
1679         void x87_fxch( UINT8 modrm);
1680         void x87_fxch_sti( UINT8 modrm);
1681         void x87_fstsw_ax( UINT8 modrm);
1682         void x87_fstsw_m2byte( UINT8 modrm);
1683         void x87_invalid( UINT8 modrm);
1684         void I386OP_D(x87_group_d8)();
1685         void I386OP_D(x87_group_d9)();
1686         void I386OP_D(x87_group_da)();
1687         void I386OP_D(x87_group_db)();
1688         void I386OP_D(x87_group_dc)();
1689         void I386OP_D(x87_group_dd)();
1690         void I386OP_D(x87_group_de)();
1691         void I386OP_D(x87_group_df)();
1692         void build_x87_opcode_table_d8();
1693         void build_x87_opcode_table_d9();
1694         void build_x87_opcode_table_da();
1695         void build_x87_opcode_table_db();
1696         void build_x87_opcode_table_dc();
1697         void build_x87_opcode_table_dd();
1698         void build_x87_opcode_table_de();
1699         void build_x87_opcode_table_df();
1700         void build_x87_opcode_table();
1701
1702         floatx80 x87_add( floatx80 a, floatx80 b);
1703         floatx80 x87_sub( floatx80 a, floatx80 b);
1704         floatx80 x87_mul( floatx80 a, floatx80 b);
1705         floatx80 x87_div( floatx80 a, floatx80 b);
1706
1707         void I386OP_D(decode_two_byte)();
1708         void I386OP_D(decode_three_byte38)();
1709         void I386OP_D(decode_three_byte3a)();
1710         void I386OP_D(decode_three_byte66)();
1711         void I386OP_D(decode_three_bytef2)();
1712         void I386OP_D(decode_three_bytef3)();
1713         void I386OP_D(decode_four_byte3866)();
1714         void I386OP_D(decode_four_byte3a66)();
1715         void I386OP_D(decode_four_byte3af2)();
1716         void I386OP_D(decode_four_byte38f2)();
1717         void I386OP_D(decode_four_byte38f3)();
1718 protected:
1719
1720         // Inline Utilities.
1721         INLINE INT8 SaturatedSignedWordToSignedByte(INT16 word);
1722         INLINE UINT8 SaturatedSignedWordToUnsignedByte(INT16 word);
1723         INLINE INT16 SaturatedSignedDwordToSignedWord(INT32 dword);
1724         INLINE UINT16 SaturatedSignedDwordToUnsignedWord(INT32 dword);
1725         //
1726         INLINE vtlb_entry get_permissions(UINT32 pte, int wp);
1727         INLINE int translate_address(int pl, int type, UINT32 *address, UINT32 *error);
1728         INLINE UINT32 i386_translate(int segment, UINT32 ip, int rwn);
1729         
1730         INLINE UINT8 FETCH();
1731         INLINE UINT16 FETCH16();
1732         INLINE UINT32 FETCH32();
1733         
1734         INLINE UINT8 READ8(UINT32 ea);
1735         INLINE UINT8 READ8PL0(UINT32 ea);
1736         INLINE UINT16 READ16(UINT32 ea);
1737         INLINE UINT16 READ16PL0(UINT32 ea);
1738         INLINE UINT32 READ32(UINT32 ea);
1739         INLINE UINT32 READ32PL0(UINT32 ea);
1740         INLINE UINT64 READ64(UINT32 ea);
1741         
1742         INLINE void WRITE8(UINT32 ea, UINT8 value);
1743         INLINE void WRITE16(UINT32 ea, UINT16 value);
1744         INLINE void WRITE32(UINT32 ea, UINT32 value);
1745         INLINE void WRITE64(UINT32 ea, UINT64 value);
1746         INLINE void WRITE_TEST(UINT32 ea);
1747
1748         INLINE void WRITEPORT8(offs_t port, UINT8 value);
1749         INLINE void WRITEPORT16(offs_t port, UINT16 value);
1750         INLINE void WRITEPORT32(offs_t port, UINT32 value);
1751         INLINE UINT8 READPORT8( offs_t port);
1752         INLINE UINT16 READPORT16( offs_t port);
1753         INLINE UINT32 READPORT32( offs_t port);
1754         
1755         INLINE void PUSH8(UINT8 value);
1756         INLINE UINT8 POP8();
1757         INLINE void PUSH16(UINT16 value);
1758         INLINE UINT16 POP16();
1759         INLINE void PUSH32(UINT32 value);
1760         INLINE UINT32 POP32();
1761         
1762         INLINE UINT8 OR8(UINT8 dst, UINT8 src);
1763         INLINE UINT8 AND8(UINT8 dst, UINT8 src);
1764         INLINE UINT8 XOR8(UINT8 dst, UINT8 src);
1765         INLINE UINT8 SBB8(UINT8 dst, UINT8 src, UINT8 b);
1766         INLINE UINT8 ADC8(UINT8 dst, UINT8 src, UINT8 c);
1767         INLINE UINT8 INC8(UINT8 dst);
1768         INLINE UINT8 DEC8(UINT8 dst);
1769
1770         INLINE UINT16 OR16(UINT16 dst, UINT16 src);
1771         INLINE UINT16 AND16(UINT16 dst, UINT16 src);
1772         INLINE UINT16 XOR16(UINT16 dst, UINT16 src);
1773         INLINE UINT16 SBB16(UINT16 dst, UINT16 src, UINT16 b);
1774         INLINE UINT16 ADC16(UINT16 dst, UINT16 src, UINT8 c);
1775         INLINE UINT16 INC16(UINT16 dst);
1776         INLINE UINT16 DEC16(UINT16 dst);
1777
1778         INLINE UINT32 OR32(UINT32 dst, UINT32 src);
1779         INLINE UINT32 AND32(UINT32 dst, UINT32 src);
1780         INLINE UINT32 XOR32(UINT32 dst, UINT32 src);
1781         INLINE UINT32 SBB32(UINT32 dst, UINT32 src, UINT32 b);
1782         INLINE UINT32 ADC32(UINT32 dst, UINT32 src, UINT32 c);
1783         INLINE UINT32 INC32(UINT32 dst);
1784         INLINE UINT32 DEC32(UINT32 dst);
1785         
1786         INLINE UINT64 MSR_READ(UINT32 offset,UINT8 *valid_msr);
1787         INLINE void MSR_WRITE(UINT32 offset, UINT64 data, UINT8 *valid_msr);
1788         
1789         INLINE void CHANGE_PC(UINT32 pc);
1790         INLINE void NEAR_BRANCH(INT32 offs);
1791         INLINE void BUMP_SI(int adjustment);
1792         INLINE void BUMP_DI(int adjustment);
1793         INLINE void CYCLES(int x);
1794         INLINE void CYCLES_RM(int modrm, int r, int m);
1795
1796         INLINE void MMXPROLOG();
1797         INLINE void READMMX(UINT32 ea,MMX_REG &r);
1798         INLINE void WRITEMMX(UINT32 ea,MMX_REG &r);
1799         INLINE void READXMM(UINT32 ea,XMM_REG &r);
1800         INLINE void WRITEXMM(UINT32 ea,XMM_REG &r);
1801         INLINE void READXMM_LO64(UINT32 ea,XMM_REG &r);
1802         INLINE void WRITEXMM_LO64(UINT32 ea,XMM_REG &r);
1803         INLINE void READXMM_HI64(UINT32 ea,XMM_REG &r);
1804         INLINE void WRITEXMM_HI64(UINT32 ea,XMM_REG &r);
1805
1806         INLINE flag floatx80_is_quiet_nan(floatx80 a);
1807         INLINE int floatx80_is_zero(floatx80 fx);
1808         INLINE int floatx80_is_inf(floatx80 fx);
1809         INLINE int floatx80_is_denormal(floatx80 fx);
1810         INLINE floatx80 floatx80_abs(floatx80 fx);
1811         INLINE double fx80_to_double(floatx80 fx);
1812         INLINE floatx80 double_to_fx80(double in);
1813         INLINE floatx80 READ80( UINT32 ea);
1814         INLINE void WRITE80( UINT32 ea, floatx80 t);
1815         INLINE void x87_set_stack_top(int top);
1816         INLINE void x87_set_tag(int reg, int tag);
1817         INLINE void x87_set_stack_underflow();
1818         INLINE void x87_set_stack_overflow();
1819         INLINE void x87_write_cw( UINT16 cw);
1820
1821         UINT32 I386OP_D(shift_rotate32)(UINT8 modrm, UINT32 value, UINT8 shift);
1822
1823         UINT64 pentium_msr_read(UINT32 offset,UINT8 *valid_msr);;
1824         void pentium_msr_write(UINT32 offset, UINT64 data, UINT8 *valid_msr);
1825         UINT64 p6_msr_read(UINT32 offset,UINT8 *valid_msr);;
1826         void p6_msr_write(UINT32 offset, UINT64 data, UINT8 *valid_msr);
1827         UINT64 piv_msr_read(UINT32 offset,UINT8 *valid_msr);;
1828         void piv_msr_write(UINT32 offset, UINT64 data, UINT8 *valid_msr);
1829         
1830         int x87_inc_stack();
1831         int x87_dec_stack();
1832         int x87_check_exceptions();
1833 };
1834 extern const X86_OPCODE x86_opcode_table[];
1835 extern const X86_CYCLE_TABLE x86_cycle_table[];
1836
1837 /***********************************************************************************/
1838
1839 #define CYCLES_NUM(x)   (cpustate->cycles -= (x))
1840
1841 INLINE void I386_OPS_BASE::CYCLES(int x)
1842 {
1843         if (PROTECTED_MODE)
1844         {
1845                 cpustate->cycles -= cpustate->cycle_table_pm[x];
1846         }
1847         else
1848         {
1849                 cpustate->cycles -= cpustate->cycle_table_rm[x];
1850         }
1851 }
1852
1853 INLINE void I386_OPS_BASE::CYCLES_RM(int modrm, int r, int m)
1854 {
1855         if (modrm >= 0xc0)
1856         {
1857                 if (PROTECTED_MODE)
1858                 {
1859                         cpustate->cycles -= cpustate->cycle_table_pm[r];
1860                 }
1861                 else
1862                 {
1863                         cpustate->cycles -= cpustate->cycle_table_rm[r];
1864                 }
1865         }
1866         else
1867         {
1868                 if (PROTECTED_MODE)
1869                 {
1870                         cpustate->cycles -= cpustate->cycle_table_pm[m];
1871                 }
1872                 else
1873                 {
1874                         cpustate->cycles -= cpustate->cycle_table_rm[m];
1875                 }
1876         }
1877 }
1878
1879
1880 INLINE UINT32 I386_OPS_BASE::i386_translate(int segment, UINT32 ip, int rwn)
1881 {
1882         // TODO: segment limit access size, execution permission, handle exception thrown from exception handler
1883         if(PROTECTED_MODE && !V8086_MODE && (rwn != -1))
1884         {
1885                 if(!(cpustate->sreg[segment].valid))
1886                         FAULT_THROW((segment==SS)?FAULT_SS:FAULT_GP, 0);
1887                 if(i386_limit_check(segment, ip))
1888                         FAULT_THROW((segment==SS)?FAULT_SS:FAULT_GP, 0);
1889                 if((rwn == 0) && ((cpustate->sreg[segment].flags & 8) && !(cpustate->sreg[segment].flags & 2)))
1890                         FAULT_THROW(FAULT_GP, 0);
1891                 if((rwn == 1) && ((cpustate->sreg[segment].flags & 8) || !(cpustate->sreg[segment].flags & 2)))
1892                         FAULT_THROW(FAULT_GP, 0);
1893         }
1894         return cpustate->sreg[segment].base + ip;
1895 }
1896
1897 #define VTLB_FLAG_DIRTY 0x100
1898
1899 INLINE vtlb_entry I386_OPS_BASE::get_permissions(UINT32 pte, int wp)
1900 {
1901         vtlb_entry ret = VTLB_READ_ALLOWED | ((pte & 4) ? VTLB_USER_READ_ALLOWED : 0);
1902         if(!wp)
1903                 ret |= VTLB_WRITE_ALLOWED;
1904         if(pte & 2)
1905                 ret |= VTLB_WRITE_ALLOWED | ((pte & 4) ? VTLB_USER_WRITE_ALLOWED : 0);
1906         return ret;
1907 }
1908
1909 //#define TEST_TLB
1910
1911 INLINE int I386_OPS_BASE::translate_address(int pl, int type, UINT32 *address, UINT32 *error)
1912 {
1913         if(!(cpustate->cr[0] & 0x80000000)) // Some (very few) old OS's won't work with this
1914                 return TRUE;
1915
1916         const vtlb_entry *table = vtlb_table(cpustate->vtlb);
1917         UINT32 index = *address >> 12;
1918         vtlb_entry entry = table[index];
1919         if(type == TRANSLATE_FETCH)
1920                 type = TRANSLATE_READ;
1921         if(pl == 3)
1922                 type |= TRANSLATE_USER_MASK;
1923 #ifdef TEST_TLB
1924         UINT32 test_addr = *address;
1925 #endif
1926
1927         if(!(entry & VTLB_FLAG_VALID) || ((type & TRANSLATE_WRITE) && !(entry & VTLB_FLAG_DIRTY)))
1928         {
1929                 if(!i386_translate_address( type, address, &entry))
1930                 {
1931                         *error = ((type & TRANSLATE_WRITE) ? 2 : 0) | ((cpustate->CPL == 3) ? 4 : 0);
1932                         if(entry)
1933                                 *error |= 1;
1934                         return FALSE;
1935                 }
1936                 vtlb_dynload(cpustate->vtlb, index, *address, entry);
1937                 return TRUE;
1938         }
1939         if(!(entry & (1 << type)))
1940         {
1941                 *error = ((type & TRANSLATE_WRITE) ? 2 : 0) | ((cpustate->CPL == 3) ? 4 : 0) | 1;
1942                 return FALSE;
1943         }
1944         *address = (entry & 0xfffff000) | (*address & 0xfff);
1945 #ifdef TEST_TLB
1946         int test_ret = i386_translate_address( type | TRANSLATE_DEBUG_MASK, &test_addr, NULL);
1947         if(!test_ret || (test_addr != *address))
1948                 logerror("TLB-PTE mismatch! %06X %06X %06x\n", *address, test_addr, cpustate->pc);
1949 #endif
1950         return TRUE;
1951 }
1952
1953 INLINE void I386_OPS_BASE::CHANGE_PC(UINT32 pc)
1954 {
1955         cpustate->pc = i386_translate(CS, pc, -1 );
1956 }
1957
1958 INLINE void I386_OPS_BASE::NEAR_BRANCH(INT32 offs)
1959 {
1960         /* TODO: limit */
1961         cpustate->eip += offs;
1962         cpustate->pc += offs;
1963 }
1964
1965 INLINE UINT8 I386_OPS_BASE::FETCH()
1966 {
1967         UINT8 value;
1968         UINT32 address = cpustate->pc, error;
1969
1970         if(!translate_address(cpustate->CPL,TRANSLATE_FETCH,&address,&error))
1971                 PF_THROW(error);
1972
1973         value = cpustate->program->read_data8(address & cpustate->a20_mask);
1974 #ifdef DEBUG_MISSING_OPCODE
1975         cpustate->opcode_bytes[cpustate->opcode_bytes_length] = value;
1976         cpustate->opcode_bytes_length = (cpustate->opcode_bytes_length + 1) & 15;
1977 #endif
1978         cpustate->eip++;
1979         cpustate->pc++;
1980         return value;
1981 }
1982
1983 INLINE UINT16 I386_OPS_BASE::FETCH16()
1984 {
1985         UINT16 value;
1986         UINT32 address = cpustate->pc, error;
1987
1988         if( address & 0x1 ) {       /* Unaligned read */
1989                 value = (FETCH() << 0);
1990                 value |= (FETCH() << 8);
1991         } else {
1992                 if(!translate_address(cpustate->CPL,TRANSLATE_FETCH,&address,&error))
1993                         PF_THROW(error);
1994                 address &= cpustate->a20_mask;
1995                 value = cpustate->program->read_data16(address);
1996                 cpustate->eip += 2;
1997                 cpustate->pc += 2;
1998         }
1999         return value;
2000 }
2001 INLINE UINT32 I386_OPS_BASE::FETCH32()
2002 {
2003         UINT32 value;
2004         UINT32 address = cpustate->pc, error;
2005
2006         if( cpustate->pc & 0x3 ) {      /* Unaligned read */
2007                 value = (FETCH() << 0);
2008                 value |= (FETCH() << 8);
2009                 value |= (FETCH() << 16);
2010                 value |= (FETCH() << 24);
2011         } else {
2012                 if(!translate_address(cpustate->CPL,TRANSLATE_FETCH,&address,&error))
2013                         PF_THROW(error);
2014
2015                 address &= cpustate->a20_mask;
2016                 value = cpustate->program->read_data32(address);
2017                 cpustate->eip += 4;
2018                 cpustate->pc += 4;
2019         }
2020         return value;
2021 }
2022
2023 INLINE UINT8 I386_OPS_BASE::READ8(UINT32 ea)
2024 {
2025         UINT32 address = ea, error;
2026
2027         if(!translate_address(cpustate->CPL,TRANSLATE_READ,&address, &error))
2028                 PF_THROW(error);
2029
2030         address &= cpustate->a20_mask;
2031         return cpustate->program->read_data8(address);
2032 }
2033
2034 INLINE UINT16 I386_OPS_BASE::READ16(UINT32 ea)
2035 {
2036         UINT16 value;
2037         UINT32 address = ea, error;
2038
2039         if( ea & 0x1 ) {        /* Unaligned read */
2040                 value = (READ8(address+0) << 0);
2041                 value |= (READ8(address+1) << 8);
2042         } else {
2043                 if(!translate_address(cpustate->CPL,TRANSLATE_READ,&address,&error))
2044                         PF_THROW(error);
2045
2046                 address &= cpustate->a20_mask;
2047                 value = cpustate->program->read_data16( address );
2048         }
2049         return value;
2050 }
2051 INLINE UINT32 I386_OPS_BASE::READ32(UINT32 ea)
2052 {
2053         UINT32 value;
2054         UINT32 address = ea, error;
2055
2056         if( ea & 0x3 ) {        /* Unaligned read */
2057                 value = (READ8(address+0) << 0);
2058                 value |= (READ8(address+1) << 8);
2059                 value |= (READ8(address+2) << 16),
2060                 value |= (READ8(address+3) << 24);
2061         } else {
2062                 if(!translate_address(cpustate->CPL,TRANSLATE_READ,&address,&error))
2063                         PF_THROW(error);
2064
2065                 address &= cpustate->a20_mask;
2066                 value = cpustate->program->read_data32( address );
2067         }
2068         return value;
2069 }
2070
2071 INLINE UINT64 I386_OPS_BASE::READ64(UINT32 ea)
2072 {
2073         UINT64 value;
2074         UINT32 address = ea, error;
2075
2076         if( ea & 0x7 ) {        /* Unaligned read */
2077                 value = (((UINT64) READ8( address+0 )) << 0);
2078                 value |= (((UINT64) READ8( address+1 )) << 8);
2079                 value |= (((UINT64) READ8( address+2 )) << 16);
2080                 value |= (((UINT64) READ8( address+3 )) << 24);
2081                 value |= (((UINT64) READ8( address+4 )) << 32);
2082                 value |= (((UINT64) READ8( address+5 )) << 40);
2083                 value |= (((UINT64) READ8( address+6 )) << 48);
2084                 value |= (((UINT64) READ8( address+7 )) << 56);
2085         } else {
2086                 if(!translate_address(cpustate->CPL,TRANSLATE_READ,&address,&error))
2087                         PF_THROW(error);
2088
2089                 address &= cpustate->a20_mask;
2090                 value = (((UINT64) cpustate->program->read_data32( address+0 )) << 0);
2091                 value |= (((UINT64) cpustate->program->read_data32( address+4 )) << 32);
2092         }
2093         return value;
2094 }
2095
2096 INLINE UINT8 I386_OPS_BASE::READ8PL0(UINT32 ea)
2097 {
2098         UINT32 address = ea, error;
2099
2100         if(!translate_address(0,TRANSLATE_READ,&address,&error))
2101                 PF_THROW(error);
2102
2103         address &= cpustate->a20_mask;
2104         return cpustate->program->read_data8(address);
2105 }
2106
2107 INLINE UINT16 I386_OPS_BASE::READ16PL0(UINT32 ea)
2108 {
2109         UINT16 value;
2110         UINT32 address = ea, error;
2111
2112         if( ea & 0x1 ) {        /* Unaligned read */
2113                 value = (READ8PL0( address+0 ) << 0);
2114                 value |= (READ8PL0( address+1 ) << 8);
2115         } else {
2116                 if(!translate_address(0,TRANSLATE_READ,&address,&error))
2117                         PF_THROW(error);
2118
2119                 address &= cpustate->a20_mask;
2120                 value = cpustate->program->read_data16( address );
2121         }
2122         return value;
2123 }
2124
2125 INLINE UINT32 I386_OPS_BASE::READ32PL0(UINT32 ea)
2126 {
2127         UINT32 value;
2128         UINT32 address = ea, error;
2129
2130         if( ea & 0x3 ) {        /* Unaligned read */
2131                 value = (READ8PL0( address+0 ) << 0);
2132                 value |= (READ8PL0( address+1 ) << 8);
2133                 value |= (READ8PL0( address+2 ) << 16);
2134                 value |= (READ8PL0( address+3 ) << 24);
2135         } else {
2136                 if(!translate_address(0,TRANSLATE_READ,&address,&error))
2137                         PF_THROW(error);
2138
2139                 address &= cpustate->a20_mask;
2140                 value = cpustate->program->read_data32( address );
2141         }
2142         return value;
2143 }
2144
2145 INLINE void I386_OPS_BASE::WRITE_TEST(UINT32 ea)
2146 {
2147         UINT32 address = ea, error;
2148         if(!translate_address(cpustate->CPL,TRANSLATE_WRITE,&address,&error))
2149                 PF_THROW(error);
2150 }
2151
2152 INLINE void I386_OPS_BASE::WRITE8(UINT32 ea, UINT8 value)
2153 {
2154         UINT32 address = ea, error;
2155
2156         if(!translate_address(cpustate->CPL,TRANSLATE_WRITE,&address,&error))
2157                 PF_THROW(error);
2158
2159         address &= cpustate->a20_mask;
2160         cpustate->program->write_data8(address, value);
2161 }
2162
2163 INLINE void I386_OPS_BASE::WRITE16(UINT32 ea, UINT16 value)
2164 {
2165         UINT32 address = ea, error;
2166
2167         if( ea & 0x1 ) {        /* Unaligned write */
2168                 WRITE8( address+0, value & 0xff );
2169                 WRITE8( address+1, (value >> 8) & 0xff );
2170         } else {
2171                 if(!translate_address(cpustate->CPL,TRANSLATE_WRITE,&address,&error))
2172                         PF_THROW(error);
2173
2174                 address &= cpustate->a20_mask;
2175                 cpustate->program->write_data16(address, value);
2176         }
2177 }
2178
2179 INLINE void I386_OPS_BASE::WRITE32(UINT32 ea, UINT32 value)
2180 {
2181         UINT32 address = ea, error;
2182
2183         if( ea & 0x3 ) {        /* Unaligned write */
2184                 WRITE8( address+0, value & 0xff );
2185                 WRITE8( address+1, (value >> 8) & 0xff );
2186                 WRITE8( address+2, (value >> 16) & 0xff );
2187                 WRITE8( address+3, (value >> 24) & 0xff );
2188         } else {
2189                 if(!translate_address(cpustate->CPL,TRANSLATE_WRITE,&address,&error))
2190                         PF_THROW(error);
2191
2192                 ea &= cpustate->a20_mask;
2193                 cpustate->program->write_data32(address, value);
2194         }
2195 }
2196
2197 INLINE void I386_OPS_BASE::WRITE64(UINT32 ea, UINT64 value)
2198 {
2199         UINT32 address = ea, error;
2200
2201         if( ea & 0x7 ) {        /* Unaligned write */
2202                 WRITE8( address+0, value & 0xff );
2203                 WRITE8( address+1, (value >> 8) & 0xff );
2204                 WRITE8( address+2, (value >> 16) & 0xff );
2205                 WRITE8( address+3, (value >> 24) & 0xff );
2206                 WRITE8( address+4, (value >> 32) & 0xff );
2207                 WRITE8( address+5, (value >> 40) & 0xff );
2208                 WRITE8( address+6, (value >> 48) & 0xff );
2209                 WRITE8( address+7, (value >> 56) & 0xff );
2210         } else {
2211                 if(!translate_address(cpustate->CPL,TRANSLATE_WRITE,&address,&error))
2212                         PF_THROW(error);
2213
2214                 ea &= cpustate->a20_mask;
2215                 cpustate->program->write_data32(address+0, value & 0xffffffff);
2216                 cpustate->program->write_data32(address+4, (value >> 32) & 0xffffffff);
2217         }
2218 }
2219
2220 /***********************************************************************************/
2221
2222 INLINE UINT8 I386_OPS_BASE::OR8(UINT8 dst, UINT8 src)
2223 {
2224         UINT8 res = dst | src;
2225         cpustate->CF = cpustate->OF = 0;
2226         SetSZPF8(res);
2227         return res;
2228 }
2229
2230 INLINE UINT16 I386_OPS_BASE::OR16(UINT16 dst, UINT16 src)
2231 {
2232         UINT16 res = dst | src;
2233         cpustate->CF = cpustate->OF = 0;
2234         SetSZPF16(res);
2235         return res;
2236 }
2237
2238 INLINE UINT32 I386_OPS_BASE::OR32(UINT32 dst, UINT32 src)
2239 {
2240         UINT32 res = dst | src;
2241         cpustate->CF = cpustate->OF = 0;
2242         SetSZPF32(res);
2243         return res;
2244 }
2245
2246 INLINE UINT8 I386_OPS_BASE::AND8(UINT8 dst, UINT8 src)
2247 {
2248         UINT8 res = dst & src;
2249         cpustate->CF = cpustate->OF = 0;
2250         SetSZPF8(res);
2251         return res;
2252 }
2253 INLINE UINT16 I386_OPS_BASE::AND16(UINT16 dst, UINT16 src)
2254 {
2255         UINT16 res = dst & src;
2256         cpustate->CF = cpustate->OF = 0;
2257         SetSZPF16(res);
2258         return res;
2259 }
2260 INLINE UINT32 I386_OPS_BASE::AND32(UINT32 dst, UINT32 src)
2261 {
2262         UINT32 res = dst & src;
2263         cpustate->CF = cpustate->OF = 0;
2264         SetSZPF32(res);
2265         return res;
2266 }
2267
2268 INLINE UINT8 I386_OPS_BASE::XOR8(UINT8 dst, UINT8 src)
2269 {
2270         UINT8 res = dst ^ src;
2271         cpustate->CF = cpustate->OF = 0;
2272         SetSZPF8(res);
2273         return res;
2274 }
2275 INLINE UINT16 I386_OPS_BASE::XOR16(UINT16 dst, UINT16 src)
2276 {
2277         UINT16 res = dst ^ src;
2278         cpustate->CF = cpustate->OF = 0;
2279         SetSZPF16(res);
2280         return res;
2281 }
2282 INLINE UINT32 I386_OPS_BASE::XOR32(UINT32 dst, UINT32 src)
2283 {
2284         UINT32 res = dst ^ src;
2285         cpustate->CF = cpustate->OF = 0;
2286         SetSZPF32(res);
2287         return res;
2288 }
2289
2290 #define SUB8(dst, src) SBB8(dst, src, 0)
2291 INLINE UINT8 I386_OPS_BASE::SBB8(UINT8 dst, UINT8 src, UINT8 b)
2292 {
2293         UINT16 res = (UINT16)dst - (UINT16)src - (UINT8)b;
2294         SetCF8(res);
2295         SetOF_Sub8(res,src,dst);
2296         SetAF(res,src,dst);
2297         SetSZPF8(res);
2298         return (UINT8)res;
2299 }
2300
2301 #define SUB16(dst, src) SBB16(dst, src, 0)
2302 INLINE UINT16 I386_OPS_BASE::SBB16(UINT16 dst, UINT16 src, UINT16 b)
2303 {
2304         UINT32 res = (UINT32)dst - (UINT32)src - (UINT32)b;
2305         SetCF16(res);
2306         SetOF_Sub16(res,src,dst);
2307         SetAF(res,src,dst);
2308         SetSZPF16(res);
2309         return (UINT16)res;
2310 }
2311
2312 #define SUB32(dst, src) SBB32(dst, src, 0)
2313 INLINE UINT32 I386_OPS_BASE::SBB32(UINT32 dst, UINT32 src, UINT32 b)
2314 {
2315         UINT64 res = (UINT64)dst - (UINT64)src - (UINT64) b;
2316         SetCF32(res);
2317         SetOF_Sub32(res,src,dst);
2318         SetAF(res,src,dst);
2319         SetSZPF32(res);
2320         return (UINT32)res;
2321 }
2322
2323 #define ADD8(dst, src) ADC8(dst, src, 0)
2324 INLINE UINT8 I386_OPS_BASE::ADC8(UINT8 dst, UINT8 src, UINT8 c)
2325 {
2326         UINT16 res = (UINT16)dst + (UINT16)src + (UINT16)c;
2327         SetCF8(res);
2328         SetOF_Add8(res,src,dst);
2329         SetAF(res,src,dst);
2330         SetSZPF8(res);
2331         return (UINT8)res;
2332 }
2333
2334 #define ADD16(dst, src) ADC16(dst, src, 0)
2335 INLINE UINT16 I386_OPS_BASE::ADC16(UINT16 dst, UINT16 src, UINT8 c)
2336 {
2337         UINT32 res = (UINT32)dst + (UINT32)src + (UINT32)c;
2338         SetCF16(res);
2339         SetOF_Add16(res,src,dst);
2340         SetAF(res,src,dst);
2341         SetSZPF16(res);
2342         return (UINT16)res;
2343 }
2344
2345 #define ADD32(dst, src) ADC32(dst, src, 0)
2346 INLINE UINT32 I386_OPS_BASE::ADC32(UINT32 dst, UINT32 src, UINT32 c)
2347 {
2348         UINT64 res = (UINT64)dst + (UINT64)src + (UINT64) c;
2349         SetCF32(res);
2350         SetOF_Add32(res,src,dst);
2351         SetAF(res,src,dst);
2352         SetSZPF32(res);
2353         return (UINT32)res;
2354 }
2355
2356 INLINE UINT8 I386_OPS_BASE::INC8(UINT8 dst)
2357 {
2358         UINT16 res = (UINT16)dst + 1;
2359         SetOF_Add8(res,1,dst);
2360         SetAF(res,1,dst);
2361         SetSZPF8(res);
2362         return (UINT8)res;
2363 }
2364 INLINE UINT16 I386_OPS_BASE::INC16(UINT16 dst)
2365 {
2366         UINT32 res = (UINT32)dst + 1;
2367         SetOF_Add16(res,1,dst);
2368         SetAF(res,1,dst);
2369         SetSZPF16(res);
2370         return (UINT16)res;
2371 }
2372 INLINE UINT32 I386_OPS_BASE::INC32(UINT32 dst)
2373 {
2374         UINT64 res = (UINT64)dst + 1;
2375         SetOF_Add32(res,1,dst);
2376         SetAF(res,1,dst);
2377         SetSZPF32(res);
2378         return (UINT32)res;
2379 }
2380
2381 INLINE UINT8 I386_OPS_BASE::DEC8(UINT8 dst)
2382 {
2383         UINT16 res = (UINT16)dst - 1;
2384         SetOF_Sub8(res,1,dst);
2385         SetAF(res,1,dst);
2386         SetSZPF8(res);
2387         return (UINT8)res;
2388 }
2389 INLINE UINT16 I386_OPS_BASE::DEC16(UINT16 dst)
2390 {
2391         UINT32 res = (UINT32)dst - 1;
2392         SetOF_Sub16(res,1,dst);
2393         SetAF(res,1,dst);
2394         SetSZPF16(res);
2395         return (UINT16)res;
2396 }
2397 INLINE UINT32 I386_OPS_BASE::DEC32(UINT32 dst)
2398 {
2399         UINT64 res = (UINT64)dst - 1;
2400         SetOF_Sub32(res,1,dst);
2401         SetAF(res,1,dst);
2402         SetSZPF32(res);
2403         return (UINT32)res;
2404 }
2405
2406
2407
2408 INLINE void I386_OPS_BASE::PUSH16(UINT16 value)
2409 {
2410         UINT32 ea, new_esp;
2411         if( STACK_32BIT ) {
2412                 new_esp = REG32(ESP) - 2;
2413                 ea = i386_translate( SS, new_esp, 1);
2414                 WRITE16( ea, value );
2415                 REG32(ESP) = new_esp;
2416         } else {
2417                 new_esp = (REG16(SP) - 2) & 0xffff;
2418                 ea = i386_translate( SS, new_esp, 1);
2419                 WRITE16( ea, value );
2420                 REG16(SP) = new_esp;
2421         }
2422 }
2423 INLINE void I386_OPS_BASE::PUSH32(UINT32 value)
2424 {
2425         UINT32 ea, new_esp;
2426         if( STACK_32BIT ) {
2427                 new_esp = REG32(ESP) - 4;
2428                 ea = i386_translate( SS, new_esp, 1);
2429                 WRITE32( ea, value );
2430                 REG32(ESP) = new_esp;
2431         } else {
2432                 new_esp = (REG16(SP) - 4) & 0xffff;
2433                 ea = i386_translate( SS, new_esp, 1);
2434                 WRITE32( ea, value );
2435                 REG16(SP) = new_esp;
2436         }
2437 }
2438 INLINE void I386_OPS_BASE::PUSH8(UINT8 value)
2439 {
2440         if( cpustate->operand_size ) {
2441                 PUSH32((INT32)(INT8)value);
2442         } else {
2443                 PUSH16((INT16)(INT8)value);
2444         }
2445 }
2446
2447 INLINE UINT8 I386_OPS_BASE::POP8()
2448 {
2449         UINT8 value;
2450         UINT32 ea, new_esp;
2451         if( STACK_32BIT ) {
2452                 new_esp = REG32(ESP) + 1;
2453                 ea = i386_translate( SS, new_esp - 1, 0);
2454                 value = READ8( ea );
2455                 REG32(ESP) = new_esp;
2456         } else {
2457                 new_esp = REG16(SP) + 1;
2458                 ea = i386_translate( SS, (new_esp - 1) & 0xffff, 0);
2459                 value = READ8( ea );
2460                 REG16(SP) = new_esp;
2461         }
2462         return value;
2463 }
2464
2465 INLINE UINT16 I386_OPS_BASE::POP16()
2466 {
2467         UINT16 value;
2468         UINT32 ea, new_esp;
2469         if( STACK_32BIT ) {
2470                 new_esp = REG32(ESP) + 2;
2471                 ea = i386_translate( SS, new_esp - 2, 0);
2472                 value = READ16( ea );
2473                 REG32(ESP) = new_esp;
2474         } else {
2475                 new_esp = REG16(SP) + 2;
2476                 ea = i386_translate( SS, (new_esp - 2) & 0xffff, 0);
2477                 value = READ16( ea );
2478                 REG16(SP) = new_esp;
2479         }
2480         return value;
2481 }
2482 INLINE UINT32 I386_OPS_BASE::POP32()
2483 {
2484         UINT32 value;
2485         UINT32 ea, new_esp;
2486         if( STACK_32BIT ) {
2487                 new_esp = REG32(ESP) + 4;
2488                 ea = i386_translate( SS, new_esp - 4, 0);
2489                 value = READ32( ea );
2490                 REG32(ESP) = new_esp;
2491         } else {
2492                 new_esp = REG16(SP) + 4;
2493                 ea = i386_translate( SS, (new_esp - 4) & 0xffff, 0);
2494                 value = READ32( ea );
2495                 REG16(SP) = new_esp;
2496         }
2497         return value;
2498 }
2499
2500 INLINE void I386_OPS_BASE::BUMP_SI(int adjustment)
2501 {
2502         if ( cpustate->address_size )
2503                 REG32(ESI) += ((cpustate->DF) ? -adjustment : +adjustment);
2504         else
2505                 REG16(SI) += ((cpustate->DF) ? -adjustment : +adjustment);
2506 }
2507
2508 INLINE void I386_OPS_BASE::BUMP_DI(int adjustment)
2509 {
2510         if ( cpustate->address_size )
2511                 REG32(EDI) += ((cpustate->DF) ? -adjustment : +adjustment);
2512         else
2513                 REG16(DI) += ((cpustate->DF) ? -adjustment : +adjustment);
2514 }
2515
2516
2517
2518 /***********************************************************************************
2519     I/O ACCESS
2520 ***********************************************************************************/
2521
2522 INLINE void I386_OPS_BASE::check_ioperm( offs_t port, UINT8 mask)
2523 {
2524         UINT8 IOPL, map;
2525         UINT16 IOPB;
2526         UINT32 address;
2527
2528         if(!PROTECTED_MODE)
2529                 return;
2530
2531         IOPL = cpustate->IOP1 | (cpustate->IOP2 << 1);
2532         if(!V8086_MODE && (cpustate->CPL <= IOPL))
2533                 return;
2534
2535         if((cpustate->task.limit < 0x67) || ((cpustate->task.flags & 0xd) != 9))
2536                 FAULT_THROW(FAULT_GP,0);
2537
2538         address = cpustate->task.base;
2539         IOPB = READ16PL0( address+0x66);
2540         if((IOPB+(port/8)) > cpustate->task.limit)
2541                 FAULT_THROW(FAULT_GP,0);
2542
2543         map = READ8PL0( address+IOPB+(port/8));
2544         map >>= (port%8);
2545         if(map & mask)
2546                 FAULT_THROW(FAULT_GP,0);
2547 }
2548
2549 INLINE UINT8 I386_OPS_BASE::READPORT8( offs_t port)
2550 {
2551         check_ioperm( port, 1);
2552         return cpustate->io->read_io8(port);
2553 }
2554
2555 INLINE void I386_OPS_BASE::WRITEPORT8( offs_t port, UINT8 value)
2556 {
2557         check_ioperm( port, 1);
2558         cpustate->io->write_io8(port, value);
2559 }
2560
2561 INLINE UINT16 I386_OPS_BASE::READPORT16( offs_t port)
2562 {
2563         if (port & 1)
2564         {
2565                 UINT16 value = READPORT8( port);
2566                 value |= (READPORT8( port + 1) << 8);
2567                 return value;
2568         }
2569         else
2570         {
2571                 check_ioperm( port, 3);
2572                 return cpustate->io->read_io16(port);
2573         }
2574 }
2575
2576 INLINE void I386_OPS_BASE::WRITEPORT16( offs_t port, UINT16 value)
2577 {
2578         if (port & 1)
2579         {
2580                 WRITEPORT8( port, value & 0xff);
2581                 WRITEPORT8( port + 1, (value >> 8) & 0xff);
2582         }
2583         else
2584         {
2585                 check_ioperm( port, 3);
2586                 cpustate->io->write_io16(port, value);
2587         }
2588 }
2589
2590 INLINE UINT32 I386_OPS_BASE::READPORT32( offs_t port)
2591 {
2592         if (port & 3)
2593         {
2594                 UINT32 value = READPORT8( port);
2595                 value |= (READPORT8( port + 1) << 8);
2596                 value |= (READPORT8( port + 2) << 16);
2597                 value |= (READPORT8( port + 3) << 24);
2598                 return value;
2599         }
2600         else
2601         {
2602                 check_ioperm( port, 0xf);
2603                 return cpustate->io->read_io32(port);
2604         }
2605 }
2606
2607 INLINE void I386_OPS_BASE::WRITEPORT32( offs_t port, UINT32 value)
2608 {
2609         if (port & 3)
2610         {
2611                 WRITEPORT8( port, value & 0xff);
2612                 WRITEPORT8( port + 1, (value >> 8) & 0xff);
2613                 WRITEPORT8( port + 2, (value >> 16) & 0xff);
2614                 WRITEPORT8( port + 3, (value >> 24) & 0xff);
2615         }
2616         else
2617         {
2618                 check_ioperm( port, 0xf);
2619                 cpustate->io->write_io32(port, value);
2620         }
2621 }
2622
2623
2624 INLINE UINT64 I386_OPS_BASE::MSR_READ(UINT32 offset,UINT8 *valid_msr)
2625 {
2626         UINT64 res;
2627         UINT8 cpu_type = (cpustate->cpu_version >> 8) & 0x0f;
2628
2629         *valid_msr = 0;
2630
2631         switch(cpu_type)
2632         {
2633         case 5:  // Pentium
2634                 res = pentium_msr_read(offset,valid_msr);
2635                 break;
2636         case 6:  // Pentium Pro, Pentium II, Pentium III
2637                 res = p6_msr_read(offset,valid_msr);
2638                 break;
2639         case 15:  // Pentium 4+
2640                 res = piv_msr_read(offset,valid_msr);
2641                 break;
2642         default:
2643                 res = 0;
2644                 break;
2645         }
2646
2647         return res;
2648 }
2649
2650 INLINE void I386_OPS_BASE::MSR_WRITE(UINT32 offset, UINT64 data, UINT8 *valid_msr)
2651 {
2652         *valid_msr = 0;
2653         UINT8 cpu_type = (cpustate->cpu_version >> 8) & 0x0f;
2654
2655         switch(cpu_type)
2656         {
2657         case 5:  // Pentium
2658                 pentium_msr_write(offset,data,valid_msr);
2659                 break;
2660         case 6:  // Pentium Pro, Pentium II, Pentium III
2661                 p6_msr_write(offset,data,valid_msr);
2662                 break;
2663         case 15:  // Pentium 4+
2664                 piv_msr_write(offset,data,valid_msr);
2665                 break;
2666         }
2667 }
2668
2669 INLINE INT8 I386_OPS_BASE::SaturatedSignedWordToSignedByte(INT16 word)
2670 {
2671         if (word > 127)
2672                 return 127;
2673         if (word < -128)
2674                 return -128;
2675         return (INT8)word;
2676 }
2677
2678 INLINE UINT8 I386_OPS_BASE::SaturatedSignedWordToUnsignedByte(INT16 word)
2679 {
2680         if (word > 255)
2681                 return 255;
2682         if (word < 0)
2683                 return 0;
2684         return (UINT8)word;
2685 }
2686
2687 INLINE INT16 I386_OPS_BASE::SaturatedSignedDwordToSignedWord(INT32 dword)
2688 {
2689         if (dword > 32767)
2690                 return 32767;
2691         if (dword < -32768)
2692                 return -32768;
2693         return (INT16)dword;
2694 }
2695
2696 INLINE UINT16 I386_OPS_BASE::SaturatedSignedDwordToUnsignedWord(INT32 dword)
2697 {
2698         if (dword > 65535)
2699                 return 65535;
2700         if (dword < 0)
2701                 return 0;
2702         return (UINT16)dword;
2703 }
2704
2705 INLINE void I386_OPS_BASE::MMXPROLOG()
2706 {
2707         //cpustate->x87_sw &= ~(X87_SW_TOP_MASK << X87_SW_TOP_SHIFT); // top = 0
2708         cpustate->x87_tw = 0; // tag word = 0
2709 }
2710
2711 INLINE void I386_OPS_BASE::READMMX(UINT32 ea,MMX_REG &r)
2712 {
2713         r.q=READ64( ea);
2714 }
2715
2716 INLINE void I386_OPS_BASE::WRITEMMX(UINT32 ea,MMX_REG &r)
2717 {
2718         WRITE64( ea, r.q);
2719 }
2720
2721 INLINE void I386_OPS_BASE::READXMM(UINT32 ea,XMM_REG &r)
2722 {
2723         r.q[0]=READ64( ea);
2724         r.q[1]=READ64( ea+8);
2725 }
2726
2727 INLINE void I386_OPS_BASE::WRITEXMM(UINT32 ea,XMM_REG &r)
2728 {
2729         WRITE64( ea, r.q[0]);
2730         WRITE64( ea+8, r.q[1]);
2731 }
2732
2733 INLINE void I386_OPS_BASE::READXMM_LO64(UINT32 ea,XMM_REG &r)
2734 {
2735         r.q[0]=READ64( ea);
2736 }
2737
2738 INLINE void I386_OPS_BASE::WRITEXMM_LO64(UINT32 ea,XMM_REG &r)
2739 {
2740         WRITE64( ea, r.q[0]);
2741 }
2742
2743 INLINE void I386_OPS_BASE::READXMM_HI64(UINT32 ea,XMM_REG &r)
2744 {
2745         r.q[1]=READ64( ea);
2746 }
2747
2748 INLINE void I386_OPS_BASE::WRITEXMM_HI64(UINT32 ea,XMM_REG &r)
2749 {
2750         WRITE64( ea, r.q[1]);
2751 }
2752
2753 INLINE flag I386_OPS_BASE::floatx80_is_quiet_nan(floatx80 a)
2754 {
2755         bits64 aLow;
2756
2757         aLow = a.low & ~LIT64(0x4000000000000000);
2758         return
2759                 ((a.high & 0x7FFF) == 0x7FFF)
2760                 && (bits64)(aLow << 1)
2761                 && (a.low != aLow);
2762 }
2763
2764 INLINE int I386_OPS_BASE::floatx80_is_zero(floatx80 fx)
2765 {
2766         return (((fx.high & 0x7fff) == 0) && ((fx.low << 1) == 0));
2767 }
2768
2769 INLINE int I386_OPS_BASE::floatx80_is_inf(floatx80 fx)
2770 {
2771         return (((fx.high & 0x7fff) == 0x7fff) && ((fx.low << 1) == 0));
2772 }
2773
2774 INLINE int I386_OPS_BASE::floatx80_is_denormal(floatx80 fx)
2775 {
2776         return (((fx.high & 0x7fff) == 0) &&
2777                         ((fx.low & U64(0x8000000000000000)) == 0) &&
2778                         ((fx.low << 1) != 0));
2779 }
2780
2781 INLINE floatx80 I386_OPS_BASE::floatx80_abs(floatx80 fx)
2782 {
2783         fx.high &= 0x7fff;
2784         return fx;
2785 }
2786
2787 INLINE double I386_OPS_BASE::fx80_to_double(floatx80 fx)
2788 {
2789         UINT64 d = floatx80_to_float64(fx);
2790         return *(double*)&d;
2791 }
2792
2793 INLINE floatx80 I386_OPS_BASE::double_to_fx80(double in)
2794 {
2795         return float64_to_floatx80(*(UINT64*)&in);
2796 }
2797
2798 INLINE floatx80 I386_OPS_BASE::READ80( UINT32 ea)
2799 {
2800         floatx80 t;
2801
2802         t.low = READ64( ea);
2803         t.high = READ16( ea + 8);
2804
2805         return t;
2806 }
2807
2808 INLINE void I386_OPS_BASE::WRITE80( UINT32 ea, floatx80 t)
2809 {
2810         WRITE64( ea, t.low);
2811         WRITE16( ea + 8, t.high);
2812 }
2813
2814 /*************************************
2815  *
2816  * x87 stack handling
2817  *
2818  *************************************/
2819
2820 INLINE void I386_OPS_BASE::x87_set_stack_top(int top)
2821 {
2822         cpustate->x87_sw &= ~(X87_SW_TOP_MASK << X87_SW_TOP_SHIFT);
2823         cpustate->x87_sw |= (top << X87_SW_TOP_SHIFT);
2824 }
2825
2826 INLINE void I386_OPS_BASE::x87_set_tag(int reg, int tag)
2827 {
2828         int shift = X87_TW_FIELD_SHIFT(reg);
2829
2830         cpustate->x87_tw &= ~(X87_TW_MASK << shift);
2831         cpustate->x87_tw |= (tag << shift);
2832 }
2833
2834 INLINE void I386_OPS_BASE::x87_set_stack_underflow()
2835 {
2836         cpustate->x87_sw &= ~X87_SW_C1;
2837         cpustate->x87_sw |= X87_SW_IE | X87_SW_SF;
2838 }
2839
2840 INLINE void I386_OPS_BASE::x87_set_stack_overflow()
2841 {
2842         cpustate->x87_sw |= X87_SW_C1 | X87_SW_IE | X87_SW_SF;
2843 }
2844
2845 INLINE void I386_OPS_BASE::x87_write_cw( UINT16 cw)
2846 {
2847         cpustate->x87_cw = cw;
2848
2849         /* Update the SoftFloat rounding mode */
2850         float_rounding_mode = x87_to_sf_rc[(cpustate->x87_cw >> X87_CW_RC_SHIFT) & X87_CW_RC_MASK];
2851 }
2852
2853 #endif