+++ /dev/null
-// license:BSD-3-Clause
-// copyright-holders:Ville Linde, Barry Rodewald, Carl, Phil Bennett
-
-#pragma once
-
-#ifndef __LIB_I386_CYCLES_H__
-#define __LIB_I386_CYCLES_H__
-
-enum X86_CYCLES
-{
- CYCLES_MOV_REG_REG,
- CYCLES_MOV_REG_MEM,
- CYCLES_MOV_MEM_REG,
- CYCLES_MOV_IMM_REG,
- CYCLES_MOV_IMM_MEM,
- CYCLES_MOV_ACC_MEM,
- CYCLES_MOV_MEM_ACC,
- CYCLES_MOV_REG_SREG,
- CYCLES_MOV_MEM_SREG,
- CYCLES_MOV_SREG_REG,
- CYCLES_MOV_SREG_MEM,
- CYCLES_MOVSX_REG_REG,
- CYCLES_MOVSX_MEM_REG,
- CYCLES_MOVZX_REG_REG,
- CYCLES_MOVZX_MEM_REG,
- CYCLES_PUSH_RM,
- CYCLES_PUSH_REG_SHORT,
- CYCLES_PUSH_SREG,
- CYCLES_PUSH_IMM,
- CYCLES_PUSHA,
- CYCLES_POP_RM,
- CYCLES_POP_REG_SHORT,
- CYCLES_POP_SREG,
- CYCLES_POPA,
- CYCLES_XCHG_REG_REG,
- CYCLES_XCHG_REG_MEM,
- CYCLES_IN,
- CYCLES_IN_VAR,
- CYCLES_OUT,
- CYCLES_OUT_VAR,
- CYCLES_LEA,
- CYCLES_LDS,
- CYCLES_LES,
- CYCLES_LFS,
- CYCLES_LGS,
- CYCLES_LSS,
- CYCLES_CLC,
- CYCLES_CLD,
- CYCLES_CLI,
- CYCLES_CLTS,
- CYCLES_CMC,
- CYCLES_LAHF,
- CYCLES_POPF,
- CYCLES_PUSHF,
- CYCLES_SAHF,
- CYCLES_STC,
- CYCLES_STD,
- CYCLES_STI,
- CYCLES_ALU_REG_REG,
- CYCLES_ALU_REG_MEM,
- CYCLES_ALU_MEM_REG,
- CYCLES_ALU_IMM_REG,
- CYCLES_ALU_IMM_MEM,
- CYCLES_ALU_IMM_ACC,
- CYCLES_INC_REG,
- CYCLES_INC_MEM,
- CYCLES_DEC_REG,
- CYCLES_DEC_MEM,
- CYCLES_CMP_REG_REG,
- CYCLES_CMP_REG_MEM,
- CYCLES_CMP_MEM_REG,
- CYCLES_CMP_IMM_REG,
- CYCLES_CMP_IMM_MEM,
- CYCLES_CMP_IMM_ACC,
- CYCLES_TEST_REG_REG,
- CYCLES_TEST_REG_MEM,
- CYCLES_TEST_IMM_REG,
- CYCLES_TEST_IMM_MEM,
- CYCLES_TEST_IMM_ACC,
- CYCLES_NEG_REG,
- CYCLES_NEG_MEM,
- CYCLES_AAA,
- CYCLES_AAS,
- CYCLES_DAA,
- CYCLES_DAS,
- CYCLES_MUL8_ACC_REG,
- CYCLES_MUL8_ACC_MEM,
- CYCLES_MUL16_ACC_REG,
- CYCLES_MUL16_ACC_MEM,
- CYCLES_MUL32_ACC_REG,
- CYCLES_MUL32_ACC_MEM,
- CYCLES_IMUL8_ACC_REG,
- CYCLES_IMUL8_ACC_MEM,
- CYCLES_IMUL16_ACC_REG,
- CYCLES_IMUL16_ACC_MEM,
- CYCLES_IMUL32_ACC_REG,
- CYCLES_IMUL32_ACC_MEM,
- CYCLES_IMUL8_REG_REG,
- CYCLES_IMUL8_REG_MEM,
- CYCLES_IMUL16_REG_REG,
- CYCLES_IMUL16_REG_MEM,
- CYCLES_IMUL32_REG_REG,
- CYCLES_IMUL32_REG_MEM,
- CYCLES_IMUL16_REG_IMM_REG,
- CYCLES_IMUL16_MEM_IMM_REG,
- CYCLES_IMUL32_REG_IMM_REG,
- CYCLES_IMUL32_MEM_IMM_REG,
- CYCLES_DIV8_ACC_REG,
- CYCLES_DIV8_ACC_MEM,
- CYCLES_DIV16_ACC_REG,
- CYCLES_DIV16_ACC_MEM,
- CYCLES_DIV32_ACC_REG,
- CYCLES_DIV32_ACC_MEM,
- CYCLES_IDIV8_ACC_REG,
- CYCLES_IDIV8_ACC_MEM,
- CYCLES_IDIV16_ACC_REG,
- CYCLES_IDIV16_ACC_MEM,
- CYCLES_IDIV32_ACC_REG,
- CYCLES_IDIV32_ACC_MEM,
- CYCLES_AAD,
- CYCLES_AAM,
- CYCLES_CBW,
- CYCLES_CWD,
- CYCLES_ROTATE_REG,
- CYCLES_ROTATE_MEM,
- CYCLES_ROTATE_CARRY_REG,
- CYCLES_ROTATE_CARRY_MEM,
- CYCLES_SHLD_REG,
- CYCLES_SHLD_MEM,
- CYCLES_SHRD_REG,
- CYCLES_SHRD_MEM,
- CYCLES_NOT_REG,
- CYCLES_NOT_MEM,
- CYCLES_CMPS,
- CYCLES_INS,
- CYCLES_LODS,
- CYCLES_MOVS,
- CYCLES_OUTS,
- CYCLES_SCAS,
- CYCLES_STOS,
- CYCLES_XLAT,
- CYCLES_REP_CMPS_BASE,
- CYCLES_REP_INS_BASE,
- CYCLES_REP_LODS_BASE,
- CYCLES_REP_MOVS_BASE,
- CYCLES_REP_OUTS_BASE,
- CYCLES_REP_SCAS_BASE,
- CYCLES_REP_STOS_BASE,
- CYCLES_REP_CMPS,
- CYCLES_REP_INS,
- CYCLES_REP_LODS,
- CYCLES_REP_MOVS,
- CYCLES_REP_OUTS,
- CYCLES_REP_SCAS,
- CYCLES_REP_STOS,
- CYCLES_BSF_BASE,
- CYCLES_BSF,
- CYCLES_BSR_BASE,
- CYCLES_BSR,
- CYCLES_BT_IMM_REG,
- CYCLES_BT_IMM_MEM,
- CYCLES_BT_REG_REG,
- CYCLES_BT_REG_MEM,
- CYCLES_BTC_IMM_REG,
- CYCLES_BTC_IMM_MEM,
- CYCLES_BTC_REG_REG,
- CYCLES_BTC_REG_MEM,
- CYCLES_BTR_IMM_REG,
- CYCLES_BTR_IMM_MEM,
- CYCLES_BTR_REG_REG,
- CYCLES_BTR_REG_MEM,
- CYCLES_BTS_IMM_REG,
- CYCLES_BTS_IMM_MEM,
- CYCLES_BTS_REG_REG,
- CYCLES_BTS_REG_MEM,
- CYCLES_CALL, // E8
- CYCLES_CALL_REG, // FF /2
- CYCLES_CALL_MEM, // FF /2
- CYCLES_CALL_INTERSEG, // 9A
- CYCLES_CALL_REG_INTERSEG, // FF /3
- CYCLES_CALL_MEM_INTERSEG, // FF /3
- CYCLES_JMP_SHORT, // EB
- CYCLES_JMP, // E9
- CYCLES_JMP_REG, // FF /4
- CYCLES_JMP_MEM, // FF /4
- CYCLES_JMP_INTERSEG, // EA
- CYCLES_JMP_REG_INTERSEG, // FF /5
- CYCLES_JMP_MEM_INTERSEG, // FF /5
- CYCLES_RET, // C3
- CYCLES_RET_IMM, // C2
- CYCLES_RET_INTERSEG, // CB
- CYCLES_RET_IMM_INTERSEG, // CA
- CYCLES_JCC_DISP8,
- CYCLES_JCC_FULL_DISP,
- CYCLES_JCC_DISP8_NOBRANCH,
- CYCLES_JCC_FULL_DISP_NOBRANCH,
- CYCLES_JCXZ,
- CYCLES_JCXZ_NOBRANCH,
- CYCLES_LOOP,
- CYCLES_LOOPZ,
- CYCLES_LOOPNZ,
- CYCLES_SETCC_REG,
- CYCLES_SETCC_MEM,
- CYCLES_ENTER,
- CYCLES_LEAVE,
- CYCLES_INT,
- CYCLES_INT3,
- CYCLES_INTO_OF1,
- CYCLES_INTO_OF0,
- CYCLES_BOUND_IN_RANGE,
- CYCLES_BOUND_OUT_RANGE,
- CYCLES_IRET,
- CYCLES_HLT,
- CYCLES_MOV_REG_CR0,
- CYCLES_MOV_REG_CR2,
- CYCLES_MOV_REG_CR3,
- CYCLES_MOV_CR_REG,
- CYCLES_MOV_REG_DR0_3,
- CYCLES_MOV_REG_DR6_7,
- CYCLES_MOV_DR6_7_REG,
- CYCLES_MOV_DR0_3_REG,
- CYCLES_MOV_REG_TR6_7,
- CYCLES_MOV_TR6_7_REG,
- CYCLES_NOP,
- CYCLES_WAIT,
- CYCLES_ARPL_REG,
- CYCLES_ARPL_MEM,
- CYCLES_LAR_REG,
- CYCLES_LAR_MEM,
- CYCLES_LGDT,
- CYCLES_LIDT,
- CYCLES_LLDT_REG,
- CYCLES_LLDT_MEM,
- CYCLES_LMSW_REG,
- CYCLES_LMSW_MEM,
- CYCLES_LSL_REG,
- CYCLES_LSL_MEM,
- CYCLES_LTR_REG,
- CYCLES_LTR_MEM,
- CYCLES_SGDT,
- CYCLES_SIDT,
- CYCLES_SLDT_REG,
- CYCLES_SLDT_MEM,
- CYCLES_SMSW_REG,
- CYCLES_SMSW_MEM,
- CYCLES_STR_REG,
- CYCLES_STR_MEM,
- CYCLES_VERR_REG,
- CYCLES_VERR_MEM,
- CYCLES_VERW_REG,
- CYCLES_VERW_MEM,
- CYCLES_LOCK,
-
- CYCLES_BSWAP,
- CYCLES_CMPXCHG8B,
- CYCLES_CMPXCHG,
- CYCLES_CPUID,
- CYCLES_CPUID_EAX1,
- CYCLES_INVD,
- CYCLES_XADD,
- CYCLES_RDTSC,
- CYCLES_RSM,
- CYCLES_RDMSR,
-
- CYCLES_FABS,
- CYCLES_FADD,
- CYCLES_FBLD,
- CYCLES_FBSTP,
- CYCLES_FCHS,
- CYCLES_FCLEX,
- CYCLES_FCOM,
- CYCLES_FCOS,
- CYCLES_FDECSTP,
- CYCLES_FDISI,
- CYCLES_FDIV,
- CYCLES_FDIVR,
- CYCLES_FENI,
- CYCLES_FFREE,
- CYCLES_FIADD,
- CYCLES_FICOM,
- CYCLES_FIDIV,
- CYCLES_FILD,
- CYCLES_FIMUL,
- CYCLES_FINCSTP,
- CYCLES_FINIT,
- CYCLES_FIST,
- CYCLES_FISUB,
- CYCLES_FLD,
- CYCLES_FLDZ,
- CYCLES_FLD1,
- CYCLES_FLDL2E,
- CYCLES_FLDL2T,
- CYCLES_FLDLG2,
- CYCLES_FLDLN2,
- CYCLES_FLDPI,
- CYCLES_FLDCW,
- CYCLES_FLDENV,
- CYCLES_FMUL,
- CYCLES_FNOP,
- CYCLES_FPATAN,
- CYCLES_FPREM,
- CYCLES_FPREM1,
- CYCLES_FPTAN,
- CYCLES_FRNDINT,
- CYCLES_FRSTOR,
- CYCLES_FSAVE,
- CYCLES_FSCALE,
- CYCLES_FSETPM,
- CYCLES_FSIN,
- CYCLES_FSINCOS,
- CYCLES_FSQRT,
- CYCLES_FST,
- CYCLES_FSTCW,
- CYCLES_FSTENV,
- CYCLES_FSTSW,
- CYCLES_FSUB,
- CYCLES_FSUBR,
- CYCLES_FTST,
- CYCLES_FUCOM,
- CYCLES_FXAM,
- CYCLES_FXCH,
- CYCLES_FXTRACT,
- CYCLES_FYL2X,
- CYCLES_FYL2XPI,
- CYCLES_CMPXCHG_REG_REG_T,
- CYCLES_CMPXCHG_REG_REG_F,
- CYCLES_CMPXCHG_REG_MEM_T,
- CYCLES_CMPXCHG_REG_MEM_F,
- CYCLES_XADD_REG_REG,
- CYCLES_XADD_REG_MEM,
-
- CYCLES_NUM_OPCODES
-};
-
-
-#define X86_NUM_CPUS 4
-#define CPU_CYCLES_I386 0
-#define CPU_CYCLES_I486 1
-#define CPU_CYCLES_PENTIUM 2
-#define CPU_CYCLES_MEDIAGX 3
-
-
-struct X86_CYCLE_TABLE
-{
- X86_CYCLES op;
- UINT8 cpu_cycles[X86_NUM_CPUS][2];
-};
-
-const I386_OPS_BASE::X86_CYCLE_TABLE x86_cycle_table[] =
-{
- // opcode rm/pmode
- // i386 i486 pentium mediagx
- { CYCLES_MOV_REG_REG, { { 2, 2 }, { 1, 1 }, { 1, 1 }, { 1, 1 } } },
- { CYCLES_MOV_REG_MEM, { { 2, 2 }, { 1, 1 }, { 1, 1 }, { 1, 1 } } },
- { CYCLES_MOV_MEM_REG, { { 4, 4 }, { 1, 1 }, { 1, 1 }, { 1, 1 } } },
- { CYCLES_MOV_IMM_REG, { { 2, 2 }, { 1, 1 }, { 1, 1 }, { 1, 1 } } },
- { CYCLES_MOV_IMM_MEM, { { 2, 2 }, { 1, 1 }, { 1, 1 }, { 1, 1 } } },
- { CYCLES_MOV_ACC_MEM, { { 2, 2 }, { 1, 1 }, { 1, 1 }, { 1, 1 } } },
- { CYCLES_MOV_MEM_ACC, { { 4, 4 }, { 1, 1 }, { 1, 1 }, { 1, 1 } } },
- { CYCLES_MOV_REG_SREG, { { 2, 18 }, { 3, 3 }, { 2, 2 }, { 1, 6 } } },
- { CYCLES_MOV_MEM_SREG, { { 5, 19 }, { 9, 9 }, { 3, 3 }, { 1, 6 } } },
- { CYCLES_MOV_SREG_REG, { { 2, 2 }, { 3, 3 }, { 1, 1 }, { 1, 6 } } },
- { CYCLES_MOV_SREG_MEM, { { 2, 2 }, { 3, 3 }, { 1, 1 }, { 1, 6 } } },
- { CYCLES_MOVSX_REG_REG, { { 3, 3 }, { 3, 3 }, { 3, 3 }, { 1, 1 } } },
- { CYCLES_MOVSX_MEM_REG, { { 6, 6 }, { 3, 3 }, { 3, 3 }, { 1, 1 } } },
- { CYCLES_MOVZX_REG_REG, { { 3, 3 }, { 3, 3 }, { 3, 3 }, { 1, 1 } } },
- { CYCLES_MOVZX_MEM_REG, { { 6, 6 }, { 3, 3 }, { 3, 3 }, { 1, 1 } } },
- { CYCLES_PUSH_RM, { { 5, 5 }, { 4, 4 }, { 2, 2 }, { 3, 3 } } },
- { CYCLES_PUSH_REG_SHORT, { { 2, 2 }, { 1, 1 }, { 1, 1 }, { 1, 1 } } },
- { CYCLES_PUSH_SREG, { { 2, 2 }, { 3, 3 }, { 1, 1 }, { 1, 1 } } },
- { CYCLES_PUSH_IMM, { { 2, 2 }, { 1, 1 }, { 1, 1 }, { 1, 1 } } },
- { CYCLES_PUSHA, { { 18, 18 }, { 11, 11 }, { 5, 5 }, { 11, 11 } } },
- { CYCLES_POP_RM, { { 5, 5 }, { 4, 4 }, { 3, 3 }, { 4, 4 } } },
- { CYCLES_POP_REG_SHORT, { { 4, 4 }, { 4, 4 }, { 1, 1 }, { 1, 1 } } },
- { CYCLES_POP_SREG, { { 7, 21 }, { 3, 3 }, { 3, 3 }, { 1, 6 } } },
- { CYCLES_POPA, { { 24, 24 }, { 9, 9 }, { 5, 5 }, { 9, 9 } } },
- { CYCLES_XCHG_REG_REG, { { 3, 3 }, { 3, 3 }, { 3, 3 }, { 1, 1 } } },
- { CYCLES_XCHG_REG_MEM, { { 5, 5 }, { 5, 5 }, { 3, 3 }, { 1, 1 } } },
- { CYCLES_IN, { { 12, 26 }, { 14, 27 }, { 7, 19 }, { 8, 8 } } },
- { CYCLES_IN_VAR, { { 13, 27 }, { 14, 27 }, { 7, 19 }, { 8, 8 } } },
- { CYCLES_OUT, { { 10, 24 }, { 16, 29 }, { 12, 24 }, { 14, 14 } } },
- { CYCLES_OUT_VAR, { { 11, 25 }, { 16, 29 }, { 12, 24 }, { 14, 14 } } },
- { CYCLES_LEA, { { 2, 2 }, { 1, 1 }, { 1, 1 }, { 1, 1 } } },
- { CYCLES_LDS, { { 7, 22 }, { 6, 12 }, { 4, 4 }, { 4, 9 } } },
- { CYCLES_LES, { { 7, 22 }, { 6, 12 }, { 4, 4 }, { 4, 9 } } },
- { CYCLES_LFS, { { 7, 22 }, { 6, 12 }, { 4, 4 }, { 4, 9 } } },
- { CYCLES_LGS, { { 7, 22 }, { 6, 12 }, { 4, 4 }, { 4, 9 } } },
- { CYCLES_LSS, { { 7, 22 }, { 6, 12 }, { 4, 4 }, { 4, 10 } } },
- { CYCLES_CLC, { { 2, 2 }, { 2, 2 }, { 2, 2 }, { 1, 1 } } },
- { CYCLES_CLD, { { 2, 2 }, { 2, 2 }, { 2, 2 }, { 4, 4 } } },
- { CYCLES_CLI, { { 8, 8 }, { 5, 5 }, { 7, 7 }, { 6, 6 } } },
- { CYCLES_CLTS, { { 6, 6 }, { 7, 7 }, { 10, 10 }, { 7, 7 } } },
- { CYCLES_CMC, { { 2, 2 }, { 2, 2 }, { 2, 2 }, { 3, 3 } } },
- { CYCLES_LAHF, { { 2, 2 }, { 3, 3 }, { 2, 2 }, { 2, 2 } } },
- { CYCLES_POPF, { { 5, 5 }, { 9, 9 }, { 6, 6 }, { 8, 8 } } },
- { CYCLES_PUSHF, { { 4, 4 }, { 4, 4 }, { 9, 9 }, { 2, 2 } } },
- { CYCLES_SAHF, { { 3, 3 }, { 2, 2 }, { 2, 2 }, { 1, 1 } } },
- { CYCLES_STC, { { 2, 2 }, { 2, 2 }, { 2, 2 }, { 1, 1 } } },
- { CYCLES_STD, { { 2, 2 }, { 2, 2 }, { 2, 2 }, { 4, 4 } } },
- { CYCLES_STI, { { 8, 8 }, { 5, 5 }, { 7, 7 }, { 6, 6 } } },
- { CYCLES_ALU_REG_REG, { { 2, 2 }, { 1, 1 }, { 1, 1 }, { 1, 1 } } },
- { CYCLES_ALU_REG_MEM, { { 7, 7 }, { 3, 3 }, { 3, 3 }, { 1, 1 } } },
- { CYCLES_ALU_MEM_REG, { { 6, 6 }, { 2, 2 }, { 2, 2 }, { 1, 1 } } },
- { CYCLES_ALU_IMM_REG, { { 2, 2 }, { 1, 1 }, { 1, 1 }, { 1, 1 } } },
- { CYCLES_ALU_IMM_MEM, { { 7, 7 }, { 3, 3 }, { 3, 3 }, { 1, 1 } } },
- { CYCLES_ALU_IMM_ACC, { { 2, 2 }, { 1, 1 }, { 1, 1 }, { 1, 1 } } },
- { CYCLES_INC_REG, { { 2, 2 }, { 1, 1 }, { 1, 1 }, { 1, 1 } } },
- { CYCLES_INC_MEM, { { 6, 6 }, { 3, 3 }, { 3, 3 }, { 1, 1 } } },
- { CYCLES_DEC_REG, { { 2, 2 }, { 1, 1 }, { 1, 1 }, { 1, 1 } } },
- { CYCLES_DEC_MEM, { { 6, 6 }, { 3, 3 }, { 3, 3 }, { 1, 1 } } },
- { CYCLES_CMP_REG_REG, { { 2, 2 }, { 1, 1 }, { 1, 1 }, { 1, 1 } } },
- { CYCLES_CMP_REG_MEM, { { 5, 5 }, { 2, 2 }, { 2, 2 }, { 1, 1 } } },
- { CYCLES_CMP_MEM_REG, { { 6, 6 }, { 2, 2 }, { 2, 2 }, { 1, 1 } } },
- { CYCLES_CMP_IMM_REG, { { 2, 2 }, { 1, 1 }, { 1, 1 }, { 1, 1 } } },
- { CYCLES_CMP_IMM_MEM, { { 5, 5 }, { 2, 2 }, { 2, 2 }, { 1, 1 } } },
- { CYCLES_CMP_IMM_ACC, { { 2, 2 }, { 1, 1 }, { 1, 1 }, { 1, 1 } } },
- { CYCLES_TEST_REG_REG, { { 2, 2 }, { 1, 1 }, { 1, 1 }, { 1, 1 } } },
- { CYCLES_TEST_REG_MEM, { { 5, 5 }, { 2, 2 }, { 2, 2 }, { 1, 1 } } },
- { CYCLES_TEST_IMM_REG, { { 2, 2 }, { 1, 1 }, { 1, 1 }, { 1, 1 } } },
- { CYCLES_TEST_IMM_MEM, { { 5, 5 }, { 2, 2 }, { 2, 2 }, { 1, 1 } } },
- { CYCLES_TEST_IMM_ACC, { { 2, 2 }, { 1, 1 }, { 1, 1 }, { 1, 1 } } },
- { CYCLES_NEG_REG, { { 2, 2 }, { 1, 1 }, { 1, 1 }, { 1, 1 } } },
- { CYCLES_NEG_MEM, { { 6, 6 }, { 3, 3 }, { 3, 3 }, { 1, 1 } } },
- { CYCLES_AAA, { { 4, 4 }, { 3, 3 }, { 3, 3 }, { 3, 3 } } },
- { CYCLES_AAS, { { 4, 4 }, { 3, 3 }, { 3, 3 }, { 3, 3 } } },
- { CYCLES_DAA, { { 4, 4 }, { 2, 2 }, { 3, 3 }, { 2, 2 } } },
- { CYCLES_DAS, { { 4, 4 }, { 2, 2 }, { 3, 3 }, { 2, 2 } } },
- { CYCLES_MUL8_ACC_REG, { { 17, 17 }, { 13, 13 }, { 11, 11 }, { 4, 4 } } },
- { CYCLES_MUL8_ACC_MEM, { { 20, 20 }, { 13, 13 }, { 11, 11 }, { 4, 4 } } },
- { CYCLES_MUL16_ACC_REG, { { 25, 25 }, { 13, 13 }, { 11, 11 }, { 5, 5 } } },
- { CYCLES_MUL16_ACC_MEM, { { 28, 28 }, { 13, 13 }, { 11, 11 }, { 5, 5 } } },
- { CYCLES_MUL32_ACC_REG, { { 41, 41 }, { 13, 13 }, { 10, 10 }, { 15, 15 } } },
- { CYCLES_MUL32_ACC_MEM, { { 44, 44 }, { 13, 13 }, { 10, 10 }, { 15, 15 } } },
- { CYCLES_IMUL8_ACC_REG, { { 17, 17 }, { 18, 18 }, { 11, 11 }, { 4, 4 } } },
- { CYCLES_IMUL8_ACC_MEM, { { 20, 20 }, { 18, 18 }, { 11, 11 }, { 4, 4 } } },
- { CYCLES_IMUL16_ACC_REG, { { 25, 25 }, { 26, 26 }, { 11, 11 }, { 5, 5 } } },
- { CYCLES_IMUL16_ACC_MEM, { { 28, 28 }, { 26, 26 }, { 11, 11 }, { 5, 5 } } },
- { CYCLES_IMUL32_ACC_REG, { { 41, 41 }, { 42, 42 }, { 10, 10 }, { 15, 15 } } },
- { CYCLES_IMUL32_ACC_MEM, { { 44, 44 }, { 42, 42 }, { 10, 10 }, { 15, 15 } } },
- { CYCLES_IMUL8_REG_REG, { { 17, 17 }, { 13, 13 }, { 10, 10 }, { 4, 4 } } },
- { CYCLES_IMUL8_REG_MEM, { { 20, 20 }, { 13, 13 }, { 10, 10 }, { 4, 4 } } },
- { CYCLES_IMUL16_REG_REG, { { 25, 25 }, { 13, 13 }, { 10, 10 }, { 5, 5 } } },
- { CYCLES_IMUL16_REG_MEM, { { 28, 28 }, { 13, 13 }, { 10, 10 }, { 5, 5 } } },
- { CYCLES_IMUL32_REG_REG, { { 41, 41 }, { 13, 13 }, { 10, 10 }, { 15, 15 } } },
- { CYCLES_IMUL32_REG_MEM, { { 44, 44 }, { 13, 13 }, { 10, 10 }, { 15, 15 } } },
- { CYCLES_IMUL16_REG_IMM_REG,{ { 26, 26 }, { 26, 26 }, { 10, 10 }, { 6, 6 } } },
- { CYCLES_IMUL16_MEM_IMM_REG,{ { 27, 27 }, { 26, 26 }, { 10, 10 }, { 6, 6 } } },
- { CYCLES_IMUL32_REG_IMM_REG,{ { 42, 42 }, { 42, 42 }, { 10, 10 }, { 16, 16 } } },
- { CYCLES_IMUL32_MEM_IMM_REG,{ { 43, 43 }, { 42, 42 }, { 10, 10 }, { 16, 16 } } },
- { CYCLES_DIV8_ACC_REG, { { 14, 14 }, { 16, 16 }, { 17, 17 }, { 20, 20 } } },
- { CYCLES_DIV8_ACC_MEM, { { 17, 17 }, { 16, 16 }, { 17, 17 }, { 20, 20 } } },
- { CYCLES_DIV16_ACC_REG, { { 22, 22 }, { 24, 24 }, { 25, 25 }, { 29, 29 } } },
- { CYCLES_DIV16_ACC_MEM, { { 25, 25 }, { 24, 24 }, { 25, 25 }, { 29, 29 } } },
- { CYCLES_DIV32_ACC_REG, { { 38, 38 }, { 40, 40 }, { 41, 41 }, { 45, 45 } } },
- { CYCLES_DIV32_ACC_MEM, { { 41, 41 }, { 40, 40 }, { 41, 41 }, { 45, 45 } } },
- { CYCLES_IDIV8_ACC_REG, { { 19, 19 }, { 19, 19 }, { 22, 22 }, { 20, 20 } } },
- { CYCLES_IDIV8_ACC_MEM, { { 22, 22 }, { 20, 20 }, { 22, 22 }, { 20, 20 } } },
- { CYCLES_IDIV16_ACC_REG, { { 27, 27 }, { 27, 27 }, { 30, 30 }, { 29, 29 } } },
- { CYCLES_IDIV16_ACC_MEM, { { 30, 30 }, { 28, 28 }, { 30, 30 }, { 29, 29 } } },
- { CYCLES_IDIV32_ACC_REG, { { 43, 43 }, { 43, 43 }, { 46, 46 }, { 45, 45 } } },
- { CYCLES_IDIV32_ACC_MEM, { { 46, 46 }, { 44, 44 }, { 46, 46 }, { 45, 45 } } },
- { CYCLES_AAD, { { 19, 19 }, { 14, 14 }, { 10, 10 }, { 7, 7 } } },
- { CYCLES_AAM, { { 17, 17 }, { 15, 15 }, { 18, 18 }, { 19, 19 } } },
- { CYCLES_CBW, { { 3, 3 }, { 3, 3 }, { 3, 3 }, { 3, 3 } } },
- { CYCLES_CWD, { { 2, 2 }, { 3, 3 }, { 2, 2 }, { 2, 2 } } },
- { CYCLES_ROTATE_REG, { { 3, 3 }, { 3, 3 }, { 1, 1 }, { 2, 2 } } },
- { CYCLES_ROTATE_MEM, { { 7, 7 }, { 4, 4 }, { 3, 3 }, { 2, 2 } } },
- { CYCLES_ROTATE_CARRY_REG, { { 9, 9 }, { 8, 8 }, { 7, 7 }, { 8, 8 } } },
- { CYCLES_ROTATE_CARRY_MEM, { { 10, 10 }, { 9, 9 }, { 8, 8 }, { 8, 8 } } },
- { CYCLES_SHLD_REG, { { 3, 3 }, { 2, 2 }, { 4, 4 }, { 3, 3 } } },
- { CYCLES_SHLD_MEM, { { 7, 7 }, { 3, 3 }, { 4, 4 }, { 6, 6 } } },
- { CYCLES_SHRD_REG, { { 3, 3 }, { 2, 2 }, { 4, 4 }, { 3, 3 } } },
- { CYCLES_SHRD_MEM, { { 7, 7 }, { 3, 3 }, { 4, 4 }, { 6, 6 } } },
- { CYCLES_NOT_REG, { { 2, 2 }, { 1, 1 }, { 1, 1 }, { 1, 1 } } },
- { CYCLES_NOT_MEM, { { 6, 6 }, { 3, 3 }, { 3, 3 }, { 1, 1 } } },
- { CYCLES_CMPS, { { 10, 10 }, { 8, 8 }, { 5, 5 }, { 6, 6 } } },
- { CYCLES_INS, { { 15, 29 }, { 17, 30 }, { 9, 22 }, { 11, 11 } } },
- { CYCLES_LODS, { { 5, 5 }, { 5, 5 }, { 2, 2 }, { 3, 3 } } },
- { CYCLES_MOVS, { { 8, 8 }, { 7, 7 }, { 4, 4 }, { 6, 6 } } },
- { CYCLES_OUTS, { { 14, 28 }, { 17, 30 }, { 13, 25 }, { 15, 15 } } },
- { CYCLES_SCAS, { { 8, 8 }, { 6, 6 }, { 4, 4 }, { 2, 2 } } },
- { CYCLES_STOS, { { 5, 5 }, { 5, 5 }, { 3, 3 }, { 2, 2 } } },
- { CYCLES_XLAT, { { 5, 5 }, { 4, 4 }, { 4, 4 }, { 5, 5 } } },
- { CYCLES_REP_CMPS_BASE, { { 5, 5 }, { 0, 0 }, { 0, 0 }, { 11, 11 } } },
- { CYCLES_REP_INS_BASE, { { 14, 8 }, { 0, 0 }, { 0, 0 }, { 17, 17 } } },
- { CYCLES_REP_LODS_BASE, { { 5, 5 }, { 0, 0 }, { 0, 0 }, { 9, 9 } } },
- { CYCLES_REP_MOVS_BASE, { { 8, 8 }, { 0, 0 }, { 0, 0 }, { 12, 12 } } },
- { CYCLES_REP_OUTS_BASE, { { 12, 6 }, { 0, 0 }, { 0, 0 }, { 24, 24 } } },
- { CYCLES_REP_SCAS_BASE, { { 5, 5 }, { 0, 0 }, { 0, 0 }, { 9, 9 } } },
- { CYCLES_REP_STOS_BASE, { { 5, 5 }, { 0, 0 }, { 0, 0 }, { 9, 9 } } },
- { CYCLES_REP_CMPS, { { 5, 5 }, { 8, 8 }, { 5, 5 }, { 4, 4 } } },
- { CYCLES_REP_INS, { { 14, 8 }, { 17, 30 }, { 9, 22 }, { 4, 4 } } },
- { CYCLES_REP_LODS, { { 5, 5 }, { 5, 5 }, { 2, 2 }, { 2, 2 } } },
- { CYCLES_REP_MOVS, { { 8, 8 }, { 7, 7 }, { 4, 4 }, { 2, 2 } } },
- { CYCLES_REP_OUTS, { { 12, 6 }, { 17, 30 }, { 13, 25 }, { 4, 4 } } },
- { CYCLES_REP_SCAS, { { 5, 5 }, { 6, 6 }, { 4, 4 }, { 3, 3 } } },
- { CYCLES_REP_STOS, { { 5, 5 }, { 5, 5 }, { 3, 3 }, { 2, 2 } } },
- { CYCLES_BSF_BASE, { { 11, 11 }, { 6, 6 }, { 6, 6 }, { 4, 4 } } },
- { CYCLES_BSF, { { 3, 3 }, { 1, 1 }, { 1, 1 }, { 1, 1 } } },
- { CYCLES_BSR_BASE, { { 9, 9 }, { 6, 6 }, { 7, 7 }, { 4, 4 } } },
- { CYCLES_BSR, { { 3, 3 }, { 1, 1 }, { 1, 1 }, { 1, 1 } } },
- { CYCLES_BT_IMM_REG, { { 3, 3 }, { 3, 3 }, { 4, 4 }, { 1, 1 } } },
- { CYCLES_BT_IMM_MEM, { { 6, 6 }, { 6, 6 }, { 4, 4 }, { 1, 1 } } },
- { CYCLES_BT_REG_REG, { { 3, 3 }, { 3, 3 }, { 4, 4 }, { 1, 1 } } },
- { CYCLES_BT_REG_MEM, { { 12, 12 }, { 12, 12 }, { 9, 9 }, { 7, 7 } } },
- { CYCLES_BTC_IMM_REG, { { 6, 6 }, { 6, 6 }, { 7, 7 }, { 2, 2 } } },
- { CYCLES_BTC_IMM_MEM, { { 8, 8 }, { 8, 8 }, { 8, 8 }, { 2, 2 } } },
- { CYCLES_BTC_REG_REG, { { 6, 6 }, { 6, 6 }, { 7, 7 }, { 2, 2 } } },
- { CYCLES_BTC_REG_MEM, { { 13, 13 }, { 13, 13 }, { 13, 13 }, { 8, 8 } } },
- { CYCLES_BTR_IMM_REG, { { 6, 6 }, { 6, 6 }, { 7, 7 }, { 2, 2 } } },
- { CYCLES_BTR_IMM_MEM, { { 8, 8 }, { 8, 8 }, { 8, 8 }, { 2, 2 } } },
- { CYCLES_BTR_REG_REG, { { 6, 6 }, { 6, 6 }, { 7, 7 }, { 2, 2 } } },
- { CYCLES_BTR_REG_MEM, { { 13, 13 }, { 13, 13 }, { 13, 13 }, { 8, 8 } } },
- { CYCLES_BTS_IMM_REG, { { 6, 6 }, { 6, 6 }, { 7, 7 }, { 2, 2 } } },
- { CYCLES_BTS_IMM_MEM, { { 8, 8 }, { 8, 8 }, { 8, 8 }, { 2, 2 } } },
- { CYCLES_BTS_REG_REG, { { 6, 6 }, { 6, 6 }, { 7, 7 }, { 2, 2 } } },
- { CYCLES_BTS_REG_MEM, { { 13, 13 }, { 13, 13 }, { 13, 13 }, { 8, 8 } } },
- { CYCLES_CALL, { { 7, 7 }, { 3, 3 }, { 1, 1 }, { 3, 3 } } },
- { CYCLES_CALL_REG, { { 7, 7 }, { 5, 5 }, { 2, 2 }, { 3, 3 } } },
- { CYCLES_CALL_MEM, { { 10, 10 }, { 5, 5 }, { 2, 2 }, { 4, 4 } } },
- { CYCLES_CALL_INTERSEG, { { 17, 34 }, { 18, 20 }, { 4, 13 }, { 9, 14 } } },
- { CYCLES_CALL_REG_INTERSEG, { { 22, 38 }, { 17, 20 }, { 4, 14 }, { 11, 15 } } },
- { CYCLES_CALL_MEM_INTERSEG, { { 22, 38 }, { 17, 20 }, { 4, 14 }, { 11, 15 } } },
- { CYCLES_JMP_SHORT, { { 7, 7 }, { 3, 3 }, { 1, 1 }, { 1, 1 } } },
- { CYCLES_JMP, { { 7, 7 }, { 3, 3 }, { 1, 1 }, { 1, 1 } } },
- { CYCLES_JMP_REG, { { 7, 7 }, { 5, 5 }, { 2, 2 }, { 1, 1 } } },
- { CYCLES_JMP_MEM, { { 10, 10 }, { 5, 5 }, { 2, 2 }, { 3, 3 } } },
- { CYCLES_JMP_INTERSEG, { { 12, 27 }, { 17, 19 }, { 3, 3 }, { 8, 12 } } },
- { CYCLES_JMP_REG_INTERSEG, { { 17, 31 }, { 13, 18 }, { 4, 4 }, { 10, 10 } } },
- { CYCLES_JMP_MEM_INTERSEG, { { 17, 31 }, { 13, 18 }, { 4, 4 }, { 10, 13 } } },
- { CYCLES_RET, { { 10, 10 }, { 5, 5 }, { 2, 2 }, { 3, 3 } } },
- { CYCLES_RET_IMM, { { 10, 10 }, { 5, 5 }, { 2, 2 }, { 3, 3 } } },
- { CYCLES_RET_INTERSEG, { { 18, 32 }, { 13, 13 }, { 4, 4 }, { 10, 13 } } },
- { CYCLES_RET_IMM_INTERSEG, { { 18, 32 }, { 14, 14 }, { 4, 4 }, { 10, 13 } } },
- { CYCLES_JCC_DISP8, { { 7, 7 }, { 3, 3 }, { 1, 1 }, { 1, 1 } } },
- { CYCLES_JCC_FULL_DISP, { { 7, 7 }, { 3, 3 }, { 1, 1 }, { 1, 1 } } },
- { CYCLES_JCC_DISP8_NOBRANCH,{ { 3, 3 }, { 1, 1 }, { 1, 1 }, { 1, 1 } } },
- { CYCLES_JCC_FULL_DISP_NOBRANCH,{ { 3, 3 }, { 1, 1 }, { 1, 1 }, { 1, 1 } } },
- { CYCLES_JCXZ, { { 9, 9 }, { 1, 1 }, { 1, 1 }, { 2, 2 } } },
- { CYCLES_JCXZ_NOBRANCH, { { 5, 5 }, { 1, 1 }, { 1, 1 }, { 2, 2 } } },
- { CYCLES_LOOP, { { 11, 11 }, { 6, 6 }, { 5, 5 }, { 2, 2 } } },
- { CYCLES_LOOPZ, { { 11, 11 }, { 9, 9 }, { 8, 8 }, { 2, 2 } } },
- { CYCLES_LOOPNZ, { { 11, 11 }, { 9, 9 }, { 8, 8 }, { 2, 2 } } },
- { CYCLES_SETCC_REG, { { 4, 4 }, { 3, 3 }, { 2, 2 }, { 1, 1 } } },
- { CYCLES_SETCC_MEM, { { 5, 5 }, { 4, 4 }, { 2, 2 }, { 1, 1 } } },
- { CYCLES_ENTER, { { 10, 10 }, { 14, 14 }, { 11, 11 }, { 13, 13 } } },
- { CYCLES_LEAVE, { { 4, 4 }, { 5, 5 }, { 3, 3 }, { 1, 1 } } },
- { CYCLES_INT, { { 37, 37 }, { 30, 30 }, { 16, 16 }, { 19, 19 } } },
- { CYCLES_INT3, { { 33, 33 }, { 26, 26 }, { 13, 13 }, { 19, 19 } } },
- { CYCLES_INTO_OF1, { { 35, 35 }, { 28, 28 }, { 13, 13 }, { 19, 19 } } },
- { CYCLES_INTO_OF0, { { 3, 3 }, { 3, 3 }, { 4, 4 }, { 4, 4 } } },
- { CYCLES_BOUND_IN_RANGE, { { 10, 10 }, { 7, 7 }, { 8, 8 }, { 7, 7 } } },
- { CYCLES_BOUND_OUT_RANGE, { { 44, 44 }, { 7, 7 }, { 8, 8 }, { 8, 8 } } },
- { CYCLES_IRET, { { 22, 22 }, { 15, 15 }, { 8, 8 }, { 13, 13 } } },
- { CYCLES_HLT, { { 5, 5 }, { 4, 4 }, { 4, 4 }, { 10, 10 } } },
- { CYCLES_MOV_REG_CR0, { { 11, 11 }, { 16, 16 }, { 16, 16 }, { 20, 18 } } },
- { CYCLES_MOV_REG_CR2, { { 4, 4 }, { 4, 4 }, { 4, 4 }, { 5, 5 } } },
- { CYCLES_MOV_REG_CR3, { { 5, 5 }, { 4, 4 }, { 4, 4 }, { 5, 6 } } },
- { CYCLES_MOV_CR_REG, { { 6, 6 }, { 4, 4 }, { 4, 4 }, { 6, 6 } } },
- { CYCLES_MOV_REG_DR0_3, { { 22, 22 }, { 10, 10 }, { 10, 10 }, { 10, 10 } } },
- { CYCLES_MOV_REG_DR6_7, { { 16, 16 }, { 10, 10 }, { 10, 10 }, { 10, 10 } } },
- { CYCLES_MOV_DR6_7_REG, { { 14, 14 }, { 11, 11 }, { 11, 11 }, { 9, 9 } } },
- { CYCLES_MOV_DR0_3_REG, { { 22, 22 }, { 11, 11 }, { 11, 11 }, { 9, 9 } } },
- { CYCLES_MOV_REG_TR6_7, { { 12, 12 }, { 4, 4 }, { 4, 4 }, { 11, 11 } } },
- { CYCLES_MOV_TR6_7_REG, { { 12, 12 }, { 3, 3 }, { 3, 3 }, { 3, 3 } } },
- { CYCLES_NOP, { { 3, 3 }, { 1, 1 }, { 1, 1 }, { 1, 1 } } },
- { CYCLES_WAIT, { { 7, 7 }, { 1, 1 }, { 1, 1 }, { 1, 1 } } },
- { CYCLES_ARPL_REG, { { 0, 20 }, { 0, 9 }, { 0, 7 }, { 0, 9 } } },
- { CYCLES_ARPL_MEM, { { 0, 21 }, { 0, 9 }, { 0, 7 }, { 0, 9 } } },
- { CYCLES_LAR_REG, { { 0, 15 }, { 11, 11 }, { 8, 8 }, { 0, 9 } } },
- { CYCLES_LAR_MEM, { { 0, 16 }, { 11, 11 }, { 8, 8 }, { 0, 9 } } },
- { CYCLES_LGDT, { { 11, 11 }, { 11, 11 }, { 6, 6 }, { 10, 10 } } },
- { CYCLES_LIDT, { { 11, 11 }, { 11, 11 }, { 6, 6 }, { 10, 10 } } },
- { CYCLES_LLDT_REG, { { 0, 20 }, { 11, 11 }, { 9, 9 }, { 0, 8 } } },
- { CYCLES_LLDT_MEM, { { 0, 24 }, { 11, 11 }, { 9, 9 }, { 0, 8 } } },
- { CYCLES_LMSW_REG, { { 11, 11 }, { 13, 13 }, { 8, 8 }, { 11, 11 } } },
- { CYCLES_LMSW_MEM, { { 14, 14 }, { 13, 13 }, { 8, 8 }, { 11, 11 } } },
- { CYCLES_LSL_REG, { { 0, 21 }, { 10, 10 }, { 8, 8 }, { 0, 9 } } },
- { CYCLES_LSL_MEM, { { 0, 22 }, { 10, 10 }, { 8, 8 }, { 0, 9 } } },
- { CYCLES_LTR_REG, { { 0, 23 }, { 20, 20 }, { 10, 10 }, { 0, 9 } } },
- { CYCLES_LTR_MEM, { { 0, 27 }, { 20, 20 }, { 10, 10 }, { 0, 9 } } },
- { CYCLES_SGDT, { { 9, 9 }, { 10, 10 }, { 4, 4 }, { 6, 6 } } },
- { CYCLES_SIDT, { { 9, 9 }, { 10, 10 }, { 4, 4 }, { 6, 6 } } },
- { CYCLES_SLDT_REG, { { 0, 2 }, { 2, 2 }, { 2, 2 }, { 0, 1 } } },
- { CYCLES_SLDT_MEM, { { 0, 2 }, { 3, 3 }, { 2, 2 }, { 0, 1 } } },
- { CYCLES_SMSW_REG, { { 2, 2 }, { 2, 2 }, { 4, 4 }, { 4, 4 } } },
- { CYCLES_SMSW_MEM, { { 2, 2 }, { 3, 3 }, { 4, 4 }, { 4, 4 } } },
- { CYCLES_STR_REG, { { 0, 2 }, { 2, 2 }, { 2, 2 }, { 0, 3 } } },
- { CYCLES_STR_MEM, { { 0, 2 }, { 3, 3 }, { 2, 2 }, { 0, 3 } } },
- { CYCLES_VERR_REG, { { 0, 10 }, { 11, 11 }, { 7, 7 }, { 0, 8 } } },
- { CYCLES_VERR_MEM, { { 0, 11 }, { 11, 11 }, { 7, 7 }, { 0, 8 } } },
- { CYCLES_VERW_REG, { { 0, 15 }, { 11, 11 }, { 7, 7 }, { 0, 8 } } },
- { CYCLES_VERW_MEM, { { 0, 16 }, { 11, 11 }, { 7, 7 }, { 0, 8 } } },
- { CYCLES_LOCK, { { 0, 0 }, { 1, 1 }, { 1, 1 }, { 1, 1 } } },
-
- // i486+
- { CYCLES_BSWAP, { { 0, 0 }, { 1, 1 }, { 1, 1 }, { 6, 6 } } },
- { CYCLES_CMPXCHG, { { 0, 0 }, { 6, 6 }, { 5, 5 }, { 6, 6 } } },
- { CYCLES_INVD, { { 0, 0 }, { 4, 4 }, { 15, 15 }, { 20, 20 } } },
- { CYCLES_XADD, { { 0, 0 }, { 4, 4 }, { 4, 4 }, { 2, 2 } } },
-
- // Pentium+
- { CYCLES_CMPXCHG8B, { { 0, 0 }, { 0, 0 }, { 10, 10 }, { 6, 6 } } },
- { CYCLES_CPUID, { { 0, 0 }, { 0, 0 }, { 14, 14 }, { 12, 12 } } },
- { CYCLES_CPUID_EAX1, { { 0, 0 }, { 0, 0 }, { 14, 14 }, { 12, 12 } } },
- { CYCLES_RDTSC, { { 0, 0 }, { 0, 0 }, { 20, 20 }, { 1, 1 } } },
- { CYCLES_RSM, { { 0, 0 }, { 0, 0 }, { 82, 82 }, { 57, 57 } } },
- { CYCLES_RDMSR, { { 0, 0 }, { 0, 0 }, { 20, 20 }, { 1, 1 } } },
-
- // FPU
- { CYCLES_FABS, { { 0, 0 }, { 3, 3 }, { 1, 1 }, { 1, 1 } } },
- { CYCLES_FADD, { { 0, 0 }, { 8, 8 }, { 3, 3 }, { 1, 1 } } },
- { CYCLES_FBLD, { { 0, 0 }, { 70, 70 }, { 48, 48 }, { 1, 1 } } },
- { CYCLES_FBSTP, { { 0, 0 }, {172,172 }, {148,148 }, { 1, 1 } } },
- { CYCLES_FCHS, { { 0, 0 }, { 6, 6 }, { 1, 1 }, { 1, 1 } } },
- { CYCLES_FCLEX, { { 0, 0 }, { 7, 7 }, { 9, 9 }, { 1, 1 } } },
- { CYCLES_FCOM, { { 0, 0 }, { 4, 4 }, { 4, 4 }, { 1, 1 } } },
- { CYCLES_FCOS, { { 0, 0 }, {255,255 }, {124,124 }, { 1, 1 } } },
- { CYCLES_FDECSTP, { { 0, 0 }, { 3, 3 }, { 1, 1 }, { 1, 1 } } },
- { CYCLES_FDISI, { { 0, 0 }, { 3, 3 }, { 1, 1 }, { 1, 1 } } },
- { CYCLES_FDIV, { { 0, 0 }, { 73, 73 }, { 39, 39 }, { 1, 1 } } },
- { CYCLES_FDIVR, { { 0, 0 }, { 73, 73 }, { 39, 39 }, { 1, 1 } } },
- { CYCLES_FENI, { { 0, 0 }, { 3, 3 }, { 1, 1 }, { 1, 1 } } },
- { CYCLES_FFREE, { { 0, 0 }, { 3, 3 }, { 1, 1 }, { 1, 1 } } },
- { CYCLES_FIADD, { { 0, 0 }, { 20, 20 }, { 7, 7 }, { 1, 1 } } },
- { CYCLES_FICOM, { { 0, 0 }, { 16, 16 }, { 8, 8 }, { 1, 1 } } },
- { CYCLES_FIDIV, { { 0, 0 }, { 85, 85 }, { 42, 42 }, { 1, 1 } } },
- { CYCLES_FILD, { { 0, 0 }, { 13, 13 }, { 3, 3 }, { 1, 1 } } },
- { CYCLES_FIMUL, { { 0, 0 }, { 23, 23 }, { 7, 7 }, { 1, 1 } } },
- { CYCLES_FINCSTP, { { 0, 0 }, { 3, 3 }, { 1, 1 }, { 1, 1 } } },
- { CYCLES_FINIT, { { 0, 0 }, { 17, 17 }, { 16, 16 }, { 1, 1 } } },
- { CYCLES_FIST, { { 0, 0 }, { 29, 29 }, { 6, 6 }, { 1, 1 } } },
- { CYCLES_FISUB, { { 0, 0 }, { 20, 20 }, { 7, 7 }, { 1, 1 } } },
- { CYCLES_FLD, { { 0, 0 }, { 4, 4 }, { 1, 1 }, { 1, 1 } } },
- { CYCLES_FLDZ, { { 0, 0 }, { 4, 4 }, { 2, 2 }, { 1, 1 } } },
- { CYCLES_FLD1, { { 0, 0 }, { 4, 4 }, { 2, 2 }, { 1, 1 } } },
- { CYCLES_FLDL2E, { { 0, 0 }, { 8, 8 }, { 5, 5 }, { 1, 1 } } },
- { CYCLES_FLDL2T, { { 0, 0 }, { 8, 8 }, { 5, 5 }, { 1, 1 } } },
- { CYCLES_FLDLG2, { { 0, 0 }, { 8, 8 }, { 5, 5 }, { 1, 1 } } },
- { CYCLES_FLDLN2, { { 0, 0 }, { 8, 8 }, { 5, 5 }, { 1, 1 } } },
- { CYCLES_FLDPI, { { 0, 0 }, { 8, 8 }, { 5, 5 }, { 1, 1 } } },
- { CYCLES_FLDCW, { { 0, 0 }, { 4, 4 }, { 7, 7 }, { 1, 1 } } },
- { CYCLES_FLDENV, { { 0, 0 }, { 44, 44 }, { 37, 37 }, { 1, 1 } } },
- { CYCLES_FMUL, { { 0, 0 }, { 16, 16 }, { 3, 3 }, { 1, 1 } } },
- { CYCLES_FNOP, { { 0, 0 }, { 3, 3 }, { 1, 1 }, { 1, 1 } } },
- { CYCLES_FPATAN, { { 0, 0 }, {218,218 }, {173,173 }, { 1, 1 } } },
- { CYCLES_FPREM, { { 0, 0 }, { 70, 70 }, { 16, 16 }, { 1, 1 } } },
- { CYCLES_FPREM1, { { 0, 0 }, { 72, 72 }, { 20, 20 }, { 1, 1 } } },
- { CYCLES_FPTAN, { { 0, 0 }, {200,200 }, {173,173 }, { 1, 1 } } },
- { CYCLES_FRNDINT, { { 0, 0 }, { 21, 21 }, { 9, 9 }, { 1, 1 } } },
- { CYCLES_FRSTOR, { { 0, 0 }, {131,131 }, { 75, 75 }, { 1, 1 } } },
- { CYCLES_FSAVE, { { 0, 0 }, {154,154 }, {127,127 }, { 1, 1 } } },
- { CYCLES_FSCALE, { { 0, 0 }, { 30, 30 }, { 20, 20 }, { 1, 1 } } },
- { CYCLES_FSETPM, { { 0, 0 }, { 3, 3 }, { 1, 1 }, { 1, 1 } } },
- { CYCLES_FSIN, { { 0, 0 }, {255,255 }, {126,126 }, { 1, 1 } } },
- { CYCLES_FSINCOS, { { 0, 0 }, {255,255 }, {137,137 }, { 1, 1 } } },
- { CYCLES_FSQRT, { { 0, 0 }, { 83, 83 }, { 70, 70 }, { 1, 1 } } },
- { CYCLES_FST, { { 0, 0 }, { 3, 3 }, { 1, 1 }, { 1, 1 } } },
- { CYCLES_FSTCW, { { 0, 0 }, { 3, 3 }, { 2, 2 }, { 1, 1 } } },
- { CYCLES_FSTENV, { { 0, 0 }, { 67, 67 }, { 48, 48 }, { 1, 1 } } },
- { CYCLES_FSTSW, { { 0, 0 }, { 3, 3 }, { 2, 2 }, { 1, 1 } } },
- { CYCLES_FSUB, { { 0, 0 }, { 8, 8 }, { 3, 3 }, { 1, 1 } } },
- { CYCLES_FSUBR, { { 0, 0 }, { 8, 8 }, { 3, 3 }, { 1, 1 } } },
- { CYCLES_FTST, { { 0, 0 }, { 4, 4 }, { 4, 4 }, { 1, 1 } } },
- { CYCLES_FUCOM, { { 0, 0 }, { 4, 4 }, { 4, 4 }, { 1, 1 } } },
- { CYCLES_FXAM, { { 0, 0 }, { 8, 8 }, { 21, 21 }, { 1, 1 } } },
- { CYCLES_FXCH, { { 0, 0 }, { 4, 4 }, { 1, 1 }, { 1, 1 } } },
- { CYCLES_FXTRACT, { { 0, 0 }, { 16, 16 }, { 13, 13 }, { 1, 1 } } },
- { CYCLES_FYL2X, { { 0, 0 }, {196,196 }, {111,111 }, { 1, 1 } } },
- { CYCLES_FYL2XPI, { { 0, 0 }, {171,171 }, {103,103 }, { 1, 1 } } },
- { CYCLES_CMPXCHG_REG_REG_T, { { 0, 0 }, { 6, 6 }, { 6, 6 }, { 6, 6 } } },
- { CYCLES_CMPXCHG_REG_REG_F, { { 0, 0 }, { 9, 9 }, { 9, 9 }, { 9, 9 } } },
- { CYCLES_CMPXCHG_REG_MEM_T, { { 0, 0 }, { 7, 7 }, { 7, 7 }, { 7, 7 } } },
- { CYCLES_CMPXCHG_REG_MEM_F, { { 0, 0 }, { 10, 10 }, { 10, 10 }, { 10, 10 } } },
-};
-
-#endif /* __CYCLES_H__ */
+++ /dev/null
-// license:BSD-3-Clause
-// copyright-holders:Ville Linde, Barry Rodewald, Carl, Phil Bennett
-#pragma once
-
-#ifndef __I386INTF_H__
-#define __I386INTF_H__
-
-#define INPUT_LINE_A20 1
-#define INPUT_LINE_SMI 2
-
-struct i386_interface
-{
- devcb_write_line smiact;
-};
-
-// mingw has this defined for 32-bit compiles
-#undef i386
-
-DECLARE_LEGACY_CPU_DEVICE(I386, i386);
-DECLARE_LEGACY_CPU_DEVICE(I386SX, i386SX);
-DECLARE_LEGACY_CPU_DEVICE(I486, i486);
-DECLARE_LEGACY_CPU_DEVICE(PENTIUM, pentium);
-DECLARE_LEGACY_CPU_DEVICE(MEDIAGX, mediagx);
-DECLARE_LEGACY_CPU_DEVICE(PENTIUM_PRO, pentium_pro);
-DECLARE_LEGACY_CPU_DEVICE(PENTIUM_MMX, pentium_mmx);
-DECLARE_LEGACY_CPU_DEVICE(PENTIUM2, pentium2);
-DECLARE_LEGACY_CPU_DEVICE(PENTIUM3, pentium3);
-DECLARE_LEGACY_CPU_DEVICE(PENTIUM4, pentium4);
-
-
-
-#endif /* __I386INTF_H__ */
+++ /dev/null
-#include "./i386_opdef.h"
-
-int I386_OPS_BASE::i386_translate_address(int intention, offs_t *address, vtlb_entry *entry)
-{
- UINT32 a = *address;
- UINT32 pdbr = cpustate->cr[3] & 0xfffff000;
- UINT32 directory = (a >> 22) & 0x3ff;
- UINT32 table = (a >> 12) & 0x3ff;
- vtlb_entry perm = 0;
- int ret = FALSE;
- bool user = (intention & TRANSLATE_USER_MASK) ? true : false;
- bool write = (intention & TRANSLATE_WRITE) ? true : false;
- bool debug = (intention & TRANSLATE_DEBUG_MASK) ? true : false;
-
- if(!(cpustate->cr[0] & 0x80000000))
- {
- if(entry)
- *entry = 0x77;
- return TRUE;
- }
-
- UINT32 page_dir = cpustate->program->read_data32(pdbr + directory * 4);
- if(page_dir & 1)
- {
- if ((page_dir & 0x80) && (cpustate->cr[4] & 0x10))
- {
- a = (page_dir & 0xffc00000) | (a & 0x003fffff);
- if(debug)
- {
- *address = a;
- return TRUE;
- }
- perm = get_permissions(page_dir, WP);
- if(write && (!(perm & VTLB_WRITE_ALLOWED) || (user && !(perm & VTLB_USER_WRITE_ALLOWED))))
- ret = FALSE;
- else if(user && !(perm & VTLB_USER_READ_ALLOWED))
- ret = FALSE;
- else
- {
- if(write)
- perm |= VTLB_FLAG_DIRTY;
- if(!(page_dir & 0x40) && write)
- cpustate->program->write_data32(pdbr + directory * 4, page_dir | 0x60);
- else if(!(page_dir & 0x20))
- cpustate->program->write_data32(pdbr + directory * 4, page_dir | 0x20);
- ret = TRUE;
- }
- }
- else
- {
- UINT32 page_entry = cpustate->program->read_data32((page_dir & 0xfffff000) + (table * 4));
- if(!(page_entry & 1))
- ret = FALSE;
- else
- {
- a = (page_entry & 0xfffff000) | (a & 0xfff);
- if(debug)
- {
- *address = a;
- return TRUE;
- }
- perm = get_permissions(page_entry, WP);
- if(write && (!(perm & VTLB_WRITE_ALLOWED) || (user && !(perm & VTLB_USER_WRITE_ALLOWED))))
- ret = FALSE;
- else if(user && !(perm & VTLB_USER_READ_ALLOWED))
- ret = FALSE;
- else
- {
- if(write)
- perm |= VTLB_FLAG_DIRTY;
- if(!(page_dir & 0x20))
- cpustate->program->write_data32(pdbr + directory * 4, page_dir | 0x20);
- if(!(page_entry & 0x40) && write)
- cpustate->program->write_data32((page_dir & 0xfffff000) + (table * 4), page_entry | 0x60);
- else if(!(page_entry & 0x20))
- cpustate->program->write_data32((page_dir & 0xfffff000) + (table * 4), page_entry | 0x20);
- ret = TRUE;
- }
- }
- }
- }
- else
- ret = FALSE;
- if(entry)
- *entry = perm;
- if(ret)
- *address = a;
- return ret;
-}
-
-/***********************************************************************************
- MSR ACCESS
-***********************************************************************************/
-
-// Pentium MSR handling
-UINT64 I386_OPS_BASE::pentium_msr_read(i386_state *cpustate, UINT32 offset,UINT8 *valid_msr)
-{
- switch(offset)
- {
- // Machine Check Exception (TODO)
- case 0x00:
- *valid_msr = 1;
- popmessage("RDMSR: Reading P5_MC_ADDR");
- return 0;
- case 0x01:
- *valid_msr = 1;
- popmessage("RDMSR: Reading P5_MC_TYPE");
- return 0;
- // Time Stamp Counter
- case 0x10:
- *valid_msr = 1;
- popmessage("RDMSR: Reading TSC");
- return cpustate->tsc;
- // Event Counters (TODO)
- case 0x11: // CESR
- *valid_msr = 1;
- popmessage("RDMSR: Reading CESR");
- return 0;
- case 0x12: // CTR0
- *valid_msr = 1;
- return cpustate->perfctr[0];
- case 0x13: // CTR1
- *valid_msr = 1;
- return cpustate->perfctr[1];
- default:
- if(!(offset & ~0xf)) // 2-f are test registers
- {
- *valid_msr = 1;
- logerror("RDMSR: Reading test MSR %x", offset);
- return 0;
- }
- logerror("RDMSR: invalid P5 MSR read %08x at %08x\n",offset,cpustate->pc-2);
- *valid_msr = 0;
- return 0;
- }
- return -1;
-}
-
-void I386_OPS_BASE::pentium_msr_write(i386_state *cpustate, UINT32 offset, UINT64 data, UINT8 *valid_msr)
-{
- switch(offset)
- {
- // Machine Check Exception (TODO)
- case 0x00:
- popmessage("WRMSR: Writing P5_MC_ADDR");
- *valid_msr = 1;
- break;
- case 0x01:
- popmessage("WRMSR: Writing P5_MC_TYPE");
- *valid_msr = 1;
- break;
- // Time Stamp Counter
- case 0x10:
- cpustate->tsc = data;
- popmessage("WRMSR: Writing to TSC");
- *valid_msr = 1;
- break;
- // Event Counters (TODO)
- case 0x11: // CESR
- popmessage("WRMSR: Writing to CESR");
- *valid_msr = 1;
- break;
- case 0x12: // CTR0
- cpustate->perfctr[0] = data;
- *valid_msr = 1;
- break;
- case 0x13: // CTR1
- cpustate->perfctr[1] = data;
- *valid_msr = 1;
- break;
- default:
- if(!(offset & ~0xf)) // 2-f are test registers
- {
- *valid_msr = 1;
- logerror("WRMSR: Writing test MSR %x", offset);
- break;
- }
- logerror("WRMSR: invalid MSR write %08x (%08x%08x) at %08x\n",offset,(UINT32)(data >> 32),(UINT32)data,cpustate->pc-2);
- *valid_msr = 0;
- break;
- }
-}
-
-// P6 (Pentium Pro, Pentium II, Pentium III) MSR handling
-UINT64 I386_OPS_BASE::p6_msr_read(i386_state *cpustate, UINT32 offset,UINT8 *valid_msr)
-{
- switch(offset)
- {
- // Machine Check Exception (TODO)
- case 0x00:
- *valid_msr = 1;
- popmessage("RDMSR: Reading P5_MC_ADDR");
- return 0;
- case 0x01:
- *valid_msr = 1;
- popmessage("RDMSR: Reading P5_MC_TYPE");
- return 0;
- // Time Stamp Counter
- case 0x10:
- *valid_msr = 1;
- popmessage("RDMSR: Reading TSC");
- return cpustate->tsc;
- // Performance Counters (TODO)
- case 0xc1: // PerfCtr0
- *valid_msr = 1;
- return cpustate->perfctr[0];
- case 0xc2: // PerfCtr1
- *valid_msr = 1;
- return cpustate->perfctr[1];
- default:
- logerror("RDMSR: unimplemented register called %08x at %08x\n",offset,cpustate->pc-2);
- *valid_msr = 1;
- return 0;
- }
- return -1;
-}
-
-void I386_OPS_BASE::p6_msr_write(i386_state *cpustate, UINT32 offset, UINT64 data, UINT8 *valid_msr)
-{
- switch(offset)
- {
- // Time Stamp Counter
- case 0x10:
- cpustate->tsc = data;
- popmessage("WRMSR: Writing to TSC");
- *valid_msr = 1;
- break;
- // Performance Counters (TODO)
- case 0xc1: // PerfCtr0
- cpustate->perfctr[0] = data;
- *valid_msr = 1;
- break;
- case 0xc2: // PerfCtr1
- cpustate->perfctr[1] = data;
- *valid_msr = 1;
- break;
- default:
- logerror("WRMSR: unimplemented register called %08x (%08x%08x) at %08x\n",offset,(UINT32)(data >> 32),(UINT32)data,cpustate->pc-2);
- *valid_msr = 1;
- break;
- }
-}
-
-// PIV (Pentium 4+)
-UINT64 I386_OPS_BASE::piv_msr_read(i386_state *cpustate, UINT32 offset,UINT8 *valid_msr)
-{
- switch(offset)
- {
- default:
- logerror("RDMSR: unimplemented register called %08x at %08x\n",offset,cpustate->pc-2);
- *valid_msr = 1;
- return 0;
- }
- return -1;
-}
-
-void I386_OPS_BASE::piv_msr_write(i386_state *cpustate, UINT32 offset, UINT64 data, UINT8 *valid_msr)
-{
- switch(offset)
- {
- default:
- logerror("WRMSR: unimplemented register called %08x (%08x%08x) at %08x\n",offset,(UINT32)(data >> 32),(UINT32)data,cpustate->pc-2);
- *valid_msr = 1;
- break;
- }
-}
-
+++ /dev/null
-// license:BSD-3-Clause
-// copyright-holders:Ville Linde, Barry Rodewald, Carl, Phil Bennett
-/*
- Intel 386 emulator
-
- Written by Ville Linde
-
- Currently supports:
- Intel 386
- Intel 486
- Intel Pentium
- Cyrix MediaGX
- Intel Pentium MMX
- Intel Pentium Pro
- Intel Pentium II
- Intel Pentium III
- Intel Pentium 4
-*/
-
-//#include "emu.h"
-//#include "debugger.h"
-//#include "i386priv.h"
-#include "./i386_opdef.h"
-//#include "i386.h"
-
-//#include "debug/debugcpu.h"
-
-/* seems to be defined on mingw-gcc */
-#undef i386
-
-//static CPU_RESET( CPU_MODEL );
-
-
-#define FAULT(fault,error) {cpustate->ext = 1; i386_trap_with_error(cpustate,fault,0,0,error); return;}
-#define FAULT_EXP(fault,error) {cpustate->ext = 1; i386_trap_with_error(cpustate,fault,0,trap_level+1,error); return;}
-
-/*************************************************************************/
-
-UINT32 I386_OPS_BASE::i386_load_protected_mode_segment( I386_SREG *seg, UINT64 *desc )
-{
- UINT32 v1,v2;
- UINT32 base, limit;
- int entry;
-
- if(!seg->selector)
- {
- seg->flags = 0;
- seg->base = 0;
- seg->limit = 0;
- seg->d = 0;
- seg->valid = false;
- return 0;
- }
-
- if ( seg->selector & 0x4 )
- {
- base = cpustate->ldtr.base;
- limit = cpustate->ldtr.limit;
- } else {
- base = cpustate->gdtr.base;
- limit = cpustate->gdtr.limit;
- }
-
- entry = seg->selector & ~0x7;
- if (limit == 0 || entry + 7 > limit)
- return 0;
-
- v1 = READ32PL0(cpustate, base + entry );
- v2 = READ32PL0(cpustate, base + entry + 4 );
-
- seg->flags = (v2 >> 8) & 0xf0ff;
- seg->base = (v2 & 0xff000000) | ((v2 & 0xff) << 16) | ((v1 >> 16) & 0xffff);
- seg->limit = (v2 & 0xf0000) | (v1 & 0xffff);
- if (seg->flags & 0x8000)
- seg->limit = (seg->limit << 12) | 0xfff;
- seg->d = (seg->flags & 0x4000) ? 1 : 0;
- seg->valid = true;
-
- if(desc)
- *desc = ((UINT64)v2<<32)|v1;
- return 1;
-}
-
-void I386_OPS_BASE::i386_load_call_gate(I386_CALL_GATE *gate)
-{
- UINT32 v1,v2;
- UINT32 base,limit;
- int entry;
-
- if ( gate->segment & 0x4 )
- {
- base = cpustate->ldtr.base;
- limit = cpustate->ldtr.limit;
- } else {
- base = cpustate->gdtr.base;
- limit = cpustate->gdtr.limit;
- }
-
- entry = gate->segment & ~0x7;
- if (limit == 0 || entry + 7 > limit)
- return;
-
- v1 = READ32PL0(cpustate, base + entry );
- v2 = READ32PL0(cpustate, base + entry + 4 );
-
- /* Note that for task gates, offset and dword_count are not used */
- gate->selector = (v1 >> 16) & 0xffff;
- gate->offset = (v1 & 0x0000ffff) | (v2 & 0xffff0000);
- gate->ar = (v2 >> 8) & 0xff;
- gate->dword_count = v2 & 0x001f;
- gate->present = (gate->ar >> 7) & 0x01;
- gate->dpl = (gate->ar >> 5) & 0x03;
-}
-
-void I386_OPS_BASE::i386_set_descriptor_accessed( UINT16 selector)
-{
- // assume the selector is valid, we don't need to check it again
- UINT32 base, addr;
- UINT8 rights;
- if(!(selector & ~3))
- return;
-
- if ( selector & 0x4 )
- base = cpustate->ldtr.base;
- else
- base = cpustate->gdtr.base;
-
- addr = base + (selector & ~7) + 5;
- i386_translate_address(cpustate, TRANSLATE_READ, &addr, NULL);
- rights = cpustate->program->read_data8(addr);
- // Should a fault be thrown if the table is read only?
- cpustate->program->write_data8(addr, rights | 1);
-}
-
-void I386_OPS_BASE::i386_load_segment_descriptor( int segment )
-{
- if (PROTECTED_MODE)
- {
- if (!V8086_MODE)
- {
- i386_load_protected_mode_segment(cpustate, &cpustate->sreg[segment], NULL );
- if(cpustate->sreg[segment].selector)
- i386_set_descriptor_accessed(cpustate, cpustate->sreg[segment].selector);
- }
- else
- {
- cpustate->sreg[segment].base = cpustate->sreg[segment].selector << 4;
- cpustate->sreg[segment].limit = 0xffff;
- cpustate->sreg[segment].flags = (segment == CS) ? 0x00fb : 0x00f3;
- cpustate->sreg[segment].d = 0;
- cpustate->sreg[segment].valid = true;
- }
- }
- else
- {
- cpustate->sreg[segment].base = cpustate->sreg[segment].selector << 4;
- cpustate->sreg[segment].d = 0;
- cpustate->sreg[segment].valid = true;
-
- if( segment == CS && !cpustate->performed_intersegment_jump )
- cpustate->sreg[segment].base |= 0xfff00000;
- }
-}
-
-/* Retrieves the stack selector located in the current TSS */
-UINT32 I386_OPS_BASE::i386_get_stack_segment(UINT8 privilege)
-{
- UINT32 ret;
- if(privilege >= 3)
- return 0;
-
- if(cpustate->task.flags & 8)
- ret = READ32PL0(cpustate,(cpustate->task.base+8) + (8*privilege));
- else
- ret = READ16PL0(cpustate,(cpustate->task.base+4) + (4*privilege));
-
- return ret;
-}
-
-/* Retrieves the stack pointer located in the current TSS */
-UINT32 I386_OPS_BASE::i386_get_stack_ptr(UINT8 privilege)
-{
- UINT32 ret;
- if(privilege >= 3)
- return 0;
-
- if(cpustate->task.flags & 8)
- ret = READ32PL0(cpustate,(cpustate->task.base+4) + (8*privilege));
- else
- ret = READ16PL0(cpustate,(cpustate->task.base+2) + (4*privilege));
-
- return ret;
-}
-
-UINT32 I386_OPS_BASE::get_flags()
-{
- UINT32 f = 0x2;
- f |= cpustate->CF;
- f |= cpustate->PF << 2;
- f |= cpustate->AF << 4;
- f |= cpustate->ZF << 6;
- f |= cpustate->SF << 7;
- f |= cpustate->TF << 8;
- f |= cpustate->IF << 9;
- f |= cpustate->DF << 10;
- f |= cpustate->OF << 11;
- f |= cpustate->IOP1 << 12;
- f |= cpustate->IOP2 << 13;
- f |= cpustate->NT << 14;
- f |= cpustate->RF << 16;
- f |= cpustate->VM << 17;
- f |= cpustate->AC << 18;
- f |= cpustate->VIF << 19;
- f |= cpustate->VIP << 20;
- f |= cpustate->ID << 21;
- return (cpustate->eflags & ~cpustate->eflags_mask) | (f & cpustate->eflags_mask);
-}
-
-void I386_OPS_BASE::set_flags( UINT32 f )
-{
- cpustate->CF = (f & 0x1) ? 1 : 0;
- cpustate->PF = (f & 0x4) ? 1 : 0;
- cpustate->AF = (f & 0x10) ? 1 : 0;
- cpustate->ZF = (f & 0x40) ? 1 : 0;
- cpustate->SF = (f & 0x80) ? 1 : 0;
- cpustate->TF = (f & 0x100) ? 1 : 0;
- cpustate->IF = (f & 0x200) ? 1 : 0;
- cpustate->DF = (f & 0x400) ? 1 : 0;
- cpustate->OF = (f & 0x800) ? 1 : 0;
- cpustate->IOP1 = (f & 0x1000) ? 1 : 0;
- cpustate->IOP2 = (f & 0x2000) ? 1 : 0;
- cpustate->NT = (f & 0x4000) ? 1 : 0;
- cpustate->RF = (f & 0x10000) ? 1 : 0;
- cpustate->VM = (f & 0x20000) ? 1 : 0;
- cpustate->AC = (f & 0x40000) ? 1 : 0;
- cpustate->VIF = (f & 0x80000) ? 1 : 0;
- cpustate->VIP = (f & 0x100000) ? 1 : 0;
- cpustate->ID = (f & 0x200000) ? 1 : 0;
- cpustate->eflags = f & cpustate->eflags_mask;
-}
-
-void I386_OPS_BASE::sib_byte(UINT8 mod, UINT32* out_ea, UINT8* out_segment)
-{
- UINT32 ea = 0;
- UINT8 segment = 0;
- UINT8 scale, i, base;
- UINT8 sib = FETCH(cpustate);
- scale = (sib >> 6) & 0x3;
- i = (sib >> 3) & 0x7;
- base = sib & 0x7;
-
- switch( base )
- {
- case 0: ea = REG32(EAX); segment = DS; break;
- case 1: ea = REG32(ECX); segment = DS; break;
- case 2: ea = REG32(EDX); segment = DS; break;
- case 3: ea = REG32(EBX); segment = DS; break;
- case 4: ea = REG32(ESP); segment = SS; break;
- case 5:
- if( mod == 0 ) {
- ea = FETCH32(cpustate);
- segment = DS;
- } else if( mod == 1 ) {
- ea = REG32(EBP);
- segment = SS;
- } else if( mod == 2 ) {
- ea = REG32(EBP);
- segment = SS;
- }
- break;
- case 6: ea = REG32(ESI); segment = DS; break;
- case 7: ea = REG32(EDI); segment = DS; break;
- }
- switch( i )
- {
- case 0: ea += REG32(EAX) * (1 << scale); break;
- case 1: ea += REG32(ECX) * (1 << scale); break;
- case 2: ea += REG32(EDX) * (1 << scale); break;
- case 3: ea += REG32(EBX) * (1 << scale); break;
- case 4: break;
- case 5: ea += REG32(EBP) * (1 << scale); break;
- case 6: ea += REG32(ESI) * (1 << scale); break;
- case 7: ea += REG32(EDI) * (1 << scale); break;
- }
- *out_ea = ea;
- *out_segment = segment;
-}
-
-void I386_OPS_BASE::modrm_to_EA(UINT8 mod_rm, UINT32* out_ea, UINT8* out_segment)
-{
- INT8 disp8;
- INT16 disp16;
- INT32 disp32;
- UINT8 mod = (mod_rm >> 6) & 0x3;
- UINT8 rm = mod_rm & 0x7;
- UINT32 ea;
- UINT8 segment;
-
- if( mod_rm >= 0xc0 )
- fatalerror("i386: Called modrm_to_EA with modrm value %02X!\n",mod_rm);
-
-
- if( cpustate->address_size ) {
- switch( rm )
- {
- default:
- case 0: ea = REG32(EAX); segment = DS; break;
- case 1: ea = REG32(ECX); segment = DS; break;
- case 2: ea = REG32(EDX); segment = DS; break;
- case 3: ea = REG32(EBX); segment = DS; break;
- case 4: sib_byte(cpustate, mod, &ea, &segment ); break;
- case 5:
- if( mod == 0 ) {
- ea = FETCH32(cpustate); segment = DS;
- } else {
- ea = REG32(EBP); segment = SS;
- }
- break;
- case 6: ea = REG32(ESI); segment = DS; break;
- case 7: ea = REG32(EDI); segment = DS; break;
- }
- if( mod == 1 ) {
- disp8 = FETCH(cpustate);
- ea += (INT32)disp8;
- } else if( mod == 2 ) {
- disp32 = FETCH32(cpustate);
- ea += disp32;
- }
-
- if( cpustate->segment_prefix )
- segment = cpustate->segment_override;
-
- *out_ea = ea;
- *out_segment = segment;
-
- } else {
- switch( rm )
- {
- default:
- case 0: ea = REG16(BX) + REG16(SI); segment = DS; break;
- case 1: ea = REG16(BX) + REG16(DI); segment = DS; break;
- case 2: ea = REG16(BP) + REG16(SI); segment = SS; break;
- case 3: ea = REG16(BP) + REG16(DI); segment = SS; break;
- case 4: ea = REG16(SI); segment = DS; break;
- case 5: ea = REG16(DI); segment = DS; break;
- case 6:
- if( mod == 0 ) {
- ea = FETCH16(cpustate); segment = DS;
- } else {
- ea = REG16(BP); segment = SS;
- }
- break;
- case 7: ea = REG16(BX); segment = DS; break;
- }
- if( mod == 1 ) {
- disp8 = FETCH(cpustate);
- ea += (INT32)disp8;
- } else if( mod == 2 ) {
- disp16 = FETCH16(cpustate);
- ea += (INT32)disp16;
- }
-
- if( cpustate->segment_prefix )
- segment = cpustate->segment_override;
-
- *out_ea = ea & 0xffff;
- *out_segment = segment;
- }
-}
-
-UINT32 I386_OPS_BASE::GetNonTranslatedEA(UINT8 modrm,UINT8 *seg)
-{
- UINT8 segment;
- UINT32 ea;
- modrm_to_EA(cpustate, modrm, &ea, &segment );
- if(seg) *seg = segment;
- return ea;
-}
-
-UINT32 I386_OPS_BASE::GetEA(UINT8 modrm, int rwn)
-{
- UINT8 segment;
- UINT32 ea;
- modrm_to_EA(cpustate, modrm, &ea, &segment );
- return i386_translate(cpustate, segment, ea, rwn );
-}
-
-/* Check segment register for validity when changing privilege level after an RETF */
-void I386_OPS_BASE::i386_check_sreg_validity(int reg)
-{
- UINT16 selector = cpustate->sreg[reg].selector;
- UINT8 CPL = cpustate->CPL;
- UINT8 DPL,RPL;
- I386_SREG desc;
- int invalid = 0;
-
- memset(&desc, 0, sizeof(desc));
- desc.selector = selector;
- i386_load_protected_mode_segment(cpustate,&desc,NULL);
- DPL = (desc.flags >> 5) & 0x03; // descriptor privilege level
- RPL = selector & 0x03;
-
- /* Must be within the relevant descriptor table limits */
- if(selector & 0x04)
- {
- if((selector & ~0x07) > cpustate->ldtr.limit)
- invalid = 1;
- }
- else
- {
- if((selector & ~0x07) > cpustate->gdtr.limit)
- invalid = 1;
- }
-
- /* Must be either a data or readable code segment */
- if(((desc.flags & 0x0018) == 0x0018 && (desc.flags & 0x0002)) || (desc.flags & 0x0018) == 0x0010)
- invalid = 0;
- else
- invalid = 1;
-
- /* If a data segment or non-conforming code segment, then either DPL >= CPL or DPL >= RPL */
- if(((desc.flags & 0x0018) == 0x0018 && (desc.flags & 0x0004) == 0) || (desc.flags & 0x0018) == 0x0010)
- {
- if((DPL < CPL) || (DPL < RPL))
- invalid = 1;
- }
-
- /* if segment is invalid, then segment register is nulled */
- if(invalid != 0)
- {
- cpustate->sreg[reg].selector = 0;
- i386_load_segment_descriptor(cpustate,reg);
- }
-}
-
-int I386_OPS_BASE::i386_limit_check( int seg, UINT32 offset)
-{
- if(PROTECTED_MODE && !V8086_MODE)
- {
- if((cpustate->sreg[seg].flags & 0x0018) == 0x0010 && cpustate->sreg[seg].flags & 0x0004) // if expand-down data segment
- {
- // compare if greater then 0xffffffff when we're passed the access size
- if((offset <= cpustate->sreg[seg].limit) || ((cpustate->sreg[seg].d)?0:(offset > 0xffff)))
- {
- logerror("Limit check at 0x%08x failed. Segment %04x, limit %08x, offset %08x (expand-down)\n",cpustate->pc,cpustate->sreg[seg].selector,cpustate->sreg[seg].limit,offset);
- return 1;
- }
- }
- else
- {
- if(offset > cpustate->sreg[seg].limit)
- {
- logerror("Limit check at 0x%08x failed. Segment %04x, limit %08x, offset %08x\n",cpustate->pc,cpustate->sreg[seg].selector,cpustate->sreg[seg].limit,offset);
- return 1;
- }
- }
- }
- return 0;
-}
-
-void I386_OPS_BASE::i386_sreg_load( UINT16 selector, UINT8 reg, bool *fault)
-{
- // Checks done when MOV changes a segment register in protected mode
- UINT8 CPL,RPL,DPL;
-
- CPL = cpustate->CPL;
- RPL = selector & 0x0003;
-
- if(!PROTECTED_MODE || V8086_MODE)
- {
- cpustate->sreg[reg].selector = selector;
- i386_load_segment_descriptor(cpustate, reg);
- if(fault) *fault = false;
- return;
- }
-
- if(fault) *fault = true;
- if(reg == SS)
- {
- I386_SREG stack;
-
- memset(&stack, 0, sizeof(stack));
- stack.selector = selector;
- i386_load_protected_mode_segment(cpustate,&stack,NULL);
- DPL = (stack.flags >> 5) & 0x03;
-
- if((selector & ~0x0003) == 0)
- {
- logerror("SReg Load (%08x): Selector is null.\n",cpustate->pc);
- FAULT(FAULT_GP,0)
- }
- if(selector & 0x0004) // LDT
- {
- if((selector & ~0x0007) > cpustate->ldtr.limit)
- {
- logerror("SReg Load (%08x): Selector is out of LDT bounds.\n",cpustate->pc);
- FAULT(FAULT_GP,selector & ~0x03)
- }
- }
- else // GDT
- {
- if((selector & ~0x0007) > cpustate->gdtr.limit)
- {
- logerror("SReg Load (%08x): Selector is out of GDT bounds.\n",cpustate->pc);
- FAULT(FAULT_GP,selector & ~0x03)
- }
- }
- if (RPL != CPL)
- {
- logerror("SReg Load (%08x): Selector RPL does not equal CPL.\n",cpustate->pc);
- FAULT(FAULT_GP,selector & ~0x03)
- }
- if(((stack.flags & 0x0018) != 0x10) && (stack.flags & 0x0002) != 0)
- {
- logerror("SReg Load (%08x): Segment is not a writable data segment.\n",cpustate->pc);
- FAULT(FAULT_GP,selector & ~0x03)
- }
- if(DPL != CPL)
- {
- logerror("SReg Load (%08x): Segment DPL does not equal CPL.\n",cpustate->pc);
- FAULT(FAULT_GP,selector & ~0x03)
- }
- if(!(stack.flags & 0x0080))
- {
- logerror("SReg Load (%08x): Segment is not present.\n",cpustate->pc);
- FAULT(FAULT_SS,selector & ~0x03)
- }
- }
- if(reg == DS || reg == ES || reg == FS || reg == GS)
- {
- I386_SREG desc;
-
- if((selector & ~0x0003) == 0)
- {
- cpustate->sreg[reg].selector = selector;
- i386_load_segment_descriptor(cpustate, reg );
- if(fault) *fault = false;
- return;
- }
-
- memset(&desc, 0, sizeof(desc));
- desc.selector = selector;
- i386_load_protected_mode_segment(cpustate,&desc,NULL);
- DPL = (desc.flags >> 5) & 0x03;
-
- if(selector & 0x0004) // LDT
- {
- if((selector & ~0x0007) > cpustate->ldtr.limit)
- {
- logerror("SReg Load (%08x): Selector is out of LDT bounds.\n",cpustate->pc);
- FAULT(FAULT_GP,selector & ~0x03)
- }
- }
- else // GDT
- {
- if((selector & ~0x0007) > cpustate->gdtr.limit)
- {
- logerror("SReg Load (%08x): Selector is out of GDT bounds.\n",cpustate->pc);
- FAULT(FAULT_GP,selector & ~0x03)
- }
- }
- if((desc.flags & 0x0018) != 0x10)
- {
- if((((desc.flags & 0x0002) != 0) && ((desc.flags & 0x0018) != 0x18)) || !(desc.flags & 0x10))
- {
- logerror("SReg Load (%08x): Segment is not a data segment or readable code segment.\n",cpustate->pc);
- FAULT(FAULT_GP,selector & ~0x03)
- }
- }
- if(((desc.flags & 0x0018) == 0x10) || ((!(desc.flags & 0x0004)) && ((desc.flags & 0x0018) == 0x18)))
- {
- // if data or non-conforming code segment
- if((RPL > DPL) || (CPL > DPL))
- {
- logerror("SReg Load (%08x): Selector RPL or CPL is not less or equal to segment DPL.\n",cpustate->pc);
- FAULT(FAULT_GP,selector & ~0x03)
- }
- }
- if(!(desc.flags & 0x0080))
- {
- logerror("SReg Load (%08x): Segment is not present.\n",cpustate->pc);
- FAULT(FAULT_NP,selector & ~0x03)
- }
- }
-
- cpustate->sreg[reg].selector = selector;
- i386_load_segment_descriptor(cpustate, reg );
- if(fault) *fault = false;
-}
-
-void I386_OPS_BASE::i386_trap(int irq, int irq_gate, int trap_level)
-{
- /* I386 Interrupts/Traps/Faults:
- *
- * 0x00 Divide by zero
- * 0x01 Debug exception
- * 0x02 NMI
- * 0x03 Int3
- * 0x04 Overflow
- * 0x05 Array bounds check
- * 0x06 Illegal Opcode
- * 0x07 FPU not available
- * 0x08 Double fault
- * 0x09 Coprocessor segment overrun
- * 0x0a Invalid task state
- * 0x0b Segment not present
- * 0x0c Stack exception
- * 0x0d General Protection Fault
- * 0x0e Page fault
- * 0x0f Reserved
- * 0x10 Coprocessor error
- */
- UINT32 v1, v2;
- UINT32 offset, oldflags = get_flags();
- UINT16 segment;
- int entry = irq * (PROTECTED_MODE ? 8 : 4);
- int SetRPL = 0;
- cpustate->lock = false;
-
- if( !(PROTECTED_MODE) )
- {
- /* 16-bit */
- PUSH16(cpustate, oldflags & 0xffff );
- PUSH16(cpustate, cpustate->sreg[CS].selector );
- if(irq == 3 || irq == 4 || irq == 9 || irq_gate == 1)
- PUSH16(cpustate, cpustate->eip );
- else
- PUSH16(cpustate, cpustate->prev_eip );
-
- cpustate->sreg[CS].selector = READ16(cpustate, cpustate->idtr.base + entry + 2 );
- cpustate->eip = READ16(cpustate, cpustate->idtr.base + entry );
-
- cpustate->TF = 0;
- cpustate->IF = 0;
- }
- else
- {
- int type;
- UINT16 flags;
- I386_SREG desc;
- UINT8 CPL = cpustate->CPL, DPL = 0; //, RPL = 0;
-
- /* 32-bit */
- v1 = READ32PL0(cpustate, cpustate->idtr.base + entry );
- v2 = READ32PL0(cpustate, cpustate->idtr.base + entry + 4 );
- offset = (v2 & 0xffff0000) | (v1 & 0xffff);
- segment = (v1 >> 16) & 0xffff;
- type = (v2>>8) & 0x1F;
- flags = (v2>>8) & 0xf0ff;
-
- if(trap_level == 2)
- {
- logerror("IRQ: Double fault.\n");
- FAULT_EXP(FAULT_DF,0);
- }
- if(trap_level >= 3)
- {
- logerror("IRQ: Triple fault. CPU reset.\n");
- CPU_RESET_CALL(CPU_MODEL);
- cpustate->shutdown = 1;
- return;
- }
-
- /* segment privilege checks */
- if(entry >= cpustate->idtr.limit)
- {
- logerror("IRQ (%08x): Vector %02xh is past IDT limit.\n",cpustate->pc,entry);
- FAULT_EXP(FAULT_GP,entry+2)
- }
- /* segment must be interrupt gate, trap gate, or task gate */
- if(type != 0x05 && type != 0x06 && type != 0x07 && type != 0x0e && type != 0x0f)
- {
- logerror("IRQ#%02x (%08x): Vector segment %04x is not an interrupt, trap or task gate.\n",irq,cpustate->pc,segment);
- FAULT_EXP(FAULT_GP,entry+2)
- }
-
- if(cpustate->ext == 0) // if software interrupt (caused by INT/INTO/INT3)
- {
- if(((flags >> 5) & 0x03) < CPL)
- {
- logerror("IRQ (%08x): Software IRQ - gate DPL is less than CPL.\n",cpustate->pc);
- FAULT_EXP(FAULT_GP,entry+2)
- }
- if(V8086_MODE)
- {
- if((!cpustate->IOP1 || !cpustate->IOP2) && (cpustate->opcode != 0xcc))
- {
- logerror("IRQ (%08x): Is in Virtual 8086 mode and IOPL != 3.\n",cpustate->pc);
- FAULT(FAULT_GP,0)
- }
-
- }
- }
-
- if((flags & 0x0080) == 0)
- {
- logerror("IRQ: Vector segment is not present.\n");
- FAULT_EXP(FAULT_NP,entry+2)
- }
-
- if(type == 0x05)
- {
- /* Task gate */
- memset(&desc, 0, sizeof(desc));
- desc.selector = segment;
- i386_load_protected_mode_segment(cpustate,&desc,NULL);
- if(segment & 0x04)
- {
- logerror("IRQ: Task gate: TSS is not in the GDT.\n");
- FAULT_EXP(FAULT_TS,segment & ~0x03);
- }
- else
- {
- if(segment > cpustate->gdtr.limit)
- {
- logerror("IRQ: Task gate: TSS is past GDT limit.\n");
- FAULT_EXP(FAULT_TS,segment & ~0x03);
- }
- }
- if((desc.flags & 0x000f) != 0x09 && (desc.flags & 0x000f) != 0x01)
- {
- logerror("IRQ: Task gate: TSS is not an available TSS.\n");
- FAULT_EXP(FAULT_TS,segment & ~0x03);
- }
- if((desc.flags & 0x0080) == 0)
- {
- logerror("IRQ: Task gate: TSS is not present.\n");
- FAULT_EXP(FAULT_NP,segment & ~0x03);
- }
- if(!(irq == 3 || irq == 4 || irq == 9 || irq_gate == 1))
- cpustate->eip = cpustate->prev_eip;
- if(desc.flags & 0x08)
- i386_task_switch(cpustate,desc.selector,1);
- else
- i286_task_switch(cpustate,desc.selector,1);
- return;
- }
- else
- {
- /* Interrupt or Trap gate */
- memset(&desc, 0, sizeof(desc));
- desc.selector = segment;
- i386_load_protected_mode_segment(cpustate,&desc,NULL);
- CPL = cpustate->CPL; // current privilege level
- DPL = (desc.flags >> 5) & 0x03; // descriptor privilege level
-// RPL = segment & 0x03; // requested privilege level
-
- if((segment & ~0x03) == 0)
- {
- logerror("IRQ: Gate segment is null.\n");
- FAULT_EXP(FAULT_GP,cpustate->ext)
- }
- if(segment & 0x04)
- {
- if((segment & ~0x07) > cpustate->ldtr.limit)
- {
- logerror("IRQ: Gate segment is past LDT limit.\n");
- FAULT_EXP(FAULT_GP,(segment & 0x03)+cpustate->ext)
- }
- }
- else
- {
- if((segment & ~0x07) > cpustate->gdtr.limit)
- {
- logerror("IRQ: Gate segment is past GDT limit.\n");
- FAULT_EXP(FAULT_GP,(segment & 0x03)+cpustate->ext)
- }
- }
- if((desc.flags & 0x0018) != 0x18)
- {
- logerror("IRQ: Gate descriptor is not a code segment.\n");
- FAULT_EXP(FAULT_GP,(segment & 0x03)+cpustate->ext)
- }
- if((desc.flags & 0x0080) == 0)
- {
- logerror("IRQ: Gate segment is not present.\n");
- FAULT_EXP(FAULT_NP,(segment & 0x03)+cpustate->ext)
- }
- if((desc.flags & 0x0004) == 0 && (DPL < CPL))
- {
- /* IRQ to inner privilege */
- I386_SREG stack;
- UINT32 newESP,oldSS,oldESP;
-
- if(V8086_MODE && DPL)
- {
- logerror("IRQ: Gate to CPL>0 from VM86 mode.\n");
- FAULT_EXP(FAULT_GP,segment & ~0x03);
- }
- /* Check new stack segment in TSS */
- memset(&stack, 0, sizeof(stack));
- stack.selector = i386_get_stack_segment(cpustate,DPL);
- i386_load_protected_mode_segment(cpustate,&stack,NULL);
- oldSS = cpustate->sreg[SS].selector;
- if(flags & 0x0008)
- oldESP = REG32(ESP);
- else
- oldESP = REG16(SP);
- if((stack.selector & ~0x03) == 0)
- {
- logerror("IRQ: New stack selector is null.\n");
- FAULT_EXP(FAULT_GP,cpustate->ext)
- }
- if(stack.selector & 0x04)
- {
- if((stack.selector & ~0x07) > cpustate->ldtr.base)
- {
- logerror("IRQ: New stack selector is past LDT limit.\n");
- FAULT_EXP(FAULT_TS,(stack.selector & ~0x03)+cpustate->ext)
- }
- }
- else
- {
- if((stack.selector & ~0x07) > cpustate->gdtr.base)
- {
- logerror("IRQ: New stack selector is past GDT limit.\n");
- FAULT_EXP(FAULT_TS,(stack.selector & ~0x03)+cpustate->ext)
- }
- }
- if((stack.selector & 0x03) != DPL)
- {
- logerror("IRQ: New stack selector RPL is not equal to code segment DPL.\n");
- FAULT_EXP(FAULT_TS,(stack.selector & ~0x03)+cpustate->ext)
- }
- if(((stack.flags >> 5) & 0x03) != DPL)
- {
- logerror("IRQ: New stack segment DPL is not equal to code segment DPL.\n");
- FAULT_EXP(FAULT_TS,(stack.selector & ~0x03)+cpustate->ext)
- }
- if(((stack.flags & 0x0018) != 0x10) && (stack.flags & 0x0002) != 0)
- {
- logerror("IRQ: New stack segment is not a writable data segment.\n");
- FAULT_EXP(FAULT_TS,(stack.selector & ~0x03)+cpustate->ext) // #TS(stack selector + EXT)
- }
- if((stack.flags & 0x0080) == 0)
- {
- logerror("IRQ: New stack segment is not present.\n");
- FAULT_EXP(FAULT_SS,(stack.selector & ~0x03)+cpustate->ext) // #TS(stack selector + EXT)
- }
- newESP = i386_get_stack_ptr(cpustate,DPL);
- if(type & 0x08) // 32-bit gate
- {
- if(((newESP < (V8086_MODE?36:20)) && !(stack.flags & 0x4)) || ((~stack.limit < (~(newESP - 1) + (V8086_MODE?36:20))) && (stack.flags & 0x4)))
- {
- logerror("IRQ: New stack has no space for return addresses.\n");
- FAULT_EXP(FAULT_SS,0)
- }
- }
- else // 16-bit gate
- {
- newESP &= 0xffff;
- if(((newESP < (V8086_MODE?18:10)) && !(stack.flags & 0x4)) || ((~stack.limit < (~(newESP - 1) + (V8086_MODE?18:10))) && (stack.flags & 0x4)))
- {
- logerror("IRQ: New stack has no space for return addresses.\n");
- FAULT_EXP(FAULT_SS,0)
- }
- }
- if(offset > desc.limit)
- {
- logerror("IRQ: New EIP is past code segment limit.\n");
- FAULT_EXP(FAULT_GP,0)
- }
- /* change CPL before accessing the stack */
- cpustate->CPL = DPL;
- /* check for page fault at new stack TODO: check if stack frame crosses page boundary */
- WRITE_TEST(cpustate, stack.base+newESP-1);
- /* Load new stack segment descriptor */
- cpustate->sreg[SS].selector = stack.selector;
- i386_load_protected_mode_segment(cpustate,&cpustate->sreg[SS],NULL);
- i386_set_descriptor_accessed(cpustate, stack.selector);
- REG32(ESP) = newESP;
- if(V8086_MODE)
- {
- //logerror("IRQ (%08x): Interrupt during V8086 task\n",cpustate->pc);
- if(type & 0x08)
- {
- PUSH32(cpustate,cpustate->sreg[GS].selector & 0xffff);
- PUSH32(cpustate,cpustate->sreg[FS].selector & 0xffff);
- PUSH32(cpustate,cpustate->sreg[DS].selector & 0xffff);
- PUSH32(cpustate,cpustate->sreg[ES].selector & 0xffff);
- }
- else
- {
- PUSH16(cpustate,cpustate->sreg[GS].selector);
- PUSH16(cpustate,cpustate->sreg[FS].selector);
- PUSH16(cpustate,cpustate->sreg[DS].selector);
- PUSH16(cpustate,cpustate->sreg[ES].selector);
- }
- cpustate->sreg[GS].selector = 0;
- cpustate->sreg[FS].selector = 0;
- cpustate->sreg[DS].selector = 0;
- cpustate->sreg[ES].selector = 0;
- cpustate->VM = 0;
- i386_load_segment_descriptor(cpustate,GS);
- i386_load_segment_descriptor(cpustate,FS);
- i386_load_segment_descriptor(cpustate,DS);
- i386_load_segment_descriptor(cpustate,ES);
- }
- if(type & 0x08)
- {
- // 32-bit gate
- PUSH32(cpustate,oldSS);
- PUSH32(cpustate,oldESP);
- }
- else
- {
- // 16-bit gate
- PUSH16(cpustate,oldSS);
- PUSH16(cpustate,oldESP);
- }
- SetRPL = 1;
- }
- else
- {
- int stack_limit;
- if((desc.flags & 0x0004) || (DPL == CPL))
- {
- /* IRQ to same privilege */
- if(V8086_MODE && !cpustate->ext)
- {
- logerror("IRQ: Gate to same privilege from VM86 mode.\n");
- FAULT_EXP(FAULT_GP,segment & ~0x03);
- }
- if(type == 0x0e || type == 0x0f) // 32-bit gate
- stack_limit = 10;
- else
- stack_limit = 6;
- // TODO: Add check for error code (2 extra bytes)
- if(REG32(ESP) < stack_limit)
- {
- logerror("IRQ: Stack has no space left (needs %i bytes).\n",stack_limit);
- FAULT_EXP(FAULT_SS,0)
- }
- if(offset > desc.limit)
- {
- logerror("IRQ: Gate segment offset is past segment limit.\n");
- FAULT_EXP(FAULT_GP,0)
- }
- SetRPL = 1;
- }
- else
- {
- logerror("IRQ: Gate descriptor is non-conforming, and DPL does not equal CPL.\n");
- FAULT_EXP(FAULT_GP,segment)
- }
- }
- }
- UINT32 tempSP = REG32(ESP);
- try
- {
- // this is ugly but the alternative is worse
- if(type != 0x0e && type != 0x0f) // if not 386 interrupt or trap gate
- {
- PUSH16(cpustate, oldflags & 0xffff );
- PUSH16(cpustate, cpustate->sreg[CS].selector );
- if(irq == 3 || irq == 4 || irq == 9 || irq_gate == 1)
- PUSH16(cpustate, cpustate->eip );
- else
- PUSH16(cpustate, cpustate->prev_eip );
- }
- else
- {
- PUSH32(cpustate, oldflags & 0x00ffffff );
- PUSH32(cpustate, cpustate->sreg[CS].selector );
- if(irq == 3 || irq == 4 || irq == 9 || irq_gate == 1)
- PUSH32(cpustate, cpustate->eip );
- else
- PUSH32(cpustate, cpustate->prev_eip );
- }
- }
- catch(UINT64 e)
- {
- REG32(ESP) = tempSP;
- throw e;
- }
- if(SetRPL != 0)
- segment = (segment & ~0x03) | cpustate->CPL;
- cpustate->sreg[CS].selector = segment;
- cpustate->eip = offset;
-
- if(type == 0x0e || type == 0x06)
- cpustate->IF = 0;
- cpustate->TF = 0;
- cpustate->NT = 0;
- }
-
- i386_load_segment_descriptor(CS);
- CHANGE_PC(cpustate,cpustate->eip);
-
-}
-
-void I386_OPS_BASE::i386_trap_with_error(int irq, int irq_gate, int trap_level, UINT32 error)
-{
- i386_trap(cpustate,irq,irq_gate,trap_level);
- if(irq == 8 || irq == 10 || irq == 11 || irq == 12 || irq == 13 || irq == 14)
- {
- // for these exceptions, an error code is pushed onto the stack by the processor.
- // no error code is pushed for software interrupts, either.
- if(PROTECTED_MODE)
- {
- UINT32 entry = irq * 8;
- UINT32 v2,type;
- v2 = READ32PL0(cpustate, cpustate->idtr.base + entry + 4 );
- type = (v2>>8) & 0x1F;
- if(type == 5)
- {
- v2 = READ32PL0(cpustate, cpustate->idtr.base + entry);
- v2 = READ32PL0(cpustate, cpustate->gdtr.base + ((v2 >> 16) & 0xfff8) + 4);
- type = (v2>>8) & 0x1F;
- }
- if(type >= 9)
- PUSH32(cpustate,error);
- else
- PUSH16(cpustate,error);
- }
- else
- PUSH16(cpustate,error);
- }
-}
-
-
-void I386_OPS_BASE::i286_task_switch( UINT16 selector, UINT8 nested)
-{
- UINT32 tss;
- I386_SREG seg;
- UINT16 old_task;
- UINT8 ar_byte; // access rights byte
-
- /* TODO: Task State Segment privilege checks */
-
- /* For tasks that aren't nested, clear the busy bit in the task's descriptor */
- if(nested == 0)
- {
- if(cpustate->task.segment & 0x0004)
- {
- ar_byte = READ8(cpustate,cpustate->ldtr.base + (cpustate->task.segment & ~0x0007) + 5);
- WRITE8(cpustate,cpustate->ldtr.base + (cpustate->task.segment & ~0x0007) + 5,ar_byte & ~0x02);
- }
- else
- {
- ar_byte = READ8(cpustate,cpustate->gdtr.base + (cpustate->task.segment & ~0x0007) + 5);
- WRITE8(cpustate,cpustate->gdtr.base + (cpustate->task.segment & ~0x0007) + 5,ar_byte & ~0x02);
- }
- }
-
- /* Save the state of the current task in the current TSS (TR register base) */
- tss = cpustate->task.base;
- WRITE16(cpustate,tss+0x0e,cpustate->eip & 0x0000ffff);
- WRITE16(cpustate,tss+0x10,get_flags() & 0x0000ffff);
- WRITE16(cpustate,tss+0x12,REG16(AX));
- WRITE16(cpustate,tss+0x14,REG16(CX));
- WRITE16(cpustate,tss+0x16,REG16(DX));
- WRITE16(cpustate,tss+0x18,REG16(BX));
- WRITE16(cpustate,tss+0x1a,REG16(SP));
- WRITE16(cpustate,tss+0x1c,REG16(BP));
- WRITE16(cpustate,tss+0x1e,REG16(SI));
- WRITE16(cpustate,tss+0x20,REG16(DI));
- WRITE16(cpustate,tss+0x22,cpustate->sreg[ES].selector);
- WRITE16(cpustate,tss+0x24,cpustate->sreg[CS].selector);
- WRITE16(cpustate,tss+0x26,cpustate->sreg[SS].selector);
- WRITE16(cpustate,tss+0x28,cpustate->sreg[DS].selector);
-
- old_task = cpustate->task.segment;
-
- /* Load task register with the selector of the incoming task */
- cpustate->task.segment = selector;
- memset(&seg, 0, sizeof(seg));
- seg.selector = cpustate->task.segment;
- i386_load_protected_mode_segment(cpustate,&seg,NULL);
- cpustate->task.limit = seg.limit;
- cpustate->task.base = seg.base;
- cpustate->task.flags = seg.flags;
-
- /* Set TS bit in CR0 */
- cpustate->cr[0] |= 0x08;
-
- /* Load incoming task state from the new task's TSS */
- tss = cpustate->task.base;
- cpustate->ldtr.segment = READ16(cpustate,tss+0x2a) & 0xffff;
- seg.selector = cpustate->ldtr.segment;
- i386_load_protected_mode_segment(cpustate,&seg,NULL);
- cpustate->ldtr.limit = seg.limit;
- cpustate->ldtr.base = seg.base;
- cpustate->ldtr.flags = seg.flags;
- cpustate->eip = READ16(cpustate,tss+0x0e);
- set_flags(cpustate,READ16(cpustate,tss+0x10));
- REG16(AX) = READ16(cpustate,tss+0x12);
- REG16(CX) = READ16(cpustate,tss+0x14);
- REG16(DX) = READ16(cpustate,tss+0x16);
- REG16(BX) = READ16(cpustate,tss+0x18);
- REG16(SP) = READ16(cpustate,tss+0x1a);
- REG16(BP) = READ16(cpustate,tss+0x1c);
- REG16(SI) = READ16(cpustate,tss+0x1e);
- REG16(DI) = READ16(cpustate,tss+0x20);
- cpustate->sreg[ES].selector = READ16(cpustate,tss+0x22) & 0xffff;
- i386_load_segment_descriptor(cpustate, ES);
- cpustate->sreg[CS].selector = READ16(cpustate,tss+0x24) & 0xffff;
- i386_load_segment_descriptor(cpustate, CS);
- cpustate->sreg[SS].selector = READ16(cpustate,tss+0x26) & 0xffff;
- i386_load_segment_descriptor(cpustate, SS);
- cpustate->sreg[DS].selector = READ16(cpustate,tss+0x28) & 0xffff;
- i386_load_segment_descriptor(cpustate, DS);
-
- /* Set the busy bit in the new task's descriptor */
- if(selector & 0x0004)
- {
- ar_byte = READ8(cpustate,cpustate->ldtr.base + (selector & ~0x0007) + 5);
- WRITE8(cpustate,cpustate->ldtr.base + (selector & ~0x0007) + 5,ar_byte | 0x02);
- }
- else
- {
- ar_byte = READ8(cpustate,cpustate->gdtr.base + (selector & ~0x0007) + 5);
- WRITE8(cpustate,cpustate->gdtr.base + (selector & ~0x0007) + 5,ar_byte | 0x02);
- }
-
- /* For nested tasks, we write the outgoing task's selector to the back-link field of the new TSS,
- and set the NT flag in the EFLAGS register */
- if(nested != 0)
- {
- WRITE16(cpustate,tss+0,old_task);
- cpustate->NT = 1;
- }
- CHANGE_PC(cpustate,cpustate->eip);
-
- cpustate->CPL = (cpustate->sreg[SS].flags >> 5) & 3;
-// printf("286 Task Switch from selector %04x to %04x\n",old_task,selector);
-}
-
-void I386_OPS_BASE::i386_task_switch( UINT16 selector, UINT8 nested)
-{
- UINT32 tss;
- I386_SREG seg;
- UINT16 old_task;
- UINT8 ar_byte; // access rights byte
- UINT32 oldcr3 = cpustate->cr[3];
-
- /* TODO: Task State Segment privilege checks */
-
- /* For tasks that aren't nested, clear the busy bit in the task's descriptor */
- if(nested == 0)
- {
- if(cpustate->task.segment & 0x0004)
- {
- ar_byte = READ8(cpustate,cpustate->ldtr.base + (cpustate->task.segment & ~0x0007) + 5);
- WRITE8(cpustate,cpustate->ldtr.base + (cpustate->task.segment & ~0x0007) + 5,ar_byte & ~0x02);
- }
- else
- {
- ar_byte = READ8(cpustate,cpustate->gdtr.base + (cpustate->task.segment & ~0x0007) + 5);
- WRITE8(cpustate,cpustate->gdtr.base + (cpustate->task.segment & ~0x0007) + 5,ar_byte & ~0x02);
- }
- }
-
- /* Save the state of the current task in the current TSS (TR register base) */
- tss = cpustate->task.base;
- WRITE32(cpustate,tss+0x1c,cpustate->cr[3]); // correct?
- WRITE32(cpustate,tss+0x20,cpustate->eip);
- WRITE32(cpustate,tss+0x24,get_flags());
- WRITE32(cpustate,tss+0x28,REG32(EAX));
- WRITE32(cpustate,tss+0x2c,REG32(ECX));
- WRITE32(cpustate,tss+0x30,REG32(EDX));
- WRITE32(cpustate,tss+0x34,REG32(EBX));
- WRITE32(cpustate,tss+0x38,REG32(ESP));
- WRITE32(cpustate,tss+0x3c,REG32(EBP));
- WRITE32(cpustate,tss+0x40,REG32(ESI));
- WRITE32(cpustate,tss+0x44,REG32(EDI));
- WRITE32(cpustate,tss+0x48,cpustate->sreg[ES].selector);
- WRITE32(cpustate,tss+0x4c,cpustate->sreg[CS].selector);
- WRITE32(cpustate,tss+0x50,cpustate->sreg[SS].selector);
- WRITE32(cpustate,tss+0x54,cpustate->sreg[DS].selector);
- WRITE32(cpustate,tss+0x58,cpustate->sreg[FS].selector);
- WRITE32(cpustate,tss+0x5c,cpustate->sreg[GS].selector);
-
- old_task = cpustate->task.segment;
-
- /* Load task register with the selector of the incoming task */
- cpustate->task.segment = selector;
- memset(&seg, 0, sizeof(seg));
- seg.selector = cpustate->task.segment;
- i386_load_protected_mode_segment(cpustate,&seg,NULL);
- cpustate->task.limit = seg.limit;
- cpustate->task.base = seg.base;
- cpustate->task.flags = seg.flags;
-
- /* Set TS bit in CR0 */
- cpustate->cr[0] |= 0x08;
-
- /* Load incoming task state from the new task's TSS */
- tss = cpustate->task.base;
- cpustate->ldtr.segment = READ32(cpustate,tss+0x60) & 0xffff;
- seg.selector = cpustate->ldtr.segment;
- i386_load_protected_mode_segment(cpustate,&seg,NULL);
- cpustate->ldtr.limit = seg.limit;
- cpustate->ldtr.base = seg.base;
- cpustate->ldtr.flags = seg.flags;
- cpustate->eip = READ32(cpustate,tss+0x20);
- set_flags(cpustate,READ32(cpustate,tss+0x24));
- REG32(EAX) = READ32(cpustate,tss+0x28);
- REG32(ECX) = READ32(cpustate,tss+0x2c);
- REG32(EDX) = READ32(cpustate,tss+0x30);
- REG32(EBX) = READ32(cpustate,tss+0x34);
- REG32(ESP) = READ32(cpustate,tss+0x38);
- REG32(EBP) = READ32(cpustate,tss+0x3c);
- REG32(ESI) = READ32(cpustate,tss+0x40);
- REG32(EDI) = READ32(cpustate,tss+0x44);
- cpustate->sreg[ES].selector = READ32(cpustate,tss+0x48) & 0xffff;
- i386_load_segment_descriptor(cpustate, ES);
- cpustate->sreg[CS].selector = READ32(cpustate,tss+0x4c) & 0xffff;
- i386_load_segment_descriptor(cpustate, CS);
- cpustate->sreg[SS].selector = READ32(cpustate,tss+0x50) & 0xffff;
- i386_load_segment_descriptor(cpustate, SS);
- cpustate->sreg[DS].selector = READ32(cpustate,tss+0x54) & 0xffff;
- i386_load_segment_descriptor(cpustate, DS);
- cpustate->sreg[FS].selector = READ32(cpustate,tss+0x58) & 0xffff;
- i386_load_segment_descriptor(cpustate, FS);
- cpustate->sreg[GS].selector = READ32(cpustate,tss+0x5c) & 0xffff;
- i386_load_segment_descriptor(cpustate, GS);
- /* For nested tasks, we write the outgoing task's selector to the back-link field of the new TSS,
- and set the NT flag in the EFLAGS register before setting cr3 as the old tss address might be gone */
- if(nested != 0)
- {
- WRITE32(cpustate,tss+0,old_task);
- cpustate->NT = 1;
- }
- cpustate->cr[3] = READ32(cpustate,tss+0x1c); // CR3 (PDBR)
- if(oldcr3 != cpustate->cr[3])
- vtlb_flush_dynamic(cpustate->vtlb);
-
- /* Set the busy bit in the new task's descriptor */
- if(selector & 0x0004)
- {
- ar_byte = READ8(cpustate,cpustate->ldtr.base + (selector & ~0x0007) + 5);
- WRITE8(cpustate,cpustate->ldtr.base + (selector & ~0x0007) + 5,ar_byte | 0x02);
- }
- else
- {
- ar_byte = READ8(cpustate,cpustate->gdtr.base + (selector & ~0x0007) + 5);
- WRITE8(cpustate,cpustate->gdtr.base + (selector & ~0x0007) + 5,ar_byte | 0x02);
- }
-
- CHANGE_PC(cpustate,cpustate->eip);
-
- cpustate->CPL = (cpustate->sreg[SS].flags >> 5) & 3;
-// printf("386 Task Switch from selector %04x to %04x\n",old_task,selector);
-}
-
-void I386_OPS_BASE::i386_check_irq_line()
-{
- if(!cpustate->smm && cpustate->smi)
- {
- pentium_smi();
- return;
- }
-
- /* Check if the interrupts are enabled */
- if ( (cpustate->irq_state) && cpustate->IF )
- {
- cpustate->cycles -= 2;
- i386_trap(cpustate, cpustate->pic->get_intr_ack(), 1, 0);
- cpustate->irq_state = 0;
- }
-}
-
-void I386_OPS_BASE::i386_protected_mode_jump( UINT16 seg, UINT32 off, int indirect, int operand32)
-{
- I386_SREG desc;
- I386_CALL_GATE call_gate;
- UINT8 CPL,DPL,RPL;
- UINT8 SetRPL = 0;
- UINT16 segment = seg;
- UINT32 offset = off;
-
- /* Check selector is not null */
- if((segment & ~0x03) == 0)
- {
- logerror("JMP: Segment is null.\n");
- FAULT(FAULT_GP,0)
- }
- /* Selector is within descriptor table limit */
- if((segment & 0x04) == 0)
- {
- /* check GDT limit */
- if((segment & ~0x07) > (cpustate->gdtr.limit))
- {
- logerror("JMP: Segment is past GDT limit.\n");
- FAULT(FAULT_GP,segment & 0xfffc)
- }
- }
- else
- {
- /* check LDT limit */
- if((segment & ~0x07) > (cpustate->ldtr.limit))
- {
- logerror("JMP: Segment is past LDT limit.\n");
- FAULT(FAULT_GP,segment & 0xfffc)
- }
- }
- /* Determine segment type */
- memset(&desc, 0, sizeof(desc));
- desc.selector = segment;
- i386_load_protected_mode_segment(cpustate,&desc,NULL);
- CPL = cpustate->CPL; // current privilege level
- DPL = (desc.flags >> 5) & 0x03; // descriptor privilege level
- RPL = segment & 0x03; // requested privilege level
- if((desc.flags & 0x0018) == 0x0018)
- {
- /* code segment */
- if((desc.flags & 0x0004) == 0)
- {
- /* non-conforming */
- if(RPL > CPL)
- {
- logerror("JMP: RPL %i is less than CPL %i\n",RPL,CPL);
- FAULT(FAULT_GP,segment & 0xfffc)
- }
- if(DPL != CPL)
- {
- logerror("JMP: DPL %i is not equal CPL %i\n",DPL,CPL);
- FAULT(FAULT_GP,segment & 0xfffc)
- }
- }
- else
- {
- /* conforming */
- if(DPL > CPL)
- {
- logerror("JMP: DPL %i is less than CPL %i\n",DPL,CPL);
- FAULT(FAULT_GP,segment & 0xfffc)
- }
- }
- SetRPL = 1;
- if((desc.flags & 0x0080) == 0)
- {
- logerror("JMP: Segment is not present\n");
- FAULT(FAULT_NP,segment & 0xfffc)
- }
- if(offset > desc.limit)
- {
- logerror("JMP: Offset is past segment limit\n");
- FAULT(FAULT_GP,0)
- }
- }
- else
- {
- if((desc.flags & 0x0010) != 0)
- {
- logerror("JMP: Segment is a data segment\n");
- FAULT(FAULT_GP,segment & 0xfffc) // #GP (cannot execute code in a data segment)
- }
- else
- {
- switch(desc.flags & 0x000f)
- {
- case 0x01: // 286 Available TSS
- case 0x09: // 386 Available TSS
- logerror("JMP: Available 386 TSS at %08x\n",cpustate->pc);
- memset(&desc, 0, sizeof(desc));
- desc.selector = segment;
- i386_load_protected_mode_segment(cpustate,&desc,NULL);
- DPL = (desc.flags >> 5) & 0x03; // descriptor privilege level
- if(DPL < CPL)
- {
- logerror("JMP: TSS: DPL %i is less than CPL %i\n",DPL,CPL);
- FAULT(FAULT_GP,segment & 0xfffc)
- }
- if(DPL < RPL)
- {
- logerror("JMP: TSS: DPL %i is less than TSS RPL %i\n",DPL,RPL);
- FAULT(FAULT_GP,segment & 0xfffc)
- }
- if((desc.flags & 0x0080) == 0)
- {
- logerror("JMP: TSS: Segment is not present\n");
- FAULT(FAULT_GP,segment & 0xfffc)
- }
- if(desc.flags & 0x0008)
- i386_task_switch(cpustate,desc.selector,0);
- else
- i286_task_switch(cpustate,desc.selector,0);
- return;
- case 0x04: // 286 Call Gate
- case 0x0c: // 386 Call Gate
- //logerror("JMP: Call gate at %08x\n",cpustate->pc);
- SetRPL = 1;
- memset(&call_gate, 0, sizeof(call_gate));
- call_gate.segment = segment;
- i386_load_call_gate(cpustate,&call_gate);
- DPL = call_gate.dpl;
- if(DPL < CPL)
- {
- logerror("JMP: Call Gate: DPL %i is less than CPL %i\n",DPL,CPL);
- FAULT(FAULT_GP,segment & 0xfffc)
- }
- if(DPL < RPL)
- {
- logerror("JMP: Call Gate: DPL %i is less than RPL %i\n",DPL,RPL);
- FAULT(FAULT_GP,segment & 0xfffc)
- }
- if((desc.flags & 0x0080) == 0)
- {
- logerror("JMP: Call Gate: Segment is not present\n");
- FAULT(FAULT_NP,segment & 0xfffc)
- }
- /* Now we examine the segment that the call gate refers to */
- if(call_gate.selector == 0)
- {
- logerror("JMP: Call Gate: Gate selector is null\n");
- FAULT(FAULT_GP,0)
- }
- if(call_gate.selector & 0x04)
- {
- if((call_gate.selector & ~0x07) > cpustate->ldtr.limit)
- {
- logerror("JMP: Call Gate: Gate Selector is past LDT segment limit\n");
- FAULT(FAULT_GP,call_gate.selector & 0xfffc)
- }
- }
- else
- {
- if((call_gate.selector & ~0x07) > cpustate->gdtr.limit)
- {
- logerror("JMP: Call Gate: Gate Selector is past GDT segment limit\n");
- FAULT(FAULT_GP,call_gate.selector & 0xfffc)
- }
- }
- desc.selector = call_gate.selector;
- i386_load_protected_mode_segment(cpustate,&desc,NULL);
- DPL = (desc.flags >> 5) & 0x03;
- if((desc.flags & 0x0018) != 0x18)
- {
- logerror("JMP: Call Gate: Gate does not point to a code segment\n");
- FAULT(FAULT_GP,call_gate.selector & 0xfffc)
- }
- if((desc.flags & 0x0004) == 0)
- { // non-conforming
- if(DPL != CPL)
- {
- logerror("JMP: Call Gate: Gate DPL does not equal CPL\n");
- FAULT(FAULT_GP,call_gate.selector & 0xfffc)
- }
- }
- else
- { // conforming
- if(DPL > CPL)
- {
- logerror("JMP: Call Gate: Gate DPL is greater than CPL\n");
- FAULT(FAULT_GP,call_gate.selector & 0xfffc)
- }
- }
- if((desc.flags & 0x0080) == 0)
- {
- logerror("JMP: Call Gate: Gate Segment is not present\n");
- FAULT(FAULT_NP,call_gate.selector & 0xfffc)
- }
- if(call_gate.offset > desc.limit)
- {
- logerror("JMP: Call Gate: Gate offset is past Gate segment limit\n");
- FAULT(FAULT_GP,call_gate.selector & 0xfffc)
- }
- segment = call_gate.selector;
- offset = call_gate.offset;
- break;
- case 0x05: // Task Gate
- logerror("JMP: Task gate at %08x\n",cpustate->pc);
- memset(&call_gate, 0, sizeof(call_gate));
- call_gate.segment = segment;
- i386_load_call_gate(cpustate,&call_gate);
- DPL = call_gate.dpl;
- if(DPL < CPL)
- {
- logerror("JMP: Task Gate: Gate DPL %i is less than CPL %i\n",DPL,CPL);
- FAULT(FAULT_GP,segment & 0xfffc)
- }
- if(DPL < RPL)
- {
- logerror("JMP: Task Gate: Gate DPL %i is less than CPL %i\n",DPL,CPL);
- FAULT(FAULT_GP,segment & 0xfffc)
- }
- if(call_gate.present == 0)
- {
- logerror("JMP: Task Gate: Gate is not present.\n");
- FAULT(FAULT_GP,segment & 0xfffc)
- }
- /* Check the TSS that the task gate points to */
- desc.selector = call_gate.selector;
- i386_load_protected_mode_segment(cpustate,&desc,NULL);
- DPL = (desc.flags >> 5) & 0x03; // descriptor privilege level
- RPL = call_gate.selector & 0x03; // requested privilege level
- if(call_gate.selector & 0x04)
- {
- logerror("JMP: Task Gate TSS: TSS must be global.\n");
- FAULT(FAULT_GP,call_gate.selector & 0xfffc)
- }
- else
- {
- if((call_gate.selector & ~0x07) > cpustate->gdtr.limit)
- {
- logerror("JMP: Task Gate TSS: TSS is past GDT limit.\n");
- FAULT(FAULT_GP,call_gate.selector & 0xfffc)
- }
- }
- if((call_gate.ar & 0x000f) == 0x0009 || (call_gate.ar & 0x000f) == 0x0001)
- {
- logerror("JMP: Task Gate TSS: Segment is not an available TSS.\n");
- FAULT(FAULT_GP,call_gate.selector & 0xfffc)
- }
- if(call_gate.present == 0)
- {
- logerror("JMP: Task Gate TSS: TSS is not present.\n");
- FAULT(FAULT_NP,call_gate.selector & 0xfffc)
- }
- if(call_gate.ar & 0x08)
- i386_task_switch(cpustate,call_gate.selector,0);
- else
- i286_task_switch(cpustate,call_gate.selector,0);
- return;
- default: // invalid segment type
- logerror("JMP: Invalid segment type (%i) to jump to.\n",desc.flags & 0x000f);
- FAULT(FAULT_GP,segment & 0xfffc)
- }
- }
- }
-
- if(SetRPL != 0)
- segment = (segment & ~0x03) | cpustate->CPL;
- if(operand32 == 0)
- cpustate->eip = offset & 0x0000ffff;
- else
- cpustate->eip = offset;
- cpustate->sreg[CS].selector = segment;
- cpustate->performed_intersegment_jump = 1;
- i386_load_segment_descriptor(cpustate,CS);
- CHANGE_PC(cpustate,cpustate->eip);
-}
-
-void I386_OPS_BASE::i386_protected_mode_call( UINT16 seg, UINT32 off, int indirect, int operand32)
-{
- I386_SREG desc;
- I386_CALL_GATE gate;
- UINT8 SetRPL = 0;
- UINT8 CPL, DPL, RPL;
- UINT16 selector = seg;
- UINT32 offset = off;
- int x;
-
- if((selector & ~0x03) == 0)
- {
- logerror("CALL (%08x): Selector is null.\n",cpustate->pc);
- FAULT(FAULT_GP,0) // #GP(0)
- }
- if(selector & 0x04)
- {
- if((selector & ~0x07) > cpustate->ldtr.limit)
- {
- logerror("CALL: Selector is past LDT limit.\n");
- FAULT(FAULT_GP,selector & ~0x03) // #GP(selector)
- }
- }
- else
- {
- if((selector & ~0x07) > cpustate->gdtr.limit)
- {
- logerror("CALL: Selector is past GDT limit.\n");
- FAULT(FAULT_GP,selector & ~0x03) // #GP(selector)
- }
- }
-
- /* Determine segment type */
- memset(&desc, 0, sizeof(desc));
- desc.selector = selector;
- i386_load_protected_mode_segment(cpustate,&desc,NULL);
- CPL = cpustate->CPL; // current privilege level
- DPL = (desc.flags >> 5) & 0x03; // descriptor privilege level
- RPL = selector & 0x03; // requested privilege level
- if((desc.flags & 0x0018) == 0x18) // is a code segment
- {
- if(desc.flags & 0x0004)
- {
- /* conforming */
- if(DPL > CPL)
- {
- logerror("CALL: Code segment DPL %i is greater than CPL %i\n",DPL,CPL);
- FAULT(FAULT_GP,selector & ~0x03) // #GP(selector)
- }
- }
- else
- {
- /* non-conforming */
- if(RPL > CPL)
- {
- logerror("CALL: RPL %i is greater than CPL %i\n",RPL,CPL);
- FAULT(FAULT_GP,selector & ~0x03) // #GP(selector)
- }
- if(DPL != CPL)
- {
- logerror("CALL: Code segment DPL %i is not equal to CPL %i\n",DPL,CPL);
- FAULT(FAULT_GP,selector & ~0x03) // #GP(selector)
- }
- }
- SetRPL = 1;
- if((desc.flags & 0x0080) == 0)
- {
- logerror("CALL (%08x): Code segment is not present.\n",cpustate->pc);
- FAULT(FAULT_NP,selector & ~0x03) // #NP(selector)
- }
- if (operand32 != 0) // if 32-bit
- {
- if(i386_limit_check(cpustate, SS, REG32(ESP) - 8))
- {
- logerror("CALL (%08x): Stack has no room for return address.\n",cpustate->pc);
- FAULT(FAULT_SS,0) // #SS(0)
- }
- }
- else
- {
- if(i386_limit_check(cpustate, SS, (REG16(SP) - 4) & 0xffff))
- {
- logerror("CALL (%08x): Stack has no room for return address.\n",cpustate->pc);
- FAULT(FAULT_SS,0) // #SS(0)
- }
- }
- if(offset > desc.limit)
- {
- logerror("CALL: EIP is past segment limit.\n");
- FAULT(FAULT_GP,0) // #GP(0)
- }
- }
- else
- {
- /* special segment type */
- if(desc.flags & 0x0010)
- {
- logerror("CALL: Segment is a data segment.\n");
- FAULT(FAULT_GP,desc.selector & ~0x03) // #GP(selector)
- }
- else
- {
- switch(desc.flags & 0x000f)
- {
- case 0x01: // Available 286 TSS
- case 0x09: // Available 386 TSS
- logerror("CALL: Available TSS at %08x\n",cpustate->pc);
- if(DPL < CPL)
- {
- logerror("CALL: TSS: DPL is less than CPL.\n");
- FAULT(FAULT_TS,selector & ~0x03) // #TS(selector)
- }
- if(DPL < RPL)
- {
- logerror("CALL: TSS: DPL is less than RPL.\n");
- FAULT(FAULT_TS,selector & ~0x03) // #TS(selector)
- }
- if(desc.flags & 0x0002)
- {
- logerror("CALL: TSS: TSS is busy.\n");
- FAULT(FAULT_TS,selector & ~0x03) // #TS(selector)
- }
- if((desc.flags & 0x0080) == 0)
- {
- logerror("CALL: TSS: Segment %02x is not present.\n",selector);
- FAULT(FAULT_NP,selector & ~0x03) // #NP(selector)
- }
- if(desc.flags & 0x08)
- i386_task_switch(cpustate,desc.selector,1);
- else
- i286_task_switch(cpustate,desc.selector,1);
- return;
- case 0x04: // 286 call gate
- case 0x0c: // 386 call gate
- if((desc.flags & 0x000f) == 0x04)
- operand32 = 0;
- else
- operand32 = 1;
- memset(&gate, 0, sizeof(gate));
- gate.segment = selector;
- i386_load_call_gate(cpustate,&gate);
- DPL = gate.dpl;
- //logerror("CALL: Call gate at %08x (%i parameters)\n",cpustate->pc,gate.dword_count);
- if(DPL < CPL)
- {
- logerror("CALL: Call gate DPL %i is less than CPL %i.\n",DPL,CPL);
- FAULT(FAULT_GP,desc.selector & ~0x03) // #GP(selector)
- }
- if(DPL < RPL)
- {
- logerror("CALL: Call gate DPL %i is less than RPL %i.\n",DPL,RPL);
- FAULT(FAULT_GP,desc.selector & ~0x03) // #GP(selector)
- }
- if(gate.present == 0)
- {
- logerror("CALL: Call gate is not present.\n");
- FAULT(FAULT_NP,desc.selector & ~0x03) // #GP(selector)
- }
- desc.selector = gate.selector;
- if((gate.selector & ~0x03) == 0)
- {
- logerror("CALL: Call gate: Segment is null.\n");
- FAULT(FAULT_GP,0) // #GP(0)
- }
- if(desc.selector & 0x04)
- {
- if((desc.selector & ~0x07) > cpustate->ldtr.limit)
- {
- logerror("CALL: Call gate: Segment is past LDT limit\n");
- FAULT(FAULT_GP,desc.selector & ~0x03) // #GP(selector)
- }
- }
- else
- {
- if((desc.selector & ~0x07) > cpustate->gdtr.limit)
- {
- logerror("CALL: Call gate: Segment is past GDT limit\n");
- FAULT(FAULT_GP,desc.selector & ~0x03) // #GP(selector)
- }
- }
- i386_load_protected_mode_segment(cpustate,&desc,NULL);
- if((desc.flags & 0x0018) != 0x18)
- {
- logerror("CALL: Call gate: Segment is not a code segment.\n");
- FAULT(FAULT_GP,desc.selector & ~0x03) // #GP(selector)
- }
- DPL = ((desc.flags >> 5) & 0x03);
- if(DPL > CPL)
- {
- logerror("CALL: Call gate: Segment DPL %i is greater than CPL %i.\n",DPL,CPL);
- FAULT(FAULT_GP,desc.selector & ~0x03) // #GP(selector)
- }
- if((desc.flags & 0x0080) == 0)
- {
- logerror("CALL (%08x): Code segment is not present.\n",cpustate->pc);
- FAULT(FAULT_NP,desc.selector & ~0x03) // #NP(selector)
- }
- if(DPL < CPL && (desc.flags & 0x0004) == 0)
- {
- I386_SREG stack;
- I386_SREG temp;
- UINT32 oldSS,oldESP;
- /* more privilege */
- /* Check new SS segment for privilege level from TSS */
- memset(&stack, 0, sizeof(stack));
- stack.selector = i386_get_stack_segment(cpustate,DPL);
- i386_load_protected_mode_segment(cpustate,&stack,NULL);
- if((stack.selector & ~0x03) == 0)
- {
- logerror("CALL: Call gate: TSS selector is null\n");
- FAULT(FAULT_TS,0) // #TS(0)
- }
- if(stack.selector & 0x04)
- {
- if((stack.selector & ~0x07) > cpustate->ldtr.limit)
- {
- logerror("CALL: Call gate: TSS selector is past LDT limit\n");
- FAULT(FAULT_TS,stack.selector) // #TS(SS selector)
- }
- }
- else
- {
- if((stack.selector & ~0x07) > cpustate->gdtr.limit)
- {
- logerror("CALL: Call gate: TSS selector is past GDT limit\n");
- FAULT(FAULT_TS,stack.selector) // #TS(SS selector)
- }
- }
- if((stack.selector & 0x03) != DPL)
- {
- logerror("CALL: Call gate: Stack selector RPL does not equal code segment DPL %i\n",DPL);
- FAULT(FAULT_TS,stack.selector) // #TS(SS selector)
- }
- if(((stack.flags >> 5) & 0x03) != DPL)
- {
- logerror("CALL: Call gate: Stack DPL does not equal code segment DPL %i\n",DPL);
- FAULT(FAULT_TS,stack.selector) // #TS(SS selector)
- }
- if((stack.flags & 0x0018) != 0x10 && (stack.flags & 0x0002))
- {
- logerror("CALL: Call gate: Stack segment is not a writable data segment\n");
- FAULT(FAULT_TS,stack.selector) // #TS(SS selector)
- }
- if((stack.flags & 0x0080) == 0)
- {
- logerror("CALL: Call gate: Stack segment is not present\n");
- FAULT(FAULT_SS,stack.selector) // #SS(SS selector)
- }
- UINT32 newESP = i386_get_stack_ptr(cpustate,DPL);
- if(!stack.d)
- {
- newESP &= 0xffff;
- }
- if(operand32 != 0)
- {
- if(newESP < ((gate.dword_count & 0x1f) + 16))
- {
- logerror("CALL: Call gate: New stack has no room for 32-bit return address and parameters.\n");
- FAULT(FAULT_SS,0) // #SS(0)
- }
- if(gate.offset > desc.limit)
- {
- logerror("CALL: Call gate: EIP is past segment limit.\n");
- FAULT(FAULT_GP,0) // #GP(0)
- }
- }
- else
- {
- if(newESP < ((gate.dword_count & 0x1f) + 8))
- {
- logerror("CALL: Call gate: New stack has no room for 16-bit return address and parameters.\n");
- FAULT(FAULT_SS,0) // #SS(0)
- }
- if((gate.offset & 0xffff) > desc.limit)
- {
- logerror("CALL: Call gate: IP is past segment limit.\n");
- FAULT(FAULT_GP,0) // #GP(0)
- }
- }
- selector = gate.selector;
- offset = gate.offset;
-
- cpustate->CPL = (stack.flags >> 5) & 0x03;
- /* check for page fault at new stack */
- WRITE_TEST(cpustate, stack.base+newESP-1);
- /* switch to new stack */
- oldSS = cpustate->sreg[SS].selector;
- cpustate->sreg[SS].selector = i386_get_stack_segment(cpustate,cpustate->CPL);
- if(operand32 != 0)
- {
- oldESP = REG32(ESP);
- }
- else
- {
- oldESP = REG16(SP);
- }
- i386_load_segment_descriptor(cpustate, SS );
- REG32(ESP) = newESP;
-
- if(operand32 != 0)
- {
- PUSH32(cpustate,oldSS);
- PUSH32(cpustate,oldESP);
- }
- else
- {
- PUSH16(cpustate,oldSS);
- PUSH16(cpustate,oldESP & 0xffff);
- }
-
- memset(&temp, 0, sizeof(temp));
- temp.selector = oldSS;
- i386_load_protected_mode_segment(cpustate,&temp,NULL);
- /* copy parameters from old stack to new stack */
- for(x=(gate.dword_count & 0x1f)-1;x>=0;x--)
- {
- UINT32 addr = oldESP + (operand32?(x*4):(x*2));
- addr = temp.base + (temp.d?addr:(addr&0xffff));
- if(operand32)
- PUSH32(cpustate,READ32(cpustate,addr));
- else
- PUSH16(cpustate,READ16(cpustate,addr));
- }
- SetRPL = 1;
- }
- else
- {
- /* same privilege */
- if (operand32 != 0) // if 32-bit
- {
- if(i386_limit_check(cpustate, SS, REG32(ESP) - 8))
- {
- logerror("CALL: Stack has no room for return address.\n");
- FAULT(FAULT_SS,0) // #SS(0)
- }
- selector = gate.selector;
- offset = gate.offset;
- }
- else
- {
- if(i386_limit_check(cpustate, SS, (REG16(SP) - 4) & 0xffff))
- {
- logerror("CALL: Stack has no room for return address.\n");
- FAULT(FAULT_SS,0) // #SS(0)
- }
- selector = gate.selector;
- offset = gate.offset & 0xffff;
- }
- if(offset > desc.limit)
- {
- logerror("CALL: EIP is past segment limit.\n");
- FAULT(FAULT_GP,0) // #GP(0)
- }
- SetRPL = 1;
- }
- break;
- case 0x05: // task gate
- logerror("CALL: Task gate at %08x\n",cpustate->pc);
- memset(&gate, 0, sizeof(gate));
- gate.segment = selector;
- i386_load_call_gate(cpustate,&gate);
- DPL = gate.dpl;
- if(DPL < CPL)
- {
- logerror("CALL: Task Gate: Gate DPL is less than CPL.\n");
- FAULT(FAULT_TS,selector & ~0x03) // #TS(selector)
- }
- if(DPL < RPL)
- {
- logerror("CALL: Task Gate: Gate DPL is less than RPL.\n");
- FAULT(FAULT_TS,selector & ~0x03) // #TS(selector)
- }
- if((gate.ar & 0x0080) == 0)
- {
- logerror("CALL: Task Gate: Gate is not present.\n");
- FAULT(FAULT_NP,selector & ~0x03) // #NP(selector)
- }
- /* Check the TSS that the task gate points to */
- desc.selector = gate.selector;
- i386_load_protected_mode_segment(cpustate,&desc,NULL);
- if(gate.selector & 0x04)
- {
- logerror("CALL: Task Gate: TSS is not global.\n");
- FAULT(FAULT_TS,gate.selector & ~0x03) // #TS(selector)
- }
- else
- {
- if((gate.selector & ~0x07) > cpustate->gdtr.limit)
- {
- logerror("CALL: Task Gate: TSS is past GDT limit.\n");
- FAULT(FAULT_TS,gate.selector & ~0x03) // #TS(selector)
- }
- }
- if(desc.flags & 0x0002)
- {
- logerror("CALL: Task Gate: TSS is busy.\n");
- FAULT(FAULT_TS,gate.selector & ~0x03) // #TS(selector)
- }
- if((desc.flags & 0x0080) == 0)
- {
- logerror("CALL: Task Gate: TSS is not present.\n");
- FAULT(FAULT_NP,gate.selector & ~0x03) // #TS(selector)
- }
- if(desc.flags & 0x08)
- i386_task_switch(cpustate,desc.selector,1); // with nesting
- else
- i286_task_switch(cpustate,desc.selector,1);
- return;
- default:
- logerror("CALL: Invalid special segment type (%i) to jump to.\n",desc.flags & 0x000f);
- FAULT(FAULT_GP,selector & ~0x07) // #GP(selector)
- }
- }
- }
-
- if(SetRPL != 0)
- selector = (selector & ~0x03) | cpustate->CPL;
-
- UINT32 tempSP = REG32(ESP);
- try
- {
- // this is ugly but the alternative is worse
- if(operand32 == 0)
- {
- /* 16-bit operand size */
- PUSH16(cpustate, cpustate->sreg[CS].selector );
- PUSH16(cpustate, cpustate->eip & 0x0000ffff );
- cpustate->sreg[CS].selector = selector;
- cpustate->performed_intersegment_jump = 1;
- cpustate->eip = offset;
- i386_load_segment_descriptor(cpustate,CS);
- }
- else
- {
- /* 32-bit operand size */
- PUSH32(cpustate, cpustate->sreg[CS].selector );
- PUSH32(cpustate, cpustate->eip );
- cpustate->sreg[CS].selector = selector;
- cpustate->performed_intersegment_jump = 1;
- cpustate->eip = offset;
- i386_load_segment_descriptor(cpustate, CS );
- }
- }
- catch(UINT64 e)
- {
- REG32(ESP) = tempSP;
- throw e;
- }
-
- CHANGE_PC(cpustate,cpustate->eip);
-}
-
-void I386_OPS_BASE::i386_protected_mode_retf(UINT8 count, UINT8 operand32)
-{
- UINT32 newCS, newEIP;
- I386_SREG desc;
- UINT8 CPL, RPL, DPL;
-
- UINT32 ea = i386_translate(cpustate, SS, (STACK_32BIT)?REG32(ESP):REG16(SP), 0);
-
- if(operand32 == 0)
- {
- newEIP = READ16(cpustate, ea) & 0xffff;
- newCS = READ16(cpustate, ea+2) & 0xffff;
- }
- else
- {
- newEIP = READ32(cpustate, ea);
- newCS = READ32(cpustate, ea+4) & 0xffff;
- }
-
- memset(&desc, 0, sizeof(desc));
- desc.selector = newCS;
- i386_load_protected_mode_segment(cpustate,&desc,NULL);
- CPL = cpustate->CPL; // current privilege level
- DPL = (desc.flags >> 5) & 0x03; // descriptor privilege level
- RPL = newCS & 0x03;
-
- if(RPL < CPL)
- {
- logerror("RETF (%08x): Return segment RPL is less than CPL.\n",cpustate->pc);
- FAULT(FAULT_GP,newCS & ~0x03)
- }
-
- if(RPL == CPL)
- {
- /* same privilege level */
- if((newCS & ~0x03) == 0)
- {
- logerror("RETF: Return segment is null.\n");
- FAULT(FAULT_GP,0)
- }
- if(newCS & 0x04)
- {
- if((newCS & ~0x07) >= cpustate->ldtr.limit)
- {
- logerror("RETF: Return segment is past LDT limit.\n");
- FAULT(FAULT_GP,newCS & ~0x03)
- }
- }
- else
- {
- if((newCS & ~0x07) >= cpustate->gdtr.limit)
- {
- logerror("RETF: Return segment is past GDT limit.\n");
- FAULT(FAULT_GP,newCS & ~0x03)
- }
- }
- if((desc.flags & 0x0018) != 0x0018)
- {
- logerror("RETF: Return segment is not a code segment.\n");
- FAULT(FAULT_GP,newCS & ~0x03)
- }
- if(desc.flags & 0x0004)
- {
- if(DPL > RPL)
- {
- logerror("RETF: Conforming code segment DPL is greater than CS RPL.\n");
- FAULT(FAULT_GP,newCS & ~0x03)
- }
- }
- else
- {
- if(DPL != RPL)
- {
- logerror("RETF: Non-conforming code segment DPL does not equal CS RPL.\n");
- FAULT(FAULT_GP,newCS & ~0x03)
- }
- }
- if((desc.flags & 0x0080) == 0)
- {
- logerror("RETF (%08x): Code segment is not present.\n",cpustate->pc);
- FAULT(FAULT_NP,newCS & ~0x03)
- }
- if(newEIP > desc.limit)
- {
- logerror("RETF: EIP is past code segment limit.\n");
- FAULT(FAULT_GP,0)
- }
- if(operand32 == 0)
- {
- UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
- if(i386_limit_check(cpustate,SS,offset+count+3) != 0)
- {
- logerror("RETF (%08x): SP is past stack segment limit.\n",cpustate->pc);
- FAULT(FAULT_SS,0)
- }
- }
- else
- {
- UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
- if(i386_limit_check(cpustate,SS,offset+count+7) != 0)
- {
- logerror("RETF: ESP is past stack segment limit.\n");
- FAULT(FAULT_SS,0)
- }
- }
- if(operand32 == 0)
- REG16(SP) += (4+count);
- else
- REG32(ESP) += (8+count);
- }
- else if(RPL > CPL)
- {
- UINT32 newSS, newESP; // when changing privilege
- /* outer privilege level */
- if(operand32 == 0)
- {
- UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
- if(i386_limit_check(cpustate,SS,offset+count+7) != 0)
- {
- logerror("RETF (%08x): SP is past stack segment limit.\n",cpustate->pc);
- FAULT(FAULT_SS,0)
- }
- }
- else
- {
- UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
- if(i386_limit_check(cpustate,SS,offset+count+15) != 0)
- {
- logerror("RETF: ESP is past stack segment limit.\n");
- FAULT(FAULT_SS,0)
- }
- }
- /* Check CS selector and descriptor */
- if((newCS & ~0x03) == 0)
- {
- logerror("RETF: CS segment is null.\n");
- FAULT(FAULT_GP,0)
- }
- if(newCS & 0x04)
- {
- if((newCS & ~0x07) >= cpustate->ldtr.limit)
- {
- logerror("RETF: CS segment selector is past LDT limit.\n");
- FAULT(FAULT_GP,newCS & ~0x03)
- }
- }
- else
- {
- if((newCS & ~0x07) >= cpustate->gdtr.limit)
- {
- logerror("RETF: CS segment selector is past GDT limit.\n");
- FAULT(FAULT_GP,newCS & ~0x03)
- }
- }
- if((desc.flags & 0x0018) != 0x0018)
- {
- logerror("RETF: CS segment is not a code segment.\n");
- FAULT(FAULT_GP,newCS & ~0x03)
- }
- if(desc.flags & 0x0004)
- {
- if(DPL > RPL)
- {
- logerror("RETF: Conforming CS segment DPL is greater than return selector RPL.\n");
- FAULT(FAULT_GP,newCS & ~0x03)
- }
- }
- else
- {
- if(DPL != RPL)
- {
- logerror("RETF: Non-conforming CS segment DPL is not equal to return selector RPL.\n");
- FAULT(FAULT_GP,newCS & ~0x03)
- }
- }
- if((desc.flags & 0x0080) == 0)
- {
- logerror("RETF: CS segment is not present.\n");
- FAULT(FAULT_NP,newCS & ~0x03)
- }
- if(newEIP > desc.limit)
- {
- logerror("RETF: EIP is past return CS segment limit.\n");
- FAULT(FAULT_GP,0)
- }
-
- if(operand32 == 0)
- {
- ea += count+4;
- newESP = READ16(cpustate, ea) & 0xffff;
- newSS = READ16(cpustate, ea+2) & 0xffff;
- }
- else
- {
- ea += count+8;
- newESP = READ32(cpustate, ea);
- newSS = READ32(cpustate, ea+4) & 0xffff;
- }
-
- /* Check SS selector and descriptor */
- desc.selector = newSS;
- i386_load_protected_mode_segment(cpustate,&desc,NULL);
- DPL = (desc.flags >> 5) & 0x03; // descriptor privilege level
- if((newSS & ~0x07) == 0)
- {
- logerror("RETF: SS segment is null.\n");
- FAULT(FAULT_GP,0)
- }
- if(newSS & 0x04)
- {
- if((newSS & ~0x07) > cpustate->ldtr.limit)
- {
- logerror("RETF (%08x): SS segment selector is past LDT limit.\n",cpustate->pc);
- FAULT(FAULT_GP,newSS & ~0x03)
- }
- }
- else
- {
- if((newSS & ~0x07) > cpustate->gdtr.limit)
- {
- logerror("RETF (%08x): SS segment selector is past GDT limit.\n",cpustate->pc);
- FAULT(FAULT_GP,newSS & ~0x03)
- }
- }
- if((newSS & 0x03) != RPL)
- {
- logerror("RETF: SS segment RPL is not equal to CS segment RPL.\n");
- FAULT(FAULT_GP,newSS & ~0x03)
- }
- if((desc.flags & 0x0018) != 0x0010 || (desc.flags & 0x0002) == 0)
- {
- logerror("RETF: SS segment is not a writable data segment.\n");
- FAULT(FAULT_GP,newSS & ~0x03)
- }
- if(((desc.flags >> 5) & 0x03) != RPL)
- {
- logerror("RETF: SS DPL is not equal to CS segment RPL.\n");
- FAULT(FAULT_GP,newSS & ~0x03)
- }
- if((desc.flags & 0x0080) == 0)
- {
- logerror("RETF: SS segment is not present.\n");
- FAULT(FAULT_GP,newSS & ~0x03)
- }
- cpustate->CPL = newCS & 0x03;
-
- /* Load new SS:(E)SP */
- if(operand32 == 0)
- REG16(SP) = (newESP+count) & 0xffff;
- else
- REG32(ESP) = newESP+count;
- cpustate->sreg[SS].selector = newSS;
- i386_load_segment_descriptor(cpustate, SS );
-
- /* Check that DS, ES, FS and GS are valid for the new privilege level */
- i386_check_sreg_validity(cpustate,DS);
- i386_check_sreg_validity(cpustate,ES);
- i386_check_sreg_validity(cpustate,FS);
- i386_check_sreg_validity(cpustate,GS);
- }
-
- /* Load new CS:(E)IP */
- if(operand32 == 0)
- cpustate->eip = newEIP & 0xffff;
- else
- cpustate->eip = newEIP;
- cpustate->sreg[CS].selector = newCS;
- i386_load_segment_descriptor(cpustate, CS );
- CHANGE_PC(cpustate,cpustate->eip);
-}
-
-void I386_OPS_BASE::i386_protected_mode_iret(int operand32)
-{
- UINT32 newCS, newEIP;
- UINT32 newSS, newESP; // when changing privilege
- I386_SREG desc,stack;
- UINT8 CPL, RPL, DPL;
- UINT32 newflags;
-
- CPL = cpustate->CPL;
- UINT32 ea = i386_translate(cpustate, SS, (STACK_32BIT)?REG32(ESP):REG16(SP), 0);
- if(operand32 == 0)
- {
- newEIP = READ16(cpustate, ea) & 0xffff;
- newCS = READ16(cpustate, ea+2) & 0xffff;
- newflags = READ16(cpustate, ea+4) & 0xffff;
- }
- else
- {
- newEIP = READ32(cpustate, ea);
- newCS = READ32(cpustate, ea+4) & 0xffff;
- newflags = READ32(cpustate, ea+8);
- }
-
- if(V8086_MODE)
- {
- UINT32 oldflags = get_flags();
- if(!cpustate->IOP1 || !cpustate->IOP2)
- {
- logerror("IRET (%08x): Is in Virtual 8086 mode and IOPL != 3.\n",cpustate->pc);
- FAULT(FAULT_GP,0)
- }
- if(operand32 == 0)
- {
- cpustate->eip = newEIP & 0xffff;
- cpustate->sreg[CS].selector = newCS & 0xffff;
- newflags &= ~(3<<12);
- newflags |= (((oldflags>>12)&3)<<12); // IOPL cannot be changed in V86 mode
- set_flags(cpustate,(newflags & 0xffff) | (oldflags & ~0xffff));
- REG16(SP) += 6;
- }
- else
- {
- cpustate->eip = newEIP;
- cpustate->sreg[CS].selector = newCS & 0xffff;
- newflags &= ~(3<<12);
- newflags |= 0x20000 | (((oldflags>>12)&3)<<12); // IOPL and VM cannot be changed in V86 mode
- set_flags(cpustate,newflags);
- REG32(ESP) += 12;
- }
- }
- else if(NESTED_TASK)
- {
- UINT32 task = READ32(cpustate,cpustate->task.base);
- /* Task Return */
- logerror("IRET (%08x): Nested task return.\n",cpustate->pc);
- /* Check back-link selector in TSS */
- if(task & 0x04)
- {
- logerror("IRET: Task return: Back-linked TSS is not in GDT.\n");
- FAULT(FAULT_TS,task & ~0x03)
- }
- if((task & ~0x07) >= cpustate->gdtr.limit)
- {
- logerror("IRET: Task return: Back-linked TSS is not in GDT.\n");
- FAULT(FAULT_TS,task & ~0x03)
- }
- memset(&desc, 0, sizeof(desc));
- desc.selector = task;
- i386_load_protected_mode_segment(cpustate,&desc,NULL);
- if((desc.flags & 0x001f) != 0x000b)
- {
- logerror("IRET (%08x): Task return: Back-linked TSS is not a busy TSS.\n",cpustate->pc);
- FAULT(FAULT_TS,task & ~0x03)
- }
- if((desc.flags & 0x0080) == 0)
- {
- logerror("IRET: Task return: Back-linked TSS is not present.\n");
- FAULT(FAULT_NP,task & ~0x03)
- }
- if(desc.flags & 0x08)
- i386_task_switch(cpustate,desc.selector,0);
- else
- i286_task_switch(cpustate,desc.selector,0);
- return;
- }
- else
- {
- if(newflags & 0x00020000) // if returning to virtual 8086 mode
- {
- // 16-bit iret can't reach here
- newESP = READ32(cpustate, ea+12);
- newSS = READ32(cpustate, ea+16) & 0xffff;
- /* Return to v86 mode */
- //logerror("IRET (%08x): Returning to Virtual 8086 mode.\n",cpustate->pc);
- if(CPL != 0)
- {
- UINT32 oldflags = get_flags();
- newflags = (newflags & ~0x00003000) | (oldflags & 0x00003000);
- }
- set_flags(cpustate,newflags);
- cpustate->eip = POP32(cpustate) & 0xffff; // high 16 bits are ignored
- cpustate->sreg[CS].selector = POP32(cpustate) & 0xffff;
- POP32(cpustate); // already set flags
- newESP = POP32(cpustate);
- newSS = POP32(cpustate) & 0xffff;
- cpustate->sreg[ES].selector = POP32(cpustate) & 0xffff;
- cpustate->sreg[DS].selector = POP32(cpustate) & 0xffff;
- cpustate->sreg[FS].selector = POP32(cpustate) & 0xffff;
- cpustate->sreg[GS].selector = POP32(cpustate) & 0xffff;
- REG32(ESP) = newESP; // all 32 bits are loaded
- cpustate->sreg[SS].selector = newSS;
- i386_load_segment_descriptor(cpustate,ES);
- i386_load_segment_descriptor(cpustate,DS);
- i386_load_segment_descriptor(cpustate,FS);
- i386_load_segment_descriptor(cpustate,GS);
- i386_load_segment_descriptor(cpustate,SS);
- cpustate->CPL = 3; // Virtual 8086 tasks are always run at CPL 3
- }
- else
- {
- if(operand32 == 0)
- {
- UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
- if(i386_limit_check(cpustate,SS,offset+3) != 0)
- {
- logerror("IRET: Data on stack is past SS limit.\n");
- FAULT(FAULT_SS,0)
- }
- }
- else
- {
- UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
- if(i386_limit_check(cpustate,SS,offset+7) != 0)
- {
- logerror("IRET: Data on stack is past SS limit.\n");
- FAULT(FAULT_SS,0)
- }
- }
- RPL = newCS & 0x03;
- if(RPL < CPL)
- {
- logerror("IRET (%08x): Return CS RPL is less than CPL.\n",cpustate->pc);
- FAULT(FAULT_GP,newCS & ~0x03)
- }
- if(RPL == CPL)
- {
- /* return to same privilege level */
- if(operand32 == 0)
- {
- UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
- if(i386_limit_check(cpustate,SS,offset+5) != 0)
- {
- logerror("IRET (%08x): Data on stack is past SS limit.\n",cpustate->pc);
- FAULT(FAULT_SS,0)
- }
- }
- else
- {
- UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
- if(i386_limit_check(cpustate,SS,offset+11) != 0)
- {
- logerror("IRET (%08x): Data on stack is past SS limit.\n",cpustate->pc);
- FAULT(FAULT_SS,0)
- }
- }
- if((newCS & ~0x03) == 0)
- {
- logerror("IRET: Return CS selector is null.\n");
- FAULT(FAULT_GP,0)
- }
- if(newCS & 0x04)
- {
- if((newCS & ~0x07) >= cpustate->ldtr.limit)
- {
- logerror("IRET: Return CS selector (%04x) is past LDT limit.\n",newCS);
- FAULT(FAULT_GP,newCS & ~0x03)
- }
- }
- else
- {
- if((newCS & ~0x07) >= cpustate->gdtr.limit)
- {
- logerror("IRET: Return CS selector is past GDT limit.\n");
- FAULT(FAULT_GP,newCS & ~0x03)
- }
- }
- memset(&desc, 0, sizeof(desc));
- desc.selector = newCS;
- i386_load_protected_mode_segment(cpustate,&desc,NULL);
- DPL = (desc.flags >> 5) & 0x03; // descriptor privilege level
- RPL = newCS & 0x03;
- if((desc.flags & 0x0018) != 0x0018)
- {
- logerror("IRET (%08x): Return CS segment is not a code segment.\n",cpustate->pc);
- FAULT(FAULT_GP,newCS & ~0x07)
- }
- if(desc.flags & 0x0004)
- {
- if(DPL > RPL)
- {
- logerror("IRET: Conforming return CS DPL is greater than CS RPL.\n");
- FAULT(FAULT_GP,newCS & ~0x03)
- }
- }
- else
- {
- if(DPL != RPL)
- {
- logerror("IRET: Non-conforming return CS DPL is not equal to CS RPL.\n");
- FAULT(FAULT_GP,newCS & ~0x03)
- }
- }
- if((desc.flags & 0x0080) == 0)
- {
- logerror("IRET: Return CS segment is not present.\n");
- FAULT(FAULT_NP,newCS & ~0x03)
- }
- if(newEIP > desc.limit)
- {
- logerror("IRET: Return EIP is past return CS limit.\n");
- FAULT(FAULT_GP,0)
- }
-
- if(CPL != 0)
- {
- UINT32 oldflags = get_flags(cpustate);
- newflags = (newflags & ~0x00003000) | (oldflags & 0x00003000);
- }
-
- if(operand32 == 0)
- {
- cpustate->eip = newEIP;
- cpustate->sreg[CS].selector = newCS;
- set_flags(cpustate,newflags);
- REG16(SP) += 6;
- }
- else
- {
- cpustate->eip = newEIP;
- cpustate->sreg[CS].selector = newCS & 0xffff;
- set_flags(cpustate,newflags);
- REG32(ESP) += 12;
- }
- }
- else if(RPL > CPL)
- {
- /* return to outer privilege level */
- memset(&desc, 0, sizeof(desc));
- desc.selector = newCS;
- i386_load_protected_mode_segment(cpustate,&desc,NULL);
- DPL = (desc.flags >> 5) & 0x03; // descriptor privilege level
- RPL = newCS & 0x03;
- if(operand32 == 0)
- {
- UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
- if(i386_limit_check(cpustate,SS,offset+9) != 0)
- {
- logerror("IRET: SP is past SS limit.\n");
- FAULT(FAULT_SS,0)
- }
- }
- else
- {
- UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
- if(i386_limit_check(cpustate,SS,offset+19) != 0)
- {
- logerror("IRET: ESP is past SS limit.\n");
- FAULT(FAULT_SS,0)
- }
- }
- /* Check CS selector and descriptor */
- if((newCS & ~0x03) == 0)
- {
- logerror("IRET: Return CS selector is null.\n");
- FAULT(FAULT_GP,0)
- }
- if(newCS & 0x04)
- {
- if((newCS & ~0x07) >= cpustate->ldtr.limit)
- {
- logerror("IRET: Return CS selector is past LDT limit.\n");
- FAULT(FAULT_GP,newCS & ~0x03);
- }
- }
- else
- {
- if((newCS & ~0x07) >= cpustate->gdtr.limit)
- {
- logerror("IRET: Return CS selector is past GDT limit.\n");
- FAULT(FAULT_GP,newCS & ~0x03);
- }
- }
- if((desc.flags & 0x0018) != 0x0018)
- {
- logerror("IRET: Return CS segment is not a code segment.\n");
- FAULT(FAULT_GP,newCS & ~0x03)
- }
- if(desc.flags & 0x0004)
- {
- if(DPL > RPL)
- {
- logerror("IRET: Conforming return CS DPL is greater than CS RPL.\n");
- FAULT(FAULT_GP,newCS & ~0x03)
- }
- }
- else
- {
- if(DPL != RPL)
- {
- logerror("IRET: Non-conforming return CS DPL does not equal CS RPL.\n");
- FAULT(FAULT_GP,newCS & ~0x03)
- }
- }
- if((desc.flags & 0x0080) == 0)
- {
- logerror("IRET: Return CS segment is not present.\n");
- FAULT(FAULT_NP,newCS & ~0x03)
- }
-
- /* Check SS selector and descriptor */
- if(operand32 == 0)
- {
- newESP = READ16(cpustate, ea+6) & 0xffff;
- newSS = READ16(cpustate, ea+8) & 0xffff;
- }
- else
- {
- newESP = READ32(cpustate, ea+12);
- newSS = READ32(cpustate, ea+16) & 0xffff;
- }
- memset(&stack, 0, sizeof(stack));
- stack.selector = newSS;
- i386_load_protected_mode_segment(cpustate,&stack,NULL);
- DPL = (stack.flags >> 5) & 0x03;
- if((newSS & ~0x03) == 0)
- {
- logerror("IRET: Return SS selector is null.\n");
- FAULT(FAULT_GP,0)
- }
- if(newSS & 0x04)
- {
- if((newSS & ~0x07) >= cpustate->ldtr.limit)
- {
- logerror("IRET: Return SS selector is past LDT limit.\n");
- FAULT(FAULT_GP,newSS & ~0x03);
- }
- }
- else
- {
- if((newSS & ~0x07) >= cpustate->gdtr.limit)
- {
- logerror("IRET: Return SS selector is past GDT limit.\n");
- FAULT(FAULT_GP,newSS & ~0x03);
- }
- }
- if((newSS & 0x03) != RPL)
- {
- logerror("IRET: Return SS RPL is not equal to return CS RPL.\n");
- FAULT(FAULT_GP,newSS & ~0x03)
- }
- if((stack.flags & 0x0018) != 0x0010)
- {
- logerror("IRET: Return SS segment is not a data segment.\n");
- FAULT(FAULT_GP,newSS & ~0x03)
- }
- if((stack.flags & 0x0002) == 0)
- {
- logerror("IRET: Return SS segment is not writable.\n");
- FAULT(FAULT_GP,newSS & ~0x03)
- }
- if(DPL != RPL)
- {
- logerror("IRET: Return SS DPL does not equal SS RPL.\n");
- FAULT(FAULT_GP,newSS & ~0x03)
- }
- if((stack.flags & 0x0080) == 0)
- {
- logerror("IRET: Return SS segment is not present.\n");
- FAULT(FAULT_NP,newSS & ~0x03)
- }
- if(newEIP > desc.limit)
- {
- logerror("IRET: EIP is past return CS limit.\n");
- FAULT(FAULT_GP,0)
- }
-
-// if(operand32 == 0)
-// REG16(SP) += 10;
-// else
-// REG32(ESP) += 20;
-
- // IOPL can only change if CPL is zero
- if(CPL != 0)
- {
- UINT32 oldflags = get_flags(cpustate);
- newflags = (newflags & ~0x00003000) | (oldflags & 0x00003000);
- }
-
- if(operand32 == 0)
- {
- cpustate->eip = newEIP & 0xffff;
- cpustate->sreg[CS].selector = newCS;
- set_flags(cpustate,newflags);
- REG16(SP) = newESP & 0xffff;
- cpustate->sreg[SS].selector = newSS;
- }
- else
- {
- cpustate->eip = newEIP;
- cpustate->sreg[CS].selector = newCS & 0xffff;
- set_flags(cpustate,newflags);
- REG32(ESP) = newESP;
- cpustate->sreg[SS].selector = newSS & 0xffff;
- }
- cpustate->CPL = newCS & 0x03;
- i386_load_segment_descriptor(cpustate,SS);
-
- /* Check that DS, ES, FS and GS are valid for the new privilege level */
- i386_check_sreg_validity(cpustate,DS);
- i386_check_sreg_validity(cpustate,ES);
- i386_check_sreg_validity(cpustate,FS);
- i386_check_sreg_validity(cpustate,GS);
- }
- }
- }
-
- i386_load_segment_descriptor(cpustate,CS);
- CHANGE_PC(cpustate,cpustate->eip);
-}
-
-#include "cycles.h"
-
-#define CYCLES_NUM(x) (cpustate->cycles -= (x))
-
-INLINE void CYCLES(int x)
-{
- if (PROTECTED_MODE)
- {
- cpustate->cycles -= cpustate->cycle_table_pm[x];
- }
- else
- {
- cpustate->cycles -= cpustate->cycle_table_rm[x];
- }
-}
-
-INLINE void CYCLES_RM(int modrm, int r, int m)
-{
- if (modrm >= 0xc0)
- {
- if (PROTECTED_MODE)
- {
- cpustate->cycles -= cpustate->cycle_table_pm[r];
- }
- else
- {
- cpustate->cycles -= cpustate->cycle_table_rm[r];
- }
- }
- else
- {
- if (PROTECTED_MODE)
- {
- cpustate->cycles -= cpustate->cycle_table_pm[m];
- }
- else
- {
- cpustate->cycles -= cpustate->cycle_table_rm[m];
- }
- }
-}
-
-void I386_OPS_BASE::build_cycle_table()
-{
- int i, j;
- for (j=0; j < X86_NUM_CPUS; j++)
- {
-// cycle_table_rm[j] = (UINT8 *)malloc(CYCLES_NUM_OPCODES);
-// cycle_table_pm[j] = (UINT8 *)malloc(CYCLES_NUM_OPCODES);
-
- for (i=0; i < sizeof(x86_cycle_table)/sizeof(X86_CYCLE_TABLE); i++)
- {
- int opcode = x86_cycle_table[i].op;
- cycle_table_rm[j][opcode] = x86_cycle_table[i].cpu_cycles[j][0];
- cycle_table_pm[j][opcode] = x86_cycle_table[i].cpu_cycles[j][1];
- }
- }
-}
-
-void I386_OPS_BASE::report_invalid_opcode()
-{
-#ifndef DEBUG_MISSING_OPCODE
- logerror("i386: Invalid opcode %02X at %08X %s\n", cpustate->opcode, cpustate->pc - 1, cpustate->lock ? "with lock" : "");
-#else
- logerror("i386: Invalid opcode");
- for (int a = 0; a < cpustate->opcode_bytes_length; a++)
- logerror(" %02X", cpustate->opcode_bytes[a]);
- logerror(" at %08X\n", cpustate->opcode_pc);
-#endif
-}
-
-void I386_OPS_BASE::report_invalid_modrm( const char* opcode, UINT8 modrm)
-{
-#ifndef DEBUG_MISSING_OPCODE
- logerror("i386: Invalid %s modrm %01X at %08X\n", opcode, modrm, cpustate->pc - 2);
-#else
- logerror("i386: Invalid %s modrm %01X", opcode, modrm);
- for (int a = 0; a < cpustate->opcode_bytes_length; a++)
- logerror(" %02X", cpustate->opcode_bytes[a]);
- logerror(" at %08X\n", cpustate->opcode_pc);
-#endif
- i386_trap(cpustate, 6, 0, 0);
-}
-
-/* Forward declarations */
-
-#include "i386ops.c"
-#include "i386op16.c"
-#include "i386op32.c"
-#include "i486ops.c"
-#include "pentops.c"
-#include "x87ops.c"
-#include "i386ops.h"
-
-void I386OP(decode_opcode)()
-{
- cpustate->opcode = FETCH(cpustate);
-
- if(cpustate->lock && !cpustate->lock_table[0][cpustate->opcode])
- return I386OP(invalid)();
-
- if( cpustate->operand_size )
- cpustate->opcode_table1_32[cpustate->opcode]();
- else
- cpustate->opcode_table1_16[cpustate->opcode]();
-}
-
-/* Two-byte opcode 0f xx */
-void I386OP(decode_two_byte)()
-{
- cpustate->opcode = FETCH(cpustate);
-
- if(cpustate->lock && !cpustate->lock_table[1][cpustate->opcode])
- return I386OP(invalid)();
-
- if( cpustate->operand_size )
- cpustate->opcode_table2_32[cpustate->opcode]();
- else
- cpustate->opcode_table2_16[cpustate->opcode]();
-}
-
-/* Three-byte opcode 0f 38 xx */
-void I386OP(decode_three_byte38)()
-{
- cpustate->opcode = FETCH();
-
- if (cpustate->operand_size)
- cpustate->opcode_table338_32[cpustate->opcode]();
- else
- cpustate->opcode_table338_16[cpustate->opcode]();
-}
-
-/* Three-byte opcode 0f 3a xx */
-void I386OP(decode_three_byte3a)()
-{
- cpustate->opcode = FETCH(cpustate);
-
- if (cpustate->operand_size)
- cpustate->opcode_table33a_32[cpustate->opcode]();
- else
- cpustate->opcode_table33a_16[cpustate->opcode]();
-}
-
-/* Three-byte opcode prefix 66 0f xx */
-void I386OP(decode_three_byte66)()
-{
- cpustate->opcode = FETCH(cpustate);
- if( cpustate->operand_size )
- cpustate->opcode_table366_32[cpustate->opcode]();
- else
- cpustate->opcode_table366_16[cpustate->opcode]();
-}
-
-/* Three-byte opcode prefix f2 0f xx */
-void I386OP(decode_three_bytef2)()
-{
- cpustate->opcode = FETCH(cpustate);
- if( cpustate->operand_size )
- cpustate->opcode_table3f2_32[cpustate->opcode]();
- else
- cpustate->opcode_table3f2_16[cpustate->opcode]();
-}
-
-/* Three-byte opcode prefix f3 0f */
-void I386OP(decode_three_bytef3)()
-{
- cpustate->opcode = FETCH(cpustate);
- if( cpustate->operand_size )
- cpustate->opcode_table3f3_32[cpustate->opcode]();
- else
- cpustate->opcode_table3f3_16[cpustate->opcode]();
-}
-
-/* Four-byte opcode prefix 66 0f 38 xx */
-void I386OP(decode_four_byte3866)()
-{
- cpustate->opcode = FETCH(cpustate);
- if (cpustate->operand_size)
- cpustate->opcode_table46638_32[cpustate->opcode]();
- else
- cpustate->opcode_table46638_16[cpustate->opcode]();
-}
-
-/* Four-byte opcode prefix 66 0f 3a xx */
-void I386OP(decode_four_byte3a66)()
-{
- cpustate->opcode = FETCH(cpustate);
- if (cpustate->operand_size)
- cpustate->opcode_table4663a_32[cpustate->opcode]();
- else
- cpustate->opcode_table4663a_16[cpustate->opcode]();
-}
-
-/* Four-byte opcode prefix f2 0f 38 xx */
-void I386OP(decode_four_byte38f2)()
-{
- cpustate->opcode = FETCH(cpustate);
- if (cpustate->operand_size)
- cpustate->opcode_table4f238_32[cpustate->opcode]();
- else
- cpustate->opcode_table4f238_16[cpustate->opcode]();
-}
-
-/* Four-byte opcode prefix f2 0f 3a xx */
-void I386OP(decode_four_byte3af2)()
-{
- cpustate->opcode = FETCH(cpustate);
- if (cpustate->operand_size)
- cpustate->opcode_table4f23a_32[cpustate->opcode]();
- else
- cpustate->opcode_table4f23a_16[cpustate->opcode]();
-}
-
-/* Four-byte opcode prefix f3 0f 38 xx */
-void I386OP(decode_four_byte38f3)()
-{
- cpustate->opcode = FETCH(cpustate);
- if (cpustate->operand_size)
- cpustate->opcode_table4f338_32[cpustate->opcode]();
- else
- cpustate->opcode_table4f338_16[cpustate->opcode]();
-}
-
-
-/*************************************************************************/
-
-void I386_OPS_BASE::i386_postload()
-{
- int i;
- for (i = 0; i < 6; i++)
- i386_load_segment_descriptor(i);
- CHANGE_PC(cpustate,cpustate->eip);
-}
-
-i386_state *I386_OPS_BASE::i386_common_init(int tlbsize)
-{
- int i, j;
- static const int regs8[8] = {AL,CL,DL,BL,AH,CH,DH,BH};
- static const int regs16[8] = {AX,CX,DX,BX,SP,BP,SI,DI};
- static const int regs32[8] = {EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI};
- cpustate = (i386_state *)malloc(sizeof(i386_state));
-
- assert((sizeof(XMM_REG)/sizeof(double)) == 2);
-
- build_cycle_table();
-
- for( i=0; i < 256; i++ ) {
- int c=0;
- for( j=0; j < 8; j++ ) {
- if( i & (1 << j) )
- c++;
- }
- i386_parity_table[i] = ~(c & 0x1) & 0x1;
- }
-
- for( i=0; i < 256; i++ ) {
- i386_MODRM_table[i].reg.b = regs8[(i >> 3) & 0x7];
- i386_MODRM_table[i].reg.w = regs16[(i >> 3) & 0x7];
- i386_MODRM_table[i].reg.d = regs32[(i >> 3) & 0x7];
-
- i386_MODRM_table[i].rm.b = regs8[i & 0x7];
- i386_MODRM_table[i].rm.w = regs16[i & 0x7];
- i386_MODRM_table[i].rm.d = regs32[i & 0x7];
- }
-
- cpustate->vtlb = vtlb_alloc(AS_PROGRAM, 0, tlbsize);
- cpustate->smi = false;
- cpustate->lock = false;
-
-// i386_interface *intf = (i386_interface *) device->static_config();
-//
-// if (intf != NULL)
-// cpustate->smiact.resolve(intf->smiact, *device);
-// else
-// memset(&cpustate->smiact, 0, sizeof(cpustate->smiact));
-
- zero_state();
-
- return cpustate;
-}
-
-CPU_INIT( i386 )
-{
- i386_common_init(32);
- build_opcode_table(OP_I386);
- cpustate->cycle_table_rm = cycle_table_rm[CPU_CYCLES_I386];
- cpustate->cycle_table_pm = cycle_table_pm[CPU_CYCLES_I386];
- return cpustate;
-}
-
-#include "./i386_ops_table.h"
-
-void I386_OPS_BASE::build_opcode_table(UINT32 features)
-{
- int i;
- i386_state *_cpustate = cpustate;
- for (i=0; i < 256; i++)
- {
- _cpustate->opcode_table1_16[i] = I386OP(invalid);
- _cpustate->opcode_table1_32[i] = I386OP(invalid);
- _cpustate->opcode_table2_16[i] = I386OP(invalid);
- _cpustate->opcode_table2_32[i] = I386OP(invalid);
- _cpustate->opcode_table366_16[i] = I386OP(invalid);
- _cpustate->opcode_table366_32[i] = I386OP(invalid);
- _cpustate->opcode_table3f2_16[i] = I386OP(invalid);
- _cpustate->opcode_table3f2_32[i] = I386OP(invalid);
- _cpustate->opcode_table3f3_16[i] = I386OP(invalid);
- _cpustate->opcode_table3f3_32[i] = I386OP(invalid);
- _cpustate->lock_table[0][i] = false;
- _cpustate->lock_table[1][i] = false;
- }
-
- for (i=0; i < sizeof(x86_opcode_table)/sizeof(X86_OPCODE); i++)
- {
- const X86_OPCODE *op = &x86_opcode_table[i];
-
- if ((op->flags & features))
- {
- if (op->flags & OP_2BYTE)
- {
- _cpustate->opcode_table2_32[op->opcode] = op->handler32;
- _cpustate->opcode_table2_16[op->opcode] = op->handler16;
- _cpustate->opcode_table366_32[op->opcode] = op->handler32;
- _cpustate->opcode_table366_16[op->opcode] = op->handler16;
- _cpustate->lock_table[1][op->opcode] = op->lockable;
- }
- else if (op->flags & OP_3BYTE66)
- {
- _cpustate->opcode_table366_32[op->opcode] = op->handler32;
- _cpustate->opcode_table366_16[op->opcode] = op->handler16;
- }
- else if (op->flags & OP_3BYTEF2)
- {
- _cpustate->opcode_table3f2_32[op->opcode] = op->handler32;
- _cpustate->opcode_table3f2_16[op->opcode] = op->handler16;
- }
- else if (op->flags & OP_3BYTEF3)
- {
- _cpustate->opcode_table3f3_32[op->opcode] = op->handler32;
- _cpustate->opcode_table3f3_16[op->opcode] = op->handler16;
- }
- else if (op->flags & OP_3BYTE38)
- {
- _cpustate->opcode_table338_32[op->opcode] = op->handler32;
- _cpustate->opcode_table338_16[op->opcode] = op->handler16;
- }
- else if (op->flags & OP_3BYTE3A)
- {
- _cpustate->opcode_table33a_32[op->opcode] = op->handler32;
- _cpustate->opcode_table33a_16[op->opcode] = op->handler16;
- }
- else if (op->flags & OP_4BYTE3866)
- {
- _cpustate->opcode_table46638_32[op->opcode] = op->handler32;
- _cpustate->opcode_table46638_16[op->opcode] = op->handler16;
- }
- else if (op->flags & OP_4BYTE3A66)
- {
- _cpustate->opcode_table4663a_32[op->opcode] = op->handler32;
- _cpustate->opcode_table4663a_16[op->opcode] = op->handler16;
- }
- else if (op->flags & OP_4BYTE38F2)
- {
- _cpustate->opcode_table4f238_32[op->opcode] = op->handler32;
- _cpustate->opcode_table4f238_16[op->opcode] = op->handler16;
- }
- else if (op->flags & OP_4BYTE3AF2)
- {
- _cpustate->opcode_table4f23a_32[op->opcode] = op->handler32;
- _cpustate->opcode_table4f23a_16[op->opcode] = op->handler16;
- }
- else if (op->flags & OP_4BYTE38F3)
- {
- _cpustate->opcode_table4f338_32[op->opcode] = op->handler32;
- _cpustate->opcode_table4f338_16[op->opcode] = op->handler16;
- }
- else
- {
- _cpustate->opcode_table1_32[op->opcode] = op->handler32;
- _cpustate->opcode_table1_16[op->opcode] = op->handler16;
- _cpustate->lock_table[0][op->opcode] = op->lockable;
- }
- }
- }
-}
-
-void I386_OPS_BASE::zero_state()
-{
- memset( &cpustate->reg, 0, sizeof(cpustate->reg) );
- memset( cpustate->sreg, 0, sizeof(cpustate->sreg) );
- cpustate->eip = 0;
- cpustate->pc = 0;
- cpustate->prev_eip = 0;
- cpustate->eflags = 0;
- cpustate->eflags_mask = 0;
- cpustate->CF = 0;
- cpustate->DF = 0;
- cpustate->SF = 0;
- cpustate->OF = 0;
- cpustate->ZF = 0;
- cpustate->PF = 0;
- cpustate->AF = 0;
- cpustate->IF = 0;
- cpustate->TF = 0;
- cpustate->IOP1 = 0;
- cpustate->IOP2 = 0;
- cpustate->NT = 0;
- cpustate->RF = 0;
- cpustate->VM = 0;
- cpustate->AC = 0;
- cpustate->VIF = 0;
- cpustate->VIP = 0;
- cpustate->ID = 0;
- cpustate->CPL = 0;
- cpustate->performed_intersegment_jump = 0;
- cpustate->delayed_interrupt_enable = 0;
- memset( cpustate->cr, 0, sizeof(cpustate->cr) );
- memset( cpustate->dr, 0, sizeof(cpustate->dr) );
- memset( cpustate->tr, 0, sizeof(cpustate->tr) );
- memset( &cpustate->gdtr, 0, sizeof(cpustate->gdtr) );
- memset( &cpustate->idtr, 0, sizeof(cpustate->idtr) );
- memset( &cpustate->task, 0, sizeof(cpustate->task) );
- memset( &cpustate->ldtr, 0, sizeof(cpustate->ldtr) );
- cpustate->ext = 0;
- cpustate->halted = 0;
- cpustate->operand_size = 0;
- cpustate->xmm_operand_size = 0;
- cpustate->address_size = 0;
- cpustate->operand_prefix = 0;
- cpustate->address_prefix = 0;
- cpustate->segment_prefix = 0;
- cpustate->segment_override = 0;
- cpustate->cycles = 0;
- cpustate->base_cycles = 0;
- cpustate->opcode = 0;
- cpustate->irq_state = 0;
- cpustate->a20_mask = 0;
- cpustate->cpuid_max_input_value_eax = 0;
- cpustate->cpuid_id0 = 0;
- cpustate->cpuid_id1 = 0;
- cpustate->cpuid_id2 = 0;
- cpustate->cpu_version = 0;
- cpustate->feature_flags = 0;
- cpustate->tsc = 0;
- cpustate->perfctr[0] = cpustate->perfctr[1] = 0;
- memset( cpustate->x87_reg, 0, sizeof(cpustate->x87_reg) );
- cpustate->x87_cw = 0;
- cpustate->x87_sw = 0;
- cpustate->x87_tw = 0;
- cpustate->x87_data_ptr = 0;
- cpustate->x87_inst_ptr = 0;
- cpustate->x87_opcode = 0;
- memset( cpustate->sse_reg, 0, sizeof(cpustate->sse_reg) );
- cpustate->mxcsr = 0;
- cpustate->smm = false;
- cpustate->smi = false;
- cpustate->smi_latched = false;
- cpustate->nmi_masked = false;
- cpustate->nmi_latched = false;
- cpustate->smbase = 0;
-#ifdef DEBUG_MISSING_OPCODE
- memset( cpustate->opcode_bytes, 0, sizeof(cpustate->opcode_bytes) );
- cpustate->opcode_pc = 0;
- cpustate->opcode_bytes_length = 0;
-#endif
-}
-
-CPU_RESET( i386 )
-{
- zero_state();
- vtlb_flush_dynamic(cpustate->vtlb);
-
- cpustate->sreg[CS].selector = 0xf000;
- cpustate->sreg[CS].base = 0xffff0000;
- cpustate->sreg[CS].limit = 0xffff;
- cpustate->sreg[CS].flags = 0x9b;
- cpustate->sreg[CS].valid = true;
-
- cpustate->sreg[DS].base = cpustate->sreg[ES].base = cpustate->sreg[FS].base = cpustate->sreg[GS].base = cpustate->sreg[SS].base = 0x00000000;
- cpustate->sreg[DS].limit = cpustate->sreg[ES].limit = cpustate->sreg[FS].limit = cpustate->sreg[GS].limit = cpustate->sreg[SS].limit = 0xffff;
- cpustate->sreg[DS].flags = cpustate->sreg[ES].flags = cpustate->sreg[FS].flags = cpustate->sreg[GS].flags = cpustate->sreg[SS].flags = 0x0092;
- cpustate->sreg[DS].valid = cpustate->sreg[ES].valid = cpustate->sreg[FS].valid = cpustate->sreg[GS].valid = cpustate->sreg[SS].valid =true;
-
- cpustate->idtr.base = 0;
- cpustate->idtr.limit = 0x3ff;
- cpustate->smm = false;
- cpustate->smi_latched = false;
- cpustate->nmi_masked = false;
- cpustate->nmi_latched = false;
-
- cpustate->a20_mask = ~0;
-
- cpustate->cr[0] = 0x7fffffe0; // reserved bits set to 1
- cpustate->eflags = 0;
- cpustate->eflags_mask = 0x00037fd7;
- cpustate->eip = 0xfff0;
-
- // [11:8] Family
- // [ 7:4] Model
- // [ 3:0] Stepping ID
- // Family 3 (386), Model 0 (DX), Stepping 8 (D1)
- REG32(EAX) = 0;
- REG32(EDX) = (3 << 8) | (0 << 4) | (8);
-
- cpustate->CPL = 0;
-
- CHANGE_PC(cpustate,cpustate->eip);
-}
-
-void I386_OPS_BASE::pentium_smi()
-{
- UINT32 smram_state = cpustate->smbase + 0xfe00;
- UINT32 old_cr0 = cpustate->cr[0];
- UINT32 old_flags = get_flags(cpustate);
-
- if(cpustate->smm)
- return;
-
- cpustate->cr[0] &= ~(0x8000000d);
- set_flags(cpustate, 2);
-// if(!cpustate->smiact.isnull())
-// cpustate->smiact(true);
- cpustate->smm = true;
- cpustate->smi_latched = false;
-
- // save state
- WRITE32(cpustate, cpustate->cr[4], smram_state+SMRAM_IP5_CR4);
- WRITE32(cpustate, cpustate->sreg[ES].limit, smram_state+SMRAM_IP5_ESLIM);
- WRITE32(cpustate, cpustate->sreg[ES].base, smram_state+SMRAM_IP5_ESBASE);
- WRITE32(cpustate, cpustate->sreg[ES].flags, smram_state+SMRAM_IP5_ESACC);
- WRITE32(cpustate, cpustate->sreg[CS].limit, smram_state+SMRAM_IP5_CSLIM);
- WRITE32(cpustate, cpustate->sreg[CS].base, smram_state+SMRAM_IP5_CSBASE);
- WRITE32(cpustate, cpustate->sreg[CS].flags, smram_state+SMRAM_IP5_CSACC);
- WRITE32(cpustate, cpustate->sreg[SS].limit, smram_state+SMRAM_IP5_SSLIM);
- WRITE32(cpustate, cpustate->sreg[SS].base, smram_state+SMRAM_IP5_SSBASE);
- WRITE32(cpustate, cpustate->sreg[SS].flags, smram_state+SMRAM_IP5_SSACC);
- WRITE32(cpustate, cpustate->sreg[DS].limit, smram_state+SMRAM_IP5_DSLIM);
- WRITE32(cpustate, cpustate->sreg[DS].base, smram_state+SMRAM_IP5_DSBASE);
- WRITE32(cpustate, cpustate->sreg[DS].flags, smram_state+SMRAM_IP5_DSACC);
- WRITE32(cpustate, cpustate->sreg[FS].limit, smram_state+SMRAM_IP5_FSLIM);
- WRITE32(cpustate, cpustate->sreg[FS].base, smram_state+SMRAM_IP5_FSBASE);
- WRITE32(cpustate, cpustate->sreg[FS].flags, smram_state+SMRAM_IP5_FSACC);
- WRITE32(cpustate, cpustate->sreg[GS].limit, smram_state+SMRAM_IP5_GSLIM);
- WRITE32(cpustate, cpustate->sreg[GS].base, smram_state+SMRAM_IP5_GSBASE);
- WRITE32(cpustate, cpustate->sreg[GS].flags, smram_state+SMRAM_IP5_GSACC);
- WRITE32(cpustate, cpustate->ldtr.flags, smram_state+SMRAM_IP5_LDTACC);
- WRITE32(cpustate, cpustate->ldtr.limit, smram_state+SMRAM_IP5_LDTLIM);
- WRITE32(cpustate, cpustate->ldtr.base, smram_state+SMRAM_IP5_LDTBASE);
- WRITE32(cpustate, cpustate->gdtr.limit, smram_state+SMRAM_IP5_GDTLIM);
- WRITE32(cpustate, cpustate->gdtr.base, smram_state+SMRAM_IP5_GDTBASE);
- WRITE32(cpustate, cpustate->idtr.limit, smram_state+SMRAM_IP5_IDTLIM);
- WRITE32(cpustate, cpustate->idtr.base, smram_state+SMRAM_IP5_IDTBASE);
- WRITE32(cpustate, cpustate->task.limit, smram_state+SMRAM_IP5_TRLIM);
- WRITE32(cpustate, cpustate->task.base, smram_state+SMRAM_IP5_TRBASE);
- WRITE32(cpustate, cpustate->task.flags, smram_state+SMRAM_IP5_TRACC);
-
- WRITE32(cpustate, cpustate->sreg[ES].selector, smram_state+SMRAM_ES);
- WRITE32(cpustate, cpustate->sreg[CS].selector, smram_state+SMRAM_CS);
- WRITE32(cpustate, cpustate->sreg[SS].selector, smram_state+SMRAM_SS);
- WRITE32(cpustate, cpustate->sreg[DS].selector, smram_state+SMRAM_DS);
- WRITE32(cpustate, cpustate->sreg[FS].selector, smram_state+SMRAM_FS);
- WRITE32(cpustate, cpustate->sreg[GS].selector, smram_state+SMRAM_GS);
- WRITE32(cpustate, cpustate->ldtr.segment, smram_state+SMRAM_LDTR);
- WRITE32(cpustate, cpustate->task.segment, smram_state+SMRAM_TR);
-
- WRITE32(cpustate, cpustate->dr[7], smram_state+SMRAM_DR7);
- WRITE32(cpustate, cpustate->dr[6], smram_state+SMRAM_DR6);
- WRITE32(cpustate, REG32(EAX), smram_state+SMRAM_EAX);
- WRITE32(cpustate, REG32(ECX), smram_state+SMRAM_ECX);
- WRITE32(cpustate, REG32(EDX), smram_state+SMRAM_EDX);
- WRITE32(cpustate, REG32(EBX), smram_state+SMRAM_EBX);
- WRITE32(cpustate, REG32(ESP), smram_state+SMRAM_ESP);
- WRITE32(cpustate, REG32(EBP), smram_state+SMRAM_EBP);
- WRITE32(cpustate, REG32(ESI), smram_state+SMRAM_ESI);
- WRITE32(cpustate, REG32(EDI), smram_state+SMRAM_EDI);
- WRITE32(cpustate, cpustate->eip, smram_state+SMRAM_EIP);
- WRITE32(cpustate, old_flags, smram_state+SMRAM_EAX);
- WRITE32(cpustate, cpustate->cr[3], smram_state+SMRAM_CR3);
- WRITE32(cpustate, old_cr0, smram_state+SMRAM_CR0);
-
- cpustate->sreg[DS].selector = cpustate->sreg[ES].selector = cpustate->sreg[FS].selector = cpustate->sreg[GS].selector = cpustate->sreg[SS].selector = 0;
- cpustate->sreg[DS].base = cpustate->sreg[ES].base = cpustate->sreg[FS].base = cpustate->sreg[GS].base = cpustate->sreg[SS].base = 0x00000000;
- cpustate->sreg[DS].limit = cpustate->sreg[ES].limit = cpustate->sreg[FS].limit = cpustate->sreg[GS].limit = cpustate->sreg[SS].limit = 0xffffffff;
- cpustate->sreg[DS].flags = cpustate->sreg[ES].flags = cpustate->sreg[FS].flags = cpustate->sreg[GS].flags = cpustate->sreg[SS].flags = 0x8093;
- cpustate->sreg[DS].valid = cpustate->sreg[ES].valid = cpustate->sreg[FS].valid = cpustate->sreg[GS].valid = cpustate->sreg[SS].valid =true;
- cpustate->sreg[CS].selector = 0x3000; // pentium only, ppro sel = smbase >> 4
- cpustate->sreg[CS].base = cpustate->smbase;
- cpustate->sreg[CS].limit = 0xffffffff;
- cpustate->sreg[CS].flags = 0x809b;
- cpustate->sreg[CS].valid = true;
- cpustate->cr[4] = 0;
- cpustate->dr[7] = 0x400;
- cpustate->eip = 0x8000;
-
- cpustate->nmi_masked = true;
- CHANGE_PC(cpustate,cpustate->eip);
-}
-
-void I386_OPS_BASE::i386_set_irq_line(int irqline, int state)
-{
- if (state != CLEAR_LINE && cpustate->halted)
- {
- cpustate->halted = 0;
- }
-
- if ( irqline == INPUT_LINE_NMI )
- {
- /* NMI (I do not think that this is 100% right) */
- if(cpustate->nmi_masked)
- {
- cpustate->nmi_latched = true;
- return;
- }
- if ( state )
- i386_trap(cpustate,2, 1, 0);
- }
- else
- {
- cpustate->irq_state = state;
- }
-}
-
-void I386_OPS_BASE::i386_set_a20_line(int state)
-{
- if (state)
- {
- cpustate->a20_mask = ~0;
- }
- else
- {
- cpustate->a20_mask = ~(1 << 20);
- }
- // TODO: how does A20M and the tlb interact
- vtlb_flush_dynamic(cpustate->vtlb);
-}
-
-// BASE execution : EXECUTE without DMA, BIOS and debugger.
-int I386_OPS_BASE::cpu_execute_i386(int cycle)
-{
- CHANGE_PC(cpustate,cpustate->eip);
-
- if (cpustate->halted || cpustate->busreq)
- {
- if (cycles == -1) {
- int passed_cycles = max(1, cpustate->extra_cycles);
- // this is main cpu, cpustate->cycles is not used
- /*cpustate->cycles = */cpustate->extra_cycles = 0;
- cpustate->tsc += passed_cycles;
- return passed_cycles;
- } else {
- cpustate->cycles += cycles;
- cpustate->base_cycles = cpustate->cycles;
-
- /* adjust for any interrupts that came in */
- cpustate->cycles -= cpustate->extra_cycles;
- cpustate->extra_cycles = 0;
-
- /* if busreq is raised, spin cpu while remained clock */
- if (cpustate->cycles > 0) {
- cpustate->cycles = 0;
- }
- int passed_cycles = cpustate->base_cycles - cpustate->cycles;
- cpustate->tsc += passed_cycles;
- return passed_cycles;
- }
- }
-
- if (cycles == -1) {
- cpustate->cycles = 1;
- } else {
- cpustate->cycles += cycles;
- }
- cpustate->base_cycles = cpustate->cycles;
-
- /* adjust for any interrupts that came in */
- cpustate->cycles -= cpustate->extra_cycles;
- cpustate->extra_cycles = 0;
-
- while( cpustate->cycles > 0 && !cpustate->busreq )
- {
- i386_check_irq_line(cpustate);
- cpustate->operand_size = cpustate->sreg[CS].d;
- cpustate->xmm_operand_size = 0;
- cpustate->address_size = cpustate->sreg[CS].d;
- cpustate->operand_prefix = 0;
- cpustate->address_prefix = 0;
-
- cpustate->ext = 1;
- int old_tf = cpustate->TF;
-
- cpustate->segment_prefix = 0;
- cpustate->prev_eip = cpustate->eip;
- cpustate->prev_pc = cpustate->pc;
-
- if(cpustate->delayed_interrupt_enable != 0)
- {
- cpustate->IF = 1;
- cpustate->delayed_interrupt_enable = 0;
- }
-#ifdef DEBUG_MISSING_OPCODE
- cpustate->opcode_bytes_length = 0;
- cpustate->opcode_pc = cpustate->pc;
-#endif
- try
- {
- I386OP(decode_opcode)(cpustate);
- if(cpustate->TF && old_tf)
- {
- cpustate->prev_eip = cpustate->eip;
- cpustate->ext = 1;
- i386_trap(cpustate,1,0,0);
- }
- if(cpustate->lock && (cpustate->opcode != 0xf0))
- cpustate->lock = false;
- }
- catch(UINT64 e)
- {
- cpustate->ext = 1;
- i386_trap_with_error(cpustate,e&0xffffffff,0,0,e>>32);
- }
- /* adjust for any interrupts that came in */
- cpustate->cycles -= cpustate->extra_cycles;
- cpustate->extra_cycles = 0;
- }
-
- /* if busreq is raised, spin cpu while remained clock */
- if (cpustate->cycles > 0 && cpustate->busreq) {
- cpustate->cycles = 0;
- }
- int passed_cycles = cpustate->base_cycles - cpustate->cycles;
- cpustate->tsc += passed_cycles;
- return passed_cycles;
-}
-
-/*************************************************************************/
-
-int I386_OPS_BASE::cpu_translate_i386(void *cpudevice, address_spacenum space, int intention, offs_t *address)
-{
- i386_state *cpu_state = (i386_state *)cpudevice;
- int ret = TRUE;
- if(space == AS_PROGRAM)
- ret = i386_translate_address(cpu_state, intention, address, NULL);
- *address &= cpu_state->a20_mask;
- return ret;
-}
-
-/*****************************************************************************/
-/* Intel 486 */
-
-
-CPU_INIT( i486 )
-{
- i386_common_init(32);
- build_opcode_table(OP_I386 | OP_FPU | OP_I486);
- build_x87_opcode_table();
- cpustate->cycle_table_rm = cycle_table_rm[CPU_CYCLES_I486];
- cpustate->cycle_table_pm = cycle_table_pm[CPU_CYCLES_I486];
- return cpustate;
-}
-
-CPU_RESET( i486 )
-{
- zero_state();
- vtlb_flush_dynamic(cpustate->vtlb);
-
- cpustate->sreg[CS].selector = 0xf000;
- cpustate->sreg[CS].base = 0xffff0000;
- cpustate->sreg[CS].limit = 0xffff;
- cpustate->sreg[CS].flags = 0x009b;
-
- cpustate->sreg[DS].base = cpustate->sreg[ES].base = cpustate->sreg[FS].base = cpustate->sreg[GS].base = cpustate->sreg[SS].base = 0x00000000;
- cpustate->sreg[DS].limit = cpustate->sreg[ES].limit = cpustate->sreg[FS].limit = cpustate->sreg[GS].limit = cpustate->sreg[SS].limit = 0xffff;
- cpustate->sreg[DS].flags = cpustate->sreg[ES].flags = cpustate->sreg[FS].flags = cpustate->sreg[GS].flags = cpustate->sreg[SS].flags = 0x0092;
-
- cpustate->idtr.base = 0;
- cpustate->idtr.limit = 0x3ff;
-
- cpustate->a20_mask = ~0;
-
- cpustate->cr[0] = 0x00000010;
- cpustate->eflags = 0;
- cpustate->eflags_mask = 0x00077fd7;
- cpustate->eip = 0xfff0;
- cpustate->smm = false;
- cpustate->smi_latched = false;
- cpustate->nmi_masked = false;
- cpustate->nmi_latched = false;
-
- x87_reset(cpustate);
-
- // [11:8] Family
- // [ 7:4] Model
- // [ 3:0] Stepping ID
- // Family 4 (486), Model 0/1 (DX), Stepping 3
- REG32(EAX) = 0;
- REG32(EDX) = (4 << 8) | (0 << 4) | (3);
-
- CHANGE_PC(cpustate,cpustate->eip);
-}
-
-/*****************************************************************************/
-/* Pentium */
-
-
-CPU_INIT( pentium )
-{
- // 64 dtlb small, 8 dtlb large, 32 itlb
- i386_common_init(96);
- build_opcode_table(OP_I386 | OP_FPU | OP_I486 | OP_PENTIUM);
- build_x87_opcode_table();
- cpustate->cycle_table_rm = cycle_table_rm[CPU_CYCLES_PENTIUM];
- cpustate->cycle_table_pm = cycle_table_pm[CPU_CYCLES_PENTIUM];
- return cpustate;
-}
-
-CPU_RESET( pentium )
-{
- zero_state();
- vtlb_flush_dynamic(cpustate->vtlb);
-
- cpustate->sreg[CS].selector = 0xf000;
- cpustate->sreg[CS].base = 0xffff0000;
- cpustate->sreg[CS].limit = 0xffff;
- cpustate->sreg[CS].flags = 0x009b;
-
- cpustate->sreg[DS].base = cpustate->sreg[ES].base = cpustate->sreg[FS].base = cpustate->sreg[GS].base = cpustate->sreg[SS].base = 0x00000000;
- cpustate->sreg[DS].limit = cpustate->sreg[ES].limit = cpustate->sreg[FS].limit = cpustate->sreg[GS].limit = cpustate->sreg[SS].limit = 0xffff;
- cpustate->sreg[DS].flags = cpustate->sreg[ES].flags = cpustate->sreg[FS].flags = cpustate->sreg[GS].flags = cpustate->sreg[SS].flags = 0x0092;
-
- cpustate->idtr.base = 0;
- cpustate->idtr.limit = 0x3ff;
-
- cpustate->a20_mask = ~0;
-
- cpustate->cr[0] = 0x00000010;
- cpustate->eflags = 0x00200000;
- cpustate->eflags_mask = 0x003f7fd7;
- cpustate->eip = 0xfff0;
- cpustate->mxcsr = 0x1f80;
- cpustate->smm = false;
- cpustate->smi_latched = false;
- cpustate->smbase = 0x30000;
- cpustate->nmi_masked = false;
- cpustate->nmi_latched = false;
-
- x87_reset(cpustate);
-
- // [11:8] Family
- // [ 7:4] Model
- // [ 3:0] Stepping ID
- // Family 5 (Pentium), Model 2 (75 - 200MHz), Stepping 5
- REG32(EAX) = 0;
- REG32(EDX) = (5 << 8) | (2 << 4) | (5);
-
- cpustate->cpuid_id0 = 0x756e6547; // Genu
- cpustate->cpuid_id1 = 0x49656e69; // ineI
- cpustate->cpuid_id2 = 0x6c65746e; // ntel
-
- cpustate->cpuid_max_input_value_eax = 0x01;
- cpustate->cpu_version = REG32(EDX);
-
- // [ 0:0] FPU on chip
- // [ 2:2] I/O breakpoints
- // [ 4:4] Time Stamp Counter
- // [ 5:5] Pentium CPU style model specific registers
- // [ 7:7] Machine Check Exception
- // [ 8:8] CMPXCHG8B instruction
- cpustate->feature_flags = 0x000001bf;
-
- CHANGE_PC(cpustate,cpustate->eip);
-}
-
-/*****************************************************************************/
-/* Cyrix MediaGX */
-
-
-CPU_INIT( mediagx )
-{
- // probably 32 unified
- i386_common_init(32);
- build_x87_opcode_table();
- build_opcode_table(OP_I386 | OP_FPU | OP_I486 | OP_PENTIUM | OP_CYRIX);
- cpustate->cycle_table_rm = cycle_table_rm[CPU_CYCLES_MEDIAGX];
- cpustate->cycle_table_pm = cycle_table_pm[CPU_CYCLES_MEDIAGX];
- return cpustate;
-}
-
-CPU_RESET( mediagx )
-{
- zero_state();
- vtlb_flush_dynamic(cpustate->vtlb);
-
- cpustate->sreg[CS].selector = 0xf000;
- cpustate->sreg[CS].base = 0xffff0000;
- cpustate->sreg[CS].limit = 0xffff;
- cpustate->sreg[CS].flags = 0x009b;
-
- cpustate->sreg[DS].base = cpustate->sreg[ES].base = cpustate->sreg[FS].base = cpustate->sreg[GS].base = cpustate->sreg[SS].base = 0x00000000;
- cpustate->sreg[DS].limit = cpustate->sreg[ES].limit = cpustate->sreg[FS].limit = cpustate->sreg[GS].limit = cpustate->sreg[SS].limit = 0xffff;
- cpustate->sreg[DS].flags = cpustate->sreg[ES].flags = cpustate->sreg[FS].flags = cpustate->sreg[GS].flags = cpustate->sreg[SS].flags = 0x0092;
-
- cpustate->idtr.base = 0;
- cpustate->idtr.limit = 0x3ff;
-
- cpustate->a20_mask = ~0;
-
- cpustate->cr[0] = 0x00000010;
- cpustate->eflags = 0x00200000;
- cpustate->eflags_mask = 0x00277fd7; /* TODO: is this correct? */
- cpustate->eip = 0xfff0;
- cpustate->smm = false;
- cpustate->smi_latched = false;
- cpustate->nmi_masked = false;
- cpustate->nmi_latched = false;
-
- x87_reset(cpustate);
-
- // [11:8] Family
- // [ 7:4] Model
- // [ 3:0] Stepping ID
- // Family 4, Model 4 (MediaGX)
- REG32(EAX) = 0;
- REG32(EDX) = (4 << 8) | (4 << 4) | (1); /* TODO: is this correct? */
-
- cpustate->cpuid_id0 = 0x69727943; // Cyri
- cpustate->cpuid_id1 = 0x736e4978; // xIns
- cpustate->cpuid_id2 = 0x6d616574; // tead
-
- cpustate->cpuid_max_input_value_eax = 0x01;
- cpustate->cpu_version = REG32(EDX);
-
- // [ 0:0] FPU on chip
- cpustate->feature_flags = 0x00000001;
-
- CHANGE_PC(cpustate,cpustate->eip);
-}
-
-/*****************************************************************************/
-/* Intel Pentium Pro */
-
-CPU_INIT( pentium_pro )
-{
- // 64 dtlb small, 32 itlb
- i386_common_init(96);
- build_x87_opcode_table();
- build_opcode_table(OP_I386 | OP_FPU | OP_I486 | OP_PENTIUM | OP_PPRO);
- cpustate->cycle_table_rm = cycle_table_rm[CPU_CYCLES_PENTIUM]; // TODO: generate own cycle tables
- cpustate->cycle_table_pm = cycle_table_pm[CPU_CYCLES_PENTIUM]; // TODO: generate own cycle tables
- return cpustate;
-}
-
-CPU_RESET( pentium_pro )
-{
- zero_state();
- vtlb_flush_dynamic(cpustate->vtlb);
-
- cpustate->sreg[CS].selector = 0xf000;
- cpustate->sreg[CS].base = 0xffff0000;
- cpustate->sreg[CS].limit = 0xffff;
- cpustate->sreg[CS].flags = 0x009b;
-
- cpustate->sreg[DS].base = cpustate->sreg[ES].base = cpustate->sreg[FS].base = cpustate->sreg[GS].base = cpustate->sreg[SS].base = 0x00000000;
- cpustate->sreg[DS].limit = cpustate->sreg[ES].limit = cpustate->sreg[FS].limit = cpustate->sreg[GS].limit = cpustate->sreg[SS].limit = 0xffff;
- cpustate->sreg[DS].flags = cpustate->sreg[ES].flags = cpustate->sreg[FS].flags = cpustate->sreg[GS].flags = cpustate->sreg[SS].flags = 0x0092;
-
- cpustate->idtr.base = 0;
- cpustate->idtr.limit = 0x3ff;
-
- cpustate->a20_mask = ~0;
-
- cpustate->cr[0] = 0x60000010;
- cpustate->eflags = 0x00200000;
- cpustate->eflags_mask = 0x00277fd7; /* TODO: is this correct? */
- cpustate->eip = 0xfff0;
- cpustate->mxcsr = 0x1f80;
- cpustate->smm = false;
- cpustate->smi_latched = false;
- cpustate->smbase = 0x30000;
- cpustate->nmi_masked = false;
- cpustate->nmi_latched = false;
-
- x87_reset(cpustate);
-
- // [11:8] Family
- // [ 7:4] Model
- // [ 3:0] Stepping ID
- // Family 6, Model 1 (Pentium Pro)
- REG32(EAX) = 0;
- REG32(EDX) = (6 << 8) | (1 << 4) | (1); /* TODO: is this correct? */
-
- cpustate->cpuid_id0 = 0x756e6547; // Genu
- cpustate->cpuid_id1 = 0x49656e69; // ineI
- cpustate->cpuid_id2 = 0x6c65746e; // ntel
-
- cpustate->cpuid_max_input_value_eax = 0x02;
- cpustate->cpu_version = REG32(EDX);
-
- // [ 0:0] FPU on chip
- // [ 2:2] I/O breakpoints
- // [ 4:4] Time Stamp Counter
- // [ 5:5] Pentium CPU style model specific registers
- // [ 7:7] Machine Check Exception
- // [ 8:8] CMPXCHG8B instruction
- // [15:15] CMOV and FCMOV
- // No MMX
- cpustate->feature_flags = 0x000081bf;
-
- CHANGE_PC(cpustate,cpustate->eip);
-}
-
-/*****************************************************************************/
-/* Intel Pentium MMX */
-
-CPU_INIT( pentium_mmx )
-{
- // 64 dtlb small, 8 dtlb large, 32 itlb small, 2 itlb large
- i386_common_init(96);
- build_x87_opcode_table();
- build_opcode_table(OP_I386 | OP_FPU | OP_I486 | OP_PENTIUM | OP_MMX);
- cpustate->cycle_table_rm = cycle_table_rm[CPU_CYCLES_PENTIUM]; // TODO: generate own cycle tables
- cpustate->cycle_table_pm = cycle_table_pm[CPU_CYCLES_PENTIUM]; // TODO: generate own cycle tables
- return cpustate;
-}
-
-CPU_RESET( pentium_mmx )
-{
- zero_state();
- vtlb_flush_dynamic(cpustate->vtlb);
-
- cpustate->sreg[CS].selector = 0xf000;
- cpustate->sreg[CS].base = 0xffff0000;
- cpustate->sreg[CS].limit = 0xffff;
- cpustate->sreg[CS].flags = 0x009b;
-
- cpustate->sreg[DS].base = cpustate->sreg[ES].base = cpustate->sreg[FS].base = cpustate->sreg[GS].base = cpustate->sreg[SS].base = 0x00000000;
- cpustate->sreg[DS].limit = cpustate->sreg[ES].limit = cpustate->sreg[FS].limit = cpustate->sreg[GS].limit = cpustate->sreg[SS].limit = 0xffff;
- cpustate->sreg[DS].flags = cpustate->sreg[ES].flags = cpustate->sreg[FS].flags = cpustate->sreg[GS].flags = cpustate->sreg[SS].flags = 0x0092;
-
- cpustate->idtr.base = 0;
- cpustate->idtr.limit = 0x3ff;
-
- cpustate->a20_mask = ~0;
-
- cpustate->cr[0] = 0x60000010;
- cpustate->eflags = 0x00200000;
- cpustate->eflags_mask = 0x00277fd7; /* TODO: is this correct? */
- cpustate->eip = 0xfff0;
- cpustate->mxcsr = 0x1f80;
- cpustate->smm = false;
- cpustate->smi_latched = false;
- cpustate->smbase = 0x30000;
- cpustate->nmi_masked = false;
- cpustate->nmi_latched = false;
-
- x87_reset(cpustate);
-
- // [11:8] Family
- // [ 7:4] Model
- // [ 3:0] Stepping ID
- // Family 5, Model 4 (P55C)
- REG32(EAX) = 0;
- REG32(EDX) = (5 << 8) | (4 << 4) | (1);
-
- cpustate->cpuid_id0 = 0x756e6547; // Genu
- cpustate->cpuid_id1 = 0x49656e69; // ineI
- cpustate->cpuid_id2 = 0x6c65746e; // ntel
-
- cpustate->cpuid_max_input_value_eax = 0x01;
- cpustate->cpu_version = REG32(EDX);
-
- // [ 0:0] FPU on chip
- // [ 2:2] I/O breakpoints
- // [ 4:4] Time Stamp Counter
- // [ 5:5] Pentium CPU style model specific registers
- // [ 7:7] Machine Check Exception
- // [ 8:8] CMPXCHG8B instruction
- // [23:23] MMX instructions
- cpustate->feature_flags = 0x008001bf;
-
- CHANGE_PC(cpustate,cpustate->eip);
-}
-
-/*****************************************************************************/
-/* Intel Pentium II */
-
-CPU_INIT( pentium2 )
-{
- // 64 dtlb small, 8 dtlb large, 32 itlb small, 2 itlb large
- i386_common_init(96);
- build_x87_opcode_table(cpustate);
- build_opcode_table(OP_I386 | OP_FPU | OP_I486 | OP_PENTIUM | OP_PPRO | OP_MMX);
- cpustate->cycle_table_rm = cycle_table_rm[CPU_CYCLES_PENTIUM]; // TODO: generate own cycle tables
- cpustate->cycle_table_pm = cycle_table_pm[CPU_CYCLES_PENTIUM]; // TODO: generate own cycle tables
- return cpustate;
-}
-
-CPU_RESET( pentium2 )
-{
- zero_state();
- vtlb_flush_dynamic(cpustate->vtlb);
-
- cpustate->sreg[CS].selector = 0xf000;
- cpustate->sreg[CS].base = 0xffff0000;
- cpustate->sreg[CS].limit = 0xffff;
- cpustate->sreg[CS].flags = 0x009b;
-
- cpustate->sreg[DS].base = cpustate->sreg[ES].base = cpustate->sreg[FS].base = cpustate->sreg[GS].base = cpustate->sreg[SS].base = 0x00000000;
- cpustate->sreg[DS].limit = cpustate->sreg[ES].limit = cpustate->sreg[FS].limit = cpustate->sreg[GS].limit = cpustate->sreg[SS].limit = 0xffff;
- cpustate->sreg[DS].flags = cpustate->sreg[ES].flags = cpustate->sreg[FS].flags = cpustate->sreg[GS].flags = cpustate->sreg[SS].flags = 0x0092;
-
- cpustate->idtr.base = 0;
- cpustate->idtr.limit = 0x3ff;
-
- cpustate->a20_mask = ~0;
-
- cpustate->cr[0] = 0x60000010;
- cpustate->eflags = 0x00200000;
- cpustate->eflags_mask = 0x00277fd7; /* TODO: is this correct? */
- cpustate->eip = 0xfff0;
- cpustate->mxcsr = 0x1f80;
- cpustate->smm = false;
- cpustate->smi_latched = false;
- cpustate->smbase = 0x30000;
- cpustate->nmi_masked = false;
- cpustate->nmi_latched = false;
-
- x87_reset(cpustate);
-
- // [11:8] Family
- // [ 7:4] Model
- // [ 3:0] Stepping ID
- // Family 6, Model 3 (Pentium II / Klamath)
- REG32(EAX) = 0;
- REG32(EDX) = (6 << 8) | (3 << 4) | (1); /* TODO: is this correct? */
-
- cpustate->cpuid_id0 = 0x756e6547; // Genu
- cpustate->cpuid_id1 = 0x49656e69; // ineI
- cpustate->cpuid_id2 = 0x6c65746e; // ntel
-
- cpustate->cpuid_max_input_value_eax = 0x02;
- cpustate->cpu_version = REG32(EDX);
-
- // [ 0:0] FPU on chip
- cpustate->feature_flags = 0x008081bf; // TODO: enable relevant flags here
-
- CHANGE_PC(cpustate,cpustate->eip);
-}
-
-/*****************************************************************************/
-/* Intel Pentium III */
-
-CPU_INIT( pentium3 )
-{
- // 64 dtlb small, 8 dtlb large, 32 itlb small, 2 itlb large
- i386_common_init(96);
- build_x87_opcode_table(cpustate);
- build_opcode_table(OP_I386 | OP_FPU | OP_I486 | OP_PENTIUM | OP_PPRO | OP_MMX | OP_SSE);
- cpustate->cycle_table_rm = cycle_table_rm[CPU_CYCLES_PENTIUM]; // TODO: generate own cycle tables
- cpustate->cycle_table_pm = cycle_table_pm[CPU_CYCLES_PENTIUM]; // TODO: generate own cycle tables
- return cpustate;
-}
-
-CPU_RESET( pentium3 )
-{
- zero_state();
- vtlb_flush_dynamic(cpustate->vtlb);
-
- cpustate->sreg[CS].selector = 0xf000;
- cpustate->sreg[CS].base = 0xffff0000;
- cpustate->sreg[CS].limit = 0xffff;
- cpustate->sreg[CS].flags = 0x009b;
-
- cpustate->sreg[DS].base = cpustate->sreg[ES].base = cpustate->sreg[FS].base = cpustate->sreg[GS].base = cpustate->sreg[SS].base = 0x00000000;
- cpustate->sreg[DS].limit = cpustate->sreg[ES].limit = cpustate->sreg[FS].limit = cpustate->sreg[GS].limit = cpustate->sreg[SS].limit = 0xffff;
- cpustate->sreg[DS].flags = cpustate->sreg[ES].flags = cpustate->sreg[FS].flags = cpustate->sreg[GS].flags = cpustate->sreg[SS].flags = 0x0092;
-
- cpustate->idtr.base = 0;
- cpustate->idtr.limit = 0x3ff;
-
- cpustate->a20_mask = ~0;
-
- cpustate->cr[0] = 0x60000010;
- cpustate->eflags = 0x00200000;
- cpustate->eflags_mask = 0x00277fd7; /* TODO: is this correct? */
- cpustate->eip = 0xfff0;
- cpustate->mxcsr = 0x1f80;
- cpustate->smm = false;
- cpustate->smi_latched = false;
- cpustate->smbase = 0x30000;
- cpustate->nmi_masked = false;
- cpustate->nmi_latched = false;
-
- x87_reset(cpustate);
-
- // [11:8] Family
- // [ 7:4] Model
- // [ 3:0] Stepping ID
- // Family 6, Model 8 (Pentium III / Coppermine)
- REG32(EAX) = 0;
- REG32(EDX) = (6 << 8) | (8 << 4) | (10);
-
- cpustate->cpuid_id0 = 0x756e6547; // Genu
- cpustate->cpuid_id1 = 0x49656e69; // ineI
- cpustate->cpuid_id2 = 0x6c65746e; // ntel
-
- cpustate->cpuid_max_input_value_eax = 0x03;
- cpustate->cpu_version = REG32(EDX);
-
- // [ 0:0] FPU on chip
- // [ 4:4] Time Stamp Counter
- // [ D:D] PTE Global Bit
- cpustate->feature_flags = 0x00002011; // TODO: enable relevant flags here
-
- CHANGE_PC(cpustate,cpustate->eip);
-}
-
-/*****************************************************************************/
-/* Intel Pentium 4 */
-
-CPU_INIT( pentium4 )
-{
- // 128 dtlb, 64 itlb
- i386_common_init(196);
- build_x87_opcode_table();
- build_opcode_table(OP_I386 | OP_FPU | OP_I486 | OP_PENTIUM | OP_PPRO | OP_MMX | OP_SSE | OP_SSE2);
- cpustate->cycle_table_rm = cycle_table_rm[CPU_CYCLES_PENTIUM]; // TODO: generate own cycle tables
- cpustate->cycle_table_pm = cycle_table_pm[CPU_CYCLES_PENTIUM]; // TODO: generate own cycle tables
- return cpustate;
-}
-
-CPU_RESET( pentium4 )
-{
- zero_state();
- vtlb_flush_dynamic(cpustate->vtlb);
-
- cpustate->sreg[CS].selector = 0xf000;
- cpustate->sreg[CS].base = 0xffff0000;
- cpustate->sreg[CS].limit = 0xffff;
- cpustate->sreg[CS].flags = 0x009b;
-
- cpustate->sreg[DS].base = cpustate->sreg[ES].base = cpustate->sreg[FS].base = cpustate->sreg[GS].base = cpustate->sreg[SS].base = 0x00000000;
- cpustate->sreg[DS].limit = cpustate->sreg[ES].limit = cpustate->sreg[FS].limit = cpustate->sreg[GS].limit = cpustate->sreg[SS].limit = 0xffff;
- cpustate->sreg[DS].flags = cpustate->sreg[ES].flags = cpustate->sreg[FS].flags = cpustate->sreg[GS].flags = cpustate->sreg[SS].flags = 0x0092;
-
- cpustate->idtr.base = 0;
- cpustate->idtr.limit = 0x3ff;
-
- cpustate->a20_mask = ~0;
-
- cpustate->cr[0] = 0x60000010;
- cpustate->eflags = 0x00200000;
- cpustate->eflags_mask = 0x00277fd7; /* TODO: is this correct? */
- cpustate->eip = 0xfff0;
- cpustate->mxcsr = 0x1f80;
- cpustate->smm = false;
- cpustate->smi_latched = false;
- cpustate->smbase = 0x30000;
- cpustate->nmi_masked = false;
- cpustate->nmi_latched = false;
-
- x87_reset(cpustate);
-
- // [27:20] Extended family
- // [19:16] Extended model
- // [13:12] Type
- // [11: 8] Family
- // [ 7: 4] Model
- // [ 3: 0] Stepping ID
- // Family 15, Model 0 (Pentium 4 / Willamette)
- REG32(EAX) = 0;
- REG32(EDX) = (0 << 20) | (0xf << 8) | (0 << 4) | (1);
-
- cpustate->cpuid_id0 = 0x756e6547; // Genu
- cpustate->cpuid_id1 = 0x49656e69; // ineI
- cpustate->cpuid_id2 = 0x6c65746e; // ntel
-
- cpustate->cpuid_max_input_value_eax = 0x02;
- cpustate->cpu_version = REG32(EDX);
-
- // [ 0:0] FPU on chip
- cpustate->feature_flags = 0x00000001; // TODO: enable relevant flags here
-
- CHANGE_PC(cpustate,cpustate->eip);
-}
-
+++ /dev/null
-
-#ifndef __LIB_I386_OPDEF_H__
-#define __LIB_I386_OPDEF_H__
-
-#include "./i386priv.h"
-#include "./i386ops.h"
-
-extern "C" {
-#include "../libcpu_softfloat/fpu_constant.h"
-#include "../libcpu_softfloat/mamesf.h"
-#include "../libcpu_softfloat/milieu.h"
-#include "../libcpu_softfloat/softfloat.h"
-};
-
-#ifndef INLINE
-#define INLINE inline
-#endif
-
-#define U64(v) UINT64(v)
-
-#define fatalerror(...) exit(1)
-#define logerror(...)
-#define popmessage(...)
-
-/*****************************************************************************/
-/* src/emu/devcpu.h */
-
-// CPU interface functions
-#define CPU_INIT_NAME(name) I386_OPS_BASE::cpu_init_##name
-#define CPU_INIT(name) void* CPU_INIT_NAME(name)()
-#define CPU_INIT_CALL_NAME(name) cpu_init_##name
-#define CPU_INIT_CALL(name) CPU_INIT_CALL_NAME(name)()
-
-#define CPU_RESET_NAME(name) I386_OPS_BASE::cpu_reset_##name
-#define CPU_RESET(name) void CPU_RESET_NAME(name)(i386_state *cpustate)
-#define CPU_RESET_CALL_NAME(name) cpu_reset_##name
-#define CPU_RESET_CALL(name) CPU_RESET_CALL_NAME(name)(cpustate)
-
-#define CPU_EXECUTE_NAME(name) I386_OPS_BASE::cpu_execute_##name
-#define CPU_EXECUTE(name) int CPU_EXECUTE_NAME(name)(i386_state *cpustate, int cycles)
-#define CPU_EXECUTE_CALL_NAME(name) cpu_execute_##name
-#define CPU_EXECUTE_CALL(name) CPU_EXECUTE_CALL_NAME(name)(cpustate, cycles)
-
-#define CPU_TRANSLATE_NAME(name) I386_OPS_BASE::cpu_translate_##name
-#define CPU_TRANSLATE(name) int CPU_TRANSLATE_NAME(name)(void *cpudevice, address_spacenum space, int intention, offs_t *address)
-#define CPU_TRANSLATE_CALL_NAME(name) cpu_translate_##name
-#define CPU_TRANSLATE_CALL(name) CPU_TRANSLATE_CALL_NAME(name)(cpudevice, space, intention, address)
-
-#define CPU_DISASSEMBLE_NAME(name) I386_OPS_BASE::cpu_disassemble_##name
-#define CPU_DISASSEMBLE(name) int CPU_DISASSEMBLE_NAME(name)(_TCHAR *buffer, offs_t eip, const UINT8 *oprom)
-#define CPU_DISASSEMBLE_CALL_NAME(name) cpu_disassemble_##name
-#define CPU_DISASSEMBLE_CALL(name) CPU_DISASSEMBLE_CALL_NAME(name)(buffer, eip, oprom)
-
-/*****************************************************************************/
-/* src/emu/didisasm.h */
-
-// Disassembler constants
-const UINT32 DASMFLAG_SUPPORTED = 0x80000000; // are disassembly flags supported?
-const UINT32 DASMFLAG_STEP_OUT = 0x40000000; // this instruction should be the end of a step out sequence
-const UINT32 DASMFLAG_STEP_OVER = 0x20000000; // this instruction should be stepped over by setting a breakpoint afterwards
-const UINT32 DASMFLAG_OVERINSTMASK = 0x18000000; // number of extra instructions to skip when stepping over
-const UINT32 DASMFLAG_OVERINSTSHIFT = 27; // bits to shift after masking to get the value
-const UINT32 DASMFLAG_LENGTHMASK = 0x0000ffff; // the low 16-bits contain the actual length
-
-/*****************************************************************************/
-/* src/emu/diexec.h */
-
-// I/O line states
-enum line_state
-{
- CLEAR_LINE = 0, // clear (a fired or held) line
- ASSERT_LINE, // assert an interrupt immediately
- HOLD_LINE, // hold interrupt line until acknowledged
- PULSE_LINE // pulse interrupt line instantaneously (only for NMI, RESET)
-};
-
-enum
-{
- INPUT_LINE_IRQ = 0,
- INPUT_LINE_NMI
-};
-
-/*****************************************************************************/
-/* src/emu/dimemory.h */
-
-enum {
- I386_OPS_CPUTYPE_I386 = 0,
- I386_OPS_CPUTYPE_I486,
- I386_OPS_CPUTYPE_PENTIUM,
- I386_OPS_CPUTYPE_MEDIAGX,
- I386_OPS_CPUTYPE_PENTIUM_PRO,
- I386_OPS_CPUTYPE_PENTIUM_MMX,
- I386_OPS_CPUTYPE_PENTIUM2,
- I386_OPS_CPUTYPE_PENTIUM3,
- I386_OPS_CPUTYPE_PENTIUM4,
- I386_OPS_CPUTYPE_IX87FPU,
- I386_OPS_CPUTYPE_END
-};
-
-
-
-class DEBUG;
-class I386_OPS_BASE {
-protected:
- i386_state *cpustate;
-// Parameters.
-
- int i386_parity_table[256];
- MODRM_TABLE i386_MODRM_table[256];
-
- const X86_OPCODE x86_opcode_table[];
- const X86_CYCLE_TABLE x86_cycle_table[];
-
- UINT8 cycle_table_rm[X86_NUM_CPUS][CYCLES_NUM_OPCODES];
- UINT8 cycle_table_pm[X86_NUM_CPUS][CYCLES_NUM_OPCODES];
- const floatx80 ffx80_zero = { 0x0000, U64(0x0000000000000000) };
- const floatx80 ffx80_one = { 0x3fff, U64(0x8000000000000000) };
- const floatx80 ffx80_ninf = { 0xffff, U64(0x8000000000000000) };
- const floatx80 ffx80_inan = { 0xffff, U64(0xc000000000000000) };
- const int fx87_to_sf_rc[4];
-
- UINT32 i386_escape_ea; // hack around GCC 4.6 error because we need the side effects of GetEA()
-public:
- I386_OPS_BASE(int cputypes = I386_OPS_CPUTYPE_I386)
- {
- cpustate = NULL;
- _cputype = cputypes;
- }
- ~I386_OPS_BASE() {}
- void I386OP(decode_opcode)();
-
- int i386_translate_address(int intention, offs_t *address, vtlb_entry *entry);
- virtual int cpu_translate_i386(void *cpudevice, address_spacenum space, int intention, offs_t *address);
- virtual int cpu_execute_i386(int cycles);
- void i386_set_irq_line(int irqline, int state);
- void i386_set_a20_line(int state);
- int i386_limit_check( int seg, UINT32 offset);
-
-
-protected:
- // Utilities
- void build_cycle_table();
- i386_state *i386_common_init(int tlbsize);
- void build_opcode_table( UINT32 features);
- void zero_state();
- void pentium_smi();
-
- UINT32 i386_load_protected_mode_segment( I386_SREG *seg, UINT64 *desc );
- static void i386_load_call_gate(I386_CALL_GATE *gate);
- void i386_set_descriptor_accessed( UINT16 selector);
- void i386_load_segment_descriptor( int segment );
- UINT32 i386_get_stack_segment(UINT8 privilege);
- UINT32 i386_get_stack_ptr(UINT8 privilege);
-
- UINT32 get_flags();
- void set_flags( UINT32 f );
-
- void sib_byte(UINT8 mod, UINT32* out_ea, UINT8* out_segment);
- void modrm_to_EA(UINT8 mod_rm, UINT32* out_ea, UINT8* out_segment);
-
- UINT32 GetNonTranslatedEA(UINT8 modrm,UINT8 *seg);
- UINT32 GetEA(UINT8 modrm, int rwn);
-
- //
- void i386_check_sreg_validity(int reg);
- void i386_sreg_load( UINT16 selector, UINT8 reg, bool *fault);
- void i386_trap(int irq, int irq_gate, int trap_level);
- void i386_trap_with_error(int irq, int irq_gate, int trap_level, UINT32 error);
- void i286_task_switch( UINT16 selector, UINT8 nested);
- void i386_task_switch( UINT16 selector, UINT8 nested);
- void i386_check_irq_line();
-
- void i386_protected_mode_jump( UINT16 seg, UINT32 off, int indirect, int operand32);
- void i386_protected_mode_call( UINT16 seg, UINT32 off, int indirect, int operand32);
- void i386_protected_mode_retf(UINT8 count, UINT8 operand32);
- void i386_protected_mode_iret(int operand32);
-
- // Reporter.
- void report_invalid_opcode();
- void report_invalid_modrm(const char* opcode, UINT8 modrm);
-
- //LINES
- void i386_postload();
-protected:
- // Init per vm..
- void cpu_init_i386(void);
- void cpu_init_i486(void);
- void cpu_init_pentium(void);
- void cpu_init_mediagx(void);
- void cpu_init_pentium_pro(void);
- void cpu_init_pentium_mmx(void);
- void cpu_init_pentium2(void);
- void cpu_init_pentium3(void);
- void cpu_init_pentium4(void);
- // Reset pewr type.
- void cpu_reset_i386(void);
- void cpu_reset_i486(void);
- void cpu_reset_pentium(void);
- void cpu_reset_mediagx(void);
- void cpu_reset_pentium_pro(void);
- void cpu_reset_pentium_mmx(void);
- void cpu_reset_pentium2(void);
- void cpu_reset_pentium3(void);
- void cpu_reset_pentium4(void);
-
-protected:
- // INSNs.
- // i386/op16
- void I386OP(adc_rm16_r16)(); // Opcode 0x11
- void I386OP(adc_r16_rm16)(); // Opcode 0x13
- void I386OP(adc_ax_i16)(); // Opcode 0x15
- void I386OP(add_rm16_r16)(); // Opcode 0x01
- void I386OP(add_r16_rm16)(); // Opcode 0x03
- void I386OP(add_ax_i16)(); // Opcode 0x05
- void I386OP(and_rm16_r16)(); // Opcode 0x21
- void I386OP(and_r16_rm16)(); // Opcode 0x23
- void I386OP(and_ax_i16)(); // Opcode 0x25
- void I386OP(bsf_r16_rm16)(); // Opcode 0x0f bc
- void I386OP(bsr_r16_rm16)(); // Opcode 0x0f bd
- void I386OP(bt_rm16_r16)(); // Opcode 0x0f a3
- void I386OP(btc_rm16_r16)(); // Opcode 0x0f bb
- void I386OP(btr_rm16_r16)(); // Opcode 0x0f b3
- void I386OP(bts_rm16_r16)(); // Opcode 0x0f ab
- void I386OP(call_abs16)(); // Opcode 0x9a
- void I386OP(call_rel16)(); // Opcode 0xe8
- void I386OP(cbw)(); // Opcode 0x98
- void I386OP(cmp_rm16_r16)(); // Opcode 0x39
- void I386OP(cmp_r16_rm16)(); // Opcode 0x3b
- void I386OP(cmp_ax_i16)(); // Opcode 0x3d
- void I386OP(cmpsw)(); // Opcode 0xa7
- void I386OP(cwd)(); // Opcode 0x99
- void I386OP(dec_ax)(); // Opcode 0x48
- void I386OP(dec_cx)(); // Opcode 0x49
- void I386OP(dec_dx)(); // Opcode 0x4a
- void I386OP(dec_bx)(); // Opcode 0x4b
- void I386OP(dec_sp)(); // Opcode 0x4c
- void I386OP(dec_bp)(); // Opcode 0x4d
- void I386OP(dec_si)(); // Opcode 0x4e
- void I386OP(dec_di)(); // Opcode 0x4f
- void I386OP(imul_r16_rm16)(); // Opcode 0x0f af
- void I386OP(imul_r16_rm16_i16)(); // Opcode 0x69
- void I386OP(imul_r16_rm16_i8)(); // Opcode 0x6b
- void I386OP(in_ax_i8)(); // Opcode 0xe5
- void I386OP(in_ax_dx)(); // Opcode 0xed
- void I386OP(inc_ax)(); // Opcode 0x40
- void I386OP(inc_cx)(); // Opcode 0x41
- void I386OP(inc_dx)(); // Opcode 0x42
- void I386OP(inc_bx)(); // Opcode 0x43
- void I386OP(inc_sp)(); // Opcode 0x44
- void I386OP(inc_bp)(); // Opcode 0x45
- void I386OP(inc_si)(); // Opcode 0x46
- void I386OP(inc_di)(); // Opcode 0x47
- void I386OP(iret16)(); // Opcode 0xcf
- void I386OP(ja_rel16)(); // Opcode 0x0f 87
- void I386OP(jbe_rel16)(); // Opcode 0x0f 86
- void I386OP(jc_rel16)(); // Opcode 0x0f 82
- void I386OP(jg_rel16)(); // Opcode 0x0f 8f
- void I386OP(jge_rel16)(); // Opcode 0x0f 8d
- void I386OP(jl_rel16)(); // Opcode 0x0f 8c
- void I386OP(jle_rel16)(); // Opcode 0x0f 8e
- void I386OP(jnc_rel16)(); // Opcode 0x0f 83
- void I386OP(jno_rel16)(); // Opcode 0x0f 81
- void I386OP(jnp_rel16)(); // Opcode 0x0f 8b
- void I386OP(jns_rel16)(); // Opcode 0x0f 89
- void I386OP(jnz_rel16)(); // Opcode 0x0f 85
- void I386OP(jo_rel16)(); // Opcode 0x0f 80
- void I386OP(jp_rel16)(); // Opcode 0x0f 8a
- void I386OP(js_rel16)(); // Opcode 0x0f 88
- void I386OP(jz_rel16)(); // Opcode 0x0f 84
- void I386OP(jcxz16)(); // Opcode 0xe3
- void I386OP(jmp_rel16)(); // Opcode 0xe9
- void I386OP(jmp_abs16)(); // Opcode 0xea
- void I386OP(lea16)(); // Opcode 0x8d
- void I386OP(enter16)(); // Opcode 0xc8
- void I386OP(leave16)(); // Opcode 0xc9
- void I386OP(lodsw)(); // Opcode 0xad
- void I386OP(loop16)(); // Opcode 0xe2
- void I386OP(loopne16)(); // Opcode 0xe0
- void I386OP(loopz16)(); // Opcode 0xe1
- void I386OP(mov_rm16_r16)(); // Opcode 0x89
- void I386OP(mov_r16_rm16)(); // Opcode 0x8b
- void I386OP(mov_rm16_i16)(); // Opcode 0xc7
- void I386OP(mov_ax_m16)(); // Opcode 0xa1
- void I386OP(mov_m16_ax)(); // Opcode 0xa3
- void I386OP(mov_ax_i16)(); // Opcode 0xb8
- void I386OP(mov_cx_i16)(); // Opcode 0xb9
- void I386OP(mov_dx_i16)(); // Opcode 0xba
- void I386OP(mov_bx_i16)(); // Opcode 0xbb
- void I386OP(mov_sp_i16)(); // Opcode 0xbc
- void I386OP(mov_bp_i16)(); // Opcode 0xbd
- void I386OP(mov_si_i16)(); // Opcode 0xbe
- void I386OP(mov_di_i16)(); // Opcode 0xbf
- void I386OP(movsw)(); // Opcode 0xa5
- void I386OP(movsx_r16_rm8)(); // Opcode 0x0f be
- void I386OP(movzx_r16_rm8)(); // Opcode 0x0f b6
- void I386OP(or_rm16_r16)(); // Opcode 0x09
- void I386OP(or_r16_rm16)(); // Opcode 0x0b
- void I386OP(or_ax_i16)(); // Opcode 0x0d
- void I386OP(out_ax_i8)(); // Opcode 0xe7
- void I386OP(out_ax_dx)(); // Opcode 0xef
- void I386OP(pop_ax)(); // Opcode 0x58
- void I386OP(pop_cx)(); // Opcode 0x59
- void I386OP(pop_dx)(); // Opcode 0x5a
- void I386OP(pop_bx)(); // Opcode 0x5b
- void I386OP(pop_sp)(); // Opcode 0x5c
- void I386OP(pop_bp)(); // Opcode 0x5d
- void I386OP(pop_si)(); // Opcode 0x5e
- void I386OP(pop_di)(); // Opcode 0x5f
- void I386OP(pop_ds16)(); // Opcode 0x1f
- void I386OP(pop_es16)(); // Opcode 0x07
- void I386OP(pop_fs16)(); // Opcode 0x0f a1
- void I386OP(pop_gs16)(); // Opcode 0x0f a9
- void I386OP(pop_ss16)(); // Opcode 0x17
- void I386OP(pop_rm16)(); // Opcode 0x8f
- void I386OP(popa)(); // Opcode 0x61
- void I386OP(popf)(); // Opcode 0x9d
- void I386OP(push_ax)(); // Opcode 0x50
- void I386OP(push_cx)(); // Opcode 0x51
- void I386OP(push_dx)(); // Opcode 0x52
- void I386OP(push_bx)(); // Opcode 0x53
- void I386OP(push_sp)(); // Opcode 0x54
- void I386OP(push_bp)(); // Opcode 0x55
- void I386OP(push_si)(); // Opcode 0x56
- void I386OP(push_di)(); // Opcode 0x57
- void I386OP(push_cs16)(); // Opcode 0x0e
- void I386OP(push_ds16)(); // Opcode 0x1e
- void I386OP(push_es16)(); // Opcode 0x06
- void I386OP(push_fs16)(); // Opcode 0x0f a0
- void I386OP(push_gs16)(); // Opcode 0x0f a8
- void I386OP(push_ss16)(); // Opcode 0x16
- void I386OP(push_i16)(); // Opcode 0x68
- void I386OP(pusha)(); // Opcode 0x60
- void I386OP(pushf)(); // Opcode 0x9c
- void I386OP(ret_near16_i16)(); // Opcode 0xc2
- void I386OP(ret_near16)(); // Opcode 0xc3
- void I386OP(sbb_rm16_r16)(); // Opcode 0x19
- void I386OP(sbb_r16_rm16)(); // Opcode 0x1b
- void I386OP(sbb_ax_i16)(); // Opcode 0x1d
- void I386OP(scasw)(); // Opcode 0xaf
- void I386OP(shld16_i8)(); // Opcode 0x0f a4
- void I386OP(shld16_cl)(); // Opcode 0x0f a5
- void I386OP(shrd16_i8)(); // Opcode 0x0f ac
- void I386OP(shrd16_cl)(); // Opcode 0x0f ad
- void I386OP(stosw)(); // Opcode 0xab
- void I386OP(sub_rm16_r16)(); // Opcode 0x29
- void I386OP(sub_r16_rm16)(); // Opcode 0x2b
- void I386OP(sub_ax_i16)(); // Opcode 0x2d
- void I386OP(test_ax_i16)(); // Opcode 0xa9
- void I386OP(test_rm16_r16)(); // Opcode 0x85
- void I386OP(xchg_ax_cx)(); // Opcode 0x91
- void I386OP(xchg_ax_dx)(); // Opcode 0x92
- void I386OP(xchg_ax_bx)(); // Opcode 0x93
- void I386OP(xchg_ax_sp)(); // Opcode 0x94
- void I386OP(xchg_ax_bp)(); // Opcode 0x95
- void I386OP(xchg_ax_si)(); // Opcode 0x96
- void I386OP(xchg_ax_di)(); // Opcode 0x97
- void I386OP(xchg_r16_rm16)(); // Opcode 0x87
- void I386OP(xor_rm16_r16)(); // Opcode 0x31
- void I386OP(xor_r16_rm16)(); // Opcode 0x33
- void I386OP(xor_ax_i16)(); // Opcode 0x35
- void I386OP(group81_16)(); // Opcode 0x81
- void I386OP(group83_16)(); // Opcode 0x83
- void I386OP(groupC1_16)(); // Opcode 0xc1
- void I386OP(groupD1_16)(); // Opcode 0xd1
- void I386OP(groupD3_16)(); // Opcode 0xd3
- void I386OP(groupF7_16)(); // Opcode 0xf7
- void I386OP(groupFF_16)(); // Opcode 0xff
- void I386OP(group0F00_16)(); // Opcode 0x0f 00
- void I386OP(group0F01_16)(); // Opcode 0x0f 01
- void I386OP(group0FBA_16)(); // Opcode 0x0f ba
- void I386OP(lar_r16_rm16)(); // Opcode 0x0f 0x02
- void I386OP(lsl_r16_rm16)(); // Opcode 0x0f 0x03
- void I386OP(bound_r16_m16_m16)(); // Opcode 0x62
- void I386OP(retf16)(); // Opcode 0xcb
- void I386OP(retf_i16)(); // Opcode 0xca
- void I386OP(lds16)(); // Opcode 0xc5
- void I386OP(lss16)(); // Opcode 0x0f 0xb2
- void I386OP(les16)(); // Opcode 0xc4
- void I386OP(lfs16)(); // Opcode 0x0f 0xb4
- void I386OP(lgs16)(); // Opcode 0x0f 0xb5
- UINT16 I386OP(shift_rotate16)( UINT8 modrm, UINT32 value, UINT8 shift);
- UINT8 I386OP(shift_rotate8)( UINT8 modrm, UINT32 value, UINT8 shift);
- //i386/op32
- void I386OP(adc_rm32_r32)(); // Opcode 0x11
- void I386OP(adc_r32_rm32)(); // Opcode 0x13
- void I386OP(adc_eax_i32)(); // Opcode 0x15
- void I386OP(add_rm32_r32)(); // Opcode 0x01
- void I386OP(add_r32_rm32)(); // Opcode 0x03
- void I386OP(add_eax_i32)(); // Opcode 0x05
- void I386OP(and_rm32_r32)(); // Opcode 0x21
- void I386OP(and_r32_rm32)(); // Opcode 0x23
- void I386OP(and_eax_i32)(); // Opcode 0x25
- void I386OP(bsf_r32_rm32)(); // Opcode 0x0f bc
- void I386OP(bsr_r32_rm32)(); // Opcode 0x0f bd
- void I386OP(bt_rm32_r32)(); // Opcode 0x0f a3
- void I386OP(btc_rm32_r32)(); // Opcode 0x0f bb
- void I386OP(btr_rm32_r32)(); // Opcode 0x0f b3
- void I386OP(bts_rm32_r32)(); // Opcode 0x0f ab
- void I386OP(call_abs32)(); // Opcode 0x9a
- void I386OP(call_rel32)(); // Opcode 0xe8
- void I386OP(cdq)(); // Opcode 0x99
- void I386OP(cmp_rm32_r32)(); // Opcode 0x39
- void I386OP(cmp_r32_rm32)(); // Opcode 0x3b
- void I386OP(cmp_eax_i32)(); // Opcode 0x3d
- void I386OP(cmpsd)(); // Opcode 0xa7
- void I386OP(cwde)(); // Opcode 0x98
- void I386OP(dec_eax)(); // Opcode 0x48
- void I386OP(dec_ecx)(); // Opcode 0x49
- void I386OP(dec_edx)(); // Opcode 0x4a
- void I386OP(dec_ebx)(); // Opcode 0x4b
- void I386OP(dec_esp)(); // Opcode 0x4c
- void I386OP(dec_ebp)(); // Opcode 0x4d
- void I386OP(dec_esi)(); // Opcode 0x4e
- void I386OP(dec_edi)(); // Opcode 0x4f
- void I386OP(imul_r32_rm32)(); // Opcode 0x0f af
- void I386OP(imul_r32_rm32_i32)(); // Opcode 0x69
- void I386OP(imul_r32_rm32_i8)(); // Opcode 0x6b
- void I386OP(in_eax_i8)(); // Opcode 0xe5
- void I386OP(in_eax_dx)(); // Opcode 0xed
- void I386OP(inc_eax)(); // Opcode 0x40
- void I386OP(inc_ecx)(); // Opcode 0x41
- void I386OP(inc_edx)(); // Opcode 0x42
- void I386OP(inc_ebx)(); // Opcode 0x43
- void I386OP(inc_esp)(); // Opcode 0x44
- void I386OP(inc_ebp)(); // Opcode 0x45
- void I386OP(inc_esi)(); // Opcode 0x46
- void I386OP(inc_edi)(); // Opcode 0x47
- void I386OP(iret32)(); // Opcode 0xcf
- void I386OP(ja_rel32)(); // Opcode 0x0f 87
- void I386OP(jbe_rel32)(); // Opcode 0x0f 86
- void I386OP(jc_rel32)(); // Opcode 0x0f 82
- void I386OP(jg_rel32)(); // Opcode 0x0f 8f
- void I386OP(jge_rel32)(); // Opcode 0x0f 8d
- void I386OP(jl_rel32)(); // Opcode 0x0f 8c
- void I386OP(jle_rel32)(); // Opcode 0x0f 8e
- void I386OP(jnc_rel32)(); // Opcode 0x0f 83
- void I386OP(jno_rel32)(); // Opcode 0x0f 81
- void I386OP(jnp_rel32)(); // Opcode 0x0f 8b
- void I386OP(jns_rel32)(); // Opcode 0x0f 89
- void I386OP(jnz_rel32)(); // Opcode 0x0f 85
- void I386OP(jo_rel32)(); // Opcode 0x0f 80
- void I386OP(jp_rel32)(); // Opcode 0x0f 8a
- void I386OP(js_rel32)(); // Opcode 0x0f 88
- void I386OP(jz_rel32)(); // Opcode 0x0f 84
- void I386OP(jcxz32)(); // Opcode 0xe3
- void I386OP(jmp_rel32)(); // Opcode 0xe9
- void I386OP(jmp_abs32)(); // Opcode 0xea
- void I386OP(lea32)(); // Opcode 0x8d
- void I386OP(enter32)(); // Opcode 0xc8
- void I386OP(leave32)(); // Opcode 0xc9
- void I386OP(lodsd)(); // Opcode 0xad
- void I386OP(loop32)(); // Opcode 0xe2
- void I386OP(loopne32)(); // Opcode 0xe0
- void I386OP(loopz32)(); // Opcode 0xe1
- void I386OP(mov_rm32_r32)(); // Opcode 0x89
- void I386OP(mov_r32_rm32)(); // Opcode 0x8b
- void I386OP(mov_rm32_i32)(); // Opcode 0xc7
- void I386OP(mov_eax_m32)(); // Opcode 0xa1
- void I386OP(mov_m32_eax)(); // Opcode 0xa3
- void I386OP(mov_eax_i32)(); // Opcode 0xb8
- void I386OP(mov_ecx_i32)(); // Opcode 0xb9
- void I386OP(mov_edx_i32)(); // Opcode 0xba
- void I386OP(mov_ebx_i32)(); // Opcode 0xbb
- void I386OP(mov_esp_i32)(); // Opcode 0xbc
- void I386OP(mov_ebp_i32)(); // Opcode 0xbd
- void I386OP(mov_esi_i32)(); // Opcode 0xbe
- void I386OP(mov_edi_i32)(); // Opcode 0xbf
- void I386OP(movsd)(); // Opcode 0xa5
- void I386OP(movsx_r32_rm8)(); // Opcode 0x0f be
- void I386OP(movsx_r32_rm16)(); // Opcode 0x0f bf
- void I386OP(movzx_r32_rm8)(); // Opcode 0x0f b6
- void I386OP(movzx_r32_rm16)(); // Opcode 0x0f b7
- void I386OP(or_rm32_r32)(); // Opcode 0x09
- void I386OP(or_r32_rm32)(); // Opcode 0x0b
- void I386OP(or_eax_i32)(); // Opcode 0x0d
- void I386OP(out_eax_i8)(); // Opcode 0xe7
- void I386OP(out_eax_dx)(); // Opcode 0xef
- void I386OP(pop_eax)(); // Opcode 0x58
- void I386OP(pop_ecx)(); // Opcode 0x59
- void I386OP(pop_edx)(); // Opcode 0x5a
- void I386OP(pop_ebx)(); // Opcode 0x5b
- void I386OP(pop_esp)(); // Opcode 0x5c
- void I386OP(pop_ebp)(); // Opcode 0x5d
- void I386OP(pop_esi)(); // Opcode 0x5e
- void I386OP(pop_edi)(); // Opcode 0x5f
- void I386OP(pop_ds32)(); // Opcode 0x1f
- void I386OP(pop_es32)(); // Opcode 0x07
- void I386OP(pop_fs32)(); // Opcode 0x0f a1
- void I386OP(pop_gs32)(); // Opcode 0x0f a9
- void I386OP(pop_ss32)(); // Opcode 0x17
- void I386OP(pop_rm32)(); // Opcode 0x8f
- void I386OP(popad)(); // Opcode 0x61
- void I386OP(popfd)(); // Opcode 0x9d
- void I386OP(push_eax)(); // Opcode 0x50
- void I386OP(push_ecx)(); // Opcode 0x51
- void I386OP(push_edx)(); // Opcode 0x52
- void I386OP(push_ebx)(); // Opcode 0x53
- void I386OP(push_esp)(); // Opcode 0x54
- void I386OP(push_ebp)(); // Opcode 0x55
- void I386OP(push_esi)(); // Opcode 0x56
- void I386OP(push_edi)(); // Opcode 0x57
- void I386OP(push_cs32)(); // Opcode 0x0e
- void I386OP(push_ds32)(); // Opcode 0x1e
- void I386OP(push_es32)(); // Opcode 0x06
- void I386OP(push_fs32)(); // Opcode 0x0f a0
- void I386OP(push_gs32)(); // Opcode 0x0f a8
- void I386OP(push_ss32)(); // Opcode 0x16
- void I386OP(push_i32)(); // Opcode 0x68
- void I386OP(pushad)(); // Opcode 0x60
- void I386OP(pushfd)(); // Opcode 0x9c
- void I386OP(ret_near32_i16)(); // Opcode 0xc2
- void I386OP(ret_near32)(); // Opcode 0xc3
- void I386OP(sbb_rm32_r32)(); // Opcode 0x19
- void I386OP(sbb_r32_rm32)(); // Opcode 0x1b
- void I386OP(sbb_eax_i32)(); // Opcode 0x1d
- void I386OP(scasd)(); // Opcode 0xaf
- void I386OP(shld32_i8)(); // Opcode 0x0f a4
- void I386OP(shld32_cl)(); // Opcode 0x0f a5
- void I386OP(shrd32_i8)(); // Opcode 0x0f ac
- void I386OP(shrd32_cl)(); // Opcode 0x0f ad
- void I386OP(stosd)(); // Opcode 0xab
- void I386OP(sub_rm32_r32)(); // Opcode 0x29
- void I386OP(sub_r32_rm32)(); // Opcode 0x2b
- void I386OP(sub_eax_i32)(); // Opcode 0x2d
- void I386OP(test_eax_i32)(); // Opcode 0xa9
- void I386OP(test_rm32_r32)(); // Opcode 0x85
- void I386OP(xchg_eax_ecx)(); // Opcode 0x91
- void I386OP(xchg_eax_edx)(); // Opcode 0x92
- void I386OP(xchg_eax_ebx)(); // Opcode 0x93
- void I386OP(xchg_eax_esp)(); // Opcode 0x94
- void I386OP(xchg_eax_ebp)(); // Opcode 0x95
- void I386OP(xchg_eax_esi)(); // Opcode 0x96
- void I386OP(xchg_eax_edi)(); // Opcode 0x97
- void I386OP(xchg_r32_rm32)(); // Opcode 0x87
- void I386OP(xor_rm32_r32)(); // Opcode 0x31
- void I386OP(xor_r32_rm32)(); // Opcode 0x33
- void I386OP(xor_eax_i32)(); // Opcode 0x35
- void I386OP(group81_32)(); // Opcode 0x81
- void I386OP(group83_32)(); // Opcode 0x83
- void I386OP(groupC1_32)(); // Opcode 0xc1
- void I386OP(groupD1_32)(); // Opcode 0xd1
- void I386OP(groupD3_32)(); // Opcode 0xd3
- void I386OP(groupF7_32)(); // Opcode 0xf7
- void I386OP(groupFF_32)(); // Opcode 0xff
- void I386OP(group0F00_32)(); // Opcode 0x0f 00
- void I386OP(group0F01_32)(); // Opcode 0x0f 01
- void I386OP(group0FBA_32)(); // Opcode 0x0f ba
- void I386OP(lar_r32_rm32)(); // Opcode 0x0f 0x02
- void I386OP(lsl_r32_rm32)(); // Opcode 0x0f 0x03
- void I386OP(bound_r32_m32_m32)(); // Opcode 0x62
- void I386OP(retf32)(); // Opcode 0xcb
- void I386OP(retf_i32)(); // Opcode 0xca
- void I386OP(load_far_pointer32)( int s);
- void I386OP(lds32)(); // Opcode 0xc5
- void I386OP(lss32)(); // Opcode 0x0f 0xb2
- void I386OP(les32)(); // Opcode 0xc4
- void I386OP(lfs32)(); // Opcode 0x0f 0xb4
- void I386OP(lgs32)(); // Opcode 0x0f 0xb5
-// i386 other OPS.
- void I386OP(adc_rm8_r8)(); // Opcode 0x10
- void I386OP(adc_r8_rm8)(); // Opcode 0x12
- void I386OP(adc_al_i8)(); // Opcode 0x14
- void I386OP(add_rm8_r8)(); // Opcode 0x00
- void I386OP(add_r8_rm8)(); // Opcode 0x02
- void I386OP(add_al_i8)(); // Opcode 0x04
- void I386OP(and_rm8_r8)(); // Opcode 0x20
- void I386OP(and_r8_rm8)(); // Opcode 0x22
- void I386OP(and_al_i8)(); // Opcode 0x24
- void I386OP(clc)(); // Opcode 0xf8
- void I386OP(cld)(); // Opcode 0xfc
- void I386OP(cli)(); // Opcode 0xfa
- void I386OP(cmc)(); // Opcode 0xf5
- void I386OP(cmp_rm8_r8)(); // Opcode 0x38
- void I386OP(cmp_r8_rm8)(); // Opcode 0x3a
- void I386OP(cmp_al_i8)(); // Opcode 0x3c
- void I386OP(cmpsb)(); // Opcode 0xa6
- void I386OP(in_al_i8)(); // Opcode 0xe4
- void I386OP(in_al_dx)(); // Opcode 0xec
- void I386OP(ja_rel8)(); // Opcode 0x77
- void I386OP(jbe_rel8)(); // Opcode 0x76
- void I386OP(jc_rel8)(); // Opcode 0x72
- void I386OP(jg_rel8)(); // Opcode 0x7f
- void I386OP(jge_rel8)(); // Opcode 0x7d
- void I386OP(jl_rel8)(); // Opcode 0x7c
- void I386OP(jle_rel8)(); // Opcode 0x7e
- void I386OP(jnc_rel8)(); // Opcode 0x73
- void I386OP(jno_rel8)(); // Opcode 0x71
- void I386OP(jnp_rel8)(); // Opcode 0x7b
- void I386OP(jns_rel8)(); // Opcode 0x79
- void I386OP(jnz_rel8)(); // Opcode 0x75
- void I386OP(jo_rel8)(); // Opcode 0x70
- void I386OP(jp_rel8)(); // Opcode 0x7a
- void I386OP(js_rel8)(); // Opcode 0x78
- void I386OP(jz_rel8)(); // Opcode 0x74
- void I386OP(jmp_rel8)(); // Opcode 0xeb
- void I386OP(lahf)(); // Opcode 0x9f
- void I386OP(lodsb)(); // Opcode 0xac
- void I386OP(mov_rm8_r8)(); // Opcode 0x88
- void I386OP(mov_r8_rm8)(); // Opcode 0x8a
- void I386OP(mov_rm8_i8)(); // Opcode 0xc6
- void I386OP(mov_r32_cr)(); // Opcode 0x0f 20
- void I386OP(mov_r32_dr)(); // Opcode 0x0f 21
- void I386OP(mov_cr_r32)(); // Opcode 0x0f 22
- void I386OP(mov_dr_r32)(); // Opcode 0x0f 23
- void I386OP(mov_al_m8)(); // Opcode 0xa0
- void I386OP(mov_m8_al)(); // Opcode 0xa2
- void I386OP(mov_rm16_sreg)(); // Opcode 0x8c
- void I386OP(mov_sreg_rm16)(); // Opcode 0x8e
- void I386OP(mov_al_i8)(); // Opcode 0xb0
- void I386OP(mov_cl_i8)(); // Opcode 0xb1
- void I386OP(mov_dl_i8)(); // Opcode 0xb2
- void I386OP(mov_bl_i8)(); // Opcode 0xb3
- void I386OP(mov_ah_i8)(); // Opcode 0xb4
- void I386OP(mov_ch_i8)(); // Opcode 0xb5
- void I386OP(mov_dh_i8)(); // Opcode 0xb6
- void I386OP(mov_bh_i8)(); // Opcode 0xb7
- void I386OP(movsb)(); // Opcode 0xa4
- void I386OP(or_rm8_r8)(); // Opcode 0x08
- void I386OP(or_r8_rm8)(); // Opcode 0x0a
- void I386OP(or_al_i8)(); // Opcode 0x0c
- void I386OP(out_al_i8)(); // Opcode 0xe6
- void I386OP(out_al_dx)(); // Opcode 0xee
- void I386OP(arpl)(); // Opcode 0x63
- void I386OP(push_i8)(); // Opcode 0x6a
- void I386OP(ins_generic)( int size);
- void I386OP(insb)(); // Opcode 0x6c
- void I386OP(insw)(); // Opcode 0x6d
- void I386OP(insd)(); // Opcode 0x6d
- void I386OP(outs_generic)( int size);
- void I386OP(outsb)(); // Opcode 0x6e
- void I386OP(outsw)(); // Opcode 0x6f
- void I386OP(outsd)(); // Opcode 0x6f
- void I386OP(repeat)( int invert_flag);
- void I386OP(rep)(); // Opcode 0xf3
- void I386OP(repne)(); // Opcode 0xf2
- void I386OP(sahf)(); // Opcode 0x9e
- void I386OP(sbb_rm8_r8)(); // Opcode 0x18
- void I386OP(sbb_r8_rm8)(); // Opcode 0x1a
- void I386OP(sbb_al_i8)(); // Opcode 0x1c
- void I386OP(scasb)(); // Opcode 0xae
- void I386OP(setalc)(); // Opcode 0xd6 (undocumented)
- void I386OP(seta_rm8)(); // Opcode 0x0f 97
- void I386OP(setbe_rm8)(); // Opcode 0x0f 96
- void I386OP(setc_rm8)(); // Opcode 0x0f 92
- void I386OP(setg_rm8)(); // Opcode 0x0f 9f
- void I386OP(setge_rm8)(); // Opcode 0x0f 9d
- void I386OP(setl_rm8)(); // Opcode 0x0f 9c
- void I386OP(setle_rm8)(); // Opcode 0x0f 9e
- void I386OP(setnc_rm8)(); // Opcode 0x0f 93
- void I386OP(setno_rm8)(); // Opcode 0x0f 91
- void I386OP(setnp_rm8)(); // Opcode 0x0f 9b
- void I386OP(setns_rm8)(); // Opcode 0x0f 99
- void I386OP(setnz_rm8)(); // Opcode 0x0f 95
- void I386OP(seto_rm8)(); // Opcode 0x0f 90
- void I386OP(setp_rm8)(); // Opcode 0x0f 9a
- void I386OP(sets_rm8)(); // Opcode 0x0f 98
- void I386OP(setz_rm8)(); // Opcode 0x0f 94
- void I386OP(stc)(); // Opcode 0xf9
- void I386OP(std)(); // Opcode 0xfd
- void I386OP(sti)(); // Opcode 0xfb
- void I386OP(stosb)(); // Opcode 0xaa
- void I386OP(sub_rm8_r8)(); // Opcode 0x28
- void I386OP(sub_r8_rm8)(); // Opcode 0x2a
- void I386OP(sub_al_i8)(); // Opcode 0x2c
- void I386OP(test_al_i8)(); // Opcode 0xa8
- void I386OP(test_rm8_r8)(); // Opcode 0x84
- void I386OP(xchg_r8_rm8)(); // Opcode 0x86
- void I386OP(xor_rm8_r8)(); // Opcode 0x30
- void I386OP(xor_r8_rm8)(); // Opcode 0x32
- void I386OP(xor_al_i8)(); // Opcode 0x34
- void I386OP(group80_8)(); // Opcode 0x80
- void I386OP(groupC0_8)(); // Opcode 0xc0
- void I386OP(groupD0_8)(); // Opcode 0xd0
- void I386OP(groupD2_8)(); // Opcode 0xd2
- void I386OP(groupF6_8)(); // Opcode 0xf6
- void I386OP(groupFE_8)(); // Opcode 0xfe
- void I386OP(segment_CS)(); // Opcode 0x2e
- void I386OP(segment_DS)(); // Opcode 0x3e
- void I386OP(segment_ES)(); // Opcode 0x26
- void I386OP(segment_FS)(); // Opcode 0x64
- void I386OP(segment_GS)(); // Opcode 0x65
- void I386OP(segment_SS)(); // Opcode 0x36
- void I386OP(operand_size)(); // Opcode prefix 0x66
- void I386OP(address_size)(); // Opcode 0x67
- void I386OP(nop)(); // Opcode 0x90
- void I386OP(int3)(); // Opcode 0xcc
- void I386OP(int)(); // Opcode 0xcd
- void I386OP(into)(); // Opcode 0xce
- void I386OP(escape)(); // Opcodes 0xd8 - 0xdf
- void I386OP(hlt)(); // Opcode 0xf4
- void I386OP(decimal_adjust)(int direction);
- void I386OP(daa)(); // Opcode 0x27
- void I386OP(das)(); // Opcode 0x2f
- void I386OP(aaa)(); // Opcode 0x37
- void I386OP(aas)(); // Opcode 0x3f
- void I386OP(aad)(); // Opcode 0xd5
- void I386OP(aam)(); // Opcode 0xd4
- void I386OP(clts)(); // Opcode 0x0f 0x06
- void I386OP(wait)(); // Opcode 0x9B
- void I386OP(lock)(); // Opcode 0xf0
- void I386OP(mov_r32_tr)(); // Opcode 0x0f 24
- void I386OP(mov_tr_r32)(); // Opcode 0x0f 26
- void I386OP(loadall)(); // Opcode 0x0f 0x07 (0x0f 0x05 on 80286), undocumented
- void I386OP(invalid)();
- void I386OP(xlat)(); // Opcode 0xd7
- bool I386OP(pop_seg16)( int segment);
- bool I386OP(load_far_pointer16)(int s);
- bool I386OP(pop_seg32)( int segment);
-//i486
- void I486OP(cpuid)(); // Opcode 0x0F A2
- void I486OP(invd)(); // Opcode 0x0f 08
- void I486OP(wbinvd)(); // Opcode 0x0f 09
- void I486OP(cmpxchg_rm8_r8)(); // Opcode 0x0f b0
- void I486OP(cmpxchg_rm16_r16)(); // Opcode 0x0f b1
- void I486OP(cmpxchg_rm32_r32)(); // Opcode 0x0f b1
- void I486OP(xadd_rm8_r8)(); // Opcode 0x0f c0
- void I486OP(xadd_rm16_r16)(); // Opcode 0x0f c1
- void I486OP(xadd_rm32_r32)(); // Opcode 0x0f c1
- void I486OP(group0F01_16)(); // Opcode 0x0f 01
- void I486OP(group0F01_32)(); // Opcode 0x0f 01
- void I486OP(bswap_eax)(); // Opcode 0x0f 38
- void I486OP(bswap_ecx)(); // Opcode 0x0f 39
- void I486OP(bswap_edx)(); // Opcode 0x0f 3A
- void I486OP(bswap_ebx)(); // Opcode 0x0f 3B
- void I486OP(bswap_esp)(); // Opcode 0x0f 3C
- void I486OP(bswap_ebp)(); // Opcode 0x0f 3D
- void I486OP(bswap_esi)(); // Opcode 0x0f 3E
- void I486OP(bswap_edi)(); // Opcode 0x0f 3F
- void I486OP(mov_cr_r32)(); // Opcode 0x0f 22
-//Pentium, MMX, SSE.
- void PENTIUMOP(rdmsr)(); // Opcode 0x0f 32
- void PENTIUMOP(wrmsr)(); // Opcode 0x0f 30
- void PENTIUMOP(rdtsc)(); // Opcode 0x0f 31
- void PENTIUMOP(ud2)(); // Opcode 0x0f 0b
- void PENTIUMOP(rsm)();
- void PENTIUMOP(prefetch_m8)(); // Opcode 0x0f 18
- void PENTIUMOP(cmovo_r16_rm16)(); // Opcode 0x0f 40
- void PENTIUMOP(cmovo_r32_rm32)(); // Opcode 0x0f 40
- void PENTIUMOP(cmovno_r16_rm16)(); // Opcode 0x0f 41
- void PENTIUMOP(cmovno_r32_rm32)(); // Opcode 0x0f 41
- void PENTIUMOP(cmovb_r16_rm16)(); // Opcode 0x0f 42
- void PENTIUMOP(cmovb_r32_rm32)(); // Opcode 0x0f 42
- void PENTIUMOP(cmovae_r16_rm16)(); // Opcode 0x0f 43
- void PENTIUMOP(cmovae_r32_rm32)(); // Opcode 0x0f 43
- void PENTIUMOP(cmove_r16_rm16)(); // Opcode 0x0f 44
- void PENTIUMOP(cmove_r32_rm32)(); // Opcode 0x0f 44
- void PENTIUMOP(cmovne_r16_rm16)(); // Opcode 0x0f 45
- void PENTIUMOP(cmovne_r32_rm32)(); // Opcode 0x0f 45
- void PENTIUMOP(cmovbe_r16_rm16)(); // Opcode 0x0f 46
- void PENTIUMOP(cmovbe_r32_rm32)(); // Opcode 0x0f 46
- void PENTIUMOP(cmova_r16_rm16)(); // Opcode 0x0f 47
- void PENTIUMOP(cmova_r32_rm32)(); // Opcode 0x0f 47
- void PENTIUMOP(cmovs_r16_rm16)(); // Opcode 0x0f 48
- void PENTIUMOP(cmovs_r32_rm32)(); // Opcode 0x0f 48
- void PENTIUMOP(cmovns_r16_rm16)(); // Opcode 0x0f 49
- void PENTIUMOP(cmovns_r32_rm32)(); // Opcode 0x0f 49
- void PENTIUMOP(cmovp_r16_rm16)(); // Opcode 0x0f 4a
- void PENTIUMOP(cmovp_r32_rm32)(); // Opcode 0x0f 4a
- void PENTIUMOP(cmovnp_r16_rm16)(); // Opcode 0x0f 4b
- void PENTIUMOP(cmovnp_r32_rm32)(); // Opcode 0x0f 4b
- void PENTIUMOP(cmovl_r16_rm16)(); // Opcode 0x0f 4c
- void PENTIUMOP(cmovl_r32_rm32)(); // Opcode 0x0f 4c
- void PENTIUMOP(cmovge_r16_rm16)(); // Opcode 0x0f 4d
- void PENTIUMOP(cmovge_r32_rm32)(); // Opcode 0x0f 4d
- void PENTIUMOP(cmovle_r16_rm16)(); // Opcode 0x0f 4e
- void PENTIUMOP(cmovle_r32_rm32)(); // Opcode 0x0f 4e
- void PENTIUMOP(cmovg_r16_rm16)(); // Opcode 0x0f 4f
- void PENTIUMOP(cmovg_r32_rm32)(); // Opcode 0x0f 4f
- void PENTIUMOP(movnti_m16_r16)(); // Opcode 0f c3
- void PENTIUMOP(movnti_m32_r32)(); // Opcode 0f c3
- void PENTIUMOP(cmpxchg8b_m64)(); // Opcode 0x0f c7
- void PENTIUMOP(movntq_m64_r64)(); // Opcode 0f e7
- void PENTIUMOP(maskmovq_r64_r64)(); // Opcode 0f f7
- void SSEOP(maskmovdqu_r128_r128)(); // Opcode 66 0f f7
- void PENTIUMOP(popcnt_r16_rm16)(); // Opcode f3 0f b8
- void PENTIUMOP(popcnt_r32_rm32)(); // Opcode f3 0f b8
- void PENTIUMOP(tzcnt_r16_rm16)();
- void PENTIUMOP(tzcnt_r32_rm32)();
- void MMXOP(group_0f71)(); // Opcode 0f 71
- void SSEOP(group_660f71)(); // Opcode 66 0f 71
- void MMXOP(group_0f72)(); // Opcode 0f 72
- void SSEOP(group_660f72)(); // Opcode 66 0f 72
- void MMXOP(group_0f73)(); // Opcode 0f 73
- void SSEOP(group_660f73)(); // Opcode 66 0f 73
- void MMXOP(psrlw_r64_rm64)(); // Opcode 0f d1
- void MMXOP(psrld_r64_rm64)(); // Opcode 0f d2
- void MMXOP(psrlq_r64_rm64)(); // Opcode 0f d3
- void MMXOP(paddq_r64_rm64)(); // Opcode 0f d4
- void MMXOP(pmullw_r64_rm64)(); // Opcode 0f d5
- void MMXOP(psubusb_r64_rm64)(); // Opcode 0f d8
- void MMXOP(psubusw_r64_rm64)(); // Opcode 0f d9
- void MMXOP(pand_r64_rm64)(); // Opcode 0f db
- void MMXOP(paddusb_r64_rm64)(); // Opcode 0f dc
- void MMXOP(paddusw_r64_rm64)(); // Opcode 0f dd
- void MMXOP(pandn_r64_rm64)(); // Opcode 0f df
- void MMXOP(psraw_r64_rm64)(); // Opcode 0f e1
- void MMXOP(psrad_r64_rm64)(); // Opcode 0f e2
- void MMXOP(pmulhw_r64_rm64)(); // Opcode 0f e5
- void MMXOP(psubsb_r64_rm64)(); // Opcode 0f e8
- void MMXOP(psubsw_r64_rm64)(); // Opcode 0f e9
- void MMXOP(por_r64_rm64)(); // Opcode 0f eb
- void MMXOP(paddsb_r64_rm64)(); // Opcode 0f ec
- void MMXOP(paddsw_r64_rm64)(); // Opcode 0f ed
- void MMXOP(pxor_r64_rm64)(); // Opcode 0f ef
- void MMXOP(psllw_r64_rm64)(); // Opcode 0f f1
- void MMXOP(pslld_r64_rm64)(); // Opcode 0f f2
- void MMXOP(psllq_r64_rm64)(); // Opcode 0f f3
- void MMXOP(pmaddwd_r64_rm64)(); // Opcode 0f f5
- void MMXOP(psubb_r64_rm64)(); // Opcode 0f f8
- void MMXOP(psubw_r64_rm64)(); // Opcode 0f f9
- void MMXOP(psubd_r64_rm64)(); // Opcode 0f fa
- void MMXOP(paddb_r64_rm64)(); // Opcode 0f fc
- void MMXOP(paddw_r64_rm64)(); // Opcode 0f fd
- void MMXOP(paddd_r64_rm64)(); // Opcode 0f fe
- void MMXOP(emms)(); // Opcode 0f 77
- void MMXOP(movd_r64_rm32)(); // Opcode 0f 6e
- void MMXOP(movq_r64_rm64)(); // Opcode 0f 6f
- void MMXOP(movd_rm32_r64)(); // Opcode 0f 7e
- void MMXOP(movq_rm64_r64)(); // Opcode 0f 7f
- void MMXOP(pcmpeqb_r64_rm64)(); // Opcode 0f 74
- void MMXOP(pcmpeqw_r64_rm64)(); // Opcode 0f 75
- void MMXOP(pcmpeqd_r64_rm64)(); // Opcode 0f 76
- void MMXOP(pshufw_r64_rm64_i8)(); // Opcode 0f 70
- void SSEOP(punpcklbw_r128_rm128)(); // Opcode 66 0f 60
- void SSEOP(punpcklwd_r128_rm128)();
- void SSEOP(punpckldq_r128_rm128)();
- void SSEOP(punpcklqdq_r128_rm128)();
- void MMXOP(punpcklbw_r64_r64m32)(); // Opcode 0f 60
- void MMXOP(punpcklwd_r64_r64m32)(); // Opcode 0f 61
- void MMXOP(punpckldq_r64_r64m32)(); // Opcode 0f 62
- void MMXOP(packsswb_r64_rm64)(); // Opcode 0f 63
- void MMXOP(pcmpgtb_r64_rm64)(); // Opcode 0f 64
- void MMXOP(pcmpgtw_r64_rm64)(); // Opcode 0f 65
- void MMXOP(pcmpgtd_r64_rm64)(); // Opcode 0f 66
- void MMXOP(packuswb_r64_rm64)(); // Opcode 0f 67
- void MMXOP(punpckhbw_r64_rm64)(); // Opcode 0f 68
- void MMXOP(punpckhwd_r64_rm64)(); // Opcode 0f 69
- void MMXOP(punpckhdq_r64_rm64)(); // Opcode 0f 6a
- void MMXOP(packssdw_r64_rm64)(); // Opcode 0f 6b
- void SSEOP(group_0fae)(); // Opcode 0f ae
- void SSEOP(cvttps2dq_r128_rm128)(); // Opcode f3 0f 5b
- void SSEOP(cvtss2sd_r128_r128m32)(); // Opcode f3 0f 5a
- void SSEOP(cvttss2si_r32_r128m32)(); // Opcode f3 0f 2c
- void SSEOP(cvtss2si_r32_r128m32)(); // Opcode f3 0f 2d
- void SSEOP(cvtsi2ss_r128_rm32)(); // Opcode f3 0f 2a
- void SSEOP(cvtpi2ps_r128_rm64)(); // Opcode 0f 2a
- void SSEOP(cvttps2pi_r64_r128m64)(); // Opcode 0f 2c
- void SSEOP(cvtps2pi_r64_r128m64)(); // Opcode 0f 2d
- void SSEOP(cvtps2pd_r128_r128m64)(); // Opcode 0f 5a
- void SSEOP(cvtdq2ps_r128_rm128)(); // Opcode 0f 5b
- void SSEOP(cvtdq2pd_r128_r128m64)(); // Opcode f3 0f e6
- void SSEOP(movss_r128_rm128)(); // Opcode f3 0f 10
- void SSEOP(movss_rm128_r128)(); // Opcode f3 0f 11
- void SSEOP(movsldup_r128_rm128)(); // Opcode f3 0f 12
- void SSEOP(movshdup_r128_rm128)(); // Opcode f3 0f 16
- void SSEOP(movaps_r128_rm128)(); // Opcode 0f 28
- void SSEOP(movaps_rm128_r128)(); // Opcode 0f 29
- void SSEOP(movups_r128_rm128)(); // Opcode 0f 10
- void SSEOP(movupd_r128_rm128)(); // Opcode 66 0f 10
- void SSEOP(movups_rm128_r128)(); // Opcode 0f 11
- void SSEOP(movupd_rm128_r128)(); // Opcode 66 0f 11
- void SSEOP(movlps_r128_m64)(); // Opcode 0f 12
- void SSEOP(movlpd_r128_m64)(); // Opcode 66 0f 12
- void SSEOP(movlps_m64_r128)(); // Opcode 0f 13
- void SSEOP(movlpd_m64_r128)(); // Opcode 66 0f 13
- void SSEOP(movhps_r128_m64)(); // Opcode 0f 16
- void SSEOP(movhpd_r128_m64)(); // Opcode 66 0f 16
- void SSEOP(movhps_m64_r128)(); // Opcode 0f 17
- void SSEOP(movhpd_m64_r128)(); // Opcode 66 0f 17
- void SSEOP(movntps_m128_r128)(); // Opcode 0f 2b
- void SSEOP(movmskps_r16_r128)(); // Opcode 0f 50
- void SSEOP(movmskps_r32_r128)(); // Opcode 0f 50
- void SSEOP(movmskpd_r32_r128)(); // Opcode 66 0f 50
- void SSEOP(movq2dq_r128_r64)(); // Opcode f3 0f d6
- void SSEOP(movdqu_r128_rm128)(); // Opcode f3 0f 6f
- void SSEOP(movdqu_rm128_r128)(); // Opcode f3 0f 7f
- void SSEOP(movd_m128_rm32)(); // Opcode 66 0f 6e
- void SSEOP(movdqa_m128_rm128)(); // Opcode 66 0f 6f
- void SSEOP(movq_r128_r128m64)(); // Opcode f3 0f 7e
- void SSEOP(movd_rm32_r128)(); // Opcode 66 0f 7e
- void SSEOP(movdqa_rm128_r128)(); // Opcode 66 0f 7f
- void SSEOP(pmovmskb_r16_r64)(); // Opcode 0f d7
- void SSEOP(pmovmskb_r32_r64)(); // Opcode 0f d7
- void SSEOP(pmovmskb_r32_r128)(); // Opcode 66 0f d7
- void SSEOP(xorps)(); // Opcode 0f 57
- void SSEOP(xorpd_r128_rm128)(); // Opcode 66 0f 57
- void SSEOP(addps)(); // Opcode 0f 58
- void SSEOP(sqrtps_r128_rm128)(); // Opcode 0f 51
- void SSEOP(rsqrtps_r128_rm128)(); // Opcode 0f 52
- void SSEOP(rcpps_r128_rm128)(); // Opcode 0f 53
- void SSEOP(andps_r128_rm128)(); // Opcode 0f 54
- void SSEOP(andpd_r128_rm128)(); // Opcode 66 0f 54
- void SSEOP(andnps_r128_rm128)(); // Opcode 0f 55
- void SSEOP(andnpd_r128_rm128)(); // Opcode 66 0f 55
- void SSEOP(orps_r128_rm128)(); // Opcode 0f 56
- void SSEOP(orpd_r128_rm128)(); // Opcode 66 0f 56
- void SSEOP(mulps)(); // Opcode 0f 59 ????
- void SSEOP(subps)(); // Opcode 0f 5c
- void SSEOP(minps)(); // Opcode 0f 5d
- void SSEOP(divps)(); // Opcode 0f 5e
- void SSEOP(maxps)(); // Opcode 0f 5f
- void SSEOP(maxss_r128_r128m32)(); // Opcode f3 0f 5f
- void SSEOP(addss)(); // Opcode f3 0f 58
- void SSEOP(subss)(); // Opcode f3 0f 5c
- void SSEOP(mulss)(); // Opcode f3 0f 5e
- void SSEOP(divss)(); // Opcode 0f 59
- void SSEOP(rcpss_r128_r128m32)(); // Opcode f3 0f 53
- void SSEOP(sqrtss_r128_r128m32)(); // Opcode f3 0f 51
- void SSEOP(rsqrtss_r128_r128m32)(); // Opcode f3 0f 52
- void SSEOP(minss_r128_r128m32)(); // Opcode f3 0f 5d
- void SSEOP(comiss_r128_r128m32)(); // Opcode 0f 2f
- void SSEOP(comisd_r128_r128m64)(); // Opcode 66 0f 2f
- void SSEOP(ucomiss_r128_r128m32)(); // Opcode 0f 2e
- void SSEOP(ucomisd_r128_r128m64)(); // Opcode 66 0f 2e
- void SSEOP(shufps)(); // Opcode 0f c6
- void SSEOP(shufpd_r128_rm128_i8)(); // Opcode 66 0f c6
- void SSEOP(unpcklps_r128_rm128)(); // Opcode 0f 14
- void SSEOP(unpcklpd_r128_rm128)(); // Opcode 66 0f 14
- void SSEOP(unpckhps_r128_rm128)(); // Opcode 0f 15
- void SSEOP(unpckhpd_r128_rm128)(); // Opcode 66 0f 15
- void SSEOP(predicate_compare_single)(UINT8 imm8, XMM_REG d, XMM_REG s);
- void SSEOP(predicate_compare_double)(UINT8 imm8, XMM_REG d, XMM_REG s);
- void SSEOP(predicate_compare_single_scalar)(UINT8 imm8, XMM_REG d, XMM_REG s);
- void SSEOP(predicate_compare_double_scalar)(UINT8 imm8, XMM_REG d, XMM_REG s);
- void SSEOP(cmpps_r128_rm128_i8)(); // Opcode 0f c2
- void SSEOP(cmppd_r128_rm128_i8)(); // Opcode 66 0f c2
- void SSEOP(cmpss_r128_r128m32_i8)(); // Opcode f3 0f c2
- void SSEOP(pinsrw_r64_r16m16_i8)(); // Opcode 0f c4, 16bit register
- void SSEOP(pinsrw_r64_r32m16_i8)(); // Opcode 0f c4, 32bit register
- void SSEOP(pinsrw_r128_r32m16_i8)(); // Opcode 66 0f c4
- void SSEOP(pextrw_r16_r64_i8)(); // Opcode 0f c5
- void SSEOP(pextrw_r32_r64_i8)(); // Opcode 0f c5
- void SSEOP(pextrw_reg_r128_i8)(); // Opcode 66 0f c5
- void SSEOP(pminub_r64_rm64)(); // Opcode 0f da
- void SSEOP(pminub_r128_rm128)(); // Opcode 66 0f da
- void SSEOP(pmaxub_r64_rm64)(); // Opcode 0f de
- void SSEOP(pavgb_r64_rm64)(); // Opcode 0f e0
- void SSEOP(pavgw_r64_rm64)(); // Opcode 0f e3
- void SSEOP(pmulhuw_r64_rm64)(); // Opcode 0f e4
- void SSEOP(pminsw_r64_rm64)(); // Opcode 0f ea
- void SSEOP(pmaxsw_r64_rm64)(); // Opcode 0f ee
- void SSEOP(pmuludq_r64_rm64)(); // Opcode 0f f4
- void SSEOP(pmuludq_r128_rm128)(); // Opcode 66 0f f4
- void SSEOP(psadbw_r64_rm64)(); // Opcode 0f f6
- void SSEOP(psubq_r64_rm64)(); // Opcode 0f fb
- void SSEOP(psubq_r128_rm128)(); // Opcode 66 0f fb
- void SSEOP(pshufd_r128_rm128_i8)(); // Opcode 66 0f 70
- void SSEOP(pshuflw_r128_rm128_i8)(); // Opcode f2 0f 70
- void SSEOP(pshufhw_r128_rm128_i8)(); // Opcode f3 0f 70
- void SSEOP(packsswb_r128_rm128)(); // Opcode 66 0f 63
- void SSEOP(packssdw_r128_rm128)(); // Opcode 66 0f 6b
- void SSEOP(pcmpgtb_r128_rm128)(); // Opcode 66 0f 64
- void SSEOP(pcmpgtw_r128_rm128)(); // Opcode 66 0f 65
- void SSEOP(pcmpgtd_r128_rm128)(); // Opcode 66 0f 66
- void SSEOP(packuswb_r128_rm128)(); // Opcode 66 0f 67
- void SSEOP(punpckhbw_r128_rm128)(); // Opcode 66 0f 68
- void SSEOP(punpckhwd_r128_rm128)(); // Opcode 66 0f 69
- void SSEOP(unpckhdq_r128_rm128)(); // Opcode 66 0f 6a
- void SSEOP(punpckhqdq_r128_rm128)(); // Opcode 66 0f 6d
- void SSEOP(pcmpeqb_r128_rm128)(); // Opcode 66 0f 74
- void SSEOP(pcmpeqw_r128_rm128)(); // Opcode 66 0f 75
- void SSEOP(pcmpeqd_r128_rm128)(); // Opcode 66 0f 76
- void SSEOP(paddq_r128_rm128)(); // Opcode 66 0f d4
- void SSEOP(pmullw_r128_rm128)(); // Opcode 66 0f d5
- void SSEOP(paddb_r128_rm128)(); // Opcode 66 0f fc
- void SSEOP(paddw_r128_rm128)(); // Opcode 66 0f fd
- void SSEOP(paddd_r128_rm128)(); // Opcode 66 0f fe
- void SSEOP(psubusb_r128_rm128)(); // Opcode 66 0f d8
- void SSEOP(psubusw_r128_rm128)(); // Opcode 66 0f d9
- void SSEOP(pand_r128_rm128)(); // Opcode 66 0f db
- void SSEOP(pandn_r128_rm128)(); // Opcode 66 0f df
- void SSEOP(paddusb_r128_rm128)(); // Opcode 66 0f dc
- void SSEOP(paddusw_r128_rm128)(); // Opcode 66 0f dd
- void SSEOP(pmaxub_r128_rm128)(); // Opcode 66 0f de
- void SSEOP(pmulhuw_r128_rm128)(); // Opcode 66 0f e4
- void SSEOP(pmulhw_r128_rm128)(); // Opcode 66 0f e5
- void SSEOP(psubsb_r128_rm128)(); // Opcode 66 0f e8
- void SSEOP(psubsw_r128_rm128)(); // Opcode 66 0f e9
- void SSEOP(pminsw_r128_rm128)(); // Opcode 66 0f ea
- void SSEOP(pmaxsw_r128_rm128)(); // Opcode 66 0f ee
- void SSEOP(paddsb_r128_rm128)(); // Opcode 66 0f ec
- void SSEOP(paddsw_r128_rm128)(); // Opcode 66 0f ed
- void SSEOP(por_r128_rm128)(); // Opcode 66 0f eb
- void SSEOP(pxor_r128_rm128)(); // Opcode 66 0f ef
- void SSEOP(pmaddwd_r128_rm128)(); // Opcode 66 0f f5
- void SSEOP(psubb_r128_rm128)(); // Opcode 66 0f f8
- void SSEOP(psubw_r128_rm128)(); // Opcode 66 0f f9
- void SSEOP(psubd_r128_rm128)(); // Opcode 66 0f fa
- void SSEOP(psadbw_r128_rm128)(); // Opcode 66 0f f6
- void SSEOP(pavgb_r128_rm128)(); // Opcode 66 0f e0
- void SSEOP(pavgw_r128_rm128)(); // Opcode 66 0f e3
- void SSEOP(psrlw_r128_rm128)(); // Opcode 66 0f d1
- void SSEOP(psrld_r128_rm128)(); // Opcode 66 0f d2
- void SSEOP(psrlq_r128_rm128)(); // Opcode 66 0f d3
- void SSEOP(psllw_r128_rm128)(); // Opcode 66 0f f1
- void SSEOP(pslld_r128_rm128)(); // Opcode 66 0f f2
- void SSEOP(psllq_r128_rm128)(); // Opcode 66 0f f3
- void SSEOP(psraw_r128_rm128)(); // Opcode 66 0f e1
- void SSEOP(psrad_r128_rm128)(); // Opcode 66 0f e2
- void SSEOP(movntdq_m128_r128)(); // Opcode 66 0f e7
- void SSEOP(cvttpd2dq_r128_rm128)(); // Opcode 66 0f e6
- void SSEOP(movq_r128m64_r128)(); // Opcode 66 0f d6
- void SSEOP(addsubpd_r128_rm128)(); // Opcode 66 0f d0
- void SSEOP(haddpd_r128_rm128)(); // Opcode 66 0f 7c
- void SSEOP(hsubpd_r128_rm128)(); // Opcode 66 0f 7d
- void SSEOP(sqrtpd_r128_rm128)(); // Opcode 66 0f 51
- void SSEOP(cvtpi2pd_r128_rm64)(); // Opcode 66 0f 2a
- void SSEOP(cvttpd2pi_r64_rm128)(); // Opcode 66 0f 2c
- void SSEOP(cvtpd2pi_r64_rm128)(); // Opcode 66 0f 2d
- void SSEOP(cvtpd2ps_r128_rm128)(); // Opcode 66 0f 5a
- void SSEOP(cvtps2dq_r128_rm128)(); // Opcode 66 0f 5b
- void SSEOP(addpd_r128_rm128)(); // Opcode 66 0f 58
- void SSEOP(mulpd_r128_rm128)(); // Opcode 66 0f 59
- void SSEOP(subpd_r128_rm128)(); // Opcode 66 0f 5c
- void SSEOP(minpd_r128_rm128)(); // Opcode 66 0f 5d
- void SSEOP(divpd_r128_rm128)(); // Opcode 66 0f 5e
- void SSEOP(maxpd_r128_rm128)(); // Opcode 66 0f 5f
- void SSEOP(movntpd_m128_r128)(); // Opcode 66 0f 2b
- void SSEOP(movapd_r128_rm128)(); // Opcode 66 0f 28
- void SSEOP(movapd_rm128_r128)(); // Opcode 66 0f 29
- void SSEOP(movsd_r128_r128m64)(); // Opcode f2 0f 10
- void SSEOP(movsd_r128m64_r128)(); // Opcode f2 0f 11
- void SSEOP(movddup_r128_r128m64)(); // Opcode f2 0f 12
- void SSEOP(cvtsi2sd_r128_rm32)(); // Opcode f2 0f 2a
- void SSEOP(cvttsd2si_r32_r128m64)(); // Opcode f2 0f 2c
- void SSEOP(cvtsd2si_r32_r128m64)(); // Opcode f2 0f 2d
- void SSEOP(sqrtsd_r128_r128m64)(); // Opcode f2 0f 51
- void SSEOP(addsd_r128_r128m64)(); // Opcode f2 0f 58
- void SSEOP(mulsd_r128_r128m64)(); // Opcode f2 0f 59
- void SSEOP(cvtsd2ss_r128_r128m64)(); // Opcode f2 0f 5a
- void SSEOP(subsd_r128_r128m64)(); // Opcode f2 0f 5c
- void SSEOP(minsd_r128_r128m64)(); // Opcode f2 0f 5d
- void SSEOP(divsd_r128_r128m64)(); // Opcode f2 0f 5e
- void SSEOP(maxsd_r128_r128m64)(); // Opcode f2 0f 5f
- void SSEOP(haddps_r128_rm128)(); // Opcode f2 0f 7c
- void SSEOP(hsubps_r128_rm128)(); // Opcode f2 0f 7d
- void SSEOP(cmpsd_r128_r128m64_i8)(); // Opcode f2 0f c2
- void SSEOP(addsubps_r128_rm128)(); // Opcode f2 0f d0
- void SSEOP(movdq2q_r64_r128)(); // Opcode f2 0f d6
- void SSEOP(cvtpd2dq_r128_rm128)(); // Opcode f2 0f e6
- void SSEOP(lddqu_r128_m128)(); // Opcode f2 0f f0
- // x87 FPU
- INLINE void WRITE80( UINT32 ea, floatx80 t);
- INLINE void x87_set_stack_top( int top);
- INLINE void x87_set_tag( int reg, int tag);
- void x87_write_stack( int i, floatx80 value, int update_tag);
- INLINE void x87_set_stack_underflow();
- INLINE void x87_set_stack_overflow();
- INLINE void x87_write_cw( UINT16 cw);
- void x87_reset();
- void x87_fadd_m32real( UINT8 modrm);
- void x87_fadd_m64real( UINT8 modrm);
- void x87_fadd_st_sti( UINT8 modrm);
- void x87_fadd_sti_st( UINT8 modrm);
- void x87_faddp( UINT8 modrm);
- void x87_fiadd_m32int( UINT8 modrm);
- void x87_fiadd_m16int( UINT8 modrm);
- void x87_fsub_m32real( UINT8 modrm);
- void x87_fsub_m64real( UINT8 modrm);
- void x87_fsub_st_sti( UINT8 modrm);
- void x87_fsub_sti_st( UINT8 modrm);
- void x87_fsubp( UINT8 modrm);
- void x87_fisub_m32int( UINT8 modrm);
- void x87_fisub_m16int( UINT8 modrm);
- void x87_fsubr_m32real( UINT8 modrm);
- void x87_fsubr_m64real( UINT8 modrm);
- void x87_fsubr_st_sti( UINT8 modrm);
- void x87_fsubr_sti_st( UINT8 modrm);
- void x87_fsubrp( UINT8 modrm);
- void x87_fisubr_m32int( UINT8 modrm);
- void x87_fisubr_m16int( UINT8 modrm);
- void x87_fdiv_m32real( UINT8 modrm);
- void x87_fdiv_m64real( UINT8 modrm);
- void x87_fdiv_st_sti( UINT8 modrm);
- void fx87_fdiv_sti_st( UINT8 modrm);
- void x87_fdivp( UINT8 modrm);
- void x87_fidiv_m32int( UINT8 modrm);
- void x87_fidiv_m16int( UINT8 modrm);
- void x87_fdivr_m32real( UINT8 modrm);
- void x87_fdivr_m64real( UINT8 modrm);
- void x87_fdivr_st_sti( UINT8 modrm);
- void x87_fdivr_sti_st( UINT8 modrm);
- void x87_fdivrp( UINT8 modrm);
- void x87_fidivr_m32int( UINT8 modrm);
- void x87_fidivr_m16int( UINT8 modrm);
- void x87_fmul_m32real( UINT8 modrm);
- void x87_fmul_m64real( UINT8 modrm);
- void x87_fmul_st_sti( UINT8 modrm);
- void x87_fmul_sti_st( UINT8 modrm);
- void x87_fmulp( UINT8 modrm);
- void x87_fimul_m32int( UINT8 modrm);
- void x87_fimul_m16int( UINT8 modrm);
- void x87_fcmovb_sti( UINT8 modrm);
- void x87_fcmove_sti( UINT8 modrm);
- void x87_fcmovbe_sti( UINT8 modrm);
- void x87_fcmovu_sti( UINT8 modrm);
- void x87_fcmovnb_sti( UINT8 modrm);
- void x87_fcmovne_sti( UINT8 modrm);
- void x87_fcmovnbe_sti( UINT8 modrm);
- void x87_fcmovnu_sti( UINT8 modrm);
- void x87_fprem( UINT8 modrm);
- void x87_fprem1( UINT8 modrm);
- void x87_fsqrt( UINT8 modrm);
- void x87_f2xm1( UINT8 modrm);
- void x87_fyl2x( UINT8 modrm);
- void x87_fyl2xp1( UINT8 modrm);
- void x87_fptan( UINT8 modrm);
- void x87_fpatan( UINT8 modrm);
- void x87_fsin( UINT8 modrm);
- void x87_fcos( UINT8 modrm);
- void x87_fsincos( UINT8 modrm);
- void x87_fld_m32real( UINT8 modrm);
- void x87_fld_m64real( UINT8 modrm);
- void x87_fld_m80real( UINT8 modrm);
- void x87_fld_sti( UINT8 modrm);
- void x87_fild_m16int( UINT8 modrm);
- void x87_fild_m32int( UINT8 modrm);
- void x87_fild_m64int( UINT8 modrm);
- void x87_fbld( UINT8 modrm);
- void x87_fst_m32real( UINT8 modrm);
- void x87_fst_m64real( UINT8 modrm);
- void x87_fst_sti( UINT8 modrm);
- void x87_fstp_m32real( UINT8 modrm);
- void x87_fstp_m64real( UINT8 modrm);
- void x87_fstp_m80real( UINT8 modrm);
- void x87_fstp_sti( UINT8 modrm);
- void x87_fist_m16int( UINT8 modrm);
- void x87_fist_m32int( UINT8 modrm);
- void x87_fistp_m16int( UINT8 modrm);
- void x87_fistp_m32int( UINT8 modrm);
- void x87_fistp_m64int( UINT8 modrm);
- void x87_fbstp( UINT8 modrm);
- void x87_fld1( UINT8 modrm);
- void x87_fldl2t( UINT8 modrm);
- void x87_fldl2e( UINT8 modrm);
- void x87_fldpi( UINT8 modrm);
- void x87_fldlg2( UINT8 modrm);
- void x87_fldln2( UINT8 modrm);
- void x87_fldz( UINT8 modrm);
- void x87_fnop( UINT8 modrm);
- void x87_fchs( UINT8 modrm);
- void x87_fabs( UINT8 modrm);
- void x87_fscale( UINT8 modrm);
- void x87_frndint( UINT8 modrm);
- void x87_fxtract( UINT8 modrm);
- void x87_ftst( UINT8 modrm);
- void x87_fxam( UINT8 modrm);
- void x87_ficom_m16int( UINT8 modrm);
- void x87_ficom_m32int( UINT8 modrm);
- void x87_ficomp_m16int( UINT8 modrm);
- void x87_ficomp_m32int( UINT8 modrm);
- void x87_fcom_m32real( UINT8 modrm);
- void x87_fcom_m64real( UINT8 modrm);
- void x87_fcom_sti( UINT8 modrm);
- void x87_fcomp_m32real( UINT8 modrm);
- void x87_fcomp_m64real( UINT8 modrm);
- void x87_fcomp_sti( UINT8 modrm);
- void x87_fcomi_sti( UINT8 modrm);
- void x87_fcomip_sti( UINT8 modrm);
- void x87_fucomi_sti( UINT8 modrm);
- void x87_fucomip_sti( UINT8 modrm);
- void x87_fcompp( UINT8 modrm);
- void x87_fucom_sti( UINT8 modrm);
- void x87_fucomp_sti( UINT8 modrm);
- void x87_fucompp( UINT8 modrm);
- void x87_fdecstp( UINT8 modrm);
- void x87_fincstp( UINT8 modrm);
- void x87_fclex( UINT8 modrm);
- void x87_ffree( UINT8 modrm);
- void x87_finit( UINT8 modrm);
- void x87_fldcw( UINT8 modrm);
- void x87_fstcw( UINT8 modrm);
- void x87_fldenv( UINT8 modrm);
- void x87_fstenv( UINT8 modrm);
- void x87_fsave( UINT8 modrm);
- void x87_frstor( UINT8 modrm);
- void x87_fxch( UINT8 modrm);
- void x87_fxch_sti( UINT8 modrm);
- void x87_fstsw_ax( UINT8 modrm);
- void x87_fstsw_m2byte( UINT8 modrm);
- void x87_invalid( UINT8 modrm);
- void I386OP(x87_group_d8);();
- void I386OP(x87_group_d9);();
- void I386OP(x87_group_da);();
- void I386OP(x87_group_db);();
- void I386OP(x87_group_dc);();
- void I386OP(x87_group_dd);();
- void I386OP(x87_group_de);();
- void I386OP(x87_group_df);();
- void build_x87_opcode_table_d8();
- void build_x87_opcode_table_d9();
- void build_x87_opcode_table_da();
- void build_x87_opcode_table_db();
- void build_x87_opcode_table_dc();
- void build_x87_opcode_table_dd();
- void build_x87_opcode_table_de();
- void build_x87_opcode_table_df();
- void build_x87_opcode_table();
-
- // Inline Utilities.
- INLINE UINT8 SaturatedSignedWordToUnsignedByte(INT16 word);
- INLINE UINT16 SaturatedSignedDwordToUnsignedWord(INT32 dword);
- //
- INLINE int translate_address(int pl, int type, UINT32 *address, UINT32 *error);
- INLINE UINT32 i386_translate(int segment, UINT32 ip, int rwn);
-
- INLINE UINT32 FETCH32();
- INLINE UINT32 READ32(UINT32 ea);
- INLINE UINT32 READ32PL0(UINT32 ea);
- INLINE UINT32 OR32(UINT32 dst, UINT32 src);
- INLINE UINT32 AND32(UINT32 dst, UINT32 src);
- INLINE UINT32 XOR32(UINT32 dst, UINT32 src);
- INLINE UINT32 SBB32(UINT32 dst, UINT32 src, UINT32 b);
- INLINE UINT32 ADC32(UINT32 dst, UINT32 src, UINT32 c);
- INLINE UINT32 INC32(UINT32 dst);
- INLINE UINT32 DEC32(UINT32 dst);
- INLINE UINT32 POP32();
- INLINE UINT32 READPORT32( offs_t port);
- INLINE UINT8 FETCH();
- INLINE UINT8 READ8(UINT32 ea);
- INLINE UINT8 READ8PL0(UINT32 ea);
- INLINE UINT8 OR8(UINT8 dst, UINT8 src);
- INLINE UINT8 AND8(UINT8 dst, UINT8 src);
- INLINE UINT8 XOR8(UINT8 dst, UINT8 src);
- INLINE UINT8 SBB8(UINT8 dst, UINT8 src, UINT8 b);
- INLINE UINT8 ADC8(UINT8 dst, UINT8 src, UINT8 c);
- INLINE UINT8 DEC8(UINT8 dst);
- INLINE UINT8 POP8();
- INLINE UINT8 READPORT8( offs_t port);
- INLINE UINT16 FETCH16();
- INLINE UINT16 READ16(UINT32 ea);
- INLINE UINT16 READ16PL0(UINT32 ea);
- INLINE UINT16 OR16(UINT16 dst, UINT16 src);
- INLINE UINT16 AND16(UINT16 dst, UINT16 src);
- INLINE UINT16 XOR16(UINT16 dst, UINT16 src);
- INLINE UINT16 SBB16(UINT16 dst, UINT16 src, UINT16 b);
- INLINE UINT16 ADC16(UINT16 dst, UINT16 src, UINT8 c);
- INLINE UINT16 INC16(UINT16 dst);
- INLINE UINT16 DEC16(UINT16 dst);
- INLINE UINT16 POP16();
- INLINE UINT16 READPORT16( offs_t port);
- INLINE UINT64 READ64(UINT32 ea);
- INLINE UINT64 MSR_READ(UINT32 offset,UINT8 *valid_msr);
-
- // Utilities around FPU.
- INLINE int floatx80_is_zero(floatx80 fx);
- INLINE int floatx80_is_inf(floatx80 fx);
- INLINE int floatx80_is_denormal(floatx80 fx);
- INLINE void x87_set_stack_top( int top);
- INLINE void x87_set_tag( int reg, int tag);
- void x87_write_stack( int i, floatx80 value, int update_tag);
- int x87_inc_stack();
- int x87_dec_stack();
- int x87_check_exceptions();
-
- INLINE floatx80 ffloatx80_abs(floatx80 fx);
- INLINE floatx80 fdouble_to_fx80(double in);
- INLINE floatx80 fREAD80( UINT32 ea);
- floatx80 fx87_add( floatx80 a, floatx80 b);
- floatx80 fx87_sub( floatx80 a, floatx80 b);
- floatx80 x87_mul( floatx80 a, floatx80 b);
- floatx80 x87_div( floatx80 a, floatx80 b);
-
-protected:
- void I386OP(decode_two_byte)()
- UINT64 pentium_msr_read(i386_state *cpustate, UINT32 offset,UINT8 *valid_msr);;
- UINT64 p6_msr_read(i386_state *cpustate, UINT32 offset,UINT8 *valid_msr);;
- UINT64 piv_msr_read(i386_state *cpustate, UINT32 offset,UINT8 *valid_msr);;
-
- INLINE UINT32 i386_translate(int segment, UINT32 ip, int rwn);;
- INLINE vtlb_entry get_permissions(UINT32 pte, int wp);;
- void pentium_msr_write(i386_state *cpustate, UINT32 offset, UINT64 data, UINT8 *valid_msr);;
- void p6_msr_write(i386_state *cpustate, UINT32 offset, UINT64 data, UINT8 *valid_msr);;
- void piv_msr_write(i386_state *cpustate, UINT32 offset, UINT64 data, UINT8 *valid_msr);;
- void i386_load_call_gate(I386_CALL_GATE *gate);;
- void i386_set_descriptor_accessed( UINT16 selector);;
- void i386_load_segment_descriptor( int segment );
- void set_flags( UINT32 f );;
- void sib_byte(UINT8 mod, UINT32* out_ea, UINT8* out_segment);;
- void modrm_to_EA(UINT8 mod_rm, UINT32;* out_ea, UINT8* out_segment);;
- void i386_check_sreg_validity(int reg);;
- void i386_sreg_load( UINT16 selector, UINT8 reg, bool *fault);
- void i386_trap(int irq, int irq_gate, int trap_level);
- void i386_trap_with_error(int irq, int irq_gate, int trap_level, UINT32 error);
- void i286_task_switch( UINT16 selector, UINT8 nested);
- void i386_task_switch( UINT16 selector, UINT8 nested);
-
- void i386_protected_mode_jump( UINT16 seg, UINT32 off, int indirect, int operand32);
- void i386_protected_mode_call( UINT16 seg, UINT32 off, int indirect, int operand32);
- void i386_protected_mode_retf(UINT8 count, UINT8 operand32);
- void i386_protected_mode_iret(int operand32);
- void build_cycle_table();;;
- void report_invalid_opcode();;;
- void report_invalid_modrm( const char* opcode, UINT8 modrm);
- void i386_postload();;;
-
-};
-
-#endif
+++ /dev/null
-// license:BSD-3-Clause
-// copyright-holders:Ville Linde, Barry Rodewald, Carl, Phil Bennett
-
-#ifndef __LIB_I386_OPS_TABLE_H__
-#define __LIB_I386_OPS_TABLE_H__
-#include "./i386ops.h"
-
-#define I386OP_A(name) &I386_OPS_BASE::##i386_name
-#define I486OP_A(name) &I386_OPS_BASE::##i486_name
-#define PENTIUMOP_A(name) &I386_OPS_BASE::##pentium_name
-#define MMXOP_A(name) &I386_OPS_BASE::##mmx_name
-#define SSEOP_A(name) &I386_OPS_BASE::##sse_name
-
-const X86_OPCODE I386_OPS_BASE::x86_opcode_table[] =
-{
-// Opcode Flags 16-bit handler 32-bit handler
- { 0x00, OP_I386, I386OP_A(add_rm8_r8), I386OP_A(add_rm8_r8), true },
- { 0x01, OP_I386, I386OP_A(add_rm16_r16), I386OP_A(add_rm32_r32), true },
- { 0x02, OP_I386, I386OP_A(add_r8_rm8), I386OP_A(add_r8_rm8), false},
- { 0x03, OP_I386, I386OP_A(add_r16_rm16), I386OP_A(add_r32_rm32), false},
- { 0x04, OP_I386, I386OP_A(add_al_i8), I386OP_A(add_al_i8), false},
- { 0x05, OP_I386, I386OP_A(add_ax_i16), I386OP_A(add_eax_i32), false},
- { 0x06, OP_I386, I386OP_A(push_es16), I386OP_A(push_es32), false},
- { 0x07, OP_I386, I386OP_A(pop_es16), I386OP_A(pop_es32), false},
- { 0x08, OP_I386, I386OP_A(or_rm8_r8), I386OP_A(or_rm8_r8), true },
- { 0x09, OP_I386, I386OP_A(or_rm16_r16), I386OP_A(or_rm32_r32), true },
- { 0x0A, OP_I386, I386OP_A(or_r8_rm8), I386OP_A(or_r8_rm8), false},
- { 0x0B, OP_I386, I386OP_A(or_r16_rm16), I386OP_A(or_r32_rm32), false},
- { 0x0C, OP_I386, I386OP_A(or_al_i8), I386OP_A(or_al_i8), false},
- { 0x0D, OP_I386, I386OP_A(or_ax_i16), I386OP_A(or_eax_i32), false},
- { 0x0E, OP_I386, I386OP_A(push_cs16), I386OP_A(push_cs32), false},
- { 0x0F, OP_I386, I386OP_A(decode_two_byte), I386OP_A(decode_two_byte), true },
- { 0x10, OP_I386, I386OP_A(adc_rm8_r8), I386OP_A(adc_rm8_r8), true },
- { 0x11, OP_I386, I386OP_A(adc_rm16_r16), I386OP_A(adc_rm32_r32), true },
- { 0x12, OP_I386, I386OP_A(adc_r8_rm8), I386OP_A(adc_r8_rm8), false},
- { 0x13, OP_I386, I386OP_A(adc_r16_rm16), I386OP_A(adc_r32_rm32), false},
- { 0x14, OP_I386, I386OP_A(adc_al_i8), I386OP_A(adc_al_i8), false},
- { 0x15, OP_I386, I386OP_A(adc_ax_i16), I386OP_A(adc_eax_i32), false},
- { 0x16, OP_I386, I386OP_A(push_ss16), I386OP_A(push_ss32), false},
- { 0x17, OP_I386, I386OP_A(pop_ss16), I386OP_A(pop_ss32), false},
- { 0x18, OP_I386, I386OP_A(sbb_rm8_r8), I386OP_A(sbb_rm8_r8), true },
- { 0x19, OP_I386, I386OP_A(sbb_rm16_r16), I386OP_A(sbb_rm32_r32), true },
- { 0x1A, OP_I386, I386OP_A(sbb_r8_rm8), I386OP_A(sbb_r8_rm8), false},
- { 0x1B, OP_I386, I386OP_A(sbb_r16_rm16), I386OP_A(sbb_r32_rm32), false},
- { 0x1C, OP_I386, I386OP_A(sbb_al_i8), I386OP_A(sbb_al_i8), false},
- { 0x1D, OP_I386, I386OP_A(sbb_ax_i16), I386OP_A(sbb_eax_i32), false},
- { 0x1E, OP_I386, I386OP_A(push_ds16), I386OP_A(push_ds32), false},
- { 0x1F, OP_I386, I386OP_A(pop_ds16), I386OP_A(pop_ds32), false},
- { 0x20, OP_I386, I386OP_A(and_rm8_r8), I386OP_A(and_rm8_r8), true },
- { 0x21, OP_I386, I386OP_A(and_rm16_r16), I386OP_A(and_rm32_r32), true },
- { 0x22, OP_I386, I386OP_A(and_r8_rm8), I386OP_A(and_r8_rm8), false},
- { 0x23, OP_I386, I386OP_A(and_r16_rm16), I386OP_A(and_r32_rm32), false},
- { 0x24, OP_I386, I386OP_A(and_al_i8), I386OP_A(and_al_i8), false},
- { 0x25, OP_I386, I386OP_A(and_ax_i16), I386OP_A(and_eax_i32), false},
- { 0x26, OP_I386, I386OP_A(segment_ES), I386OP_A(segment_ES), false},
- { 0x27, OP_I386, I386OP_A(daa), I386OP_A(daa), false},
- { 0x28, OP_I386, I386OP_A(sub_rm8_r8), I386OP_A(sub_rm8_r8), true },
- { 0x29, OP_I386, I386OP_A(sub_rm16_r16), I386OP_A(sub_rm32_r32), true },
- { 0x2A, OP_I386, I386OP_A(sub_r8_rm8), I386OP_A(sub_r8_rm8), false},
- { 0x2B, OP_I386, I386OP_A(sub_r16_rm16), I386OP_A(sub_r32_rm32), false},
- { 0x2C, OP_I386, I386OP_A(sub_al_i8), I386OP_A(sub_al_i8), false},
- { 0x2D, OP_I386, I386OP_A(sub_ax_i16), I386OP_A(sub_eax_i32), false},
- { 0x2E, OP_I386, I386OP_A(segment_CS), I386OP_A(segment_CS), false},
- { 0x2F, OP_I386, I386OP_A(das), I386OP_A(das), false},
- { 0x30, OP_I386, I386OP_A(xor_rm8_r8), I386OP_A(xor_rm8_r8), true },
- { 0x31, OP_I386, I386OP_A(xor_rm16_r16), I386OP_A(xor_rm32_r32), true },
- { 0x32, OP_I386, I386OP_A(xor_r8_rm8), I386OP_A(xor_r8_rm8), false},
- { 0x33, OP_I386, I386OP_A(xor_r16_rm16), I386OP_A(xor_r32_rm32), false},
- { 0x34, OP_I386, I386OP_A(xor_al_i8), I386OP_A(xor_al_i8), false},
- { 0x35, OP_I386, I386OP_A(xor_ax_i16), I386OP_A(xor_eax_i32), false},
- { 0x36, OP_I386, I386OP_A(segment_SS), I386OP_A(segment_SS), false},
- { 0x37, OP_I386, I386OP_A(aaa), I386OP_A(aaa), false},
- { 0x38, OP_I386, I386OP_A(cmp_rm8_r8), I386OP_A(cmp_rm8_r8), false},
- { 0x39, OP_I386, I386OP_A(cmp_rm16_r16), I386OP_A(cmp_rm32_r32), false},
- { 0x3A, OP_I386, I386OP_A(cmp_r8_rm8), I386OP_A(cmp_r8_rm8), false},
- { 0x3B, OP_I386, I386OP_A(cmp_r16_rm16), I386OP_A(cmp_r32_rm32), false},
- { 0x3C, OP_I386, I386OP_A(cmp_al_i8), I386OP_A(cmp_al_i8), false},
- { 0x3D, OP_I386, I386OP_A(cmp_ax_i16), I386OP_A(cmp_eax_i32), false},
- { 0x3E, OP_I386, I386OP_A(segment_DS), I386OP_A(segment_DS), false},
- { 0x3F, OP_I386, I386OP_A(aas), I386OP_A(aas), false},
- { 0x40, OP_I386, I386OP_A(inc_ax), I386OP_A(inc_eax), false},
- { 0x41, OP_I386, I386OP_A(inc_cx), I386OP_A(inc_ecx), false},
- { 0x42, OP_I386, I386OP_A(inc_dx), I386OP_A(inc_edx), false},
- { 0x43, OP_I386, I386OP_A(inc_bx), I386OP_A(inc_ebx), false},
- { 0x44, OP_I386, I386OP_A(inc_sp), I386OP_A(inc_esp), false},
- { 0x45, OP_I386, I386OP_A(inc_bp), I386OP_A(inc_ebp), false},
- { 0x46, OP_I386, I386OP_A(inc_si), I386OP_A(inc_esi), false},
- { 0x47, OP_I386, I386OP_A(inc_di), I386OP_A(inc_edi), false},
- { 0x48, OP_I386, I386OP_A(dec_ax), I386OP_A(dec_eax), false},
- { 0x49, OP_I386, I386OP_A(dec_cx), I386OP_A(dec_ecx), false},
- { 0x4A, OP_I386, I386OP_A(dec_dx), I386OP_A(dec_edx), false},
- { 0x4B, OP_I386, I386OP_A(dec_bx), I386OP_A(dec_ebx), false},
- { 0x4C, OP_I386, I386OP_A(dec_sp), I386OP_A(dec_esp), false},
- { 0x4D, OP_I386, I386OP_A(dec_bp), I386OP_A(dec_ebp), false},
- { 0x4E, OP_I386, I386OP_A(dec_si), I386OP_A(dec_esi), false},
- { 0x4F, OP_I386, I386OP_A(dec_di), I386OP_A(dec_edi), false},
- { 0x50, OP_I386, I386OP_A(push_ax), I386OP_A(push_eax), false},
- { 0x51, OP_I386, I386OP_A(push_cx), I386OP_A(push_ecx), false},
- { 0x52, OP_I386, I386OP_A(push_dx), I386OP_A(push_edx), false},
- { 0x53, OP_I386, I386OP_A(push_bx), I386OP_A(push_ebx), false},
- { 0x54, OP_I386, I386OP_A(push_sp), I386OP_A(push_esp), false},
- { 0x55, OP_I386, I386OP_A(push_bp), I386OP_A(push_ebp), false},
- { 0x56, OP_I386, I386OP_A(push_si), I386OP_A(push_esi), false},
- { 0x57, OP_I386, I386OP_A(push_di), I386OP_A(push_edi), false},
- { 0x58, OP_I386, I386OP_A(pop_ax), I386OP_A(pop_eax), false},
- { 0x59, OP_I386, I386OP_A(pop_cx), I386OP_A(pop_ecx), false},
- { 0x5A, OP_I386, I386OP_A(pop_dx), I386OP_A(pop_edx), false},
- { 0x5B, OP_I386, I386OP_A(pop_bx), I386OP_A(pop_ebx), false},
- { 0x5C, OP_I386, I386OP_A(pop_sp), I386OP_A(pop_esp), false},
- { 0x5D, OP_I386, I386OP_A(pop_bp), I386OP_A(pop_ebp), false},
- { 0x5E, OP_I386, I386OP_A(pop_si), I386OP_A(pop_esi), false},
- { 0x5F, OP_I386, I386OP_A(pop_di), I386OP_A(pop_edi), false},
- { 0x60, OP_I386, I386OP_A(pusha), I386OP_A(pushad), false},
- { 0x61, OP_I386, I386OP_A(popa), I386OP_A(popad), false},
- { 0x62, OP_I386, I386OP_A(bound_r16_m16_m16), I386OP_A(bound_r32_m32_m32), false},
- { 0x63, OP_I386, I386OP_A(arpl), I386OP_A(arpl), false},
- { 0x64, OP_I386, I386OP_A(segment_FS), I386OP_A(segment_FS), false},
- { 0x65, OP_I386, I386OP_A(segment_GS), I386OP_A(segment_GS), false},
- { 0x66, OP_I386, I386OP_A(operand_size), I386OP_A(operand_size), false},
- { 0x67, OP_I386, I386OP_A(address_size), I386OP_A(address_size), false},
- { 0x68, OP_I386, I386OP_A(push_i16), I386OP_A(push_i32), false},
- { 0x69, OP_I386, I386OP_A(imul_r16_rm16_i16), I386OP_A(imul_r32_rm32_i32), false},
- { 0x6A, OP_I386, I386OP_A(push_i8), I386OP_A(push_i8), false},
- { 0x6B, OP_I386, I386OP_A(imul_r16_rm16_i8), I386OP_A(imul_r32_rm32_i8), false},
- { 0x6C, OP_I386, I386OP_A(insb), I386OP_A(insb), false},
- { 0x6D, OP_I386, I386OP_A(insw), I386OP_A(insd), false},
- { 0x6E, OP_I386, I386OP_A(outsb), I386OP_A(outsb), false},
- { 0x6F, OP_I386, I386OP_A(outsw), I386OP_A(outsd), false},
- { 0x70, OP_I386, I386OP_A(jo_rel8), I386OP_A(jo_rel8), false},
- { 0x71, OP_I386, I386OP_A(jno_rel8), I386OP_A(jno_rel8), false},
- { 0x72, OP_I386, I386OP_A(jc_rel8), I386OP_A(jc_rel8), false},
- { 0x73, OP_I386, I386OP_A(jnc_rel8), I386OP_A(jnc_rel8), false},
- { 0x74, OP_I386, I386OP_A(jz_rel8), I386OP_A(jz_rel8), false},
- { 0x75, OP_I386, I386OP_A(jnz_rel8), I386OP_A(jnz_rel8), false},
- { 0x76, OP_I386, I386OP_A(jbe_rel8), I386OP_A(jbe_rel8), false},
- { 0x77, OP_I386, I386OP_A(ja_rel8), I386OP_A(ja_rel8), false},
- { 0x78, OP_I386, I386OP_A(js_rel8), I386OP_A(js_rel8), false},
- { 0x79, OP_I386, I386OP_A(jns_rel8), I386OP_A(jns_rel8), false},
- { 0x7A, OP_I386, I386OP_A(jp_rel8), I386OP_A(jp_rel8), false},
- { 0x7B, OP_I386, I386OP_A(jnp_rel8), I386OP_A(jnp_rel8), false},
- { 0x7C, OP_I386, I386OP_A(jl_rel8), I386OP_A(jl_rel8), false},
- { 0x7D, OP_I386, I386OP_A(jge_rel8), I386OP_A(jge_rel8), false},
- { 0x7E, OP_I386, I386OP_A(jle_rel8), I386OP_A(jle_rel8), false},
- { 0x7F, OP_I386, I386OP_A(jg_rel8), I386OP_A(jg_rel8), false},
- { 0x80, OP_I386, I386OP_A(group80_8), I386OP_A(group80_8), true },
- { 0x81, OP_I386, I386OP_A(group81_16), I386OP_A(group81_32), true },
- { 0x82, OP_I386, I386OP_A(group80_8), I386OP_A(group80_8), true },
- { 0x83, OP_I386, I386OP_A(group83_16), I386OP_A(group83_32), true },
- { 0x84, OP_I386, I386OP_A(test_rm8_r8), I386OP_A(test_rm8_r8), false},
- { 0x85, OP_I386, I386OP_A(test_rm16_r16), I386OP_A(test_rm32_r32), false},
- { 0x86, OP_I386, I386OP_A(xchg_r8_rm8), I386OP_A(xchg_r8_rm8), true },
- { 0x87, OP_I386, I386OP_A(xchg_r16_rm16), I386OP_A(xchg_r32_rm32), true },
- { 0x88, OP_I386, I386OP_A(mov_rm8_r8), I386OP_A(mov_rm8_r8), false},
- { 0x89, OP_I386, I386OP_A(mov_rm16_r16), I386OP_A(mov_rm32_r32), false},
- { 0x8A, OP_I386, I386OP_A(mov_r8_rm8), I386OP_A(mov_r8_rm8), false},
- { 0x8B, OP_I386, I386OP_A(mov_r16_rm16), I386OP_A(mov_r32_rm32), false},
- { 0x8C, OP_I386, I386OP_A(mov_rm16_sreg), I386OP_A(mov_rm16_sreg), false},
- { 0x8D, OP_I386, I386OP_A(lea16), I386OP_A(lea32), false},
- { 0x8E, OP_I386, I386OP_A(mov_sreg_rm16), I386OP_A(mov_sreg_rm16), false},
- { 0x8F, OP_I386, I386OP_A(pop_rm16), I386OP_A(pop_rm32), false},
- { 0x90, OP_I386, I386OP_A(nop), I386OP_A(nop), false},
- { 0x91, OP_I386, I386OP_A(xchg_ax_cx), I386OP_A(xchg_eax_ecx), false},
- { 0x92, OP_I386, I386OP_A(xchg_ax_dx), I386OP_A(xchg_eax_edx), false},
- { 0x93, OP_I386, I386OP_A(xchg_ax_bx), I386OP_A(xchg_eax_ebx), false},
- { 0x94, OP_I386, I386OP_A(xchg_ax_sp), I386OP_A(xchg_eax_esp), false},
- { 0x95, OP_I386, I386OP_A(xchg_ax_bp), I386OP_A(xchg_eax_ebp), false},
- { 0x96, OP_I386, I386OP_A(xchg_ax_si), I386OP_A(xchg_eax_esi), false},
- { 0x97, OP_I386, I386OP_A(xchg_ax_di), I386OP_A(xchg_eax_edi), false},
- { 0x98, OP_I386, I386OP_A(cbw), I386OP_A(cwde), false},
- { 0x99, OP_I386, I386OP_A(cwd), I386OP_A(cdq), false},
- { 0x9A, OP_I386, I386OP_A(call_abs16), I386OP_A(call_abs32), false},
- { 0x9B, OP_I386, I386OP_A(wait), I386OP_A(wait), false},
- { 0x9C, OP_I386, I386OP_A(pushf), I386OP_A(pushfd), false},
- { 0x9D, OP_I386, I386OP_A(popf), I386OP_A(popfd), false},
- { 0x9E, OP_I386, I386OP_A(sahf), I386OP_A(sahf), false},
- { 0x9F, OP_I386, I386OP_A(lahf), I386OP_A(lahf), false},
- { 0xA0, OP_I386, I386OP_A(mov_al_m8), I386OP_A(mov_al_m8), false},
- { 0xA1, OP_I386, I386OP_A(mov_ax_m16), I386OP_A(mov_eax_m32), false},
- { 0xA2, OP_I386, I386OP_A(mov_m8_al), I386OP_A(mov_m8_al), false},
- { 0xA3, OP_I386, I386OP_A(mov_m16_ax), I386OP_A(mov_m32_eax), false},
- { 0xA4, OP_I386, I386OP_A(movsb), I386OP_A(movsb), false},
- { 0xA5, OP_I386, I386OP_A(movsw), I386OP_A(movsd), false},
- { 0xA6, OP_I386, I386OP_A(cmpsb), I386OP_A(cmpsb), false},
- { 0xA7, OP_I386, I386OP_A(cmpsw), I386OP_A(cmpsd), false},
- { 0xA8, OP_I386, I386OP_A(test_al_i8), I386OP_A(test_al_i8), false},
- { 0xA9, OP_I386, I386OP_A(test_ax_i16), I386OP_A(test_eax_i32), false},
- { 0xAA, OP_I386, I386OP_A(stosb), I386OP_A(stosb), false},
- { 0xAB, OP_I386, I386OP_A(stosw), I386OP_A(stosd), false},
- { 0xAC, OP_I386, I386OP_A(lodsb), I386OP_A(lodsb), false},
- { 0xAD, OP_I386, I386OP_A(lodsw), I386OP_A(lodsd), false},
- { 0xAE, OP_I386, I386OP_A(scasb), I386OP_A(scasb), false},
- { 0xAF, OP_I386, I386OP_A(scasw), I386OP_A(scasd), false},
- { 0xB0, OP_I386, I386OP_A(mov_al_i8), I386OP_A(mov_al_i8), false},
- { 0xB1, OP_I386, I386OP_A(mov_cl_i8), I386OP_A(mov_cl_i8), false},
- { 0xB2, OP_I386, I386OP_A(mov_dl_i8), I386OP_A(mov_dl_i8), false},
- { 0xB3, OP_I386, I386OP_A(mov_bl_i8), I386OP_A(mov_bl_i8), false},
- { 0xB4, OP_I386, I386OP_A(mov_ah_i8), I386OP_A(mov_ah_i8), false},
- { 0xB5, OP_I386, I386OP_A(mov_ch_i8), I386OP_A(mov_ch_i8), false},
- { 0xB6, OP_I386, I386OP_A(mov_dh_i8), I386OP_A(mov_dh_i8), false},
- { 0xB7, OP_I386, I386OP_A(mov_bh_i8), I386OP_A(mov_bh_i8), false},
- { 0xB8, OP_I386, I386OP_A(mov_ax_i16), I386OP_A(mov_eax_i32), false},
- { 0xB9, OP_I386, I386OP_A(mov_cx_i16), I386OP_A(mov_ecx_i32), false},
- { 0xBA, OP_I386, I386OP_A(mov_dx_i16), I386OP_A(mov_edx_i32), false},
- { 0xBB, OP_I386, I386OP_A(mov_bx_i16), I386OP_A(mov_ebx_i32), false},
- { 0xBC, OP_I386, I386OP_A(mov_sp_i16), I386OP_A(mov_esp_i32), false},
- { 0xBD, OP_I386, I386OP_A(mov_bp_i16), I386OP_A(mov_ebp_i32), false},
- { 0xBE, OP_I386, I386OP_A(mov_si_i16), I386OP_A(mov_esi_i32), false},
- { 0xBF, OP_I386, I386OP_A(mov_di_i16), I386OP_A(mov_edi_i32), false},
- { 0xC0, OP_I386, I386OP_A(groupC0_8), I386OP_A(groupC0_8), false},
- { 0xC1, OP_I386, I386OP_A(groupC1_16), I386OP_A(groupC1_32), false},
- { 0xC2, OP_I386, I386OP_A(ret_near16_i16), I386OP_A(ret_near32_i16), false},
- { 0xC3, OP_I386, I386OP_A(ret_near16), I386OP_A(ret_near32), false},
- { 0xC4, OP_I386, I386OP_A(les16), I386OP_A(les32), false},
- { 0xC5, OP_I386, I386OP_A(lds16), I386OP_A(lds32), false},
- { 0xC6, OP_I386, I386OP_A(mov_rm8_i8), I386OP_A(mov_rm8_i8), false},
- { 0xC7, OP_I386, I386OP_A(mov_rm16_i16), I386OP_A(mov_rm32_i32), false},
- { 0xC8, OP_I386, I386OP_A(enter16), I386OP_A(enter32), false},
- { 0xC9, OP_I386, I386OP_A(leave16), I386OP_A(leave32), false},
- { 0xCA, OP_I386, I386OP_A(retf_i16), I386OP_A(retf_i32), false},
- { 0xCB, OP_I386, I386OP_A(retf16), I386OP_A(retf32), false},
- { 0xCC, OP_I386, I386OP_A(int3), I386OP_A(int3), false},
- { 0xCD, OP_I386, I386OP_A(int), I386OP_A(int), false},
- { 0xCE, OP_I386, I386OP_A(into), I386OP_A(into), false},
- { 0xCF, OP_I386, I386OP_A(iret16), I386OP_A(iret32), false},
- { 0xD0, OP_I386, I386OP_A(groupD0_8), I386OP_A(groupD0_8), false},
- { 0xD1, OP_I386, I386OP_A(groupD1_16), I386OP_A(groupD1_32), false},
- { 0xD2, OP_I386, I386OP_A(groupD2_8), I386OP_A(groupD2_8), false},
- { 0xD3, OP_I386, I386OP_A(groupD3_16), I386OP_A(groupD3_32), false},
- { 0xD4, OP_I386, I386OP_A(aam), I386OP_A(aam), false},
- { 0xD5, OP_I386, I386OP_A(aad), I386OP_A(aad), false},
- { 0xD6, OP_I386, I386OP_A(setalc), I386OP_A(setalc), false},
- { 0xD7, OP_I386, I386OP_A(xlat), I386OP_A(xlat), false},
- { 0xD8, OP_I386, I386OP_A(escape), I386OP_A(escape), false},
- { 0xD9, OP_I386, I386OP_A(escape), I386OP_A(escape), false},
- { 0xDA, OP_I386, I386OP_A(escape), I386OP_A(escape), false},
- { 0xDB, OP_I386, I386OP_A(escape), I386OP_A(escape), false},
- { 0xDC, OP_I386, I386OP_A(escape), I386OP_A(escape), false},
- { 0xDD, OP_I386, I386OP_A(escape), I386OP_A(escape), false},
- { 0xDE, OP_I386, I386OP_A(escape), I386OP_A(escape), false},
- { 0xDF, OP_I386, I386OP_A(escape), I386OP_A(escape), false},
- { 0xD8, OP_FPU, I386OP_A(x87_group_d8), I386OP_A(x87_group_d8), false},
- { 0xD9, OP_FPU, I386OP_A(x87_group_d9), I386OP_A(x87_group_d9), false},
- { 0xDA, OP_FPU, I386OP_A(x87_group_da), I386OP_A(x87_group_da), false},
- { 0xDB, OP_FPU, I386OP_A(x87_group_db), I386OP_A(x87_group_db), false},
- { 0xDC, OP_FPU, I386OP_A(x87_group_dc), I386OP_A(x87_group_dc), false},
- { 0xDD, OP_FPU, I386OP_A(x87_group_dd), I386OP_A(x87_group_dd), false},
- { 0xDE, OP_FPU, I386OP_A(x87_group_de), I386OP_A(x87_group_de), false},
- { 0xDF, OP_FPU, I386OP_A(x87_group_df), I386OP_A(x87_group_df), false},
- { 0xE0, OP_I386, I386OP_A(loopne16), I386OP_A(loopne32), false},
- { 0xE1, OP_I386, I386OP_A(loopz16), I386OP_A(loopz32), false},
- { 0xE2, OP_I386, I386OP_A(loop16), I386OP_A(loop32), false},
- { 0xE3, OP_I386, I386OP_A(jcxz16), I386OP_A(jcxz32), false},
- { 0xE4, OP_I386, I386OP_A(in_al_i8), I386OP_A(in_al_i8), false},
- { 0xE5, OP_I386, I386OP_A(in_ax_i8), I386OP_A(in_eax_i8), false},
- { 0xE6, OP_I386, I386OP_A(out_al_i8), I386OP_A(out_al_i8), false},
- { 0xE7, OP_I386, I386OP_A(out_ax_i8), I386OP_A(out_eax_i8), false},
- { 0xE8, OP_I386, I386OP_A(call_rel16), I386OP_A(call_rel32), false},
- { 0xE9, OP_I386, I386OP_A(jmp_rel16), I386OP_A(jmp_rel32), false},
- { 0xEA, OP_I386, I386OP_A(jmp_abs16), I386OP_A(jmp_abs32), false},
- { 0xEB, OP_I386, I386OP_A(jmp_rel8), I386OP_A(jmp_rel8), false},
- { 0xEC, OP_I386, I386OP_A(in_al_dx), I386OP_A(in_al_dx), false},
- { 0xED, OP_I386, I386OP_A(in_ax_dx), I386OP_A(in_eax_dx), false},
- { 0xEE, OP_I386, I386OP_A(out_al_dx), I386OP_A(out_al_dx), false},
- { 0xEF, OP_I386, I386OP_A(out_ax_dx), I386OP_A(out_eax_dx), false},
- { 0xF0, OP_I386, I386OP_A(lock), I386OP_A(lock), false},
- { 0xF1, OP_I386, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0xF2, OP_I386, I386OP_A(repne), I386OP_A(repne), false},
- { 0xF3, OP_I386, I386OP_A(rep), I386OP_A(rep), false},
- { 0xF4, OP_I386, I386OP_A(hlt), I386OP_A(hlt), false},
- { 0xF5, OP_I386, I386OP_A(cmc), I386OP_A(cmc), false},
- { 0xF6, OP_I386, I386OP_A(groupF6_8), I386OP_A(groupF6_8), true },
- { 0xF7, OP_I386, I386OP_A(groupF7_16), I386OP_A(groupF7_32), true },
- { 0xF8, OP_I386, I386OP_A(clc), I386OP_A(clc), false},
- { 0xF9, OP_I386, I386OP_A(stc), I386OP_A(stc), false},
- { 0xFA, OP_I386, I386OP_A(cli), I386OP_A(cli), false},
- { 0xFB, OP_I386, I386OP_A(sti), I386OP_A(sti), false},
- { 0xFC, OP_I386, I386OP_A(cld), I386OP_A(cld), false},
- { 0xFD, OP_I386, I386OP_A(std), I386OP_A(std), false},
- { 0xFE, OP_I386, I386OP_A(groupFE_8), I386OP_A(groupFE_8), true },
- { 0xFF, OP_I386, I386OP_A(groupFF_16), I386OP_A(groupFF_32), true },
- /* 0F ?? */
- { 0x00, OP_2BYTE|OP_I386, I386OP_A(group0F00_16), I386OP_A(group0F00_32), false},
- { 0x01, OP_2BYTE|OP_I386, I386OP_A(group0F01_16), I386OP_A(group0F01_32), false},
- { 0x01, OP_2BYTE|OP_I486, I486OP_A(group0F01_16), I486OP_A(group0F01_32), false},
- { 0x02, OP_2BYTE|OP_I386, I386OP_A(lar_r16_rm16), I386OP_A(lar_r32_rm32), false},
- { 0x03, OP_2BYTE|OP_I386, I386OP_A(lsl_r16_rm16), I386OP_A(lsl_r32_rm32), false},
- { 0x06, OP_2BYTE|OP_I386, I386OP_A(clts), I386OP_A(clts), false},
- { 0x07, OP_2BYTE|OP_I386, I386OP_A(loadall), I386OP_A(loadall), false},
- { 0x08, OP_2BYTE|OP_I486, I486OP_A(invd), I486OP_A(invd), false},
- { 0x09, OP_2BYTE|OP_I486, I486OP_A(wbinvd), I486OP_A(wbinvd), false},
- { 0x0B, OP_2BYTE|OP_PENTIUM, PENTIUMOP_A(ud2), PENTIUMOP_A(ud2), false},
- { 0x10, OP_2BYTE|OP_SSE, SSEOP_A(movups_r128_rm128), SSEOP_A(movups_r128_rm128), false},
- { 0x11, OP_2BYTE|OP_SSE, SSEOP_A(movups_rm128_r128), SSEOP_A(movups_rm128_r128), false},
- { 0x12, OP_2BYTE|OP_SSE, SSEOP_A(movlps_r128_m64), SSEOP_A(movlps_r128_m64), false},
- { 0x13, OP_2BYTE|OP_SSE, SSEOP_A(movlps_m64_r128), SSEOP_A(movlps_m64_r128), false},
- { 0x14, OP_2BYTE|OP_SSE, SSEOP_A(unpcklps_r128_rm128), SSEOP_A(unpcklps_r128_rm128), false},
- { 0x15, OP_2BYTE|OP_SSE, SSEOP_A(unpckhps_r128_rm128), SSEOP_A(unpckhps_r128_rm128), false},
- { 0x16, OP_2BYTE|OP_SSE, SSEOP_A(movhps_r128_m64), SSEOP_A(movhps_r128_m64), false},
- { 0x17, OP_2BYTE|OP_SSE, SSEOP_A(movhps_m64_r128), SSEOP_A(movhps_m64_r128), false},
- { 0x18, OP_2BYTE|OP_PENTIUM, PENTIUMOP_A(prefetch_m8), PENTIUMOP_A(prefetch_m8), false},
- { 0x20, OP_2BYTE|OP_I386, I386OP_A(mov_r32_cr), I386OP_A(mov_r32_cr), false},
- { 0x21, OP_2BYTE|OP_I386, I386OP_A(mov_r32_dr), I386OP_A(mov_r32_dr), false},
- { 0x22, OP_2BYTE|OP_I386, I386OP_A(mov_cr_r32), I386OP_A(mov_cr_r32), false},
- { 0x22, OP_2BYTE|OP_I486, I486OP_A(mov_cr_r32), I486OP_A(mov_cr_r32), false},
- { 0x23, OP_2BYTE|OP_I386, I386OP_A(mov_dr_r32), I386OP_A(mov_dr_r32), false},
- { 0x24, OP_2BYTE|OP_I386, I386OP_A(mov_r32_tr), I386OP_A(mov_r32_tr), false},
- { 0x26, OP_2BYTE|OP_I386, I386OP_A(mov_tr_r32), I386OP_A(mov_tr_r32), false},
- { 0x28, OP_2BYTE|OP_SSE, SSEOP_A(movaps_r128_rm128), SSEOP_A(movaps_r128_rm128), false},
- { 0x29, OP_2BYTE|OP_SSE, SSEOP_A(movaps_rm128_r128), SSEOP_A(movaps_rm128_r128), false},
- { 0x2a, OP_2BYTE|OP_SSE, SSEOP_A(cvtpi2ps_r128_rm64), SSEOP_A(cvtpi2ps_r128_rm64), false},
- { 0x2b, OP_2BYTE|OP_SSE, SSEOP_A(movntps_m128_r128), SSEOP_A(movntps_m128_r128), false},
- { 0x2c, OP_2BYTE|OP_SSE, SSEOP_A(cvttps2pi_r64_r128m64), SSEOP_A(cvttps2pi_r64_r128m64),false},
- { 0x2d, OP_2BYTE|OP_SSE, SSEOP_A(cvtps2pi_r64_r128m64), SSEOP_A(cvtps2pi_r64_r128m64),false},
- { 0x2e, OP_2BYTE|OP_SSE, SSEOP_A(ucomiss_r128_r128m32), SSEOP_A(ucomiss_r128_r128m32),false},
- { 0x2f, OP_2BYTE|OP_SSE, SSEOP_A(comiss_r128_r128m32), SSEOP_A(comiss_r128_r128m32), false},
- { 0x30, OP_2BYTE|OP_PENTIUM, PENTIUMOP_A(wrmsr), PENTIUMOP_A(wrmsr), false},
- { 0x31, OP_2BYTE|OP_PENTIUM, PENTIUMOP_A(rdtsc), PENTIUMOP_A(rdtsc), false},
- { 0x32, OP_2BYTE|OP_PENTIUM, PENTIUMOP_A(rdmsr), PENTIUMOP_A(rdmsr), false},
- { 0x38, OP_2BYTE|OP_PENTIUM, I386OP_A(decode_three_byte38), I386OP_A(decode_three_byte38),false},
- { 0x3A, OP_2BYTE|OP_PENTIUM, I386OP_A(decode_three_byte3a), I386OP_A(decode_three_byte3a),false},
- { 0x3A, OP_2BYTE|OP_CYRIX, I386OP_A(cyrix_special), I386OP_A(cyrix_special), false},
- { 0x3B, OP_2BYTE|OP_CYRIX, I386OP_A(cyrix_special), I386OP_A(cyrix_special), false},
- { 0x3C, OP_2BYTE|OP_CYRIX, I386OP_A(cyrix_special), I386OP_A(cyrix_special), false},
- { 0x3D, OP_2BYTE|OP_CYRIX, I386OP_A(cyrix_special), I386OP_A(cyrix_special), false},
- { 0x40, OP_2BYTE|OP_PENTIUM, PENTIUMOP_A(cmovo_r16_rm16), PENTIUMOP_A(cmovo_r32_rm32), false},
- { 0x41, OP_2BYTE|OP_PENTIUM, PENTIUMOP_A(cmovno_r16_rm16), PENTIUMOP_A(cmovno_r32_rm32), false},
- { 0x42, OP_2BYTE|OP_PENTIUM, PENTIUMOP_A(cmovb_r16_rm16), PENTIUMOP_A(cmovb_r32_rm32), false},
- { 0x43, OP_2BYTE|OP_PENTIUM, PENTIUMOP_A(cmovae_r16_rm16), PENTIUMOP_A(cmovae_r32_rm32), false},
- { 0x44, OP_2BYTE|OP_PENTIUM, PENTIUMOP_A(cmove_r16_rm16), PENTIUMOP_A(cmove_r32_rm32), false},
- { 0x45, OP_2BYTE|OP_PENTIUM, PENTIUMOP_A(cmovne_r16_rm16), PENTIUMOP_A(cmovne_r32_rm32), false},
- { 0x46, OP_2BYTE|OP_PENTIUM, PENTIUMOP_A(cmovbe_r16_rm16), PENTIUMOP_A(cmovbe_r32_rm32), false},
- { 0x47, OP_2BYTE|OP_PENTIUM, PENTIUMOP_A(cmova_r16_rm16), PENTIUMOP_A(cmova_r32_rm32), false},
- { 0x48, OP_2BYTE|OP_PENTIUM, PENTIUMOP_A(cmovs_r16_rm16), PENTIUMOP_A(cmovs_r32_rm32), false},
- { 0x49, OP_2BYTE|OP_PENTIUM, PENTIUMOP_A(cmovns_r16_rm16), PENTIUMOP_A(cmovns_r32_rm32), false},
- { 0x4a, OP_2BYTE|OP_PENTIUM, PENTIUMOP_A(cmovp_r16_rm16), PENTIUMOP_A(cmovp_r32_rm32), false},
- { 0x4b, OP_2BYTE|OP_PENTIUM, PENTIUMOP_A(cmovnp_r16_rm16), PENTIUMOP_A(cmovnp_r32_rm32), false},
- { 0x4c, OP_2BYTE|OP_PENTIUM, PENTIUMOP_A(cmovl_r16_rm16), PENTIUMOP_A(cmovl_r32_rm32), false},
- { 0x4d, OP_2BYTE|OP_PENTIUM, PENTIUMOP_A(cmovge_r16_rm16), PENTIUMOP_A(cmovge_r32_rm32), false},
- { 0x4e, OP_2BYTE|OP_PENTIUM, PENTIUMOP_A(cmovle_r16_rm16), PENTIUMOP_A(cmovle_r32_rm32), false},
- { 0x4f, OP_2BYTE|OP_PENTIUM, PENTIUMOP_A(cmovg_r16_rm16), PENTIUMOP_A(cmovg_r32_rm32), false},
- { 0x50, OP_2BYTE|OP_SSE, SSEOP_A(movmskps_r16_r128), SSEOP_A(movmskps_r32_r128), false},
- { 0x51, OP_2BYTE|OP_SSE, SSEOP_A(sqrtps_r128_rm128), SSEOP_A(sqrtps_r128_rm128), false},
- { 0x52, OP_2BYTE|OP_SSE, SSEOP_A(rsqrtps_r128_rm128), SSEOP_A(rsqrtps_r128_rm128), false},
- { 0x53, OP_2BYTE|OP_SSE, SSEOP_A(rcpps_r128_rm128), SSEOP_A(rcpps_r128_rm128), false},
- { 0x54, OP_2BYTE|OP_SSE, SSEOP_A(andps_r128_rm128), SSEOP_A(andps_r128_rm128), false},
- { 0x55, OP_2BYTE|OP_SSE, SSEOP_A(andnps_r128_rm128), SSEOP_A(andnps_r128_rm128), false},
- { 0x56, OP_2BYTE|OP_SSE, SSEOP_A(orps_r128_rm128), SSEOP_A(orps_r128_rm128), false},
- { 0x57, OP_2BYTE|OP_SSE, SSEOP_A(xorps), SSEOP_A(xorps), false},
- { 0x58, OP_2BYTE|OP_SSE, SSEOP_A(addps), SSEOP_A(addps), false},
- { 0x59, OP_2BYTE|OP_SSE, SSEOP_A(mulps), SSEOP_A(mulps), false},
- { 0x5a, OP_2BYTE|OP_SSE, SSEOP_A(cvtps2pd_r128_r128m64), SSEOP_A(cvtps2pd_r128_r128m64),false},
- { 0x5b, OP_2BYTE|OP_SSE, SSEOP_A(cvtdq2ps_r128_rm128), SSEOP_A(cvtdq2ps_r128_rm128), false},
- { 0x5c, OP_2BYTE|OP_SSE, SSEOP_A(subps), SSEOP_A(subps), false},
- { 0x5d, OP_2BYTE|OP_SSE, SSEOP_A(minps), SSEOP_A(minps), false},
- { 0x5e, OP_2BYTE|OP_SSE, SSEOP_A(divps), SSEOP_A(divps), false},
- { 0x5f, OP_2BYTE|OP_SSE, SSEOP_A(maxps), SSEOP_A(maxps), false},
- { 0x60, OP_2BYTE|OP_MMX, MMXOP_A(punpcklbw_r64_r64m32), MMXOP_A(punpcklbw_r64_r64m32),false},
- { 0x61, OP_2BYTE|OP_MMX, MMXOP_A(punpcklwd_r64_r64m32), MMXOP_A(punpcklwd_r64_r64m32),false},
- { 0x62, OP_2BYTE|OP_MMX, MMXOP_A(punpckldq_r64_r64m32), MMXOP_A(punpckldq_r64_r64m32),false},
- { 0x63, OP_2BYTE|OP_MMX, MMXOP_A(packsswb_r64_rm64), MMXOP_A(packsswb_r64_rm64), false},
- { 0x64, OP_2BYTE|OP_MMX, MMXOP_A(pcmpgtb_r64_rm64), MMXOP_A(pcmpgtb_r64_rm64), false},
- { 0x65, OP_2BYTE|OP_MMX, MMXOP_A(pcmpgtw_r64_rm64), MMXOP_A(pcmpgtw_r64_rm64), false},
- { 0x66, OP_2BYTE|OP_MMX, MMXOP_A(pcmpgtd_r64_rm64), MMXOP_A(pcmpgtd_r64_rm64), false},
- { 0x67, OP_2BYTE|OP_MMX, MMXOP_A(packuswb_r64_rm64), MMXOP_A(packuswb_r64_rm64), false},
- { 0x68, OP_2BYTE|OP_MMX, MMXOP_A(punpckhbw_r64_rm64), MMXOP_A(punpckhbw_r64_rm64), false},
- { 0x69, OP_2BYTE|OP_MMX, MMXOP_A(punpckhwd_r64_rm64), MMXOP_A(punpckhwd_r64_rm64), false},
- { 0x6a, OP_2BYTE|OP_MMX, MMXOP_A(punpckhdq_r64_rm64), MMXOP_A(punpckhdq_r64_rm64), false},
- { 0x6b, OP_2BYTE|OP_MMX, MMXOP_A(packssdw_r64_rm64), MMXOP_A(packssdw_r64_rm64), false},
- { 0x6e, OP_2BYTE|OP_MMX, MMXOP_A(movd_r64_rm32), MMXOP_A(movd_r64_rm32), false},
- { 0x6f, OP_2BYTE|OP_MMX, MMXOP_A(movq_r64_rm64), MMXOP_A(movq_r64_rm64), false},
- { 0x70, OP_2BYTE|OP_MMX, MMXOP_A(pshufw_r64_rm64_i8), MMXOP_A(pshufw_r64_rm64_i8), false},
- { 0x71, OP_2BYTE|OP_MMX, MMXOP_A(group_0f71), MMXOP_A(group_0f71), false},
- { 0x72, OP_2BYTE|OP_MMX, MMXOP_A(group_0f72), MMXOP_A(group_0f72), false},
- { 0x73, OP_2BYTE|OP_MMX, MMXOP_A(group_0f73), MMXOP_A(group_0f73), false},
- { 0x74, OP_2BYTE|OP_CYRIX, I386OP_A(cyrix_unknown), I386OP_A(cyrix_unknown), false},
- { 0x74, OP_2BYTE|OP_MMX, MMXOP_A(pcmpeqb_r64_rm64), MMXOP_A(pcmpeqb_r64_rm64), false},
- { 0x75, OP_2BYTE|OP_MMX, MMXOP_A(pcmpeqw_r64_rm64), MMXOP_A(pcmpeqw_r64_rm64), false},
- { 0x76, OP_2BYTE|OP_MMX, MMXOP_A(pcmpeqd_r64_rm64), MMXOP_A(pcmpeqd_r64_rm64), false},
- { 0x77, OP_2BYTE|OP_MMX, MMXOP_A(emms), MMXOP_A(emms), false},
- { 0x78, OP_2BYTE|OP_CYRIX, I386OP_A(cyrix_svdc), I386OP_A(cyrix_svdc), false},
- { 0x79, OP_2BYTE|OP_CYRIX, I386OP_A(cyrix_rsdc), I386OP_A(cyrix_rsdc), false},
- { 0x7a, OP_2BYTE|OP_CYRIX, I386OP_A(cyrix_svldt), I386OP_A(cyrix_svldt), false},
- { 0x7b, OP_2BYTE|OP_CYRIX, I386OP_A(cyrix_rsldt), I386OP_A(cyrix_rsldt), false},
- { 0x7c, OP_2BYTE|OP_CYRIX, I386OP_A(cyrix_svts), I386OP_A(cyrix_svts), false},
- { 0x7d, OP_2BYTE|OP_CYRIX, I386OP_A(cyrix_rsts), I386OP_A(cyrix_rsts), false},
- { 0x7e, OP_2BYTE|OP_MMX, MMXOP_A(movd_rm32_r64), MMXOP_A(movd_rm32_r64), false},
- { 0x7f, OP_2BYTE|OP_MMX, MMXOP_A(movq_rm64_r64), MMXOP_A(movq_rm64_r64), false},
- { 0x80, OP_2BYTE|OP_I386, I386OP_A(jo_rel16), I386OP_A(jo_rel32), false},
- { 0x81, OP_2BYTE|OP_I386, I386OP_A(jno_rel16), I386OP_A(jno_rel32), false},
- { 0x82, OP_2BYTE|OP_I386, I386OP_A(jc_rel16), I386OP_A(jc_rel32), false},
- { 0x83, OP_2BYTE|OP_I386, I386OP_A(jnc_rel16), I386OP_A(jnc_rel32), false},
- { 0x84, OP_2BYTE|OP_I386, I386OP_A(jz_rel16), I386OP_A(jz_rel32), false},
- { 0x85, OP_2BYTE|OP_I386, I386OP_A(jnz_rel16), I386OP_A(jnz_rel32), false},
- { 0x86, OP_2BYTE|OP_I386, I386OP_A(jbe_rel16), I386OP_A(jbe_rel32), false},
- { 0x87, OP_2BYTE|OP_I386, I386OP_A(ja_rel16), I386OP_A(ja_rel32), false},
- { 0x88, OP_2BYTE|OP_I386, I386OP_A(js_rel16), I386OP_A(js_rel32), false},
- { 0x89, OP_2BYTE|OP_I386, I386OP_A(jns_rel16), I386OP_A(jns_rel32), false},
- { 0x8A, OP_2BYTE|OP_I386, I386OP_A(jp_rel16), I386OP_A(jp_rel32), false},
- { 0x8B, OP_2BYTE|OP_I386, I386OP_A(jnp_rel16), I386OP_A(jnp_rel32), false},
- { 0x8C, OP_2BYTE|OP_I386, I386OP_A(jl_rel16), I386OP_A(jl_rel32), false},
- { 0x8D, OP_2BYTE|OP_I386, I386OP_A(jge_rel16), I386OP_A(jge_rel32), false},
- { 0x8E, OP_2BYTE|OP_I386, I386OP_A(jle_rel16), I386OP_A(jle_rel32), false},
- { 0x8F, OP_2BYTE|OP_I386, I386OP_A(jg_rel16), I386OP_A(jg_rel32), false},
- { 0x90, OP_2BYTE|OP_I386, I386OP_A(seto_rm8), I386OP_A(seto_rm8), false},
- { 0x91, OP_2BYTE|OP_I386, I386OP_A(setno_rm8), I386OP_A(setno_rm8), false},
- { 0x92, OP_2BYTE|OP_I386, I386OP_A(setc_rm8), I386OP_A(setc_rm8), false},
- { 0x93, OP_2BYTE|OP_I386, I386OP_A(setnc_rm8), I386OP_A(setnc_rm8), false},
- { 0x94, OP_2BYTE|OP_I386, I386OP_A(setz_rm8), I386OP_A(setz_rm8), false},
- { 0x95, OP_2BYTE|OP_I386, I386OP_A(setnz_rm8), I386OP_A(setnz_rm8), false},
- { 0x96, OP_2BYTE|OP_I386, I386OP_A(setbe_rm8), I386OP_A(setbe_rm8), false},
- { 0x97, OP_2BYTE|OP_I386, I386OP_A(seta_rm8), I386OP_A(seta_rm8), false},
- { 0x98, OP_2BYTE|OP_I386, I386OP_A(sets_rm8), I386OP_A(sets_rm8), false},
- { 0x99, OP_2BYTE|OP_I386, I386OP_A(setns_rm8), I386OP_A(setns_rm8), false},
- { 0x9A, OP_2BYTE|OP_I386, I386OP_A(setp_rm8), I386OP_A(setp_rm8), false},
- { 0x9B, OP_2BYTE|OP_I386, I386OP_A(setnp_rm8), I386OP_A(setnp_rm8), false},
- { 0x9C, OP_2BYTE|OP_I386, I386OP_A(setl_rm8), I386OP_A(setl_rm8), false},
- { 0x9D, OP_2BYTE|OP_I386, I386OP_A(setge_rm8), I386OP_A(setge_rm8), false},
- { 0x9E, OP_2BYTE|OP_I386, I386OP_A(setle_rm8), I386OP_A(setle_rm8), false},
- { 0x9F, OP_2BYTE|OP_I386, I386OP_A(setg_rm8), I386OP_A(setg_rm8), false},
- { 0xA0, OP_2BYTE|OP_I386, I386OP_A(push_fs16), I386OP_A(push_fs32), false},
- { 0xA1, OP_2BYTE|OP_I386, I386OP_A(pop_fs16), I386OP_A(pop_fs32), false},
- { 0xA2, OP_2BYTE|OP_I486, I486OP_A(cpuid), I486OP_A(cpuid), false},
- { 0xA3, OP_2BYTE|OP_I386, I386OP_A(bt_rm16_r16), I386OP_A(bt_rm32_r32), false},
- { 0xA4, OP_2BYTE|OP_I386, I386OP_A(shld16_i8), I386OP_A(shld32_i8), false},
- { 0xA5, OP_2BYTE|OP_I386, I386OP_A(shld16_cl), I386OP_A(shld32_cl), false},
- { 0xA8, OP_2BYTE|OP_I386, I386OP_A(push_gs16), I386OP_A(push_gs32), false},
- { 0xA9, OP_2BYTE|OP_I386, I386OP_A(pop_gs16), I386OP_A(pop_gs32), false},
- { 0xAA, OP_2BYTE|OP_PENTIUM, PENTIUMOP_A(rsm), PENTIUMOP_A(rsm), false},
- { 0xAB, OP_2BYTE|OP_I386, I386OP_A(bts_rm16_r16), I386OP_A(bts_rm32_r32), true },
- { 0xAC, OP_2BYTE|OP_I386, I386OP_A(shrd16_i8), I386OP_A(shrd32_i8), false},
- { 0xAD, OP_2BYTE|OP_I386, I386OP_A(shrd16_cl), I386OP_A(shrd32_cl), false},
- { 0xAE, OP_2BYTE|OP_SSE, SSEOP_A(group_0fae), SSEOP_A(group_0fae), false},
- { 0xAF, OP_2BYTE|OP_I386, I386OP_A(imul_r16_rm16), I386OP_A(imul_r32_rm32), false},
- { 0xB0, OP_2BYTE|OP_I486, I486OP_A(cmpxchg_rm8_r8), I486OP_A(cmpxchg_rm8_r8), true },
- { 0xB1, OP_2BYTE|OP_I486, I486OP_A(cmpxchg_rm16_r16), I486OP_A(cmpxchg_rm32_r32), true },
- { 0xB2, OP_2BYTE|OP_I386, I386OP_A(lss16), I386OP_A(lss32), false},
- { 0xB3, OP_2BYTE|OP_I386, I386OP_A(btr_rm16_r16), I386OP_A(btr_rm32_r32), true },
- { 0xB4, OP_2BYTE|OP_I386, I386OP_A(lfs16), I386OP_A(lfs32), false},
- { 0xB5, OP_2BYTE|OP_I386, I386OP_A(lgs16), I386OP_A(lgs32), false},
- { 0xB6, OP_2BYTE|OP_I386, I386OP_A(movzx_r16_rm8), I386OP_A(movzx_r32_rm8), false},
- { 0xB7, OP_2BYTE|OP_I386, I386OP_A(invalid), I386OP_A(movzx_r32_rm16), false},
- { 0xBA, OP_2BYTE|OP_I386, I386OP_A(group0FBA_16), I386OP_A(group0FBA_32), true },
- { 0xBB, OP_2BYTE|OP_I386, I386OP_A(btc_rm16_r16), I386OP_A(btc_rm32_r32), true },
- { 0xBC, OP_2BYTE|OP_I386, I386OP_A(bsf_r16_rm16), I386OP_A(bsf_r32_rm32), false},
- { 0xBD, OP_2BYTE|OP_I386, I386OP_A(bsr_r16_rm16), I386OP_A(bsr_r32_rm32), false},
- { 0xBE, OP_2BYTE|OP_I386, I386OP_A(movsx_r16_rm8), I386OP_A(movsx_r32_rm8), false},
- { 0xBF, OP_2BYTE|OP_I386, I386OP_A(invalid), I386OP_A(movsx_r32_rm16), false},
- { 0xC0, OP_2BYTE|OP_I486, I486OP_A(xadd_rm8_r8), I486OP_A(xadd_rm8_r8), true },
- { 0xC1, OP_2BYTE|OP_I486, I486OP_A(xadd_rm16_r16), I486OP_A(xadd_rm32_r32), true },
- { 0xC2, OP_2BYTE|OP_SSE, SSEOP_A(cmpps_r128_rm128_i8), SSEOP_A(cmpps_r128_rm128_i8), false},
- { 0xC3, OP_2BYTE|OP_PENTIUM, PENTIUMOP_A(movnti_m16_r16), PENTIUMOP_A(movnti_m32_r32), false},
- { 0xC4, OP_2BYTE|OP_SSE, SSEOP_A(pinsrw_r64_r16m16_i8), SSEOP_A(pinsrw_r64_r32m16_i8),false},
- { 0xC5, OP_2BYTE|OP_SSE, SSEOP_A(pextrw_r16_r64_i8), SSEOP_A(pextrw_r32_r64_i8), false},
- { 0xC6, OP_2BYTE|OP_SSE, SSEOP_A(shufps), SSEOP_A(shufps), false},
- { 0xC7, OP_2BYTE|OP_PENTIUM, PENTIUMOP_A(cmpxchg8b_m64), PENTIUMOP_A(cmpxchg8b_m64), true },
- { 0xC8, OP_2BYTE|OP_I486, I486OP_A(bswap_eax), I486OP_A(bswap_eax), false},
- { 0xC9, OP_2BYTE|OP_I486, I486OP_A(bswap_ecx), I486OP_A(bswap_ecx), false},
- { 0xCA, OP_2BYTE|OP_I486, I486OP_A(bswap_edx), I486OP_A(bswap_edx), false},
- { 0xCB, OP_2BYTE|OP_I486, I486OP_A(bswap_ebx), I486OP_A(bswap_ebx), false},
- { 0xCC, OP_2BYTE|OP_I486, I486OP_A(bswap_esp), I486OP_A(bswap_esp), false},
- { 0xCD, OP_2BYTE|OP_I486, I486OP_A(bswap_ebp), I486OP_A(bswap_ebp), false},
- { 0xCE, OP_2BYTE|OP_I486, I486OP_A(bswap_esi), I486OP_A(bswap_esi), false},
- { 0xCF, OP_2BYTE|OP_I486, I486OP_A(bswap_edi), I486OP_A(bswap_edi), false},
- { 0xD1, OP_2BYTE|OP_MMX, MMXOP_A(psrlw_r64_rm64), MMXOP_A(psrlw_r64_rm64), false},
- { 0xD2, OP_2BYTE|OP_MMX, MMXOP_A(psrld_r64_rm64), MMXOP_A(psrld_r64_rm64), false},
- { 0xD3, OP_2BYTE|OP_MMX, MMXOP_A(psrlq_r64_rm64), MMXOP_A(psrlq_r64_rm64), false},
- { 0xD4, OP_2BYTE|OP_MMX, MMXOP_A(paddq_r64_rm64), MMXOP_A(paddq_r64_rm64), false},
- { 0xD5, OP_2BYTE|OP_MMX, MMXOP_A(pmullw_r64_rm64), MMXOP_A(pmullw_r64_rm64), false},
- { 0xD7, OP_2BYTE|OP_SSE, SSEOP_A(pmovmskb_r16_r64), SSEOP_A(pmovmskb_r32_r64), false},
- { 0xD8, OP_2BYTE|OP_MMX, MMXOP_A(psubusb_r64_rm64), MMXOP_A(psubusb_r64_rm64), false},
- { 0xD9, OP_2BYTE|OP_MMX, MMXOP_A(psubusw_r64_rm64), MMXOP_A(psubusw_r64_rm64), false},
- { 0xDA, OP_2BYTE|OP_SSE, SSEOP_A(pminub_r64_rm64), SSEOP_A(pminub_r64_rm64), false},
- { 0xDB, OP_2BYTE|OP_MMX, MMXOP_A(pand_r64_rm64), MMXOP_A(pand_r64_rm64), false},
- { 0xDC, OP_2BYTE|OP_MMX, MMXOP_A(paddusb_r64_rm64), MMXOP_A(paddusb_r64_rm64), false},
- { 0xDD, OP_2BYTE|OP_MMX, MMXOP_A(paddusw_r64_rm64), MMXOP_A(paddusw_r64_rm64), false},
- { 0xDE, OP_2BYTE|OP_SSE, SSEOP_A(pmaxub_r64_rm64), SSEOP_A(pmaxub_r64_rm64), false},
- { 0xDF, OP_2BYTE|OP_MMX, MMXOP_A(pandn_r64_rm64), MMXOP_A(pandn_r64_rm64), false},
- { 0xE0, OP_2BYTE|OP_SSE, SSEOP_A(pavgb_r64_rm64), SSEOP_A(pavgb_r64_rm64), false},
- { 0xE1, OP_2BYTE|OP_MMX, MMXOP_A(psraw_r64_rm64), MMXOP_A(psraw_r64_rm64), false},
- { 0xE2, OP_2BYTE|OP_MMX, MMXOP_A(psrad_r64_rm64), MMXOP_A(psrad_r64_rm64), false},
- { 0xE3, OP_2BYTE|OP_SSE, SSEOP_A(pavgw_r64_rm64), SSEOP_A(pavgw_r64_rm64), false},
- { 0xE4, OP_2BYTE|OP_SSE, SSEOP_A(pmulhuw_r64_rm64), SSEOP_A(pmulhuw_r64_rm64), false},
- { 0xE5, OP_2BYTE|OP_MMX, MMXOP_A(pmulhw_r64_rm64), MMXOP_A(pmulhw_r64_rm64), false},
- { 0xE7, OP_2BYTE|OP_PENTIUM, PENTIUMOP_A(movntq_m64_r64), PENTIUMOP_A(movntq_m64_r64), false},
- { 0xE8, OP_2BYTE|OP_MMX, MMXOP_A(psubsb_r64_rm64), MMXOP_A(psubsb_r64_rm64), false},
- { 0xE9, OP_2BYTE|OP_MMX, MMXOP_A(psubsw_r64_rm64), MMXOP_A(psubsw_r64_rm64), false},
- { 0xEA, OP_2BYTE|OP_SSE, SSEOP_A(pminsw_r64_rm64), SSEOP_A(pminsw_r64_rm64), false},
- { 0xEB, OP_2BYTE|OP_MMX, MMXOP_A(por_r64_rm64), MMXOP_A(por_r64_rm64), false},
- { 0xEC, OP_2BYTE|OP_MMX, MMXOP_A(paddsb_r64_rm64), MMXOP_A(paddsb_r64_rm64), false},
- { 0xED, OP_2BYTE|OP_MMX, MMXOP_A(paddsw_r64_rm64), MMXOP_A(paddsw_r64_rm64), false},
- { 0xEE, OP_2BYTE|OP_SSE, SSEOP_A(pmaxsw_r64_rm64), SSEOP_A(pmaxsw_r64_rm64), false},
- { 0xEF, OP_2BYTE|OP_MMX, MMXOP_A(pxor_r64_rm64), MMXOP_A(pxor_r64_rm64), false},
- { 0xF1, OP_2BYTE|OP_MMX, MMXOP_A(psllw_r64_rm64), MMXOP_A(psllw_r64_rm64), false},
- { 0xF2, OP_2BYTE|OP_MMX, MMXOP_A(pslld_r64_rm64), MMXOP_A(pslld_r64_rm64), false},
- { 0xF3, OP_2BYTE|OP_MMX, MMXOP_A(psllq_r64_rm64), MMXOP_A(psllq_r64_rm64), false},
- { 0xF4, OP_2BYTE|OP_SSE, SSEOP_A(pmuludq_r64_rm64), SSEOP_A(pmuludq_r64_rm64), false},
- { 0xF5, OP_2BYTE|OP_MMX, MMXOP_A(pmaddwd_r64_rm64), MMXOP_A(pmaddwd_r64_rm64), false},
- { 0xF6, OP_2BYTE|OP_SSE, SSEOP_A(psadbw_r64_rm64), SSEOP_A(psadbw_r64_rm64), false},
- { 0xf7, OP_2BYTE|OP_PENTIUM, PENTIUMOP_A(maskmovq_r64_r64), PENTIUMOP_A(maskmovq_r64_r64),false},
- { 0xF8, OP_2BYTE|OP_MMX, MMXOP_A(psubb_r64_rm64), MMXOP_A(psubb_r64_rm64), false},
- { 0xF9, OP_2BYTE|OP_MMX, MMXOP_A(psubw_r64_rm64), MMXOP_A(psubw_r64_rm64), false},
- { 0xFA, OP_2BYTE|OP_MMX, MMXOP_A(psubd_r64_rm64), MMXOP_A(psubd_r64_rm64), false},
- { 0xFB, OP_2BYTE|OP_SSE, SSEOP_A(psubq_r64_rm64), SSEOP_A(psubq_r64_rm64), false},
- { 0xFC, OP_2BYTE|OP_MMX, MMXOP_A(paddb_r64_rm64), MMXOP_A(paddb_r64_rm64), false},
- { 0xFD, OP_2BYTE|OP_MMX, MMXOP_A(paddw_r64_rm64), MMXOP_A(paddw_r64_rm64), false},
- { 0xFE, OP_2BYTE|OP_MMX, MMXOP_A(paddd_r64_rm64), MMXOP_A(paddd_r64_rm64), false},
- /* F3 0F ?? */
- { 0x10, OP_3BYTEF3|OP_SSE, SSEOP_A(movss_r128_rm128), SSEOP_A(movss_r128_rm128), false},
- { 0x11, OP_3BYTEF3|OP_SSE, SSEOP_A(movss_rm128_r128), SSEOP_A(movss_rm128_r128), false},
- { 0x12, OP_3BYTEF3|OP_SSE, SSEOP_A(movsldup_r128_rm128), SSEOP_A(movsldup_r128_rm128), false},
- { 0x16, OP_3BYTEF3|OP_SSE, SSEOP_A(movshdup_r128_rm128), SSEOP_A(movshdup_r128_rm128), false},
- { 0x2A, OP_3BYTEF3|OP_SSE, SSEOP_A(cvtsi2ss_r128_rm32), SSEOP_A(cvtsi2ss_r128_rm32), false},
- { 0x2C, OP_3BYTEF3|OP_SSE, SSEOP_A(cvttss2si_r32_r128m32), SSEOP_A(cvttss2si_r32_r128m32),false},
- { 0x2D, OP_3BYTEF3|OP_SSE, SSEOP_A(cvtss2si_r32_r128m32), SSEOP_A(cvtss2si_r32_r128m32),false},
- { 0x51, OP_3BYTEF3|OP_SSE, SSEOP_A(sqrtss_r128_r128m32), SSEOP_A(sqrtss_r128_r128m32), false},
- { 0x52, OP_3BYTEF3|OP_SSE, SSEOP_A(rsqrtss_r128_r128m32), SSEOP_A(rsqrtss_r128_r128m32),false},
- { 0x53, OP_3BYTEF3|OP_SSE, SSEOP_A(rcpss_r128_r128m32), SSEOP_A(rcpss_r128_r128m32), false},
- { 0x58, OP_3BYTEF3|OP_SSE, SSEOP_A(addss), SSEOP_A(addss), false},
- { 0x59, OP_3BYTEF3|OP_SSE, SSEOP_A(mulss), SSEOP_A(mulss), false},
- { 0x5A, OP_3BYTEF3|OP_SSE, SSEOP_A(cvtss2sd_r128_r128m32), SSEOP_A(cvtss2sd_r128_r128m32),false},
- { 0x5B, OP_3BYTEF3|OP_SSE, SSEOP_A(cvttps2dq_r128_rm128), SSEOP_A(cvttps2dq_r128_rm128),false},
- { 0x5C, OP_3BYTEF3|OP_SSE, SSEOP_A(subss), SSEOP_A(subss), false},
- { 0x5D, OP_3BYTEF3|OP_SSE, SSEOP_A(minss_r128_r128m32), SSEOP_A(minss_r128_r128m32), false},
- { 0x5E, OP_3BYTEF3|OP_SSE, SSEOP_A(divss), SSEOP_A(divss), false},
- { 0x5F, OP_3BYTEF3|OP_SSE, SSEOP_A(maxss_r128_r128m32), SSEOP_A(maxss_r128_r128m32), false},
- { 0x6F, OP_3BYTEF3|OP_SSE, SSEOP_A(movdqu_r128_rm128), SSEOP_A(movdqu_r128_rm128), false},
- { 0x70, OP_3BYTEF3|OP_SSE, SSEOP_A(pshufhw_r128_rm128_i8), SSEOP_A(pshufhw_r128_rm128_i8),false},
- { 0x7E, OP_3BYTEF3|OP_SSE, SSEOP_A(movq_r128_r128m64), SSEOP_A(movq_r128_r128m64), false},
- { 0x7F, OP_3BYTEF3|OP_SSE, SSEOP_A(movdqu_rm128_r128), SSEOP_A(movdqu_rm128_r128), false},
- { 0xAE, OP_3BYTE66|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0xB8, OP_3BYTEF3|OP_PENTIUM, PENTIUMOP_A(popcnt_r16_rm16), PENTIUMOP_A(popcnt_r32_rm32), false},
- { 0xBC, OP_3BYTEF3|OP_PENTIUM, PENTIUMOP_A(tzcnt_r16_rm16), PENTIUMOP_A(tzcnt_r32_rm32), false},
- { 0xC2, OP_3BYTEF3|OP_SSE, SSEOP_A(cmpss_r128_r128m32_i8), SSEOP_A(cmpss_r128_r128m32_i8),false},
- { 0xC7, OP_3BYTEF2|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0xD6, OP_3BYTEF3|OP_SSE, SSEOP_A(movq2dq_r128_r64), SSEOP_A(movq2dq_r128_r64), false},
- { 0xE6, OP_3BYTEF3|OP_SSE, SSEOP_A(cvtdq2pd_r128_r128m64), SSEOP_A(cvtdq2pd_r128_r128m64),false},
- /* F2 0F ?? */
- { 0x10, OP_3BYTEF2|OP_SSE, SSEOP_A(movsd_r128_r128m64), SSEOP_A(movsd_r128_r128m64), false},
- { 0x11, OP_3BYTEF2|OP_SSE, SSEOP_A(movsd_r128m64_r128), SSEOP_A(movsd_r128m64_r128), false},
- { 0x12, OP_3BYTEF2|OP_SSE, SSEOP_A(movddup_r128_r128m64), SSEOP_A(movddup_r128_r128m64),false},
- { 0x2A, OP_3BYTEF2|OP_SSE, SSEOP_A(cvtsi2sd_r128_rm32), SSEOP_A(cvtsi2sd_r128_rm32), false},
- { 0x2C, OP_3BYTEF2|OP_SSE, SSEOP_A(cvttsd2si_r32_r128m64), SSEOP_A(cvttsd2si_r32_r128m64),false},
- { 0x2D, OP_3BYTEF2|OP_SSE, SSEOP_A(cvtsd2si_r32_r128m64), SSEOP_A(cvtsd2si_r32_r128m64),false},
- { 0x51, OP_3BYTEF2|OP_SSE, SSEOP_A(sqrtsd_r128_r128m64), SSEOP_A(sqrtsd_r128_r128m64), false},
- { 0x58, OP_3BYTEF2|OP_SSE, SSEOP_A(addsd_r128_r128m64), SSEOP_A(addsd_r128_r128m64), false},
- { 0x59, OP_3BYTEF2|OP_SSE, SSEOP_A(mulsd_r128_r128m64), SSEOP_A(mulsd_r128_r128m64), false},
- { 0x5A, OP_3BYTEF2|OP_SSE, SSEOP_A(cvtsd2ss_r128_r128m64), SSEOP_A(cvtsd2ss_r128_r128m64),false},
- { 0x5C, OP_3BYTEF2|OP_SSE, SSEOP_A(subsd_r128_r128m64), SSEOP_A(subsd_r128_r128m64), false},
- { 0x5D, OP_3BYTEF2|OP_SSE, SSEOP_A(minsd_r128_r128m64), SSEOP_A(minsd_r128_r128m64), false},
- { 0x5E, OP_3BYTEF2|OP_SSE, SSEOP_A(divsd_r128_r128m64), SSEOP_A(divsd_r128_r128m64), false},
- { 0x5F, OP_3BYTEF2|OP_SSE, SSEOP_A(maxsd_r128_r128m64), SSEOP_A(maxsd_r128_r128m64), false},
- { 0x70, OP_3BYTEF2|OP_SSE, SSEOP_A(pshuflw_r128_rm128_i8), SSEOP_A(pshuflw_r128_rm128_i8),false},
- { 0x7C, OP_3BYTEF2|OP_SSE, SSEOP_A(haddps_r128_rm128), SSEOP_A(haddps_r128_rm128), false},
- { 0x7D, OP_3BYTEF2|OP_SSE, SSEOP_A(hsubps_r128_rm128), SSEOP_A(hsubps_r128_rm128), false},
- { 0xC2, OP_3BYTEF2|OP_SSE, SSEOP_A(cmpsd_r128_r128m64_i8), SSEOP_A(cmpsd_r128_r128m64_i8),false},
- { 0xD0, OP_3BYTEF2|OP_SSE, SSEOP_A(addsubps_r128_rm128), SSEOP_A(addsubps_r128_rm128), false},
- { 0xD6, OP_3BYTEF2|OP_SSE, SSEOP_A(movdq2q_r64_r128), SSEOP_A(movdq2q_r64_r128), false},
- { 0xE6, OP_3BYTEF2|OP_SSE, SSEOP_A(cvtpd2dq_r128_rm128), SSEOP_A(cvtpd2dq_r128_rm128), false},
- { 0xF0, OP_3BYTEF2|OP_SSE, SSEOP_A(lddqu_r128_m128), SSEOP_A(lddqu_r128_m128), false},
- /* 66 0F ?? */
- { 0x10, OP_3BYTE66|OP_SSE, SSEOP_A(movupd_r128_rm128), SSEOP_A(movupd_r128_rm128), false},
- { 0x11, OP_3BYTE66|OP_SSE, SSEOP_A(movupd_rm128_r128), SSEOP_A(movupd_rm128_r128), false},
- { 0x12, OP_3BYTE66|OP_SSE, SSEOP_A(movlpd_r128_m64), SSEOP_A(movlpd_r128_m64), false},
- { 0x13, OP_3BYTE66|OP_SSE, SSEOP_A(movlpd_m64_r128), SSEOP_A(movlpd_m64_r128), false},
- { 0x14, OP_3BYTE66|OP_SSE, SSEOP_A(unpcklpd_r128_rm128), SSEOP_A(unpcklpd_r128_rm128), false},
- { 0x15, OP_3BYTE66|OP_SSE, SSEOP_A(unpckhpd_r128_rm128), SSEOP_A(unpckhpd_r128_rm128), false},
- { 0x16, OP_3BYTE66|OP_SSE, SSEOP_A(movhpd_r128_m64), SSEOP_A(movhpd_r128_m64), false},
- { 0x17, OP_3BYTE66|OP_SSE, SSEOP_A(movhpd_m64_r128), SSEOP_A(movhpd_m64_r128), false},
- { 0x28, OP_3BYTE66|OP_SSE, SSEOP_A(movapd_r128_rm128), SSEOP_A(movapd_r128_rm128), false},
- { 0x29, OP_3BYTE66|OP_SSE, SSEOP_A(movapd_rm128_r128), SSEOP_A(movapd_rm128_r128), false},
- { 0x2A, OP_3BYTE66|OP_SSE, SSEOP_A(cvtpi2pd_r128_rm64), SSEOP_A(cvtpi2pd_r128_rm64), false},
- { 0x2B, OP_3BYTE66|OP_SSE, SSEOP_A(movntpd_m128_r128), SSEOP_A(movntpd_m128_r128), false},
- { 0x2C, OP_3BYTE66|OP_SSE, SSEOP_A(cvttpd2pi_r64_rm128), SSEOP_A(cvttpd2pi_r64_rm128), false},
- { 0x2D, OP_3BYTE66|OP_SSE, SSEOP_A(cvtpd2pi_r64_rm128), SSEOP_A(cvtpd2pi_r64_rm128), false},
- { 0x2E, OP_3BYTE66|OP_SSE, SSEOP_A(ucomisd_r128_r128m64), SSEOP_A(ucomisd_r128_r128m64),false},
- { 0x2F, OP_3BYTE66|OP_SSE, SSEOP_A(comisd_r128_r128m64), SSEOP_A(comisd_r128_r128m64), false},
- { 0x50, OP_3BYTE66|OP_SSE, SSEOP_A(movmskpd_r32_r128), SSEOP_A(movmskpd_r32_r128), false},
- { 0x51, OP_3BYTE66|OP_SSE, SSEOP_A(sqrtpd_r128_rm128), SSEOP_A(sqrtpd_r128_rm128), false},
- { 0x54, OP_3BYTE66|OP_SSE, SSEOP_A(andpd_r128_rm128), SSEOP_A(andpd_r128_rm128), false},
- { 0x55, OP_3BYTE66|OP_SSE, SSEOP_A(andnpd_r128_rm128), SSEOP_A(andnpd_r128_rm128), false},
- { 0x56, OP_3BYTE66|OP_SSE, SSEOP_A(orpd_r128_rm128), SSEOP_A(orpd_r128_rm128), false},
- { 0x57, OP_3BYTE66|OP_SSE, SSEOP_A(xorpd_r128_rm128), SSEOP_A(xorpd_r128_rm128), false},
- { 0x58, OP_3BYTE66|OP_SSE, SSEOP_A(addpd_r128_rm128), SSEOP_A(addpd_r128_rm128), false},
- { 0x59, OP_3BYTE66|OP_SSE, SSEOP_A(mulpd_r128_rm128), SSEOP_A(mulpd_r128_rm128), false},
- { 0x5A, OP_3BYTE66|OP_SSE, SSEOP_A(cvtpd2ps_r128_rm128), SSEOP_A(cvtpd2ps_r128_rm128), false},
- { 0x5B, OP_3BYTE66|OP_SSE, SSEOP_A(cvtps2dq_r128_rm128), SSEOP_A(cvtps2dq_r128_rm128), false},
- { 0x5C, OP_3BYTE66|OP_SSE, SSEOP_A(subpd_r128_rm128), SSEOP_A(subpd_r128_rm128), false},
- { 0x5D, OP_3BYTE66|OP_SSE, SSEOP_A(minpd_r128_rm128), SSEOP_A(minpd_r128_rm128), false},
- { 0x5E, OP_3BYTE66|OP_SSE, SSEOP_A(divpd_r128_rm128), SSEOP_A(divpd_r128_rm128), false},
- { 0x5F, OP_3BYTE66|OP_SSE, SSEOP_A(maxpd_r128_rm128), SSEOP_A(maxpd_r128_rm128), false},
- { 0x60, OP_3BYTE66|OP_SSE, SSEOP_A(punpcklbw_r128_rm128), SSEOP_A(punpcklbw_r128_rm128),false},
- { 0x61, OP_3BYTE66|OP_SSE, SSEOP_A(punpcklwd_r128_rm128), SSEOP_A(punpcklwd_r128_rm128),false},
- { 0x62, OP_3BYTE66|OP_SSE, SSEOP_A(punpckldq_r128_rm128), SSEOP_A(punpckldq_r128_rm128),false},
- { 0x63, OP_3BYTE66|OP_SSE, SSEOP_A(packsswb_r128_rm128), SSEOP_A(packsswb_r128_rm128), false},
- { 0x64, OP_3BYTE66|OP_SSE, SSEOP_A(pcmpgtb_r128_rm128), SSEOP_A(pcmpgtb_r128_rm128), false},
- { 0x65, OP_3BYTE66|OP_SSE, SSEOP_A(pcmpgtw_r128_rm128), SSEOP_A(pcmpgtw_r128_rm128), false},
- { 0x66, OP_3BYTE66|OP_SSE, SSEOP_A(pcmpgtd_r128_rm128), SSEOP_A(pcmpgtd_r128_rm128), false},
- { 0x67, OP_3BYTE66|OP_SSE, SSEOP_A(packuswb_r128_rm128), SSEOP_A(packuswb_r128_rm128), false},
- { 0x68, OP_3BYTE66|OP_SSE, SSEOP_A(punpckhbw_r128_rm128), SSEOP_A(punpckhbw_r128_rm128),false},
- { 0x69, OP_3BYTE66|OP_SSE, SSEOP_A(punpckhwd_r128_rm128), SSEOP_A(punpckhwd_r128_rm128),false},
- { 0x6A, OP_3BYTE66|OP_SSE, SSEOP_A(unpckhdq_r128_rm128), SSEOP_A(unpckhdq_r128_rm128), false},
- { 0x6B, OP_3BYTE66|OP_SSE, SSEOP_A(packssdw_r128_rm128), SSEOP_A(packssdw_r128_rm128), false},
- { 0x6C, OP_3BYTE66|OP_SSE, SSEOP_A(punpcklqdq_r128_rm128), SSEOP_A(punpcklqdq_r128_rm128),false},
- { 0x6D, OP_3BYTE66|OP_SSE, SSEOP_A(punpckhqdq_r128_rm128), SSEOP_A(punpckhqdq_r128_rm128),false},
- { 0x6E, OP_3BYTE66|OP_SSE, SSEOP_A(movd_m128_rm32), SSEOP_A(movd_m128_rm32), false},
- { 0x6F, OP_3BYTE66|OP_SSE, SSEOP_A(movdqa_m128_rm128), SSEOP_A(movdqa_m128_rm128), false},
- { 0x70, OP_3BYTE66|OP_SSE, SSEOP_A(pshufd_r128_rm128_i8), SSEOP_A(pshufd_r128_rm128_i8),false},
- { 0x71, OP_3BYTE66|OP_SSE, SSEOP_A(group_660f71), SSEOP_A(group_660f71), false},
- { 0x72, OP_3BYTE66|OP_SSE, SSEOP_A(group_660f72), SSEOP_A(group_660f72), false},
- { 0x73, OP_3BYTE66|OP_SSE, SSEOP_A(group_660f73), SSEOP_A(group_660f73), false},
- { 0x74, OP_3BYTE66|OP_SSE, SSEOP_A(pcmpeqb_r128_rm128), SSEOP_A(pcmpeqb_r128_rm128), false},
- { 0x75, OP_3BYTE66|OP_SSE, SSEOP_A(pcmpeqw_r128_rm128), SSEOP_A(pcmpeqw_r128_rm128), false},
- { 0x76, OP_3BYTE66|OP_SSE, SSEOP_A(pcmpeqd_r128_rm128), SSEOP_A(pcmpeqd_r128_rm128), false},
- { 0x7C, OP_3BYTE66|OP_SSE, SSEOP_A(haddpd_r128_rm128), SSEOP_A(haddpd_r128_rm128), false},
- { 0x7D, OP_3BYTE66|OP_SSE, SSEOP_A(hsubpd_r128_rm128), SSEOP_A(hsubpd_r128_rm128), false},
- { 0x7E, OP_3BYTE66|OP_SSE, SSEOP_A(movd_rm32_r128), SSEOP_A(movd_rm32_r128), false},
- { 0x7F, OP_3BYTE66|OP_SSE, SSEOP_A(movdqa_rm128_r128), SSEOP_A(movdqa_rm128_r128), false},
- { 0xC2, OP_3BYTE66|OP_SSE, SSEOP_A(cmppd_r128_rm128_i8), SSEOP_A(cmppd_r128_rm128_i8), false},
- { 0xC4, OP_3BYTE66|OP_SSE, SSEOP_A(pinsrw_r128_r32m16_i8), SSEOP_A(pinsrw_r128_r32m16_i8),false},
- { 0xC5, OP_3BYTE66|OP_SSE, SSEOP_A(pextrw_reg_r128_i8), SSEOP_A(pextrw_reg_r128_i8), false},
- { 0xC6, OP_3BYTE66|OP_SSE, SSEOP_A(shufpd_r128_rm128_i8), SSEOP_A(shufpd_r128_rm128_i8),false},
- { 0xC7, OP_3BYTE66|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0xD0, OP_3BYTE66|OP_SSE, SSEOP_A(addsubpd_r128_rm128), SSEOP_A(addsubpd_r128_rm128), false},
- { 0xD1, OP_3BYTE66|OP_SSE, SSEOP_A(psrlw_r128_rm128), SSEOP_A(psrlw_r128_rm128), false},
- { 0xD2, OP_3BYTE66|OP_SSE, SSEOP_A(psrld_r128_rm128), SSEOP_A(psrld_r128_rm128), false},
- { 0xD3, OP_3BYTE66|OP_SSE, SSEOP_A(psrlq_r128_rm128), SSEOP_A(psrlq_r128_rm128), false},
- { 0xD4, OP_3BYTE66|OP_SSE, SSEOP_A(paddq_r128_rm128), SSEOP_A(paddq_r128_rm128), false},
- { 0xD5, OP_3BYTE66|OP_SSE, SSEOP_A(pmullw_r128_rm128), SSEOP_A(pmullw_r128_rm128), false},
- { 0xD6, OP_3BYTE66|OP_SSE, SSEOP_A(movq_r128m64_r128), SSEOP_A(movq_r128m64_r128), false},
- { 0xD7, OP_3BYTE66|OP_SSE, SSEOP_A(pmovmskb_r32_r128), SSEOP_A(pmovmskb_r32_r128), false},
- { 0xD8, OP_3BYTE66|OP_SSE, SSEOP_A(psubusb_r128_rm128), SSEOP_A(psubusb_r128_rm128), false},
- { 0xD9, OP_3BYTE66|OP_SSE, SSEOP_A(psubusw_r128_rm128), SSEOP_A(psubusw_r128_rm128), false},
- { 0xDA, OP_3BYTE66|OP_SSE, SSEOP_A(pminub_r128_rm128), SSEOP_A(pminub_r128_rm128), false},
- { 0xDB, OP_3BYTE66|OP_SSE, SSEOP_A(pand_r128_rm128), SSEOP_A(pand_r128_rm128), false},
- { 0xDC, OP_3BYTE66|OP_SSE, SSEOP_A(paddusb_r128_rm128), SSEOP_A(paddusb_r128_rm128), false},
- { 0xDD, OP_3BYTE66|OP_SSE, SSEOP_A(paddusw_r128_rm128), SSEOP_A(paddusw_r128_rm128), false},
- { 0xDE, OP_3BYTE66|OP_SSE, SSEOP_A(pmaxub_r128_rm128), SSEOP_A(pmaxub_r128_rm128), false},
- { 0xDF, OP_3BYTE66|OP_SSE, SSEOP_A(pandn_r128_rm128), SSEOP_A(pandn_r128_rm128), false},
- { 0xE0, OP_3BYTE66|OP_SSE, SSEOP_A(pavgb_r128_rm128), SSEOP_A(pavgb_r128_rm128), false},
- { 0xE1, OP_3BYTE66|OP_SSE, SSEOP_A(psraw_r128_rm128), SSEOP_A(psraw_r128_rm128), false},
- { 0xE2, OP_3BYTE66|OP_SSE, SSEOP_A(psrad_r128_rm128), SSEOP_A(psrad_r128_rm128), false},
- { 0xE3, OP_3BYTE66|OP_SSE, SSEOP_A(pavgw_r128_rm128), SSEOP_A(pavgw_r128_rm128), false},
- { 0xE4, OP_3BYTE66|OP_SSE, SSEOP_A(pmulhuw_r128_rm128), SSEOP_A(pmulhuw_r128_rm128), false},
- { 0xE5, OP_3BYTE66|OP_SSE, SSEOP_A(pmulhw_r128_rm128), SSEOP_A(pmulhw_r128_rm128), false},
- { 0xE6, OP_3BYTE66|OP_SSE, SSEOP_A(cvttpd2dq_r128_rm128), SSEOP_A(cvttpd2dq_r128_rm128),false},
- { 0xE7, OP_3BYTE66|OP_SSE, SSEOP_A(movntdq_m128_r128), SSEOP_A(movntdq_m128_r128), false},
- { 0xE8, OP_3BYTE66|OP_SSE, SSEOP_A(psubsb_r128_rm128), SSEOP_A(psubsb_r128_rm128), false},
- { 0xE9, OP_3BYTE66|OP_SSE, SSEOP_A(psubsw_r128_rm128), SSEOP_A(psubsw_r128_rm128), false},
- { 0xEA, OP_3BYTE66|OP_SSE, SSEOP_A(pminsw_r128_rm128), SSEOP_A(pminsw_r128_rm128), false},
- { 0xEB, OP_3BYTE66|OP_SSE, SSEOP_A(por_r128_rm128), SSEOP_A(por_r128_rm128), false},
- { 0xEC, OP_3BYTE66|OP_SSE, SSEOP_A(paddsb_r128_rm128), SSEOP_A(paddsb_r128_rm128), false},
- { 0xED, OP_3BYTE66|OP_SSE, SSEOP_A(paddsw_r128_rm128), SSEOP_A(paddsw_r128_rm128), false},
- { 0xEE, OP_3BYTE66|OP_SSE, SSEOP_A(pmaxsw_r128_rm128), SSEOP_A(pmaxsw_r128_rm128), false},
- { 0xEF, OP_3BYTE66|OP_SSE, SSEOP_A(pxor_r128_rm128), SSEOP_A(pxor_r128_rm128), false},
- { 0xF1, OP_3BYTE66|OP_SSE, SSEOP_A(psllw_r128_rm128), SSEOP_A(psllw_r128_rm128), false},
- { 0xF2, OP_3BYTE66|OP_SSE, SSEOP_A(pslld_r128_rm128), SSEOP_A(pslld_r128_rm128), false},
- { 0xF3, OP_3BYTE66|OP_SSE, SSEOP_A(psllq_r128_rm128), SSEOP_A(psllq_r128_rm128), false},
- { 0xF4, OP_3BYTE66|OP_SSE, SSEOP_A(pmuludq_r128_rm128), SSEOP_A(pmuludq_r128_rm128), false},
- { 0xF5, OP_3BYTE66|OP_SSE, SSEOP_A(pmaddwd_r128_rm128), SSEOP_A(pmaddwd_r128_rm128), false},
- { 0xF6, OP_3BYTE66|OP_SSE, SSEOP_A(psadbw_r128_rm128), SSEOP_A(psadbw_r128_rm128), false},
- { 0xF7, OP_3BYTE66|OP_SSE, SSEOP_A(maskmovdqu_r128_r128), SSEOP_A(maskmovdqu_r128_r128),false},
- { 0xF8, OP_3BYTE66|OP_SSE, SSEOP_A(psubb_r128_rm128), SSEOP_A(psubb_r128_rm128), false},
- { 0xF9, OP_3BYTE66|OP_SSE, SSEOP_A(psubw_r128_rm128), SSEOP_A(psubw_r128_rm128), false},
- { 0xFA, OP_3BYTE66|OP_SSE, SSEOP_A(psubd_r128_rm128), SSEOP_A(psubd_r128_rm128), false},
- { 0xFB, OP_3BYTE66|OP_SSE, SSEOP_A(psubq_r128_rm128), SSEOP_A(psubq_r128_rm128), false},
- { 0xFC, OP_3BYTE66|OP_SSE, SSEOP_A(paddb_r128_rm128), SSEOP_A(paddb_r128_rm128), false},
- { 0xFD, OP_3BYTE66|OP_SSE, SSEOP_A(paddw_r128_rm128), SSEOP_A(paddw_r128_rm128), false},
- { 0xFE, OP_3BYTE66|OP_SSE, SSEOP_A(paddd_r128_rm128), SSEOP_A(paddd_r128_rm128), false},
- /* 0F 38 ?? */
- { 0x00, OP_3BYTE38|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x01, OP_3BYTE38|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x02, OP_3BYTE38|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x03, OP_3BYTE38|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x04, OP_3BYTE38|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x05, OP_3BYTE38|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x06, OP_3BYTE38|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x07, OP_3BYTE38|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x08, OP_3BYTE38|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x09, OP_3BYTE38|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x0A, OP_3BYTE38|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x0B, OP_3BYTE38|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x1C, OP_3BYTE38|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x1D, OP_3BYTE38|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x1E, OP_3BYTE38|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0xF0, OP_3BYTE38|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0xF1, OP_3BYTE38|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0xF2, OP_3BYTE38|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0xF3, OP_3BYTE38|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0xF5, OP_3BYTE38|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0xF7, OP_3BYTE38|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- /* 0F 3A ?? */
- { 0x0F, OP_3BYTE3A|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- /* 66 0F 38 ?? */
- { 0x00, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x01, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x02, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x03, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x04, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x05, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x06, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x07, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x08, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x09, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x0A, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x0B, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x0C, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x0D, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x0E, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x0F, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x10, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x13, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x14, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x15, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x16, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x17, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x18, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x19, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x1A, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x1C, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x1D, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x1E, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x20, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x21, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x22, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x23, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x24, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x25, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x28, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x29, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x2A, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x2B, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x2C, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x2D, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x2E, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x2F, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x30, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x31, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x32, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x33, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x34, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x35, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x36, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x37, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x38, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x39, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x3A, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x3B, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x3C, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x3D, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x3E, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x3F, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x40, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x41, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x45, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x46, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x47, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x58, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x59, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x5A, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x78, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x79, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x80, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x81, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x82, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x8C, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x8E, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x90, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x91, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x92, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x93, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x96, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x97, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x98, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x99, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x9A, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x9B, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x9C, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x9D, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x9E, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x9F, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0xA6, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0xA7, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0xA8, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0xA9, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0xAA, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0xAB, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0xAC, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0xAD, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0xAE, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0xAF, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0xB6, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0xB7, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0xB8, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0xB9, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0xBA, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0xBB, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0xBC, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0xBD, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0xBE, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0xBF, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0xDB, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0xDC, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0xDD, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0xDE, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0xDF, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0xF0, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0xF1, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0xF3, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0xF6, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0xF7, OP_4BYTE3866|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- /* F2 0F 38 ?? */
- { 0xF0, OP_4BYTE38F2|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0xF1, OP_4BYTE38F2|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0xF3, OP_4BYTE38F2|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0xF5, OP_4BYTE38F2|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0xF6, OP_4BYTE38F2|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0xF7, OP_4BYTE38F2|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- /* F3 0F 38 ?? */
- { 0xF3, OP_4BYTE38F3|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0xF5, OP_4BYTE38F3|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0xF6, OP_4BYTE38F3|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0xF7, OP_4BYTE38F3|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- /* 66 0F 3A ?? */
- { 0x00, OP_4BYTE3A66|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x01, OP_4BYTE3A66|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x02, OP_4BYTE3A66|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x04, OP_4BYTE3A66|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x05, OP_4BYTE3A66|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x06, OP_4BYTE3A66|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x08, OP_4BYTE3A66|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x09, OP_4BYTE3A66|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x0A, OP_4BYTE3A66|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x0B, OP_4BYTE3A66|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x0C, OP_4BYTE3A66|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x0D, OP_4BYTE3A66|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x0E, OP_4BYTE3A66|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x0F, OP_4BYTE3A66|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x14, OP_4BYTE3A66|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x15, OP_4BYTE3A66|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x16, OP_4BYTE3A66|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x17, OP_4BYTE3A66|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x18, OP_4BYTE3A66|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x19, OP_4BYTE3A66|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x1D, OP_4BYTE3A66|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x20, OP_4BYTE3A66|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x21, OP_4BYTE3A66|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x22, OP_4BYTE3A66|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x38, OP_4BYTE3A66|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x39, OP_4BYTE3A66|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x40, OP_4BYTE3A66|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x41, OP_4BYTE3A66|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x42, OP_4BYTE3A66|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x44, OP_4BYTE3A66|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x46, OP_4BYTE3A66|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x4A, OP_4BYTE3A66|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x4B, OP_4BYTE3A66|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x4C, OP_4BYTE3A66|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x60, OP_4BYTE3A66|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x61, OP_4BYTE3A66|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x62, OP_4BYTE3A66|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0x63, OP_4BYTE3A66|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- { 0xDF, OP_4BYTE3A66|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false},
- /* F2 0F 3A ?? */
- { 0xF0, OP_4BYTE3AF2|OP_SSE, I386OP_A(invalid), I386OP_A(invalid), false}
-};
-#endif
+++ /dev/null
-
-#include "../vm.h"
-#include "../../emu.h"
-#include "./i386opdef_real.h"
-
-I386_OPS::I386_OPS(void) : I386_OPS_BASE()
-{
-}
-
-I386_OPS::~I386_OPS_BASE()
-{
-}
-
-int I386_OPS::cpu_translate_i386(void *cpudevice, address_spacenum space, int intention, offs_t *address)
-{
- i386_state *cpu_state = (i386_state *)cpudevice;
- int ret = TRUE;
- if(space == AS_PROGRAM)
- ret = i386_translate_address(cpu_state, intention, address, NULL);
- *address &= cpu_state->a20_mask;
- return ret;
-}
-
-int I386_OPS::cpu_execute_i386(int cycles)
-{
- CHANGE_PC(cpustate,cpustate->eip);
-
- if (cpustate->halted || cpustate->busreq)
- {
-#ifdef SINGLE_MODE_DMA
- if(cpustate->dma != NULL) {
- cpustate->dma->do_dma();
- }
-#endif
- if (cycles == -1) {
- int passed_cycles = max(1, cpustate->extra_cycles);
- // this is main cpu, cpustate->cycles is not used
- /*cpustate->cycles = */cpustate->extra_cycles = 0;
- cpustate->tsc += passed_cycles;
- return passed_cycles;
- } else {
- cpustate->cycles += cycles;
- cpustate->base_cycles = cpustate->cycles;
-
- /* adjust for any interrupts that came in */
- cpustate->cycles -= cpustate->extra_cycles;
- cpustate->extra_cycles = 0;
-
- /* if busreq is raised, spin cpu while remained clock */
- if (cpustate->cycles > 0) {
- cpustate->cycles = 0;
- }
- int passed_cycles = cpustate->base_cycles - cpustate->cycles;
- cpustate->tsc += passed_cycles;
- return passed_cycles;
- }
- }
-
- if (cycles == -1) {
- cpustate->cycles = 1;
- } else {
- cpustate->cycles += cycles;
- }
- cpustate->base_cycles = cpustate->cycles;
-
- /* adjust for any interrupts that came in */
- cpustate->cycles -= cpustate->extra_cycles;
- cpustate->extra_cycles = 0;
-
- while( cpustate->cycles > 0 && !cpustate->busreq )
- {
-#ifdef USE_DEBUGGER
- bool now_debugging = cpustate->debugger->now_debugging;
- if(now_debugging) {
- cpustate->debugger->check_break_points(cpustate->pc);
- if(cpustate->debugger->now_suspended) {
- cpustate->emu->mute_sound();
- while(cpustate->debugger->now_debugging && cpustate->debugger->now_suspended) {
- cpustate->emu->sleep(10);
- }
- }
- if(cpustate->debugger->now_debugging) {
- cpustate->program = cpustate->io = cpustate->debugger;
- } else {
- now_debugging = false;
- }
- i386_check_irq_line(cpustate);
- cpustate->operand_size = cpustate->sreg[CS].d;
- cpustate->xmm_operand_size = 0;
- cpustate->address_size = cpustate->sreg[CS].d;
- cpustate->operand_prefix = 0;
- cpustate->address_prefix = 0;
-
- cpustate->ext = 1;
- int old_tf = cpustate->TF;
-
- cpustate->segment_prefix = 0;
- cpustate->prev_eip = cpustate->eip;
- cpustate->prev_pc = cpustate->pc;
-
- if(cpustate->delayed_interrupt_enable != 0)
- {
- cpustate->IF = 1;
- cpustate->delayed_interrupt_enable = 0;
- }
-#ifdef DEBUG_MISSING_OPCODE
- cpustate->opcode_bytes_length = 0;
- cpustate->opcode_pc = cpustate->pc;
-#endif
- try
- {
- I386OP(decode_opcode)(cpustate);
- if(cpustate->TF && old_tf)
- {
- cpustate->prev_eip = cpustate->eip;
- cpustate->ext = 1;
- i386_trap(cpustate,1,0,0);
- }
- if(cpustate->lock && (cpustate->opcode != 0xf0))
- cpustate->lock = false;
- }
- catch(UINT64 e)
- {
- cpustate->ext = 1;
- i386_trap_with_error(cpustate,e&0xffffffff,0,0,e>>32);
- }
-#ifdef SINGLE_MODE_DMA
- if(cpustate->dma != NULL) {
- cpustate->dma->do_dma();
- }
-#endif
- /* adjust for any interrupts that came in */
- cpustate->cycles -= cpustate->extra_cycles;
- cpustate->extra_cycles = 0;
-
- if(now_debugging) {
- if(!cpustate->debugger->now_going) {
- cpustate->debugger->now_suspended = true;
- }
- cpustate->program = cpustate->program_stored;
- cpustate->io = cpustate->io_stored;
- }
- } else {
-#endif
- i386_check_irq_line(cpustate);
- cpustate->operand_size = cpustate->sreg[CS].d;
- cpustate->xmm_operand_size = 0;
- cpustate->address_size = cpustate->sreg[CS].d;
- cpustate->operand_prefix = 0;
- cpustate->address_prefix = 0;
-
- cpustate->ext = 1;
- int old_tf = cpustate->TF;
-
- cpustate->segment_prefix = 0;
- cpustate->prev_eip = cpustate->eip;
- cpustate->prev_pc = cpustate->pc;
-
- if(cpustate->delayed_interrupt_enable != 0)
- {
- cpustate->IF = 1;
- cpustate->delayed_interrupt_enable = 0;
- }
-#ifdef DEBUG_MISSING_OPCODE
- cpustate->opcode_bytes_length = 0;
- cpustate->opcode_pc = cpustate->pc;
-#endif
- try
- {
- I386OP(decode_opcode)(cpustate);
- if(cpustate->TF && old_tf)
- {
- cpustate->prev_eip = cpustate->eip;
- cpustate->ext = 1;
- i386_trap(cpustate,1,0,0);
- }
- if(cpustate->lock && (cpustate->opcode != 0xf0))
- cpustate->lock = false;
- }
- catch(UINT64 e)
- {
- cpustate->ext = 1;
- i386_trap_with_error(cpustate,e&0xffffffff,0,0,e>>32);
- }
-#ifdef SINGLE_MODE_DMA
- if(cpustate->dma != NULL) {
- cpustate->dma->do_dma();
- }
-#endif
- /* adjust for any interrupts that came in */
- cpustate->cycles -= cpustate->extra_cycles;
- cpustate->extra_cycles = 0;
-#ifdef USE_DEBUGGER
- }
-#endif
- }
-
- /* if busreq is raised, spin cpu while remained clock */
- if (cpustate->cycles > 0 && cpustate->busreq) {
- cpustate->cycles = 0;
- }
- int passed_cycles = cpustate->base_cycles - cpustate->cycles;
- cpustate->tsc += passed_cycles;
- return passed_cycles;
-}
-
-
-void I386_OPS::I386OP(int)(i386_state *cpustate) // Opcode 0xcd
-{
- int interrupt = FETCH(cpustate);
- CYCLES(cpustate,CYCLES_INT);
-#ifdef I386_PSEUDO_BIOS
- BIOS_INT(interrupt)
-#endif
- cpustate->ext = 0; // not an external interrupt
- i386_trap(cpustate,interrupt, 1, 0);
- cpustate->ext = 1;
-}
+++ /dev/null
-// license:BSD-3-Clause
-// copyright-holders:Ville Linde
-/*
- i386 Disassembler
-
- Written by Ville Linde
-*/
-
-//#include "emu.h"
-
-enum
-{
- PARAM_REG = 1, /* 16 or 32-bit register */
- PARAM_REG8, /* 8-bit register */
- PARAM_REG16, /* 16-bit register */
- PARAM_REG32, /* 32-bit register */
- PARAM_REG3264, /* 32-bit or 64-bit register */
- PARAM_REG2_32, /* 32-bit register */
- PARAM_MMX, /* MMX register */
- PARAM_MMX2, /* MMX register in modrm */
- PARAM_XMM, /* XMM register */
- PARAM_RM, /* 16 or 32-bit memory or register */
- PARAM_RM8, /* 8-bit memory or register */
- PARAM_RM16, /* 16-bit memory or register */
- PARAM_RM32, /* 32-bit memory or register */
- PARAM_RMPTR, /* 16 or 32-bit memory or register */
- PARAM_RMPTR8, /* 8-bit memory or register */
- PARAM_RMPTR16, /* 16-bit memory or register */
- PARAM_RMPTR32, /* 32-bit memory or register */
- PARAM_RMXMM, /* 32 or 64-bit memory or register */
- PARAM_REGORXMM, /* 32 or 64-bit register or XMM register */
- PARAM_M64, /* 64-bit memory */
- PARAM_M64PTR, /* 64-bit memory */
- PARAM_MMXM, /* 64-bit memory or MMX register */
- PARAM_XMMM, /* 128-bit memory or XMM register */
- PARAM_I4, /* 4-bit signed immediate */
- PARAM_I8, /* 8-bit signed immediate */
- PARAM_I16, /* 16-bit signed immediate */
- PARAM_UI8, /* 8-bit unsigned immediate */
- PARAM_UI16, /* 16-bit unsigned immediate */
- PARAM_IMM, /* 16 or 32-bit immediate */
- PARAM_IMM64, /* 16, 32 or 64-bit immediate */
- PARAM_ADDR, /* 16:16 or 16:32 address */
- PARAM_REL, /* 16 or 32-bit PC-relative displacement */
- PARAM_REL8, /* 8-bit PC-relative displacement */
- PARAM_MEM_OFFS, /* 16 or 32-bit mem offset */
- PARAM_PREIMP, /* prefix with implicit register */
- PARAM_SREG, /* segment register */
- PARAM_CREG, /* control register */
- PARAM_DREG, /* debug register */
- PARAM_TREG, /* test register */
- PARAM_1, /* used by shift/rotate instructions */
- PARAM_AL,
- PARAM_CL,
- PARAM_DL,
- PARAM_BL,
- PARAM_AH,
- PARAM_CH,
- PARAM_DH,
- PARAM_BH,
- PARAM_DX,
- PARAM_EAX, /* EAX or AX */
- PARAM_ECX, /* ECX or CX */
- PARAM_EDX, /* EDX or DX */
- PARAM_EBX, /* EBX or BX */
- PARAM_ESP, /* ESP or SP */
- PARAM_EBP, /* EBP or BP */
- PARAM_ESI, /* ESI or SI */
- PARAM_EDI, /* EDI or DI */
- PARAM_XMM0,
- PARAM_XMM64, /* 64-bit memory or XMM register */
- PARAM_XMM32, /* 32-bit memory or XMM register */
- PARAM_XMM16, /* 16-bit memory or XMM register */
-};
-
-enum
-{
- MODRM = 1,
- GROUP,
- FPU,
- OP_SIZE,
- ADDR_SIZE,
- TWO_BYTE,
- PREFIX,
- SEG_CS,
- SEG_DS,
- SEG_ES,
- SEG_FS,
- SEG_GS,
- SEG_SS,
- ISREX,
- THREE_BYTE /* [prefix] 0f op1 op2 and then mod/rm */
-};
-
-#define FLAGS_MASK 0x0ff
-#define VAR_NAME 0x100
-#define VAR_NAME4 0x200
-#define ALWAYS64 0x400
-#define SPECIAL64 0x800
-#define SPECIAL64_ENT(x) (SPECIAL64 | ((x) << 24))
-#define GROUP_MOD 0x1000
-
-struct I386_OPCODE {
- const _TCHAR *mnemonic;
- UINT32 flags;
- UINT32 param1;
- UINT32 param2;
- UINT32 param3;
- offs_t dasm_flags;
-};
-
-struct GROUP_OP {
- _TCHAR mnemonic[32];
- const I386_OPCODE *opcode;
-};
-
-static const UINT8 *opcode_ptr;
-static const UINT8 *opcode_ptr_base;
-
-static const i386_opcode_table1[256] =
-{
- // 0x00
- {_T("add"), MODRM, PARAM_RM8, PARAM_REG8, 0 },
- {_T("add"), MODRM, PARAM_RM, PARAM_REG, 0 },
- {_T("add"), MODRM, PARAM_REG8, PARAM_RM8, 0 },
- {_T("add"), MODRM, PARAM_REG, PARAM_RM, 0 },
- {_T("add"), 0, PARAM_AL, PARAM_UI8, 0 },
- {_T("add"), 0, PARAM_EAX, PARAM_IMM, 0 },
- {_T("push es"), 0, 0, 0, 0 },
- {_T("pop es"), 0, 0, 0, 0 },
- {_T("or"), MODRM, PARAM_RM8, PARAM_REG8, 0 },
- {_T("or"), MODRM, PARAM_RM, PARAM_REG, 0 },
- {_T("or"), MODRM, PARAM_REG8, PARAM_RM8, 0 },
- {_T("or"), MODRM, PARAM_REG, PARAM_RM, 0 },
- {_T("or"), 0, PARAM_AL, PARAM_UI8, 0 },
- {_T("or"), 0, PARAM_EAX, PARAM_IMM, 0 },
- {_T("push cs"), 0, 0, 0, 0 },
- {_T("two_byte"), TWO_BYTE, 0, 0, 0 },
- // 0x10
- {_T("adc"), MODRM, PARAM_RM8, PARAM_REG8, 0 },
- {_T("adc"), MODRM, PARAM_RM, PARAM_REG, 0 },
- {_T("adc"), MODRM, PARAM_REG8, PARAM_RM8, 0 },
- {_T("adc"), MODRM, PARAM_REG, PARAM_RM, 0 },
- {_T("adc"), 0, PARAM_AL, PARAM_UI8, 0 },
- {_T("adc"), 0, PARAM_EAX, PARAM_IMM, 0 },
- {_T("push ss"), 0, 0, 0, 0 },
- {_T("pop ss"), 0, 0, 0, 0 },
- {_T("sbb"), MODRM, PARAM_RM8, PARAM_REG8, 0 },
- {_T("sbb"), MODRM, PARAM_RM, PARAM_REG, 0 },
- {_T("sbb"), MODRM, PARAM_REG8, PARAM_RM8, 0 },
- {_T("sbb"), MODRM, PARAM_REG, PARAM_RM, 0 },
- {_T("sbb"), 0, PARAM_AL, PARAM_UI8, 0 },
- {_T("sbb"), 0, PARAM_EAX, PARAM_IMM, 0 },
- {_T("push ds"), 0, 0, 0, 0 },
- {_T("pop ds"), 0, 0, 0, 0 },
- // 0x20
- {_T("and"), MODRM, PARAM_RM8, PARAM_REG8, 0 },
- {_T("and"), MODRM, PARAM_RM, PARAM_REG, 0 },
- {_T("and"), MODRM, PARAM_REG8, PARAM_RM8, 0 },
- {_T("and"), MODRM, PARAM_REG, PARAM_RM, 0 },
- {_T("and"), 0, PARAM_AL, PARAM_UI8, 0 },
- {_T("and"), 0, PARAM_EAX, PARAM_IMM, 0 },
- {_T("seg_es"), SEG_ES, 0, 0, 0 },
- {_T("daa"), 0, 0, 0, 0 },
- {_T("sub"), MODRM, PARAM_RM8, PARAM_REG8, 0 },
- {_T("sub"), MODRM, PARAM_RM, PARAM_REG, 0 },
- {_T("sub"), MODRM, PARAM_REG8, PARAM_RM8, 0 },
- {_T("sub"), MODRM, PARAM_REG, PARAM_RM, 0 },
- {_T("sub"), 0, PARAM_AL, PARAM_UI8, 0 },
- {_T("sub"), 0, PARAM_EAX, PARAM_IMM, 0 },
- {_T("seg_cs"), SEG_CS, 0, 0, 0 },
- {_T("das"), 0, 0, 0, 0 },
- // 0x30
- {_T("xor"), MODRM, PARAM_RM8, PARAM_REG8, 0 },
- {_T("xor"), MODRM, PARAM_RM, PARAM_REG, 0 },
- {_T("xor"), MODRM, PARAM_REG8, PARAM_RM8, 0 },
- {_T("xor"), MODRM, PARAM_REG, PARAM_RM, 0 },
- {_T("xor"), 0, PARAM_AL, PARAM_UI8, 0 },
- {_T("xor"), 0, PARAM_EAX, PARAM_IMM, 0 },
- {_T("seg_ss"), SEG_SS, 0, 0, 0 },
- {_T("aaa"), 0, 0, 0, 0 },
- {_T("cmp"), MODRM, PARAM_RM8, PARAM_REG8, 0 },
- {_T("cmp"), MODRM, PARAM_RM, PARAM_REG, 0 },
- {_T("cmp"), MODRM, PARAM_REG8, PARAM_RM8, 0 },
- {_T("cmp"), MODRM, PARAM_REG, PARAM_RM, 0 },
- {_T("cmp"), 0, PARAM_AL, PARAM_UI8, 0 },
- {_T("cmp"), 0, PARAM_EAX, PARAM_IMM, 0 },
- {_T("seg_ds"), SEG_DS, 0, 0, 0 },
- {_T("aas"), 0, 0, 0, 0 },
- // 0x40
- {_T("inc"), ISREX, PARAM_EAX, 0, 0 },
- {_T("inc"), ISREX, PARAM_ECX, 0, 0 },
- {_T("inc"), ISREX, PARAM_EDX, 0, 0 },
- {_T("inc"), ISREX, PARAM_EBX, 0, 0 },
- {_T("inc"), ISREX, PARAM_ESP, 0, 0 },
- {_T("inc"), ISREX, PARAM_EBP, 0, 0 },
- {_T("inc"), ISREX, PARAM_ESI, 0, 0 },
- {_T("inc"), ISREX, PARAM_EDI, 0, 0 },
- {_T("dec"), ISREX, PARAM_EAX, 0, 0 },
- {_T("dec"), ISREX, PARAM_ECX, 0, 0 },
- {_T("dec"), ISREX, PARAM_EDX, 0, 0 },
- {_T("dec"), ISREX, PARAM_EBX, 0, 0 },
- {_T("dec"), ISREX, PARAM_ESP, 0, 0 },
- {_T("dec"), ISREX, PARAM_EBP, 0, 0 },
- {_T("dec"), ISREX, PARAM_ESI, 0, 0 },
- {_T("dec"), ISREX, PARAM_EDI, 0, 0 },
- // 0x50
- {_T("push"), ALWAYS64, PARAM_EAX, 0, 0 },
- {_T("push"), ALWAYS64, PARAM_ECX, 0, 0 },
- {_T("push"), ALWAYS64, PARAM_EDX, 0, 0 },
- {_T("push"), ALWAYS64, PARAM_EBX, 0, 0 },
- {_T("push"), ALWAYS64, PARAM_ESP, 0, 0 },
- {_T("push"), ALWAYS64, PARAM_EBP, 0, 0 },
- {_T("push"), ALWAYS64, PARAM_ESI, 0, 0 },
- {_T("push"), ALWAYS64, PARAM_EDI, 0, 0 },
- {_T("pop"), ALWAYS64, PARAM_EAX, 0, 0 },
- {_T("pop"), ALWAYS64, PARAM_ECX, 0, 0 },
- {_T("pop"), ALWAYS64, PARAM_EDX, 0, 0 },
- {_T("pop"), ALWAYS64, PARAM_EBX, 0, 0 },
- {_T("pop"), ALWAYS64, PARAM_ESP, 0, 0 },
- {_T("pop"), ALWAYS64, PARAM_EBP, 0, 0 },
- {_T("pop"), ALWAYS64, PARAM_ESI, 0, 0 },
- {_T("pop"), ALWAYS64, PARAM_EDI, 0, 0 },
- // 0x60
- {_T("pusha\0pushad\0<invalid>"),VAR_NAME,0, 0, 0 },
- {_T("popa\0popad\0<invalid>"), VAR_NAME,0, 0, 0 },
- {_T("bound"), MODRM, PARAM_REG, PARAM_RM, 0 },
- {_T("arpl"), MODRM | SPECIAL64_ENT(0),PARAM_RM, PARAM_REG16, 0 },
- {_T("seg_fs"), SEG_FS, 0, 0, 0 },
- {_T("seg_gs"), SEG_GS, 0, 0, 0 },
- {_T("op_size"), OP_SIZE, 0, 0, 0 },
- {_T("addr_size"), ADDR_SIZE, 0, 0, 0 },
- {_T("push"), 0, PARAM_IMM, 0, 0 },
- {_T("imul"), MODRM, PARAM_REG, PARAM_RM, PARAM_IMM },
- {_T("push"), 0, PARAM_I8, 0, 0 },
- {_T("imul"), MODRM, PARAM_REG, PARAM_RM, PARAM_I8 },
- {_T("insb"), 0, 0, 0, 0 },
- {_T("insw\0insd\0insd"),VAR_NAME, 0, 0, 0 },
- {_T("outsb"), 0, PARAM_PREIMP, 0, 0 },
- {_T("outsw\0outsd\0outsd"),VAR_NAME, PARAM_PREIMP, 0, 0 },
- // 0x70
- {_T("jo"), 0, PARAM_REL8, 0, 0 },
- {_T("jno"), 0, PARAM_REL8, 0, 0 },
- {_T("jb"), 0, PARAM_REL8, 0, 0 },
- {_T("jae"), 0, PARAM_REL8, 0, 0 },
- {_T("je"), 0, PARAM_REL8, 0, 0 },
- {_T("jne"), 0, PARAM_REL8, 0, 0 },
- {_T("jbe"), 0, PARAM_REL8, 0, 0 },
- {_T("ja"), 0, PARAM_REL8, 0, 0 },
- {_T("js"), 0, PARAM_REL8, 0, 0 },
- {_T("jns"), 0, PARAM_REL8, 0, 0 },
- {_T("jp"), 0, PARAM_REL8, 0, 0 },
- {_T("jnp"), 0, PARAM_REL8, 0, 0 },
- {_T("jl"), 0, PARAM_REL8, 0, 0 },
- {_T("jge"), 0, PARAM_REL8, 0, 0 },
- {_T("jle"), 0, PARAM_REL8, 0, 0 },
- {_T("jg"), 0, PARAM_REL8, 0, 0 },
- // 0x80
- {_T("group80"), GROUP, 0, 0, 0 },
- {_T("group81"), GROUP, 0, 0, 0 },
- {_T("group80"), GROUP, 0, 0, 0 },
- {_T("group83"), GROUP, 0, 0, 0 },
- {_T("test"), MODRM, PARAM_RM8, PARAM_REG8, 0 },
- {_T("test"), MODRM, PARAM_RM, PARAM_REG, 0 },
- {_T("xchg"), MODRM, PARAM_REG8, PARAM_RM8, 0 },
- {_T("xchg"), MODRM, PARAM_REG, PARAM_RM, 0 },
- {_T("mov"), MODRM, PARAM_RM8, PARAM_REG8, 0 },
- {_T("mov"), MODRM, PARAM_RM, PARAM_REG, 0 },
- {_T("mov"), MODRM, PARAM_REG8, PARAM_RM8, 0 },
- {_T("mov"), MODRM, PARAM_REG, PARAM_RM, 0 },
- {_T("mov"), MODRM, PARAM_RM, PARAM_SREG, 0 },
- {_T("lea"), MODRM, PARAM_REG, PARAM_RM, 0 },
- {_T("mov"), MODRM, PARAM_SREG, PARAM_RM, 0 },
- {_T("pop"), MODRM, PARAM_RM, 0, 0 },
- // 0x90
- {_T("nop\0???\0???\0pause"), VAR_NAME4, 0, 0, 0 },
- {_T("xchg"), 0, PARAM_EAX, PARAM_ECX, 0 },
- {_T("xchg"), 0, PARAM_EAX, PARAM_EDX, 0 },
- {_T("xchg"), 0, PARAM_EAX, PARAM_EBX, 0 },
- {_T("xchg"), 0, PARAM_EAX, PARAM_ESP, 0 },
- {_T("xchg"), 0, PARAM_EAX, PARAM_EBP, 0 },
- {_T("xchg"), 0, PARAM_EAX, PARAM_ESI, 0 },
- {_T("xchg"), 0, PARAM_EAX, PARAM_EDI, 0 },
- {_T("cbw\0cwde\0cdqe"), VAR_NAME, 0, 0, 0 },
- {_T("cwd\0cdq\0cqo"), VAR_NAME, 0, 0, 0 },
- {_T("call"), ALWAYS64, PARAM_ADDR, 0, 0, DASMFLAG_STEP_OVER},
- {_T("wait"), 0, 0, 0, 0 },
- {_T("pushf\0pushfd\0pushfq"),VAR_NAME, 0, 0, 0 },
- {_T("popf\0popfd\0popfq"),VAR_NAME, 0, 0, 0 },
- {_T("sahf"), 0, 0, 0, 0 },
- {_T("lahf"), 0, 0, 0, 0 },
- // 0xa0
- {_T("mov"), 0, PARAM_AL, PARAM_MEM_OFFS, 0 },
- {_T("mov"), 0, PARAM_EAX, PARAM_MEM_OFFS, 0 },
- {_T("mov"), 0, PARAM_MEM_OFFS, PARAM_AL, 0 },
- {_T("mov"), 0, PARAM_MEM_OFFS, PARAM_EAX, 0 },
- {_T("movsb"), 0, PARAM_PREIMP, 0, 0 },
- {_T("movsw\0movsd\0movsq"),VAR_NAME, PARAM_PREIMP, 0, 0 },
- {_T("cmpsb"), 0, PARAM_PREIMP, 0, 0 },
- {_T("cmpsw\0cmpsd\0cmpsq"),VAR_NAME, PARAM_PREIMP, 0, 0 },
- {_T("test"), 0, PARAM_AL, PARAM_UI8, 0 },
- {_T("test"), 0, PARAM_EAX, PARAM_IMM, 0 },
- {_T("stosb"), 0, 0, 0, 0 },
- {_T("stosw\0stosd\0stosq"),VAR_NAME, 0, 0, 0 },
- {_T("lodsb"), 0, PARAM_PREIMP, 0, 0 },
- {_T("lodsw\0lodsd\0lodsq"),VAR_NAME, PARAM_PREIMP, 0, 0 },
- {_T("scasb"), 0, 0, 0, 0 },
- {_T("scasw\0scasd\0scasq"),VAR_NAME, 0, 0, 0 },
- // 0xb0
- {_T("mov"), 0, PARAM_AL, PARAM_UI8, 0 },
- {_T("mov"), 0, PARAM_CL, PARAM_UI8, 0 },
- {_T("mov"), 0, PARAM_DL, PARAM_UI8, 0 },
- {_T("mov"), 0, PARAM_BL, PARAM_UI8, 0 },
- {_T("mov"), 0, PARAM_AH, PARAM_UI8, 0 },
- {_T("mov"), 0, PARAM_CH, PARAM_UI8, 0 },
- {_T("mov"), 0, PARAM_DH, PARAM_UI8, 0 },
- {_T("mov"), 0, PARAM_BH, PARAM_UI8, 0 },
- {_T("mov"), 0, PARAM_EAX, PARAM_IMM64, 0 },
- {_T("mov"), 0, PARAM_ECX, PARAM_IMM64, 0 },
- {_T("mov"), 0, PARAM_EDX, PARAM_IMM64, 0 },
- {_T("mov"), 0, PARAM_EBX, PARAM_IMM64, 0 },
- {_T("mov"), 0, PARAM_ESP, PARAM_IMM64, 0 },
- {_T("mov"), 0, PARAM_EBP, PARAM_IMM64, 0 },
- {_T("mov"), 0, PARAM_ESI, PARAM_IMM64, 0 },
- {_T("mov"), 0, PARAM_EDI, PARAM_IMM64, 0 },
- // 0xc0
- {_T("groupC0"), GROUP, 0, 0, 0 },
- {_T("groupC1"), GROUP, 0, 0, 0 },
- {_T("ret"), 0, PARAM_UI16, 0, 0, DASMFLAG_STEP_OUT},
- {_T("ret"), 0, 0, 0, 0, DASMFLAG_STEP_OUT},
- {_T("les"), MODRM, PARAM_REG, PARAM_RM, 0 },
- {_T("lds"), MODRM, PARAM_REG, PARAM_RM, 0 },
- {_T("mov"), MODRM, PARAM_RMPTR8, PARAM_UI8, 0 },
- {_T("mov"), MODRM, PARAM_RMPTR, PARAM_IMM, 0 },
- {_T("enter"), 0, PARAM_UI16, PARAM_UI8, 0 },
- {_T("leave"), 0, 0, 0, 0 },
- {_T("retf"), 0, PARAM_UI16, 0, 0, DASMFLAG_STEP_OUT},
- {_T("retf"), 0, 0, 0, 0, DASMFLAG_STEP_OUT},
- {_T("int 3"), 0, 0, 0, 0, DASMFLAG_STEP_OVER},
- {_T("int"), 0, PARAM_UI8, 0, 0, DASMFLAG_STEP_OVER},
- {_T("into"), 0, 0, 0, 0 },
- {_T("iret"), 0, 0, 0, 0, DASMFLAG_STEP_OUT},
- // 0xd0
- {_T("groupD0"), GROUP, 0, 0, 0 },
- {_T("groupD1"), GROUP, 0, 0, 0 },
- {_T("groupD2"), GROUP, 0, 0, 0 },
- {_T("groupD3"), GROUP, 0, 0, 0 },
- {_T("aam"), 0, PARAM_UI8, 0, 0 },
- {_T("aad"), 0, PARAM_UI8, 0, 0 },
- {_T("salc"), 0, 0, 0, 0 }, //AMD docs name it
- {_T("xlat"), 0, 0, 0, 0 },
- {_T("escape"), FPU, 0, 0, 0 },
- {_T("escape"), FPU, 0, 0, 0 },
- {_T("escape"), FPU, 0, 0, 0 },
- {_T("escape"), FPU, 0, 0, 0 },
- {_T("escape"), FPU, 0, 0, 0 },
- {_T("escape"), FPU, 0, 0, 0 },
- {_T("escape"), FPU, 0, 0, 0 },
- {_T("escape"), FPU, 0, 0, 0 },
- // 0xe0
- {_T("loopne"), 0, PARAM_REL8, 0, 0, DASMFLAG_STEP_OVER},
- {_T("loopz"), 0, PARAM_REL8, 0, 0, DASMFLAG_STEP_OVER},
- {_T("loop"), 0, PARAM_REL8, 0, 0, DASMFLAG_STEP_OVER},
- {_T("jcxz\0jecxz\0jrcxz"),VAR_NAME, PARAM_REL8, 0, 0 },
- {_T("in"), 0, PARAM_AL, PARAM_UI8, 0 },
- {_T("in"), 0, PARAM_EAX, PARAM_UI8, 0 },
- {_T("out"), 0, PARAM_UI8, PARAM_AL, 0 },
- {_T("out"), 0, PARAM_UI8, PARAM_EAX, 0 },
- {_T("call"), 0, PARAM_REL, 0, 0, DASMFLAG_STEP_OVER},
- {_T("jmp"), 0, PARAM_REL, 0, 0 },
- {_T("jmp"), 0, PARAM_ADDR, 0, 0 },
- {_T("jmp"), 0, PARAM_REL8, 0, 0 },
- {_T("in"), 0, PARAM_AL, PARAM_DX, 0 },
- {_T("in"), 0, PARAM_EAX, PARAM_DX, 0 },
- {_T("out"), 0, PARAM_DX, PARAM_AL, 0 },
- {_T("out"), 0, PARAM_DX, PARAM_EAX, 0 },
- // 0xf0
- {_T("lock"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("repne"), PREFIX, 0, 0, 0 },
- {_T("rep"), PREFIX, 0, 0, 0 },
- {_T("hlt"), 0, 0, 0, 0 },
- {_T("cmc"), 0, 0, 0, 0 },
- {_T("groupF6"), GROUP, 0, 0, 0 },
- {_T("groupF7"), GROUP, 0, 0, 0 },
- {_T("clc"), 0, 0, 0, 0 },
- {_T("stc"), 0, 0, 0, 0 },
- {_T("cli"), 0, 0, 0, 0 },
- {_T("sti"), 0, 0, 0, 0 },
- {_T("cld"), 0, 0, 0, 0 },
- {_T("std"), 0, 0, 0, 0 },
- {_T("groupFE"), GROUP, 0, 0, 0 },
- {_T("groupFF"), GROUP, 0, 0, 0 }
-};
-
-static const I386_OPCODE x64_opcode_alt[] =
-{
- {_T("movsxd"), MODRM | ALWAYS64,PARAM_REG, PARAM_RMPTR32, 0 },
-};
-
-static const I386_OPCODE i386_opcode_table2[256] =
-{
- // 0x00
- {_T("group0F00"), GROUP, 0, 0, 0 },
- {_T("group0F01"), GROUP, 0, 0, 0 },
- {_T("lar"), MODRM, PARAM_REG, PARAM_RM, 0 },
- {_T("lsl"), MODRM, PARAM_REG, PARAM_RM, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("syscall"), 0, 0, 0, 0 },
- {_T("clts"), 0, 0, 0, 0 },
- {_T("sysret"), 0, 0, 0, 0 },
- {_T("invd"), 0, 0, 0, 0 },
- {_T("wbinvd"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("ud2"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("group0F0D"), GROUP, 0, 0, 0 }, //AMD only
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- // 0x10
- {_T("movups\0")
- _T("movupd\0")
- _T("movsd\0")
- _T("movss"), MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 },
- {_T("movups\0")
- _T("movupd\0")
- _T("movsd\0")
- _T("movss"), MODRM|VAR_NAME4,PARAM_XMMM, PARAM_XMM, 0 },
- {_T("movlps\0")
- _T("movlpd\0")
- _T("movddup\0")
- _T("movsldup"), MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 },
- {_T("movlps\0")
- _T("movlpd\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4,PARAM_XMMM, PARAM_XMM, 0 },
- {_T("unpcklps\0")
- _T("unpcklpd\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 },
- {_T("unpckhps\0")
- _T("unpckhpd\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 },
- {_T("group0F16"), GROUP|GROUP_MOD, 0, 0, 0 },
- {_T("movhps\0")
- _T("movhpd\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4,PARAM_XMMM, PARAM_XMM, 0 },
- {_T("group0F18"), GROUP, 0, 0, 0 },
- {_T("nop_hint"), 0, PARAM_RMPTR8, 0, 0 },
- {_T("nop_hint"), 0, PARAM_RMPTR8, 0, 0 },
- {_T("nop_hint"), 0, PARAM_RMPTR8, 0, 0 },
- {_T("nop_hint"), 0, PARAM_RMPTR8, 0, 0 },
- {_T("nop_hint"), 0, PARAM_RMPTR8, 0, 0 },
- {_T("nop_hint"), 0, PARAM_RMPTR8, 0, 0 },
- {_T("nop_hint"), 0, PARAM_RMPTR8, 0, 0 },
- // 0x20
- {_T("mov"), MODRM, PARAM_REG2_32, PARAM_CREG, 0 },
- {_T("mov"), MODRM, PARAM_REG2_32, PARAM_DREG, 0 },
- {_T("mov"), MODRM, PARAM_CREG, PARAM_REG2_32, 0 },
- {_T("mov"), MODRM, PARAM_DREG, PARAM_REG2_32, 0 },
- {_T("mov"), MODRM, PARAM_REG2_32, PARAM_TREG, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("mov"), MODRM, PARAM_TREG, PARAM_REG2_32, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("movaps\0")
- _T("movapd\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 },
- {_T("movaps\0")
- _T("movapd\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4,PARAM_XMMM, PARAM_XMM, 0 },
- {_T("cvtpi2ps\0")
- _T("cvtpi2pd\0")
- _T("cvtsi2sd\0")
- _T("cvtsi2ss"), MODRM|VAR_NAME4,PARAM_XMM, PARAM_RMXMM, 0 },
- {_T("movntps\0")
- _T("movntpd\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4,PARAM_XMMM, PARAM_XMM, 0 },
- {_T("cvttps2pi\0")
- _T("cvttpd2pi\0")
- _T("cvttsd2si\0")
- _T("cvttss2si"), MODRM|VAR_NAME4,PARAM_REGORXMM, PARAM_XMMM, 0 },
- {_T("cvtps2pi\0")
- _T("cvtpd2pi\0")
- _T("cvtsd2si\0")
- _T("cvtss2si"), MODRM|VAR_NAME4,PARAM_REGORXMM, PARAM_XMMM, 0 },
- {_T("ucomiss\0")
- _T("ucomisd\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 },
- {_T("comiss\0")
- _T("comisd\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 },
- // 0x30
- {_T("wrmsr"), 0, 0, 0, 0 },
- {_T("rdtsc"), 0, 0, 0, 0 },
- {_T("rdmsr"), 0, 0, 0, 0 },
- {_T("rdpmc"), 0, 0, 0, 0 },
- {_T("sysenter"), 0, 0, 0, 0 },
- {_T("sysexit"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("three_byte"), THREE_BYTE, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("three_byte"), THREE_BYTE, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- // 0x40
- {_T("cmovo"), MODRM, PARAM_REG, PARAM_RM, 0 },
- {_T("cmovno"), MODRM, PARAM_REG, PARAM_RM, 0 },
- {_T("cmovb"), MODRM, PARAM_REG, PARAM_RM, 0 },
- {_T("cmovae"), MODRM, PARAM_REG, PARAM_RM, 0 },
- {_T("cmove"), MODRM, PARAM_REG, PARAM_RM, 0 },
- {_T("cmovne"), MODRM, PARAM_REG, PARAM_RM, 0 },
- {_T("cmovbe"), MODRM, PARAM_REG, PARAM_RM, 0 },
- {_T("cmova"), MODRM, PARAM_REG, PARAM_RM, 0 },
- {_T("cmovs"), MODRM, PARAM_REG, PARAM_RM, 0 },
- {_T("cmovns"), MODRM, PARAM_REG, PARAM_RM, 0 },
- {_T("cmovpe"), MODRM, PARAM_REG, PARAM_RM, 0 },
- {_T("cmovpo"), MODRM, PARAM_REG, PARAM_RM, 0 },
- {_T("cmovl"), MODRM, PARAM_REG, PARAM_RM, 0 },
- {_T("cmovge"), MODRM, PARAM_REG, PARAM_RM, 0 },
- {_T("cmovle"), MODRM, PARAM_REG, PARAM_RM, 0 },
- {_T("cmovg"), MODRM, PARAM_REG, PARAM_RM, 0 },
- // 0x50
- {_T("movmskps\0")
- _T("movmskpd\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4,PARAM_REG3264, PARAM_XMMM, 0 },
- {_T("sqrtps\0")
- _T("sqrtpd\0")
- _T("sqrtsd\0")
- _T("sqrtss"), MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 },
- {_T("rsqrtps\0")
- _T("???\0")
- _T("???\0")
- _T("rsqrtss"), MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 },
- {_T("rcpps\0")
- _T("???\0")
- _T("???\0")
- _T("rcpss"), MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 },
- {_T("andps\0")
- _T("andpd\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 },
- {_T("andnps\0")
- _T("andnpd\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 },
- {_T("orps\0")
- _T("orpd\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 },
- {_T("xorps\0")
- _T("xorpd\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 },
- {_T("addps\0")
- _T("addpd\0")
- _T("addsd\0")
- _T("addss"), MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 },
- {_T("mulps\0")
- _T("mulpd\0")
- _T("mulsd\0")
- _T("mulss"), MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 },
- {_T("cvtps2pd\0")
- _T("cvtpd2ps\0")
- _T("cvtsd2ss\0")
- _T("cvtss2sd"), MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 },
- {_T("cvtdq2ps\0")
- _T("cvtps2dq\0")
- _T("???\0")
- _T("cvttps2dq"), MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 },
- {_T("subps\0")
- _T("subpd\0")
- _T("subsd\0")
- _T("subss"), MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 },
- {_T("minps\0")
- _T("minpd\0")
- _T("minsd\0")
- _T("minss"), MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 },
- {_T("divps\0")
- _T("divpd\0")
- _T("divsd\0")
- _T("divss"), MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 },
- {_T("maxps\0")
- _T("maxpd\0")
- _T("maxsd\0")
- _T("maxss"), MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 },
- // 0x60
- {_T("punpcklbw"), MODRM, PARAM_MMX, PARAM_MMXM, 0 },
- {_T("punpcklwd"), MODRM, PARAM_MMX, PARAM_MMXM, 0 },
- {_T("punpckldq"), MODRM, PARAM_MMX, PARAM_MMXM, 0 },
- {_T("packsswb"), MODRM, PARAM_MMX, PARAM_MMXM, 0 },
- {_T("pcmpgtb"), MODRM, PARAM_MMX, PARAM_MMXM, 0 },
- {_T("pcmpgtw"), MODRM, PARAM_MMX, PARAM_MMXM, 0 },
- {_T("pcmpgtd"), MODRM, PARAM_MMX, PARAM_MMXM, 0 },
- {_T("packuswb"), MODRM, PARAM_MMX, PARAM_MMXM, 0 },
- {_T("punpckhbw"), MODRM, PARAM_MMX, PARAM_MMXM, 0 },
- {_T("punpckhwd"), MODRM, PARAM_MMX, PARAM_MMXM, 0 },
- {_T("punpckhdq"), MODRM, PARAM_MMX, PARAM_MMXM, 0 },
- {_T("packssdw"), MODRM, PARAM_MMX, PARAM_MMXM, 0 },
- {_T("???\0")
- _T("punpcklqdq\0")
- _T("???\0")
- _T("???\0"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
- {_T("???\0")
- _T("punpckhqdq\0")
- _T("???\0")
- _T("???\0"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
- {_T("movd"), MODRM, PARAM_MMX, PARAM_RM, 0 },
- {_T("movq\0")
- _T("movdqa\0")
- _T("???\0")
- _T("movdqu"), MODRM|VAR_NAME4,PARAM_MMX, PARAM_MMXM, 0 },
- // 0x70
- {_T("pshufw\0")
- _T("pshufd\0")
- _T("pshuflw\0")
- _T("pshufhw"), MODRM|VAR_NAME4,PARAM_MMX, PARAM_MMXM, PARAM_UI8 },
- {_T("group0F71"), GROUP, 0, 0, 0 },
- {_T("group0F72"), GROUP, 0, 0, 0 },
- {_T("group0F73"), GROUP, 0, 0, 0 },
- {_T("pcmpeqb"), MODRM, PARAM_MMX, PARAM_MMXM, 0 },
- {_T("pcmpeqw"), MODRM, PARAM_MMX, PARAM_MMXM, 0 },
- {_T("pcmpeqd"), MODRM, PARAM_MMX, PARAM_MMXM, 0 },
- {_T("emms"), 0, 0, 0, 0 },
- {_T("vmread"), MODRM, PARAM_RM, PARAM_REG, 0 },
- {_T("vmwrite"), MODRM, PARAM_RM, PARAM_REG, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???\0")
- _T("haddpd\0")
- _T("haddps\0")
- _T("???"), MODRM|VAR_NAME4,PARAM_MMX, PARAM_MMXM, 0 },
- {_T("???\0")
- _T("hsubpd\0")
- _T("hsubps\0")
- _T("???"), MODRM|VAR_NAME4,PARAM_MMX, PARAM_MMXM, 0 },
- {_T("movd\0")
- _T("movd\0")
- _T("???\0")
- _T("movq"), MODRM|VAR_NAME4,PARAM_RM, PARAM_MMX, 0 },
- {_T("movq\0")
- _T("movdqa\0")
- _T("???\0")
- _T("movdqu"), MODRM|VAR_NAME4,PARAM_MMXM, PARAM_MMX, 0 },
- // 0x80
- {_T("jo"), 0, PARAM_REL, 0, 0 },
- {_T("jno"), 0, PARAM_REL, 0, 0 },
- {_T("jb"), 0, PARAM_REL, 0, 0 },
- {_T("jae"), 0, PARAM_REL, 0, 0 },
- {_T("je"), 0, PARAM_REL, 0, 0 },
- {_T("jne"), 0, PARAM_REL, 0, 0 },
- {_T("jbe"), 0, PARAM_REL, 0, 0 },
- {_T("ja"), 0, PARAM_REL, 0, 0 },
- {_T("js"), 0, PARAM_REL, 0, 0 },
- {_T("jns"), 0, PARAM_REL, 0, 0 },
- {_T("jp"), 0, PARAM_REL, 0, 0 },
- {_T("jnp"), 0, PARAM_REL, 0, 0 },
- {_T("jl"), 0, PARAM_REL, 0, 0 },
- {_T("jge"), 0, PARAM_REL, 0, 0 },
- {_T("jle"), 0, PARAM_REL, 0, 0 },
- {_T("jg"), 0, PARAM_REL, 0, 0 },
- // 0x90
- {_T("seto"), MODRM, PARAM_RMPTR8, 0, 0 },
- {_T("setno"), MODRM, PARAM_RMPTR8, 0, 0 },
- {_T("setb"), MODRM, PARAM_RMPTR8, 0, 0 },
- {_T("setae"), MODRM, PARAM_RMPTR8, 0, 0 },
- {_T("sete"), MODRM, PARAM_RMPTR8, 0, 0 },
- {_T("setne"), MODRM, PARAM_RMPTR8, 0, 0 },
- {_T("setbe"), MODRM, PARAM_RMPTR8, 0, 0 },
- {_T("seta"), MODRM, PARAM_RMPTR8, 0, 0 },
- {_T("sets"), MODRM, PARAM_RMPTR8, 0, 0 },
- {_T("setns"), MODRM, PARAM_RMPTR8, 0, 0 },
- {_T("setp"), MODRM, PARAM_RMPTR8, 0, 0 },
- {_T("setnp"), MODRM, PARAM_RMPTR8, 0, 0 },
- {_T("setl"), MODRM, PARAM_RMPTR8, 0, 0 },
- {_T("setge"), MODRM, PARAM_RMPTR8, 0, 0 },
- {_T("setle"), MODRM, PARAM_RMPTR8, 0, 0 },
- {_T("setg"), MODRM, PARAM_RMPTR8, 0, 0 },
- // 0xa0
- {_T("push fs"), 0, 0, 0, 0 },
- {_T("pop fs"), 0, 0, 0, 0 },
- {_T("cpuid"), 0, 0, 0, 0 },
- {_T("bt"), MODRM, PARAM_RM, PARAM_REG, 0 },
- {_T("shld"), MODRM, PARAM_RM, PARAM_REG, PARAM_UI8 },
- {_T("shld"), MODRM, PARAM_RM, PARAM_REG, PARAM_CL },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("push gs"), 0, 0, 0, 0 },
- {_T("pop gs"), 0, 0, 0, 0 },
- {_T("rsm"), 0, 0, 0, 0 },
- {_T("bts"), MODRM, PARAM_RM, PARAM_REG, 0 },
- {_T("shrd"), MODRM, PARAM_RM, PARAM_REG, PARAM_UI8 },
- {_T("shrd"), MODRM, PARAM_RM, PARAM_REG, PARAM_CL },
- {_T("group0FAE"), GROUP, 0, 0, 0 },
- {_T("imul"), MODRM, PARAM_REG, PARAM_RM, 0 },
- // 0xb0
- {_T("cmpxchg"), MODRM, PARAM_RM8, PARAM_REG, 0 },
- {_T("cmpxchg"), MODRM, PARAM_RM, PARAM_REG, 0 },
- {_T("lss"), MODRM, PARAM_REG, PARAM_RM, 0 },
- {_T("btr"), MODRM, PARAM_RM, PARAM_REG, 0 },
- {_T("lfs"), MODRM, PARAM_REG, PARAM_RM, 0 },
- {_T("lgs"), MODRM, PARAM_REG, PARAM_RM, 0 },
- {_T("movzx"), MODRM, PARAM_REG, PARAM_RMPTR8, 0 },
- {_T("movzx"), MODRM, PARAM_REG, PARAM_RMPTR16, 0 },
- {_T("???\0")
- _T("???\0")
- _T("???\0")
- _T("popcnt"), MODRM|VAR_NAME4, PARAM_REG, PARAM_RM16, 0 },
- {_T("ud2"), 0, 0, 0, 0 },
- {_T("group0FBA"), GROUP, 0, 0, 0 },
- {_T("btc"), MODRM, PARAM_RM, PARAM_REG, 0 },
- {_T("bsf\0")
- _T("???\0")
- _T("???\0")
- _T("tzcnt"), MODRM|VAR_NAME4, PARAM_REG, PARAM_RM, 0 },
- {_T("bsr\0")
- _T("???\0")
- _T("???\0")
- _T("lzcnt"), MODRM|VAR_NAME4, PARAM_REG, PARAM_RM, 0, DASMFLAG_STEP_OVER},
- {_T("movsx"), MODRM, PARAM_REG, PARAM_RMPTR8, 0 },
- {_T("movsx"), MODRM, PARAM_REG, PARAM_RMPTR16, 0 },
- // 0xc0
- {_T("xadd"), MODRM, PARAM_RM8, PARAM_REG, 0 },
- {_T("xadd"), MODRM, PARAM_RM, PARAM_REG, 0 },
- {_T("cmpps\0")
- _T("cmppd\0")
- _T("cmpsd\0")
- _T("cmpss"), MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 },
- {_T("movnti"), MODRM, PARAM_RM, PARAM_REG, 0 },
- {_T("pinsrw"), MODRM, PARAM_MMX, PARAM_RM, PARAM_UI8 },
- {_T("pextrw"), MODRM, PARAM_MMX, PARAM_RM, PARAM_UI8 },
- {_T("shufps\0")
- _T("shufpd\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, PARAM_UI8 },
- {_T("group0FC7"), GROUP, 0, 0, 0 },
- {_T("bswap"), 0, PARAM_EAX, 0, 0 },
- {_T("bswap"), 0, PARAM_ECX, 0, 0 },
- {_T("bswap"), 0, PARAM_EDX, 0, 0 },
- {_T("bswap"), 0, PARAM_EBX, 0, 0 },
- {_T("bswap"), 0, PARAM_ESP, 0, 0 },
- {_T("bswap"), 0, PARAM_EBP, 0, 0 },
- {_T("bswap"), 0, PARAM_ESI, 0, 0 },
- {_T("bswap"), 0, PARAM_EDI, 0, 0 },
- // 0xd0
- {_T("???\0")
- _T("addsubpd\0")
- _T("addsubps\0")
- _T("???\0"), MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 },
- {_T("psrlw"), MODRM, PARAM_MMX, PARAM_MMXM, 0 },
- {_T("psrld"), MODRM, PARAM_MMX, PARAM_MMXM, 0 },
- {_T("psrlq"), MODRM, PARAM_MMX, PARAM_MMXM, 0 },
- {_T("paddq"), MODRM, PARAM_MMX, PARAM_MMXM, 0 },
- {_T("pmullw"), MODRM, PARAM_MMX, PARAM_MMXM, 0 },
- {_T("???\0")
- _T("movq\0")
- _T("movdq2q\0")
- _T("movq2dq"), MODRM|VAR_NAME4,PARAM_MMX, PARAM_MMXM, 0 },
- {_T("pmovmskb"), MODRM, PARAM_REG3264, PARAM_MMXM, 0 },
- {_T("psubusb"), MODRM, PARAM_MMX, PARAM_MMXM, 0 },
- {_T("psubusw"), MODRM, PARAM_MMX, PARAM_MMXM, 0 },
- {_T("pminub"), MODRM, PARAM_MMX, PARAM_MMXM, 0 },
- {_T("pand"), MODRM, PARAM_MMX, PARAM_MMXM, 0 },
- {_T("paddusb"), MODRM, PARAM_MMX, PARAM_MMXM, 0 },
- {_T("paddusw"), MODRM, PARAM_MMX, PARAM_MMXM, 0 },
- {_T("pmaxub"), MODRM, PARAM_MMX, PARAM_MMXM, 0 },
- {_T("pandn"), MODRM, PARAM_MMX, PARAM_MMXM, 0 },
- // 0xe0
- {_T("pavgb"), MODRM, PARAM_MMX, PARAM_MMXM, 0 },
- {_T("psraw"), MODRM, PARAM_MMX, PARAM_MMXM, 0 },
- {_T("psrad"), MODRM, PARAM_MMX, PARAM_MMXM, 0 },
- {_T("pavgw"), MODRM, PARAM_MMX, PARAM_MMXM, 0 },
- {_T("pmulhuw"), MODRM, PARAM_MMX, PARAM_MMXM, 0 },
- {_T("pmulhw"), MODRM, PARAM_MMX, PARAM_MMXM, 0 },
- {_T("???\0")
- _T("cvttpd2dq\0")
- _T("cvtpd2dq\0")
- _T("cvtdq2pd"), MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 },
- {_T("movntq\0")
- _T("movntdq\0")
- _T("???\0")
- _T("???\0"), MODRM|VAR_NAME4, PARAM_M64, PARAM_MMX, 0 },
- {_T("psubsb"), MODRM, PARAM_MMX, PARAM_MMXM, 0 },
- {_T("psubsw"), MODRM, PARAM_MMX, PARAM_MMXM, 0 },
- {_T("pminsw"), MODRM, PARAM_MMX, PARAM_MMXM, 0 },
- {_T("por"), MODRM, PARAM_MMX, PARAM_MMXM, 0 },
- {_T("paddsb"), MODRM, PARAM_MMX, PARAM_MMXM, 0 },
- {_T("paddsw"), MODRM, PARAM_MMX, PARAM_MMXM, 0 },
- {_T("pmaxsw"), MODRM, PARAM_MMX, PARAM_MMXM, 0 },
- {_T("pxor"), MODRM, PARAM_MMX, PARAM_MMXM, 0 },
- // 0xf0
- {_T("???\0")
- _T("???\0")
- _T("lddqu\0")
- _T("???"), MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 },
- {_T("psllw"), MODRM, PARAM_MMX, PARAM_MMXM, 0 },
- {_T("pslld"), MODRM, PARAM_MMX, PARAM_MMXM, 0 },
- {_T("psllq"), MODRM, PARAM_MMX, PARAM_MMXM, 0 },
- {_T("pmuludq"), MODRM, PARAM_MMX, PARAM_MMXM, 0 },
- {_T("pmaddwd"), MODRM, PARAM_MMX, PARAM_MMXM, 0 },
- {_T("psadbw"), MODRM, PARAM_MMX, PARAM_MMXM, 0 },
- {_T("maskmovq\0")
- _T("maskmovdqu\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4,PARAM_MMX, PARAM_MMXM, 0 },
- {_T("psubb"), MODRM, PARAM_MMX, PARAM_MMXM, 0 },
- {_T("psubw"), MODRM, PARAM_MMX, PARAM_MMXM, 0 },
- {_T("psubd"), MODRM, PARAM_MMX, PARAM_MMXM, 0 },
- {_T("psubq"), MODRM, PARAM_MMX, PARAM_MMXM, 0 },
- {_T("paddb"), MODRM, PARAM_MMX, PARAM_MMXM, 0 },
- {_T("paddw"), MODRM, PARAM_MMX, PARAM_MMXM, 0 },
- {_T("paddd"), MODRM, PARAM_MMX, PARAM_MMXM, 0 },
- {_T("???"), 0, 0, 0, 0 }
-};
-
-static const I386_OPCODE i386_opcode_table0F38[256] =
-{
- // 0x00
- {_T("pshufb\0")
- _T("pshufb\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
- {_T("phaddw\0")
- _T("phaddw\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
- {_T("phaddd\0")
- _T("phadd\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
- {_T("phaddsw\0")
- _T("phaddsw\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
- {_T("pmaddubsw\0")
- _T("pmaddubsw\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
- {_T("phsubw\0")
- _T("phsubw\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
- {_T("phsubd\0")
- _T("phsubd\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
- {_T("phsubsw\0")
- _T("phsubsw\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
- {_T("psignb\0")
- _T("psignb\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
- {_T("psignw\0")
- _T("psignw\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
- {_T("psignd\0")
- _T("psignd\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
- {_T("pmulhrsw\0")
- _T("pmulhrsw\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- // 0x10
- {_T("???\0")
- _T("pblendvb\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, PARAM_XMM0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???\0")
- _T("blendvps\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, PARAM_XMM0 },
- {_T("???\0")
- _T("blendvpd\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, PARAM_XMM0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???\0")
- _T("ptest\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("pabsb\0")
- _T("pabsb\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
- {_T("pabsw\0")
- _T("pabsw\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
- {_T("pabsd\0")
- _T("pabsd\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
- {_T("???"), 0, 0, 0, 0 },
- // 0x20
- {_T("???\0")
- _T("pmovsxbw\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMM64, 0 },
- {_T("???\0")
- _T("pmovsxbd\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMM32, 0 },
- {_T("???\0")
- _T("pmovsxbq\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMM16, 0 },
- {_T("???\0")
- _T("pmovsxwd\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMM64, 0 },
- {_T("???\0")
- _T("pmovsxwq\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMM32, 0 },
- {_T("???\0")
- _T("pmovsxdq\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMM64, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???\0")
- _T("pmuldq\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
- {_T("???\0")
- _T("pcmpeqq\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
- {_T("???\0")
- _T("movntdqa\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
- {_T("???\0")
- _T("packusdw\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- // 0x30
- {_T("???\0")
- _T("pmovzxbw\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMM64, 0 },
- {_T("???\0")
- _T("pmovzxbd\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMM32, 0 },
- {_T("???\0")
- _T("pmovzxbq\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMM16, 0 },
- {_T("???\0")
- _T("pmovzxwd\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMM64, 0 },
- {_T("???\0")
- _T("pmovzxwq\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMM32, 0 },
- {_T("???\0")
- _T("pmovzxdq\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMM64, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???\0")
- _T("pcmpgtq\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
- {_T("???\0")
- _T("pminsb\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
- {_T("???\0")
- _T("pminsd\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
- {_T("???\0")
- _T("pminuw\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
- {_T("???\0")
- _T("pminud\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
- {_T("???\0")
- _T("pmaxsb\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
- {_T("???\0")
- _T("pmaxsd\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
- {_T("???\0")
- _T("pmaxuw\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
- {_T("???\0")
- _T("pmaxud\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
- // 0x40
- {_T("???\0")
- _T("pmulld\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
- {_T("???\0")
- _T("phminposuw\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- // 0x50
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- // 0x60
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- // 0x70
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- // 0x80
- {_T("???\0")
- _T("invept\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_REG32, PARAM_XMMM, 0 },
- {_T("???\0")
- _T("invvpid\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_REG32, PARAM_XMMM, 0 },
- {_T("???\0")
- _T("invpcid\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_REG32, PARAM_XMMM, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- // 0x90
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- // 0xa0
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- // 0xb0
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- // 0xc0
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- // 0xd0
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???\0")
- _T("aesimc\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
- {_T("???\0")
- _T("aesenc\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
- {_T("???\0")
- _T("aesenclast\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
- {_T("???\0")
- _T("aesdec\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
- {_T("???\0")
- _T("aesdeclast\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 },
- // 0xe0
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- // 0xf0
- {_T("movbe\0")
- _T("???\0")
- _T("crc32\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_REG32, PARAM_RMPTR, 0 }, // not quite correct
- {_T("movbe\0")
- _T("???\0")
- _T("crc32\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_RMPTR, PARAM_REG32, 0 }, // not quite correct
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
-};
-
-static const I386_OPCODE i386_opcode_table0F3A[256] =
-{
- // 0x00
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???\0")
- _T("roundps\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, PARAM_UI8 },
- {_T("???\0")
- _T("roundpd\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, PARAM_UI8 },
- {_T("???\0")
- _T("roundss\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, PARAM_UI8 },
- {_T("???\0")
- _T("roundsd\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, PARAM_UI8 },
- {_T("???\0")
- _T("blendps\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, PARAM_UI8 },
- {_T("???\0")
- _T("blendpd\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, PARAM_UI8 },
- {_T("???\0")
- _T("pblendw\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, PARAM_UI8 },
- {_T("palignr\0")
- _T("palignr\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, PARAM_UI8 },
- // 0x10
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???\0")
- _T("pextrb\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_RM8, PARAM_XMM, PARAM_UI8 },
- {_T("???\0")
- _T("pextrw\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_RM16, PARAM_XMM, PARAM_UI8 },
- {_T("???\0")
- _T("pextrd\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_RM8, PARAM_XMM, PARAM_UI8 },
- {_T("???\0")
- _T("extractps\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_RM32, PARAM_XMM, PARAM_UI8 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- // 0x20
- {_T("???\0")
- _T("pinsrb\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_RM8, PARAM_UI8 },
- {_T("???\0")
- _T("insertps\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_RM8, PARAM_UI8 },
- {_T("???\0")
- _T("pinsrd\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_RM32, PARAM_UI8 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- // 0x30
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- // 0x40
- {_T("???\0")
- _T("dpps\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, PARAM_UI8 },
- {_T("???\0")
- _T("dppd\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, PARAM_UI8 },
- {_T("???\0")
- _T("mpsadbw\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, PARAM_UI8 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???\0")
- _T("pclmulqdq\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, PARAM_UI8 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- // 0x50
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- // 0x60
- {_T("???\0")
- _T("pcmestrm\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, PARAM_UI8 },
- {_T("???\0")
- _T("pcmestri\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, PARAM_UI8 },
- {_T("???\0")
- _T("pcmistrm\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, PARAM_UI8 },
- {_T("???\0")
- _T("pcmistri\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, PARAM_UI8 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- // 0x70
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- // 0x80
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- // 0x90
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- // 0xa0
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- // 0xb0
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- // 0xc0
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- // 0xd0
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???\0")
- _T("aeskeygenassist\0")
- _T("???\0")
- _T("???"), MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, PARAM_UI8 },
- // 0xe0
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- // 0xf0
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
-};
-
-static const I386_OPCODE group80_table[8] =
-{
- {_T("add"), 0, PARAM_RMPTR8, PARAM_UI8, 0 },
- {_T("or"), 0, PARAM_RMPTR8, PARAM_UI8, 0 },
- {_T("adc"), 0, PARAM_RMPTR8, PARAM_UI8, 0 },
- {_T("sbb"), 0, PARAM_RMPTR8, PARAM_UI8, 0 },
- {_T("and"), 0, PARAM_RMPTR8, PARAM_UI8, 0 },
- {_T("sub"), 0, PARAM_RMPTR8, PARAM_UI8, 0 },
- {_T("xor"), 0, PARAM_RMPTR8, PARAM_UI8, 0 },
- {_T("cmp"), 0, PARAM_RMPTR8, PARAM_UI8, 0 }
-};
-
-static const I386_OPCODE group81_table[8] =
-{
- {_T("add"), 0, PARAM_RMPTR, PARAM_IMM, 0 },
- {_T("or"), 0, PARAM_RMPTR, PARAM_IMM, 0 },
- {_T("adc"), 0, PARAM_RMPTR, PARAM_IMM, 0 },
- {_T("sbb"), 0, PARAM_RMPTR, PARAM_IMM, 0 },
- {_T("and"), 0, PARAM_RMPTR, PARAM_IMM, 0 },
- {_T("sub"), 0, PARAM_RMPTR, PARAM_IMM, 0 },
- {_T("xor"), 0, PARAM_RMPTR, PARAM_IMM, 0 },
- {_T("cmp"), 0, PARAM_RMPTR, PARAM_IMM, 0 }
-};
-
-static const I386_OPCODE group83_table[8] =
-{
- {_T("add"), 0, PARAM_RMPTR, PARAM_I8, 0 },
- {_T("or"), 0, PARAM_RMPTR, PARAM_I8, 0 },
- {_T("adc"), 0, PARAM_RMPTR, PARAM_I8, 0 },
- {_T("sbb"), 0, PARAM_RMPTR, PARAM_I8, 0 },
- {_T("and"), 0, PARAM_RMPTR, PARAM_I8, 0 },
- {_T("sub"), 0, PARAM_RMPTR, PARAM_I8, 0 },
- {_T("xor"), 0, PARAM_RMPTR, PARAM_I8, 0 },
- {_T("cmp"), 0, PARAM_RMPTR, PARAM_I8, 0 }
-};
-
-static const I386_OPCODE groupC0_table[8] =
-{
- {_T("rol"), 0, PARAM_RMPTR8, PARAM_UI8, 0 },
- {_T("ror"), 0, PARAM_RMPTR8, PARAM_UI8, 0 },
- {_T("rcl"), 0, PARAM_RMPTR8, PARAM_UI8, 0 },
- {_T("rcr"), 0, PARAM_RMPTR8, PARAM_UI8, 0 },
- {_T("shl"), 0, PARAM_RMPTR8, PARAM_UI8, 0 },
- {_T("shr"), 0, PARAM_RMPTR8, PARAM_UI8, 0 },
- {_T("sal"), 0, PARAM_RMPTR8, PARAM_UI8, 0 },
- {_T("sar"), 0, PARAM_RMPTR8, PARAM_UI8, 0 }
-};
-
-static const I386_OPCODE groupC1_table[8] =
-{
- {_T("rol"), 0, PARAM_RMPTR, PARAM_UI8, 0 },
- {_T("ror"), 0, PARAM_RMPTR, PARAM_UI8, 0 },
- {_T("rcl"), 0, PARAM_RMPTR, PARAM_UI8, 0 },
- {_T("rcr"), 0, PARAM_RMPTR, PARAM_UI8, 0 },
- {_T("shl"), 0, PARAM_RMPTR, PARAM_UI8, 0 },
- {_T("shr"), 0, PARAM_RMPTR, PARAM_UI8, 0 },
- {_T("sal"), 0, PARAM_RMPTR, PARAM_UI8, 0 },
- {_T("sar"), 0, PARAM_RMPTR, PARAM_UI8, 0 }
-};
-
-static const I386_OPCODE groupD0_table[8] =
-{
- {_T("rol"), 0, PARAM_RMPTR8, PARAM_1, 0 },
- {_T("ror"), 0, PARAM_RMPTR8, PARAM_1, 0 },
- {_T("rcl"), 0, PARAM_RMPTR8, PARAM_1, 0 },
- {_T("rcr"), 0, PARAM_RMPTR8, PARAM_1, 0 },
- {_T("shl"), 0, PARAM_RMPTR8, PARAM_1, 0 },
- {_T("shr"), 0, PARAM_RMPTR8, PARAM_1, 0 },
- {_T("sal"), 0, PARAM_RMPTR8, PARAM_1, 0 },
- {_T("sar"), 0, PARAM_RMPTR8, PARAM_1, 0 }
-};
-
-static const I386_OPCODE groupD1_table[8] =
-{
- {_T("rol"), 0, PARAM_RMPTR, PARAM_1, 0 },
- {_T("ror"), 0, PARAM_RMPTR, PARAM_1, 0 },
- {_T("rcl"), 0, PARAM_RMPTR, PARAM_1, 0 },
- {_T("rcr"), 0, PARAM_RMPTR, PARAM_1, 0 },
- {_T("shl"), 0, PARAM_RMPTR, PARAM_1, 0 },
- {_T("shr"), 0, PARAM_RMPTR, PARAM_1, 0 },
- {_T("sal"), 0, PARAM_RMPTR, PARAM_1, 0 },
- {_T("sar"), 0, PARAM_RMPTR, PARAM_1, 0 }
-};
-
-static const I386_OPCODE groupD2_table[8] =
-{
- {_T("rol"), 0, PARAM_RMPTR8, PARAM_CL, 0 },
- {_T("ror"), 0, PARAM_RMPTR8, PARAM_CL, 0 },
- {_T("rcl"), 0, PARAM_RMPTR8, PARAM_CL, 0 },
- {_T("rcr"), 0, PARAM_RMPTR8, PARAM_CL, 0 },
- {_T("shl"), 0, PARAM_RMPTR8, PARAM_CL, 0 },
- {_T("shr"), 0, PARAM_RMPTR8, PARAM_CL, 0 },
- {_T("sal"), 0, PARAM_RMPTR8, PARAM_CL, 0 },
- {_T("sar"), 0, PARAM_RMPTR8, PARAM_CL, 0 }
-};
-
-static const I386_OPCODE groupD3_table[8] =
-{
- {_T("rol"), 0, PARAM_RMPTR, PARAM_CL, 0 },
- {_T("ror"), 0, PARAM_RMPTR, PARAM_CL, 0 },
- {_T("rcl"), 0, PARAM_RMPTR, PARAM_CL, 0 },
- {_T("rcr"), 0, PARAM_RMPTR, PARAM_CL, 0 },
- {_T("shl"), 0, PARAM_RMPTR, PARAM_CL, 0 },
- {_T("shr"), 0, PARAM_RMPTR, PARAM_CL, 0 },
- {_T("sal"), 0, PARAM_RMPTR, PARAM_CL, 0 },
- {_T("sar"), 0, PARAM_RMPTR, PARAM_CL, 0 }
-};
-
-static const I386_OPCODE groupF6_table[8] =
-{
- {_T("test"), 0, PARAM_RMPTR8, PARAM_UI8, 0 },
- {_T("test"), 0, PARAM_RMPTR8, PARAM_UI8, 0 },
- {_T("not"), 0, PARAM_RMPTR8, 0, 0 },
- {_T("neg"), 0, PARAM_RMPTR8, 0, 0 },
- {_T("mul"), 0, PARAM_RMPTR8, 0, 0 },
- {_T("imul"), 0, PARAM_RMPTR8, 0, 0 },
- {_T("div"), 0, PARAM_RMPTR8, 0, 0 },
- {_T("idiv"), 0, PARAM_RMPTR8, 0, 0 }
-};
-
-static const I386_OPCODE groupF7_table[8] =
-{
- {_T("test"), 0, PARAM_RMPTR, PARAM_IMM, 0 },
- {_T("test"), 0, PARAM_RMPTR, PARAM_IMM, 0 },
- {_T("not"), 0, PARAM_RMPTR, 0, 0 },
- {_T("neg"), 0, PARAM_RMPTR, 0, 0 },
- {_T("mul"), 0, PARAM_RMPTR, 0, 0 },
- {_T("imul"), 0, PARAM_RMPTR, 0, 0 },
- {_T("div"), 0, PARAM_RMPTR, 0, 0 },
- {_T("idiv"), 0, PARAM_RMPTR, 0, 0 }
-};
-
-static const I386_OPCODE groupFE_table[8] =
-{
- {_T("inc"), 0, PARAM_RMPTR8, 0, 0 },
- {_T("dec"), 0, PARAM_RMPTR8, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 }
-};
-
-static const I386_OPCODE groupFF_table[8] =
-{
- {_T("inc"), 0, PARAM_RMPTR, 0, 0 },
- {_T("dec"), 0, PARAM_RMPTR, 0, 0 },
- {_T("call"), ALWAYS64, PARAM_RMPTR, 0, 0, DASMFLAG_STEP_OVER},
- {_T("call far ptr "),0, PARAM_RM, 0, 0, DASMFLAG_STEP_OVER},
- {_T("jmp"), ALWAYS64, PARAM_RMPTR, 0, 0 },
- {_T("jmp far ptr "),0, PARAM_RM, 0, 0 },
- {_T("push"), 0, PARAM_RMPTR, 0, 0 },
- {_T("???"), 0, 0, 0, 0 }
-};
-
-static const I386_OPCODE group0F00_table[8] =
-{
- {_T("sldt"), 0, PARAM_RM, 0, 0 },
- {_T("str"), 0, PARAM_RM, 0, 0 },
- {_T("lldt"), 0, PARAM_RM, 0, 0 },
- {_T("ltr"), 0, PARAM_RM, 0, 0 },
- {_T("verr"), 0, PARAM_RM, 0, 0 },
- {_T("verw"), 0, PARAM_RM, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 }
-};
-
-static const I386_OPCODE group0F01_table[8] =
-{
- {_T("sgdt"), 0, PARAM_RM, 0, 0 },
- {_T("sidt"), 0, PARAM_RM, 0, 0 },
- {_T("lgdt"), 0, PARAM_RM, 0, 0 },
- {_T("lidt"), 0, PARAM_RM, 0, 0 },
- {_T("smsw"), 0, PARAM_RM, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("lmsw"), 0, PARAM_RM, 0, 0 },
- {_T("invlpg"), 0, PARAM_RM, 0, 0 }
-};
-
-static const I386_OPCODE group0F0D_table[8] =
-{
- {_T("prefetch"), 0, PARAM_RM8, 0, 0 },
- {_T("prefetchw"), 0, PARAM_RM8, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 }
-};
-
-static const I386_OPCODE group0F12_table[4] =
-{
- {_T("movlps\0")
- _T("movlpd\0")
- _T("movddup\0")
- _T("movsldup"), VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 },
- {_T("movlps\0")
- _T("movlpd\0")
- _T("movddup\0")
- _T("movsldup"), VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 },
- {_T("movlps\0")
- _T("movlpd\0")
- _T("movddup\0")
- _T("movsldup"), VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 },
- {_T("movhlps\0")
- _T("???\0")
- _T("movddup\0")
- _T("movsldup"), VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 }
-};
-
-static const I386_OPCODE group0F16_table[4] =
-{
- {_T("movhps\0")
- _T("movhpd\0")
- _T("???\0")
- _T("movshdup"), VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 },
- {_T("movhps\0")
- _T("movhpd\0")
- _T("???\0")
- _T("movshdup"), VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 },
- {_T("movhps\0")
- _T("movhpd\0")
- _T("???\0")
- _T("movshdup"), VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 },
- {_T("movlhps\0")
- _T("movhpd\0")
- _T("???\0")
- _T("movshdup"), VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 }
-};
-
-static const I386_OPCODE group0F18_table[8] =
-{
- {_T("prefetchnta"), 0, PARAM_RM8, 0, 0 },
- {_T("prefetch0"), 0, PARAM_RM8, 0, 0 },
- {_T("prefetch1"), 0, PARAM_RM8, 0, 0 },
- {_T("prefetch2"), 0, PARAM_RM8, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 }
-};
-
-static const I386_OPCODE group0F71_table[8] =
-{
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("psrlw"), 0, PARAM_MMX2, PARAM_UI8, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("psraw"), 0, PARAM_MMX2, PARAM_UI8, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("psllw"), 0, PARAM_MMX2, PARAM_UI8, 0 },
- {_T("???"), 0, 0, 0, 0 }
-};
-
-static const I386_OPCODE group0F72_table[8] =
-{
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("psrld"), 0, PARAM_MMX2, PARAM_UI8, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("psrad"), 0, PARAM_MMX2, PARAM_UI8, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("pslld"), 0, PARAM_MMX2, PARAM_UI8, 0 },
- {_T("???"), 0, 0, 0, 0 }
-};
-
-static const I386_OPCODE group0F73_table[8] =
-{
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("psrlq"), 0, PARAM_MMX2, PARAM_UI8, 0 },
- {_T("psrldq"), 0, PARAM_MMX2, PARAM_UI8, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("psllq"), 0, PARAM_MMX2, PARAM_UI8, 0 },
- {_T("pslldq"), 0, PARAM_MMX2, PARAM_UI8, 0 },
-};
-
-static const I386_OPCODE group0FAE_table[8] =
-{
- {_T("fxsave"), 0, PARAM_RM, 0, 0 },
- {_T("fxrstor"), 0, PARAM_RM, 0, 0 },
- {_T("ldmxcsr"), 0, PARAM_RM, 0, 0 },
- {_T("stmxscr"), 0, PARAM_RM, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("lfence"), 0, 0, 0, 0 },
- {_T("mfence"), 0, 0, 0, 0 },
- {_T("sfence"), 0, 0, 0, 0 }
-};
-
-
-static const I386_OPCODE group0FBA_table[8] =
-{
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("bt"), 0, PARAM_RM, PARAM_UI8, 0 },
- {_T("bts"), 0, PARAM_RM, PARAM_UI8, 0 },
- {_T("btr"), 0, PARAM_RM, PARAM_UI8, 0 },
- {_T("btc"), 0, PARAM_RM, PARAM_UI8, 0 }
-};
-
-static const I386_OPCODE group0FC7_table[8] =
-{
- {_T("???"), 0, 0, 0, 0 },
- {_T("cmpxchg8b"), MODRM, PARAM_M64PTR, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("???"), 0, 0, 0, 0 },
- {_T("vmptrld\0")
- _T("vmclear\0")
- _T("???\0")
- _T("vmxon"), MODRM|VAR_NAME4, PARAM_M64PTR, 0, 0 },
- {_T("vmptrtst"), MODRM, PARAM_M64PTR, 0, 0 }
-};
-
-static const GROUP_OP group_op_table[] =
-{
- {_T("group80"), group80_table },
- {_T("group81"), group81_table },
- {_T("group83"), group83_table },
- {_T("groupC0"), groupC0_table },
- {_T("groupC1"), groupC1_table },
- {_T("groupD0"), groupD0_table },
- {_T("groupD1"), groupD1_table },
- {_T("groupD2"), groupD2_table },
- {_T("groupD3"), groupD3_table },
- {_T("groupF6"), groupF6_table },
- {_T("groupF7"), groupF7_table },
- {_T("groupFE"), groupFE_table },
- {_T("groupFF"), groupFF_table },
- {_T("group0F00"), group0F00_table },
- {_T("group0F01"), group0F01_table },
- {_T("group0F0D"), group0F0D_table },
- {_T("group0F12"), group0F12_table },
- {_T("group0F16"), group0F16_table },
- {_T("group0F18"), group0F18_table },
- {_T("group0F71"), group0F71_table },
- {_T("group0F72"), group0F72_table },
- {_T("group0F73"), group0F73_table },
- {_T("group0FAE"), group0FAE_table },
- {_T("group0FBA"), group0FBA_table },
- {_T("group0FC7"), group0FC7_table }
-};
-
-
-
-static const _TCHAR *const i386_reg[3][16] =
-{
- {_T("ax"), _T("cx"), _T("dx"), _T("bx"), _T("sp"), _T("bp"), _T("si"), _T("di"), _T("r8w"), _T("r9w"), _T("r10w"),_T("r11w"),_T("r12w"),_T("r13w"),_T("r14w"),_T("r15w")},
- {_T("eax"), _T("ecx"), _T("edx"), _T("ebx"), _T("esp"), _T("ebp"), _T("esi"), _T("edi"), _T("r8d"), _T("r9d"), _T("r10d"),_T("r11d"),_T("r12d"),_T("r13d"),_T("r14d"),_T("r15d")},
- {_T("rax"), _T("rcx"), _T("rdx"), _T("rbx"), _T("rsp"), _T("rbp"), _T("rsi"), _T("rdi"), _T("r8"), _T("r9"), _T("r10"), _T("r11"), _T("r12"), _T("r13"), _T("r14"), _T("r15")}
-};
-
-static const _TCHAR *const i386_reg8[8] = {_T("al"), _T("cl"), _T("dl"), _T("bl"), _T("ah"), _T("ch"), _T("dh"), _T("bh")};
-static const _TCHAR *const i386_reg8rex[16] = {_T("al"), _T("cl"), _T("dl"), _T("bl"), _T("spl"), _T("bpl"), _T("sil"), _T("dil"), _T("r8l"), _T("r9l"), _T("r10l"), _T("r11l"), _T("r12l"), _T("r13l"), _T("r14l"), _T("r15l")};
-static const _TCHAR *const i386_sreg[8] = {_T("es"), _T("cs"), _T("ss"), _T("ds"), _T("fs"), _T("gs"), _T("???"), _T("???")};
-
-static int address_size;
-static int operand_size;
-static int address_prefix;
-static int operand_prefix;
-static int max_length;
-static UINT64 pc;
-static UINT8 modrm;
-static UINT32 segment;
-static offs_t dasm_flags;
-static _TCHAR modrm_string[256];
-static UINT8 rex, regex, sibex, rmex;
-static UINT8 pre0f;
-static UINT8 curmode;
-
-#define MODRM_REG1 ((modrm >> 3) & 0x7)
-#define MODRM_REG2 (modrm & 0x7)
-#define MODRM_MOD ((modrm >> 6) & 0x3)
-
-INLINE UINT8 I386_OPS::_FETCH(void)
-{
- if ((opcode_ptr - opcode_ptr_base) + 1 > max_length)
- return 0xff;
- pc++;
- return *opcode_ptr++;
-}
-
-#if 0
-INLINE UINT16 I386_OPS::_FETCH16(void)
-{
- UINT16 d;
- if ((opcode_ptr - opcode_ptr_base) + 2 > max_length)
- return 0xffff;
- d = opcode_ptr[0] | (opcode_ptr[1] << 8);
- opcode_ptr += 2;
- pc += 2;
- return d;
-}
-#endif
-
-INLINE UINT32 I386_OPS::_FETCH32(void)
-{
- UINT32 d;
- if ((opcode_ptr - opcode_ptr_base) + 4 > max_length)
- return 0xffffffff;
- d = opcode_ptr[0] | (opcode_ptr[1] << 8) | (opcode_ptr[2] << 16) | (opcode_ptr[3] << 24);
- opcode_ptr += 4;
- pc += 4;
- return d;
-}
-
-INLINE UINT8 I386_OPS::_FETCHD(void)
-{
- if ((opcode_ptr - opcode_ptr_base) + 1 > max_length)
- return 0xff;
- pc++;
- return *opcode_ptr++;
-}
-
-INLINE UINT16 I386_OPS::_FETCHD16(void)
-{
- UINT16 d;
- if ((opcode_ptr - opcode_ptr_base) + 2 > max_length)
- return 0xffff;
- d = opcode_ptr[0] | (opcode_ptr[1] << 8);
- opcode_ptr += 2;
- pc += 2;
- return d;
-}
-
-INLINE UINT32 I386_OPS::_FETCHD32(void)
-{
- UINT32 d;
- if ((opcode_ptr - opcode_ptr_base) + 4 > max_length)
- return 0xffffffff;
- d = opcode_ptr[0] | (opcode_ptr[1] << 8) | (opcode_ptr[2] << 16) | (opcode_ptr[3] << 24);
- opcode_ptr += 4;
- pc += 4;
- return d;
-}
-
-static _TCHAR *I386_OPS::hexstring(UINT32 value, int digits)
-{
- static _TCHAR buffer[20];
- buffer[0] = _T('0');
- if (digits)
- _stprintf(&buffer[1], _T("%0*Xh"), digits, value);
- else
- _stprintf(&buffer[1], _T("%Xh"), value);
- return (buffer[1] >= _T('0') && buffer[1] <= _T('9')) ? &buffer[1] : &buffer[0];
-}
-
-static _TCHAR *I386_OPS::hexstring64(UINT32 lo, UINT32 hi)
-{
- static _TCHAR buffer[40];
- buffer[0] = _T('0');
- if (hi != 0)
- _stprintf(&buffer[1], _T("%X%08Xh"), hi, lo);
- else
- _stprintf(&buffer[1], _T("%Xh"), lo);
- return (buffer[1] >= _T('0') && buffer[1] <= _T('9')) ? &buffer[1] : &buffer[0];
-}
-
-static _TCHAR *I386_OPS::hexstringpc(UINT64 pc)
-{
- if (curmode == 64)
- return hexstring64((UINT32)pc, (UINT32)(pc >> 32));
- else
- return hexstring((UINT32)pc, 0);
-}
-
-_TCHAR *I386_OPS::shexstring(UINT32 value, int digits, int always)
-{
- static _TCHAR buffer[20];
- if (value >= 0x80000000)
- _stprintf(buffer, _T("-%s"), hexstring(-value, digits));
- else if (always)
- _stprintf(buffer, _T("+%s"), hexstring(value, digits));
- else
- return hexstring(value, digits);
- return buffer;
-}
-
-_TCHAR* I386_OPS::handle_sib_byte( _TCHAR* s, UINT8 mod )
-{
- UINT32 i32;
- UINT8 scale, i, base;
- UINT8 sib = _FETCHD();
-
- scale = (sib >> 6) & 0x3;
- i = ((sib >> 3) & 0x7) | sibex;
- base = (sib & 0x7) | rmex;
-
- if (base == 5 && mod == 0) {
- i32 = _FETCH32();
- s += _stprintf( s, _T("%s"), hexstring(i32, 0) );
- } else if (base != 5 || mod != 3)
- s += _stprintf( s, _T("%s"), i386_reg[address_size][base] );
-
- if ( i != 4 ) {
- s += _stprintf( s, _T("+%s"), i386_reg[address_size][i] );
- if (scale)
- s += _stprintf( s, _T("*%d"), 1 << scale );
- }
- return s;
-}
-
-void I386_OPS::handle_modrm(_TCHAR* s)
-{
- INT8 disp8;
- INT16 disp16;
- INT32 disp32;
- UINT8 mod, rm;
-
- modrm = _FETCHD();
- mod = (modrm >> 6) & 0x3;
- rm = (modrm & 0x7) | rmex;
-
- if( modrm >= 0xc0 )
- return;
-
- switch(segment)
- {
- case SEG_CS: s += _stprintf( s, _T("cs:") ); break;
- case SEG_DS: s += _stprintf( s, _T("ds:") ); break;
- case SEG_ES: s += _stprintf( s, _T("es:") ); break;
- case SEG_FS: s += _stprintf( s, _T("fs:") ); break;
- case SEG_GS: s += _stprintf( s, _T("gs:") ); break;
- case SEG_SS: s += _stprintf( s, _T("ss:") ); break;
- }
-
- s += _stprintf( s, _T("[") );
- if( address_size == 2 ) {
- if ((rm & 7) == 4)
- s = handle_sib_byte( s, mod );
- else if ((rm & 7) == 5 && mod == 0) {
- disp32 = _FETCHD32();
- s += _stprintf( s, _T("rip%s"), shexstring(disp32, 0, TRUE) );
- } else
- s += _stprintf( s, _T("%s"), i386_reg[2][rm]);
- if( mod == 1 ) {
- disp8 = _FETCHD();
- if (disp8 != 0)
- s += _stprintf( s, _T("%s"), shexstring((INT32)disp8, 0, TRUE) );
- } else if( mod == 2 ) {
- disp32 = _FETCHD32();
- if (disp32 != 0)
- s += _stprintf( s, _T("%s"), shexstring(disp32, 0, TRUE) );
- }
- } else if (address_size == 1) {
- if ((rm & 7) == 4)
- s = handle_sib_byte( s, mod );
- else if ((rm & 7) == 5 && mod == 0) {
- disp32 = _FETCHD32();
- if (curmode == 64)
- s += _stprintf( s, _T("eip%s"), shexstring(disp32, 0, TRUE) );
- else
- s += _stprintf( s, _T("%s"), hexstring(disp32, 0) );
- } else
- s += _stprintf( s, _T("%s"), i386_reg[1][rm]);
- if( mod == 1 ) {
- disp8 = _FETCHD();
- if (disp8 != 0)
- s += _stprintf( s, _T("%s"), shexstring((INT32)disp8, 0, TRUE) );
- } else if( mod == 2 ) {
- disp32 = _FETCHD32();
- if (disp32 != 0)
- s += _stprintf( s, _T("%s"), shexstring(disp32, 0, TRUE) );
- }
- } else {
- switch( rm )
- {
- case 0: s += _stprintf( s, _T("bx+si") ); break;
- case 1: s += _stprintf( s, _T("bx+di") ); break;
- case 2: s += _stprintf( s, _T("bp+si") ); break;
- case 3: s += _stprintf( s, _T("bp+di") ); break;
- case 4: s += _stprintf( s, _T("si") ); break;
- case 5: s += _stprintf( s, _T("di") ); break;
- case 6:
- if( mod == 0 ) {
- disp16 = _FETCHD16();
- s += _stprintf( s, _T("%s"), hexstring((unsigned) (UINT16) disp16, 0) );
- } else {
- s += _stprintf( s, _T("bp") );
- }
- break;
- case 7: s += _stprintf( s, _T("bx") ); break;
- }
- if( mod == 1 ) {
- disp8 = _FETCHD();
- if (disp8 != 0)
- s += _stprintf( s, _T("%s"), shexstring((INT32)disp8, 0, TRUE) );
- } else if( mod == 2 ) {
- disp16 = _FETCHD16();
- if (disp16 != 0)
- s += _stprintf( s, _T("%s"), shexstring((INT32)disp16, 0, TRUE) );
- }
- }
- s += _stprintf( s, _T("]") );
-}
-
-_TCHAR* I386_OPS::handle_param(_TCHAR* s, UINT32 param)
-{
- UINT8 i8;
- UINT16 i16;
- UINT32 i32;
- UINT16 ptr;
- UINT32 addr;
- INT8 d8;
- INT16 d16;
- INT32 d32;
-
- switch(param)
- {
- case PARAM_REG:
- s += _stprintf( s, _T("%s"), i386_reg[operand_size][MODRM_REG1 | regex] );
- break;
-
- case PARAM_REG8:
- s += _stprintf( s, _T("%s"), (rex ? i386_reg8rex : i386_reg8)[MODRM_REG1 | regex] );
- break;
-
- case PARAM_REG16:
- s += _stprintf( s, _T("%s"), i386_reg[0][MODRM_REG1 | regex] );
- break;
-
- case PARAM_REG32:
- s += _stprintf( s, _T("%s"), i386_reg[1][MODRM_REG1 | regex] );
- break;
-
- case PARAM_REG3264:
- s += _stprintf( s, _T("%s"), i386_reg[(operand_size == 2) ? 2 : 1][MODRM_REG1 | regex] );
- break;
-
- case PARAM_MMX:
- if (pre0f == 0x66 || pre0f == 0xf2 || pre0f == 0xf3)
- s += _stprintf( s, _T("xmm%d"), MODRM_REG1 | regex );
- else
- s += _stprintf( s, _T("mm%d"), MODRM_REG1 | regex );
- break;
-
- case PARAM_MMX2:
- if (pre0f == 0x66 || pre0f == 0xf2 || pre0f == 0xf3)
- s += _stprintf( s, _T("xmm%d"), MODRM_REG2 | regex );
- else
- s += _stprintf( s, _T("mm%d"), MODRM_REG2 | regex );
- break;
-
- case PARAM_XMM:
- s += _stprintf( s, _T("xmm%d"), MODRM_REG1 | regex );
- break;
-
- case PARAM_REGORXMM:
- if (pre0f != 0xf2 && pre0f != 0xf3)
- s += _stprintf( s, _T("xmm%d"), MODRM_REG1 | regex );
- else
- s += _stprintf( s, _T("%s"), i386_reg[(operand_size == 2) ? 2 : 1][MODRM_REG1 | regex] );
- break;
-
- case PARAM_REG2_32:
- s += _stprintf( s, _T("%s"), i386_reg[1][MODRM_REG2 | rmex] );
- break;
-
- case PARAM_RM:
- case PARAM_RMPTR:
- if( modrm >= 0xc0 ) {
- s += _stprintf( s, _T("%s"), i386_reg[operand_size][MODRM_REG2 | rmex] );
- } else {
- if (param == PARAM_RMPTR)
- {
- if( operand_size == 2 )
- s += _stprintf( s, _T("qword ptr ") );
- else if (operand_size == 1)
- s += _stprintf( s, _T("dword ptr ") );
- else
- s += _stprintf( s, _T("word ptr ") );
- }
- s += _stprintf( s, _T("%s"), modrm_string );
- }
- break;
-
- case PARAM_RM8:
- case PARAM_RMPTR8:
- if( modrm >= 0xc0 ) {
- s += _stprintf( s, _T("%s"), (rex ? i386_reg8rex : i386_reg8)[MODRM_REG2 | rmex] );
- } else {
- if (param == PARAM_RMPTR8)
- s += _stprintf( s, _T("byte ptr ") );
- s += _stprintf( s, _T("%s"), modrm_string );
- }
- break;
-
- case PARAM_RM16:
- case PARAM_RMPTR16:
- if( modrm >= 0xc0 ) {
- s += _stprintf( s, _T("%s"), i386_reg[0][MODRM_REG2 | rmex] );
- } else {
- if (param == PARAM_RMPTR16)
- s += _stprintf( s, _T("word ptr ") );
- s += _stprintf( s, _T("%s"), modrm_string );
- }
- break;
-
- case PARAM_RM32:
- case PARAM_RMPTR32:
- if( modrm >= 0xc0 ) {
- s += _stprintf( s, _T("%s"), i386_reg[1][MODRM_REG2 | rmex] );
- } else {
- if (param == PARAM_RMPTR32)
- s += _stprintf( s, _T("dword ptr ") );
- s += _stprintf( s, _T("%s"), modrm_string );
- }
- break;
-
- case PARAM_RMXMM:
- if( modrm >= 0xc0 ) {
- if (pre0f != 0xf2 && pre0f != 0xf3)
- s += _stprintf( s, _T("xmm%d"), MODRM_REG2 | rmex );
- else
- s += _stprintf( s, _T("%s"), i386_reg[(operand_size == 2) ? 2 : 1][MODRM_REG2 | rmex] );
- } else {
- if (param == PARAM_RMPTR32)
- s += _stprintf( s, _T("dword ptr ") );
- s += _stprintf( s, _T("%s"), modrm_string );
- }
- break;
-
- case PARAM_M64:
- case PARAM_M64PTR:
- if( modrm >= 0xc0 ) {
- s += _stprintf( s, _T("???") );
- } else {
- if (param == PARAM_M64PTR)
- s += _stprintf( s, _T("qword ptr ") );
- s += _stprintf( s, _T("%s"), modrm_string );
- }
- break;
-
- case PARAM_MMXM:
- if( modrm >= 0xc0 ) {
- if (pre0f == 0x66 || pre0f == 0xf2 || pre0f == 0xf3)
- s += _stprintf( s, _T("xmm%d"), MODRM_REG2 | rmex );
- else
- s += _stprintf( s, _T("mm%d"), MODRM_REG2 | rmex );
- } else {
- s += _stprintf( s, _T("%s"), modrm_string );
- }
- break;
-
- case PARAM_XMMM:
- if( modrm >= 0xc0 ) {
- s += _stprintf( s, _T("xmm%d"), MODRM_REG2 | rmex );
- } else {
- s += _stprintf( s, _T("%s"), modrm_string );
- }
- break;
-
- case PARAM_I4:
- i8 = _FETCHD();
- s += _stprintf( s, _T("%d"), i8 & 0x0f );
- break;
-
- case PARAM_I8:
- i8 = _FETCHD();
- s += _stprintf( s, _T("%s"), shexstring((INT8)i8, 0, FALSE) );
- break;
-
- case PARAM_I16:
- i16 = _FETCHD16();
- s += _stprintf( s, _T("%s"), shexstring((INT16)i16, 0, FALSE) );
- break;
-
- case PARAM_UI8:
- i8 = _FETCHD();
- s += _stprintf( s, _T("%s"), shexstring((UINT8)i8, 0, FALSE) );
- break;
-
- case PARAM_UI16:
- i16 = _FETCHD16();
- s += _stprintf( s, _T("%s"), shexstring((UINT16)i16, 0, FALSE) );
- break;
-
- case PARAM_IMM64:
- if (operand_size == 2) {
- UINT32 lo32 = _FETCHD32();
- i32 = _FETCHD32();
- s += _stprintf( s, _T("%s"), hexstring64(lo32, i32) );
- } else if( operand_size ) {
- i32 = _FETCHD32();
- s += _stprintf( s, _T("%s"), hexstring(i32, 0) );
- } else {
- i16 = _FETCHD16();
- s += _stprintf( s, _T("%s"), hexstring(i16, 0) );
- }
- break;
-
- case PARAM_IMM:
- if( operand_size ) {
- i32 = _FETCHD32();
- s += _stprintf( s, _T("%s"), hexstring(i32, 0) );
- } else {
- i16 = _FETCHD16();
- s += _stprintf( s, _T("%s"), hexstring(i16, 0) );
- }
- break;
-
- case PARAM_ADDR:
- if( operand_size ) {
- addr = _FETCHD32();
- ptr = _FETCHD16();
- s += _stprintf( s, _T("%s:"), hexstring(ptr, 4) );
- s += _stprintf( s, _T("%s"), hexstring(addr, 0) );
- } else {
- addr = _FETCHD16();
- ptr = _FETCHD16();
- s += _stprintf( s, _T("%s:"), hexstring(ptr, 4) );
- s += _stprintf( s, _T("%s"), hexstring(addr, 0) );
- }
- break;
-
- case PARAM_REL:
- if( operand_size ) {
- d32 = _FETCHD32();
- s += _stprintf( s, _T("%s"), hexstringpc(pc + d32) );
- } else {
- /* make sure to keep the relative offset within the segment */
- d16 = _FETCHD16();
- s += _stprintf( s, _T("%s"), hexstringpc((pc & 0xFFFF0000) | ((pc + d16) & 0x0000FFFF)) );
- }
- break;
-
- case PARAM_REL8:
- d8 = _FETCHD();
- s += _stprintf( s, _T("%s"), hexstringpc(pc + d8) );
- break;
-
- case PARAM_MEM_OFFS:
- switch(segment)
- {
- case SEG_CS: s += _stprintf( s, _T("cs:") ); break;
- case SEG_DS: s += _stprintf( s, _T("ds:") ); break;
- case SEG_ES: s += _stprintf( s, _T("es:") ); break;
- case SEG_FS: s += _stprintf( s, _T("fs:") ); break;
- case SEG_GS: s += _stprintf( s, _T("gs:") ); break;
- case SEG_SS: s += _stprintf( s, _T("ss:") ); break;
- }
-
- if( address_size ) {
- i32 = _FETCHD32();
- s += _stprintf( s, _T("[%s]"), hexstring(i32, 0) );
- } else {
- i16 = _FETCHD16();
- s += _stprintf( s, _T("[%s]"), hexstring(i16, 0) );
- }
- break;
-
- case PARAM_PREIMP:
- switch(segment)
- {
- case SEG_CS: s += _stprintf( s, _T("cs:") ); break;
- case SEG_DS: s += _stprintf( s, _T("ds:") ); break;
- case SEG_ES: s += _stprintf( s, _T("es:") ); break;
- case SEG_FS: s += _stprintf( s, _T("fs:") ); break;
- case SEG_GS: s += _stprintf( s, _T("gs:") ); break;
- case SEG_SS: s += _stprintf( s, _T("ss:") ); break;
- }
- break;
-
- case PARAM_SREG:
- s += _stprintf( s, _T("%s"), i386_sreg[MODRM_REG1] );
- break;
-
- case PARAM_CREG:
- s += _stprintf( s, _T("cr%d"), MODRM_REG1 | regex );
- break;
-
- case PARAM_TREG:
- s += _stprintf( s, _T("tr%d"), MODRM_REG1 | regex );
- break;
-
- case PARAM_DREG:
- s += _stprintf( s, _T("dr%d"), MODRM_REG1 | regex );
- break;
-
- case PARAM_1:
- s += _stprintf( s, _T("1") );
- break;
-
- case PARAM_DX:
- s += _stprintf( s, _T("dx") );
- break;
-
- case PARAM_XMM0:
- s += _stprintf( s, _T("xmm0") );
- break;
-
- case PARAM_AL: s += _stprintf( s, _T("al") ); break;
- case PARAM_CL: s += _stprintf( s, _T("cl") ); break;
- case PARAM_DL: s += _stprintf( s, _T("dl") ); break;
- case PARAM_BL: s += _stprintf( s, _T("bl") ); break;
- case PARAM_AH: s += _stprintf( s, _T("ah") ); break;
- case PARAM_CH: s += _stprintf( s, _T("ch") ); break;
- case PARAM_DH: s += _stprintf( s, _T("dh") ); break;
- case PARAM_BH: s += _stprintf( s, _T("bh") ); break;
-
- case PARAM_EAX: s += _stprintf( s, _T("%s"), i386_reg[operand_size][0 | rmex] ); break;
- case PARAM_ECX: s += _stprintf( s, _T("%s"), i386_reg[operand_size][1 | rmex] ); break;
- case PARAM_EDX: s += _stprintf( s, _T("%s"), i386_reg[operand_size][2 | rmex] ); break;
- case PARAM_EBX: s += _stprintf( s, _T("%s"), i386_reg[operand_size][3 | rmex] ); break;
- case PARAM_ESP: s += _stprintf( s, _T("%s"), i386_reg[operand_size][4 | rmex] ); break;
- case PARAM_EBP: s += _stprintf( s, _T("%s"), i386_reg[operand_size][5 | rmex] ); break;
- case PARAM_ESI: s += _stprintf( s, _T("%s"), i386_reg[operand_size][6 | rmex] ); break;
- case PARAM_EDI: s += _stprintf( s, _T("%s"), i386_reg[operand_size][7 | rmex] ); break;
- }
- return s;
-}
-
-void I386_OPS::handle_fpu(_TCHAR *s, UINT8 op1, UINT8 op2)
-{
- switch (op1 & 0x7)
- {
- case 0: // Group D8
- {
- if (op2 < 0xc0)
- {
- pc--; // adjust fetch pointer, so modrm byte read again
- opcode_ptr--;
- handle_modrm( modrm_string );
- switch ((op2 >> 3) & 0x7)
- {
- case 0: _stprintf(s, _T("fadd dword ptr %s"), modrm_string); break;
- case 1: _stprintf(s, _T("fmul dword ptr %s"), modrm_string); break;
- case 2: _stprintf(s, _T("fcom dword ptr %s"), modrm_string); break;
- case 3: _stprintf(s, _T("fcomp dword ptr %s"), modrm_string); break;
- case 4: _stprintf(s, _T("fsub dword ptr %s"), modrm_string); break;
- case 5: _stprintf(s, _T("fsubr dword ptr %s"), modrm_string); break;
- case 6: _stprintf(s, _T("fdiv dword ptr %s"), modrm_string); break;
- case 7: _stprintf(s, _T("fdivr dword ptr %s"), modrm_string); break;
- }
- }
- else
- {
- switch ((op2 >> 3) & 0x7)
- {
- case 0: _stprintf(s, _T("fadd st(0),st(%d)"), op2 & 0x7); break;
- case 1: _stprintf(s, _T("fmul st(0),st(%d)"), op2 & 0x7); break;
- case 2: _stprintf(s, _T("fcom st(0),st(%d)"), op2 & 0x7); break;
- case 3: _stprintf(s, _T("fcomp st(0),st(%d)"), op2 & 0x7); break;
- case 4: _stprintf(s, _T("fsub st(0),st(%d)"), op2 & 0x7); break;
- case 5: _stprintf(s, _T("fsubr st(0),st(%d)"), op2 & 0x7); break;
- case 6: _stprintf(s, _T("fdiv st(0),st(%d)"), op2 & 0x7); break;
- case 7: _stprintf(s, _T("fdivr st(0),st(%d)"), op2 & 0x7); break;
- }
- }
- break;
- }
-
- case 1: // Group D9
- {
- if (op2 < 0xc0)
- {
- pc--; // adjust fetch pointer, so modrm byte read again
- opcode_ptr--;
- handle_modrm( modrm_string );
- switch ((op2 >> 3) & 0x7)
- {
- case 0: _stprintf(s, _T("fld dword ptr %s"), modrm_string); break;
- case 1: _stprintf(s, _T("??? (FPU)")); break;
- case 2: _stprintf(s, _T("fst dword ptr %s"), modrm_string); break;
- case 3: _stprintf(s, _T("fstp dword ptr %s"), modrm_string); break;
- case 4: _stprintf(s, _T("fldenv word ptr %s"), modrm_string); break;
- case 5: _stprintf(s, _T("fldcw word ptr %s"), modrm_string); break;
- case 6: _stprintf(s, _T("fstenv word ptr %s"), modrm_string); break;
- case 7: _stprintf(s, _T("fstcw word ptr %s"), modrm_string); break;
- }
- }
- else
- {
- switch (op2 & 0x3f)
- {
- case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
- _stprintf(s, _T("fld st(0),st(%d)"), op2 & 0x7); break;
-
- case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
- _stprintf(s, _T("fxch st(0),st(%d)"), op2 & 0x7); break;
-
- case 0x10: _stprintf(s, _T("fnop")); break;
- case 0x20: _stprintf(s, _T("fchs")); break;
- case 0x21: _stprintf(s, _T("fabs")); break;
- case 0x24: _stprintf(s, _T("ftst")); break;
- case 0x25: _stprintf(s, _T("fxam")); break;
- case 0x28: _stprintf(s, _T("fld1")); break;
- case 0x29: _stprintf(s, _T("fldl2t")); break;
- case 0x2a: _stprintf(s, _T("fldl2e")); break;
- case 0x2b: _stprintf(s, _T("fldpi")); break;
- case 0x2c: _stprintf(s, _T("fldlg2")); break;
- case 0x2d: _stprintf(s, _T("fldln2")); break;
- case 0x2e: _stprintf(s, _T("fldz")); break;
- case 0x30: _stprintf(s, _T("f2xm1")); break;
- case 0x31: _stprintf(s, _T("fyl2x")); break;
- case 0x32: _stprintf(s, _T("fptan")); break;
- case 0x33: _stprintf(s, _T("fpatan")); break;
- case 0x34: _stprintf(s, _T("fxtract")); break;
- case 0x35: _stprintf(s, _T("fprem1")); break;
- case 0x36: _stprintf(s, _T("fdecstp")); break;
- case 0x37: _stprintf(s, _T("fincstp")); break;
- case 0x38: _stprintf(s, _T("fprem")); break;
- case 0x39: _stprintf(s, _T("fyl2xp1")); break;
- case 0x3a: _stprintf(s, _T("fsqrt")); break;
- case 0x3b: _stprintf(s, _T("fsincos")); break;
- case 0x3c: _stprintf(s, _T("frndint")); break;
- case 0x3d: _stprintf(s, _T("fscale")); break;
- case 0x3e: _stprintf(s, _T("fsin")); break;
- case 0x3f: _stprintf(s, _T("fcos")); break;
-
- default: _stprintf(s, _T("??? (FPU)")); break;
- }
- }
- break;
- }
-
- case 2: // Group DA
- {
- if (op2 < 0xc0)
- {
- pc--; // adjust fetch pointer, so modrm byte read again
- opcode_ptr--;
- handle_modrm( modrm_string );
- switch ((op2 >> 3) & 0x7)
- {
- case 0: _stprintf(s, _T("fiadd dword ptr %s"), modrm_string); break;
- case 1: _stprintf(s, _T("fimul dword ptr %s"), modrm_string); break;
- case 2: _stprintf(s, _T("ficom dword ptr %s"), modrm_string); break;
- case 3: _stprintf(s, _T("ficomp dword ptr %s"), modrm_string); break;
- case 4: _stprintf(s, _T("fisub dword ptr %s"), modrm_string); break;
- case 5: _stprintf(s, _T("fisubr dword ptr %s"), modrm_string); break;
- case 6: _stprintf(s, _T("fidiv dword ptr %s"), modrm_string); break;
- case 7: _stprintf(s, _T("fidivr dword ptr %s"), modrm_string); break;
- }
- }
- else
- {
- switch (op2 & 0x3f)
- {
- case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
- _stprintf(s, _T("fcmovb st(0),st(%d)"), op2 & 0x7); break;
-
- case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
- _stprintf(s, _T("fcmove st(0),st(%d)"), op2 & 0x7); break;
-
- case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
- _stprintf(s, _T("fcmovbe st(0),st(%d)"), op2 & 0x7); break;
-
- case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f:
- _stprintf(s, _T("fcmovu st(0),st(%d)"), op2 & 0x7); break;
- case 0x29:
- _stprintf(s, _T("fucompp")); break;
-
- default: _stprintf(s, _T("??? (FPU)")); break;
-
- }
- }
- break;
- }
-
- case 3: // Group DB
- {
- if (op2 < 0xc0)
- {
- pc--; // adjust fetch pointer, so modrm byte read again
- opcode_ptr--;
- handle_modrm( modrm_string );
- switch ((op2 >> 3) & 0x7)
- {
- case 0: _stprintf(s, _T("fild dword ptr %s"), modrm_string); break;
- case 1: _stprintf(s, _T("fisttp dword ptr %s"), modrm_string); break;
- case 2: _stprintf(s, _T("fist dword ptr %s"), modrm_string); break;
- case 3: _stprintf(s, _T("fistp dword ptr %s"), modrm_string); break;
- case 4: _stprintf(s, _T("??? (FPU)")); break;
- case 5: _stprintf(s, _T("fld tword ptr %s"), modrm_string); break;
- case 6: _stprintf(s, _T("??? (FPU)")); break;
- case 7: _stprintf(s, _T("fstp tword ptr %s"), modrm_string); break;
- }
- }
- else
- {
- switch (op2 & 0x3f)
- {
- case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
- _stprintf(s, _T("fcmovnb st(0),st(%d)"), op2 & 0x7); break;
-
- case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
- _stprintf(s, _T("fcmovne st(0),st(%d)"), op2 & 0x7); break;
-
- case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
- _stprintf(s, _T("fcmovnbe st(0),st(%d)"), op2 & 0x7); break;
-
- case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f:
- _stprintf(s, _T("fcmovnu st(0),st(%d)"), op2 & 0x7); break;
-
- case 0x22: _stprintf(s, _T("fclex")); break;
- case 0x23: _stprintf(s, _T("finit")); break;
-
- case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:
- _stprintf(s, _T("fucomi st(0),st(%d)"), op2 & 0x7); break;
-
- case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
- _stprintf(s, _T("fcomi st(0),st(%d)"), op2 & 0x7); break;
-
- default: _stprintf(s, _T("??? (FPU)")); break;
- }
- }
- break;
- }
-
- case 4: // Group DC
- {
- if (op2 < 0xc0)
- {
- pc--; // adjust fetch pointer, so modrm byte read again
- opcode_ptr--;
- handle_modrm( modrm_string );
- switch ((op2 >> 3) & 0x7)
- {
- case 0: _stprintf(s, _T("fadd qword ptr %s"), modrm_string); break;
- case 1: _stprintf(s, _T("fmul qword ptr %s"), modrm_string); break;
- case 2: _stprintf(s, _T("fcom qword ptr %s"), modrm_string); break;
- case 3: _stprintf(s, _T("fcomp qword ptr %s"), modrm_string); break;
- case 4: _stprintf(s, _T("fsub qword ptr %s"), modrm_string); break;
- case 5: _stprintf(s, _T("fsubr qword ptr %s"), modrm_string); break;
- case 6: _stprintf(s, _T("fdiv qword ptr %s"), modrm_string); break;
- case 7: _stprintf(s, _T("fdivr qword ptr %s"), modrm_string); break;
- }
- }
- else
- {
- switch (op2 & 0x3f)
- {
- case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
- _stprintf(s, _T("fadd st(%d),st(0)"), op2 & 0x7); break;
-
- case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
- _stprintf(s, _T("fmul st(%d),st(0)"), op2 & 0x7); break;
-
- case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
- _stprintf(s, _T("fsubr st(%d),st(0)"), op2 & 0x7); break;
-
- case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:
- _stprintf(s, _T("fsub st(%d),st(0)"), op2 & 0x7); break;
-
- case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
- _stprintf(s, _T("fdivr st(%d),st(0)"), op2 & 0x7); break;
-
- case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f:
- _stprintf(s, _T("fdiv st(%d),st(0)"), op2 & 0x7); break;
-
- default: _stprintf(s, _T("??? (FPU)")); break;
- }
- }
- break;
- }
-
- case 5: // Group DD
- {
- if (op2 < 0xc0)
- {
- pc--; // adjust fetch pointer, so modrm byte read again
- opcode_ptr--;
- handle_modrm( modrm_string );
- switch ((op2 >> 3) & 0x7)
- {
- case 0: _stprintf(s, _T("fld qword ptr %s"), modrm_string); break;
- case 1: _stprintf(s, _T("fisttp qword ptr %s"), modrm_string); break;
- case 2: _stprintf(s, _T("fst qword ptr %s"), modrm_string); break;
- case 3: _stprintf(s, _T("fstp qword ptr %s"), modrm_string); break;
- case 4: _stprintf(s, _T("frstor %s"), modrm_string); break;
- case 5: _stprintf(s, _T("??? (FPU)")); break;
- case 6: _stprintf(s, _T("fsave %s"), modrm_string); break;
- case 7: _stprintf(s, _T("fstsw word ptr %s"), modrm_string); break;
- }
- }
- else
- {
- switch (op2 & 0x3f)
- {
- case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
- _stprintf(s, _T("ffree st(%d)"), op2 & 0x7); break;
-
- case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
- _stprintf(s, _T("fst st(%d)"), op2 & 0x7); break;
-
- case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f:
- _stprintf(s, _T("fstp st(%d)"), op2 & 0x7); break;
-
- case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
- _stprintf(s, _T("fucom st(%d), st(0)"), op2 & 0x7); break;
-
- case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:
- _stprintf(s, _T("fucomp st(%d)"), op2 & 0x7); break;
-
- default: _stprintf(s, _T("??? (FPU)")); break;
- }
- }
- break;
- }
-
- case 6: // Group DE
- {
- if (op2 < 0xc0)
- {
- pc--; // adjust fetch pointer, so modrm byte read again
- opcode_ptr--;
- handle_modrm( modrm_string );
- switch ((op2 >> 3) & 0x7)
- {
- case 0: _stprintf(s, _T("fiadd word ptr %s"), modrm_string); break;
- case 1: _stprintf(s, _T("fimul word ptr %s"), modrm_string); break;
- case 2: _stprintf(s, _T("ficom word ptr %s"), modrm_string); break;
- case 3: _stprintf(s, _T("ficomp word ptr %s"), modrm_string); break;
- case 4: _stprintf(s, _T("fisub word ptr %s"), modrm_string); break;
- case 5: _stprintf(s, _T("fisubr word ptr %s"), modrm_string); break;
- case 6: _stprintf(s, _T("fidiv word ptr %s"), modrm_string); break;
- case 7: _stprintf(s, _T("fidivr word ptr %s"), modrm_string); break;
- }
- }
- else
- {
- switch (op2 & 0x3f)
- {
- case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
- _stprintf(s, _T("faddp st(%d)"), op2 & 0x7); break;
-
- case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
- _stprintf(s, _T("fmulp st(%d)"), op2 & 0x7); break;
-
- case 0x19: _stprintf(s, _T("fcompp")); break;
-
- case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
- _stprintf(s, _T("fsubrp st(%d)"), op2 & 0x7); break;
-
- case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:
- _stprintf(s, _T("fsubp st(%d)"), op2 & 0x7); break;
-
- case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
- _stprintf(s, _T("fdivrp st(%d), st(0)"), op2 & 0x7); break;
-
- case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f:
- _stprintf(s, _T("fdivp st(%d)"), op2 & 0x7); break;
-
- default: _stprintf(s, _T("??? (FPU)")); break;
- }
- }
- break;
- }
-
- case 7: // Group DF
- {
- if (op2 < 0xc0)
- {
- pc--; // adjust fetch pointer, so modrm byte read again
- opcode_ptr--;
- handle_modrm( modrm_string );
- switch ((op2 >> 3) & 0x7)
- {
- case 0: _stprintf(s, _T("fild word ptr %s"), modrm_string); break;
- case 1: _stprintf(s, _T("fisttp word ptr %s"), modrm_string); break;
- case 2: _stprintf(s, _T("fist word ptr %s"), modrm_string); break;
- case 3: _stprintf(s, _T("fistp word ptr %s"), modrm_string); break;
- case 4: _stprintf(s, _T("fbld %s"), modrm_string); break;
- case 5: _stprintf(s, _T("fild qword ptr %s"), modrm_string); break;
- case 6: _stprintf(s, _T("fbstp %s"), modrm_string); break;
- case 7: _stprintf(s, _T("fistp qword ptr %s"), modrm_string); break;
- }
- }
- else
- {
- switch (op2 & 0x3f)
- {
- case 0x20: _stprintf(s, _T("fstsw ax")); break;
-
- case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:
- _stprintf(s, _T("fucomip st(%d)"), op2 & 0x7); break;
-
- case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
- _stprintf(s, _T("fcomip st(%d),st(0)"), op2 & 0x7); break;
-
- default: _stprintf(s, _T("??? (FPU)")); break;
- }
- }
- break;
- }
- }
-}
-
-void I386_OPS::decode_opcode(_TCHAR *s, const I386_OPCODE *op, UINT8 op1)
-{
- int i;
- UINT8 op2;
-
- if ((op->flags & SPECIAL64) && (address_size == 2))
- op = &x64_opcode_alt[op->flags >> 24];
-
- switch( op->flags & FLAGS_MASK )
- {
- case ISREX:
- if (curmode == 64)
- {
- rex = op1;
- operand_size = (op1 & 8) ? 2 : 1;
- regex = (op1 << 1) & 8;
- sibex = (op1 << 2) & 8;
- rmex = (op1 << 3) & 8;
- op2 = _FETCH();
- decode_opcode( s, &i386_opcode_table1[op2], op1 );
- return;
- }
- break;
-
- case OP_SIZE:
- rex = regex = sibex = rmex = 0;
- if (operand_size < 2 && operand_prefix == 0)
- {
- operand_size ^= 1;
- operand_prefix = 1;
- }
- op2 = _FETCH();
- decode_opcode( s, &i386_opcode_table1[op2], op2 );
- return;
-
- case ADDR_SIZE:
- rex = regex = sibex = rmex = 0;
- if(address_prefix == 0)
- {
- if (curmode != 64)
- address_size ^= 1;
- else
- address_size ^= 3;
- address_prefix = 1;
- }
- op2 = _FETCH();
- decode_opcode( s, &i386_opcode_table1[op2], op2 );
- return;
-
- case TWO_BYTE:
- if (&opcode_ptr[-2] >= opcode_ptr_base)
- pre0f = opcode_ptr[-2];
- op2 = _FETCHD();
- decode_opcode( s, &i386_opcode_table2[op2], op1 );
- return;
-
- case THREE_BYTE:
- op2 = _FETCHD();
- if (opcode_ptr[-2] == 0x38)
- decode_opcode( s, &i386_opcode_table0F38[op2], op1 );
- else
- decode_opcode( s, &i386_opcode_table0F3A[op2], op1 );
- return;
-
- case SEG_CS:
- case SEG_DS:
- case SEG_ES:
- case SEG_FS:
- case SEG_GS:
- case SEG_SS:
- rex = regex = sibex = rmex = 0;
- segment = op->flags;
- op2 = _FETCH();
- decode_opcode( s, &i386_opcode_table1[op2], op2 );
- return;
-
- case PREFIX:
- op2 = _FETCH();
- if ((op2 != 0x0f) && (op2 != 0x90))
- s += _stprintf( s, _T("%-7s "), op->mnemonic );
- if ((op2 == 0x90) && !pre0f)
- pre0f = op1;
- decode_opcode( s, &i386_opcode_table1[op2], op2 );
- return;
-
- case GROUP:
- handle_modrm( modrm_string );
- for( i=0; i < ARRAY_LENGTH(group_op_table); i++ ) {
- if( _tcscmp(op->mnemonic, group_op_table[i].mnemonic) == 0 ) {
- if (op->flags & GROUP_MOD)
- decode_opcode( s, &group_op_table[i].opcode[MODRM_MOD], op1 );
- else
- decode_opcode( s, &group_op_table[i].opcode[MODRM_REG1], op1 );
- return;
- }
- }
- goto handle_unknown;
-
- case FPU:
- op2 = _FETCHD();
- handle_fpu( s, op1, op2);
- return;
-
- case MODRM:
- handle_modrm( modrm_string );
- break;
- }
-
- if ((op->flags & ALWAYS64) && curmode == 64)
- operand_size = 2;
-
- if ((op->flags & VAR_NAME) && operand_size > 0)
- {
- const _TCHAR *mnemonic = op->mnemonic + _tcslen(op->mnemonic) + 1;
- if (operand_size == 2)
- mnemonic += _tcslen(mnemonic) + 1;
- s += _stprintf( s, _T("%-7s "), mnemonic );
- }
- else if (op->flags & VAR_NAME4)
- {
- const _TCHAR *mnemonic = op->mnemonic;
- int which = (pre0f == 0xf3) ? 3 : (pre0f == 0xf2) ? 2 : (pre0f == 0x66) ? 1 : 0;
- while (which--)
- mnemonic += _tcslen(mnemonic) + 1;
- s += _stprintf( s, _T("%-7s "), mnemonic );
- }
- else
- s += _stprintf( s, _T("%-7s "), op->mnemonic );
- dasm_flags = op->dasm_flags;
-
- if( op->param1 != 0 ) {
- s = handle_param( s, op->param1 );
- }
-
- if( op->param2 != 0 ) {
- s += _stprintf( s, _T(",") );
- s = handle_param( s, op->param2 );
- }
-
- if( op->param3 != 0 ) {
- s += _stprintf( s, _T(",") );
- s = handle_param( s, op->param3 );
- }
- return;
-
-handle_unknown:
- _stprintf(s, _T("???"));
-}
-
-int i386_dasm_one_ex(_TCHAR *buffer, UINT64 eip, const UINT8 *oprom, int mode)
-{
- UINT8 op;
-
- opcode_ptr = opcode_ptr_base = oprom;
- switch(mode)
- {
- case 1: /* 8086/8088/80186/80188 */
- address_size = 0;
- operand_size = 0;
- max_length = 8; /* maximum without redundant prefixes - not enforced by chip */
- break;
- case 2: /* 80286 */
- address_size = 0;
- operand_size = 0;
- max_length = 10;
- break;
- case 16: /* 80386+ 16-bit code segment */
- address_size = 0;
- operand_size = 0;
- max_length = 15;
- break;
- case 32: /* 80386+ 32-bit code segment */
- address_size = 1;
- operand_size = 1;
- max_length = 15;
- break;
- case 64: /* x86_64 */
- address_size = 2;
- operand_size = 1;
- max_length = 15;
- break;
- }
- pc = eip;
- dasm_flags = 0;
- segment = 0;
- curmode = mode;
- pre0f = 0;
- rex = regex = sibex = rmex = 0;
- address_prefix = 0;
- operand_prefix = 0;
-
- op = _FETCH();
-
- decode_opcode( buffer, &i386_opcode_table1[op], op );
- return (pc-eip) | dasm_flags | DASMFLAG_SUPPORTED;
-}
-
-int i386_dasm_one(_TCHAR *buffer, offs_t eip, const UINT8 *oprom, int mode)
-{
- return i386_dasm_one_ex(buffer, eip, oprom, mode);
-}
-
-CPU_DISASSEMBLE( x86_16 )
-{
- return i386_dasm_one_ex(buffer, pc, oprom, 16);
-}
-
-CPU_DISASSEMBLE( x86_32 )
-{
- return i386_dasm_one_ex(buffer, pc, oprom, 32);
-}
-
-CPU_DISASSEMBLE( x86_64 )
-{
- return i386_dasm_one_ex(buffer, pc, oprom, 64);
-}
+++ /dev/null
-// license:BSD-3-Clause
-// copyright-holders:Ville Linde, Barry Rodewald, Carl, Phil Bennett
-UINT16 I386_OPS_BASE::I386OP(shift_rotate16)( UINT8 modrm, UINT32 value, UINT8 shift)
-{
- UINT32 src = value & 0xffff;
- UINT16 dst = value;
-
- if( shift == 0 ) {
- CYCLES_RM(modrm, 3, 7);
- } else if( shift == 1 ) {
- switch( (modrm >> 3) & 0x7 )
- {
- case 0: /* ROL rm16, 1 */
- cpustate->CF = (src & 0x8000) ? 1 : 0;
- dst = (src << 1) + cpustate->CF;
- cpustate->OF = ((src ^ dst) & 0x8000) ? 1 : 0;
- CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
- break;
- case 1: /* ROR rm16, 1 */
- cpustate->CF = (src & 0x1) ? 1 : 0;
- dst = (cpustate->CF << 15) | (src >> 1);
- cpustate->OF = ((src ^ dst) & 0x8000) ? 1 : 0;
- CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
- break;
- case 2: /* RCL rm16, 1 */
- dst = (src << 1) + cpustate->CF;
- cpustate->CF = (src & 0x8000) ? 1 : 0;
- cpustate->OF = ((src ^ dst) & 0x8000) ? 1 : 0;
- CYCLES_RM(modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM);
- break;
- case 3: /* RCR rm16, 1 */
- dst = (cpustate->CF << 15) | (src >> 1);
- cpustate->CF = src & 0x1;
- cpustate->OF = ((src ^ dst) & 0x8000) ? 1 : 0;
- CYCLES_RM(modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM);
- break;
- case 4: /* SHL/SAL rm16, 1 */
- case 6:
- dst = src << 1;
- cpustate->CF = (src & 0x8000) ? 1 : 0;
- cpustate->OF = (((cpustate->CF << 15) ^ dst) & 0x8000) ? 1 : 0;
- SetSZPF16(dst);
- CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
- break;
- case 5: /* SHR rm16, 1 */
- dst = src >> 1;
- cpustate->CF = src & 0x1;
- cpustate->OF = (dst & 0x8000) ? 1 : 0;
- SetSZPF16(dst);
- CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
- break;
- case 7: /* SAR rm16, 1 */
- dst = (INT16)(src) >> 1;
- cpustate->CF = src & 0x1;
- cpustate->OF = 0;
- SetSZPF16(dst);
- CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
- break;
- }
- } else {
- switch( (modrm >> 3) & 0x7 )
- {
- case 0: /* ROL rm16, i8 */
- if(!(shift & 15))
- {
- if(shift & 16)
- {
- cpustate->CF = src & 1;
- cpustate->OF = (src & 1) ^ ((src >> 15) & 1);
- }
- break;
- }
- shift &= 15;
- dst = ((src & ((UINT16)0xffff >> shift)) << shift) |
- ((src & ((UINT16)0xffff << (16-shift))) >> (16-shift));
- cpustate->CF = dst & 0x1;
- cpustate->OF = (dst & 1) ^ (dst >> 15);
- CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
- break;
- case 1: /* ROR rm16, i8 */
- if(!(shift & 15))
- {
- if(shift & 16)
- {
- cpustate->CF = (src >> 15) & 1;
- cpustate->OF = ((src >> 15) & 1) ^ ((src >> 14) & 1);
- }
- break;
- }
- shift &= 15;
- dst = ((src & ((UINT16)0xffff << shift)) >> shift) |
- ((src & ((UINT16)0xffff >> (16-shift))) << (16-shift));
- cpustate->CF = (dst >> 15) & 1;
- cpustate->OF = ((dst >> 15) ^ (dst >> 14)) & 1;
- CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
- break;
- case 2: /* RCL rm16, i8 */
- shift %= 17;
- dst = ((src & ((UINT16)0xffff >> shift)) << shift) |
- ((src & ((UINT16)0xffff << (17-shift))) >> (17-shift)) |
- (cpustate->CF << (shift-1));
- if(shift) cpustate->CF = (src >> (16-shift)) & 0x1;
- cpustate->OF = cpustate->CF ^ ((dst >> 15) & 1);
- CYCLES_RM(modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM);
- break;
- case 3: /* RCR rm16, i8 */
- shift %= 17;
- dst = ((src & ((UINT16)0xffff << shift)) >> shift) |
- ((src & ((UINT16)0xffff >> (16-shift))) << (17-shift)) |
- (cpustate->CF << (16-shift));
- if(shift) cpustate->CF = (src >> (shift-1)) & 0x1;
- cpustate->OF = ((dst >> 15) ^ (dst >> 14)) & 1;
- CYCLES_RM(modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM);
- break;
- case 4: /* SHL/SAL rm16, i8 */
- case 6:
- shift &= 31;
- dst = src << shift;
- cpustate->CF = (shift <= 16) && (src & (1 << (16-shift)));
- SetSZPF16(dst);
- CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
- break;
- case 5: /* SHR rm16, i8 */
- shift &= 31;
- dst = src >> shift;
- cpustate->CF = (src & (1 << (shift-1))) ? 1 : 0;
- SetSZPF16(dst);
- CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
- break;
- case 7: /* SAR rm16, i8 */
- shift &= 31;
- dst = (INT16)src >> shift;
- cpustate->CF = (src & (1 << (shift-1))) ? 1 : 0;
- SetSZPF16(dst);
- CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
- break;
- }
-
- }
- return dst;
-}
-
-
-
-void I386_OPS_BASE::I386OP(adc_rm16_r16)() // Opcode 0x11
-{
- UINT16 src, dst;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- src = LOAD_REG16(modrm);
- dst = LOAD_RM16(modrm);
- dst = ADC16( dst, src, cpustate->CF);
- STORE_RM16(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- src = LOAD_REG16(modrm);
- dst = READ16(ea);
- dst = ADC16( dst, src, cpustate->CF);
- WRITE16(ea, dst);
- CYCLES(CYCLES_ALU_REG_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(adc_r16_rm16)() // Opcode 0x13
-{
- UINT16 src, dst;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- src = LOAD_RM16(modrm);
- dst = LOAD_REG16(modrm);
- dst = ADC16( dst, src, cpustate->CF);
- STORE_REG16(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,0);
- src = READ16(ea);
- dst = LOAD_REG16(modrm);
- dst = ADC16( dst, src, cpustate->CF);
- STORE_REG16(modrm, dst);
- CYCLES(CYCLES_ALU_MEM_REG);
- }
-}
-
-void I386_OPS_BASE::I386OP(adc_ax_i16)() // Opcode 0x15
-{
- UINT16 src, dst;
- src = FETCH16();
- dst = REG16(AX);
- dst = ADC16( dst, src, cpustate->CF);
- REG16(AX) = dst;
- CYCLES(CYCLES_ALU_IMM_ACC);
-}
-
-void I386_OPS_BASE::I386OP(add_rm16_r16)() // Opcode 0x01
-{
- UINT16 src, dst;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- src = LOAD_REG16(modrm);
- dst = LOAD_RM16(modrm);
- dst = ADD16(dst, src);
- STORE_RM16(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- src = LOAD_REG16(modrm);
- dst = READ16(ea);
- dst = ADD16(dst, src);
- WRITE16(ea, dst);
- CYCLES(CYCLES_ALU_REG_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(add_r16_rm16)() // Opcode 0x03
-{
- UINT16 src, dst;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- src = LOAD_RM16(modrm);
- dst = LOAD_REG16(modrm);
- dst = ADD16(dst, src);
- STORE_REG16(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,0);
- src = READ16(ea);
- dst = LOAD_REG16(modrm);
- dst = ADD16(dst, src);
- STORE_REG16(modrm, dst);
- CYCLES(CYCLES_ALU_MEM_REG);
- }
-}
-
-void I386_OPS_BASE::I386OP(add_ax_i16)() // Opcode 0x05
-{
- UINT16 src, dst;
- src = FETCH16();
- dst = REG16(AX);
- dst = ADD16(dst, src);
- REG16(AX) = dst;
- CYCLES(CYCLES_ALU_IMM_ACC);
-}
-
-void I386_OPS_BASE::I386OP(and_rm16_r16)() // Opcode 0x21
-{
- UINT16 src, dst;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- src = LOAD_REG16(modrm);
- dst = LOAD_RM16(modrm);
- dst = AND16(dst, src);
- STORE_RM16(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- src = LOAD_REG16(modrm);
- dst = READ16(ea);
- dst = AND16(dst, src);
- WRITE16(ea, dst);
- CYCLES(CYCLES_ALU_REG_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(and_r16_rm16)() // Opcode 0x23
-{
- UINT16 src, dst;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- src = LOAD_RM16(modrm);
- dst = LOAD_REG16(modrm);
- dst = AND16(dst, src);
- STORE_REG16(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,0);
- src = READ16(ea);
- dst = LOAD_REG16(modrm);
- dst = AND16(dst, src);
- STORE_REG16(modrm, dst);
- CYCLES(CYCLES_ALU_MEM_REG);
- }
-}
-
-void I386_OPS_BASE::I386OP(and_ax_i16)() // Opcode 0x25
-{
- UINT16 src, dst;
- src = FETCH16();
- dst = REG16(AX);
- dst = AND16(dst, src);
- REG16(AX) = dst;
- CYCLES(CYCLES_ALU_IMM_ACC);
-}
-
-void I386_OPS_BASE::I386OP(bsf_r16_rm16)() // Opcode 0x0f bc
-{
- UINT16 src, dst, temp;
- UINT8 modrm = FETCH();
-
- if( modrm >= 0xc0 ) {
- src = LOAD_RM16(modrm);
- } else {
- UINT32 ea = GetEA(modrm,0);
- src = READ16(ea);
- }
-
- dst = 0;
-
- if( src == 0 ) {
- cpustate->ZF = 1;
- } else {
- cpustate->ZF = 0;
- temp = 0;
- while( (src & (1 << temp)) == 0 ) {
- temp++;
- dst = temp;
- CYCLES(CYCLES_BSF);
- }
- STORE_REG16(modrm, dst);
- }
- CYCLES(CYCLES_BSF_BASE);
-}
-
-void I386_OPS_BASE::I386OP(bsr_r16_rm16)() // Opcode 0x0f bd
-{
- UINT16 src, dst, temp;
- UINT8 modrm = FETCH();
-
- if( modrm >= 0xc0 ) {
- src = LOAD_RM16(modrm);
- } else {
- UINT32 ea = GetEA(modrm,0);
- src = READ16(ea);
- }
-
- dst = 0;
-
- if( src == 0 ) {
- cpustate->ZF = 1;
- } else {
- cpustate->ZF = 0;
- dst = temp = 15;
- while( (src & (1 << temp)) == 0 ) {
- temp--;
- dst = temp;
- CYCLES(CYCLES_BSR);
- }
- STORE_REG16(modrm, dst);
- }
- CYCLES(CYCLES_BSR_BASE);
-}
-
-
-void I386_OPS_BASE::I386OP(bt_rm16_r16)() // Opcode 0x0f a3
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- UINT16 dst = LOAD_RM16(modrm);
- UINT16 bit = LOAD_REG16(modrm);
-
- if( dst & (1 << (bit & 0xf)) )
- cpustate->CF = 1;
- else
- cpustate->CF = 0;
-
- CYCLES(CYCLES_BT_REG_REG);
- } else {
- UINT8 segment;
- UINT32 ea = GetNonTranslatedEA(modrm,&segment);
- UINT16 bit = LOAD_REG16(modrm);
- ea += 2*(bit/16);
- ea = i386_translate(segment,(cpustate->address_size)?ea:(ea&0xffff),0);
- bit %= 16;
- UINT16 dst = READ16(ea);
-
- if( dst & (1 << bit) )
- cpustate->CF = 1;
- else
- cpustate->CF = 0;
-
- CYCLES(CYCLES_BT_REG_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(btc_rm16_r16)() // Opcode 0x0f bb
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- UINT16 dst = LOAD_RM16(modrm);
- UINT16 bit = LOAD_REG16(modrm);
-
- if( dst & (1 << (bit & 0xf)) )
- cpustate->CF = 1;
- else
- cpustate->CF = 0;
- dst ^= (1 << (bit & 0xf));
-
- STORE_RM16(modrm, dst);
- CYCLES(CYCLES_BTC_REG_REG);
- } else {
- UINT8 segment;
- UINT32 ea = GetNonTranslatedEA(modrm,&segment);
- UINT16 bit = LOAD_REG16(modrm);
- ea += 2*(bit/16);
- ea = i386_translate(segment,(cpustate->address_size)?ea:(ea&0xffff),1);
- bit %= 16;
- UINT16 dst = READ16(ea);
-
- if( dst & (1 << bit) )
- cpustate->CF = 1;
- else
- cpustate->CF = 0;
- dst ^= (1 << bit);
-
- WRITE16(ea, dst);
- CYCLES(CYCLES_BTC_REG_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(btr_rm16_r16)() // Opcode 0x0f b3
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- UINT16 dst = LOAD_RM16(modrm);
- UINT16 bit = LOAD_REG16(modrm);
-
- if( dst & (1 << (bit & 0xf)) )
- cpustate->CF = 1;
- else
- cpustate->CF = 0;
- dst &= ~(1 << (bit & 0xf));
-
- STORE_RM16(modrm, dst);
- CYCLES(CYCLES_BTR_REG_REG);
- } else {
- UINT8 segment;
- UINT32 ea = GetNonTranslatedEA(modrm,&segment);
- UINT16 bit = LOAD_REG16(modrm);
- ea += 2*(bit/16);
- ea = i386_translate(segment,(cpustate->address_size)?ea:(ea&0xffff),1);
- bit %= 16;
- UINT16 dst = READ16(ea);
-
- if( dst & (1 << bit) )
- cpustate->CF = 1;
- else
- cpustate->CF = 0;
- dst &= ~(1 << bit);
-
- WRITE16(ea, dst);
- CYCLES(CYCLES_BTR_REG_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(bts_rm16_r16)() // Opcode 0x0f ab
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- UINT16 dst = LOAD_RM16(modrm);
- UINT16 bit = LOAD_REG16(modrm);
-
- if( dst & (1 << (bit & 0xf)) )
- cpustate->CF = 1;
- else
- cpustate->CF = 0;
- dst |= (1 << (bit & 0xf));
-
- STORE_RM16(modrm, dst);
- CYCLES(CYCLES_BTS_REG_REG);
- } else {
- UINT8 segment;
- UINT32 ea = GetNonTranslatedEA(modrm,&segment);
- UINT16 bit = LOAD_REG16(modrm);
- ea += 2*(bit/16);
- ea = i386_translate(segment,(cpustate->address_size)?ea:(ea&0xffff),1);
- bit %= 16;
- UINT16 dst = READ16(ea);
-
- if( dst & (1 << bit) )
- cpustate->CF = 1;
- else
- cpustate->CF = 0;
- dst |= (1 << bit);
-
- WRITE16(ea, dst);
- CYCLES(CYCLES_BTS_REG_MEM);
- }
-}
-// Belows are without PSEUDO_BIOS, sometimes needs to use i386op16_real.cpp .
-void I386_OPS_BASE::I386OP(call_abs16)() // Opcode 0x9a
-{
- UINT16 offset = FETCH16();
- UINT16 ptr = FETCH16();
-
- if( PROTECTED_MODE && !V8086_MODE)
- {
- i386_protected_mode_call(ptr,offset,0,0);
- }
- else
- {
- PUSH16( cpustate->sreg[CS].selector );
- PUSH16( cpustate->eip );
- cpustate->sreg[CS].selector = ptr;
- cpustate->performed_intersegment_jump = 1;
- cpustate->eip = offset;
- i386_load_segment_descriptor(CS);
- }
- CYCLES(CYCLES_CALL_INTERSEG); /* TODO: Timing = 17 + m */
- CHANGE_PC(cpustate->eip);
-}
-
-void I386_OPS_BASE::I386OP(call_rel16)() // Opcode 0xe8
-{
- INT16 disp = FETCH16();
-
-
- PUSH16( cpustate->eip );
- if (cpustate->sreg[CS].d)
- {
- cpustate->eip += disp;
- }
- else
- {
- cpustate->eip = (cpustate->eip + disp) & 0xffff;
- }
- CHANGE_PC(cpustate->eip);
- CYCLES(CYCLES_CALL); /* TODO: Timing = 7 + m */
-}
-
-void I386_OPS_BASE::I386OP(cbw)() // Opcode 0x98
-{
- REG16(AX) = (INT16)((INT8)REG8(AL));
- CYCLES(CYCLES_CBW);
-}
-
-void I386_OPS_BASE::I386OP(cmp_rm16_r16)() // Opcode 0x39
-{
- UINT16 src, dst;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- src = LOAD_REG16(modrm);
- dst = LOAD_RM16(modrm);
- SUB16(dst, src);
- CYCLES(CYCLES_CMP_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,0);
- src = LOAD_REG16(modrm);
- dst = READ16(ea);
- SUB16(dst, src);
- CYCLES(CYCLES_CMP_REG_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(cmp_r16_rm16)() // Opcode 0x3b
-{
- UINT16 src, dst;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- src = LOAD_RM16(modrm);
- dst = LOAD_REG16(modrm);
- SUB16(dst, src);
- CYCLES(CYCLES_CMP_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,0);
- src = READ16(ea);
- dst = LOAD_REG16(modrm);
- SUB16(dst, src);
- CYCLES(CYCLES_CMP_MEM_REG);
- }
-}
-
-void I386_OPS_BASE::I386OP(cmp_ax_i16)() // Opcode 0x3d
-{
- UINT16 src, dst;
- src = FETCH16();
- dst = REG16(AX);
- SUB16(dst, src);
- CYCLES(CYCLES_CMP_IMM_ACC);
-}
-
-void I386_OPS_BASE::I386OP(cmpsw)() // Opcode 0xa7
-{
- UINT32 eas, ead;
- UINT16 src, dst;
- if( cpustate->segment_prefix ) {
- eas = i386_translate( cpustate->segment_override, cpustate->address_size ? REG32(ESI) : REG16(SI), 0 );
- } else {
- eas = i386_translate( DS, cpustate->address_size ? REG32(ESI) : REG16(SI), 0 );
- }
- ead = i386_translate( ES, cpustate->address_size ? REG32(EDI) : REG16(DI), 0 );
- src = READ16(eas);
- dst = READ16(ead);
- SUB16(src,dst);
- BUMP_SI(2);
- BUMP_DI(2);
- CYCLES(CYCLES_CMPS);
-}
-
-void I386_OPS_BASE::I386OP(cwd)() // Opcode 0x99
-{
- if( REG16(AX) & 0x8000 ) {
- REG16(DX) = 0xffff;
- } else {
- REG16(DX) = 0x0000;
- }
- CYCLES(CYCLES_CWD);
-}
-
-void I386_OPS_BASE::I386OP(dec_ax)() // Opcode 0x48
-{
- REG16(AX) = DEC16( REG16(AX) );
- CYCLES(CYCLES_DEC_REG);
-}
-
-void I386_OPS_BASE::I386OP(dec_cx)() // Opcode 0x49
-{
- REG16(CX) = DEC16( REG16(CX) );
- CYCLES(CYCLES_DEC_REG);
-}
-
-void I386_OPS_BASE::I386OP(dec_dx)() // Opcode 0x4a
-{
- REG16(DX) = DEC16( REG16(DX) );
- CYCLES(CYCLES_DEC_REG);
-}
-
-void I386_OPS_BASE::I386OP(dec_bx)() // Opcode 0x4b
-{
- REG16(BX) = DEC16( REG16(BX) );
- CYCLES(CYCLES_DEC_REG);
-}
-
-void I386_OPS_BASE::I386OP(dec_sp)() // Opcode 0x4c
-{
- REG16(SP) = DEC16( REG16(SP) );
- CYCLES(CYCLES_DEC_REG);
-}
-
-void I386_OPS_BASE::I386OP(dec_bp)() // Opcode 0x4d
-{
- REG16(BP) = DEC16( REG16(BP) );
- CYCLES(CYCLES_DEC_REG);
-}
-
-void I386_OPS_BASE::I386OP(dec_si)() // Opcode 0x4e
-{
- REG16(SI) = DEC16( REG16(SI) );
- CYCLES(CYCLES_DEC_REG);
-}
-
-void I386_OPS_BASE::I386OP(dec_di)() // Opcode 0x4f
-{
- REG16(DI) = DEC16( REG16(DI) );
- CYCLES(CYCLES_DEC_REG);
-}
-
-void I386_OPS_BASE::I386OP(imul_r16_rm16)() // Opcode 0x0f af
-{
- UINT8 modrm = FETCH();
- INT32 result;
- INT32 src, dst;
- if( modrm >= 0xc0 ) {
- src = (INT32)(INT16)LOAD_RM16(modrm);
- CYCLES(CYCLES_IMUL16_REG_REG); /* TODO: Correct multiply timing */
- } else {
- UINT32 ea = GetEA(modrm,0);
- src = (INT32)(INT16)READ16(ea);
- CYCLES(CYCLES_IMUL16_REG_MEM); /* TODO: Correct multiply timing */
- }
-
- dst = (INT32)(INT16)LOAD_REG16(modrm);
- result = src * dst;
-
- STORE_REG16(modrm, (UINT16)result);
-
- cpustate->CF = cpustate->OF = !(result == (INT32)(INT16)result);
-}
-
-void I386_OPS_BASE::I386OP(imul_r16_rm16_i16)() // Opcode 0x69
-{
- UINT8 modrm = FETCH();
- INT32 result;
- INT32 src, dst;
- if( modrm >= 0xc0 ) {
- dst = (INT32)(INT16)LOAD_RM16(modrm);
- CYCLES(CYCLES_IMUL16_REG_IMM_REG); /* TODO: Correct multiply timing */
- } else {
- UINT32 ea = GetEA(modrm,0);
- dst = (INT32)(INT16)READ16(ea);
- CYCLES(CYCLES_IMUL16_MEM_IMM_REG); /* TODO: Correct multiply timing */
- }
-
- src = (INT32)(INT16)FETCH16();
- result = src * dst;
-
- STORE_REG16(modrm, (UINT16)result);
-
- cpustate->CF = cpustate->OF = !(result == (INT32)(INT16)result);
-}
-
-void I386_OPS_BASE::I386OP(imul_r16_rm16_i8)() // Opcode 0x6b
-{
- UINT8 modrm = FETCH();
- INT32 result;
- INT32 src, dst;
- if( modrm >= 0xc0 ) {
- dst = (INT32)(INT16)LOAD_RM16(modrm);
- CYCLES(CYCLES_IMUL16_REG_IMM_REG); /* TODO: Correct multiply timing */
- } else {
- UINT32 ea = GetEA(modrm,0);
- dst = (INT32)(INT16)READ16(ea);
- CYCLES(CYCLES_IMUL16_MEM_IMM_REG); /* TODO: Correct multiply timing */
- }
-
- src = (INT32)(INT8)FETCH();
- result = src * dst;
-
- STORE_REG16(modrm, (UINT16)result);
-
- cpustate->CF = cpustate->OF = !(result == (INT32)(INT16)result);
-}
-
-void I386_OPS_BASE::I386OP(in_ax_i8)() // Opcode 0xe5
-{
- UINT16 port = FETCH();
- UINT16 data = READPORT16( port);
- REG16(AX) = data;
- CYCLES(CYCLES_IN_VAR);
-}
-
-void I386_OPS_BASE::I386OP(in_ax_dx)() // Opcode 0xed
-{
- UINT16 port = REG16(DX);
- UINT16 data = READPORT16( port);
- REG16(AX) = data;
- CYCLES(CYCLES_IN);
-}
-
-void I386_OPS_BASE::I386OP(inc_ax)() // Opcode 0x40
-{
- REG16(AX) = INC16( REG16(AX) );
- CYCLES(CYCLES_INC_REG);
-}
-
-void I386_OPS_BASE::I386OP(inc_cx)() // Opcode 0x41
-{
- REG16(CX) = INC16( REG16(CX) );
- CYCLES(CYCLES_INC_REG);
-}
-
-void I386_OPS_BASE::I386OP(inc_dx)() // Opcode 0x42
-{
- REG16(DX) = INC16( REG16(DX) );
- CYCLES(CYCLES_INC_REG);
-}
-
-void I386_OPS_BASE::I386OP(inc_bx)() // Opcode 0x43
-{
- REG16(BX) = INC16( REG16(BX) );
- CYCLES(CYCLES_INC_REG);
-}
-
-void I386_OPS_BASE::I386OP(inc_sp)() // Opcode 0x44
-{
- REG16(SP) = INC16( REG16(SP) );
- CYCLES(CYCLES_INC_REG);
-}
-
-void I386_OPS_BASE::I386OP(inc_bp)() // Opcode 0x45
-{
- REG16(BP) = INC16( REG16(BP) );
- CYCLES(CYCLES_INC_REG);
-}
-
-void I386_OPS_BASE::I386OP(inc_si)() // Opcode 0x46
-{
- REG16(SI) = INC16( REG16(SI) );
- CYCLES(CYCLES_INC_REG);
-}
-
-void I386_OPS_BASE::I386OP(inc_di)() // Opcode 0x47
-{
- REG16(DI) = INC16( REG16(DI) );
- CYCLES(CYCLES_INC_REG);
-}
-
-void I386_OPS_BASE::I386OP(iret16)() // Opcode 0xcf
-{
- if( PROTECTED_MODE )
- {
- i386_protected_mode_iret(0);
- }
- else
- {
- /* TODO: #SS(0) exception */
- /* TODO: #GP(0) exception */
- cpustate->eip = POP16();
- cpustate->sreg[CS].selector = POP16();
- set_flags( POP16() );
- i386_load_segment_descriptor(CS);
- CHANGE_PC(cpustate->eip);
- }
- CYCLES(CYCLES_IRET);
-}
-
-void I386_OPS_BASE::I386OP(ja_rel16)() // Opcode 0x0f 87
-{
- INT16 disp = FETCH16();
- if( cpustate->CF == 0 && cpustate->ZF == 0 ) {
- if (cpustate->sreg[CS].d)
- {
- cpustate->eip += disp;
- }
- else
- {
- cpustate->eip = (cpustate->eip + disp) & 0xffff;
- }
- CHANGE_PC(cpustate->eip);
- CYCLES(CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */
- } else {
- CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
- }
-}
-
-void I386_OPS_BASE::I386OP(jbe_rel16)() // Opcode 0x0f 86
-{
- INT16 disp = FETCH16();
- if( cpustate->CF != 0 || cpustate->ZF != 0 ) {
- if (cpustate->sreg[CS].d)
- {
- cpustate->eip += disp;
- }
- else
- {
- cpustate->eip = (cpustate->eip + disp) & 0xffff;
- }
- CHANGE_PC(cpustate->eip);
- CYCLES(CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */
- } else {
- CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
- }
-}
-
-void I386_OPS_BASE::I386OP(jc_rel16)() // Opcode 0x0f 82
-{
- INT16 disp = FETCH16();
- if( cpustate->CF != 0 ) {
- if (cpustate->sreg[CS].d)
- {
- cpustate->eip += disp;
- }
- else
- {
- cpustate->eip = (cpustate->eip + disp) & 0xffff;
- }
- CHANGE_PC(cpustate->eip);
- CYCLES(CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */
- } else {
- CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
- }
-}
-
-void I386_OPS_BASE::I386OP(jg_rel16)() // Opcode 0x0f 8f
-{
- INT16 disp = FETCH16();
- if( cpustate->ZF == 0 && (cpustate->SF == cpustate->OF) ) {
- if (cpustate->sreg[CS].d)
- {
- cpustate->eip += disp;
- }
- else
- {
- cpustate->eip = (cpustate->eip + disp) & 0xffff;
- }
- CHANGE_PC(cpustate->eip);
- CYCLES(CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */
- } else {
- CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
- }
-}
-
-void I386_OPS_BASE::I386OP(jge_rel16)() // Opcode 0x0f 8d
-{
- INT16 disp = FETCH16();
- if(cpustate->SF == cpustate->OF) {
- if (cpustate->sreg[CS].d)
- {
- cpustate->eip += disp;
- }
- else
- {
- cpustate->eip = (cpustate->eip + disp) & 0xffff;
- }
- CHANGE_PC(cpustate->eip);
- CYCLES(CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */
- } else {
- CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
- }
-}
-
-void I386_OPS_BASE::I386OP(jl_rel16)() // Opcode 0x0f 8c
-{
- INT16 disp = FETCH16();
- if( (cpustate->SF != cpustate->OF) ) {
- if (cpustate->sreg[CS].d)
- {
- cpustate->eip += disp;
- }
- else
- {
- cpustate->eip = (cpustate->eip + disp) & 0xffff;
- }
- CHANGE_PC(cpustate->eip);
- CYCLES(CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */
- } else {
- CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
- }
-}
-
-void I386_OPS_BASE::I386OP(jle_rel16)() // Opcode 0x0f 8e
-{
- INT16 disp = FETCH16();
- if( cpustate->ZF != 0 || (cpustate->SF != cpustate->OF) ) {
- if (cpustate->sreg[CS].d)
- {
- cpustate->eip += disp;
- }
- else
- {
- cpustate->eip = (cpustate->eip + disp) & 0xffff;
- }
- CHANGE_PC(cpustate->eip);
- CYCLES(CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */
- } else {
- CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
- }
-}
-
-void I386_OPS_BASE::I386OP(jnc_rel16)() // Opcode 0x0f 83
-{
- INT16 disp = FETCH16();
- if( cpustate->CF == 0 ) {
- if (cpustate->sreg[CS].d)
- {
- cpustate->eip += disp;
- }
- else
- {
- cpustate->eip = (cpustate->eip + disp) & 0xffff;
- }
- CHANGE_PC(cpustate->eip);
- CYCLES(CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */
- } else {
- CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
- }
-}
-
-void I386_OPS_BASE::I386OP(jno_rel16)() // Opcode 0x0f 81
-{
- INT16 disp = FETCH16();
- if( cpustate->OF == 0 ) {
- if (cpustate->sreg[CS].d)
- {
- cpustate->eip += disp;
- }
- else
- {
- cpustate->eip = (cpustate->eip + disp) & 0xffff;
- }
- CHANGE_PC(cpustate->eip);
- CYCLES(CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */
- } else {
- CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
- }
-}
-
-void I386_OPS_BASE::I386OP(jnp_rel16)() // Opcode 0x0f 8b
-{
- INT16 disp = FETCH16();
- if( cpustate->PF == 0 ) {
- if (cpustate->sreg[CS].d)
- {
- cpustate->eip += disp;
- }
- else
- {
- cpustate->eip = (cpustate->eip + disp) & 0xffff;
- }
- CHANGE_PC(cpustate->eip);
- CYCLES(CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */
- } else {
- CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
- }
-}
-
-void I386_OPS_BASE::I386OP(jns_rel16)() // Opcode 0x0f 89
-{
- INT16 disp = FETCH16();
- if( cpustate->SF == 0 ) {
- if (cpustate->sreg[CS].d)
- {
- cpustate->eip += disp;
- }
- else
- {
- cpustate->eip = (cpustate->eip + disp) & 0xffff;
- }
- CHANGE_PC(cpustate->eip);
- CYCLES(CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */
- } else {
- CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
- }
-}
-
-void I386_OPS_BASE::I386OP(jnz_rel16)() // Opcode 0x0f 85
-{
- INT16 disp = FETCH16();
- if( cpustate->ZF == 0 ) {
- if (cpustate->sreg[CS].d)
- {
- cpustate->eip += disp;
- }
- else
- {
- cpustate->eip = (cpustate->eip + disp) & 0xffff;
- }
- CHANGE_PC(cpustate->eip);
- CYCLES(CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */
- } else {
- CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
- }
-}
-
-void I386_OPS_BASE::I386OP(jo_rel16)() // Opcode 0x0f 80
-{
- INT16 disp = FETCH16();
- if( cpustate->OF != 0 ) {
- if (cpustate->sreg[CS].d)
- {
- cpustate->eip += disp;
- }
- else
- {
- cpustate->eip = (cpustate->eip + disp) & 0xffff;
- }
- CHANGE_PC(cpustate->eip);
- CYCLES(CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */
- } else {
- CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
- }
-}
-
-void I386_OPS_BASE::I386OP(jp_rel16)() // Opcode 0x0f 8a
-{
- INT16 disp = FETCH16();
- if( cpustate->PF != 0 ) {
- if (cpustate->sreg[CS].d)
- {
- cpustate->eip += disp;
- }
- else
- {
- cpustate->eip = (cpustate->eip + disp) & 0xffff;
- }
- CHANGE_PC(cpustate->eip);
- CYCLES(CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */
- } else {
- CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
- }
-}
-
-void I386_OPS_BASE::I386OP(js_rel16)() // Opcode 0x0f 88
-{
- INT16 disp = FETCH16();
- if( cpustate->SF != 0 ) {
- if (cpustate->sreg[CS].d)
- {
- cpustate->eip += disp;
- }
- else
- {
- cpustate->eip = (cpustate->eip + disp) & 0xffff;
- }
- CHANGE_PC(cpustate->eip);
- CYCLES(CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */
- } else {
- CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
- }
-}
-
-void I386_OPS_BASE::I386OP(jz_rel16)() // Opcode 0x0f 84
-{
- INT16 disp = FETCH16();
- if( cpustate->ZF != 0 ) {
- if (cpustate->sreg[CS].d)
- {
- cpustate->eip += disp;
- }
- else
- {
- cpustate->eip = (cpustate->eip + disp) & 0xffff;
- }
- CHANGE_PC(cpustate->eip);
- CYCLES(CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */
- } else {
- CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
- }
-}
-
-void I386_OPS_BASE::I386OP(jcxz16)() // Opcode 0xe3
-{
- INT8 disp = FETCH();
- int val = (cpustate->address_size)?(REG32(ECX) == 0):(REG16(CX) == 0);
- if( val ) {
- if (cpustate->sreg[CS].d)
- {
- cpustate->eip += disp;
- }
- else
- {
- cpustate->eip = (cpustate->eip + disp) & 0xffff;
- }
- CHANGE_PC(cpustate->eip);
- CYCLES(CYCLES_JCXZ); /* TODO: Timing = 9 + m */
- } else {
- CYCLES(CYCLES_JCXZ_NOBRANCH);
- }
-}
-
-void I386_OPS_BASE::I386OP(jmp_rel16)() // Opcode 0xe9
-{
- INT16 disp = FETCH16();
-
- if (cpustate->sreg[CS].d)
- {
- cpustate->eip += disp;
- }
- else
- {
- cpustate->eip = (cpustate->eip + disp) & 0xffff;
- }
- CHANGE_PC(cpustate->eip);
- CYCLES(CYCLES_JMP); /* TODO: Timing = 7 + m */
-}
-
-void I386_OPS_BASE::I386OP(jmp_abs16)() // Opcode 0xea
-{
- UINT16 address = FETCH16();
- UINT16 segment = FETCH16();
-
- if( PROTECTED_MODE && !V8086_MODE)
- {
- i386_protected_mode_jump(segment,address,0,0);
- }
- else
- {
- cpustate->eip = address;
- cpustate->sreg[CS].selector = segment;
- cpustate->performed_intersegment_jump = 1;
- i386_load_segment_descriptor(CS);
- CHANGE_PC(cpustate->eip);
- }
- CYCLES(CYCLES_JMP_INTERSEG);
-}
-
-void I386_OPS_BASE::I386OP(lea16)() // Opcode 0x8d
-{
- UINT8 modrm = FETCH();
- UINT32 ea = GetNonTranslatedEA(modrm,NULL);
- STORE_REG16(modrm, ea);
- CYCLES(CYCLES_LEA);
-}
-
-void I386_OPS_BASE::I386OP(enter16)() // Opcode 0xc8
-{
- UINT16 framesize = FETCH16();
- UINT8 level = FETCH() % 32;
- UINT8 x;
- UINT16 frameptr;
- PUSH16(REG16(BP));
-
- if(!STACK_32BIT)
- frameptr = REG16(SP);
- else
- frameptr = REG32(ESP);
-
- if(level > 0)
- {
- for(x=1;x<level-1;x++)
- {
- REG16(BP) -= 2;
- PUSH16(READ16(REG16(BP)));
- }
- PUSH16(frameptr);
- }
- REG16(BP) = frameptr;
- if(!STACK_32BIT)
- REG16(SP) -= framesize;
- else
- REG32(ESP) -= framesize;
- CYCLES(CYCLES_ENTER);
-}
-
-void I386_OPS_BASE::I386OP(leave16)() // Opcode 0xc9
-{
- if(!STACK_32BIT)
- REG16(SP) = REG16(BP);
- else
- REG32(ESP) = REG32(EBP);
- REG16(BP) = POP16();
- CYCLES(CYCLES_LEAVE);
-}
-
-void I386_OPS_BASE::I386OP(lodsw)() // Opcode 0xad
-{
- UINT32 eas;
- if( cpustate->segment_prefix ) {
- eas = i386_translate( cpustate->segment_override, cpustate->address_size ? REG32(ESI) : REG16(SI), 0 );
- } else {
- eas = i386_translate( DS, cpustate->address_size ? REG32(ESI) : REG16(SI), 0 );
- }
- REG16(AX) = READ16(eas);
- BUMP_SI(2);
- CYCLES(CYCLES_LODS);
-}
-
-void I386_OPS_BASE::I386OP(loop16)() // Opcode 0xe2
-{
- INT8 disp = FETCH();
- INT32 val = (cpustate->address_size)?(--REG32(ECX)):(--REG16(CX));
- if( val != 0 ) {
- if (cpustate->sreg[CS].d)
- {
- cpustate->eip += disp;
- }
- else
- {
- cpustate->eip = (cpustate->eip + disp) & 0xffff;
- }
- CHANGE_PC(cpustate->eip);
- }
- CYCLES(CYCLES_LOOP); /* TODO: Timing = 11 + m */
-}
-
-void I386_OPS_BASE::I386OP(loopne16)() // Opcode 0xe0
-{
- INT8 disp = FETCH();
- INT32 val = (cpustate->address_size)?(--REG32(ECX)):(--REG16(CX));
- if( val != 0 && cpustate->ZF == 0 ) {
- if (cpustate->sreg[CS].d)
- {
- cpustate->eip += disp;
- }
- else
- {
- cpustate->eip = (cpustate->eip + disp) & 0xffff;
- }
- CHANGE_PC(cpustate->eip);
- }
- CYCLES(CYCLES_LOOPNZ); /* TODO: Timing = 11 + m */
-}
-
-void I386_OPS_BASE::I386OP(loopz16)() // Opcode 0xe1
-{
- INT8 disp = FETCH();
- INT32 val = (cpustate->address_size)?(--REG32(ECX)):(--REG16(CX));
- if( val != 0 && cpustate->ZF != 0 ) {
- if (cpustate->sreg[CS].d)
- {
- cpustate->eip += disp;
- }
- else
- {
- cpustate->eip = (cpustate->eip + disp) & 0xffff;
- }
- CHANGE_PC(cpustate->eip);
- }
- CYCLES(CYCLES_LOOPZ); /* TODO: Timing = 11 + m */
-}
-
-void I386_OPS_BASE::I386OP(mov_rm16_r16)() // Opcode 0x89
-{
- UINT16 src;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- src = LOAD_REG16(modrm);
- STORE_RM16(modrm, src);
- CYCLES(CYCLES_MOV_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- src = LOAD_REG16(modrm);
- WRITE16(ea, src);
- CYCLES(CYCLES_MOV_REG_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(mov_r16_rm16)() // Opcode 0x8b
-{
- UINT16 src;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- src = LOAD_RM16(modrm);
- STORE_REG16(modrm, src);
- CYCLES(CYCLES_MOV_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,0);
- src = READ16(ea);
- STORE_REG16(modrm, src);
- CYCLES(CYCLES_MOV_MEM_REG);
- }
-}
-
-void I386_OPS_BASE::I386OP(mov_rm16_i16)() // Opcode 0xc7
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- UINT16 value = FETCH16();
- STORE_RM16(modrm, value);
- CYCLES(CYCLES_MOV_IMM_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- UINT16 value = FETCH16();
- WRITE16(ea, value);
- CYCLES(CYCLES_MOV_IMM_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(mov_ax_m16)() // Opcode 0xa1
-{
- UINT32 offset, ea;
- if( cpustate->address_size ) {
- offset = FETCH32();
- } else {
- offset = FETCH16();
- }
- /* TODO: Not sure if this is correct... */
- if( cpustate->segment_prefix ) {
- ea = i386_translate( cpustate->segment_override, offset, 0 );
- } else {
- ea = i386_translate( DS, offset, 0 );
- }
- REG16(AX) = READ16(ea);
- CYCLES(CYCLES_MOV_MEM_ACC);
-}
-
-void I386_OPS_BASE::I386OP(mov_m16_ax)() // Opcode 0xa3
-{
- UINT32 offset, ea;
- if( cpustate->address_size ) {
- offset = FETCH32();
- } else {
- offset = FETCH16();
- }
- /* TODO: Not sure if this is correct... */
- if( cpustate->segment_prefix ) {
- ea = i386_translate( cpustate->segment_override, offset, 1 );
- } else {
- ea = i386_translate( DS, offset, 1 );
- }
- WRITE16( ea, REG16(AX) );
- CYCLES(CYCLES_MOV_ACC_MEM);
-}
-
-void I386_OPS_BASE::I386OP(mov_ax_i16)() // Opcode 0xb8
-{
- REG16(AX) = FETCH16();
- CYCLES(CYCLES_MOV_IMM_REG);
-}
-
-void I386_OPS_BASE::I386OP(mov_cx_i16)() // Opcode 0xb9
-{
- REG16(CX) = FETCH16();
- CYCLES(CYCLES_MOV_IMM_REG);
-}
-
-void I386_OPS_BASE::I386OP(mov_dx_i16)() // Opcode 0xba
-{
- REG16(DX) = FETCH16();
- CYCLES(CYCLES_MOV_IMM_REG);
-}
-
-void I386_OPS_BASE::I386OP(mov_bx_i16)() // Opcode 0xbb
-{
- REG16(BX) = FETCH16();
- CYCLES(CYCLES_MOV_IMM_REG);
-}
-
-void I386_OPS_BASE::I386OP(mov_sp_i16)() // Opcode 0xbc
-{
- REG16(SP) = FETCH16();
- CYCLES(CYCLES_MOV_IMM_REG);
-}
-
-void I386_OPS_BASE::I386OP(mov_bp_i16)() // Opcode 0xbd
-{
- REG16(BP) = FETCH16();
- CYCLES(CYCLES_MOV_IMM_REG);
-}
-
-void I386_OPS_BASE::I386OP(mov_si_i16)() // Opcode 0xbe
-{
- REG16(SI) = FETCH16();
- CYCLES(CYCLES_MOV_IMM_REG);
-}
-
-void I386_OPS_BASE::I386OP(mov_di_i16)() // Opcode 0xbf
-{
- REG16(DI) = FETCH16();
- CYCLES(CYCLES_MOV_IMM_REG);
-}
-
-void I386_OPS_BASE::I386OP(movsw)() // Opcode 0xa5
-{
- UINT32 eas, ead;
- UINT16 v;
- if( cpustate->segment_prefix ) {
- eas = i386_translate( cpustate->segment_override, cpustate->address_size ? REG32(ESI) : REG16(SI), 0 );
- } else {
- eas = i386_translate( DS, cpustate->address_size ? REG32(ESI) : REG16(SI), 0 );
- }
- ead = i386_translate( ES, cpustate->address_size ? REG32(EDI) : REG16(DI), 1 );
- v = READ16(eas);
- WRITE16(ead, v);
- BUMP_SI(2);
- BUMP_DI(2);
- CYCLES(CYCLES_MOVS);
-}
-
-void I386_OPS_BASE::I386OP(movsx_r16_rm8)() // Opcode 0x0f be
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- INT16 src = (INT8)LOAD_RM8(modrm);
- STORE_REG16(modrm, src);
- CYCLES(CYCLES_MOVSX_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,0);
- INT16 src = (INT8)READ8(ea);
- STORE_REG16(modrm, src);
- CYCLES(CYCLES_MOVSX_MEM_REG);
- }
-}
-
-void I386_OPS_BASE::I386OP(movzx_r16_rm8)() // Opcode 0x0f b6
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- UINT16 src = (UINT8)LOAD_RM8(modrm);
- STORE_REG16(modrm, src);
- CYCLES(CYCLES_MOVZX_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,0);
- UINT16 src = (UINT8)READ8(ea);
- STORE_REG16(modrm, src);
- CYCLES(CYCLES_MOVZX_MEM_REG);
- }
-}
-
-void I386_OPS_BASE::I386OP(or_rm16_r16)() // Opcode 0x09
-{
- UINT16 src, dst;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- src = LOAD_REG16(modrm);
- dst = LOAD_RM16(modrm);
- dst = OR16(dst, src);
- STORE_RM16(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- src = LOAD_REG16(modrm);
- dst = READ16(ea);
- dst = OR16(dst, src);
- WRITE16(ea, dst);
- CYCLES(CYCLES_ALU_REG_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(or_r16_rm16)() // Opcode 0x0b
-{
- UINT16 src, dst;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- src = LOAD_RM16(modrm);
- dst = LOAD_REG16(modrm);
- dst = OR16(dst, src);
- STORE_REG16(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,0);
- src = READ16(ea);
- dst = LOAD_REG16(modrm);
- dst = OR16(dst, src);
- STORE_REG16(modrm, dst);
- CYCLES(CYCLES_ALU_MEM_REG);
- }
-}
-
-void I386_OPS_BASE::I386OP(or_ax_i16)() // Opcode 0x0d
-{
- UINT16 src, dst;
- src = FETCH16();
- dst = REG16(AX);
- dst = OR16(dst, src);
- REG16(AX) = dst;
- CYCLES(CYCLES_ALU_IMM_ACC);
-}
-
-void I386_OPS_BASE::I386OP(out_ax_i8)() // Opcode 0xe7
-{
- UINT16 port = FETCH();
- UINT16 data = REG16(AX);
- WRITEPORT16( port, data);
- CYCLES(CYCLES_OUT_VAR);
-}
-
-void I386_OPS_BASE::I386OP(out_ax_dx)() // Opcode 0xef
-{
- UINT16 port = REG16(DX);
- UINT16 data = REG16(AX);
- WRITEPORT16( port, data);
- CYCLES(CYCLES_OUT);
-}
-
-void I386_OPS_BASE::I386OP(pop_ax)() // Opcode 0x58
-{
- UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
- if(i386_limit_check(SS,offset+1) == 0)
- REG16(AX) = POP16();
- else
- FAULT(FAULT_SS,0)
- CYCLES(CYCLES_POP_REG_SHORT);
-}
-
-void I386_OPS_BASE::I386OP(pop_cx)() // Opcode 0x59
-{
- UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
- if(i386_limit_check(SS,offset+1) == 0)
- REG16(CX) = POP16();
- else
- FAULT(FAULT_SS,0)
- CYCLES(CYCLES_POP_REG_SHORT);
-}
-
-void I386_OPS_BASE::I386OP(pop_dx)() // Opcode 0x5a
-{
- UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
- if(i386_limit_check(SS,offset+1) == 0)
- REG16(DX) = POP16();
- else
- FAULT(FAULT_SS,0)
- CYCLES(CYCLES_POP_REG_SHORT);
-}
-
-void I386_OPS_BASE::I386OP(pop_bx)() // Opcode 0x5b
-{
- UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
- if(i386_limit_check(SS,offset+1) == 0)
- REG16(BX) = POP16();
- else
- FAULT(FAULT_SS,0)
- CYCLES(CYCLES_POP_REG_SHORT);
-}
-
-void I386_OPS_BASE::I386OP(pop_sp)() // Opcode 0x5c
-{
- UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
- if(i386_limit_check(SS,offset+1) == 0)
- REG16(SP) = POP16();
- else
- FAULT(FAULT_SS,0)
- CYCLES(CYCLES_POP_REG_SHORT);
-}
-
-void I386_OPS_BASE::I386OP(pop_bp)() // Opcode 0x5d
-{
- UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
- if(i386_limit_check(SS,offset+1) == 0)
- REG16(BP) = POP16();
- else
- FAULT(FAULT_SS,0)
- CYCLES(CYCLES_POP_REG_SHORT);
-}
-
-void I386_OPS_BASE::I386OP(pop_si)() // Opcode 0x5e
-{
- UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
- if(i386_limit_check(SS,offset+1) == 0)
- REG16(SI) = POP16();
- else
- FAULT(FAULT_SS,0)
- CYCLES(CYCLES_POP_REG_SHORT);
-}
-
-void I386_OPS_BASE::I386OP(pop_di)() // Opcode 0x5f
-{
- UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
- if(i386_limit_check(SS,offset+1) == 0)
- REG16(DI) = POP16();
- else
- FAULT(FAULT_SS,0)
- CYCLES(CYCLES_POP_REG_SHORT);
-}
-
-bool I386_OPS_BASE::I386OP(pop_seg16)( int segment)
-{
- UINT32 ea, offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
- UINT16 value;
- bool fault;
- if(i386_limit_check(SS,offset+1) == 0)
- {
- ea = i386_translate( SS, offset, 0);
- value = READ16( ea);
- i386_sreg_load(value, segment, &fault);
- if(fault) return false;
- if(STACK_32BIT)
- REG32(ESP) = offset + 2;
- else
- REG16(SP) = offset + 2;
- }
- else
- {
- cpustate->ext = 1;
- i386_trap_with_error(FAULT_SS,0,0,0);
- return false;
- }
- CYCLES(CYCLES_POP_SREG);
- return true;
-}
-
-void I386_OPS_BASE::I386OP(pop_ds16)() // Opcode 0x1f
-{
- I386OP(pop_seg16)( DS);
-}
-
-void I386_OPS_BASE::I386OP(pop_es16)() // Opcode 0x07
-{
- I386OP(pop_seg16)( ES);
-}
-
-void I386_OPS_BASE::I386OP(pop_fs16)() // Opcode 0x0f a1
-{
- I386OP(pop_seg16)( FS);
-}
-
-void I386_OPS_BASE::I386OP(pop_gs16)() // Opcode 0x0f a9
-{
- I386OP(pop_seg16)( GS);
-}
-
-void I386_OPS_BASE::I386OP(pop_ss16)() // Opcode 0x17
-{
- if(!I386OP(pop_seg16)( SS)) return;
- if(cpustate->IF != 0) // if external interrupts are enabled
- {
- cpustate->IF = 0; // reset IF for the next instruction
- cpustate->delayed_interrupt_enable = 1;
- }
-}
-
-void I386_OPS_BASE::I386OP(pop_rm16)() // Opcode 0x8f
-{
- UINT8 modrm = FETCH();
- UINT16 value;
- UINT32 ea, offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
-
- if(i386_limit_check(SS,offset+1) == 0)
- {
- UINT32 temp_sp = REG32(ESP);
- value = POP16();
-
- if( modrm >= 0xc0 ) {
- STORE_RM16(modrm, value);
- } else {
- ea = GetEA(modrm,1);
- try
- {
- WRITE16(ea, value);
- }
- catch(UINT64 e)
- {
- REG32(ESP) = temp_sp;
- throw e;
- }
- }
- }
- else
- FAULT(FAULT_SS,0)
- CYCLES(CYCLES_POP_RM);
-}
-
-void I386_OPS_BASE::I386OP(popa)() // Opcode 0x61
-{
- UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
-
- if(i386_limit_check(SS,offset+15) == 0)
- {
- REG16(DI) = POP16();
- REG16(SI) = POP16();
- REG16(BP) = POP16();
- REG16(SP) += 2;
- REG16(BX) = POP16();
- REG16(DX) = POP16();
- REG16(CX) = POP16();
- REG16(AX) = POP16();
- }
- else
- FAULT(FAULT_SS,0)
- CYCLES(CYCLES_POPA);
-}
-
-void I386_OPS_BASE::I386OP(popf)() // Opcode 0x9d
-{
- UINT32 value;
- UINT32 current = get_flags();
- UINT8 IOPL = (current >> 12) & 0x03;
- UINT32 mask = 0x7fd5;
- UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
-
- // IOPL can only change if CPL is 0
- if(cpustate->CPL != 0)
- mask &= ~0x00003000;
-
- // IF can only change if CPL is at least as privileged as IOPL
- if(cpustate->CPL > IOPL)
- mask &= ~0x00000200;
-
- if(V8086_MODE)
- {
- if(IOPL < 3)
- {
- logerror("POPFD(%08x): IOPL < 3 while in V86 mode.\n",cpustate->pc);
- FAULT(FAULT_GP,0) // #GP(0)
- }
- mask &= ~0x00003000; // IOPL cannot be changed while in V8086 mode
- }
-
- if(i386_limit_check(SS,offset+1) == 0)
- {
- value = POP16();
- set_flags((current & ~mask) | (value & mask)); // mask out reserved bits
- }
- else
- FAULT(FAULT_SS,0)
- CYCLES(CYCLES_POPF);
-}
-
-void I386_OPS_BASE::I386OP(push_ax)() // Opcode 0x50
-{
- UINT32 offset;
- if(STACK_32BIT)
- offset = REG32(ESP) - 2;
- else
- offset = (REG16(SP) - 2) & 0xffff;
- if(i386_limit_check(SS,offset) == 0)
- PUSH16( REG16(AX) );
- else
- FAULT(FAULT_SS,0)
- CYCLES(CYCLES_PUSH_REG_SHORT);
-}
-
-void I386_OPS_BASE::I386OP(push_cx)() // Opcode 0x51
-{
- UINT32 offset;
- if(STACK_32BIT)
- offset = REG32(ESP) - 2;
- else
- offset = (REG16(SP) - 2) & 0xffff;
- if(i386_limit_check(SS,offset) == 0)
- PUSH16( REG16(CX) );
- else
- FAULT(FAULT_SS,0)
- CYCLES(CYCLES_PUSH_REG_SHORT);
-}
-
-void I386_OPS_BASE::I386OP(push_dx)() // Opcode 0x52
-{
- UINT32 offset;
- if(STACK_32BIT)
- offset = REG32(ESP) - 2;
- else
- offset = (REG16(SP) - 2) & 0xffff;
- if(i386_limit_check(SS,offset) == 0)
- PUSH16( REG16(DX) );
- else
- FAULT(FAULT_SS,0)
- CYCLES(CYCLES_PUSH_REG_SHORT);
-}
-
-void I386_OPS_BASE::I386OP(push_bx)() // Opcode 0x53
-{
- UINT32 offset;
- if(STACK_32BIT)
- offset = REG32(ESP) - 2;
- else
- offset = (REG16(SP) - 2) & 0xffff;
- if(i386_limit_check(SS,offset) == 0)
- PUSH16( REG16(BX) );
- else
- FAULT(FAULT_SS,0)
- CYCLES(CYCLES_PUSH_REG_SHORT);
-}
-
-void I386_OPS_BASE::I386OP(push_sp)() // Opcode 0x54
-{
- UINT32 offset;
- if(STACK_32BIT)
- offset = REG32(ESP) - 2;
- else
- offset = (REG16(SP) - 2) & 0xffff;
- if(i386_limit_check(SS,offset) == 0)
- PUSH16( REG16(SP) );
- else
- FAULT(FAULT_SS,0)
- CYCLES(CYCLES_PUSH_REG_SHORT);
-}
-
-void I386_OPS_BASE::I386OP(push_bp)() // Opcode 0x55
-{
- UINT32 offset;
- if(STACK_32BIT)
- offset = REG32(ESP) - 2;
- else
- offset = (REG16(SP) - 2) & 0xffff;
- if(i386_limit_check(SS,offset) == 0)
- PUSH16( REG16(BP) );
- else
- FAULT(FAULT_SS,0)
- CYCLES(CYCLES_PUSH_REG_SHORT);
-}
-
-void I386_OPS_BASE::I386OP(push_si)() // Opcode 0x56
-{
- UINT32 offset;
- if(STACK_32BIT)
- offset = REG32(ESP) - 2;
- else
- offset = (REG16(SP) - 2) & 0xffff;
- if(i386_limit_check(SS,offset) == 0)
- PUSH16( REG16(SI) );
- else
- FAULT(FAULT_SS,0)
- CYCLES(CYCLES_PUSH_REG_SHORT);
-}
-
-void I386_OPS_BASE::I386OP(push_di)() // Opcode 0x57
-{
- UINT32 offset;
- if(STACK_32BIT)
- offset = REG32(ESP) - 2;
- else
- offset = (REG16(SP) - 2) & 0xffff;
- if(i386_limit_check(SS,offset) == 0)
- PUSH16( REG16(DI) );
- else
- FAULT(FAULT_SS,0)
- CYCLES(CYCLES_PUSH_REG_SHORT);
-}
-
-void I386_OPS_BASE::I386OP(push_cs16)() // Opcode 0x0e
-{
- UINT32 offset;
- if(STACK_32BIT)
- offset = REG32(ESP) - 2;
- else
- offset = (REG16(SP) - 2) & 0xffff;
- if(i386_limit_check(SS,offset) == 0)
- PUSH16( cpustate->sreg[CS].selector );
- else
- FAULT(FAULT_SS,0)
- CYCLES(CYCLES_PUSH_SREG);
-}
-
-void I386_OPS_BASE::I386OP(push_ds16)() // Opcode 0x1e
-{
- UINT32 offset;
- if(STACK_32BIT)
- offset = REG32(ESP) - 2;
- else
- offset = (REG16(SP) - 2) & 0xffff;
- if(i386_limit_check(SS,offset) == 0)
- PUSH16( cpustate->sreg[DS].selector );
- else
- FAULT(FAULT_SS,0)
- CYCLES(CYCLES_PUSH_SREG);
-}
-
-void I386_OPS_BASE::I386OP(push_es16)() // Opcode 0x06
-{
- UINT32 offset;
- if(STACK_32BIT)
- offset = REG32(ESP) - 2;
- else
- offset = (REG16(SP) - 2) & 0xffff;
- if(i386_limit_check(SS,offset) == 0)
- PUSH16( cpustate->sreg[ES].selector );
- else
- FAULT(FAULT_SS,0)
- CYCLES(CYCLES_PUSH_SREG);
-}
-
-void I386_OPS_BASE::I386OP(push_fs16)() // Opcode 0x0f a0
-{
- UINT32 offset;
- if(STACK_32BIT)
- offset = REG32(ESP) - 2;
- else
- offset = (REG16(SP) - 2) & 0xffff;
- if(i386_limit_check(SS,offset) == 0)
- PUSH16( cpustate->sreg[FS].selector );
- else
- FAULT(FAULT_SS,0)
- CYCLES(CYCLES_PUSH_SREG);
-}
-
-void I386_OPS_BASE::I386OP(push_gs16)() // Opcode 0x0f a8
-{
- UINT32 offset;
- if(STACK_32BIT)
- offset = REG32(ESP) - 2;
- else
- offset = (REG16(SP) - 2) & 0xffff;
- if(i386_limit_check(SS,offset) == 0)
- PUSH16( cpustate->sreg[GS].selector );
- else
- FAULT(FAULT_SS,0)
- CYCLES(CYCLES_PUSH_SREG);
-}
-
-void I386_OPS_BASE::I386OP(push_ss16)() // Opcode 0x16
-{
- UINT32 offset;
- if(STACK_32BIT)
- offset = REG32(ESP) - 2;
- else
- offset = (REG16(SP) - 2) & 0xffff;
- if(i386_limit_check(SS,offset) == 0)
- PUSH16( cpustate->sreg[SS].selector );
- else
- FAULT(FAULT_SS,0)
- CYCLES(CYCLES_PUSH_SREG);
-}
-
-void I386_OPS_BASE::I386OP(push_i16)() // Opcode 0x68
-{
- UINT16 value = FETCH16();
- UINT32 offset;
- if(STACK_32BIT)
- offset = REG32(ESP) - 2;
- else
- offset = (REG16(SP) - 2) & 0xffff;
- if(i386_limit_check(SS,offset) == 0)
- PUSH16(value);
- else
- FAULT(FAULT_SS,0)
- CYCLES(CYCLES_PUSH_IMM);
-}
-
-void I386_OPS_BASE::I386OP(pusha)() // Opcode 0x60
-{
- UINT16 temp = REG16(SP);
- UINT32 offset;
- if(STACK_32BIT)
- offset = REG32(ESP) - 16;
- else
- offset = (REG16(SP) - 16) & 0xffff;
- if(i386_limit_check(SS,offset) == 0)
- {
- PUSH16( REG16(AX) );
- PUSH16( REG16(CX) );
- PUSH16( REG16(DX) );
- PUSH16( REG16(BX) );
- PUSH16( temp );
- PUSH16( REG16(BP) );
- PUSH16( REG16(SI) );
- PUSH16( REG16(DI) );
- }
- else
- FAULT(FAULT_SS,0)
- CYCLES(CYCLES_PUSHA);
-}
-
-void I386_OPS_BASE::I386OP(pushf)() // Opcode 0x9c
-{
- UINT32 offset;
- if(STACK_32BIT)
- offset = REG32(ESP) - 2;
- else
- offset = (REG16(SP) - 2) & 0xffff;
- if(i386_limit_check(SS,offset) == 0)
- PUSH16( get_flags() & 0xffff );
- else
- FAULT(FAULT_SS,0)
- CYCLES(CYCLES_PUSHF);
-}
-
-void I386_OPS_BASE::I386OP(ret_near16_i16)() // Opcode 0xc2
-{
- INT16 disp = FETCH16();
- cpustate->eip = POP16();
- REG16(SP) += disp;
- CHANGE_PC(cpustate->eip);
- CYCLES(CYCLES_RET_IMM); /* TODO: Timing = 10 + m */
-}
-
-void I386_OPS_BASE::I386OP(ret_near16)() // Opcode 0xc3
-{
- cpustate->eip = POP16();
- CHANGE_PC(cpustate->eip);
- CYCLES(CYCLES_RET); /* TODO: Timing = 10 + m */
-}
-
-void I386_OPS_BASE::I386OP(sbb_rm16_r16)() // Opcode 0x19
-{
- UINT16 src, dst;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- src = LOAD_REG16(modrm);
- dst = LOAD_RM16(modrm);
- dst = SBB16( dst, src, cpustate->CF);
- STORE_RM16(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- src = LOAD_REG16(modrm);
- dst = READ16(ea);
- dst = SBB16( dst, src, cpustate->CF);
- WRITE16(ea, dst);
- CYCLES(CYCLES_ALU_REG_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(sbb_r16_rm16)() // Opcode 0x1b
-{
- UINT16 src, dst;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- src = LOAD_RM16(modrm);
- dst = LOAD_REG16(modrm);
- dst = SBB16( dst, src, cpustate->CF);
- STORE_REG16(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,0);
- src = READ16(ea);
- dst = LOAD_REG16(modrm);
- dst = SBB16( dst, src, cpustate->CF);
- STORE_REG16(modrm, dst);
- CYCLES(CYCLES_ALU_MEM_REG);
- }
-}
-
-void I386_OPS_BASE::I386OP(sbb_ax_i16)() // Opcode 0x1d
-{
- UINT16 src, dst;
- src = FETCH16();
- dst = REG16(AX);
- dst = SBB16( dst, src, cpustate->CF);
- REG16(AX) = dst;
- CYCLES(CYCLES_ALU_IMM_ACC);
-}
-
-void I386_OPS_BASE::I386OP(scasw)() // Opcode 0xaf
-{
- UINT32 eas;
- UINT16 src, dst;
- eas = i386_translate( ES, cpustate->address_size ? REG32(EDI) : REG16(DI), 0 );
- src = READ16(eas);
- dst = REG16(AX);
- SUB16(dst, src);
- BUMP_DI(2);
- CYCLES(CYCLES_SCAS);
-}
-
-void I386_OPS_BASE::I386OP(shld16_i8)() // Opcode 0x0f a4
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- UINT16 dst = LOAD_RM16(modrm);
- UINT16 upper = LOAD_REG16(modrm);
- UINT8 shift = FETCH();
- shift &= 31;
- if( shift == 0 ) {
- } else if( shift > 15 ) {
- cpustate->CF = (upper & (1 << (16-shift))) ? 1 : 0;
- // ppro and above should be (dst >> (32-shift))
- dst = (upper << (shift-16)) | (upper >> (32-shift));
- cpustate->OF = cpustate->CF ^ (dst >> 15);
- SetSZPF16(dst);
- } else {
- cpustate->CF = (dst & (1 << (16-shift))) ? 1 : 0;
- dst = (dst << shift) | (upper >> (16-shift));
- cpustate->OF = cpustate->CF ^ (dst >> 15);
- SetSZPF16(dst);
- }
- STORE_RM16(modrm, dst);
- CYCLES(CYCLES_SHLD_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- UINT16 dst = READ16(ea);
- UINT16 upper = LOAD_REG16(modrm);
- UINT8 shift = FETCH();
- shift &= 31;
- if( shift == 0 ) {
- } else if( shift > 15 ) {
- cpustate->CF = (upper & (1 << (16-shift))) ? 1 : 0;
- dst = (upper << (shift-16)) | (upper >> (32-shift));
- cpustate->OF = cpustate->CF ^ (dst >> 15);
- SetSZPF16(dst);
- } else {
- cpustate->CF = (dst & (1 << (16-shift))) ? 1 : 0;
- dst = (dst << shift) | (upper >> (16-shift));
- cpustate->OF = cpustate->CF ^ (dst >> 15);
- SetSZPF16(dst);
- }
- WRITE16(ea, dst);
- CYCLES(CYCLES_SHLD_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(shld16_cl)() // Opcode 0x0f a5
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- UINT16 dst = LOAD_RM16(modrm);
- UINT16 upper = LOAD_REG16(modrm);
- UINT8 shift = REG8(CL);
- shift &= 31;
- if( shift == 0 ) {
- } else if( shift > 15 ) {
- cpustate->CF = (upper & (1 << (16-shift))) ? 1 : 0;
- dst = (upper << (shift-16)) | (upper >> (32-shift));
- cpustate->OF = cpustate->CF ^ (dst >> 15);
- SetSZPF16(dst);
- } else {
- cpustate->CF = (dst & (1 << (16-shift))) ? 1 : 0;
- dst = (dst << shift) | (upper >> (16-shift));
- cpustate->OF = cpustate->CF ^ (dst >> 15);
- SetSZPF16(dst);
- }
- STORE_RM16(modrm, dst);
- CYCLES(CYCLES_SHLD_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- UINT16 dst = READ16(ea);
- UINT16 upper = LOAD_REG16(modrm);
- UINT8 shift = REG8(CL);
- shift &= 31;
- if( shift == 0 ) {
- } else if( shift > 15 ) {
- cpustate->CF = (upper & (1 << (16-shift))) ? 1 : 0;
- dst = (upper << (shift-16)) | (upper >> (32-shift));
- cpustate->OF = cpustate->CF ^ (dst >> 15);
- SetSZPF16(dst);
- } else {
- cpustate->CF = (dst & (1 << (16-shift))) ? 1 : 0;
- dst = (dst << shift) | (upper >> (16-shift));
- cpustate->OF = cpustate->CF ^ (dst >> 15);
- SetSZPF16(dst);
- }
- WRITE16(ea, dst);
- CYCLES(CYCLES_SHLD_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(shrd16_i8)() // Opcode 0x0f ac
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- UINT16 dst = LOAD_RM16(modrm);
- UINT16 upper = LOAD_REG16(modrm);
- UINT8 shift = FETCH();
- shift &= 31;
- if( shift == 0) {
- } else if( shift > 15 ) {
- cpustate->CF = (upper & (1 << (shift-1))) ? 1 : 0;
- dst = (upper >> (shift-16)) | (upper << (32-shift));
- cpustate->OF = ((dst >> 15) ^ (dst >> 14)) & 1;
- SetSZPF16(dst);
- } else {
- cpustate->CF = (dst & (1 << (shift-1))) ? 1 : 0;
- dst = (dst >> shift) | (upper << (16-shift));
- cpustate->OF = ((dst >> 15) ^ (dst >> 14)) & 1;
- SetSZPF16(dst);
- }
- STORE_RM16(modrm, dst);
- CYCLES(CYCLES_SHRD_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- UINT16 dst = READ16(ea);
- UINT16 upper = LOAD_REG16(modrm);
- UINT8 shift = FETCH();
- shift &= 31;
- if( shift == 0) {
- } else if( shift > 15 ) {
- cpustate->CF = (upper & (1 << (shift-1))) ? 1 : 0;
- dst = (upper >> (shift-16)) | (upper << (32-shift));
- cpustate->OF = ((dst >> 15) ^ (dst >> 14)) & 1;
- SetSZPF16(dst);
- } else {
- cpustate->CF = (dst & (1 << (shift-1))) ? 1 : 0;
- dst = (dst >> shift) | (upper << (16-shift));
- cpustate->OF = ((dst >> 15) ^ (dst >> 14)) & 1;
- SetSZPF16(dst);
- }
- WRITE16(ea, dst);
- CYCLES(CYCLES_SHRD_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(shrd16_cl)() // Opcode 0x0f ad
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- UINT16 dst = LOAD_RM16(modrm);
- UINT16 upper = LOAD_REG16(modrm);
- UINT8 shift = REG8(CL);
- shift &= 31;
- if( shift == 0) {
- } else if( shift > 15 ) {
- cpustate->CF = (upper & (1 << (shift-1))) ? 1 : 0;
- dst = (upper >> (shift-16)) | (upper << (32-shift));
- cpustate->OF = ((dst >> 15) ^ (dst >> 14)) & 1;
- SetSZPF16(dst);
- } else {
- cpustate->CF = (dst & (1 << (shift-1))) ? 1 : 0;
- dst = (dst >> shift) | (upper << (16-shift));
- cpustate->OF = ((dst >> 15) ^ (dst >> 14)) & 1;
- SetSZPF16(dst);
- }
- STORE_RM16(modrm, dst);
- CYCLES(CYCLES_SHRD_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- UINT16 dst = READ16(ea);
- UINT16 upper = LOAD_REG16(modrm);
- UINT8 shift = REG8(CL);
- shift &= 31;
- if( shift == 0) {
- } else if( shift > 15 ) {
- cpustate->CF = (upper & (1 << (shift-1))) ? 1 : 0;
- dst = (upper >> (shift-16)) | (upper << (32-shift));
- cpustate->OF = ((dst >> 15) ^ (dst >> 14)) & 1;
- SetSZPF16(dst);
- } else {
- cpustate->CF = (dst & (1 << (shift-1))) ? 1 : 0;
- dst = (dst >> shift) | (upper << (16-shift));
- cpustate->OF = ((dst >> 15) ^ (dst >> 14)) & 1;
- SetSZPF16(dst);
- }
- WRITE16(ea, dst);
- CYCLES(CYCLES_SHRD_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(stosw)() // Opcode 0xab
-{
- UINT32 ead;
- ead = i386_translate( ES, cpustate->address_size ? REG32(EDI) : REG16(DI), 1 );
- WRITE16(ead, REG16(AX));
- BUMP_DI(2);
- CYCLES(CYCLES_STOS);
-}
-
-void I386_OPS_BASE::I386OP(sub_rm16_r16)() // Opcode 0x29
-{
- UINT16 src, dst;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- src = LOAD_REG16(modrm);
- dst = LOAD_RM16(modrm);
- dst = SUB16(dst, src);
- STORE_RM16(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- src = LOAD_REG16(modrm);
- dst = READ16(ea);
- dst = SUB16(dst, src);
- WRITE16(ea, dst);
- CYCLES(CYCLES_ALU_REG_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(sub_r16_rm16)() // Opcode 0x2b
-{
- UINT16 src, dst;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- src = LOAD_RM16(modrm);
- dst = LOAD_REG16(modrm);
- dst = SUB16(dst, src);
- STORE_REG16(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,0);
- src = READ16(ea);
- dst = LOAD_REG16(modrm);
- dst = SUB16(dst, src);
- STORE_REG16(modrm, dst);
- CYCLES(CYCLES_ALU_MEM_REG);
- }
-}
-
-void I386_OPS_BASE::I386OP(sub_ax_i16)() // Opcode 0x2d
-{
- UINT16 src, dst;
- src = FETCH16();
- dst = REG16(AX);
- dst = SUB16(dst, src);
- REG16(AX) = dst;
- CYCLES(CYCLES_ALU_IMM_ACC);
-}
-
-void I386_OPS_BASE::I386OP(test_ax_i16)() // Opcode 0xa9
-{
- UINT16 src = FETCH16();
- UINT16 dst = REG16(AX);
- dst = src & dst;
- SetSZPF16(dst);
- cpustate->CF = 0;
- cpustate->OF = 0;
- CYCLES(CYCLES_TEST_IMM_ACC);
-}
-
-void I386_OPS_BASE::I386OP(test_rm16_r16)() // Opcode 0x85
-{
- UINT16 src, dst;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- src = LOAD_REG16(modrm);
- dst = LOAD_RM16(modrm);
- dst = src & dst;
- SetSZPF16(dst);
- cpustate->CF = 0;
- cpustate->OF = 0;
- CYCLES(CYCLES_TEST_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,0);
- src = LOAD_REG16(modrm);
- dst = READ16(ea);
- dst = src & dst;
- SetSZPF16(dst);
- cpustate->CF = 0;
- cpustate->OF = 0;
- CYCLES(CYCLES_TEST_REG_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(xchg_ax_cx)() // Opcode 0x91
-{
- UINT16 temp;
- temp = REG16(AX);
- REG16(AX) = REG16(CX);
- REG16(CX) = temp;
- CYCLES(CYCLES_XCHG_REG_REG);
-}
-
-void I386_OPS_BASE::I386OP(xchg_ax_dx)() // Opcode 0x92
-{
- UINT16 temp;
- temp = REG16(AX);
- REG16(AX) = REG16(DX);
- REG16(DX) = temp;
- CYCLES(CYCLES_XCHG_REG_REG);
-}
-
-void I386_OPS_BASE::I386OP(xchg_ax_bx)() // Opcode 0x93
-{
- UINT16 temp;
- temp = REG16(AX);
- REG16(AX) = REG16(BX);
- REG16(BX) = temp;
- CYCLES(CYCLES_XCHG_REG_REG);
-}
-
-void I386_OPS_BASE::I386OP(xchg_ax_sp)() // Opcode 0x94
-{
- UINT16 temp;
- temp = REG16(AX);
- REG16(AX) = REG16(SP);
- REG16(SP) = temp;
- CYCLES(CYCLES_XCHG_REG_REG);
-}
-
-void I386_OPS_BASE::I386OP(xchg_ax_bp)() // Opcode 0x95
-{
- UINT16 temp;
- temp = REG16(AX);
- REG16(AX) = REG16(BP);
- REG16(BP) = temp;
- CYCLES(CYCLES_XCHG_REG_REG);
-}
-
-void I386_OPS_BASE::I386OP(xchg_ax_si)() // Opcode 0x96
-{
- UINT16 temp;
- temp = REG16(AX);
- REG16(AX) = REG16(SI);
- REG16(SI) = temp;
- CYCLES(CYCLES_XCHG_REG_REG);
-}
-
-void I386_OPS_BASE::I386OP(xchg_ax_di)() // Opcode 0x97
-{
- UINT16 temp;
- temp = REG16(AX);
- REG16(AX) = REG16(DI);
- REG16(DI) = temp;
- CYCLES(CYCLES_XCHG_REG_REG);
-}
-
-void I386_OPS_BASE::I386OP(xchg_r16_rm16)() // Opcode 0x87
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- UINT16 src = LOAD_RM16(modrm);
- UINT16 dst = LOAD_REG16(modrm);
- STORE_REG16(modrm, src);
- STORE_RM16(modrm, dst);
- CYCLES(CYCLES_XCHG_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- UINT16 src = READ16(ea);
- UINT16 dst = LOAD_REG16(modrm);
- STORE_REG16(modrm, src);
- WRITE16(ea, dst);
- CYCLES(CYCLES_XCHG_REG_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(xor_rm16_r16)() // Opcode 0x31
-{
- UINT16 src, dst;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- src = LOAD_REG16(modrm);
- dst = LOAD_RM16(modrm);
- dst = XOR16(dst, src);
- STORE_RM16(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- src = LOAD_REG16(modrm);
- dst = READ16(ea);
- dst = XOR16(dst, src);
- WRITE16(ea, dst);
- CYCLES(CYCLES_ALU_REG_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(xor_r16_rm16)() // Opcode 0x33
-{
- UINT16 src, dst;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- src = LOAD_RM16(modrm);
- dst = LOAD_REG16(modrm);
- dst = XOR16(dst, src);
- STORE_REG16(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,0);
- src = READ16(ea);
- dst = LOAD_REG16(modrm);
- dst = XOR16(dst, src);
- STORE_REG16(modrm, dst);
- CYCLES(CYCLES_ALU_MEM_REG);
- }
-}
-
-void I386_OPS_BASE::I386OP(xor_ax_i16)() // Opcode 0x35
-{
- UINT16 src, dst;
- src = FETCH16();
- dst = REG16(AX);
- dst = XOR16(dst, src);
- REG16(AX) = dst;
- CYCLES(CYCLES_ALU_IMM_ACC);
-}
-
-
-
-void I386_OPS_BASE::I386OP(group81_16)() // Opcode 0x81
-{
- UINT32 ea;
- UINT16 src, dst;
- UINT8 modrm = FETCH();
-
- switch( (modrm >> 3) & 0x7 )
- {
- case 0: // ADD Rm16, i16
- if( modrm >= 0xc0 ) {
- dst = LOAD_RM16(modrm);
- src = FETCH16();
- dst = ADD16(dst, src);
- STORE_RM16(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- ea = GetEA(modrm,1);
- dst = READ16(ea);
- src = FETCH16();
- dst = ADD16(dst, src);
- WRITE16(ea, dst);
- CYCLES(CYCLES_ALU_REG_MEM);
- }
- break;
- case 1: // OR Rm16, i16
- if( modrm >= 0xc0 ) {
- dst = LOAD_RM16(modrm);
- src = FETCH16();
- dst = OR16(dst, src);
- STORE_RM16(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- ea = GetEA(modrm,1);
- dst = READ16(ea);
- src = FETCH16();
- dst = OR16(dst, src);
- WRITE16(ea, dst);
- CYCLES(CYCLES_ALU_REG_MEM);
- }
- break;
- case 2: // ADC Rm16, i16
- if( modrm >= 0xc0 ) {
- dst = LOAD_RM16(modrm);
- src = FETCH16();
- dst = ADC16( dst, src, cpustate->CF);
- STORE_RM16(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- ea = GetEA(modrm,1);
- dst = READ16(ea);
- src = FETCH16();
- dst = ADC16( dst, src, cpustate->CF);
- WRITE16(ea, dst);
- CYCLES(CYCLES_ALU_REG_MEM);
- }
- break;
- case 3: // SBB Rm16, i16
- if( modrm >= 0xc0 ) {
- dst = LOAD_RM16(modrm);
- src = FETCH16();
- dst = SBB16( dst, src, cpustate->CF);
- STORE_RM16(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- ea = GetEA(modrm,1);
- dst = READ16(ea);
- src = FETCH16();
- dst = SBB16( dst, src, cpustate->CF);
- WRITE16(ea, dst);
- CYCLES(CYCLES_ALU_REG_MEM);
- }
- break;
- case 4: // AND Rm16, i16
- if( modrm >= 0xc0 ) {
- dst = LOAD_RM16(modrm);
- src = FETCH16();
- dst = AND16(dst, src);
- STORE_RM16(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- ea = GetEA(modrm,1);
- dst = READ16(ea);
- src = FETCH16();
- dst = AND16(dst, src);
- WRITE16(ea, dst);
- CYCLES(CYCLES_ALU_REG_MEM);
- }
- break;
- case 5: // SUB Rm16, i16
- if( modrm >= 0xc0 ) {
- dst = LOAD_RM16(modrm);
- src = FETCH16();
- dst = SUB16(dst, src);
- STORE_RM16(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- ea = GetEA(modrm,1);
- dst = READ16(ea);
- src = FETCH16();
- dst = SUB16(dst, src);
- WRITE16(ea, dst);
- CYCLES(CYCLES_ALU_REG_MEM);
- }
- break;
- case 6: // XOR Rm16, i16
- if( modrm >= 0xc0 ) {
- dst = LOAD_RM16(modrm);
- src = FETCH16();
- dst = XOR16(dst, src);
- STORE_RM16(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- ea = GetEA(modrm,1);
- dst = READ16(ea);
- src = FETCH16();
- dst = XOR16(dst, src);
- WRITE16(ea, dst);
- CYCLES(CYCLES_ALU_REG_MEM);
- }
- break;
- case 7: // CMP Rm16, i16
- if( modrm >= 0xc0 ) {
- dst = LOAD_RM16(modrm);
- src = FETCH16();
- SUB16(dst, src);
- CYCLES(CYCLES_CMP_REG_REG);
- } else {
- ea = GetEA(modrm,0);
- dst = READ16(ea);
- src = FETCH16();
- SUB16(dst, src);
- CYCLES(CYCLES_CMP_REG_MEM);
- }
- break;
- }
-}
-
-void I386_OPS_BASE::I386OP(group83_16)() // Opcode 0x83
-{
- UINT32 ea;
- UINT16 src, dst;
- UINT8 modrm = FETCH();
-
- switch( (modrm >> 3) & 0x7 )
- {
- case 0: // ADD Rm16, i16
- if( modrm >= 0xc0 ) {
- dst = LOAD_RM16(modrm);
- src = (UINT16)(INT16)(INT8)FETCH();
- dst = ADD16(dst, src);
- STORE_RM16(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- ea = GetEA(modrm,1);
- dst = READ16(ea);
- src = (UINT16)(INT16)(INT8)FETCH();
- dst = ADD16(dst, src);
- WRITE16(ea, dst);
- CYCLES(CYCLES_ALU_REG_MEM);
- }
- break;
- case 1: // OR Rm16, i16
- if( modrm >= 0xc0 ) {
- dst = LOAD_RM16(modrm);
- src = (UINT16)(INT16)(INT8)FETCH();
- dst = OR16(dst, src);
- STORE_RM16(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- ea = GetEA(modrm,1);
- dst = READ16(ea);
- src = (UINT16)(INT16)(INT8)FETCH();
- dst = OR16(dst, src);
- WRITE16(ea, dst);
- CYCLES(CYCLES_ALU_REG_MEM);
- }
- break;
- case 2: // ADC Rm16, i16
- if( modrm >= 0xc0 ) {
- dst = LOAD_RM16(modrm);
- src = (UINT16)(INT16)(INT8)FETCH();
- dst = ADC16( dst, src, cpustate->CF);
- STORE_RM16(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- ea = GetEA(modrm,1);
- dst = READ16(ea);
- src = (UINT16)(INT16)(INT8)FETCH();
- dst = ADC16( dst, src, cpustate->CF);
- WRITE16(ea, dst);
- CYCLES(CYCLES_ALU_REG_MEM);
- }
- break;
- case 3: // SBB Rm16, i16
- if( modrm >= 0xc0 ) {
- dst = LOAD_RM16(modrm);
- src = ((UINT16)(INT16)(INT8)FETCH());
- dst = SBB16( dst, src, cpustate->CF);
- STORE_RM16(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- ea = GetEA(modrm,1);
- dst = READ16(ea);
- src = ((UINT16)(INT16)(INT8)FETCH());
- dst = SBB16( dst, src, cpustate->CF);
- WRITE16(ea, dst);
- CYCLES(CYCLES_ALU_REG_MEM);
- }
- break;
- case 4: // AND Rm16, i16
- if( modrm >= 0xc0 ) {
- dst = LOAD_RM16(modrm);
- src = (UINT16)(INT16)(INT8)FETCH();
- dst = AND16(dst, src);
- STORE_RM16(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- ea = GetEA(modrm,1);
- dst = READ16(ea);
- src = (UINT16)(INT16)(INT8)FETCH();
- dst = AND16(dst, src);
- WRITE16(ea, dst);
- CYCLES(CYCLES_ALU_REG_MEM);
- }
- break;
- case 5: // SUB Rm16, i16
- if( modrm >= 0xc0 ) {
- dst = LOAD_RM16(modrm);
- src = (UINT16)(INT16)(INT8)FETCH();
- dst = SUB16(dst, src);
- STORE_RM16(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- ea = GetEA(modrm,1);
- dst = READ16(ea);
- src = (UINT16)(INT16)(INT8)FETCH();
- dst = SUB16(dst, src);
- WRITE16(ea, dst);
- CYCLES(CYCLES_ALU_REG_MEM);
- }
- break;
- case 6: // XOR Rm16, i16
- if( modrm >= 0xc0 ) {
- dst = LOAD_RM16(modrm);
- src = (UINT16)(INT16)(INT8)FETCH();
- dst = XOR16(dst, src);
- STORE_RM16(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- ea = GetEA(modrm,1);
- dst = READ16(ea);
- src = (UINT16)(INT16)(INT8)FETCH();
- dst = XOR16(dst, src);
- WRITE16(ea, dst);
- CYCLES(CYCLES_ALU_REG_MEM);
- }
- break;
- case 7: // CMP Rm16, i16
- if( modrm >= 0xc0 ) {
- dst = LOAD_RM16(modrm);
- src = (UINT16)(INT16)(INT8)FETCH();
- SUB16(dst, src);
- CYCLES(CYCLES_CMP_REG_REG);
- } else {
- ea = GetEA(modrm,0);
- dst = READ16(ea);
- src = (UINT16)(INT16)(INT8)FETCH();
- SUB16(dst, src);
- CYCLES(CYCLES_CMP_REG_MEM);
- }
- break;
- }
-}
-
-void I386_OPS_BASE::I386OP(groupC1_16)() // Opcode 0xc1
-{
- UINT16 dst;
- UINT8 modrm = FETCH();
- UINT8 shift;
-
- if( modrm >= 0xc0 ) {
- dst = LOAD_RM16(modrm);
- shift = FETCH() & 0x1f;
- dst = i386_shift_rotate16( modrm, dst, shift);
- STORE_RM16(modrm, dst);
- } else {
- UINT32 ea = GetEA(modrm,1);
- dst = READ16(ea);
- shift = FETCH() & 0x1f;
- dst = i386_shift_rotate16( modrm, dst, shift);
- WRITE16(ea, dst);
- }
-}
-
-void I386_OPS_BASE::I386OP(groupD1_16)() // Opcode 0xd1
-{
- UINT16 dst;
- UINT8 modrm = FETCH();
-
- if( modrm >= 0xc0 ) {
- dst = LOAD_RM16(modrm);
- dst = i386_shift_rotate16( modrm, dst, 1);
- STORE_RM16(modrm, dst);
- } else {
- UINT32 ea = GetEA(modrm,1);
- dst = READ16(ea);
- dst = i386_shift_rotate16( modrm, dst, 1);
- WRITE16(ea, dst);
- }
-}
-
-void I386_OPS_BASE::I386OP(groupD3_16)() // Opcode 0xd3
-{
- UINT16 dst;
- UINT8 modrm = FETCH();
-
- if( modrm >= 0xc0 ) {
- dst = LOAD_RM16(modrm);
- dst = i386_shift_rotate16( modrm, dst, REG8(CL));
- STORE_RM16(modrm, dst);
- } else {
- UINT32 ea = GetEA(modrm,1);
- dst = READ16(ea);
- dst = i386_shift_rotate16( modrm, dst, REG8(CL));
- WRITE16(ea, dst);
- }
-}
-
-void I386_OPS_BASE::I386OP(groupF7_16)() // Opcode 0xf7
-{
- UINT8 modrm = FETCH();
-
- switch( (modrm >> 3) & 0x7 )
- {
- case 0: /* TEST Rm16, i16 */
- if( modrm >= 0xc0 ) {
- UINT16 dst = LOAD_RM16(modrm);
- UINT16 src = FETCH16();
- dst &= src;
- cpustate->CF = cpustate->OF = cpustate->AF = 0;
- SetSZPF16(dst);
- CYCLES(CYCLES_TEST_IMM_REG);
- } else {
- UINT32 ea = GetEA(modrm,0);
- UINT16 dst = READ16(ea);
- UINT16 src = FETCH16();
- dst &= src;
- cpustate->CF = cpustate->OF = cpustate->AF = 0;
- SetSZPF16(dst);
- CYCLES(CYCLES_TEST_IMM_MEM);
- }
- break;
- case 2: /* NOT Rm16 */
- if( modrm >= 0xc0 ) {
- UINT16 dst = LOAD_RM16(modrm);
- dst = ~dst;
- STORE_RM16(modrm, dst);
- CYCLES(CYCLES_NOT_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- UINT16 dst = READ16(ea);
- dst = ~dst;
- WRITE16(ea, dst);
- CYCLES(CYCLES_NOT_MEM);
- }
- break;
- case 3: /* NEG Rm16 */
- if( modrm >= 0xc0 ) {
- UINT16 dst = LOAD_RM16(modrm);
- dst = SUB16( 0, dst );
- STORE_RM16(modrm, dst);
- CYCLES(CYCLES_NEG_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- UINT16 dst = READ16(ea);
- dst = SUB16( 0, dst );
- WRITE16(ea, dst);
- CYCLES(CYCLES_NEG_MEM);
- }
- break;
- case 4: /* MUL AX, Rm16 */
- {
- UINT32 result;
- UINT16 src, dst;
- if( modrm >= 0xc0 ) {
- src = LOAD_RM16(modrm);
- CYCLES(CYCLES_MUL16_ACC_REG); /* TODO: Correct multiply timing */
- } else {
- UINT32 ea = GetEA(modrm,0);
- src = READ16(ea);
- CYCLES(CYCLES_MUL16_ACC_MEM); /* TODO: Correct multiply timing */
- }
-
- dst = REG16(AX);
- result = (UINT32)src * (UINT32)dst;
- REG16(DX) = (UINT16)(result >> 16);
- REG16(AX) = (UINT16)result;
-
- cpustate->CF = cpustate->OF = (REG16(DX) != 0);
- }
- break;
- case 5: /* IMUL AX, Rm16 */
- {
- INT32 result;
- INT32 src, dst;
- if( modrm >= 0xc0 ) {
- src = (INT32)(INT16)LOAD_RM16(modrm);
- CYCLES(CYCLES_IMUL16_ACC_REG); /* TODO: Correct multiply timing */
- } else {
- UINT32 ea = GetEA(modrm,0);
- src = (INT32)(INT16)READ16(ea);
- CYCLES(CYCLES_IMUL16_ACC_MEM); /* TODO: Correct multiply timing */
- }
-
- dst = (INT32)(INT16)REG16(AX);
- result = src * dst;
-
- REG16(DX) = (UINT16)(result >> 16);
- REG16(AX) = (UINT16)result;
-
- cpustate->CF = cpustate->OF = !(result == (INT32)(INT16)result);
- }
- break;
- case 6: /* DIV AX, Rm16 */
- {
- UINT32 quotient, remainder, result;
- UINT16 src;
- if( modrm >= 0xc0 ) {
- src = LOAD_RM16(modrm);
- CYCLES(CYCLES_DIV16_ACC_REG);
- } else {
- UINT32 ea = GetEA(modrm,0);
- src = READ16(ea);
- CYCLES(CYCLES_DIV16_ACC_MEM);
- }
-
- quotient = ((UINT32)(REG16(DX)) << 16) | (UINT32)(REG16(AX));
- if( src ) {
- remainder = quotient % (UINT32)src;
- result = quotient / (UINT32)src;
- if( result > 0xffff ) {
- /* TODO: Divide error */
- } else {
- REG16(DX) = (UINT16)remainder;
- REG16(AX) = (UINT16)result;
-
- // this flag is actually undefined, enable on non-cyrix
- if (cpustate->cpuid_id0 != 0x69727943)
- cpustate->CF = 1;
- }
- } else {
- i386_trap( 0, 0, 0);
- }
- }
- break;
- case 7: /* IDIV AX, Rm16 */
- {
- INT32 quotient, remainder, result;
- UINT16 src;
- if( modrm >= 0xc0 ) {
- src = LOAD_RM16(modrm);
- CYCLES(CYCLES_IDIV16_ACC_REG);
- } else {
- UINT32 ea = GetEA(modrm,0);
- src = READ16(ea);
- CYCLES(CYCLES_IDIV16_ACC_MEM);
- }
-
- quotient = (((INT32)REG16(DX)) << 16) | ((UINT32)REG16(AX));
- if( src ) {
- remainder = quotient % (INT32)(INT16)src;
- result = quotient / (INT32)(INT16)src;
- if( result > 0xffff ) {
- /* TODO: Divide error */
- } else {
- REG16(DX) = (UINT16)remainder;
- REG16(AX) = (UINT16)result;
-
- // this flag is actually undefined, enable on non-cyrix
- if (cpustate->cpuid_id0 != 0x69727943)
- cpustate->CF = 1;
- }
- } else {
- i386_trap( 0, 0, 0);
- }
- }
- break;
- }
-}
-
-void I386_OPS_BASE::I386OP(groupFF_16)() // Opcode 0xff
-{
- UINT8 modrm = FETCH();
-
- switch( (modrm >> 3) & 0x7 )
- {
- case 0: /* INC Rm16 */
- if( modrm >= 0xc0 ) {
- UINT16 dst = LOAD_RM16(modrm);
- dst = INC16(dst);
- STORE_RM16(modrm, dst);
- CYCLES(CYCLES_INC_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- UINT16 dst = READ16(ea);
- dst = INC16(dst);
- WRITE16(ea, dst);
- CYCLES(CYCLES_INC_MEM);
- }
- break;
- case 1: /* DEC Rm16 */
- if( modrm >= 0xc0 ) {
- UINT16 dst = LOAD_RM16(modrm);
- dst = DEC16(dst);
- STORE_RM16(modrm, dst);
- CYCLES(CYCLES_DEC_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- UINT16 dst = READ16(ea);
- dst = DEC16(dst);
- WRITE16(ea, dst);
- CYCLES(CYCLES_DEC_MEM);
- }
- break;
- case 2: /* CALL Rm16 */
- {
- UINT16 address;
- if( modrm >= 0xc0 ) {
- address = LOAD_RM16(modrm);
- CYCLES(CYCLES_CALL_REG); /* TODO: Timing = 7 + m */
- } else {
- UINT32 ea = GetEA(modrm,0);
- address = READ16(ea);
- CYCLES(CYCLES_CALL_MEM); /* TODO: Timing = 10 + m */
- }
- PUSH16( cpustate->eip );
- cpustate->eip = address;
- CHANGE_PC(cpustate->eip);
- }
- break;
- case 3: /* CALL FAR Rm16 */
- {
- UINT16 address, selector;
- if( modrm >= 0xc0 )
- {
- report_invalid_modrm( "groupFF_16", modrm);
- }
- else
- {
- UINT32 ea = GetEA(modrm,0);
- address = READ16(ea + 0);
- selector = READ16(ea + 2);
- CYCLES(CYCLES_CALL_MEM_INTERSEG); /* TODO: Timing = 10 + m */
- if(PROTECTED_MODE && !V8086_MODE)
- {
- i386_protected_mode_call(selector,address,1,0);
- }
- else
- {
- PUSH16( cpustate->sreg[CS].selector );
- PUSH16( cpustate->eip );
- cpustate->sreg[CS].selector = selector;
- cpustate->performed_intersegment_jump = 1;
- i386_load_segment_descriptor( CS );
- cpustate->eip = address;
- CHANGE_PC(cpustate->eip);
- }
- }
- }
- break;
- case 4: /* JMP Rm16 */
- {
- UINT16 address;
- if( modrm >= 0xc0 ) {
- address = LOAD_RM16(modrm);
- CYCLES(CYCLES_JMP_REG); /* TODO: Timing = 7 + m */
- } else {
- UINT32 ea = GetEA(modrm,0);
- address = READ16(ea);
- CYCLES(CYCLES_JMP_MEM); /* TODO: Timing = 10 + m */
- }
- cpustate->eip = address;
- CHANGE_PC(cpustate->eip);
- }
- break;
- case 5: /* JMP FAR Rm16 */
- {
- UINT16 address, selector;
-
- if( modrm >= 0xc0 )
- {
- report_invalid_modrm( "groupFF_16", modrm);
- }
- else
- {
- UINT32 ea = GetEA(modrm,0);
- address = READ16(ea + 0);
- selector = READ16(ea + 2);
- CYCLES(CYCLES_JMP_MEM_INTERSEG); /* TODO: Timing = 10 + m */
- if(PROTECTED_MODE && !V8086_MODE)
- {
- i386_protected_mode_jump(selector,address,1,0);
- }
- else
- {
- cpustate->sreg[CS].selector = selector;
- cpustate->performed_intersegment_jump = 1;
- i386_load_segment_descriptor( CS );
- cpustate->eip = address;
- CHANGE_PC(cpustate->eip);
- }
- }
- }
- break;
- case 6: /* PUSH Rm16 */
- {
- UINT16 value;
- if( modrm >= 0xc0 ) {
- value = LOAD_RM16(modrm);
- } else {
- UINT32 ea = GetEA(modrm,0);
- value = READ16(ea);
- }
- PUSH16(value);
- CYCLES(CYCLES_PUSH_RM);
- }
- break;
- default:
- report_invalid_modrm( "groupFF_16", modrm);
- break;
- }
-}
-
-void I386_OPS_BASE::I386OP(group0F00_16)() // Opcode 0x0f 00
-{
- UINT32 address, ea;
- UINT8 modrm = FETCH();
- I386_SREG seg;
- UINT8 result;
-
- switch( (modrm >> 3) & 0x7 )
- {
- case 0: /* SLDT */
- if ( PROTECTED_MODE && !V8086_MODE )
- {
- if( modrm >= 0xc0 ) {
- STORE_RM16(modrm, cpustate->ldtr.segment);
- CYCLES(CYCLES_SLDT_REG);
- } else {
- ea = GetEA(modrm,1);
- WRITE16( ea, cpustate->ldtr.segment);
- CYCLES(CYCLES_SLDT_MEM);
- }
- }
- else
- {
- i386_trap(6, 0, 0);
- }
- break;
- case 1: /* STR */
- if ( PROTECTED_MODE && !V8086_MODE )
- {
- if( modrm >= 0xc0 ) {
- STORE_RM16(modrm, cpustate->task.segment);
- CYCLES(CYCLES_STR_REG);
- } else {
- ea = GetEA(modrm,1);
- WRITE16( ea, cpustate->task.segment);
- CYCLES(CYCLES_STR_MEM);
- }
- }
- else
- {
- i386_trap(6, 0, 0);
- }
- break;
- case 2: /* LLDT */
- if ( PROTECTED_MODE && !V8086_MODE )
- {
- if(cpustate->CPL)
- FAULT(FAULT_GP,0)
- if( modrm >= 0xc0 ) {
- address = LOAD_RM16(modrm);
- cpustate->ldtr.segment = address;
- CYCLES(CYCLES_LLDT_REG);
- } else {
- ea = GetEA(modrm,0);
- cpustate->ldtr.segment = READ16(ea);
- CYCLES(CYCLES_LLDT_MEM);
- }
- memset(&seg, 0, sizeof(seg));
- seg.selector = cpustate->ldtr.segment;
- i386_load_protected_mode_segment(&seg,NULL);
- cpustate->ldtr.limit = seg.limit;
- cpustate->ldtr.base = seg.base;
- cpustate->ldtr.flags = seg.flags;
- }
- else
- {
- i386_trap(6, 0, 0);
- }
- break;
-
- case 3: /* LTR */
- if ( PROTECTED_MODE && !V8086_MODE )
- {
- if(cpustate->CPL)
- FAULT(FAULT_GP,0)
- if( modrm >= 0xc0 ) {
- address = LOAD_RM16(modrm);
- cpustate->task.segment = address;
- CYCLES(CYCLES_LTR_REG);
- } else {
- ea = GetEA(modrm,0);
- cpustate->task.segment = READ16(ea);
- CYCLES(CYCLES_LTR_MEM);
- }
- memset(&seg, 0, sizeof(seg));
- seg.selector = cpustate->task.segment;
- i386_load_protected_mode_segment(&seg,NULL);
-
- UINT32 addr = ((seg.selector & 4) ? cpustate->ldtr.base : cpustate->gdtr.base) + (seg.selector & ~7) + 5;
- i386_translate_address( TRANSLATE_READ, &addr, NULL);
- cpustate->program->write_data16(addr, (seg.flags & 0xff) | 2);
-
- cpustate->task.limit = seg.limit;
- cpustate->task.base = seg.base;
- cpustate->task.flags = seg.flags | 2;
- }
- else
- {
- i386_trap(6, 0, 0);
- }
- break;
-
- case 4: /* VERR */
- if ( PROTECTED_MODE && !V8086_MODE )
- {
- result = 1;
- if( modrm >= 0xc0 ) {
- address = LOAD_RM16(modrm);
- CYCLES(CYCLES_VERR_REG);
- } else {
- ea = GetEA(modrm,0);
- address = READ16(ea);
- CYCLES(CYCLES_VERR_MEM);
- }
- memset(&seg, 0, sizeof(seg));
- seg.selector = address;
- result = i386_load_protected_mode_segment(&seg,NULL);
- // check if the segment is a code or data segment (not a special segment type, like a TSS, gate, LDT...)
- if(!(seg.flags & 0x10))
- result = 0;
- // check that the segment is readable
- if(seg.flags & 0x10) // is code or data segment
- {
- if(seg.flags & 0x08) // is code segment, so check if it's readable
- {
- if(!(seg.flags & 0x02))
- {
- result = 0;
- }
- else
- { // check if conforming, these are always readable, regardless of privilege
- if(!(seg.flags & 0x04))
- {
- // if not conforming, then we must check privilege levels (TODO: current privilege level check)
- if(((seg.flags >> 5) & 0x03) < (address & 0x03))
- result = 0;
- }
- }
- }
- }
- // check that the descriptor privilege is greater or equal to the selector's privilege level and the current privilege (TODO)
- SetZF(result);
- }
- else
- {
- i386_trap(6, 0, 0);
- logerror("i386: VERR: Exception - Running in real mode or virtual 8086 mode.\n");
- }
- break;
-
- case 5: /* VERW */
- if ( PROTECTED_MODE && !V8086_MODE )
- {
- result = 1;
- if( modrm >= 0xc0 ) {
- address = LOAD_RM16(modrm);
- CYCLES(CYCLES_VERW_REG);
- } else {
- ea = GetEA(modrm,0);
- address = READ16(ea);
- CYCLES(CYCLES_VERW_MEM);
- }
- memset(&seg, 0, sizeof(seg));
- seg.selector = address;
- result = i386_load_protected_mode_segment(&seg,NULL);
- // check if the segment is a code or data segment (not a special segment type, like a TSS, gate, LDT...)
- if(!(seg.flags & 0x10))
- result = 0;
- // check that the segment is writable
- if(seg.flags & 0x10) // is code or data segment
- {
- if(seg.flags & 0x08) // is code segment (and thus, not writable)
- {
- result = 0;
- }
- else
- { // is data segment
- if(!(seg.flags & 0x02))
- result = 0;
- }
- }
- // check that the descriptor privilege is greater or equal to the selector's privilege level and the current privilege (TODO)
- if(((seg.flags >> 5) & 0x03) < (address & 0x03))
- result = 0;
- SetZF(result);
- }
- else
- {
- i386_trap(6, 0, 0);
- logerror("i386: VERW: Exception - Running in real mode or virtual 8086 mode.\n");
- }
- break;
-
- default:
- report_invalid_modrm( "group0F00_16", modrm);
- break;
- }
-}
-
-void I386_OPS_BASE::I386OP(group0F01_16)() // Opcode 0x0f 01
-{
- UINT8 modrm = FETCH();
- UINT16 address;
- UINT32 ea;
-
- switch( (modrm >> 3) & 0x7 )
- {
- case 0: /* SGDT */
- {
- if( modrm >= 0xc0 ) {
- address = LOAD_RM16(modrm);
- ea = i386_translate( CS, address, 1 );
- } else {
- ea = GetEA(modrm,1);
- }
- WRITE16(ea, cpustate->gdtr.limit);
- WRITE32(ea + 2, cpustate->gdtr.base);
- CYCLES(CYCLES_SGDT);
- break;
- }
- case 1: /* SIDT */
- {
- if (modrm >= 0xc0)
- {
- address = LOAD_RM16(modrm);
- ea = i386_translate( CS, address, 1 );
- }
- else
- {
- ea = GetEA(modrm,1);
- }
- WRITE16(ea, cpustate->idtr.limit);
- WRITE32(ea + 2, cpustate->idtr.base);
- CYCLES(CYCLES_SIDT);
- break;
- }
- case 2: /* LGDT */
- {
- if(PROTECTED_MODE && cpustate->CPL)
- FAULT(FAULT_GP,0)
- if( modrm >= 0xc0 ) {
- address = LOAD_RM16(modrm);
- ea = i386_translate( CS, address, 0 );
- } else {
- ea = GetEA(modrm,0);
- }
- cpustate->gdtr.limit = READ16(ea);
- cpustate->gdtr.base = READ32(ea + 2) & 0xffffff;
- CYCLES(CYCLES_LGDT);
- break;
- }
- case 3: /* LIDT */
- {
- if(PROTECTED_MODE && cpustate->CPL)
- FAULT(FAULT_GP,0)
- if( modrm >= 0xc0 ) {
- address = LOAD_RM16(modrm);
- ea = i386_translate( CS, address, 0 );
- } else {
- ea = GetEA(modrm,0);
- }
- cpustate->idtr.limit = READ16(ea);
- cpustate->idtr.base = READ32(ea + 2) & 0xffffff;
- CYCLES(CYCLES_LIDT);
- break;
- }
- case 4: /* SMSW */
- {
- if( modrm >= 0xc0 ) {
- STORE_RM16(modrm, cpustate->cr[0]);
- CYCLES(CYCLES_SMSW_REG);
- } else {
- ea = GetEA(modrm,1);
- WRITE16(ea, cpustate->cr[0]);
- CYCLES(CYCLES_SMSW_MEM);
- }
- break;
- }
- case 6: /* LMSW */
- {
- if(PROTECTED_MODE && cpustate->CPL)
- FAULT(FAULT_GP,0)
- UINT16 b;
- if( modrm >= 0xc0 ) {
- b = LOAD_RM16(modrm);
- CYCLES(CYCLES_LMSW_REG);
- } else {
- ea = GetEA(modrm,0);
- CYCLES(CYCLES_LMSW_MEM);
- b = READ16(ea);
- }
- if(PROTECTED_MODE)
- b |= 0x0001; // cannot return to real mode using this instruction.
- cpustate->cr[0] &= ~0x0000000f;
- cpustate->cr[0] |= b & 0x0000000f;
- break;
- }
- default:
- report_invalid_modrm( "group0F01_16", modrm);
- break;
- }
-}
-
-void I386_OPS_BASE::I386OP(group0FBA_16)() // Opcode 0x0f ba
-{
- UINT8 modrm = FETCH();
-
- switch( (modrm >> 3) & 0x7 )
- {
- case 4: /* BT Rm16, i8 */
- if( modrm >= 0xc0 ) {
- UINT16 dst = LOAD_RM16(modrm);
- UINT8 bit = FETCH();
-
- if( dst & (1 << bit) )
- cpustate->CF = 1;
- else
- cpustate->CF = 0;
-
- CYCLES(CYCLES_BT_IMM_REG);
- } else {
- UINT32 ea = GetEA(modrm,0);
- UINT16 dst = READ16(ea);
- UINT8 bit = FETCH();
-
- if( dst & (1 << bit) )
- cpustate->CF = 1;
- else
- cpustate->CF = 0;
-
- CYCLES(CYCLES_BT_IMM_MEM);
- }
- break;
- case 5: /* BTS Rm16, i8 */
- if( modrm >= 0xc0 ) {
- UINT16 dst = LOAD_RM16(modrm);
- UINT8 bit = FETCH();
-
- if( dst & (1 << bit) )
- cpustate->CF = 1;
- else
- cpustate->CF = 0;
- dst |= (1 << bit);
-
- STORE_RM16(modrm, dst);
- CYCLES(CYCLES_BTS_IMM_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- UINT16 dst = READ16(ea);
- UINT8 bit = FETCH();
-
- if( dst & (1 << bit) )
- cpustate->CF = 1;
- else
- cpustate->CF = 0;
- dst |= (1 << bit);
-
- WRITE16(ea, dst);
- CYCLES(CYCLES_BTS_IMM_MEM);
- }
- break;
- case 6: /* BTR Rm16, i8 */
- if( modrm >= 0xc0 ) {
- UINT16 dst = LOAD_RM16(modrm);
- UINT8 bit = FETCH();
-
- if( dst & (1 << bit) )
- cpustate->CF = 1;
- else
- cpustate->CF = 0;
- dst &= ~(1 << bit);
-
- STORE_RM16(modrm, dst);
- CYCLES(CYCLES_BTR_IMM_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- UINT16 dst = READ16(ea);
- UINT8 bit = FETCH();
-
- if( dst & (1 << bit) )
- cpustate->CF = 1;
- else
- cpustate->CF = 0;
- dst &= ~(1 << bit);
-
- WRITE16(ea, dst);
- CYCLES(CYCLES_BTR_IMM_MEM);
- }
- break;
- case 7: /* BTC Rm16, i8 */
- if( modrm >= 0xc0 ) {
- UINT16 dst = LOAD_RM16(modrm);
- UINT8 bit = FETCH();
-
- if( dst & (1 << bit) )
- cpustate->CF = 1;
- else
- cpustate->CF = 0;
- dst ^= (1 << bit);
-
- STORE_RM16(modrm, dst);
- CYCLES(CYCLES_BTC_IMM_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- UINT16 dst = READ16(ea);
- UINT8 bit = FETCH();
-
- if( dst & (1 << bit) )
- cpustate->CF = 1;
- else
- cpustate->CF = 0;
- dst ^= (1 << bit);
-
- WRITE16(ea, dst);
- CYCLES(CYCLES_BTC_IMM_MEM);
- }
- break;
- default:
- report_invalid_modrm( "group0FBA_16", modrm);
- break;
- }
-}
-
-void I386_OPS_BASE::I386OP(lar_r16_rm16)() // Opcode 0x0f 0x02
-{
- UINT8 modrm = FETCH();
- I386_SREG seg;
- UINT8 type;
-
- if(PROTECTED_MODE && !V8086_MODE)
- {
- memset(&seg,0,sizeof(seg));
- if(modrm >= 0xc0)
- {
- seg.selector = LOAD_RM16(modrm);
- CYCLES(CYCLES_LAR_REG);
- }
- else
- {
- UINT32 ea = GetEA(modrm,0);
- seg.selector = READ16(ea);
- CYCLES(CYCLES_LAR_MEM);
- }
- if(seg.selector == 0)
- {
- SetZF(0); // not a valid segment
- // logerror("i386 (%08x): LAR: Selector %04x is invalid type.\n",cpustate->pc,seg.selector);
- }
- else
- {
- if(!i386_load_protected_mode_segment(&seg,NULL))
- {
- SetZF(0);
- return;
- }
- UINT8 DPL = (seg.flags >> 5) & 3;
- if(((DPL < cpustate->CPL) || (DPL < (seg.selector & 3))) && ((seg.flags & 0x1c) != 0x1c))
- {
- SetZF(0);
- return;
- }
- if(!(seg.flags & 0x10)) // special segment
- {
- // check for invalid segment types
- type = seg.flags & 0x000f;
- if(type == 0x00 || type == 0x08 || type == 0x0a || type == 0x0d)
- {
- SetZF(0); // invalid segment type
- }
- else
- {
- STORE_REG16(modrm,(seg.flags << 8) & 0xff00);
- SetZF(1);
- }
- }
- else
- { // data or code segment (both are valid for LAR)
- STORE_REG16(modrm,(seg.flags << 8) & 0xff00);
- SetZF(1);
- }
- }
- }
- else
- {
- // illegal opcode
- i386_trap(6,0, 0);
- logerror("i386: LAR: Exception - running in real mode or virtual 8086 mode.\n");
- }
-}
-
-void I386_OPS_BASE::I386OP(lsl_r16_rm16)() // Opcode 0x0f 0x03
-{
- UINT8 modrm = FETCH();
- UINT32 limit;
- I386_SREG seg;
-
- if(PROTECTED_MODE && !V8086_MODE)
- {
- memset(&seg, 0, sizeof(seg));
- if(modrm >= 0xc0)
- {
- seg.selector = LOAD_RM16(modrm);
- }
- else
- {
- UINT32 ea = GetEA(modrm,0);
- seg.selector = READ16(ea);
- }
- if(seg.selector == 0)
- {
- SetZF(0); // not a valid segment
- }
- else
- {
- UINT8 type;
- if(!i386_load_protected_mode_segment(&seg,NULL))
- {
- SetZF(0);
- return;
- }
- UINT8 DPL = (seg.flags >> 5) & 3;
- if(((DPL < cpustate->CPL) || (DPL < (seg.selector & 3))) && ((seg.flags & 0x1c) != 0x1c))
- {
- SetZF(0);
- return;
- }
- type = seg.flags & 0x1f;
- switch(type)
- {
- case 0:
- case 4:
- case 5:
- case 6:
- case 7:
- case 8:
- case 10:
- case 12:
- case 13:
- case 14:
- case 15:
- SetZF(0);
- return;
- default:
- limit = seg.limit;
- STORE_REG16(modrm,limit & 0x0000ffff);
- SetZF(1);
- }
- }
- }
- else
- i386_trap(6, 0, 0);
-}
-
-void I386_OPS_BASE::I386OP(bound_r16_m16_m16)() // Opcode 0x62
-{
- UINT8 modrm;
- INT16 val, low, high;
-
- modrm = FETCH();
-
- if (modrm >= 0xc0)
- {
- low = high = LOAD_RM16(modrm);
- }
- else
- {
- UINT32 ea = GetEA(modrm,0);
- low = READ16(ea + 0);
- high = READ16(ea + 2);
- }
- val = LOAD_REG16(modrm);
-
- if ((val < low) || (val > high))
- {
- CYCLES(CYCLES_BOUND_OUT_RANGE);
- i386_trap(5, 0, 0);
- }
- else
- {
- CYCLES(CYCLES_BOUND_IN_RANGE);
- }
-}
-
-void I386_OPS_BASE::I386OP(retf16)() // Opcode 0xcb
-{
- if(PROTECTED_MODE && !V8086_MODE)
- {
- i386_protected_mode_retf(0,0);
- }
- else
- {
- cpustate->eip = POP16();
- cpustate->sreg[CS].selector = POP16();
- i386_load_segment_descriptor( CS );
- CHANGE_PC(cpustate->eip);
- }
-
- CYCLES(CYCLES_RET_INTERSEG);
-}
-
-void I386_OPS_BASE::I386OP(retf_i16)() // Opcode 0xca
-{
- UINT16 count = FETCH16();
-
- if(PROTECTED_MODE && !V8086_MODE)
- {
- i386_protected_mode_retf(count,0);
- }
- else
- {
- cpustate->eip = POP16();
- cpustate->sreg[CS].selector = POP16();
- i386_load_segment_descriptor( CS );
- CHANGE_PC(cpustate->eip);
- REG16(SP) += count;
- }
-
- CYCLES(CYCLES_RET_IMM_INTERSEG);
-}
-
-bool I386_OPS_BASE::I386OP(load_far_pointer16)(int s)
-{
- UINT8 modrm = FETCH();
- UINT16 selector;
-
- if( modrm >= 0xc0 ) {
- //logerror("i386: load_far_pointer16 NYI\n"); // don't log, NT will use this a lot
- i386_trap(6, 0, 0);
- return false;
- } else {
- UINT32 ea = GetEA(modrm,0);
- STORE_REG16(modrm, READ16(ea + 0));
- selector = READ16(ea + 2);
- i386_sreg_load(selector,s,NULL);
- }
- return true;
-}
-
-void I386_OPS_BASE::I386OP(lds16)() // Opcode 0xc5
-{
- if(I386OP(load_far_pointer16)( DS))
- CYCLES(CYCLES_LDS);
-}
-
-void I386_OPS_BASE::I386OP(lss16)() // Opcode 0x0f 0xb2
-{
- if(I386OP(load_far_pointer16)( SS))
- CYCLES(CYCLES_LSS);
-}
-
-void I386_OPS_BASE::I386OP(les16)() // Opcode 0xc4
-{
- if(I386OP(load_far_pointer16)( ES))
- CYCLES(CYCLES_LES);
-}
-
-void I386_OPS_BASE::I386OP(lfs16)() // Opcode 0x0f 0xb4
-{
- if(I386OP(load_far_pointer16)( FS))
- CYCLES(CYCLES_LFS);
-}
-
-void I386_OPS_BASE::I386OP(lgs16)() // Opcode 0x0f 0xb5
-{
- if(I386OP(load_far_pointer16)( GS))
- CYCLES(CYCLES_LGS);
-}
+++ /dev/null
-
-#include "../vm.h"
-#include "../../emu.h"
-#include "./i386opdef_real.h"
-
-#ifdef I386_PSEUDO_BIOS
-#define BIOS_INT(num) if(cpustate->bios != NULL) { \
- uint16_t regs[8], sregs[4]; \
- regs[0] = REG16(AX); regs[1] = REG16(CX); regs[2] = REG16(DX); regs[3] = REG16(BX); \
- regs[4] = REG16(SP); regs[5] = REG16(BP); regs[6] = REG16(SI); regs[7] = REG16(DI); \
- sregs[0] = cpustate->sreg[ES].selector; sregs[1] = cpustate->sreg[CS].selector; \
- sregs[2] = cpustate->sreg[SS].selector; sregs[3] = cpustate->sreg[DS].selector; \
- int32_t ZeroFlag = cpustate->ZF, CarryFlag = cpustate->CF; \
- printf("INT %x \n", num); \
- if(cpustate->bios->bios_int_i86(num, regs, sregs, &ZeroFlag, &CarryFlag)) { \
- REG16(AX) = regs[0]; REG16(CX) = regs[1]; REG16(DX) = regs[2]; REG16(BX) = regs[3]; \
- REG16(SP) = regs[4]; REG16(BP) = regs[5]; REG16(SI) = regs[6]; REG16(DI) = regs[7]; \
- cpustate->ZF = (UINT8)ZeroFlag; cpustate->CF = (UINT8)CarryFlag; \
- return; \
- } \
-}
-#define BIOS_CALL(address) if(cpustate->bios != NULL) { \
- uint16_t regs[8], sregs[4]; \
- regs[0] = REG16(AX); regs[1] = REG16(CX); regs[2] = REG16(DX); regs[3] = REG16(BX); \
- regs[4] = REG16(SP); regs[5] = REG16(BP); regs[6] = REG16(SI); regs[7] = REG16(DI); \
- sregs[0] = cpustate->sreg[ES].selector; sregs[1] = cpustate->sreg[CS].selector; \
- sregs[2] = cpustate->sreg[SS].selector; sregs[3] = cpustate->sreg[DS].selector; \
- int32_t ZeroFlag = cpustate->ZF, CarryFlag = cpustate->CF; \
- printf("CALL %08x %0x AX=%04x %02x %02x\n", cpustate, address, regs[0], REG8(AH), REG8(AL)); \
- if(cpustate->bios->bios_call_i86(address, regs, sregs, &ZeroFlag, &CarryFlag)) { \
- REG16(AX) = regs[0]; REG16(CX) = regs[1]; REG16(DX) = regs[2]; REG16(BX) = regs[3]; \
- REG16(SP) = regs[4]; REG16(BP) = regs[5]; REG16(SI) = regs[6]; REG16(DI) = regs[7]; \
- cpustate->ZF = (UINT8)ZeroFlag; cpustate->CF = (UINT8)CarryFlag; \
- return; \
- } \
-}
-#endif
-
-void I386_OPS::I386OP(call_abs16)() // Opcode 0x9a
-{
- UINT16 offset = FETCH16();
- UINT16 ptr = FETCH16();
-
-#ifdef I386_PSEUDO_BIOS
- BIOS_CALL(((ptr << 4) + offset) & cpustate->a20_mask)
-#endif
-
- if( PROTECTED_MODE && !V8086_MODE)
- {
- i386_protected_mode_call(ptr,offset,0,0);
- }
- else
- {
- PUSH16( cpustate->sreg[CS].selector );
- PUSH16( cpustate->eip );
- cpustate->sreg[CS].selector = ptr;
- cpustate->performed_intersegment_jump = 1;
- cpustate->eip = offset;
- i386_load_segment_descriptor(CS);
- }
- CYCLES(CYCLES_CALL_INTERSEG); /* TODO: Timing = 17 + m */
- CHANGE_PC(cpustate->eip);
-}
-
-void I386_OPS::I386OP(call_rel16)() // Opcode 0xe8
-{
- INT16 disp = FETCH16();
-
-#ifdef I386_PSEUDO_BIOS
- BIOS_CALL((cpustate->pc + disp) & cpustate->a20_mask)
-#endif
-
- PUSH16( cpustate->eip );
- if (cpustate->sreg[CS].d)
- {
- cpustate->eip += disp;
- }
- else
- {
- cpustate->eip = (cpustate->eip + disp) & 0xffff;
- }
- CHANGE_PC(cpustate->eip);
- CYCLES(CYCLES_CALL); /* TODO: Timing = 7 + m */
-}
-
-void I386_OPS::I386OP(groupFF_16)() // Opcode 0xff
-{
- UINT8 modrm = FETCH();
-
- switch( (modrm >> 3) & 0x7 )
- {
- case 0: /* INC Rm16 */
- if( modrm >= 0xc0 ) {
- UINT16 dst = LOAD_RM16(modrm);
- dst = INC16(dst);
- STORE_RM16(modrm, dst);
- CYCLES(CYCLES_INC_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- UINT16 dst = READ16(ea);
- dst = INC16(dst);
- WRITE16(ea, dst);
- CYCLES(CYCLES_INC_MEM);
- }
- break;
- case 1: /* DEC Rm16 */
- if( modrm >= 0xc0 ) {
- UINT16 dst = LOAD_RM16(modrm);
- dst = DEC16(dst);
- STORE_RM16(modrm, dst);
- CYCLES(CYCLES_DEC_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- UINT16 dst = READ16(ea);
- dst = DEC16(dst);
- WRITE16(ea, dst);
- CYCLES(CYCLES_DEC_MEM);
- }
- break;
- case 2: /* CALL Rm16 */
- {
- UINT16 address;
- if( modrm >= 0xc0 ) {
- address = LOAD_RM16(modrm);
- CYCLES(CYCLES_CALL_REG); /* TODO: Timing = 7 + m */
- } else {
- UINT32 ea = GetEA(modrm,0);
- address = READ16(ea);
- CYCLES(CYCLES_CALL_MEM); /* TODO: Timing = 10 + m */
- }
-#ifdef I386_PSEUDO_BIOS
- BIOS_CALL(((cpustate->sreg[CS].selector << 4) + address) & cpustate->a20_mask)
-#endif
- PUSH16( cpustate->eip );
- cpustate->eip = address;
- CHANGE_PC(cpustate->eip);
- }
- break;
- case 3: /* CALL FAR Rm16 */
- {
- UINT16 address, selector;
- if( modrm >= 0xc0 )
- {
- report_invalid_modrm( "groupFF_16", modrm);
- }
- else
- {
- UINT32 ea = GetEA(modrm,0);
- address = READ16(ea + 0);
- selector = READ16(ea + 2);
- CYCLES(CYCLES_CALL_MEM_INTERSEG); /* TODO: Timing = 10 + m */
-#ifdef I386_PSEUDO_BIOS
- BIOS_CALL(((selector << 4) + address) & cpustate->a20_mask)
-#endif
- if(PROTECTED_MODE && !V8086_MODE)
- {
- i386_protected_mode_call(selector,address,1,0);
- }
- else
- {
- PUSH16( cpustate->sreg[CS].selector );
- PUSH16( cpustate->eip );
- cpustate->sreg[CS].selector = selector;
- cpustate->performed_intersegment_jump = 1;
- i386_load_segment_descriptor( CS );
- cpustate->eip = address;
- CHANGE_PC(cpustate->eip);
- }
- }
- }
- break;
- case 4: /* JMP Rm16 */
- {
- UINT16 address;
- if( modrm >= 0xc0 ) {
- address = LOAD_RM16(modrm);
- CYCLES(CYCLES_JMP_REG); /* TODO: Timing = 7 + m */
- } else {
- UINT32 ea = GetEA(modrm,0);
- address = READ16(ea);
- CYCLES(CYCLES_JMP_MEM); /* TODO: Timing = 10 + m */
- }
- cpustate->eip = address;
- CHANGE_PC(cpustate->eip);
- }
- break;
- case 5: /* JMP FAR Rm16 */
- {
- UINT16 address, selector;
-
- if( modrm >= 0xc0 )
- {
- report_invalid_modrm( "groupFF_16", modrm);
- }
- else
- {
- UINT32 ea = GetEA(modrm,0);
- address = READ16(ea + 0);
- selector = READ16(ea + 2);
- CYCLES(CYCLES_JMP_MEM_INTERSEG); /* TODO: Timing = 10 + m */
- if(PROTECTED_MODE && !V8086_MODE)
- {
- i386_protected_mode_jump(selector,address,1,0);
- }
- else
- {
- cpustate->sreg[CS].selector = selector;
- cpustate->performed_intersegment_jump = 1;
- i386_load_segment_descriptor( CS );
- cpustate->eip = address;
- CHANGE_PC(cpustate->eip);
- }
- }
- }
- break;
- case 6: /* PUSH Rm16 */
- {
- UINT16 value;
- if( modrm >= 0xc0 ) {
- value = LOAD_RM16(modrm);
- } else {
- UINT32 ea = GetEA(modrm,0);
- value = READ16(ea);
- }
- PUSH16(value);
- CYCLES(CYCLES_PUSH_RM);
- }
- break;
- default:
- report_invalid_modrm( "groupFF_16", modrm);
- break;
- }
-}
+++ /dev/null
-// license:BSD-3-Clause
-// copyright-holders:Ville Linde, Barry Rodewald, Carl, Phil Bennett
-UINT32 I386_OPS_BASE::I386OP(shift_rotate32)( UINT8 modrm, UINT32 value, UINT8 shift)
-{
- UINT32 dst, src;
- dst = value;
- src = value;
-
- if( shift == 0 ) {
- CYCLES_RM(modrm, 3, 7);
- } else if( shift == 1 ) {
- switch( (modrm >> 3) & 0x7 )
- {
- case 0: /* ROL rm32, 1 */
- cpustate->CF = (src & 0x80000000) ? 1 : 0;
- dst = (src << 1) + cpustate->CF;
- cpustate->OF = ((src ^ dst) & 0x80000000) ? 1 : 0;
- CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
- break;
- case 1: /* ROR rm32, 1 */
- cpustate->CF = (src & 0x1) ? 1 : 0;
- dst = (cpustate->CF << 31) | (src >> 1);
- cpustate->OF = ((src ^ dst) & 0x80000000) ? 1 : 0;
- CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
- break;
- case 2: /* RCL rm32, 1 */
- dst = (src << 1) + cpustate->CF;
- cpustate->CF = (src & 0x80000000) ? 1 : 0;
- cpustate->OF = ((src ^ dst) & 0x80000000) ? 1 : 0;
- CYCLES_RM(modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM);
- break;
- case 3: /* RCR rm32, 1 */
- dst = (cpustate->CF << 31) | (src >> 1);
- cpustate->CF = src & 0x1;
- cpustate->OF = ((src ^ dst) & 0x80000000) ? 1 : 0;
- CYCLES_RM(modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM);
- break;
- case 4: /* SHL/SAL rm32, 1 */
- case 6:
- dst = src << 1;
- cpustate->CF = (src & 0x80000000) ? 1 : 0;
- cpustate->OF = (((cpustate->CF << 31) ^ dst) & 0x80000000) ? 1 : 0;
- SetSZPF32(dst);
- CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
- break;
- case 5: /* SHR rm32, 1 */
- dst = src >> 1;
- cpustate->CF = src & 0x1;
- cpustate->OF = (src & 0x80000000) ? 1 : 0;
- SetSZPF32(dst);
- CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
- break;
- case 7: /* SAR rm32, 1 */
- dst = (INT32)(src) >> 1;
- cpustate->CF = src & 0x1;
- cpustate->OF = 0;
- SetSZPF32(dst);
- CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
- break;
- }
-
- } else {
- shift &= 31;
- switch( (modrm >> 3) & 0x7 )
- {
- case 0: /* ROL rm32, i8 */
- dst = ((src & ((UINT32)0xffffffff >> shift)) << shift) |
- ((src & ((UINT32)0xffffffff << (32-shift))) >> (32-shift));
- cpustate->CF = dst & 0x1;
- cpustate->OF = (dst & 1) ^ (dst >> 31);
- CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
- break;
- case 1: /* ROR rm32, i8 */
- dst = ((src & ((UINT32)0xffffffff << shift)) >> shift) |
- ((src & ((UINT32)0xffffffff >> (32-shift))) << (32-shift));
- cpustate->CF = (dst >> 31) & 0x1;
- cpustate->OF = ((dst >> 31) ^ (dst >> 30)) & 1;
- CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
- break;
- case 2: /* RCL rm32, i8 */
- dst = ((src & ((UINT32)0xffffffff >> shift)) << shift) |
- ((src & ((UINT32)0xffffffff << (33-shift))) >> (33-shift)) |
- (cpustate->CF << (shift-1));
- cpustate->CF = (src >> (32-shift)) & 0x1;
- cpustate->OF = cpustate->CF ^ ((dst >> 31) & 1);
- CYCLES_RM(modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM);
- break;
- case 3: /* RCR rm32, i8 */
- dst = ((src & ((UINT32)0xffffffff << shift)) >> shift) |
- ((src & ((UINT32)0xffffffff >> (32-shift))) << (33-shift)) |
- (cpustate->CF << (32-shift));
- cpustate->CF = (src >> (shift-1)) & 0x1;
- cpustate->OF = ((dst >> 31) ^ (dst >> 30)) & 1;
- CYCLES_RM(modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM);
- break;
- case 4: /* SHL/SAL rm32, i8 */
- case 6:
- dst = src << shift;
- cpustate->CF = (src & (1 << (32-shift))) ? 1 : 0;
- SetSZPF32(dst);
- CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
- break;
- case 5: /* SHR rm32, i8 */
- dst = src >> shift;
- cpustate->CF = (src & (1 << (shift-1))) ? 1 : 0;
- SetSZPF32(dst);
- CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
- break;
- case 7: /* SAR rm32, i8 */
- dst = (INT32)src >> shift;
- cpustate->CF = (src & (1 << (shift-1))) ? 1 : 0;
- SetSZPF32(dst);
- CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
- break;
- }
-
- }
- return dst;
-}
-
-
-
-void I386_OPS_BASE::I386OP(adc_rm32_r32)() // Opcode 0x11
-{
- UINT32 src, dst;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- src = LOAD_REG32(modrm);
- dst = LOAD_RM32(modrm);
- dst = ADC32( dst, src, cpustate->CF);
- STORE_RM32(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- src = LOAD_REG32(modrm);
- dst = READ32(ea);
- dst = ADC32( dst, src, cpustate->CF);
- WRITE32(ea, dst);
- CYCLES(CYCLES_ALU_REG_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(adc_r32_rm32)() // Opcode 0x13
-{
- UINT32 src, dst;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- src = LOAD_RM32(modrm);
- dst = LOAD_REG32(modrm);
- dst = ADC32( dst, src, cpustate->CF);
- STORE_REG32(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,0);
- src = READ32(ea);
- dst = LOAD_REG32(modrm);
- dst = ADC32( dst, src, cpustate->CF);
- STORE_REG32(modrm, dst);
- CYCLES(CYCLES_ALU_MEM_REG);
- }
-}
-
-void I386_OPS_BASE::I386OP(adc_eax_i32)() // Opcode 0x15
-{
- UINT32 src, dst;
- src = FETCH32();
- dst = REG32(EAX);
- dst = ADC32( dst, src, cpustate->CF);
- REG32(EAX) = dst;
- CYCLES(CYCLES_ALU_IMM_ACC);
-}
-
-void I386_OPS_BASE::I386OP(add_rm32_r32)() // Opcode 0x01
-{
- UINT32 src, dst;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- src = LOAD_REG32(modrm);
- dst = LOAD_RM32(modrm);
- dst = ADD32(dst, src);
- STORE_RM32(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- src = LOAD_REG32(modrm);
- dst = READ32(ea);
- dst = ADD32(dst, src);
- WRITE32(ea, dst);
- CYCLES(CYCLES_ALU_REG_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(add_r32_rm32)() // Opcode 0x03
-{
- UINT32 src, dst;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- src = LOAD_RM32(modrm);
- dst = LOAD_REG32(modrm);
- dst = ADD32(dst, src);
- STORE_REG32(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,0);
- src = READ32(ea);
- dst = LOAD_REG32(modrm);
- dst = ADD32(dst, src);
- STORE_REG32(modrm, dst);
- CYCLES(CYCLES_ALU_MEM_REG);
- }
-}
-
-void I386_OPS_BASE::I386OP(add_eax_i32)() // Opcode 0x05
-{
- UINT32 src, dst;
- src = FETCH32();
- dst = REG32(EAX);
- dst = ADD32(dst, src);
- REG32(EAX) = dst;
- CYCLES(CYCLES_ALU_IMM_ACC);
-}
-
-void I386_OPS_BASE::I386OP(and_rm32_r32)() // Opcode 0x21
-{
- UINT32 src, dst;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- src = LOAD_REG32(modrm);
- dst = LOAD_RM32(modrm);
- dst = AND32(dst, src);
- STORE_RM32(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- src = LOAD_REG32(modrm);
- dst = READ32(ea);
- dst = AND32(dst, src);
- WRITE32(ea, dst);
- CYCLES(CYCLES_ALU_REG_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(and_r32_rm32)() // Opcode 0x23
-{
- UINT32 src, dst;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- src = LOAD_RM32(modrm);
- dst = LOAD_REG32(modrm);
- dst = AND32(dst, src);
- STORE_REG32(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,0);
- src = READ32(ea);
- dst = LOAD_REG32(modrm);
- dst = AND32(dst, src);
- STORE_REG32(modrm, dst);
- CYCLES(CYCLES_ALU_MEM_REG);
- }
-}
-
-void I386_OPS_BASE::I386OP(and_eax_i32)() // Opcode 0x25
-{
- UINT32 src, dst;
- src = FETCH32();
- dst = REG32(EAX);
- dst = AND32(dst, src);
- REG32(EAX) = dst;
- CYCLES(CYCLES_ALU_IMM_ACC);
-}
-
-void I386_OPS_BASE::I386OP(bsf_r32_rm32)() // Opcode 0x0f bc
-{
- UINT32 src, dst, temp;
- UINT8 modrm = FETCH();
-
- if( modrm >= 0xc0 ) {
- src = LOAD_RM32(modrm);
- } else {
- UINT32 ea = GetEA(modrm,0);
- src = READ32(ea);
- }
-
- dst = 0;
-
- if( src == 0 ) {
- cpustate->ZF = 1;
- } else {
- cpustate->ZF = 0;
- temp = 0;
- while( (src & (1 << temp)) == 0 ) {
- temp++;
- dst = temp;
- CYCLES(CYCLES_BSF);
- }
- STORE_REG32(modrm, dst);
- }
- CYCLES(CYCLES_BSF_BASE);
-}
-
-void I386_OPS_BASE::I386OP(bsr_r32_rm32)() // Opcode 0x0f bd
-{
- UINT32 src, dst, temp;
- UINT8 modrm = FETCH();
-
- if( modrm >= 0xc0 ) {
- src = LOAD_RM32(modrm);
- } else {
- UINT32 ea = GetEA(modrm,0);
- src = READ32(ea);
- }
-
- dst = 0;
-
- if( src == 0 ) {
- cpustate->ZF = 1;
- } else {
- cpustate->ZF = 0;
- dst = temp = 31;
- while( (src & (1 << temp)) == 0 ) {
- temp--;
- dst = temp;
- CYCLES(CYCLES_BSR);
- }
- STORE_REG32(modrm, dst);
- }
- CYCLES(CYCLES_BSR_BASE);
-}
-
-void I386_OPS_BASE::I386OP(bt_rm32_r32)() // Opcode 0x0f a3
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- UINT32 dst = LOAD_RM32(modrm);
- UINT32 bit = LOAD_REG32(modrm);
-
- if( dst & (1 << bit) )
- cpustate->CF = 1;
- else
- cpustate->CF = 0;
-
- CYCLES(CYCLES_BT_REG_REG);
- } else {
- UINT8 segment;
- UINT32 ea = GetNonTranslatedEA(modrm,&segment);
- UINT32 bit = LOAD_REG32(modrm);
- ea += 4*(bit/32);
- ea = i386_translate(segment,(cpustate->address_size)?ea:(ea&0xffff),0);
- bit %= 32;
- UINT32 dst = READ32(ea);
-
- if( dst & (1 << bit) )
- cpustate->CF = 1;
- else
- cpustate->CF = 0;
-
- CYCLES(CYCLES_BT_REG_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(btc_rm32_r32)() // Opcode 0x0f bb
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- UINT32 dst = LOAD_RM32(modrm);
- UINT32 bit = LOAD_REG32(modrm);
-
- if( dst & (1 << bit) )
- cpustate->CF = 1;
- else
- cpustate->CF = 0;
- dst ^= (1 << bit);
-
- STORE_RM32(modrm, dst);
- CYCLES(CYCLES_BTC_REG_REG);
- } else {
- UINT8 segment;
- UINT32 ea = GetNonTranslatedEA(modrm,&segment);
- UINT32 bit = LOAD_REG32(modrm);
- ea += 4*(bit/32);
- ea = i386_translate(segment,(cpustate->address_size)?ea:(ea&0xffff),1);
- bit %= 32;
- UINT32 dst = READ32(ea);
-
- if( dst & (1 << bit) )
- cpustate->CF = 1;
- else
- cpustate->CF = 0;
- dst ^= (1 << bit);
-
- WRITE32(ea, dst);
- CYCLES(CYCLES_BTC_REG_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(btr_rm32_r32)() // Opcode 0x0f b3
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- UINT32 dst = LOAD_RM32(modrm);
- UINT32 bit = LOAD_REG32(modrm);
-
- if( dst & (1 << bit) )
- cpustate->CF = 1;
- else
- cpustate->CF = 0;
- dst &= ~(1 << bit);
-
- STORE_RM32(modrm, dst);
- CYCLES(CYCLES_BTR_REG_REG);
- } else {
- UINT8 segment;
- UINT32 ea = GetNonTranslatedEA(modrm,&segment);
- UINT32 bit = LOAD_REG32(modrm);
- ea += 4*(bit/32);
- ea = i386_translate(segment,(cpustate->address_size)?ea:(ea&0xffff),1);
- bit %= 32;
- UINT32 dst = READ32(ea);
-
- if( dst & (1 << bit) )
- cpustate->CF = 1;
- else
- cpustate->CF = 0;
- dst &= ~(1 << bit);
-
- WRITE32(ea, dst);
- CYCLES(CYCLES_BTR_REG_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(bts_rm32_r32)() // Opcode 0x0f ab
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- UINT32 dst = LOAD_RM32(modrm);
- UINT32 bit = LOAD_REG32(modrm);
-
- if( dst & (1 << bit) )
- cpustate->CF = 1;
- else
- cpustate->CF = 0;
- dst |= (1 << bit);
-
- STORE_RM32(modrm, dst);
- CYCLES(CYCLES_BTS_REG_REG);
- } else {
- UINT8 segment;
- UINT32 ea = GetNonTranslatedEA(modrm,&segment);
- UINT32 bit = LOAD_REG32(modrm);
- ea += 4*(bit/32);
- ea = i386_translate(segment,(cpustate->address_size)?ea:(ea&0xffff),1);
- bit %= 32;
- UINT32 dst = READ32(ea);
-
- if( dst & (1 << bit) )
- cpustate->CF = 1;
- else
- cpustate->CF = 0;
- dst |= (1 << bit);
-
- WRITE32(ea, dst);
- CYCLES(CYCLES_BTS_REG_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(call_abs32)() // Opcode 0x9a
-{
- UINT32 offset = FETCH32();
- UINT16 ptr = FETCH16();
-
- if(PROTECTED_MODE && !V8086_MODE)
- {
- i386_protected_mode_call(ptr,offset,0,1);
- }
- else
- {
- PUSH32( cpustate->sreg[CS].selector );
- PUSH32( cpustate->eip );
- cpustate->sreg[CS].selector = ptr;
- cpustate->performed_intersegment_jump = 1;
- cpustate->eip = offset;
- i386_load_segment_descriptor(CS);
- }
- CYCLES(CYCLES_CALL_INTERSEG);
- CHANGE_PC(cpustate->eip);
-}
-
-void I386_OPS_BASE::I386OP(call_rel32)() // Opcode 0xe8
-{
- INT32 disp = FETCH32();
- PUSH32( cpustate->eip );
- cpustate->eip += disp;
- CHANGE_PC(cpustate->eip);
- CYCLES(CYCLES_CALL); /* TODO: Timing = 7 + m */
-}
-
-void I386_OPS_BASE::I386OP(cdq)() // Opcode 0x99
-{
- if( REG32(EAX) & 0x80000000 ) {
- REG32(EDX) = 0xffffffff;
- } else {
- REG32(EDX) = 0x00000000;
- }
- CYCLES(CYCLES_CWD);
-}
-
-void I386_OPS_BASE::I386OP(cmp_rm32_r32)() // Opcode 0x39
-{
- UINT32 src, dst;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- src = LOAD_REG32(modrm);
- dst = LOAD_RM32(modrm);
- SUB32(dst, src);
- CYCLES(CYCLES_CMP_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,0);
- src = LOAD_REG32(modrm);
- dst = READ32(ea);
- SUB32(dst, src);
- CYCLES(CYCLES_CMP_REG_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(cmp_r32_rm32)() // Opcode 0x3b
-{
- UINT32 src, dst;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- src = LOAD_RM32(modrm);
- dst = LOAD_REG32(modrm);
- SUB32(dst, src);
- CYCLES(CYCLES_CMP_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,0);
- src = READ32(ea);
- dst = LOAD_REG32(modrm);
- SUB32(dst, src);
- CYCLES(CYCLES_CMP_MEM_REG);
- }
-}
-
-void I386_OPS_BASE::I386OP(cmp_eax_i32)() // Opcode 0x3d
-{
- UINT32 src, dst;
- src = FETCH32();
- dst = REG32(EAX);
- SUB32(dst, src);
- CYCLES(CYCLES_CMP_IMM_ACC);
-}
-
-void I386_OPS_BASE::I386OP(cmpsd)() // Opcode 0xa7
-{
- UINT32 eas, ead, src, dst;
- if( cpustate->segment_prefix ) {
- eas = i386_translate( cpustate->segment_override, cpustate->address_size ? REG32(ESI) : REG16(SI), 0 );
- } else {
- eas = i386_translate( DS, cpustate->address_size ? REG32(ESI) : REG16(SI), 0 );
- }
- ead = i386_translate( ES, cpustate->address_size ? REG32(EDI) : REG16(DI), 0 );
- src = READ32(eas);
- dst = READ32(ead);
- SUB32(src,dst);
- BUMP_SI(4);
- BUMP_DI(4);
- CYCLES(CYCLES_CMPS);
-}
-
-void I386_OPS_BASE::I386OP(cwde)() // Opcode 0x98
-{
- REG32(EAX) = (INT32)((INT16)REG16(AX));
- CYCLES(CYCLES_CBW);
-}
-
-void I386_OPS_BASE::I386OP(dec_eax)() // Opcode 0x48
-{
- REG32(EAX) = DEC32( REG32(EAX) );
- CYCLES(CYCLES_DEC_REG);
-}
-
-void I386_OPS_BASE::I386OP(dec_ecx)() // Opcode 0x49
-{
- REG32(ECX) = DEC32( REG32(ECX) );
- CYCLES(CYCLES_DEC_REG);
-}
-
-void I386_OPS_BASE::I386OP(dec_edx)() // Opcode 0x4a
-{
- REG32(EDX) = DEC32( REG32(EDX) );
- CYCLES(CYCLES_DEC_REG);
-}
-
-void I386_OPS_BASE::I386OP(dec_ebx)() // Opcode 0x4b
-{
- REG32(EBX) = DEC32( REG32(EBX) );
- CYCLES(CYCLES_DEC_REG);
-}
-
-void I386_OPS_BASE::I386OP(dec_esp)() // Opcode 0x4c
-{
- REG32(ESP) = DEC32( REG32(ESP) );
- CYCLES(CYCLES_DEC_REG);
-}
-
-void I386_OPS_BASE::I386OP(dec_ebp)() // Opcode 0x4d
-{
- REG32(EBP) = DEC32( REG32(EBP) );
- CYCLES(CYCLES_DEC_REG);
-}
-
-void I386_OPS_BASE::I386OP(dec_esi)() // Opcode 0x4e
-{
- REG32(ESI) = DEC32( REG32(ESI) );
- CYCLES(CYCLES_DEC_REG);
-}
-
-void I386_OPS_BASE::I386OP(dec_edi)() // Opcode 0x4f
-{
- REG32(EDI) = DEC32( REG32(EDI) );
- CYCLES(CYCLES_DEC_REG);
-}
-
-void I386_OPS_BASE::I386OP(imul_r32_rm32)() // Opcode 0x0f af
-{
- UINT8 modrm = FETCH();
- INT64 result;
- INT64 src, dst;
- if( modrm >= 0xc0 ) {
- src = (INT64)(INT32)LOAD_RM32(modrm);
- CYCLES(CYCLES_IMUL32_REG_REG); /* TODO: Correct multiply timing */
- } else {
- UINT32 ea = GetEA(modrm,0);
- src = (INT64)(INT32)READ32(ea);
- CYCLES(CYCLES_IMUL32_REG_REG); /* TODO: Correct multiply timing */
- }
-
- dst = (INT64)(INT32)LOAD_REG32(modrm);
- result = src * dst;
-
- STORE_REG32(modrm, (UINT32)result);
-
- cpustate->CF = cpustate->OF = !(result == (INT64)(INT32)result);
-}
-
-void I386_OPS_BASE::I386OP(imul_r32_rm32_i32)() // Opcode 0x69
-{
- UINT8 modrm = FETCH();
- INT64 result;
- INT64 src, dst;
- if( modrm >= 0xc0 ) {
- dst = (INT64)(INT32)LOAD_RM32(modrm);
- CYCLES(CYCLES_IMUL32_REG_IMM_REG); /* TODO: Correct multiply timing */
- } else {
- UINT32 ea = GetEA(modrm,0);
- dst = (INT64)(INT32)READ32(ea);
- CYCLES(CYCLES_IMUL32_MEM_IMM_REG); /* TODO: Correct multiply timing */
- }
-
- src = (INT64)(INT32)FETCH32();
- result = src * dst;
-
- STORE_REG32(modrm, (UINT32)result);
-
- cpustate->CF = cpustate->OF = !(result == (INT64)(INT32)result);
-}
-
-void I386_OPS_BASE::I386OP(imul_r32_rm32_i8)() // Opcode 0x6b
-{
- UINT8 modrm = FETCH();
- INT64 result;
- INT64 src, dst;
- if( modrm >= 0xc0 ) {
- dst = (INT64)(INT32)LOAD_RM32(modrm);
- CYCLES(CYCLES_IMUL32_REG_IMM_REG); /* TODO: Correct multiply timing */
- } else {
- UINT32 ea = GetEA(modrm,0);
- dst = (INT64)(INT32)READ32(ea);
- CYCLES(CYCLES_IMUL32_MEM_IMM_REG); /* TODO: Correct multiply timing */
- }
-
- src = (INT64)(INT8)FETCH();
- result = src * dst;
-
- STORE_REG32(modrm, (UINT32)result);
-
- cpustate->CF = cpustate->OF = !(result == (INT64)(INT32)result);
-}
-
-void I386_OPS_BASE::I386OP(in_eax_i8)() // Opcode 0xe5
-{
- UINT16 port = FETCH();
- UINT32 data = READPORT32( port);
- REG32(EAX) = data;
- CYCLES(CYCLES_IN_VAR);
-}
-
-void I386_OPS_BASE::I386OP(in_eax_dx)() // Opcode 0xed
-{
- UINT16 port = REG16(DX);
- UINT32 data = READPORT32( port);
- REG32(EAX) = data;
- CYCLES(CYCLES_IN);
-}
-
-void I386_OPS_BASE::I386OP(inc_eax)() // Opcode 0x40
-{
- REG32(EAX) = INC32( REG32(EAX) );
- CYCLES(CYCLES_INC_REG);
-}
-
-void I386_OPS_BASE::I386OP(inc_ecx)() // Opcode 0x41
-{
- REG32(ECX) = INC32( REG32(ECX) );
- CYCLES(CYCLES_INC_REG);
-}
-
-void I386_OPS_BASE::I386OP(inc_edx)() // Opcode 0x42
-{
- REG32(EDX) = INC32( REG32(EDX) );
- CYCLES(CYCLES_INC_REG);
-}
-
-void I386_OPS_BASE::I386OP(inc_ebx)() // Opcode 0x43
-{
- REG32(EBX) = INC32( REG32(EBX) );
- CYCLES(CYCLES_INC_REG);
-}
-
-void I386_OPS_BASE::I386OP(inc_esp)() // Opcode 0x44
-{
- REG32(ESP) = INC32( REG32(ESP) );
- CYCLES(CYCLES_INC_REG);
-}
-
-void I386_OPS_BASE::I386OP(inc_ebp)() // Opcode 0x45
-{
- REG32(EBP) = INC32( REG32(EBP) );
- CYCLES(CYCLES_INC_REG);
-}
-
-void I386_OPS_BASE::I386OP(inc_esi)() // Opcode 0x46
-{
- REG32(ESI) = INC32( REG32(ESI) );
- CYCLES(CYCLES_INC_REG);
-}
-
-void I386_OPS_BASE::I386OP(inc_edi)() // Opcode 0x47
-{
- REG32(EDI) = INC32( REG32(EDI) );
- CYCLES(CYCLES_INC_REG);
-}
-
-void I386_OPS_BASE::I386OP(iret32)() // Opcode 0xcf
-{
- if( PROTECTED_MODE )
- {
- i386_protected_mode_iret(1);
- }
- else
- {
- /* TODO: #SS(0) exception */
- /* TODO: #GP(0) exception */
- cpustate->eip = POP32();
- cpustate->sreg[CS].selector = POP32() & 0xffff;
- set_flags( POP32() );
- i386_load_segment_descriptor(CS);
- CHANGE_PC(cpustate->eip);
- }
- CYCLES(CYCLES_IRET);
-}
-
-void I386_OPS_BASE::I386OP(ja_rel32)() // Opcode 0x0f 87
-{
- INT32 disp = FETCH32();
- if( cpustate->CF == 0 && cpustate->ZF == 0 ) {
- cpustate->eip += disp;
- CHANGE_PC(cpustate->eip);
- CYCLES(CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */
- } else {
- CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
- }
-}
-
-void I386_OPS_BASE::I386OP(jbe_rel32)() // Opcode 0x0f 86
-{
- INT32 disp = FETCH32();
- if( cpustate->CF != 0 || cpustate->ZF != 0 ) {
- cpustate->eip += disp;
- CHANGE_PC(cpustate->eip);
- CYCLES(CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */
- } else {
- CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
- }
-}
-
-void I386_OPS_BASE::I386OP(jc_rel32)() // Opcode 0x0f 82
-{
- INT32 disp = FETCH32();
- if( cpustate->CF != 0 ) {
- cpustate->eip += disp;
- CHANGE_PC(cpustate->eip);
- CYCLES(CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */
- } else {
- CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
- }
-}
-
-void I386_OPS_BASE::I386OP(jg_rel32)() // Opcode 0x0f 8f
-{
- INT32 disp = FETCH32();
- if( cpustate->ZF == 0 && (cpustate->SF == cpustate->OF) ) {
- cpustate->eip += disp;
- CHANGE_PC(cpustate->eip);
- CYCLES(CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */
- } else {
- CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
- }
-}
-
-void I386_OPS_BASE::I386OP(jge_rel32)() // Opcode 0x0f 8d
-{
- INT32 disp = FETCH32();
- if(cpustate->SF == cpustate->OF) {
- cpustate->eip += disp;
- CHANGE_PC(cpustate->eip);
- CYCLES(CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */
- } else {
- CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
- }
-}
-
-void I386_OPS_BASE::I386OP(jl_rel32)() // Opcode 0x0f 8c
-{
- INT32 disp = FETCH32();
- if( (cpustate->SF != cpustate->OF) ) {
- cpustate->eip += disp;
- CHANGE_PC(cpustate->eip);
- CYCLES(CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */
- } else {
- CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
- }
-}
-
-void I386_OPS_BASE::I386OP(jle_rel32)() // Opcode 0x0f 8e
-{
- INT32 disp = FETCH32();
- if( cpustate->ZF != 0 || (cpustate->SF != cpustate->OF) ) {
- cpustate->eip += disp;
- CHANGE_PC(cpustate->eip);
- CYCLES(CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */
- } else {
- CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
- }
-}
-
-void I386_OPS_BASE::I386OP(jnc_rel32)() // Opcode 0x0f 83
-{
- INT32 disp = FETCH32();
- if( cpustate->CF == 0 ) {
- cpustate->eip += disp;
- CHANGE_PC(cpustate->eip);
- CYCLES(CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */
- } else {
- CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
- }
-}
-
-void I386_OPS_BASE::I386OP(jno_rel32)() // Opcode 0x0f 81
-{
- INT32 disp = FETCH32();
- if( cpustate->OF == 0 ) {
- cpustate->eip += disp;
- CHANGE_PC(cpustate->eip);
- CYCLES(CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */
- } else {
- CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
- }
-}
-
-void I386_OPS_BASE::I386OP(jnp_rel32)() // Opcode 0x0f 8b
-{
- INT32 disp = FETCH32();
- if( cpustate->PF == 0 ) {
- cpustate->eip += disp;
- CHANGE_PC(cpustate->eip);
- CYCLES(CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */
- } else {
- CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
- }
-}
-
-void I386_OPS_BASE::I386OP(jns_rel32)() // Opcode 0x0f 89
-{
- INT32 disp = FETCH32();
- if( cpustate->SF == 0 ) {
- cpustate->eip += disp;
- CHANGE_PC(cpustate->eip);
- CYCLES(CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */
- } else {
- CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
- }
-}
-
-void I386_OPS_BASE::I386OP(jnz_rel32)() // Opcode 0x0f 85
-{
- INT32 disp = FETCH32();
- if( cpustate->ZF == 0 ) {
- cpustate->eip += disp;
- CHANGE_PC(cpustate->eip);
- CYCLES(CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */
- } else {
- CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
- }
-}
-
-void I386_OPS_BASE::I386OP(jo_rel32)() // Opcode 0x0f 80
-{
- INT32 disp = FETCH32();
- if( cpustate->OF != 0 ) {
- cpustate->eip += disp;
- CHANGE_PC(cpustate->eip);
- CYCLES(CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */
- } else {
- CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
- }
-}
-
-void I386_OPS_BASE::I386OP(jp_rel32)() // Opcode 0x0f 8a
-{
- INT32 disp = FETCH32();
- if( cpustate->PF != 0 ) {
- cpustate->eip += disp;
- CHANGE_PC(cpustate->eip);
- CYCLES(CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */
- } else {
- CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
- }
-}
-
-void I386_OPS_BASE::I386OP(js_rel32)() // Opcode 0x0f 88
-{
- INT32 disp = FETCH32();
- if( cpustate->SF != 0 ) {
- cpustate->eip += disp;
- CHANGE_PC(cpustate->eip);
- CYCLES(CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */
- } else {
- CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
- }
-}
-
-void I386_OPS_BASE::I386OP(jz_rel32)() // Opcode 0x0f 84
-{
- INT32 disp = FETCH32();
- if( cpustate->ZF != 0 ) {
- cpustate->eip += disp;
- CHANGE_PC(cpustate->eip);
- CYCLES(CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */
- } else {
- CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
- }
-}
-
-void I386_OPS_BASE::I386OP(jcxz32)() // Opcode 0xe3
-{
- INT8 disp = FETCH();
- int val = (cpustate->address_size)?(REG32(ECX) == 0):(REG16(CX) == 0);
- if( val ) {
- cpustate->eip += disp;
- CHANGE_PC(cpustate->eip);
- CYCLES(CYCLES_JCXZ); /* TODO: Timing = 9 + m */
- } else {
- CYCLES(CYCLES_JCXZ_NOBRANCH);
- }
-}
-
-void I386_OPS_BASE::I386OP(jmp_rel32)() // Opcode 0xe9
-{
- UINT32 disp = FETCH32();
- /* TODO: Segment limit */
- cpustate->eip += disp;
- CHANGE_PC(cpustate->eip);
- CYCLES(CYCLES_JMP); /* TODO: Timing = 7 + m */
-}
-
-void I386_OPS_BASE::I386OP(jmp_abs32)() // Opcode 0xea
-{
- UINT32 address = FETCH32();
- UINT16 segment = FETCH16();
-
- if( PROTECTED_MODE && !V8086_MODE)
- {
- i386_protected_mode_jump(segment,address,0,1);
- }
- else
- {
- cpustate->eip = address;
- cpustate->sreg[CS].selector = segment;
- cpustate->performed_intersegment_jump = 1;
- i386_load_segment_descriptor(CS);
- CHANGE_PC(cpustate->eip);
- }
- CYCLES(CYCLES_JMP_INTERSEG);
-}
-
-void I386_OPS_BASE::I386OP(lea32)() // Opcode 0x8d
-{
- UINT8 modrm = FETCH();
- UINT32 ea = GetNonTranslatedEA(modrm,NULL);
- if (!cpustate->address_size)
- {
- ea &= 0xffff;
- }
- STORE_REG32(modrm, ea);
- CYCLES(CYCLES_LEA);
-}
-
-void I386_OPS_BASE::I386OP(enter32)() // Opcode 0xc8
-{
- UINT16 framesize = FETCH16();
- UINT8 level = FETCH() % 32;
- UINT8 x;
- UINT32 frameptr;
- PUSH32(REG32(EBP));
- if(!STACK_32BIT)
- frameptr = REG16(SP);
- else
- frameptr = REG32(ESP);
-
- if(level > 0)
- {
- for(x=1;x<level-1;x++)
- {
- REG32(EBP) -= 4;
- PUSH32(READ32(REG32(EBP)));
- }
- PUSH32(frameptr);
- }
- REG32(EBP) = frameptr;
- if(!STACK_32BIT)
- REG16(SP) -= framesize;
- else
- REG32(ESP) -= framesize;
- CYCLES(CYCLES_ENTER);
-}
-
-void I386_OPS_BASE::I386OP(leave32)() // Opcode 0xc9
-{
- if(!STACK_32BIT)
- REG16(SP) = REG16(BP);
- else
- REG32(ESP) = REG32(EBP);
- REG32(EBP) = POP32();
- CYCLES(CYCLES_LEAVE);
-}
-
-void I386_OPS_BASE::I386OP(lodsd)() // Opcode 0xad
-{
- UINT32 eas;
- if( cpustate->segment_prefix ) {
- eas = i386_translate( cpustate->segment_override, cpustate->address_size ? REG32(ESI) : REG16(SI), 0 );
- } else {
- eas = i386_translate( DS, cpustate->address_size ? REG32(ESI) : REG16(SI), 0 );
- }
- REG32(EAX) = READ32(eas);
- BUMP_SI(4);
- CYCLES(CYCLES_LODS);
-}
-
-void I386_OPS_BASE::I386OP(loop32)() // Opcode 0xe2
-{
- INT8 disp = FETCH();
- INT32 reg = (cpustate->address_size)?--REG32(ECX):--REG16(CX);
- if( reg != 0 ) {
- cpustate->eip += disp;
- CHANGE_PC(cpustate->eip);
- }
- CYCLES(CYCLES_LOOP); /* TODO: Timing = 11 + m */
-}
-
-void I386_OPS_BASE::I386OP(loopne32)() // Opcode 0xe0
-{
- INT8 disp = FETCH();
- INT32 reg = (cpustate->address_size)?--REG32(ECX):--REG16(CX);
- if( reg != 0 && cpustate->ZF == 0 ) {
- cpustate->eip += disp;
- CHANGE_PC(cpustate->eip);
- }
- CYCLES(CYCLES_LOOPNZ); /* TODO: Timing = 11 + m */
-}
-
-void I386_OPS_BASE::I386OP(loopz32)() // Opcode 0xe1
-{
- INT8 disp = FETCH();
- INT32 reg = (cpustate->address_size)?--REG32(ECX):--REG16(CX);
- if( reg != 0 && cpustate->ZF != 0 ) {
- cpustate->eip += disp;
- CHANGE_PC(cpustate->eip);
- }
- CYCLES(CYCLES_LOOPZ); /* TODO: Timing = 11 + m */
-}
-
-void I386_OPS_BASE::I386OP(mov_rm32_r32)() // Opcode 0x89
-{
- UINT32 src;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- src = LOAD_REG32(modrm);
- STORE_RM32(modrm, src);
- CYCLES(CYCLES_MOV_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- src = LOAD_REG32(modrm);
- WRITE32(ea, src);
- CYCLES(CYCLES_MOV_REG_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(mov_r32_rm32)() // Opcode 0x8b
-{
- UINT32 src;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- src = LOAD_RM32(modrm);
- STORE_REG32(modrm, src);
- CYCLES(CYCLES_MOV_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,0);
- src = READ32(ea);
- STORE_REG32(modrm, src);
- CYCLES(CYCLES_MOV_MEM_REG);
- }
-}
-
-void I386_OPS_BASE::I386OP(mov_rm32_i32)() // Opcode 0xc7
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- UINT32 value = FETCH32();
- STORE_RM32(modrm, value);
- CYCLES(CYCLES_MOV_IMM_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- UINT32 value = FETCH32();
- WRITE32(ea, value);
- CYCLES(CYCLES_MOV_IMM_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(mov_eax_m32)() // Opcode 0xa1
-{
- UINT32 offset, ea;
- if( cpustate->address_size ) {
- offset = FETCH32();
- } else {
- offset = FETCH16();
- }
- if( cpustate->segment_prefix ) {
- ea = i386_translate( cpustate->segment_override, offset, 0 );
- } else {
- ea = i386_translate( DS, offset, 0 );
- }
- REG32(EAX) = READ32(ea);
- CYCLES(CYCLES_MOV_MEM_ACC);
-}
-
-void I386_OPS_BASE::I386OP(mov_m32_eax)() // Opcode 0xa3
-{
- UINT32 offset, ea;
- if( cpustate->address_size ) {
- offset = FETCH32();
- } else {
- offset = FETCH16();
- }
- if( cpustate->segment_prefix ) {
- ea = i386_translate( cpustate->segment_override, offset, 1 );
- } else {
- ea = i386_translate( DS, offset, 1 );
- }
- WRITE32( ea, REG32(EAX) );
- CYCLES(CYCLES_MOV_ACC_MEM);
-}
-
-void I386_OPS_BASE::I386OP(mov_eax_i32)() // Opcode 0xb8
-{
- REG32(EAX) = FETCH32();
- CYCLES(CYCLES_MOV_IMM_REG);
-}
-
-void I386_OPS_BASE::I386OP(mov_ecx_i32)() // Opcode 0xb9
-{
- REG32(ECX) = FETCH32();
- CYCLES(CYCLES_MOV_IMM_REG);
-}
-
-void I386_OPS_BASE::I386OP(mov_edx_i32)() // Opcode 0xba
-{
- REG32(EDX) = FETCH32();
- CYCLES(CYCLES_MOV_IMM_REG);
-}
-
-void I386_OPS_BASE::I386OP(mov_ebx_i32)() // Opcode 0xbb
-{
- REG32(EBX) = FETCH32();
- CYCLES(CYCLES_MOV_IMM_REG);
-}
-
-void I386_OPS_BASE::I386OP(mov_esp_i32)() // Opcode 0xbc
-{
- REG32(ESP) = FETCH32();
- CYCLES(CYCLES_MOV_IMM_REG);
-}
-
-void I386_OPS_BASE::I386OP(mov_ebp_i32)() // Opcode 0xbd
-{
- REG32(EBP) = FETCH32();
- CYCLES(CYCLES_MOV_IMM_REG);
-}
-
-void I386_OPS_BASE::I386OP(mov_esi_i32)() // Opcode 0xbe
-{
- REG32(ESI) = FETCH32();
- CYCLES(CYCLES_MOV_IMM_REG);
-}
-
-void I386_OPS_BASE::I386OP(mov_edi_i32)() // Opcode 0xbf
-{
- REG32(EDI) = FETCH32();
- CYCLES(CYCLES_MOV_IMM_REG);
-}
-
-void I386_OPS_BASE::I386OP(movsd)() // Opcode 0xa5
-{
- UINT32 eas, ead, v;
- if( cpustate->segment_prefix ) {
- eas = i386_translate( cpustate->segment_override, cpustate->address_size ? REG32(ESI) : REG16(SI), 0 );
- } else {
- eas = i386_translate( DS, cpustate->address_size ? REG32(ESI) : REG16(SI), 0 );
- }
- ead = i386_translate( ES, cpustate->address_size ? REG32(EDI) : REG16(DI), 1 );
- v = READ32(eas);
- WRITE32(ead, v);
- BUMP_SI(4);
- BUMP_DI(4);
- CYCLES(CYCLES_MOVS);
-}
-
-void I386_OPS_BASE::I386OP(movsx_r32_rm8)() // Opcode 0x0f be
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- INT32 src = (INT8)LOAD_RM8(modrm);
- STORE_REG32(modrm, src);
- CYCLES(CYCLES_MOVSX_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,0);
- INT32 src = (INT8)READ8(ea);
- STORE_REG32(modrm, src);
- CYCLES(CYCLES_MOVSX_MEM_REG);
- }
-}
-
-void I386_OPS_BASE::I386OP(movsx_r32_rm16)() // Opcode 0x0f bf
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- INT32 src = (INT16)LOAD_RM16(modrm);
- STORE_REG32(modrm, src);
- CYCLES(CYCLES_MOVSX_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,0);
- INT32 src = (INT16)READ16(ea);
- STORE_REG32(modrm, src);
- CYCLES(CYCLES_MOVSX_MEM_REG);
- }
-}
-
-void I386_OPS_BASE::I386OP(movzx_r32_rm8)() // Opcode 0x0f b6
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- UINT32 src = (UINT8)LOAD_RM8(modrm);
- STORE_REG32(modrm, src);
- CYCLES(CYCLES_MOVZX_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,0);
- UINT32 src = (UINT8)READ8(ea);
- STORE_REG32(modrm, src);
- CYCLES(CYCLES_MOVZX_MEM_REG);
- }
-}
-
-void I386_OPS_BASE::I386OP(movzx_r32_rm16)() // Opcode 0x0f b7
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- UINT32 src = (UINT16)LOAD_RM16(modrm);
- STORE_REG32(modrm, src);
- CYCLES(CYCLES_MOVZX_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,0);
- UINT32 src = (UINT16)READ16(ea);
- STORE_REG32(modrm, src);
- CYCLES(CYCLES_MOVZX_MEM_REG);
- }
-}
-
-void I386_OPS_BASE::I386OP(or_rm32_r32)() // Opcode 0x09
-{
- UINT32 src, dst;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- src = LOAD_REG32(modrm);
- dst = LOAD_RM32(modrm);
- dst = OR32(dst, src);
- STORE_RM32(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- src = LOAD_REG32(modrm);
- dst = READ32(ea);
- dst = OR32(dst, src);
- WRITE32(ea, dst);
- CYCLES(CYCLES_ALU_REG_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(or_r32_rm32)() // Opcode 0x0b
-{
- UINT32 src, dst;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- src = LOAD_RM32(modrm);
- dst = LOAD_REG32(modrm);
- dst = OR32(dst, src);
- STORE_REG32(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,0);
- src = READ32(ea);
- dst = LOAD_REG32(modrm);
- dst = OR32(dst, src);
- STORE_REG32(modrm, dst);
- CYCLES(CYCLES_ALU_MEM_REG);
- }
-}
-
-void I386_OPS_BASE::I386OP(or_eax_i32)() // Opcode 0x0d
-{
- UINT32 src, dst;
- src = FETCH32();
- dst = REG32(EAX);
- dst = OR32(dst, src);
- REG32(EAX) = dst;
- CYCLES(CYCLES_ALU_IMM_ACC);
-}
-
-void I386_OPS_BASE::I386OP(out_eax_i8)() // Opcode 0xe7
-{
- UINT16 port = FETCH();
- UINT32 data = REG32(EAX);
- WRITEPORT32( port, data);
- CYCLES(CYCLES_OUT_VAR);
-}
-
-void I386_OPS_BASE::I386OP(out_eax_dx)() // Opcode 0xef
-{
- UINT16 port = REG16(DX);
- UINT32 data = REG32(EAX);
- WRITEPORT32( port, data);
- CYCLES(CYCLES_OUT);
-}
-
-void I386_OPS_BASE::I386OP(pop_eax)() // Opcode 0x58
-{
- UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
- if(i386_limit_check(SS,offset+3) == 0)
- REG32(EAX) = POP32();
- else
- FAULT(FAULT_SS,0)
- CYCLES(CYCLES_POP_REG_SHORT);
-}
-
-void I386_OPS_BASE::I386OP(pop_ecx)() // Opcode 0x59
-{
- UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
- if(i386_limit_check(SS,offset+3) == 0)
- REG32(ECX) = POP32();
- else
- FAULT(FAULT_SS,0)
- CYCLES(CYCLES_POP_REG_SHORT);
-}
-
-void I386_OPS_BASE::I386OP(pop_edx)() // Opcode 0x5a
-{
- UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
- if(i386_limit_check(SS,offset+3) == 0)
- REG32(EDX) = POP32();
- else
- FAULT(FAULT_SS,0)
- CYCLES(CYCLES_POP_REG_SHORT);
-}
-
-void I386_OPS_BASE::I386OP(pop_ebx)() // Opcode 0x5b
-{
- UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
- if(i386_limit_check(SS,offset+3) == 0)
- REG32(EBX) = POP32();
- else
- FAULT(FAULT_SS,0)
- CYCLES(CYCLES_POP_REG_SHORT);
-}
-
-void I386_OPS_BASE::I386OP(pop_esp)() // Opcode 0x5c
-{
- UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
- if(i386_limit_check(SS,offset+3) == 0)
- REG32(ESP) = POP32();
- else
- FAULT(FAULT_SS,0)
- CYCLES(CYCLES_POP_REG_SHORT);
-}
-
-void I386_OPS_BASE::I386OP(pop_ebp)() // Opcode 0x5d
-{
- UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
- if(i386_limit_check(SS,offset+3) == 0)
- REG32(EBP) = POP32();
- else
- FAULT(FAULT_SS,0)
- CYCLES(CYCLES_POP_REG_SHORT);
-}
-
-void I386_OPS_BASE::I386OP(pop_esi)() // Opcode 0x5e
-{
- UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
- if(i386_limit_check(SS,offset+3) == 0)
- REG32(ESI) = POP32();
- else
- FAULT(FAULT_SS,0)
- CYCLES(CYCLES_POP_REG_SHORT);
-}
-
-void I386_OPS_BASE::I386OP(pop_edi)() // Opcode 0x5f
-{
- UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
- if(i386_limit_check(SS,offset+3) == 0)
- REG32(EDI) = POP32();
- else
- FAULT(FAULT_SS,0)
- CYCLES(CYCLES_POP_REG_SHORT);
-}
-
-bool I386_OPS_BASE::I386OP(pop_seg32)( int segment)
-{
- UINT32 ea, offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
- UINT32 value;
- bool fault;
- if(i386_limit_check(SS,offset+3) == 0)
- {
- ea = i386_translate( SS, offset, 0);
- value = READ32( ea);
- i386_sreg_load(value, segment, &fault);
- if(fault) return false;
- if(STACK_32BIT)
- REG32(ESP) = offset + 4;
- else
- REG16(SP) = offset + 4;
- }
- else
- {
- cpustate->ext = 1;
- i386_trap_with_error(FAULT_SS,0,0,0);
- return false;
- }
- CYCLES(CYCLES_POP_SREG);
- return true;
-}
-
-void I386_OPS_BASE::I386OP(pop_ds32)() // Opcode 0x1f
-{
- I386OP(pop_seg32)( DS);
-}
-
-void I386_OPS_BASE::I386OP(pop_es32)() // Opcode 0x07
-{
- I386OP(pop_seg32)( ES);
-}
-
-void I386_OPS_BASE::I386OP(pop_fs32)() // Opcode 0x0f a1
-{
- I386OP(pop_seg32)( FS);
-}
-
-void I386_OPS_BASE::I386OP(pop_gs32)() // Opcode 0x0f a9
-{
- I386OP(pop_seg32)( GS);
-}
-
-void I386_OPS_BASE::I386OP(pop_ss32)() // Opcode 0x17
-{
- if(!I386OP(pop_seg32)( SS)) return;
- if(cpustate->IF != 0) // if external interrupts are enabled
- {
- cpustate->IF = 0; // reset IF for the next instruction
- cpustate->delayed_interrupt_enable = 1;
- }
-}
-
-void I386_OPS_BASE::I386OP(pop_rm32)() // Opcode 0x8f
-{
- UINT8 modrm = FETCH();
- UINT32 value;
- UINT32 ea, offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
- if(i386_limit_check(SS,offset+3) == 0)
- {
- // be careful here, if the write references the esp register
- // it expects the post-pop value but esp must be wound back
- // if the write faults
- UINT32 temp_sp = REG32(ESP);
- value = POP32();
-
- if( modrm >= 0xc0 ) {
- STORE_RM32(modrm, value);
- } else {
- ea = GetEA(modrm,1);
- try
- {
- WRITE32(ea, value);
- }
- catch(UINT64 e)
- {
- REG32(ESP) = temp_sp;
- throw e;
- }
- }
- }
- else
- FAULT(FAULT_SS,0)
- CYCLES(CYCLES_POP_RM);
-}
-
-void I386_OPS_BASE::I386OP(popad)() // Opcode 0x61
-{
- UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
- if(i386_limit_check(SS,offset+31) == 0)
- {
- REG32(EDI) = POP32();
- REG32(ESI) = POP32();
- REG32(EBP) = POP32();
- REG32(ESP) += 4;
- REG32(EBX) = POP32();
- REG32(EDX) = POP32();
- REG32(ECX) = POP32();
- REG32(EAX) = POP32();
- }
- else
- FAULT(FAULT_SS,0)
- CYCLES(CYCLES_POPA);
-}
-
-void I386_OPS_BASE::I386OP(popfd)() // Opcode 0x9d
-{
- UINT32 value;
- UINT32 current = get_flags();
- UINT8 IOPL = (current >> 12) & 0x03;
- UINT32 mask = 0x00257fd5; // VM, VIP and VIF cannot be set by POPF/POPFD
- UINT32 offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
-
- // IOPL can only change if CPL is 0
- if(cpustate->CPL != 0)
- mask &= ~0x00003000;
-
- // IF can only change if CPL is at least as privileged as IOPL
- if(cpustate->CPL > IOPL)
- mask &= ~0x00000200;
-
- if(V8086_MODE)
- {
- if(IOPL < 3)
- {
- logerror("POPFD(%08x): IOPL < 3 while in V86 mode.\n",cpustate->pc);
- FAULT(FAULT_GP,0) // #GP(0)
- }
- mask &= ~0x00003000; // IOPL cannot be changed while in V8086 mode
- }
-
- if(i386_limit_check(SS,offset+3) == 0)
- {
- value = POP32();
- value &= ~0x00010000; // RF will always return zero
- set_flags((current & ~mask) | (value & mask)); // mask out reserved bits
- }
- else
- FAULT(FAULT_SS,0)
- CYCLES(CYCLES_POPF);
-}
-
-void I386_OPS_BASE::I386OP(push_eax)() // Opcode 0x50
-{
- UINT32 offset;
- if(STACK_32BIT)
- offset = REG32(ESP) - 4;
- else
- offset = (REG16(SP) - 4) & 0xffff;
- if(i386_limit_check(SS,offset) == 0)
- PUSH32( REG32(EAX) );
- else
- FAULT(FAULT_SS,0)
- CYCLES(CYCLES_PUSH_REG_SHORT);
-}
-
-void I386_OPS_BASE::I386OP(push_ecx)() // Opcode 0x51
-{
- UINT32 offset;
- if(STACK_32BIT)
- offset = REG32(ESP) - 4;
- else
- offset = (REG16(SP) - 4) & 0xffff;
- if(i386_limit_check(SS,offset) == 0)
- PUSH32( REG32(ECX) );
- else
- FAULT(FAULT_SS,0)
- CYCLES(CYCLES_PUSH_REG_SHORT);
-}
-
-void I386_OPS_BASE::I386OP(push_edx)() // Opcode 0x52
-{
- UINT32 offset;
- if(STACK_32BIT)
- offset = REG32(ESP) - 4;
- else
- offset = (REG16(SP) - 4) & 0xffff;
- if(i386_limit_check(SS,offset) == 0)
- PUSH32( REG32(EDX) );
- else
- FAULT(FAULT_SS,0)
- CYCLES(CYCLES_PUSH_REG_SHORT);
-}
-
-void I386_OPS_BASE::I386OP(push_ebx)() // Opcode 0x53
-{
- UINT32 offset;
- if(STACK_32BIT)
- offset = REG32(ESP) - 4;
- else
- offset = (REG16(SP) - 4) & 0xffff;
- if(i386_limit_check(SS,offset) == 0)
- PUSH32( REG32(EBX) );
- else
- FAULT(FAULT_SS,0)
- CYCLES(CYCLES_PUSH_REG_SHORT);
-}
-
-void I386_OPS_BASE::I386OP(push_esp)() // Opcode 0x54
-{
- UINT32 offset;
- if(STACK_32BIT)
- offset = REG32(ESP) - 4;
- else
- offset = (REG16(SP) - 4) & 0xffff;
- if(i386_limit_check(SS,offset) == 0)
- PUSH32( REG32(ESP) );
- else
- FAULT(FAULT_SS,0)
- CYCLES(CYCLES_PUSH_REG_SHORT);
-}
-
-void I386_OPS_BASE::I386OP(push_ebp)() // Opcode 0x55
-{
- UINT32 offset;
- if(STACK_32BIT)
- offset = REG32(ESP) - 4;
- else
- offset = (REG16(SP) - 4) & 0xffff;
- if(i386_limit_check(SS,offset) == 0)
- PUSH32( REG32(EBP) );
- else
- FAULT(FAULT_SS,0)
- CYCLES(CYCLES_PUSH_REG_SHORT);
-}
-
-void I386_OPS_BASE::I386OP(push_esi)() // Opcode 0x56
-{
- UINT32 offset;
- if(STACK_32BIT)
- offset = REG32(ESP) - 4;
- else
- offset = (REG16(SP) - 4) & 0xffff;
- if(i386_limit_check(SS,offset) == 0)
- PUSH32( REG32(ESI) );
- else
- FAULT(FAULT_SS,0)
- CYCLES(CYCLES_PUSH_REG_SHORT);
-}
-
-void I386_OPS_BASE::I386OP(push_edi)() // Opcode 0x57
-{
- UINT32 offset;
- if(STACK_32BIT)
- offset = REG32(ESP) - 4;
- else
- offset = (REG16(SP) - 4) & 0xffff;
- if(i386_limit_check(SS,offset) == 0)
- PUSH32( REG32(EDI) );
- else
- FAULT(FAULT_SS,0)
- CYCLES(CYCLES_PUSH_REG_SHORT);
-}
-
-void I386_OPS_BASE::I386OP(push_cs32)() // Opcode 0x0e
-{
- UINT32 offset;
- if(STACK_32BIT)
- offset = REG32(ESP) - 4;
- else
- offset = (REG16(SP) - 4) & 0xffff;
- if(i386_limit_check(SS,offset) == 0)
- PUSH32( cpustate->sreg[CS].selector );
- else
- FAULT(FAULT_SS,0)
- CYCLES(CYCLES_PUSH_SREG);
-}
-
-void I386_OPS_BASE::I386OP(push_ds32)() // Opcode 0x1e
-{
- UINT32 offset;
- if(STACK_32BIT)
- offset = REG32(ESP) - 4;
- else
- offset = (REG16(SP) - 4) & 0xffff;
- if(i386_limit_check(SS,offset) == 0)
- PUSH32( cpustate->sreg[DS].selector );
- else
- FAULT(FAULT_SS,0)
- CYCLES(CYCLES_PUSH_SREG);
-}
-
-void I386_OPS_BASE::I386OP(push_es32)() // Opcode 0x06
-{
- UINT32 offset;
- if(STACK_32BIT)
- offset = REG32(ESP) - 4;
- else
- offset = (REG16(SP) - 4) & 0xffff;
- if(i386_limit_check(SS,offset) == 0)
- PUSH32( cpustate->sreg[ES].selector );
- else
- FAULT(FAULT_SS,0)
- CYCLES(CYCLES_PUSH_SREG);
-}
-
-void I386_OPS_BASE::I386OP(push_fs32)() // Opcode 0x0f a0
-{
- UINT32 offset;
- if(STACK_32BIT)
- offset = REG32(ESP) - 4;
- else
- offset = (REG16(SP) - 4) & 0xffff;
- if(i386_limit_check(SS,offset) == 0)
- PUSH32( cpustate->sreg[FS].selector );
- else
- FAULT(FAULT_SS,0)
- CYCLES(CYCLES_PUSH_SREG);
-}
-
-void I386_OPS_BASE::I386OP(push_gs32)() // Opcode 0x0f a8
-{
- UINT32 offset;
- if(STACK_32BIT)
- offset = REG32(ESP) - 4;
- else
- offset = (REG16(SP) - 4) & 0xffff;
- if(i386_limit_check(SS,offset) == 0)
- PUSH32( cpustate->sreg[GS].selector );
- else
- FAULT(FAULT_SS,0)
- CYCLES(CYCLES_PUSH_SREG);
-}
-
-void I386_OPS_BASE::I386OP(push_ss32)() // Opcode 0x16
-{
- UINT32 offset;
- if(STACK_32BIT)
- offset = REG32(ESP) - 4;
- else
- offset = (REG16(SP) - 4) & 0xffff;
- if(i386_limit_check(SS,offset) == 0)
- PUSH32( cpustate->sreg[SS].selector );
- else
- FAULT(FAULT_SS,0)
- CYCLES(CYCLES_PUSH_SREG);
-}
-
-void I386_OPS_BASE::I386OP(push_i32)() // Opcode 0x68
-{
- UINT32 value = FETCH32();
- UINT32 offset;
- if(STACK_32BIT)
- offset = REG32(ESP) - 4;
- else
- offset = (REG16(SP) - 4) & 0xffff;
- if(i386_limit_check(SS,offset) == 0)
- PUSH32(value);
- else
- FAULT(FAULT_SS,0)
- CYCLES(CYCLES_PUSH_IMM);
-}
-
-void I386_OPS_BASE::I386OP(pushad)() // Opcode 0x60
-{
- UINT32 temp = REG32(ESP);
- UINT32 offset;
- if(STACK_32BIT)
- offset = REG32(ESP) - 32;
- else
- offset = (REG16(SP) - 32) & 0xffff;
- if(i386_limit_check(SS,offset) == 0)
- {
- PUSH32( REG32(EAX) );
- PUSH32( REG32(ECX) );
- PUSH32( REG32(EDX) );
- PUSH32( REG32(EBX) );
- PUSH32( temp );
- PUSH32( REG32(EBP) );
- PUSH32( REG32(ESI) );
- PUSH32( REG32(EDI) );
- }
- else
- FAULT(FAULT_SS,0)
- CYCLES(CYCLES_PUSHA);
-}
-
-void I386_OPS_BASE::I386OP(pushfd)() // Opcode 0x9c
-{
- if(!cpustate->IOP1 && !cpustate->IOP2 && V8086_MODE)
- FAULT(FAULT_GP,0)
- UINT32 offset;
- if(STACK_32BIT)
- offset = REG32(ESP) - 4;
- else
- offset = (REG16(SP) - 4) & 0xffff;
- if(i386_limit_check(SS,offset) == 0)
- PUSH32( get_flags() & 0x00fcffff );
- else
- FAULT(FAULT_SS,0)
- CYCLES(CYCLES_PUSHF);
-}
-
-void I386_OPS_BASE::I386OP(ret_near32_i16)() // Opcode 0xc2
-{
- INT16 disp = FETCH16();
- cpustate->eip = POP32();
- REG32(ESP) += disp;
- CHANGE_PC(cpustate->eip);
- CYCLES(CYCLES_RET_IMM); /* TODO: Timing = 10 + m */
-}
-
-void I386_OPS_BASE::I386OP(ret_near32)() // Opcode 0xc3
-{
- cpustate->eip = POP32();
- CHANGE_PC(cpustate->eip);
- CYCLES(CYCLES_RET); /* TODO: Timing = 10 + m */
-}
-
-void I386_OPS_BASE::I386OP(sbb_rm32_r32)() // Opcode 0x19
-{
- UINT32 src, dst;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- src = LOAD_REG32(modrm);
- dst = LOAD_RM32(modrm);
- dst = SBB32( dst, src, cpustate->CF);
- STORE_RM32(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- src = LOAD_REG32(modrm);
- dst = READ32(ea);
- dst = SBB32( dst, src, cpustate->CF);
- WRITE32(ea, dst);
- CYCLES(CYCLES_ALU_REG_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(sbb_r32_rm32)() // Opcode 0x1b
-{
- UINT32 src, dst;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- src = LOAD_RM32(modrm);
- dst = LOAD_REG32(modrm);
- dst = SBB32( dst, src, cpustate->CF);
- STORE_REG32(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,0);
- src = READ32(ea);
- dst = LOAD_REG32(modrm);
- dst = SBB32( dst, src, cpustate->CF);
- STORE_REG32(modrm, dst);
- CYCLES(CYCLES_ALU_MEM_REG);
- }
-}
-
-void I386_OPS_BASE::I386OP(sbb_eax_i32)() // Opcode 0x1d
-{
- UINT32 src, dst;
- src = FETCH32();
- dst = REG32(EAX);
- dst = SBB32( dst, src, cpustate->CF);
- REG32(EAX) = dst;
- CYCLES(CYCLES_ALU_IMM_ACC);
-}
-
-void I386_OPS_BASE::I386OP(scasd)() // Opcode 0xaf
-{
- UINT32 eas, src, dst;
- eas = i386_translate( ES, cpustate->address_size ? REG32(EDI) : REG16(DI), 0 );
- src = READ32(eas);
- dst = REG32(EAX);
- SUB32(dst, src);
- BUMP_DI(4);
- CYCLES(CYCLES_SCAS);
-}
-
-void I386_OPS_BASE::I386OP(shld32_i8)() // Opcode 0x0f a4
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- UINT32 dst = LOAD_RM32(modrm);
- UINT32 upper = LOAD_REG32(modrm);
- UINT8 shift = FETCH();
- shift &= 31;
- if( shift == 0 ) {
- } else {
- cpustate->CF = (dst & (1 << (32-shift))) ? 1 : 0;
- dst = (dst << shift) | (upper >> (32-shift));
- cpustate->OF = cpustate->CF ^ (dst >> 31);
- SetSZPF32(dst);
- }
- STORE_RM32(modrm, dst);
- CYCLES(CYCLES_SHLD_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- UINT32 dst = READ32(ea);
- UINT32 upper = LOAD_REG32(modrm);
- UINT8 shift = FETCH();
- shift &= 31;
- if( shift == 0 ) {
- } else {
- cpustate->CF = (dst & (1 << (32-shift))) ? 1 : 0;
- dst = (dst << shift) | (upper >> (32-shift));
- cpustate->OF = cpustate->CF ^ (dst >> 31);
- SetSZPF32(dst);
- }
- WRITE32(ea, dst);
- CYCLES(CYCLES_SHLD_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(shld32_cl)() // Opcode 0x0f a5
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- UINT32 dst = LOAD_RM32(modrm);
- UINT32 upper = LOAD_REG32(modrm);
- UINT8 shift = REG8(CL);
- shift &= 31;
- if( shift == 0 ) {
- } else {
- cpustate->CF = (dst & (1 << (32-shift))) ? 1 : 0;
- dst = (dst << shift) | (upper >> (32-shift));
- cpustate->OF = cpustate->CF ^ (dst >> 31);
- SetSZPF32(dst);
- }
- STORE_RM32(modrm, dst);
- CYCLES(CYCLES_SHLD_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- UINT32 dst = READ32(ea);
- UINT32 upper = LOAD_REG32(modrm);
- UINT8 shift = REG8(CL);
- shift &= 31;
- if( shift == 0 ) {
- } else {
- cpustate->CF = (dst & (1 << (32-shift))) ? 1 : 0;
- dst = (dst << shift) | (upper >> (32-shift));
- cpustate->OF = cpustate->CF ^ (dst >> 31);
- SetSZPF32(dst);
- }
- WRITE32(ea, dst);
- CYCLES(CYCLES_SHLD_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(shrd32_i8)() // Opcode 0x0f ac
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- UINT32 dst = LOAD_RM32(modrm);
- UINT32 upper = LOAD_REG32(modrm);
- UINT8 shift = FETCH();
- shift &= 31;
- if( shift == 0 ) {
- } else {
- cpustate->CF = (dst & (1 << (shift-1))) ? 1 : 0;
- dst = (dst >> shift) | (upper << (32-shift));
- cpustate->OF = ((dst >> 31) ^ (dst >> 30)) & 1;
- SetSZPF32(dst);
- }
- STORE_RM32(modrm, dst);
- CYCLES(CYCLES_SHRD_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- UINT32 dst = READ32(ea);
- UINT32 upper = LOAD_REG32(modrm);
- UINT8 shift = FETCH();
- shift &= 31;
- if( shift == 0 ) {
- } else {
- cpustate->CF = (dst & (1 << (shift-1))) ? 1 : 0;
- dst = (dst >> shift) | (upper << (32-shift));
- cpustate->OF = ((dst >> 31) ^ (dst >> 30)) & 1;
- SetSZPF32(dst);
- }
- WRITE32(ea, dst);
- CYCLES(CYCLES_SHRD_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(shrd32_cl)() // Opcode 0x0f ad
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- UINT32 dst = LOAD_RM32(modrm);
- UINT32 upper = LOAD_REG32(modrm);
- UINT8 shift = REG8(CL);
- shift &= 31;
- if( shift == 0 ) {
- } else {
- cpustate->CF = (dst & (1 << (shift-1))) ? 1 : 0;
- dst = (dst >> shift) | (upper << (32-shift));
- cpustate->OF = ((dst >> 31) ^ (dst >> 30)) & 1;
- SetSZPF32(dst);
- }
- STORE_RM32(modrm, dst);
- CYCLES(CYCLES_SHRD_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- UINT32 dst = READ32(ea);
- UINT32 upper = LOAD_REG32(modrm);
- UINT8 shift = REG8(CL);
- shift &= 31;
- if( shift == 0 ) {
- } else {
- cpustate->CF = (dst & (1 << (shift-1))) ? 1 : 0;
- dst = (dst >> shift) | (upper << (32-shift));
- cpustate->OF = ((dst >> 31) ^ (dst >> 30)) & 1;
- SetSZPF32(dst);
- }
- WRITE32(ea, dst);
- CYCLES(CYCLES_SHRD_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(stosd)() // Opcode 0xab
-{
- UINT32 eas = i386_translate( ES, cpustate->address_size ? REG32(EDI) : REG16(DI), 1 );
- WRITE32(eas, REG32(EAX));
- BUMP_DI(4);
- CYCLES(CYCLES_STOS);
-}
-
-void I386_OPS_BASE::I386OP(sub_rm32_r32)() // Opcode 0x29
-{
- UINT32 src, dst;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- src = LOAD_REG32(modrm);
- dst = LOAD_RM32(modrm);
- dst = SUB32(dst, src);
- STORE_RM32(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- src = LOAD_REG32(modrm);
- dst = READ32(ea);
- dst = SUB32(dst, src);
- WRITE32(ea, dst);
- CYCLES(CYCLES_ALU_REG_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(sub_r32_rm32)() // Opcode 0x2b
-{
- UINT32 src, dst;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- src = LOAD_RM32(modrm);
- dst = LOAD_REG32(modrm);
- dst = SUB32(dst, src);
- STORE_REG32(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- src = READ32(ea);
- dst = LOAD_REG32(modrm);
- dst = SUB32(dst, src);
- STORE_REG32(modrm, dst);
- CYCLES(CYCLES_ALU_MEM_REG);
- }
-}
-
-void I386_OPS_BASE::I386OP(sub_eax_i32)() // Opcode 0x2d
-{
- UINT32 src, dst;
- src = FETCH32();
- dst = REG32(EAX);
- dst = SUB32(dst, src);
- REG32(EAX) = dst;
- CYCLES(CYCLES_ALU_IMM_ACC);
-}
-
-void I386_OPS_BASE::I386OP(test_eax_i32)() // Opcode 0xa9
-{
- UINT32 src = FETCH32();
- UINT32 dst = REG32(EAX);
- dst = src & dst;
- SetSZPF32(dst);
- cpustate->CF = 0;
- cpustate->OF = 0;
- CYCLES(CYCLES_TEST_IMM_ACC);
-}
-
-void I386_OPS_BASE::I386OP(test_rm32_r32)() // Opcode 0x85
-{
- UINT32 src, dst;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- src = LOAD_REG32(modrm);
- dst = LOAD_RM32(modrm);
- dst = src & dst;
- SetSZPF32(dst);
- cpustate->CF = 0;
- cpustate->OF = 0;
- CYCLES(CYCLES_TEST_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,0);
- src = LOAD_REG32(modrm);
- dst = READ32(ea);
- dst = src & dst;
- SetSZPF32(dst);
- cpustate->CF = 0;
- cpustate->OF = 0;
- CYCLES(CYCLES_TEST_REG_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(xchg_eax_ecx)() // Opcode 0x91
-{
- UINT32 temp;
- temp = REG32(EAX);
- REG32(EAX) = REG32(ECX);
- REG32(ECX) = temp;
- CYCLES(CYCLES_XCHG_REG_REG);
-}
-
-void I386_OPS_BASE::I386OP(xchg_eax_edx)() // Opcode 0x92
-{
- UINT32 temp;
- temp = REG32(EAX);
- REG32(EAX) = REG32(EDX);
- REG32(EDX) = temp;
- CYCLES(CYCLES_XCHG_REG_REG);
-}
-
-void I386_OPS_BASE::I386OP(xchg_eax_ebx)() // Opcode 0x93
-{
- UINT32 temp;
- temp = REG32(EAX);
- REG32(EAX) = REG32(EBX);
- REG32(EBX) = temp;
- CYCLES(CYCLES_XCHG_REG_REG);
-}
-
-void I386_OPS_BASE::I386OP(xchg_eax_esp)() // Opcode 0x94
-{
- UINT32 temp;
- temp = REG32(EAX);
- REG32(EAX) = REG32(ESP);
- REG32(ESP) = temp;
- CYCLES(CYCLES_XCHG_REG_REG);
-}
-
-void I386_OPS_BASE::I386OP(xchg_eax_ebp)() // Opcode 0x95
-{
- UINT32 temp;
- temp = REG32(EAX);
- REG32(EAX) = REG32(EBP);
- REG32(EBP) = temp;
- CYCLES(CYCLES_XCHG_REG_REG);
-}
-
-void I386_OPS_BASE::I386OP(xchg_eax_esi)() // Opcode 0x96
-{
- UINT32 temp;
- temp = REG32(EAX);
- REG32(EAX) = REG32(ESI);
- REG32(ESI) = temp;
- CYCLES(CYCLES_XCHG_REG_REG);
-}
-
-void I386_OPS_BASE::I386OP(xchg_eax_edi)() // Opcode 0x97
-{
- UINT32 temp;
- temp = REG32(EAX);
- REG32(EAX) = REG32(EDI);
- REG32(EDI) = temp;
- CYCLES(CYCLES_XCHG_REG_REG);
-}
-
-void I386_OPS_BASE::I386OP(xchg_r32_rm32)() // Opcode 0x87
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- UINT32 src = LOAD_RM32(modrm);
- UINT32 dst = LOAD_REG32(modrm);
- STORE_REG32(modrm, src);
- STORE_RM32(modrm, dst);
- CYCLES(CYCLES_XCHG_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- UINT32 src = READ32(ea);
- UINT32 dst = LOAD_REG32(modrm);
- WRITE32(ea, dst);
- STORE_REG32(modrm, src);
- CYCLES(CYCLES_XCHG_REG_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(xor_rm32_r32)() // Opcode 0x31
-{
- UINT32 src, dst;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- src = LOAD_REG32(modrm);
- dst = LOAD_RM32(modrm);
- dst = XOR32(dst, src);
- STORE_RM32(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- src = LOAD_REG32(modrm);
- dst = READ32(ea);
- dst = XOR32(dst, src);
- WRITE32(ea, dst);
- CYCLES(CYCLES_ALU_REG_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(xor_r32_rm32)() // Opcode 0x33
-{
- UINT32 src, dst;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- src = LOAD_RM32(modrm);
- dst = LOAD_REG32(modrm);
- dst = XOR32(dst, src);
- STORE_REG32(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,0);
- src = READ32(ea);
- dst = LOAD_REG32(modrm);
- dst = XOR32(dst, src);
- STORE_REG32(modrm, dst);
- CYCLES(CYCLES_ALU_MEM_REG);
- }
-}
-
-void I386_OPS_BASE::I386OP(xor_eax_i32)() // Opcode 0x35
-{
- UINT32 src, dst;
- src = FETCH32();
- dst = REG32(EAX);
- dst = XOR32(dst, src);
- REG32(EAX) = dst;
- CYCLES(CYCLES_ALU_IMM_ACC);
-}
-
-
-
-void I386_OPS_BASE::I386OP(group81_32)() // Opcode 0x81
-{
- UINT32 ea;
- UINT32 src, dst;
- UINT8 modrm = FETCH();
-
- switch( (modrm >> 3) & 0x7 )
- {
- case 0: // ADD Rm32, i32
- if( modrm >= 0xc0 ) {
- dst = LOAD_RM32(modrm);
- src = FETCH32();
- dst = ADD32(dst, src);
- STORE_RM32(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- ea = GetEA(modrm,1);
- dst = READ32(ea);
- src = FETCH32();
- dst = ADD32(dst, src);
- WRITE32(ea, dst);
- CYCLES(CYCLES_ALU_REG_MEM);
- }
- break;
- case 1: // OR Rm32, i32
- if( modrm >= 0xc0 ) {
- dst = LOAD_RM32(modrm);
- src = FETCH32();
- dst = OR32(dst, src);
- STORE_RM32(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- ea = GetEA(modrm,1);
- dst = READ32(ea);
- src = FETCH32();
- dst = OR32(dst, src);
- WRITE32(ea, dst);
- CYCLES(CYCLES_ALU_REG_MEM);
- }
- break;
- case 2: // ADC Rm32, i32
- if( modrm >= 0xc0 ) {
- dst = LOAD_RM32(modrm);
- src = FETCH32();
- dst = ADC32( dst, src, cpustate->CF);
- STORE_RM32(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- ea = GetEA(modrm,1);
- dst = READ32(ea);
- src = FETCH32();
- dst = ADC32( dst, src, cpustate->CF);
- WRITE32(ea, dst);
- CYCLES(CYCLES_ALU_REG_MEM);
- }
- break;
- case 3: // SBB Rm32, i32
- if( modrm >= 0xc0 ) {
- dst = LOAD_RM32(modrm);
- src = FETCH32();
- dst = SBB32( dst, src, cpustate->CF);
- STORE_RM32(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- ea = GetEA(modrm,1);
- dst = READ32(ea);
- src = FETCH32();
- dst = SBB32( dst, src, cpustate->CF);
- WRITE32(ea, dst);
- CYCLES(CYCLES_ALU_REG_MEM);
- }
- break;
- case 4: // AND Rm32, i32
- if( modrm >= 0xc0 ) {
- dst = LOAD_RM32(modrm);
- src = FETCH32();
- dst = AND32(dst, src);
- STORE_RM32(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- ea = GetEA(modrm,1);
- dst = READ32(ea);
- src = FETCH32();
- dst = AND32(dst, src);
- WRITE32(ea, dst);
- CYCLES(CYCLES_ALU_REG_MEM);
- }
- break;
- case 5: // SUB Rm32, i32
- if( modrm >= 0xc0 ) {
- dst = LOAD_RM32(modrm);
- src = FETCH32();
- dst = SUB32(dst, src);
- STORE_RM32(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- ea = GetEA(modrm,1);
- dst = READ32(ea);
- src = FETCH32();
- dst = SUB32(dst, src);
- WRITE32(ea, dst);
- CYCLES(CYCLES_ALU_REG_MEM);
- }
- break;
- case 6: // XOR Rm32, i32
- if( modrm >= 0xc0 ) {
- dst = LOAD_RM32(modrm);
- src = FETCH32();
- dst = XOR32(dst, src);
- STORE_RM32(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- ea = GetEA(modrm,1);
- dst = READ32(ea);
- src = FETCH32();
- dst = XOR32(dst, src);
- WRITE32(ea, dst);
- CYCLES(CYCLES_ALU_REG_MEM);
- }
- break;
- case 7: // CMP Rm32, i32
- if( modrm >= 0xc0 ) {
- dst = LOAD_RM32(modrm);
- src = FETCH32();
- SUB32(dst, src);
- CYCLES(CYCLES_CMP_REG_REG);
- } else {
- ea = GetEA(modrm,0);
- dst = READ32(ea);
- src = FETCH32();
- SUB32(dst, src);
- CYCLES(CYCLES_CMP_REG_MEM);
- }
- break;
- }
-}
-
-void I386_OPS_BASE::I386OP(group83_32)() // Opcode 0x83
-{
- UINT32 ea;
- UINT32 src, dst;
- UINT8 modrm = FETCH();
-
- switch( (modrm >> 3) & 0x7 )
- {
- case 0: // ADD Rm32, i32
- if( modrm >= 0xc0 ) {
- dst = LOAD_RM32(modrm);
- src = (UINT32)(INT32)(INT8)FETCH();
- dst = ADD32(dst, src);
- STORE_RM32(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- ea = GetEA(modrm,1);
- dst = READ32(ea);
- src = (UINT32)(INT32)(INT8)FETCH();
- dst = ADD32(dst, src);
- WRITE32(ea, dst);
- CYCLES(CYCLES_ALU_REG_MEM);
- }
- break;
- case 1: // OR Rm32, i32
- if( modrm >= 0xc0 ) {
- dst = LOAD_RM32(modrm);
- src = (UINT32)(INT32)(INT8)FETCH();
- dst = OR32(dst, src);
- STORE_RM32(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- ea = GetEA(modrm,1);
- dst = READ32(ea);
- src = (UINT32)(INT32)(INT8)FETCH();
- dst = OR32(dst, src);
- WRITE32(ea, dst);
- CYCLES(CYCLES_ALU_REG_MEM);
- }
- break;
- case 2: // ADC Rm32, i32
- if( modrm >= 0xc0 ) {
- dst = LOAD_RM32(modrm);
- src = (UINT32)(INT32)(INT8)FETCH();
- dst = ADC32( dst, src, cpustate->CF);
- STORE_RM32(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- ea = GetEA(modrm,1);
- dst = READ32(ea);
- src = (UINT32)(INT32)(INT8)FETCH();
- dst = ADC32( dst, src, cpustate->CF);
- WRITE32(ea, dst);
- CYCLES(CYCLES_ALU_REG_MEM);
- }
- break;
- case 3: // SBB Rm32, i32
- if( modrm >= 0xc0 ) {
- dst = LOAD_RM32(modrm);
- src = ((UINT32)(INT32)(INT8)FETCH());
- dst = SBB32( dst, src, cpustate->CF);
- STORE_RM32(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- ea = GetEA(modrm,1);
- dst = READ32(ea);
- src = ((UINT32)(INT32)(INT8)FETCH());
- dst = SBB32( dst, src, cpustate->CF);
- WRITE32(ea, dst);
- CYCLES(CYCLES_ALU_REG_MEM);
- }
- break;
- case 4: // AND Rm32, i32
- if( modrm >= 0xc0 ) {
- dst = LOAD_RM32(modrm);
- src = (UINT32)(INT32)(INT8)FETCH();
- dst = AND32(dst, src);
- STORE_RM32(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- ea = GetEA(modrm,1);
- dst = READ32(ea);
- src = (UINT32)(INT32)(INT8)FETCH();
- dst = AND32(dst, src);
- WRITE32(ea, dst);
- CYCLES(CYCLES_ALU_REG_MEM);
- }
- break;
- case 5: // SUB Rm32, i32
- if( modrm >= 0xc0 ) {
- dst = LOAD_RM32(modrm);
- src = (UINT32)(INT32)(INT8)FETCH();
- dst = SUB32(dst, src);
- STORE_RM32(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- ea = GetEA(modrm,1);
- dst = READ32(ea);
- src = (UINT32)(INT32)(INT8)FETCH();
- dst = SUB32(dst, src);
- WRITE32(ea, dst);
- CYCLES(CYCLES_ALU_REG_MEM);
- }
- break;
- case 6: // XOR Rm32, i32
- if( modrm >= 0xc0 ) {
- dst = LOAD_RM32(modrm);
- src = (UINT32)(INT32)(INT8)FETCH();
- dst = XOR32(dst, src);
- STORE_RM32(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- ea = GetEA(modrm,1);
- dst = READ32(ea);
- src = (UINT32)(INT32)(INT8)FETCH();
- dst = XOR32(dst, src);
- WRITE32(ea, dst);
- CYCLES(CYCLES_ALU_REG_MEM);
- }
- break;
- case 7: // CMP Rm32, i32
- if( modrm >= 0xc0 ) {
- dst = LOAD_RM32(modrm);
- src = (UINT32)(INT32)(INT8)FETCH();
- SUB32(dst, src);
- CYCLES(CYCLES_CMP_REG_REG);
- } else {
- ea = GetEA(modrm,0);
- dst = READ32(ea);
- src = (UINT32)(INT32)(INT8)FETCH();
- SUB32(dst, src);
- CYCLES(CYCLES_CMP_REG_MEM);
- }
- break;
- }
-}
-
-void I386_OPS_BASE::I386OP(groupC1_32)() // Opcode 0xc1
-{
- UINT32 dst;
- UINT8 modrm = FETCH();
- UINT8 shift;
-
- if( modrm >= 0xc0 ) {
- dst = LOAD_RM32(modrm);
- shift = FETCH() & 0x1f;
- dst = i386_shift_rotate32( modrm, dst, shift);
- STORE_RM32(modrm, dst);
- } else {
- UINT32 ea = GetEA(modrm,1);
- dst = READ32(ea);
- shift = FETCH() & 0x1f;
- dst = i386_shift_rotate32( modrm, dst, shift);
- WRITE32(ea, dst);
- }
-}
-
-void I386_OPS_BASE::I386OP(groupD1_32)() // Opcode 0xd1
-{
- UINT32 dst;
- UINT8 modrm = FETCH();
-
- if( modrm >= 0xc0 ) {
- dst = LOAD_RM32(modrm);
- dst = i386_shift_rotate32( modrm, dst, 1);
- STORE_RM32(modrm, dst);
- } else {
- UINT32 ea = GetEA(modrm,1);
- dst = READ32(ea);
- dst = i386_shift_rotate32( modrm, dst, 1);
- WRITE32(ea, dst);
- }
-}
-
-void I386_OPS_BASE::I386OP(groupD3_32)() // Opcode 0xd3
-{
- UINT32 dst;
- UINT8 modrm = FETCH();
-
- if( modrm >= 0xc0 ) {
- dst = LOAD_RM32(modrm);
- dst = i386_shift_rotate32( modrm, dst, REG8(CL));
- STORE_RM32(modrm, dst);
- } else {
- UINT32 ea = GetEA(modrm,1);
- dst = READ32(ea);
- dst = i386_shift_rotate32( modrm, dst, REG8(CL));
- WRITE32(ea, dst);
- }
-}
-
-void I386_OPS_BASE::I386OP(groupF7_32)() // Opcode 0xf7
-{
- UINT8 modrm = FETCH();
-
- switch( (modrm >> 3) & 0x7 )
- {
- case 0: /* TEST Rm32, i32 */
- if( modrm >= 0xc0 ) {
- UINT32 dst = LOAD_RM32(modrm);
- UINT32 src = FETCH32();
- dst &= src;
- cpustate->CF = cpustate->OF = cpustate->AF = 0;
- SetSZPF32(dst);
- CYCLES(CYCLES_TEST_IMM_REG);
- } else {
- UINT32 ea = GetEA(modrm,0);
- UINT32 dst = READ32(ea);
- UINT32 src = FETCH32();
- dst &= src;
- cpustate->CF = cpustate->OF = cpustate->AF = 0;
- SetSZPF32(dst);
- CYCLES(CYCLES_TEST_IMM_MEM);
- }
- break;
- case 2: /* NOT Rm32 */
- if( modrm >= 0xc0 ) {
- UINT32 dst = LOAD_RM32(modrm);
- dst = ~dst;
- STORE_RM32(modrm, dst);
- CYCLES(CYCLES_NOT_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- UINT32 dst = READ32(ea);
- dst = ~dst;
- WRITE32(ea, dst);
- CYCLES(CYCLES_NOT_MEM);
- }
- break;
- case 3: /* NEG Rm32 */
- if( modrm >= 0xc0 ) {
- UINT32 dst = LOAD_RM32(modrm);
- dst = SUB32( 0, dst );
- STORE_RM32(modrm, dst);
- CYCLES(CYCLES_NEG_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- UINT32 dst = READ32(ea);
- dst = SUB32( 0, dst );
- WRITE32(ea, dst);
- CYCLES(CYCLES_NEG_MEM);
- }
- break;
- case 4: /* MUL EAX, Rm32 */
- {
- UINT64 result;
- UINT32 src, dst;
- if( modrm >= 0xc0 ) {
- src = LOAD_RM32(modrm);
- CYCLES(CYCLES_MUL32_ACC_REG); /* TODO: Correct multiply timing */
- } else {
- UINT32 ea = GetEA(modrm,0);
- src = READ32(ea);
- CYCLES(CYCLES_MUL32_ACC_MEM); /* TODO: Correct multiply timing */
- }
-
- dst = REG32(EAX);
- result = (UINT64)src * (UINT64)dst;
- REG32(EDX) = (UINT32)(result >> 32);
- REG32(EAX) = (UINT32)result;
-
- cpustate->CF = cpustate->OF = (REG32(EDX) != 0);
- }
- break;
- case 5: /* IMUL EAX, Rm32 */
- {
- INT64 result;
- INT64 src, dst;
- if( modrm >= 0xc0 ) {
- src = (INT64)(INT32)LOAD_RM32(modrm);
- CYCLES(CYCLES_IMUL32_ACC_REG); /* TODO: Correct multiply timing */
- } else {
- UINT32 ea = GetEA(modrm,0);
- src = (INT64)(INT32)READ32(ea);
- CYCLES(CYCLES_IMUL32_ACC_MEM); /* TODO: Correct multiply timing */
- }
-
- dst = (INT64)(INT32)REG32(EAX);
- result = src * dst;
-
- REG32(EDX) = (UINT32)(result >> 32);
- REG32(EAX) = (UINT32)result;
-
- cpustate->CF = cpustate->OF = !(result == (INT64)(INT32)result);
- }
- break;
- case 6: /* DIV EAX, Rm32 */
- {
- UINT64 quotient, remainder, result;
- UINT32 src;
- if( modrm >= 0xc0 ) {
- src = LOAD_RM32(modrm);
- CYCLES(CYCLES_DIV32_ACC_REG);
- } else {
- UINT32 ea = GetEA(modrm,0);
- src = READ32(ea);
- CYCLES(CYCLES_DIV32_ACC_MEM);
- }
-
- quotient = ((UINT64)(REG32(EDX)) << 32) | (UINT64)(REG32(EAX));
- if( src ) {
- remainder = quotient % (UINT64)src;
- result = quotient / (UINT64)src;
- if( result > 0xffffffff ) {
- /* TODO: Divide error */
- } else {
- REG32(EDX) = (UINT32)remainder;
- REG32(EAX) = (UINT32)result;
- }
- } else {
- i386_trap( 0, 0, 0);
- }
- }
- break;
- case 7: /* IDIV EAX, Rm32 */
- {
- INT64 quotient, remainder, result;
- UINT32 src;
- if( modrm >= 0xc0 ) {
- src = LOAD_RM32(modrm);
- CYCLES(CYCLES_IDIV32_ACC_REG);
- } else {
- UINT32 ea = GetEA(modrm,0);
- src = READ32(ea);
- CYCLES(CYCLES_IDIV32_ACC_MEM);
- }
-
- quotient = (((INT64)REG32(EDX)) << 32) | ((UINT64)REG32(EAX));
- if( src ) {
- remainder = quotient % (INT64)(INT32)src;
- result = quotient / (INT64)(INT32)src;
- if( result > 0xffffffff ) {
- /* TODO: Divide error */
- } else {
- REG32(EDX) = (UINT32)remainder;
- REG32(EAX) = (UINT32)result;
- }
- } else {
- i386_trap( 0, 0, 0);
- }
- }
- break;
- }
-}
-
-void I386_OPS_BASE::I386OP(groupFF_32)() // Opcode 0xff
-{
- UINT8 modrm = FETCH();
-
- switch( (modrm >> 3) & 0x7 )
- {
- case 0: /* INC Rm32 */
- if( modrm >= 0xc0 ) {
- UINT32 dst = LOAD_RM32(modrm);
- dst = INC32(dst);
- STORE_RM32(modrm, dst);
- CYCLES(CYCLES_INC_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- UINT32 dst = READ32(ea);
- dst = INC32(dst);
- WRITE32(ea, dst);
- CYCLES(CYCLES_INC_MEM);
- }
- break;
- case 1: /* DEC Rm32 */
- if( modrm >= 0xc0 ) {
- UINT32 dst = LOAD_RM32(modrm);
- dst = DEC32(dst);
- STORE_RM32(modrm, dst);
- CYCLES(CYCLES_DEC_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- UINT32 dst = READ32(ea);
- dst = DEC32(dst);
- WRITE32(ea, dst);
- CYCLES(CYCLES_DEC_MEM);
- }
- break;
- case 2: /* CALL Rm32 */
- {
- UINT32 address;
- if( modrm >= 0xc0 ) {
- address = LOAD_RM32(modrm);
- CYCLES(CYCLES_CALL_REG); /* TODO: Timing = 7 + m */
- } else {
- UINT32 ea = GetEA(modrm,0);
- address = READ32(ea);
- CYCLES(CYCLES_CALL_MEM); /* TODO: Timing = 10 + m */
- }
- PUSH32( cpustate->eip );
- cpustate->eip = address;
- CHANGE_PC(cpustate->eip);
- }
- break;
- case 3: /* CALL FAR Rm32 */
- {
- UINT16 selector;
- UINT32 address;
-
- if( modrm >= 0xc0 )
- {
- report_invalid_modrm( "groupFF_32", modrm);
- }
- else
- {
- UINT32 ea = GetEA(modrm,0);
- address = READ32(ea + 0);
- selector = READ16(ea + 4);
- CYCLES(CYCLES_CALL_MEM_INTERSEG); /* TODO: Timing = 10 + m */
- if(PROTECTED_MODE && !V8086_MODE)
- {
- i386_protected_mode_call(selector,address,1,1);
- }
- else
- {
- PUSH32( cpustate->sreg[CS].selector );
- PUSH32( cpustate->eip );
- cpustate->sreg[CS].selector = selector;
- cpustate->performed_intersegment_jump = 1;
- i386_load_segment_descriptor( CS );
- cpustate->eip = address;
- CHANGE_PC(cpustate->eip);
- }
- }
- }
- break;
- case 4: /* JMP Rm32 */
- {
- UINT32 address;
- if( modrm >= 0xc0 ) {
- address = LOAD_RM32(modrm);
- CYCLES(CYCLES_JMP_REG); /* TODO: Timing = 7 + m */
- } else {
- UINT32 ea = GetEA(modrm,0);
- address = READ32(ea);
- CYCLES(CYCLES_JMP_MEM); /* TODO: Timing = 10 + m */
- }
- cpustate->eip = address;
- CHANGE_PC(cpustate->eip);
- }
- break;
- case 5: /* JMP FAR Rm32 */
- {
- UINT16 selector;
- UINT32 address;
-
- if( modrm >= 0xc0 )
- {
- report_invalid_modrm( "groupFF_32", modrm);
- }
- else
- {
- UINT32 ea = GetEA(modrm,0);
- address = READ32(ea + 0);
- selector = READ16(ea + 4);
- CYCLES(CYCLES_JMP_MEM_INTERSEG); /* TODO: Timing = 10 + m */
- if(PROTECTED_MODE && !V8086_MODE)
- {
- i386_protected_mode_jump(selector,address,1,1);
- }
- else
- {
- cpustate->sreg[CS].selector = selector;
- cpustate->performed_intersegment_jump = 1;
- i386_load_segment_descriptor( CS );
- cpustate->eip = address;
- CHANGE_PC(cpustate->eip);
- }
- }
- }
- break;
- case 6: /* PUSH Rm32 */
- {
- UINT32 value;
- if( modrm >= 0xc0 ) {
- value = LOAD_RM32(modrm);
- } else {
- UINT32 ea = GetEA(modrm,0);
- value = READ32(ea);
- }
- PUSH32(value);
- CYCLES(CYCLES_PUSH_RM);
- }
- break;
- default:
- report_invalid_modrm( "groupFF_32", modrm);
- break;
- }
-}
-
-void I386_OPS_BASE::I386OP(group0F00_32)() // Opcode 0x0f 00
-{
- UINT32 address, ea;
- UINT8 modrm = FETCH();
- I386_SREG seg;
- UINT8 result;
-
- switch( (modrm >> 3) & 0x7 )
- {
- case 0: /* SLDT */
- if ( PROTECTED_MODE && !V8086_MODE )
- {
- if( modrm >= 0xc0 ) {
- STORE_RM32(modrm, cpustate->ldtr.segment);
- CYCLES(CYCLES_SLDT_REG);
- } else {
- ea = GetEA(modrm,1);
- WRITE16( ea, cpustate->ldtr.segment);
- CYCLES(CYCLES_SLDT_MEM);
- }
- }
- else
- {
- i386_trap(6, 0, 0);
- }
- break;
- case 1: /* STR */
- if ( PROTECTED_MODE && !V8086_MODE )
- {
- if( modrm >= 0xc0 ) {
- STORE_RM32(modrm, cpustate->task.segment);
- CYCLES(CYCLES_STR_REG);
- } else {
- ea = GetEA(modrm,1);
- WRITE16( ea, cpustate->task.segment);
- CYCLES(CYCLES_STR_MEM);
- }
- }
- else
- {
- i386_trap(6, 0, 0);
- }
- break;
- case 2: /* LLDT */
- if ( PROTECTED_MODE && !V8086_MODE )
- {
- if(cpustate->CPL)
- FAULT(FAULT_GP,0)
- if( modrm >= 0xc0 ) {
- address = LOAD_RM32(modrm);
- cpustate->ldtr.segment = address;
- CYCLES(CYCLES_LLDT_REG);
- } else {
- ea = GetEA(modrm,0);
- cpustate->ldtr.segment = READ32(ea);
- CYCLES(CYCLES_LLDT_MEM);
- }
- memset(&seg, 0, sizeof(seg));
- seg.selector = cpustate->ldtr.segment;
- i386_load_protected_mode_segment(&seg,NULL);
- cpustate->ldtr.limit = seg.limit;
- cpustate->ldtr.base = seg.base;
- cpustate->ldtr.flags = seg.flags;
- }
- else
- {
- i386_trap(6, 0, 0);
- }
- break;
-
- case 3: /* LTR */
- if ( PROTECTED_MODE && !V8086_MODE )
- {
- if(cpustate->CPL)
- FAULT(FAULT_GP,0)
- if( modrm >= 0xc0 ) {
- address = LOAD_RM32(modrm);
- cpustate->task.segment = address;
- CYCLES(CYCLES_LTR_REG);
- } else {
- ea = GetEA(modrm,0);
- cpustate->task.segment = READ32(ea);
- CYCLES(CYCLES_LTR_MEM);
- }
- memset(&seg, 0, sizeof(seg));
- seg.selector = cpustate->task.segment;
- i386_load_protected_mode_segment(&seg,NULL);
-
- UINT32 addr = ((seg.selector & 4) ? cpustate->ldtr.base : cpustate->gdtr.base) + (seg.selector & ~7) + 5;
- i386_translate_address( TRANSLATE_READ, &addr, NULL);
- cpustate->program->write_data8(addr, (seg.flags & 0xff) | 2);
-
- cpustate->task.limit = seg.limit;
- cpustate->task.base = seg.base;
- cpustate->task.flags = seg.flags | 2;
- }
- else
- {
- i386_trap(6, 0, 0);
- }
- break;
-
- case 4: /* VERR */
- if ( PROTECTED_MODE && !V8086_MODE )
- {
- if( modrm >= 0xc0 ) {
- address = LOAD_RM32(modrm);
- CYCLES(CYCLES_VERR_REG);
- } else {
- ea = GetEA(modrm,0);
- address = READ32(ea);
- CYCLES(CYCLES_VERR_MEM);
- }
- memset(&seg, 0, sizeof(seg));
- seg.selector = address;
- result = i386_load_protected_mode_segment(&seg,NULL);
- // check if the segment is a code or data segment (not a special segment type, like a TSS, gate, LDT...)
- if(!(seg.flags & 0x10))
- result = 0;
- // check that the segment is readable
- if(seg.flags & 0x10) // is code or data segment
- {
- if(seg.flags & 0x08) // is code segment, so check if it's readable
- {
- if(!(seg.flags & 0x02))
- {
- result = 0;
- }
- else
- { // check if conforming, these are always readable, regardless of privilege
- if(!(seg.flags & 0x04))
- {
- // if not conforming, then we must check privilege levels (TODO: current privilege level check)
- if(((seg.flags >> 5) & 0x03) < (address & 0x03))
- result = 0;
- }
- }
- }
- }
- // check that the descriptor privilege is greater or equal to the selector's privilege level and the current privilege (TODO)
- SetZF(result);
- }
- else
- {
- i386_trap(6, 0, 0);
- logerror("i386: VERR: Exception - Running in real mode or virtual 8086 mode.\n");
- }
- break;
-
- case 5: /* VERW */
- if ( PROTECTED_MODE && !V8086_MODE )
- {
- if( modrm >= 0xc0 ) {
- address = LOAD_RM16(modrm);
- CYCLES(CYCLES_VERW_REG);
- } else {
- ea = GetEA(modrm,0);
- address = READ16(ea);
- CYCLES(CYCLES_VERW_MEM);
- }
- memset(&seg, 0, sizeof(seg));
- seg.selector = address;
- result = i386_load_protected_mode_segment(&seg,NULL);
- // check if the segment is a code or data segment (not a special segment type, like a TSS, gate, LDT...)
- if(!(seg.flags & 0x10))
- result = 0;
- // check that the segment is writable
- if(seg.flags & 0x10) // is code or data segment
- {
- if(seg.flags & 0x08) // is code segment (and thus, not writable)
- {
- result = 0;
- }
- else
- { // is data segment
- if(!(seg.flags & 0x02))
- result = 0;
- }
- }
- // check that the descriptor privilege is greater or equal to the selector's privilege level and the current privilege (TODO)
- if(((seg.flags >> 5) & 0x03) < (address & 0x03))
- result = 0;
- SetZF(result);
- }
- else
- {
- i386_trap(6, 0, 0);
- logerror("i386: VERW: Exception - Running in real mode or virtual 8086 mode.\n");
- }
- break;
-
- default:
- report_invalid_modrm( "group0F00_32", modrm);
- break;
- }
-}
-
-void I386_OPS_BASE::I386OP(group0F01_32)() // Opcode 0x0f 01
-{
- UINT8 modrm = FETCH();
- UINT32 address, ea;
-
- switch( (modrm >> 3) & 0x7 )
- {
- case 0: /* SGDT */
- {
- if( modrm >= 0xc0 ) {
- address = LOAD_RM32(modrm);
- ea = i386_translate( CS, address, 1 );
- } else {
- ea = GetEA(modrm,1);
- }
- WRITE16(ea, cpustate->gdtr.limit);
- WRITE32(ea + 2, cpustate->gdtr.base);
- CYCLES(CYCLES_SGDT);
- break;
- }
- case 1: /* SIDT */
- {
- if (modrm >= 0xc0)
- {
- address = LOAD_RM32(modrm);
- ea = i386_translate( CS, address, 1 );
- }
- else
- {
- ea = GetEA(modrm,1);
- }
- WRITE16(ea, cpustate->idtr.limit);
- WRITE32(ea + 2, cpustate->idtr.base);
- CYCLES(CYCLES_SIDT);
- break;
- }
- case 2: /* LGDT */
- {
- if(PROTECTED_MODE && cpustate->CPL)
- FAULT(FAULT_GP,0)
- if( modrm >= 0xc0 ) {
- address = LOAD_RM32(modrm);
- ea = i386_translate( CS, address, 0 );
- } else {
- ea = GetEA(modrm,0);
- }
- cpustate->gdtr.limit = READ16(ea);
- cpustate->gdtr.base = READ32(ea + 2);
- CYCLES(CYCLES_LGDT);
- break;
- }
- case 3: /* LIDT */
- {
- if(PROTECTED_MODE && cpustate->CPL)
- FAULT(FAULT_GP,0)
- if( modrm >= 0xc0 ) {
- address = LOAD_RM32(modrm);
- ea = i386_translate( CS, address, 0 );
- } else {
- ea = GetEA(modrm,0);
- }
- cpustate->idtr.limit = READ16(ea);
- cpustate->idtr.base = READ32(ea + 2);
- CYCLES(CYCLES_LIDT);
- break;
- }
- case 4: /* SMSW */
- {
- if( modrm >= 0xc0 ) {
- // smsw stores all of cr0 into register
- STORE_RM32(modrm, cpustate->cr[0]);
- CYCLES(CYCLES_SMSW_REG);
- } else {
- /* always 16-bit memory operand */
- ea = GetEA(modrm,1);
- WRITE16(ea, cpustate->cr[0]);
- CYCLES(CYCLES_SMSW_MEM);
- }
- break;
- }
- case 6: /* LMSW */
- {
- if(PROTECTED_MODE && cpustate->CPL)
- FAULT(FAULT_GP,0)
- UINT16 b;
- if( modrm >= 0xc0 ) {
- b = LOAD_RM16(modrm);
- CYCLES(CYCLES_LMSW_REG);
- } else {
- ea = GetEA(modrm,0);
- CYCLES(CYCLES_LMSW_MEM);
- b = READ16(ea);
- }
- if(PROTECTED_MODE)
- b |= 0x0001; // cannot return to real mode using this instruction.
- cpustate->cr[0] &= ~0x0000000f;
- cpustate->cr[0] |= b & 0x0000000f;
- break;
- }
- default:
- report_invalid_modrm( "group0F01_32", modrm);
- break;
- }
-}
-
-void I386_OPS_BASE::I386OP(group0FBA_32)() // Opcode 0x0f ba
-{
- UINT8 modrm = FETCH();
-
- switch( (modrm >> 3) & 0x7 )
- {
- case 4: /* BT Rm32, i8 */
- if( modrm >= 0xc0 ) {
- UINT32 dst = LOAD_RM32(modrm);
- UINT8 bit = FETCH();
-
- if( dst & (1 << bit) )
- cpustate->CF = 1;
- else
- cpustate->CF = 0;
-
- CYCLES(CYCLES_BT_IMM_REG);
- } else {
- UINT32 ea = GetEA(modrm,0);
- UINT32 dst = READ32(ea);
- UINT8 bit = FETCH();
-
- if( dst & (1 << bit) )
- cpustate->CF = 1;
- else
- cpustate->CF = 0;
-
- CYCLES(CYCLES_BT_IMM_MEM);
- }
- break;
- case 5: /* BTS Rm32, i8 */
- if( modrm >= 0xc0 ) {
- UINT32 dst = LOAD_RM32(modrm);
- UINT8 bit = FETCH();
-
- if( dst & (1 << bit) )
- cpustate->CF = 1;
- else
- cpustate->CF = 0;
- dst |= (1 << bit);
-
- STORE_RM32(modrm, dst);
- CYCLES(CYCLES_BTS_IMM_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- UINT32 dst = READ32(ea);
- UINT8 bit = FETCH();
-
- if( dst & (1 << bit) )
- cpustate->CF = 1;
- else
- cpustate->CF = 0;
- dst |= (1 << bit);
-
- WRITE32(ea, dst);
- CYCLES(CYCLES_BTS_IMM_MEM);
- }
- break;
- case 6: /* BTR Rm32, i8 */
- if( modrm >= 0xc0 ) {
- UINT32 dst = LOAD_RM32(modrm);
- UINT8 bit = FETCH();
-
- if( dst & (1 << bit) )
- cpustate->CF = 1;
- else
- cpustate->CF = 0;
- dst &= ~(1 << bit);
-
- STORE_RM32(modrm, dst);
- CYCLES(CYCLES_BTR_IMM_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- UINT32 dst = READ32(ea);
- UINT8 bit = FETCH();
-
- if( dst & (1 << bit) )
- cpustate->CF = 1;
- else
- cpustate->CF = 0;
- dst &= ~(1 << bit);
-
- WRITE32(ea, dst);
- CYCLES(CYCLES_BTR_IMM_MEM);
- }
- break;
- case 7: /* BTC Rm32, i8 */
- if( modrm >= 0xc0 ) {
- UINT32 dst = LOAD_RM32(modrm);
- UINT8 bit = FETCH();
-
- if( dst & (1 << bit) )
- cpustate->CF = 1;
- else
- cpustate->CF = 0;
- dst ^= (1 << bit);
-
- STORE_RM32(modrm, dst);
- CYCLES(CYCLES_BTC_IMM_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- UINT32 dst = READ32(ea);
- UINT8 bit = FETCH();
-
- if( dst & (1 << bit) )
- cpustate->CF = 1;
- else
- cpustate->CF = 0;
- dst ^= (1 << bit);
-
- WRITE32(ea, dst);
- CYCLES(CYCLES_BTC_IMM_MEM);
- }
- break;
- default:
- report_invalid_modrm( "group0FBA_32", modrm);
- break;
- }
-}
-
-void I386_OPS_BASE::I386OP(lar_r32_rm32)() // Opcode 0x0f 0x02
-{
- UINT8 modrm = FETCH();
- I386_SREG seg;
- UINT8 type;
-
- if(PROTECTED_MODE && !V8086_MODE)
- {
- memset(&seg,0,sizeof(seg));
- if(modrm >= 0xc0)
- {
- seg.selector = LOAD_RM32(modrm);
- CYCLES(CYCLES_LAR_REG);
- }
- else
- {
- UINT32 ea = GetEA(modrm,0);
- seg.selector = READ32(ea);
- CYCLES(CYCLES_LAR_MEM);
- }
- if(seg.selector == 0)
- {
- SetZF(0); // not a valid segment
- }
- else
- {
- UINT64 desc;
- if(!i386_load_protected_mode_segment(&seg,&desc))
- {
- SetZF(0);
- return;
- }
- UINT8 DPL = (seg.flags >> 5) & 3;
- if(((DPL < cpustate->CPL) || (DPL < (seg.selector & 3))) && ((seg.flags & 0x1c) != 0x1c))
- {
- SetZF(0);
- return;
- }
- if(!(seg.flags & 0x10)) // special segment
- {
- // check for invalid segment types
- type = seg.flags & 0x000f;
- if(type == 0x00 || type == 0x08 || type == 0x0a || type == 0x0d)
- {
- SetZF(0); // invalid segment type
- }
- else
- {
- STORE_REG32(modrm,(desc>>32) & 0x00ffff00);
- SetZF(1);
- }
- }
- else
- {
- STORE_REG32(modrm,(desc>>32) & 0x00ffff00);
- SetZF(1);
- }
- }
- }
- else
- {
- // illegal opcode
- i386_trap(6,0, 0);
- logerror("i386: LAR: Exception - running in real mode or virtual 8086 mode.\n");
- }
-}
-
-void I386_OPS_BASE::I386OP(lsl_r32_rm32)() // Opcode 0x0f 0x03
-{
- UINT8 modrm = FETCH();
- UINT32 limit;
- I386_SREG seg;
-
- if(PROTECTED_MODE && !V8086_MODE)
- {
- memset(&seg, 0, sizeof(seg));
- if(modrm >= 0xc0)
- {
- seg.selector = LOAD_RM32(modrm);
- }
- else
- {
- UINT32 ea = GetEA(modrm,0);
- seg.selector = READ32(ea);
- }
- if(seg.selector == 0)
- {
- SetZF(0); // not a valid segment
- }
- else
- {
- UINT8 type;
- if(!i386_load_protected_mode_segment(&seg,NULL))
- {
- SetZF(0);
- return;
- }
- UINT8 DPL = (seg.flags >> 5) & 3;
- if(((DPL < cpustate->CPL) || (DPL < (seg.selector & 3))) && ((seg.flags & 0x1c) != 0x1c))
- {
- SetZF(0);
- return;
- }
- type = seg.flags & 0x1f;
- switch(type)
- {
- case 0:
- case 4:
- case 5:
- case 6:
- case 7:
- case 8:
- case 10:
- case 12:
- case 13:
- case 14:
- case 15:
- SetZF(0);
- return;
- default:
- limit = seg.limit;
- STORE_REG32(modrm,limit);
- SetZF(1);
- }
- }
- }
- else
- i386_trap(6, 0, 0);
-}
-
-void I386_OPS_BASE::I386OP(bound_r32_m32_m32)() // Opcode 0x62
-{
- UINT8 modrm;
- INT32 val, low, high;
-
- modrm = FETCH();
-
- if (modrm >= 0xc0)
- {
- low = high = LOAD_RM32(modrm);
- }
- else
- {
- UINT32 ea = GetEA(modrm,0);
- low = READ32(ea + 0);
- high = READ32(ea + 4);
- }
- val = LOAD_REG32(modrm);
-
- if ((val < low) || (val > high))
- {
- CYCLES(CYCLES_BOUND_OUT_RANGE);
- i386_trap(5, 0, 0);
- }
- else
- {
- CYCLES(CYCLES_BOUND_IN_RANGE);
- }
-}
-
-void I386_OPS_BASE::I386OP(retf32)() // Opcode 0xcb
-{
- if(PROTECTED_MODE && !V8086_MODE)
- {
- i386_protected_mode_retf(0,1);
- }
- else
- {
- cpustate->eip = POP32();
- cpustate->sreg[CS].selector = POP32();
- i386_load_segment_descriptor( CS );
- CHANGE_PC(cpustate->eip);
- }
-
- CYCLES(CYCLES_RET_INTERSEG);
-}
-
-void I386_OPS_BASE::I386OP(retf_i32)() // Opcode 0xca
-{
- UINT16 count = FETCH16();
-
- if(PROTECTED_MODE && !V8086_MODE)
- {
- i386_protected_mode_retf(count,1);
- }
- else
- {
- cpustate->eip = POP32();
- cpustate->sreg[CS].selector = POP32();
- i386_load_segment_descriptor( CS );
- CHANGE_PC(cpustate->eip);
- REG32(ESP) += count;
- }
-
- CYCLES(CYCLES_RET_IMM_INTERSEG);
-}
-
-void I386_OPS_BASE::I386OP(load_far_pointer32)( int s)
-{
- UINT8 modrm = FETCH();
- UINT16 selector;
-
- if( modrm >= 0xc0 ) {
- report_invalid_modrm( "load_far_pointer32", modrm);
- } else {
- UINT32 ea = GetEA(modrm,0);
- STORE_REG32(modrm, READ32(ea + 0));
- selector = READ16(ea + 4);
- i386_sreg_load(selector,s,NULL);
- }
-}
-
-void I386_OPS_BASE::I386OP(lds32)() // Opcode 0xc5
-{
- I386OP(load_far_pointer32)( DS);
- CYCLES(CYCLES_LDS);
-}
-
-void I386_OPS_BASE::I386OP(lss32)() // Opcode 0x0f 0xb2
-{
- I386OP(load_far_pointer32)( SS);
- CYCLES(CYCLES_LSS);
-}
-
-void I386_OPS_BASE::I386OP(les32)() // Opcode 0xc4
-{
- I386OP(load_far_pointer32)( ES);
- CYCLES(CYCLES_LES);
-}
-
-void I386_OPS_BASE::I386OP(lfs32)() // Opcode 0x0f 0xb4
-{
- I386OP(load_far_pointer32)( FS);
- CYCLES(CYCLES_LFS);
-}
-
-void I386_OPS_BASE::I386OP(lgs32)() // Opcode 0x0f 0xb5
-{
- I386OP(load_far_pointer32)( GS);
- CYCLES(CYCLES_LGS);
-}
+++ /dev/null
-// license:BSD-3-Clause
-// copyright-holders:Ville Linde, Barry Rodewald, Carl, Phil Bennett
-#include "./i386_opdef.h"
-
-UINT8 I386_OPS_BASE::I386OP(shift_rotate8)( UINT8 modrm, UINT32 value, UINT8 shift)
-{
- UINT32 src = value & 0xff;
- UINT8 dst = value;
-
- if( shift == 0 ) {
- CYCLES_RM(modrm, 3, 7);
- } else if( shift == 1 ) {
- switch( (modrm >> 3) & 0x7 )
- {
- case 0: /* ROL rm8, 1 */
- cpustate->CF = (src & 0x80) ? 1 : 0;
- dst = (src << 1) + cpustate->CF;
- cpustate->OF = ((src ^ dst) & 0x80) ? 1 : 0;
- CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
- break;
- case 1: /* ROR rm8, 1 */
- cpustate->CF = (src & 0x1) ? 1 : 0;
- dst = (cpustate->CF << 7) | (src >> 1);
- cpustate->OF = ((src ^ dst) & 0x80) ? 1 : 0;
- CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
- break;
- case 2: /* RCL rm8, 1 */
- dst = (src << 1) + cpustate->CF;
- cpustate->CF = (src & 0x80) ? 1 : 0;
- cpustate->OF = ((src ^ dst) & 0x80) ? 1 : 0;
- CYCLES_RM(modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM);
- break;
- case 3: /* RCR rm8, 1 */
- dst = (cpustate->CF << 7) | (src >> 1);
- cpustate->CF = src & 0x1;
- cpustate->OF = ((src ^ dst) & 0x80) ? 1 : 0;
- CYCLES_RM(modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM);
- break;
- case 4: /* SHL/SAL rm8, 1 */
- case 6:
- dst = src << 1;
- cpustate->CF = (src & 0x80) ? 1 : 0;
- cpustate->OF = (((cpustate->CF << 7) ^ dst) & 0x80) ? 1 : 0;
- SetSZPF8(dst);
- CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
- break;
- case 5: /* SHR rm8, 1 */
- dst = src >> 1;
- cpustate->CF = src & 0x1;
- cpustate->OF = (dst & 0x80) ? 1 : 0;
- SetSZPF8(dst);
- CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
- break;
- case 7: /* SAR rm8, 1 */
- dst = (INT8)(src) >> 1;
- cpustate->CF = src & 0x1;
- cpustate->OF = 0;
- SetSZPF8(dst);
- CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
- break;
- }
-
- } else {
- switch( (modrm >> 3) & 0x7 )
- {
- case 0: /* ROL rm8, i8 */
- if(!(shift & 7))
- {
- if(shift & 0x18)
- {
- cpustate->CF = src & 1;
- cpustate->OF = (src & 1) ^ ((src >> 7) & 1);
- }
- break;
- }
- shift &= 7;
- dst = ((src & ((UINT8)0xff >> shift)) << shift) |
- ((src & ((UINT8)0xff << (8-shift))) >> (8-shift));
- cpustate->CF = dst & 0x1;
- cpustate->OF = (dst & 1) ^ (dst >> 7);
- CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
- break;
- case 1: /* ROR rm8, i8 */
- if(!(shift & 7))
- {
- if(shift & 0x18)
- {
- cpustate->CF = (src >> 7) & 1;
- cpustate->OF = ((src >> 7) & 1) ^ ((src >> 6) & 1);
- }
- break;
- }
- shift &= 7;
- dst = ((src & ((UINT8)0xff << shift)) >> shift) |
- ((src & ((UINT8)0xff >> (8-shift))) << (8-shift));
- cpustate->CF = (dst >> 7) & 1;
- cpustate->OF = ((dst >> 7) ^ (dst >> 6)) & 1;
- CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
- break;
- case 2: /* RCL rm8, i8 */
- shift %= 9;
- dst = ((src & ((UINT8)0xff >> shift)) << shift) |
- ((src & ((UINT8)0xff << (9-shift))) >> (9-shift)) |
- (cpustate->CF << (shift-1));
- if(shift) cpustate->CF = (src >> (8-shift)) & 0x1;
- cpustate->OF = cpustate->CF ^ ((dst >> 7) & 1);
- CYCLES_RM(modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM);
- break;
- case 3: /* RCR rm8, i8 */
- shift %= 9;
- dst = ((src & ((UINT8)0xff << shift)) >> shift) |
- ((src & ((UINT8)0xff >> (8-shift))) << (9-shift)) |
- (cpustate->CF << (8-shift));
- if(shift) cpustate->CF = (src >> (shift-1)) & 0x1;
- cpustate->OF = ((dst >> 7) ^ (dst >> 6)) & 1;
- CYCLES_RM(modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM);
- break;
- case 4: /* SHL/SAL rm8, i8 */
- case 6:
- shift &= 31;
- dst = src << shift;
- cpustate->CF = (shift <= 8) && ((src >> (8 - shift)) & 1);
- SetSZPF8(dst);
- CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
- break;
- case 5: /* SHR rm8, i8 */
- shift &= 31;
- dst = src >> shift;
- cpustate->CF = (src & (1 << (shift-1))) ? 1 : 0;
- SetSZPF8(dst);
- CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
- break;
- case 7: /* SAR rm8, i8 */
- shift &= 31;
- dst = (INT8)src >> shift;
- cpustate->CF = (src & (1 << (shift-1))) ? 1 : 0;
- SetSZPF8(dst);
- CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
- break;
- }
- }
-
- return dst;
-}
-
-
-
-void I386_OPS_BASE::I386OP(adc_rm8_r8)() // Opcode 0x10
-{
- UINT8 src, dst;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- src = LOAD_REG8(modrm);
- dst = LOAD_RM8(modrm);
- dst = ADC8( dst, src, cpustate->CF);
- STORE_RM8(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- src = LOAD_REG8(modrm);
- dst = READ8(ea);
- dst = ADC8( dst, src, cpustate->CF);
- WRITE8(ea, dst);
- CYCLES(CYCLES_ALU_REG_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(adc_r8_rm8)() // Opcode 0x12
-{
- UINT8 src, dst;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- src = LOAD_RM8(modrm);
- dst = LOAD_REG8(modrm);
- dst = ADC8( dst, src, cpustate->CF);
- STORE_REG8(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,0);
- src = READ8(ea);
- dst = LOAD_REG8(modrm);
- dst = ADC8( dst, src, cpustate->CF);
- STORE_REG8(modrm, dst);
- CYCLES(CYCLES_ALU_MEM_REG);
- }
-}
-
-void I386_OPS_BASE::I386OP(adc_al_i8)() // Opcode 0x14
-{
- UINT8 src, dst;
- src = FETCH();
- dst = REG8(AL);
- dst = ADC8( dst, src, cpustate->CF);
- REG8(AL) = dst;
- CYCLES(CYCLES_ALU_IMM_ACC);
-}
-
-void I386_OPS_BASE::I386OP(add_rm8_r8)() // Opcode 0x00
-{
- UINT8 src, dst;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- src = LOAD_REG8(modrm);
- dst = LOAD_RM8(modrm);
- dst = ADD8(dst, src);
- STORE_RM8(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- src = LOAD_REG8(modrm);
- dst = READ8(ea);
- dst = ADD8(dst, src);
- WRITE8(ea, dst);
- CYCLES(CYCLES_ALU_REG_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(add_r8_rm8)() // Opcode 0x02
-{
- UINT8 src, dst;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- src = LOAD_RM8(modrm);
- dst = LOAD_REG8(modrm);
- dst = ADD8(dst, src);
- STORE_REG8(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,0);
- src = READ8(ea);
- dst = LOAD_REG8(modrm);
- dst = ADD8(dst, src);
- STORE_REG8(modrm, dst);
- CYCLES(CYCLES_ALU_MEM_REG);
- }
-}
-
-void I386_OPS_BASE::I386OP(add_al_i8)() // Opcode 0x04
-{
- UINT8 src, dst;
- src = FETCH();
- dst = REG8(AL);
- dst = ADD8(dst, src);
- REG8(AL) = dst;
- CYCLES(CYCLES_ALU_IMM_ACC);
-}
-
-void I386_OPS_BASE::I386OP(and_rm8_r8)() // Opcode 0x20
-{
- UINT8 src, dst;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- src = LOAD_REG8(modrm);
- dst = LOAD_RM8(modrm);
- dst = AND8(dst, src);
- STORE_RM8(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- src = LOAD_REG8(modrm);
- dst = READ8(ea);
- dst = AND8(dst, src);
- WRITE8(ea, dst);
- CYCLES(CYCLES_ALU_REG_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(and_r8_rm8)() // Opcode 0x22
-{
- UINT8 src, dst;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- src = LOAD_RM8(modrm);
- dst = LOAD_REG8(modrm);
- dst = AND8(dst, src);
- STORE_REG8(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,0);
- src = READ8(ea);
- dst = LOAD_REG8(modrm);
- dst = AND8(dst, src);
- STORE_REG8(modrm, dst);
- CYCLES(CYCLES_ALU_MEM_REG);
- }
-}
-
-void I386_OPS_BASE::I386OP(and_al_i8)() // Opcode 0x24
-{
- UINT8 src, dst;
- src = FETCH();
- dst = REG8(AL);
- dst = AND8(dst, src);
- REG8(AL) = dst;
- CYCLES(CYCLES_ALU_IMM_ACC);
-}
-
-void I386_OPS_BASE::I386OP(clc)() // Opcode 0xf8
-{
- cpustate->CF = 0;
- CYCLES(CYCLES_CLC);
-}
-
-void I386_OPS_BASE::I386OP(cld)() // Opcode 0xfc
-{
- cpustate->DF = 0;
- CYCLES(CYCLES_CLD);
-}
-
-void I386_OPS_BASE::I386OP(cli)() // Opcode 0xfa
-{
- if(PROTECTED_MODE)
- {
- UINT8 IOPL = cpustate->IOP1 | (cpustate->IOP2 << 1);
- if(cpustate->CPL > IOPL)
- FAULT(FAULT_GP,0);
- }
- cpustate->IF = 0;
- CYCLES(CYCLES_CLI);
-}
-
-void I386_OPS_BASE::I386OP(cmc)() // Opcode 0xf5
-{
- cpustate->CF ^= 1;
- CYCLES(CYCLES_CMC);
-}
-
-void I386_OPS_BASE::I386OP(cmp_rm8_r8)() // Opcode 0x38
-{
- UINT8 src, dst;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- src = LOAD_REG8(modrm);
- dst = LOAD_RM8(modrm);
- SUB8(dst, src);
- CYCLES(CYCLES_CMP_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,0);
- src = LOAD_REG8(modrm);
- dst = READ8(ea);
- SUB8(dst, src);
- CYCLES(CYCLES_CMP_REG_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(cmp_r8_rm8)() // Opcode 0x3a
-{
- UINT8 src, dst;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- src = LOAD_RM8(modrm);
- dst = LOAD_REG8(modrm);
- SUB8(dst, src);
- CYCLES(CYCLES_CMP_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,0);
- src = READ8(ea);
- dst = LOAD_REG8(modrm);
- SUB8(dst, src);
- CYCLES(CYCLES_CMP_MEM_REG);
- }
-}
-
-void I386_OPS_BASE::I386OP(cmp_al_i8)() // Opcode 0x3c
-{
- UINT8 src, dst;
- src = FETCH();
- dst = REG8(AL);
- SUB8(dst, src);
- CYCLES(CYCLES_CMP_IMM_ACC);
-}
-
-void I386_OPS_BASE::I386OP(cmpsb)() // Opcode 0xa6
-{
- UINT32 eas, ead;
- UINT8 src, dst;
- if( cpustate->segment_prefix ) {
- eas = i386_translate( cpustate->segment_override, cpustate->address_size ? REG32(ESI) : REG16(SI), 0 );
- } else {
- eas = i386_translate( DS, cpustate->address_size ? REG32(ESI) : REG16(SI), 0 );
- }
- ead = i386_translate( ES, cpustate->address_size ? REG32(EDI) : REG16(DI), 0 );
- src = READ8(eas);
- dst = READ8(ead);
- SUB8(src, dst);
- BUMP_SI(1);
- BUMP_DI(1);
- CYCLES(CYCLES_CMPS);
-}
-
-void I386_OPS_BASE::I386OP(in_al_i8)() // Opcode 0xe4
-{
- UINT16 port = FETCH();
- UINT8 data = READPORT8( port);
- REG8(AL) = data;
- CYCLES(CYCLES_IN_VAR);
-}
-
-void I386_OPS_BASE::I386OP(in_al_dx)() // Opcode 0xec
-{
- UINT16 port = REG16(DX);
- UINT8 data = READPORT8( port);
- REG8(AL) = data;
- CYCLES(CYCLES_IN);
-}
-
-void I386_OPS_BASE::I386OP(ja_rel8)() // Opcode 0x77
-{
- INT8 disp = FETCH();
- if( cpustate->CF == 0 && cpustate->ZF == 0 ) {
- NEAR_BRANCH(disp);
- CYCLES(CYCLES_JCC_DISP8); /* TODO: Timing = 7 + m */
- } else {
- CYCLES(CYCLES_JCC_DISP8_NOBRANCH);
- }
-}
-
-void I386_OPS_BASE::I386OP(jbe_rel8)() // Opcode 0x76
-{
- INT8 disp = FETCH();
- if( cpustate->CF != 0 || cpustate->ZF != 0 ) {
- NEAR_BRANCH(disp);
- CYCLES(CYCLES_JCC_DISP8); /* TODO: Timing = 7 + m */
- } else {
- CYCLES(CYCLES_JCC_DISP8_NOBRANCH);
- }
-}
-
-void I386_OPS_BASE::I386OP(jc_rel8)() // Opcode 0x72
-{
- INT8 disp = FETCH();
- if( cpustate->CF != 0 ) {
- NEAR_BRANCH(disp);
- CYCLES(CYCLES_JCC_DISP8); /* TODO: Timing = 7 + m */
- } else {
- CYCLES(CYCLES_JCC_DISP8_NOBRANCH);
- }
-}
-
-void I386_OPS_BASE::I386OP(jg_rel8)() // Opcode 0x7f
-{
- INT8 disp = FETCH();
- if( cpustate->ZF == 0 && (cpustate->SF == cpustate->OF) ) {
- NEAR_BRANCH(disp);
- CYCLES(CYCLES_JCC_DISP8); /* TODO: Timing = 7 + m */
- } else {
- CYCLES(CYCLES_JCC_DISP8_NOBRANCH);
- }
-}
-
-void I386_OPS_BASE::I386OP(jge_rel8)() // Opcode 0x7d
-{
- INT8 disp = FETCH();
- if(cpustate->SF == cpustate->OF) {
- NEAR_BRANCH(disp);
- CYCLES(CYCLES_JCC_DISP8); /* TODO: Timing = 7 + m */
- } else {
- CYCLES(CYCLES_JCC_DISP8_NOBRANCH);
- }
-}
-
-void I386_OPS_BASE::I386OP(jl_rel8)() // Opcode 0x7c
-{
- INT8 disp = FETCH();
- if( (cpustate->SF != cpustate->OF) ) {
- NEAR_BRANCH(disp);
- CYCLES(CYCLES_JCC_DISP8); /* TODO: Timing = 7 + m */
- } else {
- CYCLES(CYCLES_JCC_DISP8_NOBRANCH);
- }
-}
-
-void I386_OPS_BASE::I386OP(jle_rel8)() // Opcode 0x7e
-{
- INT8 disp = FETCH();
- if( cpustate->ZF != 0 || (cpustate->SF != cpustate->OF) ) {
- NEAR_BRANCH(disp);
- CYCLES(CYCLES_JCC_DISP8); /* TODO: Timing = 7 + m */
- } else {
- CYCLES(CYCLES_JCC_DISP8_NOBRANCH);
- }
-}
-
-void I386_OPS_BASE::I386OP(jnc_rel8)() // Opcode 0x73
-{
- INT8 disp = FETCH();
- if( cpustate->CF == 0 ) {
- NEAR_BRANCH(disp);
- CYCLES(CYCLES_JCC_DISP8); /* TODO: Timing = 7 + m */
- } else {
- CYCLES(CYCLES_JCC_DISP8_NOBRANCH);
- }
-}
-
-void I386_OPS_BASE::I386OP(jno_rel8)() // Opcode 0x71
-{
- INT8 disp = FETCH();
- if( cpustate->OF == 0 ) {
- NEAR_BRANCH(disp);
- CYCLES(CYCLES_JCC_DISP8); /* TODO: Timing = 7 + m */
- } else {
- CYCLES(CYCLES_JCC_DISP8_NOBRANCH);
- }
-}
-
-void I386_OPS_BASE::I386OP(jnp_rel8)() // Opcode 0x7b
-{
- INT8 disp = FETCH();
- if( cpustate->PF == 0 ) {
- NEAR_BRANCH(disp);
- CYCLES(CYCLES_JCC_DISP8); /* TODO: Timing = 7 + m */
- } else {
- CYCLES(CYCLES_JCC_DISP8_NOBRANCH);
- }
-}
-
-void I386_OPS_BASE::I386OP(jns_rel8)() // Opcode 0x79
-{
- INT8 disp = FETCH();
- if( cpustate->SF == 0 ) {
- NEAR_BRANCH(disp);
- CYCLES(CYCLES_JCC_DISP8); /* TODO: Timing = 7 + m */
- } else {
- CYCLES(CYCLES_JCC_DISP8_NOBRANCH);
- }
-}
-
-void I386_OPS_BASE::I386OP(jnz_rel8)() // Opcode 0x75
-{
- INT8 disp = FETCH();
- if( cpustate->ZF == 0 ) {
- NEAR_BRANCH(disp);
- CYCLES(CYCLES_JCC_DISP8); /* TODO: Timing = 7 + m */
- } else {
- CYCLES(CYCLES_JCC_DISP8_NOBRANCH);
- }
-}
-
-void I386_OPS_BASE::I386OP(jo_rel8)() // Opcode 0x70
-{
- INT8 disp = FETCH();
- if( cpustate->OF != 0 ) {
- NEAR_BRANCH(disp);
- CYCLES(CYCLES_JCC_DISP8); /* TODO: Timing = 7 + m */
- } else {
- CYCLES(CYCLES_JCC_DISP8_NOBRANCH);
- }
-}
-
-void I386_OPS_BASE::I386OP(jp_rel8)() // Opcode 0x7a
-{
- INT8 disp = FETCH();
- if( cpustate->PF != 0 ) {
- NEAR_BRANCH(disp);
- CYCLES(CYCLES_JCC_DISP8); /* TODO: Timing = 7 + m */
- } else {
- CYCLES(CYCLES_JCC_DISP8_NOBRANCH);
- }
-}
-
-void I386_OPS_BASE::I386OP(js_rel8)() // Opcode 0x78
-{
- INT8 disp = FETCH();
- if( cpustate->SF != 0 ) {
- NEAR_BRANCH(disp);
- CYCLES(CYCLES_JCC_DISP8); /* TODO: Timing = 7 + m */
- } else {
- CYCLES(CYCLES_JCC_DISP8_NOBRANCH);
- }
-}
-
-void I386_OPS_BASE::I386OP(jz_rel8)() // Opcode 0x74
-{
- INT8 disp = FETCH();
- if( cpustate->ZF != 0 ) {
- NEAR_BRANCH(disp);
- CYCLES(CYCLES_JCC_DISP8); /* TODO: Timing = 7 + m */
- } else {
- CYCLES(CYCLES_JCC_DISP8_NOBRANCH);
- }
-}
-
-void I386_OPS_BASE::I386OP(jmp_rel8)() // Opcode 0xeb
-{
- INT8 disp = FETCH();
- NEAR_BRANCH(disp);
- CYCLES(CYCLES_JMP_SHORT); /* TODO: Timing = 7 + m */
-}
-
-void I386_OPS_BASE::I386OP(lahf)() // Opcode 0x9f
-{
- REG8(AH) = get_flags() & 0xd7;
- CYCLES(CYCLES_LAHF);
-}
-
-void I386_OPS_BASE::I386OP(lodsb)() // Opcode 0xac
-{
- UINT32 eas;
- if( cpustate->segment_prefix ) {
- eas = i386_translate( cpustate->segment_override, cpustate->address_size ? REG32(ESI) : REG16(SI), 0 );
- } else {
- eas = i386_translate( DS, cpustate->address_size ? REG32(ESI) : REG16(SI), 0 );
- }
- REG8(AL) = READ8(eas);
- BUMP_SI(1);
- CYCLES(CYCLES_LODS);
-}
-
-void I386_OPS_BASE::I386OP(mov_rm8_r8)() // Opcode 0x88
-{
- UINT8 src;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- src = LOAD_REG8(modrm);
- STORE_RM8(modrm, src);
- CYCLES(CYCLES_MOV_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- src = LOAD_REG8(modrm);
- WRITE8(ea, src);
- CYCLES(CYCLES_MOV_REG_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(mov_r8_rm8)() // Opcode 0x8a
-{
- UINT8 src;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- src = LOAD_RM8(modrm);
- STORE_REG8(modrm, src);
- CYCLES(CYCLES_MOV_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,0);
- src = READ8(ea);
- STORE_REG8(modrm, src);
- CYCLES(CYCLES_MOV_MEM_REG);
- }
-}
-
-void I386_OPS_BASE::I386OP(mov_rm8_i8)() // Opcode 0xc6
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- UINT8 value = FETCH();
- STORE_RM8(modrm, value);
- CYCLES(CYCLES_MOV_IMM_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- UINT8 value = FETCH();
- WRITE8(ea, value);
- CYCLES(CYCLES_MOV_IMM_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(mov_r32_cr)() // Opcode 0x0f 20
-{
- if(PROTECTED_MODE && cpustate->CPL)
- FAULT(FAULT_GP, 0);
- UINT8 modrm = FETCH();
- UINT8 cr = (modrm >> 3) & 0x7;
-
- STORE_RM32(modrm, cpustate->cr[cr]);
- CYCLES(CYCLES_MOV_CR_REG);
-}
-
-void I386_OPS_BASE::I386OP(mov_r32_dr)() // Opcode 0x0f 21
-{
- if(PROTECTED_MODE && cpustate->CPL)
- FAULT(FAULT_GP, 0);
- UINT8 modrm = FETCH();
- UINT8 dr = (modrm >> 3) & 0x7;
-
- STORE_RM32(modrm, cpustate->dr[dr]);
- switch(dr)
- {
- case 0:
- case 1:
- case 2:
- case 3:
- CYCLES(CYCLES_MOV_REG_DR0_3);
- break;
- case 6:
- case 7:
- CYCLES(CYCLES_MOV_REG_DR6_7);
- break;
- }
-}
-
-void I386_OPS_BASE::I386OP(mov_cr_r32)() // Opcode 0x0f 22
-{
- if(PROTECTED_MODE && cpustate->CPL)
- FAULT(FAULT_GP, 0);
- UINT8 modrm = FETCH();
- UINT8 cr = (modrm >> 3) & 0x7;
- UINT32 data = LOAD_RM32(modrm);
- switch(cr)
- {
- case 0:
- data &= 0xfffeffff; // wp not supported on 386
- CYCLES(CYCLES_MOV_REG_CR0);
- break;
- case 2: CYCLES(CYCLES_MOV_REG_CR2); break;
- case 3:
- CYCLES(CYCLES_MOV_REG_CR3);
- vtlb_flush_dynamic(cpustate->vtlb);
- break;
- case 4: CYCLES(1); break; // TODO
- default:
- logerror("i386: mov_cr_r32 CR%d!\n", cr);
- return;
- }
- cpustate->cr[cr] = data;
-}
-
-void I386_OPS_BASE::I386OP(mov_dr_r32)() // Opcode 0x0f 23
-{
- if(PROTECTED_MODE && cpustate->CPL)
- FAULT(FAULT_GP, 0);
- UINT8 modrm = FETCH();
- UINT8 dr = (modrm >> 3) & 0x7;
-
- cpustate->dr[dr] = LOAD_RM32(modrm);
- switch(dr)
- {
- case 0:
- case 1:
- case 2:
- case 3:
- CYCLES(CYCLES_MOV_DR0_3_REG);
- break;
- case 6:
- case 7:
- CYCLES(CYCLES_MOV_DR6_7_REG);
- break;
- default:
- logerror("i386: mov_dr_r32 DR%d!\n", dr);
- return;
- }
-}
-
-void I386_OPS_BASE::I386OP(mov_al_m8)() // Opcode 0xa0
-{
- UINT32 offset, ea;
- if( cpustate->address_size ) {
- offset = FETCH32();
- } else {
- offset = FETCH16();
- }
- /* TODO: Not sure if this is correct... */
- if( cpustate->segment_prefix ) {
- ea = i386_translate( cpustate->segment_override, offset, 0 );
- } else {
- ea = i386_translate( DS, offset, 0 );
- }
- REG8(AL) = READ8(ea);
- CYCLES(CYCLES_MOV_IMM_MEM);
-}
-
-void I386_OPS_BASE::I386OP(mov_m8_al)() // Opcode 0xa2
-{
- UINT32 offset, ea;
- if( cpustate->address_size ) {
- offset = FETCH32();
- } else {
- offset = FETCH16();
- }
- /* TODO: Not sure if this is correct... */
- if( cpustate->segment_prefix ) {
- ea = i386_translate( cpustate->segment_override, offset, 1 );
- } else {
- ea = i386_translate( DS, offset, 1 );
- }
- WRITE8( ea, REG8(AL) );
- CYCLES(CYCLES_MOV_MEM_ACC);
-}
-
-void I386_OPS_BASE::I386OP(mov_rm16_sreg)() // Opcode 0x8c
-{
- UINT8 modrm = FETCH();
- int s = (modrm >> 3) & 0x7;
-
- if( modrm >= 0xc0 ) {
- if(cpustate->operand_size)
- STORE_RM32(modrm, cpustate->sreg[s].selector);
- else
- STORE_RM16(modrm, cpustate->sreg[s].selector);
- CYCLES(CYCLES_MOV_SREG_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- WRITE16(ea, cpustate->sreg[s].selector);
- CYCLES(CYCLES_MOV_SREG_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(mov_sreg_rm16)() // Opcode 0x8e
-{
- UINT16 selector;
- UINT8 modrm = FETCH();
- bool fault;
- int s = (modrm >> 3) & 0x7;
-
- if( modrm >= 0xc0 ) {
- selector = LOAD_RM16(modrm);
- CYCLES(CYCLES_MOV_REG_SREG);
- } else {
- UINT32 ea = GetEA(modrm,0);
- selector = READ16(ea);
- CYCLES(CYCLES_MOV_MEM_SREG);
- }
-
- i386_sreg_load(selector,s,&fault);
- if((s == SS) && !fault)
- {
- if(cpustate->IF != 0) // if external interrupts are enabled
- {
- cpustate->IF = 0; // reset IF for the next instruction
- cpustate->delayed_interrupt_enable = 1;
- }
- }
-}
-
-void I386_OPS_BASE::I386OP(mov_al_i8)() // Opcode 0xb0
-{
- REG8(AL) = FETCH();
- CYCLES(CYCLES_MOV_IMM_REG);
-}
-
-void I386_OPS_BASE::I386OP(mov_cl_i8)() // Opcode 0xb1
-{
- REG8(CL) = FETCH();
- CYCLES(CYCLES_MOV_IMM_REG);
-}
-
-void I386_OPS_BASE::I386OP(mov_dl_i8)() // Opcode 0xb2
-{
- REG8(DL) = FETCH();
- CYCLES(CYCLES_MOV_IMM_REG);
-}
-
-void I386_OPS_BASE::I386OP(mov_bl_i8)() // Opcode 0xb3
-{
- REG8(BL) = FETCH();
- CYCLES(CYCLES_MOV_IMM_REG);
-}
-
-void I386_OPS_BASE::I386OP(mov_ah_i8)() // Opcode 0xb4
-{
- REG8(AH) = FETCH();
- CYCLES(CYCLES_MOV_IMM_REG);
-}
-
-void I386_OPS_BASE::I386OP(mov_ch_i8)() // Opcode 0xb5
-{
- REG8(CH) = FETCH();
- CYCLES(CYCLES_MOV_IMM_REG);
-}
-
-void I386_OPS_BASE::I386OP(mov_dh_i8)() // Opcode 0xb6
-{
- REG8(DH) = FETCH();
- CYCLES(CYCLES_MOV_IMM_REG);
-}
-
-void I386_OPS_BASE::I386OP(mov_bh_i8)() // Opcode 0xb7
-{
- REG8(BH) = FETCH();
- CYCLES(CYCLES_MOV_IMM_REG);
-}
-
-void I386_OPS_BASE::I386OP(movsb)() // Opcode 0xa4
-{
- UINT32 eas, ead;
- UINT8 v;
- if( cpustate->segment_prefix ) {
- eas = i386_translate( cpustate->segment_override, cpustate->address_size ? REG32(ESI) : REG16(SI), 0 );
- } else {
- eas = i386_translate( DS, cpustate->address_size ? REG32(ESI) : REG16(SI), 0 );
- }
- ead = i386_translate( ES, cpustate->address_size ? REG32(EDI) : REG16(DI), 1 );
- v = READ8(eas);
- WRITE8(ead, v);
- BUMP_SI(1);
- BUMP_DI(1);
- CYCLES(CYCLES_MOVS);
-}
-
-void I386_OPS_BASE::I386OP(or_rm8_r8)() // Opcode 0x08
-{
- UINT8 src, dst;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- src = LOAD_REG8(modrm);
- dst = LOAD_RM8(modrm);
- dst = OR8(dst, src);
- STORE_RM8(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- src = LOAD_REG8(modrm);
- dst = READ8(ea);
- dst = OR8(dst, src);
- WRITE8(ea, dst);
- CYCLES(CYCLES_ALU_REG_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(or_r8_rm8)() // Opcode 0x0a
-{
- UINT8 src, dst;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- src = LOAD_RM8(modrm);
- dst = LOAD_REG8(modrm);
- dst = OR8(dst, src);
- STORE_REG8(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,0);
- src = READ8(ea);
- dst = LOAD_REG8(modrm);
- dst = OR8(dst, src);
- STORE_REG8(modrm, dst);
- CYCLES(CYCLES_ALU_MEM_REG);
- }
-}
-
-void I386_OPS_BASE::I386OP(or_al_i8)() // Opcode 0x0c
-{
- UINT8 src, dst;
- src = FETCH();
- dst = REG8(AL);
- dst = OR8(dst, src);
- REG8(EAX) = dst;
- CYCLES(CYCLES_ALU_IMM_ACC);
-}
-
-void I386_OPS_BASE::I386OP(out_al_i8)() // Opcode 0xe6
-{
- UINT16 port = FETCH();
- UINT8 data = REG8(AL);
- WRITEPORT8( port, data);
- CYCLES(CYCLES_OUT_VAR);
-}
-
-void I386_OPS_BASE::I386OP(out_al_dx)() // Opcode 0xee
-{
- UINT16 port = REG16(DX);
- UINT8 data = REG8(AL);
- WRITEPORT8( port, data);
- CYCLES(CYCLES_OUT);
-}
-
-
-void I386_OPS_BASE::I386OP(arpl)() // Opcode 0x63
-{
- UINT16 src, dst;
- UINT8 modrm = FETCH();
- UINT8 flag = 0;
-
- if(PROTECTED_MODE && !V8086_MODE)
- {
- if( modrm >= 0xc0 ) {
- src = LOAD_REG16(modrm);
- dst = LOAD_RM16(modrm);
- if( (dst&0x3) < (src&0x3) ) {
- dst = (dst&0xfffc) | (src&0x3);
- flag = 1;
- STORE_RM16(modrm, dst);
- }
- } else {
- UINT32 ea = GetEA( modrm,1);
- src = LOAD_REG16(modrm);
- dst = READ16( ea);
- if( (dst&0x3) < (src&0x3) ) {
- dst = (dst&0xfffc) | (src&0x3);
- flag = 1;
- WRITE16( ea, dst);
- }
- }
- SetZF(flag);
- }
- else
- i386_trap( 6, 0, 0); // invalid opcode in real mode or v8086 mode
-}
-
-void I386_OPS_BASE::I386OP(push_i8)() // Opcode 0x6a
-{
- UINT8 value = FETCH();
- PUSH8(value);
- CYCLES(CYCLES_PUSH_IMM);
-}
-
-void I386_OPS_BASE::I386OP(ins_generic)( int size)
-{
- UINT32 ead;
- UINT8 vb;
- UINT16 vw;
- UINT32 vd;
-
- ead = i386_translate( ES, cpustate->address_size ? REG32(EDI) : REG16(DI), 1 );
-
- switch(size) {
- case 1:
- vb = READPORT8( REG16(DX));
- WRITE8(ead, vb);
- break;
- case 2:
- vw = READPORT16( REG16(DX));
- WRITE16(ead, vw);
- break;
- case 4:
- vd = READPORT32( REG16(DX));
- WRITE32(ead, vd);
- break;
- }
-
- if(cpustate->address_size)
- REG32(EDI) += ((cpustate->DF) ? -1 : 1) * size;
- else
- REG16(DI) += ((cpustate->DF) ? -1 : 1) * size;
- CYCLES(CYCLES_INS); // TODO: Confirm this value
-}
-
-void I386_OPS_BASE::I386OP(insb)() // Opcode 0x6c
-{
- I386_OPS_BASE::I386OP(ins_generic)( 1);
-}
-
-void I386_OPS_BASE::I386OP(insw)() // Opcode 0x6d
-{
- I386_OPS_BASE::I386OP(ins_generic)( 2);
-}
-
-void I386_OPS_BASE::I386OP(insd)() // Opcode 0x6d
-{
- I386_OPS_BASE::I386OP(ins_generic)( 4);
-}
-
-void I386_OPS_BASE::I386OP(outs_generic)( int size)
-{
- UINT32 eas;
- UINT8 vb;
- UINT16 vw;
- UINT32 vd;
-
- if( cpustate->segment_prefix ) {
- eas = i386_translate( cpustate->segment_override, cpustate->address_size ? REG32(ESI) : REG16(SI), 0 );
- } else {
- eas = i386_translate( DS, cpustate->address_size ? REG32(ESI) : REG16(SI), 0 );
- }
-
- switch(size) {
- case 1:
- vb = READ8(eas);
- WRITEPORT8( REG16(DX), vb);
- break;
- case 2:
- vw = READ16(eas);
- WRITEPORT16( REG16(DX), vw);
- break;
- case 4:
- vd = READ32(eas);
- WRITEPORT32( REG16(DX), vd);
- break;
- }
-
- if(cpustate->address_size)
- REG32(ESI) += ((cpustate->DF) ? -1 : 1) * size;
- else
- REG16(SI) += ((cpustate->DF) ? -1 : 1) * size;
- CYCLES(CYCLES_OUTS); // TODO: Confirm this value
-}
-
-void I386_OPS_BASE::I386OP(outsb)() // Opcode 0x6e
-{
- I386_OPS_BASE::I386OP(outs_generic)( 1);
-}
-
-void I386_OPS_BASE::I386OP(outsw)() // Opcode 0x6f
-{
- I386_OPS_BASE::I386OP(outs_generic)( 2);
-}
-
-void I386_OPS_BASE::I386OP(outsd)() // Opcode 0x6f
-{
- I386_OPS_BASE::I386OP(outs_generic)( 4);
-}
-
-void I386_OPS_BASE::I386OP(repeat)( int invert_flag)
-{
- UINT32 repeated_eip = cpustate->eip;
- UINT32 repeated_pc = cpustate->pc;
- UINT8 opcode; // = FETCH();
-// UINT32 eas, ead;
- UINT32 count;
- INT32 cycle_base = 0, cycle_adjustment = 0;
- UINT8 prefix_flag=1;
- UINT8 *flag = NULL;
-
-
- do {
- repeated_eip = cpustate->eip;
- repeated_pc = cpustate->pc;
- opcode = FETCH();
- switch(opcode) {
- case 0x0f:
- if (invert_flag == 0)
- I386_OPS_BASE::I386OP(decode_three_bytef3)(); // sse f3 0f
- else
- I386_OPS_BASE::I386OP(decode_three_bytef2)(); // sse f2 0f
- return;
- case 0x26:
- cpustate->segment_override=ES;
- cpustate->segment_prefix=1;
- break;
- case 0x2e:
- cpustate->segment_override=CS;
- cpustate->segment_prefix=1;
- break;
- case 0x36:
- cpustate->segment_override=SS;
- cpustate->segment_prefix=1;
- break;
- case 0x3e:
- cpustate->segment_override=DS;
- cpustate->segment_prefix=1;
- break;
- case 0x64:
- cpustate->segment_override=FS;
- cpustate->segment_prefix=1;
- break;
- case 0x65:
- cpustate->segment_override=GS;
- cpustate->segment_prefix=1;
- break;
- case 0x66:
- cpustate->operand_size ^= 1;
- cpustate->xmm_operand_size ^= 1;
- break;
- case 0x67:
- cpustate->address_size ^= 1;
- break;
- default:
- prefix_flag=0;
- }
- } while (prefix_flag);
-
-
- if( cpustate->segment_prefix ) {
- // FIXME: the following does not work if both address override and segment override are used
- i386_translate( cpustate->segment_override, cpustate->sreg[cpustate->segment_prefix].d ? REG32(ESI) : REG16(SI), -1 );
- } else {
- //eas =
- i386_translate( DS, cpustate->address_size ? REG32(ESI) : REG16(SI), -1 );
- }
- i386_translate( ES, cpustate->address_size ? REG32(EDI) : REG16(DI), -1 );
-
- switch(opcode)
- {
- case 0x6c:
- case 0x6d:
- /* INSB, INSW, INSD */
- // TODO: cycle count
- cycle_base = 8;
- cycle_adjustment = -4;
- flag = NULL;
- break;
-
- case 0x6e:
- case 0x6f:
- /* OUTSB, OUTSW, OUTSD */
- // TODO: cycle count
- cycle_base = 8;
- cycle_adjustment = -4;
- flag = NULL;
- break;
-
- case 0xa4:
- case 0xa5:
- /* MOVSB, MOVSW, MOVSD */
- cycle_base = 8;
- cycle_adjustment = -4;
- flag = NULL;
- break;
-
- case 0xa6:
- case 0xa7:
- /* CMPSB, CMPSW, CMPSD */
- cycle_base = 5;
- cycle_adjustment = -1;
- flag = &cpustate->ZF;
- break;
-
- case 0xac:
- case 0xad:
- /* LODSB, LODSW, LODSD */
- cycle_base = 5;
- cycle_adjustment = 1;
- flag = NULL;
- break;
-
- case 0xaa:
- case 0xab:
- /* STOSB, STOSW, STOSD */
- cycle_base = 5;
- cycle_adjustment = 0;
- flag = NULL;
- break;
-
- case 0xae:
- case 0xaf:
- /* SCASB, SCASW, SCASD */
- cycle_base = 5;
- cycle_adjustment = 0;
- flag = &cpustate->ZF;
- break;
-
- case 0x90:
- CYCLES(CYCLES_NOP);
- return;
-
- case 0xc2: // sigh
- case 0xc3:
- cpustate->pc--;
- return;
-
- default:
- fatalerror("i386: Invalid REP/opcode %02X combination\n",opcode);
- break;
- }
-
- if( cpustate->address_size ) {
- if( REG32(ECX) == 0 )
- return;
- } else {
- if( REG16(CX) == 0 )
- return;
- }
-
- /* now actually perform the repeat */
- CYCLES_NUM(cycle_base);
- do
- {
- cpustate->eip = repeated_eip;
- cpustate->pc = repeated_pc;
- try
- {
- I386_OPS_BASE::I386OP(decode_opcode)();
- }
- catch (UINT64 e)
- {
- cpustate->eip = cpustate->prev_eip;
- throw e;
- }
-
- CYCLES_NUM(cycle_adjustment);
-
- if (cpustate->address_size)
- count = --REG32(ECX);
- else
- count = --REG16(CX);
- if (cpustate->cycles <= 0)
- goto outofcycles;
- }
- while( count && (!flag || (invert_flag ? !*flag : *flag)) );
- return;
-
-outofcycles:
- /* if we run out of cycles to execute, and we are still in the repeat, we need
- * to exit this instruction in such a way to go right back into it when we have
- * time to execute cycles */
- if(flag && (invert_flag ? *flag : !*flag))
- return;
- cpustate->eip = cpustate->prev_eip;
- CHANGE_PC(cpustate->eip);
- CYCLES_NUM(-cycle_base);
-}
-
-void I386_OPS_BASE::I386OP(rep)() // Opcode 0xf3
-{
- I386_OPS_BASE::I386OP(repeat)( 0);
-}
-
-void I386_OPS_BASE::I386OP(repne)() // Opcode 0xf2
-{
- I386_OPS_BASE::I386OP(repeat)( 1);
-}
-
-void I386_OPS_BASE::I386OP(sahf)() // Opcode 0x9e
-{
- set_flags( (get_flags() & 0xffffff00) | (REG8(AH) & 0xd7) );
- CYCLES(CYCLES_SAHF);
-}
-
-void I386_OPS_BASE::I386OP(sbb_rm8_r8)() // Opcode 0x18
-{
- UINT8 src, dst;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- src = LOAD_REG8(modrm);
- dst = LOAD_RM8(modrm);
- dst = SBB8( dst, src, cpustate->CF);
- STORE_RM8(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- src = LOAD_REG8(modrm);
- dst = READ8(ea);
- dst = SBB8( dst, src, cpustate->CF);
- WRITE8(ea, dst);
- CYCLES(CYCLES_ALU_REG_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(sbb_r8_rm8)() // Opcode 0x1a
-{
- UINT8 src, dst;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- src = LOAD_RM8(modrm);
- dst = LOAD_REG8(modrm);
- dst = SBB8( dst, src, cpustate->CF);
- STORE_REG8(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,0);
- src = READ8(ea);
- dst = LOAD_REG8(modrm);
- dst = SBB8( dst, src, cpustate->CF);
- STORE_REG8(modrm, dst);
- CYCLES(CYCLES_ALU_MEM_REG);
- }
-}
-
-void I386_OPS_BASE::I386OP(sbb_al_i8)() // Opcode 0x1c
-{
- UINT8 src, dst;
- src = FETCH();
- dst = REG8(AL);
- dst = SBB8( dst, src, cpustate->CF);
- REG8(EAX) = dst;
- CYCLES(CYCLES_ALU_IMM_ACC);
-}
-
-void I386_OPS_BASE::I386OP(scasb)() // Opcode 0xae
-{
- UINT32 eas;
- UINT8 src, dst;
- eas = i386_translate( ES, cpustate->address_size ? REG32(EDI) : REG16(DI), 0 );
- src = READ8(eas);
- dst = REG8(AL);
- SUB8(dst, src);
- BUMP_DI(1);
- CYCLES(CYCLES_SCAS);
-}
-
-void I386_OPS_BASE::I386OP(setalc)() // Opcode 0xd6 (undocumented)
-{
- if( cpustate->CF ) {
- REG8(AL) = 0xff;
- } else {
- REG8(AL) = 0;
- }
- CYCLES(3);
-}
-
-void I386_OPS_BASE::I386OP(seta_rm8)() // Opcode 0x0f 97
-{
- UINT8 modrm = FETCH();
- UINT8 value = 0;
- if( cpustate->CF == 0 && cpustate->ZF == 0 ) {
- value = 1;
- }
- if( modrm >= 0xc0 ) {
- STORE_RM8(modrm, value);
- CYCLES(CYCLES_SETCC_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- WRITE8(ea, value);
- CYCLES(CYCLES_SETCC_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(setbe_rm8)() // Opcode 0x0f 96
-{
- UINT8 modrm = FETCH();
- UINT8 value = 0;
- if( cpustate->CF != 0 || cpustate->ZF != 0 ) {
- value = 1;
- }
- if( modrm >= 0xc0 ) {
- STORE_RM8(modrm, value);
- CYCLES(CYCLES_SETCC_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- WRITE8(ea, value);
- CYCLES(CYCLES_SETCC_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(setc_rm8)() // Opcode 0x0f 92
-{
- UINT8 modrm = FETCH();
- UINT8 value = 0;
- if( cpustate->CF != 0 ) {
- value = 1;
- }
- if( modrm >= 0xc0 ) {
- STORE_RM8(modrm, value);
- CYCLES(CYCLES_SETCC_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- WRITE8(ea, value);
- CYCLES(CYCLES_SETCC_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(setg_rm8)() // Opcode 0x0f 9f
-{
- UINT8 modrm = FETCH();
- UINT8 value = 0;
- if( cpustate->ZF == 0 && (cpustate->SF == cpustate->OF) ) {
- value = 1;
- }
- if( modrm >= 0xc0 ) {
- STORE_RM8(modrm, value);
- CYCLES(CYCLES_SETCC_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- WRITE8(ea, value);
- CYCLES(CYCLES_SETCC_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(setge_rm8)() // Opcode 0x0f 9d
-{
- UINT8 modrm = FETCH();
- UINT8 value = 0;
- if(cpustate->SF == cpustate->OF) {
- value = 1;
- }
- if( modrm >= 0xc0 ) {
- STORE_RM8(modrm, value);
- CYCLES(CYCLES_SETCC_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- WRITE8(ea, value);
- CYCLES(CYCLES_SETCC_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(setl_rm8)() // Opcode 0x0f 9c
-{
- UINT8 modrm = FETCH();
- UINT8 value = 0;
- if( cpustate->SF != cpustate->OF ) {
- value = 1;
- }
- if( modrm >= 0xc0 ) {
- STORE_RM8(modrm, value);
- CYCLES(CYCLES_SETCC_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- WRITE8(ea, value);
- CYCLES(CYCLES_SETCC_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(setle_rm8)() // Opcode 0x0f 9e
-{
- UINT8 modrm = FETCH();
- UINT8 value = 0;
- if( cpustate->ZF != 0 || (cpustate->SF != cpustate->OF) ) {
- value = 1;
- }
- if( modrm >= 0xc0 ) {
- STORE_RM8(modrm, value);
- CYCLES(CYCLES_SETCC_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- WRITE8(ea, value);
- CYCLES(CYCLES_SETCC_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(setnc_rm8)() // Opcode 0x0f 93
-{
- UINT8 modrm = FETCH();
- UINT8 value = 0;
- if( cpustate->CF == 0 ) {
- value = 1;
- }
- if( modrm >= 0xc0 ) {
- STORE_RM8(modrm, value);
- CYCLES(CYCLES_SETCC_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- WRITE8(ea, value);
- CYCLES(CYCLES_SETCC_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(setno_rm8)() // Opcode 0x0f 91
-{
- UINT8 modrm = FETCH();
- UINT8 value = 0;
- if( cpustate->OF == 0 ) {
- value = 1;
- }
- if( modrm >= 0xc0 ) {
- STORE_RM8(modrm, value);
- CYCLES(CYCLES_SETCC_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- WRITE8(ea, value);
- CYCLES(CYCLES_SETCC_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(setnp_rm8)() // Opcode 0x0f 9b
-{
- UINT8 modrm = FETCH();
- UINT8 value = 0;
- if( cpustate->PF == 0 ) {
- value = 1;
- }
- if( modrm >= 0xc0 ) {
- STORE_RM8(modrm, value);
- CYCLES(CYCLES_SETCC_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- WRITE8(ea, value);
- CYCLES(CYCLES_SETCC_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(setns_rm8)() // Opcode 0x0f 99
-{
- UINT8 modrm = FETCH();
- UINT8 value = 0;
- if( cpustate->SF == 0 ) {
- value = 1;
- }
- if( modrm >= 0xc0 ) {
- STORE_RM8(modrm, value);
- CYCLES(CYCLES_SETCC_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- WRITE8(ea, value);
- CYCLES(CYCLES_SETCC_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(setnz_rm8)() // Opcode 0x0f 95
-{
- UINT8 modrm = FETCH();
- UINT8 value = 0;
- if( cpustate->ZF == 0 ) {
- value = 1;
- }
- if( modrm >= 0xc0 ) {
- STORE_RM8(modrm, value);
- CYCLES(CYCLES_SETCC_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- WRITE8(ea, value);
- CYCLES(CYCLES_SETCC_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(seto_rm8)() // Opcode 0x0f 90
-{
- UINT8 modrm = FETCH();
- UINT8 value = 0;
- if( cpustate->OF != 0 ) {
- value = 1;
- }
- if( modrm >= 0xc0 ) {
- STORE_RM8(modrm, value);
- CYCLES(CYCLES_SETCC_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- WRITE8(ea, value);
- CYCLES(CYCLES_SETCC_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(setp_rm8)() // Opcode 0x0f 9a
-{
- UINT8 modrm = FETCH();
- UINT8 value = 0;
- if( cpustate->PF != 0 ) {
- value = 1;
- }
- if( modrm >= 0xc0 ) {
- STORE_RM8(modrm, value);
- CYCLES(CYCLES_SETCC_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- WRITE8(ea, value);
- CYCLES(CYCLES_SETCC_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(sets_rm8)() // Opcode 0x0f 98
-{
- UINT8 modrm = FETCH();
- UINT8 value = 0;
- if( cpustate->SF != 0 ) {
- value = 1;
- }
- if( modrm >= 0xc0 ) {
- STORE_RM8(modrm, value);
- CYCLES(CYCLES_SETCC_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- WRITE8(ea, value);
- CYCLES(CYCLES_SETCC_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(setz_rm8)() // Opcode 0x0f 94
-{
- UINT8 modrm = FETCH();
- UINT8 value = 0;
- if( cpustate->ZF != 0 ) {
- value = 1;
- }
- if( modrm >= 0xc0 ) {
- STORE_RM8(modrm, value);
- CYCLES(CYCLES_SETCC_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- WRITE8(ea, value);
- CYCLES(CYCLES_SETCC_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(stc)() // Opcode 0xf9
-{
- cpustate->CF = 1;
- CYCLES(CYCLES_STC);
-}
-
-void I386_OPS_BASE::I386OP(std)() // Opcode 0xfd
-{
- cpustate->DF = 1;
- CYCLES(CYCLES_STD);
-}
-
-void I386_OPS_BASE::I386OP(sti)() // Opcode 0xfb
-{
- if(PROTECTED_MODE)
- {
- UINT8 IOPL = cpustate->IOP1 | (cpustate->IOP2 << 1);
- if(cpustate->CPL > IOPL)
- FAULT(FAULT_GP,0);
- }
- cpustate->delayed_interrupt_enable = 1; // IF is set after the next instruction.
- CYCLES(CYCLES_STI);
-}
-
-void I386_OPS_BASE::I386OP(stosb)() // Opcode 0xaa
-{
- UINT32 ead;
- ead = i386_translate( ES, cpustate->address_size ? REG32(EDI) : REG16(DI), 1 );
- WRITE8(ead, REG8(AL));
- BUMP_DI(1);
- CYCLES(CYCLES_STOS);
-}
-
-void I386_OPS_BASE::I386OP(sub_rm8_r8)() // Opcode 0x28
-{
- UINT8 src, dst;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- src = LOAD_REG8(modrm);
- dst = LOAD_RM8(modrm);
- dst = SUB8(dst, src);
- STORE_RM8(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- src = LOAD_REG8(modrm);
- dst = READ8(ea);
- dst = SUB8(dst, src);
- WRITE8(ea, dst);
- CYCLES(CYCLES_ALU_REG_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(sub_r8_rm8)() // Opcode 0x2a
-{
- UINT8 src, dst;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- src = LOAD_RM8(modrm);
- dst = LOAD_REG8(modrm);
- dst = SUB8(dst, src);
- STORE_REG8(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,0);
- src = READ8(ea);
- dst = LOAD_REG8(modrm);
- dst = SUB8(dst, src);
- STORE_REG8(modrm, dst);
- CYCLES(CYCLES_ALU_MEM_REG);
- }
-}
-
-void I386_OPS_BASE::I386OP(sub_al_i8)() // Opcode 0x2c
-{
- UINT8 src, dst;
- src = FETCH();
- dst = REG8(EAX);
- dst = SUB8(dst, src);
- REG8(EAX) = dst;
- CYCLES(CYCLES_ALU_IMM_ACC);
-}
-
-void I386_OPS_BASE::I386OP(test_al_i8)() // Opcode 0xa8
-{
- UINT8 src = FETCH();
- UINT8 dst = REG8(AL);
- dst = src & dst;
- SetSZPF8(dst);
- cpustate->CF = 0;
- cpustate->OF = 0;
- CYCLES(CYCLES_ALU_IMM_ACC);
-}
-
-void I386_OPS_BASE::I386OP(test_rm8_r8)() // Opcode 0x84
-{
- UINT8 src, dst;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- src = LOAD_REG8(modrm);
- dst = LOAD_RM8(modrm);
- dst = src & dst;
- SetSZPF8(dst);
- cpustate->CF = 0;
- cpustate->OF = 0;
- CYCLES(CYCLES_TEST_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,0);
- src = LOAD_REG8(modrm);
- dst = READ8(ea);
- dst = src & dst;
- SetSZPF8(dst);
- cpustate->CF = 0;
- cpustate->OF = 0;
- CYCLES(CYCLES_TEST_REG_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(xchg_r8_rm8)() // Opcode 0x86
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- UINT8 src = LOAD_RM8(modrm);
- UINT8 dst = LOAD_REG8(modrm);
- STORE_REG8(modrm, src);
- STORE_RM8(modrm, dst);
- CYCLES(CYCLES_XCHG_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- UINT8 src = READ8(ea);
- UINT8 dst = LOAD_REG8(modrm);
- WRITE8(ea, dst);
- STORE_REG8(modrm, src);
- CYCLES(CYCLES_XCHG_REG_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(xor_rm8_r8)() // Opcode 0x30
-{
- UINT8 src, dst;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- src = LOAD_REG8(modrm);
- dst = LOAD_RM8(modrm);
- dst = XOR8(dst, src);
- STORE_RM8(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- src = LOAD_REG8(modrm);
- dst = READ8(ea);
- dst = XOR8(dst, src);
- WRITE8(ea, dst);
- CYCLES(CYCLES_ALU_REG_MEM);
- }
-}
-
-void I386_OPS_BASE::I386OP(xor_r8_rm8)() // Opcode 0x32
-{
- UINT32 src, dst;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- src = LOAD_RM8(modrm);
- dst = LOAD_REG8(modrm);
- dst = XOR8(dst, src);
- STORE_REG8(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,0);
- src = READ8(ea);
- dst = LOAD_REG8(modrm);
- dst = XOR8(dst, src);
- STORE_REG8(modrm, dst);
- CYCLES(CYCLES_ALU_MEM_REG);
- }
-}
-
-void I386_OPS_BASE::I386OP(xor_al_i8)() // Opcode 0x34
-{
- UINT8 src, dst;
- src = FETCH();
- dst = REG8(AL);
- dst = XOR8(dst, src);
- REG8(AL) = dst;
- CYCLES(CYCLES_ALU_IMM_ACC);
-}
-
-
-
-void I386_OPS_BASE::I386OP(group80_8)() // Opcode 0x80
-{
- UINT32 ea;
- UINT8 src, dst;
- UINT8 modrm = FETCH();
-
- switch( (modrm >> 3) & 0x7 )
- {
- case 0: // ADD Rm8, i8
- if( modrm >= 0xc0 ) {
- dst = LOAD_RM8(modrm);
- src = FETCH();
- dst = ADD8(dst, src);
- STORE_RM8(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- ea = GetEA(modrm,0);
- dst = READ8(ea);
- src = FETCH();
- dst = ADD8(dst, src);
- WRITE8(ea, dst);
- CYCLES(CYCLES_ALU_REG_MEM);
- }
- break;
- case 1: // OR Rm8, i8
- if( modrm >= 0xc0 ) {
- dst = LOAD_RM8(modrm);
- src = FETCH();
- dst = OR8(dst, src);
- STORE_RM8(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- ea = GetEA(modrm,1);
- dst = READ8(ea);
- src = FETCH();
- dst = OR8(dst, src);
- WRITE8(ea, dst);
- CYCLES(CYCLES_ALU_REG_MEM);
- }
- break;
- case 2: // ADC Rm8, i8
- if( modrm >= 0xc0 ) {
- dst = LOAD_RM8(modrm);
- src = FETCH();
- dst = ADC8( dst, src, cpustate->CF);
- STORE_RM8(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- ea = GetEA(modrm,1);
- dst = READ8(ea);
- src = FETCH();
- dst = ADC8( dst, src, cpustate->CF);
- WRITE8(ea, dst);
- CYCLES(CYCLES_ALU_REG_MEM);
- }
- break;
- case 3: // SBB Rm8, i8
- if( modrm >= 0xc0 ) {
- dst = LOAD_RM8(modrm);
- src = FETCH();
- dst = SBB8( dst, src, cpustate->CF);
- STORE_RM8(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- ea = GetEA(modrm,1);
- dst = READ8(ea);
- src = FETCH();
- dst = SBB8( dst, src, cpustate->CF);
- WRITE8(ea, dst);
- CYCLES(CYCLES_ALU_REG_MEM);
- }
- break;
- case 4: // AND Rm8, i8
- if( modrm >= 0xc0 ) {
- dst = LOAD_RM8(modrm);
- src = FETCH();
- dst = AND8(dst, src);
- STORE_RM8(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- ea = GetEA(modrm,1);
- dst = READ8(ea);
- src = FETCH();
- dst = AND8(dst, src);
- WRITE8(ea, dst);
- CYCLES(CYCLES_ALU_REG_MEM);
- }
- break;
- case 5: // SUB Rm8, i8
- if( modrm >= 0xc0 ) {
- dst = LOAD_RM8(modrm);
- src = FETCH();
- dst = SUB8(dst, src);
- STORE_RM8(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- ea = GetEA(modrm,1);
- dst = READ8(ea);
- src = FETCH();
- dst = SUB8(dst, src);
- WRITE8(ea, dst);
- CYCLES(CYCLES_ALU_REG_MEM);
- }
- break;
- case 6: // XOR Rm8, i8
- if( modrm >= 0xc0 ) {
- dst = LOAD_RM8(modrm);
- src = FETCH();
- dst = XOR8(dst, src);
- STORE_RM8(modrm, dst);
- CYCLES(CYCLES_ALU_REG_REG);
- } else {
- ea = GetEA(modrm,1);
- dst = READ8(ea);
- src = FETCH();
- dst = XOR8(dst, src);
- WRITE8(ea, dst);
- CYCLES(CYCLES_ALU_REG_MEM);
- }
- break;
- case 7: // CMP Rm8, i8
- if( modrm >= 0xc0 ) {
- dst = LOAD_RM8(modrm);
- src = FETCH();
- SUB8(dst, src);
- CYCLES(CYCLES_CMP_REG_REG);
- } else {
- ea = GetEA(modrm,0);
- dst = READ8(ea);
- src = FETCH();
- SUB8(dst, src);
- CYCLES(CYCLES_CMP_REG_MEM);
- }
- break;
- }
-}
-
-void I386_OPS_BASE::I386OP(groupC0_8)() // Opcode 0xc0
-{
- UINT8 dst;
- UINT8 modrm = FETCH();
- UINT8 shift;
-
- if( modrm >= 0xc0 ) {
- dst = LOAD_RM8(modrm);
- shift = FETCH() & 0x1f;
- dst = i386_shift_rotate8( modrm, dst, shift);
- STORE_RM8(modrm, dst);
- } else {
- UINT32 ea = GetEA(modrm,1);
- dst = READ8(ea);
- shift = FETCH() & 0x1f;
- dst = i386_shift_rotate8( modrm, dst, shift);
- WRITE8(ea, dst);
- }
-}
-
-void I386_OPS_BASE::I386OP(groupD0_8)() // Opcode 0xd0
-{
- UINT8 dst;
- UINT8 modrm = FETCH();
-
- if( modrm >= 0xc0 ) {
- dst = LOAD_RM8(modrm);
- dst = i386_shift_rotate8( modrm, dst, 1);
- STORE_RM8(modrm, dst);
- } else {
- UINT32 ea = GetEA(modrm,1);
- dst = READ8(ea);
- dst = i386_shift_rotate8( modrm, dst, 1);
- WRITE8(ea, dst);
- }
-}
-
-void I386_OPS_BASE::I386OP(groupD2_8)() // Opcode 0xd2
-{
- UINT8 dst;
- UINT8 modrm = FETCH();
-
- if( modrm >= 0xc0 ) {
- dst = LOAD_RM8(modrm);
- dst = i386_shift_rotate8( modrm, dst, REG8(CL));
- STORE_RM8(modrm, dst);
- } else {
- UINT32 ea = GetEA(modrm,1);
- dst = READ8(ea);
- dst = i386_shift_rotate8( modrm, dst, REG8(CL));
- WRITE8(ea, dst);
- }
-}
-
-void I386_OPS_BASE::I386OP(groupF6_8)() // Opcode 0xf6
-{
- UINT8 modrm = FETCH();
-
- switch( (modrm >> 3) & 0x7 )
- {
- case 0: /* TEST Rm8, i8 */
- if( modrm >= 0xc0 ) {
- UINT8 dst = LOAD_RM8(modrm);
- UINT8 src = FETCH();
- dst &= src;
- cpustate->CF = cpustate->OF = cpustate->AF = 0;
- SetSZPF8(dst);
- CYCLES(CYCLES_TEST_IMM_REG);
- } else {
- UINT32 ea = GetEA(modrm,0);
- UINT8 dst = READ8(ea);
- UINT8 src = FETCH();
- dst &= src;
- cpustate->CF = cpustate->OF = cpustate->AF = 0;
- SetSZPF8(dst);
- CYCLES(CYCLES_TEST_IMM_MEM);
- }
- break;
- case 2: /* NOT Rm8 */
- if( modrm >= 0xc0 ) {
- UINT8 dst = LOAD_RM8(modrm);
- dst = ~dst;
- STORE_RM8(modrm, dst);
- CYCLES(CYCLES_NOT_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- UINT8 dst = READ8(ea);
- dst = ~dst;
- WRITE8(ea, dst);
- CYCLES(CYCLES_NOT_MEM);
- }
- break;
- case 3: /* NEG Rm8 */
- if( modrm >= 0xc0 ) {
- UINT8 dst = LOAD_RM8(modrm);
- dst = SUB8( 0, dst );
- STORE_RM8(modrm, dst);
- CYCLES(CYCLES_NEG_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- UINT8 dst = READ8(ea);
- dst = SUB8( 0, dst );
- WRITE8(ea, dst);
- CYCLES(CYCLES_NEG_MEM);
- }
- break;
- case 4: /* MUL AL, Rm8 */
- {
- UINT16 result;
- UINT8 src, dst;
- if( modrm >= 0xc0 ) {
- src = LOAD_RM8(modrm);
- CYCLES(CYCLES_MUL8_ACC_REG); /* TODO: Correct multiply timing */
- } else {
- UINT32 ea = GetEA(modrm,0);
- src = READ8(ea);
- CYCLES(CYCLES_MUL8_ACC_MEM); /* TODO: Correct multiply timing */
- }
-
- dst = REG8(AL);
- result = (UINT16)src * (UINT16)dst;
- REG16(AX) = (UINT16)result;
-
- cpustate->CF = cpustate->OF = (REG16(AX) > 0xff);
- }
- break;
- case 5: /* IMUL AL, Rm8 */
- {
- INT16 result;
- INT16 src, dst;
- if( modrm >= 0xc0 ) {
- src = (INT16)(INT8)LOAD_RM8(modrm);
- CYCLES(CYCLES_IMUL8_ACC_REG); /* TODO: Correct multiply timing */
- } else {
- UINT32 ea = GetEA(modrm,0);
- src = (INT16)(INT8)READ8(ea);
- CYCLES(CYCLES_IMUL8_ACC_MEM); /* TODO: Correct multiply timing */
- }
-
- dst = (INT16)(INT8)REG8(AL);
- result = src * dst;
-
- REG16(AX) = (UINT16)result;
-
- cpustate->CF = cpustate->OF = !(result == (INT16)(INT8)result);
- }
- break;
- case 6: /* DIV AL, Rm8 */
- {
- UINT16 quotient, remainder, result;
- UINT8 src;
- if( modrm >= 0xc0 ) {
- src = LOAD_RM8(modrm);
- CYCLES(CYCLES_DIV8_ACC_REG);
- } else {
- UINT32 ea = GetEA(modrm,0);
- src = READ8(ea);
- CYCLES(CYCLES_DIV8_ACC_MEM);
- }
-
- quotient = (UINT16)REG16(AX);
- if( src ) {
- remainder = quotient % (UINT16)src;
- result = quotient / (UINT16)src;
- if( result > 0xff ) {
- /* TODO: Divide error */
- } else {
- REG8(AH) = (UINT8)remainder & 0xff;
- REG8(AL) = (UINT8)result & 0xff;
-
- // this flag is actually undefined, enable on non-cyrix
- if (cpustate->cpuid_id0 != 0x69727943)
- cpustate->CF = 1;
- }
- } else {
- i386_trap( 0, 0, 0);
- }
- }
- break;
- case 7: /* IDIV AL, Rm8 */
- {
- INT16 quotient, remainder, result;
- UINT8 src;
- if( modrm >= 0xc0 ) {
- src = LOAD_RM8(modrm);
- CYCLES(CYCLES_IDIV8_ACC_REG);
- } else {
- UINT32 ea = GetEA(modrm,0);
- src = READ8(ea);
- CYCLES(CYCLES_IDIV8_ACC_MEM);
- }
-
- quotient = (INT16)REG16(AX);
- if( src ) {
- remainder = quotient % (INT16)(INT8)src;
- result = quotient / (INT16)(INT8)src;
- if( result > 0xff ) {
- /* TODO: Divide error */
- } else {
- REG8(AH) = (UINT8)remainder & 0xff;
- REG8(AL) = (UINT8)result & 0xff;
-
- // this flag is actually undefined, enable on non-cyrix
- if (cpustate->cpuid_id0 != 0x69727943)
- cpustate->CF = 1;
- }
- } else {
- i386_trap( 0, 0, 0);
- }
- }
- break;
- }
-}
-
-void I386_OPS_BASE::I386OP(groupFE_8)() // Opcode 0xfe
-{
- UINT8 modrm = FETCH();
-
- switch( (modrm >> 3) & 0x7 )
- {
- case 0: /* INC Rm8 */
- if( modrm >= 0xc0 ) {
- UINT8 dst = LOAD_RM8(modrm);
- dst = INC8(dst);
- STORE_RM8(modrm, dst);
- CYCLES(CYCLES_INC_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- UINT8 dst = READ8(ea);
- dst = INC8(dst);
- WRITE8(ea, dst);
- CYCLES(CYCLES_INC_MEM);
- }
- break;
- case 1: /* DEC Rm8 */
- if( modrm >= 0xc0 ) {
- UINT8 dst = LOAD_RM8(modrm);
- dst = DEC8(dst);
- STORE_RM8(modrm, dst);
- CYCLES(CYCLES_DEC_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- UINT8 dst = READ8(ea);
- dst = DEC8(dst);
- WRITE8(ea, dst);
- CYCLES(CYCLES_DEC_MEM);
- }
- break;
- case 6: /* PUSH Rm8*/
- {
- UINT8 value;
- if( modrm >= 0xc0 ) {
- value = LOAD_RM8(modrm);
- } else {
- UINT32 ea = GetEA(modrm,0);
- value = READ8(ea);
- }
- if( cpustate->operand_size ) {
- PUSH32(value);
- } else {
- PUSH16(value);
- }
- CYCLES(CYCLES_PUSH_RM);
- }
- break;
- default:
- report_invalid_modrm( "groupFE_8", modrm);
- break;
- }
-}
-
-
-
-void I386_OPS_BASE::I386OP(segment_CS)() // Opcode 0x2e
-{
- cpustate->segment_prefix = 1;
- cpustate->segment_override = CS;
-
- I386_OPS_BASE::I386OP(decode_opcode)();
-}
-
-void I386_OPS_BASE::I386OP(segment_DS)() // Opcode 0x3e
-{
- cpustate->segment_prefix = 1;
- cpustate->segment_override = DS;
- CYCLES(0); // TODO: Specify cycle count
- I386_OPS_BASE::I386OP(decode_opcode)();
-}
-
-void I386_OPS_BASE::I386OP(segment_ES)() // Opcode 0x26
-{
- cpustate->segment_prefix = 1;
- cpustate->segment_override = ES;
- CYCLES(0); // TODO: Specify cycle count
- I386_OPS_BASE::I386OP(decode_opcode)();
-}
-
-void I386_OPS_BASE::I386OP(segment_FS)() // Opcode 0x64
-{
- cpustate->segment_prefix = 1;
- cpustate->segment_override = FS;
- CYCLES(1); // TODO: Specify cycle count
- I386_OPS_BASE::I386OP(decode_opcode)();
-}
-
-void I386_OPS_BASE::I386OP(segment_GS)() // Opcode 0x65
-{
- cpustate->segment_prefix = 1;
- cpustate->segment_override = GS;
- CYCLES(1); // TODO: Specify cycle count
- I386_OPS_BASE::I386OP(decode_opcode)();
-}
-
-void I386_OPS_BASE::I386OP(segment_SS)() // Opcode 0x36
-{
- cpustate->segment_prefix = 1;
- cpustate->segment_override = SS;
- CYCLES(0); // TODO: Specify cycle count
- I386_OPS_BASE::I386OP(decode_opcode)();
-}
-
-void I386_OPS_BASE::I386OP(operand_size)() // Opcode prefix 0x66
-{
- if(cpustate->operand_prefix == 0)
- {
- cpustate->operand_size ^= 1;
- cpustate->xmm_operand_size ^= 1;
- cpustate->operand_prefix = 1;
- }
- cpustate->opcode = FETCH();
- if (cpustate->opcode == 0x0f)
- I386_OPS_BASE::I386OP(decode_three_byte66)();
- else
- {
- if( cpustate->operand_size )
- cpustate->opcode_table1_32[cpustate->opcode]();
- else
- cpustate->opcode_table1_16[cpustate->opcode]();
- }
-}
-
-void I386_OPS_BASE::I386OP(address_size)() // Opcode 0x67
-{
- if(cpustate->address_prefix == 0)
- {
- cpustate->address_size ^= 1;
- cpustate->address_prefix = 1;
- }
- I386_OPS_BASE::I386OP(decode_opcode)();
-}
-
-void I386_OPS_BASE::I386OP(nop)() // Opcode 0x90
-{
- CYCLES(CYCLES_NOP);
-}
-
-void I386_OPS_BASE::I386OP(int3)() // Opcode 0xcc
-{
- CYCLES(CYCLES_INT3);
- cpustate->ext = 0; // not an external interrupt
- i386_trap(3, 1, 0);
- cpustate->ext = 1;
-}
-
-void I386_OPS_BASE::I386_OPS_BASE::I386OP(int)() // Opcode 0xcd
-{
- int interrupt = FETCH();
- CYCLES(CYCLES_INT);
- // Without pseudo BIOS.
- cpustate->ext = 0; // not an external interrupt
- i386_trap(interrupt, 1, 0);
- cpustate->ext = 1;
-}
-
-void I386_OPS_BASE::I386OP(into)() // Opcode 0xce
-{
- if( cpustate->OF ) {
- cpustate->ext = 0;
- i386_trap(4, 1, 0);
- cpustate->ext = 1;
- CYCLES(CYCLES_INTO_OF1);
- }
- else
- {
- CYCLES(CYCLES_INTO_OF0);
- }
-}
-
-void I386_OPS_BASE::I386OP(escape)() // Opcodes 0xd8 - 0xdf
-{
- UINT8 modrm = FETCH();
- if(modrm < 0xc0)
- {
- i386_escape_ea = GetEA(modrm,0);
- }
- CYCLES(3); // TODO: confirm this
- (void) LOAD_RM8(modrm);
-}
-
-void I386_OPS_BASE::I386OP(hlt)() // Opcode 0xf4
-{
- if(PROTECTED_MODE && cpustate->CPL != 0)
- FAULT(FAULT_GP,0);
- cpustate->halted = 1;
- CYCLES(CYCLES_HLT);
- if (cpustate->cycles > 0)
- cpustate->cycles = 0;
-}
-
-void I386_OPS_BASE::I386OP(decimal_adjust)(int direction)
-{
- UINT8 tmpAL = REG8(AL);
- UINT8 tmpCF = cpustate->CF;
-
- if (cpustate->AF || ((REG8(AL) & 0xf) > 9))
- {
- UINT16 t= (UINT16)REG8(AL) + (direction * 0x06);
- REG8(AL) = (UINT8)t&0xff;
- cpustate->AF = 1;
- if (t & 0x100)
- cpustate->CF = 1;
- if (direction > 0)
- tmpAL = REG8(AL);
- }
-
- if (tmpCF || (tmpAL > 0x99))
- {
- REG8(AL) += (direction * 0x60);
- cpustate->CF = 1;
- }
-
- SetSZPF8(REG8(AL));
-}
-
-void I386_OPS_BASE::I386OP(daa)() // Opcode 0x27
-{
- I386_OPS_BASE::I386OP(decimal_adjust)( +1);
- CYCLES(CYCLES_DAA);
-}
-
-void I386_OPS_BASE::I386OP(das)() // Opcode 0x2f
-{
- I386_OPS_BASE::I386OP(decimal_adjust)( -1);
- CYCLES(CYCLES_DAS);
-}
-
-void I386_OPS_BASE::I386OP(aaa)() // Opcode 0x37
-{
- if( ( (REG8(AL) & 0x0f) > 9) || (cpustate->AF != 0) ) {
- REG16(AX) = REG16(AX) + 6;
- REG8(AH) = REG8(AH) + 1;
- cpustate->AF = 1;
- cpustate->CF = 1;
- } else {
- cpustate->AF = 0;
- cpustate->CF = 0;
- }
- REG8(AL) = REG8(AL) & 0x0f;
- CYCLES(CYCLES_AAA);
-}
-
-void I386_OPS_BASE::I386OP(aas)() // Opcode 0x3f
-{
- if (cpustate->AF || ((REG8(AL) & 0xf) > 9))
- {
- REG16(AX) -= 6;
- REG8(AH) -= 1;
- cpustate->AF = 1;
- cpustate->CF = 1;
- }
- else
- {
- cpustate->AF = 0;
- cpustate->CF = 0;
- }
- REG8(AL) &= 0x0f;
- CYCLES(CYCLES_AAS);
-}
-
-void I386_OPS_BASE::I386OP(aad)() // Opcode 0xd5
-{
- UINT8 tempAL = REG8(AL);
- UINT8 tempAH = REG8(AH);
- UINT8 i = FETCH();
-
- REG8(AL) = (tempAL + (tempAH * i)) & 0xff;
- REG8(AH) = 0;
- SetSZPF8( REG8(AL) );
- CYCLES(CYCLES_AAD);
-}
-
-void I386_OPS_BASE::I386OP(aam)() // Opcode 0xd4
-{
- UINT8 tempAL = REG8(AL);
- UINT8 i = FETCH();
-
- if(!i)
- {
- i386_trap( 0, 0, 0);
- return;
- }
- REG8(AH) = tempAL / i;
- REG8(AL) = tempAL % i;
- SetSZPF8( REG8(AL) );
- CYCLES(CYCLES_AAM);
-}
-
-void I386_OPS_BASE::I386OP(clts)() // Opcode 0x0f 0x06
-{
- // Privileged instruction, CPL must be zero. Can be used in real or v86 mode.
- if(PROTECTED_MODE && cpustate->CPL != 0)
- FAULT(FAULT_GP,0)
- cpustate->cr[0] &= ~0x08; /* clear TS bit */
- CYCLES(CYCLES_CLTS);
-}
-
-void I386_OPS_BASE::I386OP(wait)() // Opcode 0x9B
-{
- // TODO
-}
-
-void I386_OPS_BASE::I386OP(lock)() // Opcode 0xf0
-{
- // lock doesn't depend on iopl on 386
- cpustate->lock = true;
- CYCLES(CYCLES_LOCK); // TODO: Determine correct cycle count
- I386_OPS_BASE::I386OP(decode_opcode)();
-}
-
-void I386_OPS_BASE::I386OP(mov_r32_tr)() // Opcode 0x0f 24
-{
- FETCH();
- CYCLES(1); // TODO: correct cycle count
-}
-
-void I386_OPS_BASE::I386OP(mov_tr_r32)() // Opcode 0x0f 26
-{
- FETCH();
- CYCLES(1); // TODO: correct cycle count
-}
-
-void I386_OPS_BASE::I386OP(loadall)() // Opcode 0x0f 0x07 (0x0f 0x05 on 80286), undocumented
-{
- fatalerror("i386: LOADALL unimplemented at %08X\n", cpustate->pc - 1);
-}
-
-void I386_OPS_BASE::I386OP(invalid)()
-{
- report_invalid_opcode();
- i386_trap( 6, 0, 0);
-}
-
-void I386_OPS_BASE::I386OP(xlat)() // Opcode 0xd7
-{
- UINT32 ea;
- if( cpustate->segment_prefix ) {
- if(!cpustate->address_size)
- {
- ea = i386_translate( cpustate->segment_override, REG16(BX) + REG8(AL), 0 );
- }
- else
- {
- ea = i386_translate( cpustate->segment_override, REG32(EBX) + REG8(AL), 0 );
- }
- } else {
- if(!cpustate->address_size)
- {
- ea = i386_translate( DS, REG16(BX) + REG8(AL), 0 );
- }
- else
- {
- ea = i386_translate( DS, REG32(EBX) + REG8(AL), 0 );
- }
- }
- REG8(AL) = READ8(ea);
- CYCLES(CYCLES_XLAT);
-}
+++ /dev/null
-// license:BSD-3-Clause
-// copyright-holders:Ville Linde, Barry Rodewald, Carl, Phil Bennett
-#ifndef __LIB_I386_OPS_OPS_H__
-#define __LIB_I386_OPS_OPS_H__
-struct X86_OPCODE {
- UINT8 opcode;
- UINT32 flags;
- void (*I386_OPS_BASE::handler16)();
- void (*I386_OPS_BASE::handler32)();
- bool lockable;
-};
-
-#define OP_I386 0x1
-#define OP_FPU 0x2
-#define OP_I486 0x4
-#define OP_PENTIUM 0x8
-#define OP_MMX 0x10
-#define OP_PPRO 0x20
-#define OP_SSE 0x40
-#define OP_SSE2 0x80
-#define OP_SSE3 0x100
-#define OP_CYRIX 0x8000
-#define OP_2BYTE 0x80000000
-#define OP_3BYTE66 0x40000000
-#define OP_3BYTEF2 0x20000000
-#define OP_3BYTEF3 0x10000000
-#define OP_3BYTE38 0x08000000
-#define OP_3BYTE3A 0x04000000
-#define OP_4BYTE3866 0x02000000
-#define OP_4BYTE3A66 0x01000000
-#define OP_4BYTE38F2 0x00800000
-#define OP_4BYTE3AF2 0x00400000
-#define OP_4BYTE38F3 0x00200000
-
-#endif
+++ /dev/null
-// license:BSD-3-Clause
-// copyright-holders:Ville Linde, Barry Rodewald, Carl, Phil Bennett
-#pragma once
-
-#ifndef __LIB_I386_PRIV_H__
-#define __LIB_I386_PRIV_H__
-
-// Translation intentions
-const int TRANSLATE_TYPE_MASK = 0x03; // read write or fetch
-const int TRANSLATE_USER_MASK = 0x04; // user mode or fully privileged
-const int TRANSLATE_DEBUG_MASK = 0x08; // debug mode (no side effects)
-
-const int TRANSLATE_READ = 0; // translate for read
-const int TRANSLATE_WRITE = 1; // translate for write
-const int TRANSLATE_FETCH = 2; // translate for instruction fetch
-const int TRANSLATE_READ_USER = (TRANSLATE_READ | TRANSLATE_USER_MASK);
-const int TRANSLATE_WRITE_USER = (TRANSLATE_WRITE | TRANSLATE_USER_MASK);
-const int TRANSLATE_FETCH_USER = (TRANSLATE_FETCH | TRANSLATE_USER_MASK);
-const int TRANSLATE_READ_DEBUG = (TRANSLATE_READ | TRANSLATE_DEBUG_MASK);
-const int TRANSLATE_WRITE_DEBUG = (TRANSLATE_WRITE | TRANSLATE_DEBUG_MASK);
-const int TRANSLATE_FETCH_DEBUG = (TRANSLATE_FETCH | TRANSLATE_DEBUG_MASK);
-
-/*****************************************************************************/
-/* src/emu/emucore.h */
-
-// constants for expression endianness
-enum endianness_t
-{
- ENDIANNESS_LITTLE,
- ENDIANNESS_BIG
-};
-
-// declare native endianness to be one or the other
-#ifdef LSB_FIRST
-const endianness_t ENDIANNESS_NATIVE = ENDIANNESS_LITTLE;
-#else
-const endianness_t ENDIANNESS_NATIVE = ENDIANNESS_BIG;
-#endif
-// endian-based value: first value is if 'endian' is little-endian, second is if 'endian' is big-endian
-#define ENDIAN_VALUE_LE_BE(endian,leval,beval) (((endian) == ENDIANNESS_LITTLE) ? (leval) : (beval))
-// endian-based value: first value is if native endianness is little-endian, second is if native is big-endian
-#define NATIVE_ENDIAN_VALUE_LE_BE(leval,beval) ENDIAN_VALUE_LE_BE(ENDIANNESS_NATIVE, leval, beval)
-// endian-based value: first value is if 'endian' matches native, second is if 'endian' doesn't match native
-#define ENDIAN_VALUE_NE_NNE(endian,leval,beval) (((endian) == ENDIANNESS_NATIVE) ? (neval) : (nneval))
-
-/*****************************************************************************/
-/* src/emu/memory.h */
-
-// address spaces
-enum address_spacenum
-{
- AS_0, // first address space
- AS_1, // second address space
- AS_2, // third address space
- AS_3, // fourth address space
- ADDRESS_SPACES, // maximum number of address spaces
-
- // alternate address space names for common use
- AS_PROGRAM = AS_0, // program address space
- AS_DATA = AS_1, // data address space
- AS_IO = AS_2 // I/O address space
-};
-
-// offsets and addresses are 32-bit (for now...)
-typedef UINT32 offs_t;
-
-/*****************************************************************************/
-/* src/osd/osdcomm.h */
-
-/* Highly useful macro for compile-time knowledge of an array size */
-#define ARRAY_LENGTH(x) (sizeof(x) / sizeof(x[0]))
-
-#include <math.h>
-
-//#define DEBUG_MISSING_OPCODE
-
-#define I386OP(XX) i386_##XX
-#define I486OP(XX) i486_##XX
-#define PENTIUMOP(XX) pentium_##XX
-#define MMXOP(XX) mmx_##XX
-#define SSEOP(XX) sse_##XX
-
-//extern int i386_dasm_one(_TCHAR *buffer, UINT32 pc, const UINT8 *oprom, int mode);
-
-enum SREGS { ES, CS, SS, DS, FS, GS };
-
-enum BREGS
-{
- AL = NATIVE_ENDIAN_VALUE_LE_BE(0,3),
- AH = NATIVE_ENDIAN_VALUE_LE_BE(1,2),
- CL = NATIVE_ENDIAN_VALUE_LE_BE(4,7),
- CH = NATIVE_ENDIAN_VALUE_LE_BE(5,6),
- DL = NATIVE_ENDIAN_VALUE_LE_BE(8,11),
- DH = NATIVE_ENDIAN_VALUE_LE_BE(9,10),
- BL = NATIVE_ENDIAN_VALUE_LE_BE(12,15),
- BH = NATIVE_ENDIAN_VALUE_LE_BE(13,14)
-};
-
-enum WREGS
-{
- AX = NATIVE_ENDIAN_VALUE_LE_BE(0,1),
- CX = NATIVE_ENDIAN_VALUE_LE_BE(2,3),
- DX = NATIVE_ENDIAN_VALUE_LE_BE(4,5),
- BX = NATIVE_ENDIAN_VALUE_LE_BE(6,7),
- SP = NATIVE_ENDIAN_VALUE_LE_BE(8,9),
- BP = NATIVE_ENDIAN_VALUE_LE_BE(10,11),
- SI = NATIVE_ENDIAN_VALUE_LE_BE(12,13),
- DI = NATIVE_ENDIAN_VALUE_LE_BE(14,15)
-};
-
-enum DREGS { EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI };
-
-enum
-{
- I386_PC = 0,
-
- /* 8-bit registers */
- I386_AL,
- I386_AH,
- I386_BL,
- I386_BH,
- I386_CL,
- I386_CH,
- I386_DL,
- I386_DH,
-
- /* 16-bit registers */
- I386_AX,
- I386_BX,
- I386_CX,
- I386_DX,
- I386_BP,
- I386_SP,
- I386_SI,
- I386_DI,
- I386_IP,
-
- /* 32-bit registers */
- I386_EAX,
- I386_ECX,
- I386_EDX,
- I386_EBX,
- I386_EBP,
- I386_ESP,
- I386_ESI,
- I386_EDI,
- I386_EIP,
-
- /* segment registers */
- I386_CS,
- I386_CS_BASE,
- I386_CS_LIMIT,
- I386_CS_FLAGS,
- I386_SS,
- I386_SS_BASE,
- I386_SS_LIMIT,
- I386_SS_FLAGS,
- I386_DS,
- I386_DS_BASE,
- I386_DS_LIMIT,
- I386_DS_FLAGS,
- I386_ES,
- I386_ES_BASE,
- I386_ES_LIMIT,
- I386_ES_FLAGS,
- I386_FS,
- I386_FS_BASE,
- I386_FS_LIMIT,
- I386_FS_FLAGS,
- I386_GS,
- I386_GS_BASE,
- I386_GS_LIMIT,
- I386_GS_FLAGS,
-
- /* other */
- I386_EFLAGS,
-
- I386_CR0,
- I386_CR1,
- I386_CR2,
- I386_CR3,
- I386_CR4,
-
- I386_DR0,
- I386_DR1,
- I386_DR2,
- I386_DR3,
- I386_DR4,
- I386_DR5,
- I386_DR6,
- I386_DR7,
-
- I386_TR6,
- I386_TR7,
-
- I386_GDTR_BASE,
- I386_GDTR_LIMIT,
- I386_IDTR_BASE,
- I386_IDTR_LIMIT,
- I386_TR,
- I386_TR_BASE,
- I386_TR_LIMIT,
- I386_TR_FLAGS,
- I386_LDTR,
- I386_LDTR_BASE,
- I386_LDTR_LIMIT,
- I386_LDTR_FLAGS,
-
- I386_CPL,
-
- X87_CTRL,
- X87_STATUS,
- X87_TAG,
- X87_ST0,
- X87_ST1,
- X87_ST2,
- X87_ST3,
- X87_ST4,
- X87_ST5,
- X87_ST6,
- X87_ST7,
-
- SSE_XMM0,
- SSE_XMM1,
- SSE_XMM2,
- SSE_XMM3,
- SSE_XMM4,
- SSE_XMM5,
- SSE_XMM6,
- SSE_XMM7
-};
-
-enum
-{
- /* mmx registers aliased to x87 ones */
- MMX_MM0=X87_ST0,
- MMX_MM1=X87_ST1,
- MMX_MM2=X87_ST2,
- MMX_MM3=X87_ST3,
- MMX_MM4=X87_ST4,
- MMX_MM5=X87_ST5,
- MMX_MM6=X87_ST6,
- MMX_MM7=X87_ST7
-};
-
-enum smram
-{
- SMRAM_SMBASE = 0xF8,
- SMRAM_SMREV = 0xFC,
- SMRAM_IORSRT = 0x100,
- SMRAM_AHALT = 0x102,
- SMRAM_IOEDI = 0x104,
- SMRAM_IOECX = 0x108,
- SMRAM_IOESI = 0x10C,
-
- SMRAM_ES = 0x1A8,
- SMRAM_CS = 0x1AC,
- SMRAM_SS = 0x1B0,
- SMRAM_DS = 0x1B4,
- SMRAM_FS = 0x1B8,
- SMRAM_GS = 0x1BC,
- SMRAM_LDTR = 0x1C0,
- SMRAM_TR = 0x1C4,
- SMRAM_DR7 = 0x1C8,
- SMRAM_DR6 = 0x1CC,
- SMRAM_EAX = 0x1D0,
- SMRAM_ECX = 0x1D4,
- SMRAM_EDX = 0x1D8,
- SMRAM_EBX = 0x1DC,
- SMRAM_ESP = 0x1E0,
- SMRAM_EBP = 0x1E4,
- SMRAM_ESI = 0x1E8,
- SMRAM_EDI = 0x1EC,
- SMRAM_EIP = 0x1F0,
- SMRAM_EFLAGS = 0x1F4,
- SMRAM_CR3 = 0x1F8,
- SMRAM_CR0 = 0x1FC,
-};
-
-enum smram_intel_p5
-{
- SMRAM_IP5_IOEIP = 0x110,
- SMRAM_IP5_CR4 = 0x128,
- SMRAM_IP5_ESLIM = 0x130,
- SMRAM_IP5_ESBASE = 0x134,
- SMRAM_IP5_ESACC = 0x138,
- SMRAM_IP5_CSLIM = 0x13C,
- SMRAM_IP5_CSBASE = 0x140,
- SMRAM_IP5_CSACC = 0x144,
- SMRAM_IP5_SSLIM = 0x148,
- SMRAM_IP5_SSBASE = 0x14C,
- SMRAM_IP5_SSACC = 0x150,
- SMRAM_IP5_DSLIM = 0x154,
- SMRAM_IP5_DSBASE = 0x158,
- SMRAM_IP5_DSACC = 0x15C,
- SMRAM_IP5_FSLIM = 0x160,
- SMRAM_IP5_FSBASE = 0x164,
- SMRAM_IP5_FSACC = 0x168,
- SMRAM_IP5_GSLIM = 0x16C,
- SMRAM_IP5_GSBASE = 0x170,
- SMRAM_IP5_GSACC = 0x174,
- SMRAM_IP5_LDTLIM = 0x178,
- SMRAM_IP5_LDTBASE = 0x17C,
- SMRAM_IP5_LDTACC = 0x180,
- SMRAM_IP5_GDTLIM = 0x184,
- SMRAM_IP5_GDTBASE = 0x188,
- SMRAM_IP5_GDTACC = 0x18C,
- SMRAM_IP5_IDTLIM = 0x190,
- SMRAM_IP5_IDTBASE = 0x194,
- SMRAM_IP5_IDTACC = 0x198,
- SMRAM_IP5_TRLIM = 0x19C,
- SMRAM_IP5_TRBASE = 0x1A0,
- SMRAM_IP5_TRACC = 0x1A4,
-};
-
-/* Protected mode exceptions */
-#define FAULT_UD 6 // Invalid Opcode
-#define FAULT_NM 7 // Coprocessor not available
-#define FAULT_DF 8 // Double Fault
-#define FAULT_TS 10 // Invalid TSS
-#define FAULT_NP 11 // Segment or Gate not present
-#define FAULT_SS 12 // Stack fault
-#define FAULT_GP 13 // General Protection Fault
-#define FAULT_PF 14 // Page Fault
-#define FAULT_MF 16 // Match (Coprocessor) Fault
-
-/* MXCSR Control and Status Register */
-#define MXCSR_IE (1<<0) // Invalid Operation Flag
-#define MXCSR_DE (1<<1) // Denormal Flag
-#define MXCSR_ZE (1<<2) // Divide-by-Zero Flag
-#define MXCSR_OE (1<<3) // Overflow Flag
-#define MXCSR_UE (1<<4) // Underflow Flag
-#define MXCSR_PE (1<<5) // Precision Flag
-#define MXCSR_DAZ (1<<6) // Denormals Are Zeros
-#define MXCSR_IM (1<<7) // Invalid Operation Mask
-#define MXCSR_DM (1<<8) // Denormal Operation Mask
-#define MXCSR_ZM (1<<9) // Divide-by-Zero Mask
-#define MXCSR_OM (1<<10) // Overflow Mask
-#define MXCSR_UM (1<<11) // Underflow Mask
-#define MXCSR_PM (1<<12) // Precision Mask
-#define MXCSR_RC (3<<13) // Rounding Control
-#define MXCSR_FZ (1<<15) // Flush to Zero
-
-struct I386_SREG {
- UINT16 selector;
- UINT16 flags;
- UINT32 base;
- UINT32 limit;
- int d; // Operand size
- bool valid;
-};
-
-struct I386_CALL_GATE
-{
- UINT16 segment;
- UINT16 selector;
- UINT32 offset;
- UINT8 ar; // access rights
- UINT8 dpl;
- UINT8 dword_count;
- UINT8 present;
-};
-
-struct I386_SYS_TABLE {
- UINT32 base;
- UINT16 limit;
-};
-
-struct I386_SEG_DESC {
- UINT16 segment;
- UINT16 flags;
- UINT32 base;
- UINT32 limit;
-};
-
-union I386_GPR {
- UINT32 d[8];
- UINT16 w[16];
- UINT8 b[32];
-};
-
-union MMX_REG {
- UINT32 d[2];
- INT32 i[2];
- UINT16 w[4];
- INT16 s[4];
- UINT8 b[8];
- INT8 c[8];
- float f[2];
- UINT64 q;
- INT64 l;
-};
-
-union XMM_REG {
- UINT8 b[16];
- UINT16 w[8];
- UINT32 d[4];
- UINT64 q[2];
- INT8 c[16];
- INT16 s[8];
- INT32 i[4];
- INT64 l[2];
- float f[4];
- double f64[2];
-};
-
-class EMU;
-class DEBUGGER;
-class DEVICE;
-class I386_OPS_BASE;
-struct i386_state
-{
- I386_GPR reg;
- I386_SREG sreg[6];
- UINT32 eip;
- UINT32 pc;
- UINT32 prev_eip;
- UINT32 prev_pc;
- UINT32 eflags;
- UINT32 eflags_mask;
- UINT8 CF;
- UINT8 DF;
- UINT8 SF;
- UINT8 OF;
- UINT8 ZF;
- UINT8 PF;
- UINT8 AF;
- UINT8 IF;
- UINT8 TF;
- UINT8 IOP1;
- UINT8 IOP2;
- UINT8 NT;
- UINT8 RF;
- UINT8 VM;
- UINT8 AC;
- UINT8 VIF;
- UINT8 VIP;
- UINT8 ID;
-
- UINT8 CPL; // current privilege level
-
- UINT8 performed_intersegment_jump;
- UINT8 delayed_interrupt_enable;
-
- UINT32 cr[5]; // Control registers
- UINT32 dr[8]; // Debug registers
- UINT32 tr[8]; // Test registers
-
- I386_SYS_TABLE gdtr; // Global Descriptor Table Register
- I386_SYS_TABLE idtr; // Interrupt Descriptor Table Register
- I386_SEG_DESC task; // Task register
- I386_SEG_DESC ldtr; // Local Descriptor Table Register
-
- UINT8 ext; // external interrupt
-
- int halted;
- int busreq;
- int shutdown;
-
- int operand_size;
- int xmm_operand_size;
- int address_size;
- int operand_prefix;
- int address_prefix;
-
- int segment_prefix;
- int segment_override;
-
- int cycles;
- int extra_cycles;
- int base_cycles;
- UINT8 opcode;
-
- UINT8 irq_state;
- DEVICE *pic;
- DEVICE *program;
- DEVICE *io;
-//#ifdef I386_PSEUDO_BIOS
- DEVICE *bios;
-//#endif
-//#ifdef SINGLE_MODE_DMA
- DEVICE *dma;
-//#endif
-//#ifdef USE_DEBUGGER
- EMU *emu;
- DEBUGGER *debugger;
- DEVICE *program_stored;
- DEVICE *io_stored;
-//#endif
- UINT32 a20_mask;
-
- int cpuid_max_input_value_eax;
- UINT32 cpuid_id0, cpuid_id1, cpuid_id2;
- UINT32 cpu_version;
- UINT32 feature_flags;
- UINT64 tsc;
- UINT64 perfctr[2];
-
- // FPU
- floatx80 x87_reg[8];
-
- UINT16 x87_cw;
- UINT16 x87_sw;
- UINT16 x87_tw;
- UINT64 x87_data_ptr;
- UINT64 x87_inst_ptr;
- UINT16 x87_opcode;
-
- void (I386_OPS_BASE::*opcode_table_x87_d8[256])(UINT8 modrm);
- void (I386_OPS_BASE::*opcode_table_x87_d9[256])(UINT8 modrm);
- void (I386_OPS_BASE::*opcode_table_x87_da[256])(UINT8 modrm);
- void (I386_OPS_BASE::*opcode_table_x87_db[256])(UINT8 modrm);
- void (I386_OPS_BASE::*opcode_table_x87_dc[256])(UINT8 modrm);
- void (I386_OPS_BASE::*opcode_table_x87_dd[256])(UINT8 modrm);
- void (I386_OPS_BASE::*opcode_table_x87_de[256])(UINT8 modrm);
- void (I386_OPS_BASE::*opcode_table_x87_df[256])(UINT8 modrm);
-
- // SSE
- XMM_REG sse_reg[8];
- UINT32 mxcsr;
-
- void (I386_OPS_BASE::*opcode_table1_16[256])();
- void (I386_OPS_BASE::*opcode_table1_32[256])();
- void (I386_OPS_BASE::*opcode_table2_16[256])();
- void (I386_OPS_BASE::*opcode_table2_32[256])();
- void (I386_OPS_BASE::*opcode_table338_16[256])();
- void (I386_OPS_BASE::*opcode_table338_32[256])();
- void (I386_OPS_BASE::*opcode_table33a_16[256])();
- void (I386_OPS_BASE::*opcode_table33a_32[256])();
- void (I386_OPS_BASE::*opcode_table366_16[256])();
- void (I386_OPS_BASE::*opcode_table366_32[256])();
- void (I386_OPS_BASE::*opcode_table3f2_16[256])();
- void (I386_OPS_BASE::*opcode_table3f2_32[256])();
- void (I386_OPS_BASE::*opcode_table3f3_16[256])();
- void (I386_OPS_BASE::*opcode_table3f3_32[256])();
- void (I386_OPS_BASE::*opcode_table46638_16[256])();
- void (I386_OPS_BASE::*opcode_table46638_32[256])();
- void (I386_OPS_BASE::*opcode_table4f238_16[256])();
- void (I386_OPS_BASE::*opcode_table4f238_32[256])();
- void (I386_OPS_BASE::*opcode_table4f338_16[256])();
- void (I386_OPS_BASE::*opcode_table4f338_32[256])();
- void (I386_OPS_BASE::*opcode_table4663a_16[256])();
- void (I386_OPS_BASE::*opcode_table4663a_32[256])();
- void (I386_OPS_BASE::*opcode_table4f23a_16[256])();
- void (I386_OPS_BASE::*opcode_table4f23a_32[256])();
-
- bool lock_table[2][256];
-
- UINT8 *cycle_table_pm;
- UINT8 *cycle_table_rm;
-
- vtlb_state *vtlb;
-
- bool smm;
- bool smi;
- bool smi_latched;
- bool nmi_masked;
- bool nmi_latched;
- UINT32 smbase;
-// devcb_resolved_write_line smiact;
- bool lock;
-
- // bytes in current opcode, debug only
-#ifdef DEBUG_MISSING_OPCODE
- UINT8 opcode_bytes[16];
- UINT32 opcode_pc;
- int opcode_bytes_length;
-#endif
-};
-
-
-#define FAULT_THROW(fault,error) { throw (UINT64)(fault | (UINT64)error << 32); }
-#define PF_THROW(error) { cpustate->cr[2] = address; FAULT_THROW(FAULT_PF,error); }
-
-#define PROTECTED_MODE (cpustate->cr[0] & 0x1)
-#define STACK_32BIT (cpustate->sreg[SS].d)
-#define V8086_MODE (cpustate->VM)
-#define NESTED_TASK (cpustate->NT)
-#define WP (cpustate->cr[0] & 0x10000)
-
-#define SetOF_Add32(r,s,d) (cpustate->OF = (((r) ^ (s)) & ((r) ^ (d)) & 0x80000000) ? 1: 0)
-#define SetOF_Add16(r,s,d) (cpustate->OF = (((r) ^ (s)) & ((r) ^ (d)) & 0x8000) ? 1 : 0)
-#define SetOF_Add8(r,s,d) (cpustate->OF = (((r) ^ (s)) & ((r) ^ (d)) & 0x80) ? 1 : 0)
-
-#define SetOF_Sub32(r,s,d) (cpustate->OF = (((d) ^ (s)) & ((d) ^ (r)) & 0x80000000) ? 1 : 0)
-#define SetOF_Sub16(r,s,d) (cpustate->OF = (((d) ^ (s)) & ((d) ^ (r)) & 0x8000) ? 1 : 0)
-#define SetOF_Sub8(r,s,d) (cpustate->OF = (((d) ^ (s)) & ((d) ^ (r)) & 0x80) ? 1 : 0)
-
-#define SetCF8(x) {cpustate->CF = ((x) & 0x100) ? 1 : 0; }
-#define SetCF16(x) {cpustate->CF = ((x) & 0x10000) ? 1 : 0; }
-#define SetCF32(x) {cpustate->CF = ((x) & (((UINT64)1) << 32)) ? 1 : 0; }
-
-#define SetSF(x) (cpustate->SF = (x))
-#define SetZF(x) (cpustate->ZF = (x))
-#define SetAF(x,y,z) (cpustate->AF = (((x) ^ ((y) ^ (z))) & 0x10) ? 1 : 0)
-#define SetPF(x) (cpustate->PF = i386_parity_table[(x) & 0xFF])
-
-#define SetSZPF8(x) {cpustate->ZF = ((UINT8)(x)==0); cpustate->SF = ((x)&0x80) ? 1 : 0; cpustate->PF = i386_parity_table[x & 0xFF]; }
-#define SetSZPF16(x) {cpustate->ZF = ((UINT16)(x)==0); cpustate->SF = ((x)&0x8000) ? 1 : 0; cpustate->PF = i386_parity_table[x & 0xFF]; }
-#define SetSZPF32(x) {cpustate->ZF = ((UINT32)(x)==0); cpustate->SF = ((x)&0x80000000) ? 1 : 0; cpustate->PF = i386_parity_table[x & 0xFF]; }
-
-#define MMX(n) (*((MMX_REG *)(&cpustate->x87_reg[(n)].low)))
-#define XMM(n) cpustate->sse_reg[(n)]
-
-/***********************************************************************************/
-
-struct MODRM_TABLE {
- struct {
- int b;
- int w;
- int d;
- } reg;
- struct {
- int b;
- int w;
- int d;
- } rm;
-};
-
-#define REG8(x) (cpustate->reg.b[x])
-#define REG16(x) (cpustate->reg.w[x])
-#define REG32(x) (cpustate->reg.d[x])
-
-#define LOAD_REG8(x) (REG8(i386_MODRM_table[x].reg.b))
-#define LOAD_REG16(x) (REG16(i386_MODRM_table[x].reg.w))
-#define LOAD_REG32(x) (REG32(i386_MODRM_table[x].reg.d))
-#define LOAD_RM8(x) (REG8(i386_MODRM_table[x].rm.b))
-#define LOAD_RM16(x) (REG16(i386_MODRM_table[x].rm.w))
-#define LOAD_RM32(x) (REG32(i386_MODRM_table[x].rm.d))
-
-#define STORE_REG8(x, value) (REG8(i386_MODRM_table[x].reg.b) = value)
-#define STORE_REG16(x, value) (REG16(i386_MODRM_table[x].reg.w) = value)
-#define STORE_REG32(x, value) (REG32(i386_MODRM_table[x].reg.d) = value)
-#define STORE_RM8(x, value) (REG8(i386_MODRM_table[x].rm.b) = value)
-#define STORE_RM16(x, value) (REG16(i386_MODRM_table[x].rm.w) = value)
-#define STORE_RM32(x, value) (REG32(i386_MODRM_table[x].rm.d) = value)
-
-#define SWITCH_ENDIAN_32(x) (((((x) << 24) & (0xff << 24)) | (((x) << 8) & (0xff << 16)) | (((x) >> 8) & (0xff << 8)) | (((x) >> 24) & (0xff << 0))))
-
-/***********************************************************************************/
-
-INLINE UINT32 I386_OPS_BASE::i386_translate(int segment, UINT32 ip, int rwn)
-{
- // TODO: segment limit access size, execution permission, handle exception thrown from exception handler
- if(PROTECTED_MODE && !V8086_MODE && (rwn != -1))
- {
- if(!(cpustate->sreg[segment].valid))
- FAULT_THROW((segment==SS)?FAULT_SS:FAULT_GP, 0);
- if(i386_limit_check(segment, ip))
- FAULT_THROW((segment==SS)?FAULT_SS:FAULT_GP, 0);
- if((rwn == 0) && ((cpustate->sreg[segment].flags & 8) && !(cpustate->sreg[segment].flags & 2)))
- FAULT_THROW(FAULT_GP, 0);
- if((rwn == 1) && ((cpustate->sreg[segment].flags & 8) || !(cpustate->sreg[segment].flags & 2)))
- FAULT_THROW(FAULT_GP, 0);
- }
- return cpustate->sreg[segment].base + ip;
-}
-
-#define VTLB_FLAG_DIRTY 0x100
-
-INLINE I386_OPS_BASE::vtlb_entry get_permissions(UINT32 pte, int wp)
-{
- vtlb_entry ret = VTLB_READ_ALLOWED | ((pte & 4) ? VTLB_USER_READ_ALLOWED : 0);
- if(!wp)
- ret |= VTLB_WRITE_ALLOWED;
- if(pte & 2)
- ret |= VTLB_WRITE_ALLOWED | ((pte & 4) ? VTLB_USER_WRITE_ALLOWED : 0);
- return ret;
-}
-
-//#define TEST_TLB
-
-INLINE int I386_OPS_BASE::translate_address(int pl, int type, UINT32 *address, UINT32 *error)
-{
- if(!(cpustate->cr[0] & 0x80000000)) // Some (very few) old OS's won't work with this
- return TRUE;
-
- const vtlb_entry *table = vtlb_table(cpustate->vtlb);
- UINT32 index = *address >> 12;
- vtlb_entry entry = table[index];
- if(type == TRANSLATE_FETCH)
- type = TRANSLATE_READ;
- if(pl == 3)
- type |= TRANSLATE_USER_MASK;
-#ifdef TEST_TLB
- UINT32 test_addr = *address;
-#endif
-
- if(!(entry & VTLB_FLAG_VALID) || ((type & TRANSLATE_WRITE) && !(entry & VTLB_FLAG_DIRTY)))
- {
- if(!i386_translate_address( type, address, &entry))
- {
- *error = ((type & TRANSLATE_WRITE) ? 2 : 0) | ((cpustate->CPL == 3) ? 4 : 0);
- if(entry)
- *error |= 1;
- return FALSE;
- }
- vtlb_dynload(cpustate->vtlb, index, *address, entry);
- return TRUE;
- }
- if(!(entry & (1 << type)))
- {
- *error = ((type & TRANSLATE_WRITE) ? 2 : 0) | ((cpustate->CPL == 3) ? 4 : 0) | 1;
- return FALSE;
- }
- *address = (entry & 0xfffff000) | (*address & 0xfff);
-#ifdef TEST_TLB
- int test_ret = i386_translate_address( type | TRANSLATE_DEBUG_MASK, &test_addr, NULL);
- if(!test_ret || (test_addr != *address))
- logerror("TLB-PTE mismatch! %06X %06X %06x\n", *address, test_addr, cpustate->pc);
-#endif
- return TRUE;
-}
-
-INLINE void I386_OPS_BASE::CHANGE_PC(UINT32 pc)
-{
- cpustate->pc = i386_translate( CS, pc, -1 );
-}
-
-INLINE void I386_OPS_BASE::NEAR_BRANCH(INT32 offs)
-{
- /* TODO: limit */
- cpustate->eip += offs;
- cpustate->pc += offs;
-}
-
-INLINE UINT8 I386_OPS_BASE::FETCH()
-{
- UINT8 value;
- UINT32 address = cpustate->pc, error;
-
- if(!translate_address(cpustate->CPL,TRANSLATE_FETCH,&address,&error))
- PF_THROW(error);
-
- value = cpustate->program->read_data8(address & cpustate->a20_mask);
-#ifdef DEBUG_MISSING_OPCODE
- cpustate->opcode_bytes[cpustate->opcode_bytes_length] = value;
- cpustate->opcode_bytes_length = (cpustate->opcode_bytes_length + 1) & 15;
-#endif
- cpustate->eip++;
- cpustate->pc++;
- return value;
-}
-
-INLINE UINT16 I386_OPS_BASE::FETCH16()
-{
- UINT16 value;
- UINT32 address = cpustate->pc, error;
-
- if( address & 0x1 ) { /* Unaligned read */
- value = (FETCH(cpustate) << 0);
- value |= (FETCH(cpustate) << 8);
- } else {
- if(!translate_address(cpustate->CPL,TRANSLATE_FETCH,&address,&error))
- PF_THROW(error);
- address &= cpustate->a20_mask;
- value = cpustate->program->read_data16(address);
- cpustate->eip += 2;
- cpustate->pc += 2;
- }
- return value;
-}
-INLINE UINT32 I386_OPS_BASE::FETCH32()
-{
- UINT32 value;
- UINT32 address = cpustate->pc, error;
-
- if( cpustate->pc & 0x3 ) { /* Unaligned read */
- value = (FETCH(cpustate) << 0);
- value |= (FETCH(cpustate) << 8);
- value |= (FETCH(cpustate) << 16);
- value |= (FETCH(cpustate) << 24);
- } else {
- if(!translate_address(cpustate->CPL,TRANSLATE_FETCH,&address,&error))
- PF_THROW(error);
-
- address &= cpustate->a20_mask;
- value = cpustate->program->read_data32(address);
- cpustate->eip += 4;
- cpustate->pc += 4;
- }
- return value;
-}
-
-INLINE UINT8 I386_OPS_BASE::READ8(UINT32 ea)
-{
- UINT32 address = ea, error;
-
- if(!translate_address(cpustate->CPL,TRANSLATE_READ,&address, &error))
- PF_THROW(error);
-
- address &= cpustate->a20_mask;
- return cpustate->program->read_data8(address);
-}
-
-INLINE UINT16 I386_OPS_BASE::READ16(UINT32 ea)
-{
- UINT16 value;
- UINT32 address = ea, error;
-
- if( ea & 0x1 ) { /* Unaligned read */
- value = (READ8( cpustate, address+0 ) << 0);
- value |= (READ8( cpustate, address+1 ) << 8);
- } else {
- if(!translate_address(cpustate->CPL,TRANSLATE_READ,&address,&error))
- PF_THROW(error);
-
- address &= cpustate->a20_mask;
- value = cpustate->program->read_data16( address );
- }
- return value;
-}
-INLINE UINT32 I386_OPS_BASE::READ32(UINT32 ea)
-{
- UINT32 value;
- UINT32 address = ea, error;
-
- if( ea & 0x3 ) { /* Unaligned read */
- value = (READ8( cpustate, address+0 ) << 0);
- value |= (READ8( cpustate, address+1 ) << 8);
- value |= (READ8( cpustate, address+2 ) << 16),
- value |= (READ8( cpustate, address+3 ) << 24);
- } else {
- if(!translate_address(cpustate->CPL,TRANSLATE_READ,&address,&error))
- PF_THROW(error);
-
- address &= cpustate->a20_mask;
- value = cpustate->program->read_data32( address );
- }
- return value;
-}
-
-INLINE UINT64 I386_OPS_BASE::READ64(UINT32 ea)
-{
- UINT64 value;
- UINT32 address = ea, error;
-
- if( ea & 0x7 ) { /* Unaligned read */
- value = (((UINT64) READ8( cpustate, address+0 )) << 0);
- value |= (((UINT64) READ8( cpustate, address+1 )) << 8);
- value |= (((UINT64) READ8( cpustate, address+2 )) << 16);
- value |= (((UINT64) READ8( cpustate, address+3 )) << 24);
- value |= (((UINT64) READ8( cpustate, address+4 )) << 32);
- value |= (((UINT64) READ8( cpustate, address+5 )) << 40);
- value |= (((UINT64) READ8( cpustate, address+6 )) << 48);
- value |= (((UINT64) READ8( cpustate, address+7 )) << 56);
- } else {
- if(!translate_address(cpustate->CPL,TRANSLATE_READ,&address,&error))
- PF_THROW(error);
-
- address &= cpustate->a20_mask;
- value = (((UINT64) cpustate->program->read_data32( address+0 )) << 0);
- value |= (((UINT64) cpustate->program->read_data32( address+4 )) << 32);
- }
- return value;
-}
-
-INLINE UINT8 I386_OPS_BASE::READ8PL0(UINT32 ea)
-{
- UINT32 address = ea, error;
-
- if(!translate_address(0,TRANSLATE_READ,&address,&error))
- PF_THROW(error);
-
- address &= cpustate->a20_mask;
- return cpustate->program->read_data8(address);
-}
-
-INLINE UINT16 I386_OPS_BASE::READ16PL0(UINT32 ea)
-{
- UINT16 value;
- UINT32 address = ea, error;
-
- if( ea & 0x1 ) { /* Unaligned read */
- value = (READ8PL0( cpustate, address+0 ) << 0);
- value |= (READ8PL0( cpustate, address+1 ) << 8);
- } else {
- if(!translate_address(0,TRANSLATE_READ,&address,&error))
- PF_THROW(error);
-
- address &= cpustate->a20_mask;
- value = cpustate->program->read_data16( address );
- }
- return value;
-}
-
-INLINE UINT32 I386_OPS_BASE::READ32PL0(UINT32 ea)
-{
- UINT32 value;
- UINT32 address = ea, error;
-
- if( ea & 0x3 ) { /* Unaligned read */
- value = (READ8PL0( cpustate, address+0 ) << 0);
- value |= (READ8PL0( cpustate, address+1 ) << 8);
- value |= (READ8PL0( cpustate, address+2 ) << 16);
- value |= (READ8PL0( cpustate, address+3 ) << 24);
- } else {
- if(!translate_address(0,TRANSLATE_READ,&address,&error))
- PF_THROW(error);
-
- address &= cpustate->a20_mask;
- value = cpustate->program->read_data32( address );
- }
- return value;
-}
-
-INLINE void I386_OPS_BASE::WRITE_TEST(UINT32 ea)
-{
- UINT32 address = ea, error;
- if(!translate_address(cpustate->CPL,TRANSLATE_WRITE,&address,&error))
- PF_THROW(error);
-}
-
-INLINE void I386_OPS_BASE::WRITE8(UINT32 ea, UINT8 value)
-{
- UINT32 address = ea, error;
-
- if(!translate_address(cpustate->CPL,TRANSLATE_WRITE,&address,&error))
- PF_THROW(error);
-
- address &= cpustate->a20_mask;
- cpustate->program->write_data8(address, value);
-}
-INLINE void WRITE16(UINT32 ea, UINT16 value)
-{
- UINT32 address = ea, error;
-
- if( ea & 0x1 ) { /* Unaligned write */
- WRITE8( cpustate, address+0, value & 0xff );
- WRITE8( cpustate, address+1, (value >> 8) & 0xff );
- } else {
- if(!translate_address(cpustate->CPL,TRANSLATE_WRITE,&address,&error))
- PF_THROW(error);
-
- address &= cpustate->a20_mask;
- cpustate->program->write_data16(address, value);
- }
-}
-
-INLINE void I386_OPS_BASE::WRITE32(UINT32 ea, UINT32 value)
-{
- UINT32 address = ea, error;
-
- if( ea & 0x3 ) { /* Unaligned write */
- WRITE8( cpustate, address+0, value & 0xff );
- WRITE8( cpustate, address+1, (value >> 8) & 0xff );
- WRITE8( cpustate, address+2, (value >> 16) & 0xff );
- WRITE8( cpustate, address+3, (value >> 24) & 0xff );
- } else {
- if(!translate_address(cpustate->CPL,TRANSLATE_WRITE,&address,&error))
- PF_THROW(error);
-
- ea &= cpustate->a20_mask;
- cpustate->program->write_data32(address, value);
- }
-}
-
-INLINE void I386_OPS_BASE::WRITE64(UINT32 ea, UINT64 value)
-{
- UINT32 address = ea, error;
-
- if( ea & 0x7 ) { /* Unaligned write */
- WRITE8( cpustate, address+0, value & 0xff );
- WRITE8( cpustate, address+1, (value >> 8) & 0xff );
- WRITE8( cpustate, address+2, (value >> 16) & 0xff );
- WRITE8( cpustate, address+3, (value >> 24) & 0xff );
- WRITE8( cpustate, address+4, (value >> 32) & 0xff );
- WRITE8( cpustate, address+5, (value >> 40) & 0xff );
- WRITE8( cpustate, address+6, (value >> 48) & 0xff );
- WRITE8( cpustate, address+7, (value >> 56) & 0xff );
- } else {
- if(!translate_address(cpustate->CPL,TRANSLATE_WRITE,&address,&error))
- PF_THROW(error);
-
- ea &= cpustate->a20_mask;
- cpustate->program->write_data32(address+0, value & 0xffffffff);
- cpustate->program->write_data32(address+4, (value >> 32) & 0xffffffff);
- }
-}
-
-/***********************************************************************************/
-
-INLINE UINT8 I386_OPS_BASE::OR8(UINT8 dst, UINT8 src)
-{
- UINT8 res = dst | src;
- cpustate->CF = cpustate->OF = 0;
- SetSZPF8(res);
- return res;
-}
-
-INLINE UINT16 I386_OPS_BASE::OR16(UINT16 dst, UINT16 src)
-{
- UINT16 res = dst | src;
- cpustate->CF = cpustate->OF = 0;
- SetSZPF16(res);
- return res;
-}
-
-INLINE UINT32 I386_OPS_BASE::OR32(UINT32 dst, UINT32 src)
-{
- UINT32 res = dst | src;
- cpustate->CF = cpustate->OF = 0;
- SetSZPF32(res);
- return res;
-}
-
-INLINE UINT8 I386_OPS_BASE::AND8(UINT8 dst, UINT8 src)
-{
- UINT8 res = dst & src;
- cpustate->CF = cpustate->OF = 0;
- SetSZPF8(res);
- return res;
-}
-INLINE UINT16 I386_OPS_BASE::AND16(UINT16 dst, UINT16 src)
-{
- UINT16 res = dst & src;
- cpustate->CF = cpustate->OF = 0;
- SetSZPF16(res);
- return res;
-}
-INLINE UINT32 I386_OPS_BASE::AND32(UINT32 dst, UINT32 src)
-{
- UINT32 res = dst & src;
- cpustate->CF = cpustate->OF = 0;
- SetSZPF32(res);
- return res;
-}
-
-INLINE UINT8 I386_OPS_BASE::XOR8(UINT8 dst, UINT8 src)
-{
- UINT8 res = dst ^ src;
- cpustate->CF = cpustate->OF = 0;
- SetSZPF8(res);
- return res;
-}
-INLINE UINT16 I386_OPS_BASE::XOR16(UINT16 dst, UINT16 src)
-{
- UINT16 res = dst ^ src;
- cpustate->CF = cpustate->OF = 0;
- SetSZPF16(res);
- return res;
-}
-INLINE UINT32 I386_OPS_BASE::XOR32(UINT32 dst, UINT32 src)
-{
- UINT32 res = dst ^ src;
- cpustate->CF = cpustate->OF = 0;
- SetSZPF32(res);
- return res;
-}
-
-#define SUB8(cpu, dst, src) SBB8(cpu, dst, src, 0)
-INLINE UINT8 I386_OPS_BASE::SBB8(UINT8 dst, UINT8 src, UINT8 b)
-{
- UINT16 res = (UINT16)dst - (UINT16)src - (UINT8)b;
- SetCF8(res);
- SetOF_Sub8(res,src,dst);
- SetAF(res,src,dst);
- SetSZPF8(res);
- return (UINT8)res;
-}
-
-#define SUB16(cpu, dst, src) SBB16(cpu, dst, src, 0)
-INLINE UINT16 I386_OPS_BASE::SBB16(UINT16 dst, UINT16 src, UINT16 b)
-{
- UINT32 res = (UINT32)dst - (UINT32)src - (UINT32)b;
- SetCF16(res);
- SetOF_Sub16(res,src,dst);
- SetAF(res,src,dst);
- SetSZPF16(res);
- return (UINT16)res;
-}
-
-#define SUB32(cpu, dst, src) SBB32(cpu, dst, src, 0)
-INLINE UINT32 I386_OPS_BASE::SBB32(UINT32 dst, UINT32 src, UINT32 b)
-{
- UINT64 res = (UINT64)dst - (UINT64)src - (UINT64) b;
- SetCF32(res);
- SetOF_Sub32(res,src,dst);
- SetAF(res,src,dst);
- SetSZPF32(res);
- return (UINT32)res;
-}
-
-#define ADD8(cpu, dst, src) ADC8(cpu, dst, src, 0)
-INLINE UINT8 I386_OPS_BASE::ADC8(UINT8 dst, UINT8 src, UINT8 c)
-{
- UINT16 res = (UINT16)dst + (UINT16)src + (UINT16)c;
- SetCF8(res);
- SetOF_Add8(res,src,dst);
- SetAF(res,src,dst);
- SetSZPF8(res);
- return (UINT8)res;
-}
-
-#define ADD16(cpu, dst, src) ADC16(cpu, dst, src, 0)
-INLINE UINT16 I386_OPS_BASE::ADC16(UINT16 dst, UINT16 src, UINT8 c)
-{
- UINT32 res = (UINT32)dst + (UINT32)src + (UINT32)c;
- SetCF16(res);
- SetOF_Add16(res,src,dst);
- SetAF(res,src,dst);
- SetSZPF16(res);
- return (UINT16)res;
-}
-
-#define ADD32(cpu, dst, src) ADC32(cpu, dst, src, 0)
-INLINE UINT32 I386_OPS_BASE::ADC32(UINT32 dst, UINT32 src, UINT32 c)
-{
- UINT64 res = (UINT64)dst + (UINT64)src + (UINT64) c;
- SetCF32(res);
- SetOF_Add32(res,src,dst);
- SetAF(res,src,dst);
- SetSZPF32(res);
- return (UINT32)res;
-}
-
-INLINE UINT8 INC8(UINT8 dst)
-{
- UINT16 res = (UINT16)dst + 1;
- SetOF_Add8(res,1,dst);
- SetAF(res,1,dst);
- SetSZPF8(res);
- return (UINT8)res;
-}
-INLINE UINT16 I386_OPS_BASE::INC16(UINT16 dst)
-{
- UINT32 res = (UINT32)dst + 1;
- SetOF_Add16(res,1,dst);
- SetAF(res,1,dst);
- SetSZPF16(res);
- return (UINT16)res;
-}
-INLINE UINT32 I386_OPS_BASE::INC32(UINT32 dst)
-{
- UINT64 res = (UINT64)dst + 1;
- SetOF_Add32(res,1,dst);
- SetAF(res,1,dst);
- SetSZPF32(res);
- return (UINT32)res;
-}
-
-INLINE UINT8 I386_OPS_BASE::DEC8(UINT8 dst)
-{
- UINT16 res = (UINT16)dst - 1;
- SetOF_Sub8(res,1,dst);
- SetAF(res,1,dst);
- SetSZPF8(res);
- return (UINT8)res;
-}
-INLINE UINT16 I386_OPS_BASE::DEC16(UINT16 dst)
-{
- UINT32 res = (UINT32)dst - 1;
- SetOF_Sub16(res,1,dst);
- SetAF(res,1,dst);
- SetSZPF16(res);
- return (UINT16)res;
-}
-INLINE UINT32 I386_OPS_BASE::DEC32(UINT32 dst)
-{
- UINT64 res = (UINT64)dst - 1;
- SetOF_Sub32(res,1,dst);
- SetAF(res,1,dst);
- SetSZPF32(res);
- return (UINT32)res;
-}
-
-
-
-INLINE void I386_OPS_BASE::PUSH16(UINT16 value)
-{
- UINT32 ea, new_esp;
- if( STACK_32BIT ) {
- new_esp = REG32(ESP) - 2;
- ea = i386_translate( SS, new_esp, 1);
- WRITE16( ea, value );
- REG32(ESP) = new_esp;
- } else {
- new_esp = (REG16(SP) - 2) & 0xffff;
- ea = i386_translate( SS, new_esp, 1);
- WRITE16( ea, value );
- REG16(SP) = new_esp;
- }
-}
-INLINE void I386_OPS_BASE::PUSH32(UINT32 value)
-{
- UINT32 ea, new_esp;
- if( STACK_32BIT ) {
- new_esp = REG32(ESP) - 4;
- ea = i386_translate( SS, new_esp, 1);
- WRITE32( ea, value );
- REG32(ESP) = new_esp;
- } else {
- new_esp = (REG16(SP) - 4) & 0xffff;
- ea = i386_translate( SS, new_esp, 1);
- WRITE32( ea, value );
- REG16(SP) = new_esp;
- }
-}
-INLINE void I386_OPS_BASE::PUSH8(UINT8 value)
-{
- if( cpustate->operand_size ) {
- PUSH32((INT32)(INT8)value);
- } else {
- PUSH16((INT16)(INT8)value);
- }
-}
-
-INLINE UINT8 I386_OPS_BASE::POP8(i386_state *cpustate)
-{
- UINT8 value;
- UINT32 ea, new_esp;
- if( STACK_32BIT ) {
- new_esp = REG32(ESP) + 1;
- ea = i386_translate( SS, new_esp - 1, 0);
- value = READ8( ea );
- REG32(ESP) = new_esp;
- } else {
- new_esp = REG16(SP) + 1;
- ea = i386_translate( SS, (new_esp - 1) & 0xffff, 0);
- value = READ8( ea );
- REG16(SP) = new_esp;
- }
- return value;
-}
-INLINE UINT16 I386_OPS_BASE::POP16(i386_state *cpustate)
-{
- UINT16 value;
- UINT32 ea, new_esp;
- if( STACK_32BIT ) {
- new_esp = REG32(ESP) + 2;
- ea = i386_translate( SS, new_esp - 2, 0);
- value = READ16( ea );
- REG32(ESP) = new_esp;
- } else {
- new_esp = REG16(SP) + 2;
- ea = i386_translate( SS, (new_esp - 2) & 0xffff, 0);
- value = READ16( ea );
- REG16(SP) = new_esp;
- }
- return value;
-}
-INLINE UINT32 I386_OPS_BASE::POP32(i386_state *cpustate)
-{
- UINT32 value;
- UINT32 ea, new_esp;
- if( STACK_32BIT ) {
- new_esp = REG32(ESP) + 4;
- ea = i386_translate( SS, new_esp - 4, 0);
- value = READ32( ea );
- REG32(ESP) = new_esp;
- } else {
- new_esp = REG16(SP) + 4;
- ea = i386_translate( SS, (new_esp - 4) & 0xffff, 0);
- value = READ32( ea );
- REG16(SP) = new_esp;
- }
- return value;
-}
-
-INLINE void I386_OPS_BASE::BUMP_SI(int adjustment)
-{
- if ( cpustate->address_size )
- REG32(ESI) += ((cpustate->DF) ? -adjustment : +adjustment);
- else
- REG16(SI) += ((cpustate->DF) ? -adjustment : +adjustment);
-}
-
-INLINE void I386_OPS_BASE::BUMP_DI(int adjustment)
-{
- if ( cpustate->address_size )
- REG32(EDI) += ((cpustate->DF) ? -adjustment : +adjustment);
- else
- REG16(DI) += ((cpustate->DF) ? -adjustment : +adjustment);
-}
-
-
-
-/***********************************************************************************
- I/O ACCESS
-***********************************************************************************/
-
-INLINE void I386_OPS_BASE::check_ioperm( offs_t port, UINT8 mask)
-{
- UINT8 IOPL, map;
- UINT16 IOPB;
- UINT32 address;
-
- if(!PROTECTED_MODE)
- return;
-
- IOPL = cpustate->IOP1 | (cpustate->IOP2 << 1);
- if(!V8086_MODE && (cpustate->CPL <= IOPL))
- return;
-
- if((cpustate->task.limit < 0x67) || ((cpustate->task.flags & 0xd) != 9))
- FAULT_THROW(FAULT_GP,0);
-
- address = cpustate->task.base;
- IOPB = READ16PL0( address+0x66);
- if((IOPB+(port/8)) > cpustate->task.limit)
- FAULT_THROW(FAULT_GP,0);
-
- map = READ8PL0( address+IOPB+(port/8));
- map >>= (port%8);
- if(map & mask)
- FAULT_THROW(FAULT_GP,0);
-}
-
-INLINE UINT8 I386_OPS_BASE::READPORT8( offs_t port)
-{
- check_ioperm( port, 1);
- return cpustate->io->read_io8(port);
-}
-
-INLINE void I386_OPS_BASE::WRITEPORT8( offs_t port, UINT8 value)
-{
- check_ioperm( port, 1);
- cpustate->io->write_io8(port, value);
-}
-
-INLINE UINT16 I386_OPS_BASE::READPORT16( offs_t port)
-{
- if (port & 1)
- {
- UINT16 value = READPORT8( port);
- value |= (READPORT8( port + 1) << 8);
- return value;
- }
- else
- {
- check_ioperm( port, 3);
- return cpustate->io->read_io16(port);
- }
-}
-
-INLINE void I386_OPS_BASE::WRITEPORT16( offs_t port, UINT16 value)
-{
- if (port & 1)
- {
- WRITEPORT8( port, value & 0xff);
- WRITEPORT8( port + 1, (value >> 8) & 0xff);
- }
- else
- {
- check_ioperm( port, 3);
- cpustate->io->write_io16(port, value);
- }
-}
-
-INLINE UINT32 I386_OPS_BASE::READPORT32( offs_t port)
-{
- if (port & 3)
- {
- UINT32 value = READPORT8( port);
- value |= (READPORT8( port + 1) << 8);
- value |= (READPORT8( port + 2) << 16);
- value |= (READPORT8( port + 3) << 24);
- return value;
- }
- else
- {
- check_ioperm( port, 0xf);
- return cpustate->io->read_io32(port);
- }
-}
-
-INLINE void I386_OPS_BASE::WRITEPORT32( offs_t port, UINT32 value)
-{
- if (port & 3)
- {
- WRITEPORT8( port, value & 0xff);
- WRITEPORT8( port + 1, (value >> 8) & 0xff);
- WRITEPORT8( port + 2, (value >> 16) & 0xff);
- WRITEPORT8( port + 3, (value >> 24) & 0xff);
- }
- else
- {
- check_ioperm( port, 0xf);
- cpustate->io->write_io32(port, value);
- }
-}
-
-
-INLINE UINT64 I386_OPS_BASE::MSR_READ(UINT32 offset,UINT8 *valid_msr)
-{
- UINT64 res;
- UINT8 cpu_type = (cpustate->cpu_version >> 8) & 0x0f;
-
- *valid_msr = 0;
-
- switch(cpu_type)
- {
- case 5: // Pentium
- res = pentium_msr_read(offset,valid_msr);
- break;
- case 6: // Pentium Pro, Pentium II, Pentium III
- res = p6_msr_read(offset,valid_msr);
- break;
- case 15: // Pentium 4+
- res = piv_msr_read(offset,valid_msr);
- break;
- default:
- res = 0;
- break;
- }
-
- return res;
-}
-
-INLINE void I386_OPS_BASE::MSR_WRITE(UINT32 offset, UINT64 data, UINT8 *valid_msr)
-{
- *valid_msr = 0;
- UINT8 cpu_type = (cpustate->cpu_version >> 8) & 0x0f;
-
- switch(cpu_type)
- {
- case 5: // Pentium
- pentium_msr_write(offset,data,valid_msr);
- break;
- case 6: // Pentium Pro, Pentium II, Pentium III
- p6_msr_write(offset,data,valid_msr);
- break;
- case 15: // Pentium 4+
- piv_msr_write(offset,data,valid_msr);
- break;
- }
-}
-
-#endif /* __I386_H__ */
+++ /dev/null
-// license:BSD-3-Clause
-// copyright-holders:Ville Linde, Barry Rodewald, Carl, Phil Bennett
-// Intel 486+ specific opcodes
-
-void I386_OPS_BASE::I486OP(cpuid)() // Opcode 0x0F A2
-{
- if (cpustate->cpuid_id0 == 0)
- {
- // this 486 doesn't support the CPUID instruction
- logerror("CPUID not supported at %08x!\n", cpustate->eip);
- i386_trap( 6, 0, 0);
- }
- else
- {
- switch (REG32(EAX))
- {
- case 0:
- {
- REG32(EAX) = cpustate->cpuid_max_input_value_eax;
- REG32(EBX) = cpustate->cpuid_id0;
- REG32(ECX) = cpustate->cpuid_id2;
- REG32(EDX) = cpustate->cpuid_id1;
- CYCLES(CYCLES_CPUID);
- break;
- }
-
- case 1:
- {
- REG32(EAX) = cpustate->cpu_version;
- REG32(EDX) = cpustate->feature_flags;
- CYCLES(CYCLES_CPUID_EAX1);
- break;
- }
- }
- }
-}
-
-void I386_OPS_BASE::I486OP(invd)() // Opcode 0x0f 08
-{
- // Nothing to do ?
- CYCLES(CYCLES_INVD);
-}
-
-void I386_OPS_BASE::I486OP(wbinvd)() // Opcode 0x0f 09
-{
- // Nothing to do ?
-}
-
-void I386_OPS_BASE::I486OP(cmpxchg_rm8_r8)() // Opcode 0x0f b0
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- UINT8 dst = LOAD_RM8(modrm);
- UINT8 src = LOAD_REG8(modrm);
-
- if( REG8(AL) == dst ) {
- STORE_RM8(modrm, src);
- cpustate->ZF = 1;
- CYCLES(CYCLES_CMPXCHG_REG_REG_T);
- } else {
- REG8(AL) = dst;
- cpustate->ZF = 0;
- CYCLES(CYCLES_CMPXCHG_REG_REG_F);
- }
- } else {
- // TODO: Check write if needed
- UINT32 ea = GetEA(modrm,0);
- UINT8 dst = READ8(ea);
- UINT8 src = LOAD_REG8(modrm);
-
- if( REG8(AL) == dst ) {
- WRITE8(ea, src);
- cpustate->ZF = 1;
- CYCLES(CYCLES_CMPXCHG_REG_MEM_T);
- } else {
- REG8(AL) = dst;
- cpustate->ZF = 0;
- CYCLES(CYCLES_CMPXCHG_REG_MEM_F);
- }
- }
-}
-
-void I386_OPS_BASE::I486OP(cmpxchg_rm16_r16)() // Opcode 0x0f b1
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- UINT16 dst = LOAD_RM16(modrm);
- UINT16 src = LOAD_REG16(modrm);
-
- if( REG16(AX) == dst ) {
- STORE_RM16(modrm, src);
- cpustate->ZF = 1;
- CYCLES(CYCLES_CMPXCHG_REG_REG_T);
- } else {
- REG16(AX) = dst;
- cpustate->ZF = 0;
- CYCLES(CYCLES_CMPXCHG_REG_REG_F);
- }
- } else {
- UINT32 ea = GetEA(modrm,0);
- UINT16 dst = READ16(ea);
- UINT16 src = LOAD_REG16(modrm);
-
- if( REG16(AX) == dst ) {
- WRITE16(ea, src);
- cpustate->ZF = 1;
- CYCLES(CYCLES_CMPXCHG_REG_MEM_T);
- } else {
- REG16(AX) = dst;
- cpustate->ZF = 0;
- CYCLES(CYCLES_CMPXCHG_REG_MEM_F);
- }
- }
-}
-
-void I386_OPS_BASE::I486OP(cmpxchg_rm32_r32)() // Opcode 0x0f b1
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- UINT32 dst = LOAD_RM32(modrm);
- UINT32 src = LOAD_REG32(modrm);
-
- if( REG32(EAX) == dst ) {
- STORE_RM32(modrm, src);
- cpustate->ZF = 1;
- CYCLES(CYCLES_CMPXCHG_REG_REG_T);
- } else {
- REG32(EAX) = dst;
- cpustate->ZF = 0;
- CYCLES(CYCLES_CMPXCHG_REG_REG_F);
- }
- } else {
- UINT32 ea = GetEA(modrm,0);
- UINT32 dst = READ32(ea);
- UINT32 src = LOAD_REG32(modrm);
-
- if( REG32(EAX) == dst ) {
- WRITE32(ea, src);
- cpustate->ZF = 1;
- CYCLES(CYCLES_CMPXCHG_REG_MEM_T);
- } else {
- REG32(EAX) = dst;
- cpustate->ZF = 0;
- CYCLES(CYCLES_CMPXCHG_REG_MEM_F);
- }
- }
-}
-
-void I386_OPS_BASE::I486OP(xadd_rm8_r8)() // Opcode 0x0f c0
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- UINT8 dst = LOAD_RM8(modrm);
- UINT8 src = LOAD_REG8(modrm);
- STORE_REG8(modrm, dst);
- STORE_RM8(modrm, dst + src);
- CYCLES(CYCLES_XADD_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- UINT8 dst = READ8(ea);
- UINT8 src = LOAD_REG8(modrm);
- WRITE8(ea, dst + src);
- STORE_REG8(modrm, dst);
- CYCLES(CYCLES_XADD_REG_MEM);
- }
-}
-
-void I386_OPS_BASE::I486OP(xadd_rm16_r16)() // Opcode 0x0f c1
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- UINT16 dst = LOAD_RM16(modrm);
- UINT16 src = LOAD_REG16(modrm);
- STORE_REG16(modrm, dst);
- STORE_RM16(modrm, dst + src);
- CYCLES(CYCLES_XADD_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- UINT16 dst = READ16(ea);
- UINT16 src = LOAD_REG16(modrm);
- WRITE16(ea, dst + src);
- STORE_REG16(modrm, dst);
- CYCLES(CYCLES_XADD_REG_MEM);
- }
-}
-
-void I386_OPS_BASE::I486OP(xadd_rm32_r32)() // Opcode 0x0f c1
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- UINT32 dst = LOAD_RM32(modrm);
- UINT32 src = LOAD_REG32(modrm);
- STORE_REG32(modrm, dst);
- STORE_RM32(modrm, dst + src);
- CYCLES(CYCLES_XADD_REG_REG);
- } else {
- UINT32 ea = GetEA(modrm,1);
- UINT32 dst = READ32(ea);
- UINT32 src = LOAD_REG32(modrm);
- WRITE32(ea, dst + src);
- STORE_REG32(modrm, dst);
- CYCLES(CYCLES_XADD_REG_MEM);
- }
-}
-
-void I386_OPS_BASE::I486OP(group0F01_16)() // Opcode 0x0f 01
-{
- UINT8 modrm = FETCH();
- UINT16 address;
- UINT32 ea;
-
- switch( (modrm >> 3) & 0x7 )
- {
- case 0: /* SGDT */
- {
- if( modrm >= 0xc0 ) {
- address = LOAD_RM16(modrm);
- ea = i386_translate( cpustate, CS, address, 1 );
- } else {
- ea = GetEA(modrm,1);
- }
- WRITE16(ea, cpustate->gdtr.limit);
- WRITE32(ea + 2, cpustate->gdtr.base & 0xffffff);
- CYCLES(CYCLES_SGDT);
- break;
- }
- case 1: /* SIDT */
- {
- if (modrm >= 0xc0)
- {
- address = LOAD_RM16(modrm);
- ea = i386_translate( cpustate, CS, address, 1 );
- }
- else
- {
- ea = GetEA(modrm,1);
- }
- WRITE16(ea, cpustate->idtr.limit);
- WRITE32(ea + 2, cpustate->idtr.base & 0xffffff);
- CYCLES(CYCLES_SIDT);
- break;
- }
- case 2: /* LGDT */
- {
- if(PROTECTED_MODE && cpustate->CPL)
- FAULT(FAULT_GP,0)
- if( modrm >= 0xc0 ) {
- address = LOAD_RM16(modrm);
- ea = i386_translate( cpustate, CS, address, 0 );
- } else {
- ea = GetEA(modrm,0);
- }
- cpustate->gdtr.limit = READ16(ea);
- cpustate->gdtr.base = READ32(ea + 2) & 0xffffff;
- CYCLES(CYCLES_LGDT);
- break;
- }
- case 3: /* LIDT */
- {
- if(PROTECTED_MODE && cpustate->CPL)
- FAULT(FAULT_GP,0)
- if( modrm >= 0xc0 ) {
- address = LOAD_RM16(modrm);
- ea = i386_translate( cpustate, CS, address, 0 );
- } else {
- ea = GetEA(modrm,0);
- }
- cpustate->idtr.limit = READ16(ea);
- cpustate->idtr.base = READ32(ea + 2) & 0xffffff;
- CYCLES(CYCLES_LIDT);
- break;
- }
- case 4: /* SMSW */
- {
- if( modrm >= 0xc0 ) {
- STORE_RM16(modrm, cpustate->cr[0]);
- CYCLES(CYCLES_SMSW_REG);
- } else {
- ea = GetEA(modrm,1);
- WRITE16(ea, cpustate->cr[0]);
- CYCLES(CYCLES_SMSW_MEM);
- }
- break;
- }
- case 6: /* LMSW */
- {
- UINT16 b;
- if(PROTECTED_MODE && cpustate->CPL)
- FAULT(FAULT_GP,0)
- if( modrm >= 0xc0 ) {
- b = LOAD_RM16(modrm);
- CYCLES(CYCLES_LMSW_REG);
- } else {
- ea = GetEA(modrm,0);
- CYCLES(CYCLES_LMSW_MEM);
- b = READ16(ea);
- }
- if(PROTECTED_MODE)
- b |= 0x0001; // cannot return to real mode using this instruction.
- cpustate->cr[0] &= ~0x0000000f;
- cpustate->cr[0] |= b & 0x0000000f;
- break;
- }
- case 7: /* INVLPG */
- {
- if(PROTECTED_MODE && cpustate->CPL)
- FAULT(FAULT_GP,0)
- if(modrm >= 0xc0)
- {
- logerror("i486: invlpg with modrm %02X\n", modrm);
- FAULT(FAULT_UD,0)
- }
- ea = GetEA(modrm,-1);
- CYCLES(25); // TODO: add to cycles.h
- vtlb_flush_address(cpustate->vtlb, ea);
- break;
- }
- default:
- report_invalid_modrm( "group0F01_16", modrm);
- break;
- }
-}
-
-void I386_OPS_BASE::I486OP(group0F01_32)() // Opcode 0x0f 01
-{
- UINT8 modrm = FETCH();
- UINT32 address, ea;
-
- switch( (modrm >> 3) & 0x7 )
- {
- case 0: /* SGDT */
- {
- if( modrm >= 0xc0 ) {
- address = LOAD_RM32(modrm);
- ea = i386_translate( cpustate, CS, address, 1 );
- } else {
- ea = GetEA(modrm,1);
- }
- WRITE16(ea, cpustate->gdtr.limit);
- WRITE32(ea + 2, cpustate->gdtr.base);
- CYCLES(CYCLES_SGDT);
- break;
- }
- case 1: /* SIDT */
- {
- if (modrm >= 0xc0)
- {
- address = LOAD_RM32(modrm);
- ea = i386_translate( cpustate, CS, address, 1 );
- }
- else
- {
- ea = GetEA(modrm,1);
- }
- WRITE16(ea, cpustate->idtr.limit);
- WRITE32(ea + 2, cpustate->idtr.base);
- CYCLES(CYCLES_SIDT);
- break;
- }
- case 2: /* LGDT */
- {
- if(PROTECTED_MODE && cpustate->CPL)
- FAULT(FAULT_GP,0)
- if( modrm >= 0xc0 ) {
- address = LOAD_RM32(modrm);
- ea = i386_translate( cpustate, CS, address, 0 );
- } else {
- ea = GetEA(modrm,0);
- }
- cpustate->gdtr.limit = READ16(ea);
- cpustate->gdtr.base = READ32(ea + 2);
- CYCLES(CYCLES_LGDT);
- break;
- }
- case 3: /* LIDT */
- {
- if(PROTECTED_MODE && cpustate->CPL)
- FAULT(FAULT_GP,0)
- if( modrm >= 0xc0 ) {
- address = LOAD_RM32(modrm);
- ea = i386_translate( cpustate, CS, address, 0 );
- } else {
- ea = GetEA(modrm,0);
- }
- cpustate->idtr.limit = READ16(ea);
- cpustate->idtr.base = READ32(ea + 2);
- CYCLES(CYCLES_LIDT);
- break;
- }
- case 4: /* SMSW */
- {
- if( modrm >= 0xc0 ) {
- STORE_RM32(modrm, cpustate->cr[0] & 0xffff);
- CYCLES(CYCLES_SMSW_REG);
- } else {
- /* always 16-bit memory operand */
- ea = GetEA(modrm,1);
- WRITE16(ea, cpustate->cr[0]);
- CYCLES(CYCLES_SMSW_MEM);
- }
- break;
- }
- case 6: /* LMSW */
- {
- if(PROTECTED_MODE && cpustate->CPL)
- FAULT(FAULT_GP,0)
- UINT16 b;
- if( modrm >= 0xc0 ) {
- b = LOAD_RM16(modrm);
- CYCLES(CYCLES_LMSW_REG);
- } else {
- ea = GetEA(modrm,0);
- CYCLES(CYCLES_LMSW_MEM);
- b = READ16(ea);
- }
- if(PROTECTED_MODE)
- b |= 0x0001; // cannot return to real mode using this instruction.
- cpustate->cr[0] &= ~0x0000000f;
- cpustate->cr[0] |= b & 0x0000000f;
- break;
- }
- case 7: /* INVLPG */
- {
- if(PROTECTED_MODE && cpustate->CPL)
- FAULT(FAULT_GP,0)
- if(modrm >= 0xc0)
- {
- logerror("i486: invlpg with modrm %02X\n", modrm);
- FAULT(FAULT_UD,0)
- }
- ea = GetEA(modrm,-1);
- CYCLES(25); // TODO: add to cycles.h
- vtlb_flush_address(cpustate->vtlb, ea);
- break;
- }
- default:
- report_invalid_modrm( "group0F01_32", modrm);
- break;
- }
-}
-
-void I386_OPS_BASE::I486OP(bswap_eax)() // Opcode 0x0f 38
-{
- REG32(EAX) = SWITCH_ENDIAN_32(REG32(EAX));
- CYCLES(1); // TODO
-}
-
-void I386_OPS_BASE::I486OP(bswap_ecx)() // Opcode 0x0f 39
-{
- REG32(ECX) = SWITCH_ENDIAN_32(REG32(ECX));
- CYCLES(1); // TODO
-}
-
-void I386_OPS_BASE::I486OP(bswap_edx)() // Opcode 0x0f 3A
-{
- REG32(EDX) = SWITCH_ENDIAN_32(REG32(EDX));
- CYCLES(1); // TODO
-}
-
-void I386_OPS_BASE::I486OP(bswap_ebx)() // Opcode 0x0f 3B
-{
- REG32(EBX) = SWITCH_ENDIAN_32(REG32(EBX));
- CYCLES(1); // TODO
-}
-
-void I386_OPS_BASE::I486OP(bswap_esp)() // Opcode 0x0f 3C
-{
- REG32(ESP) = SWITCH_ENDIAN_32(REG32(ESP));
- CYCLES(1); // TODO
-}
-
-void I386_OPS_BASE::I486OP(bswap_ebp)() // Opcode 0x0f 3D
-{
- REG32(EBP) = SWITCH_ENDIAN_32(REG32(EBP));
- CYCLES(1); // TODO
-}
-
-void I386_OPS_BASE::I486OP(bswap_esi)() // Opcode 0x0f 3E
-{
- REG32(ESI) = SWITCH_ENDIAN_32(REG32(ESI));
- CYCLES(1); // TODO
-}
-
-void I386_OPS_BASE::I486OP(bswap_edi)() // Opcode 0x0f 3F
-{
- REG32(EDI) = SWITCH_ENDIAN_32(REG32(EDI));
- CYCLES(1); // TODO
-}
-
-void I386_OPS_BASE::I486OP(mov_cr_r32)() // Opcode 0x0f 22
-{
- if(PROTECTED_MODE && cpustate->CPL)
- FAULT(FAULT_GP, 0);
- UINT8 modrm = FETCH();
- UINT8 cr = (modrm >> 3) & 0x7;
- UINT32 oldcr = cpustate->cr[cr];
- UINT32 data = LOAD_RM32(modrm);
- switch(cr)
- {
- case 0:
- CYCLES(CYCLES_MOV_REG_CR0);
- if((oldcr ^ cpustate->cr[cr]) & 0x80010000)
- vtlb_flush_dynamic(cpustate->vtlb);
- break;
- case 2: CYCLES(CYCLES_MOV_REG_CR2); break;
- case 3:
- CYCLES(CYCLES_MOV_REG_CR3);
- vtlb_flush_dynamic(cpustate->vtlb);
- break;
- case 4: CYCLES(1); break; // TODO
- default:
- logerror("i386: mov_cr_r32 CR%d!\n", cr);
- return;
- }
- cpustate->cr[cr] = data;
-}
+++ /dev/null
-// license:BSD-3-Clause
-// copyright-holders:Ville Linde, Barry Rodewald, Carl, Phil Bennett
-// Pentium+ specific opcodes
-
-extern flag float32_is_nan( float32 a ); // since its not defined in softfloat.h
-extern flag float64_is_nan( float64 a ); // since its not defined in softfloat.h
-
-INLINE void MMXPROLOG()
-{
- //cpustate->x87_sw &= ~(X87_SW_TOP_MASK << X87_SW_TOP_SHIFT); // top = 0
- cpustate->x87_tw = 0; // tag word = 0
-}
-
-INLINE void READMMX(UINT32 ea,MMX_REG &r)
-{
- r.q=READ64( ea);
-}
-
-INLINE void WRITEMMX(UINT32 ea,MMX_REG &r)
-{
- WRITE64( ea, r.q);
-}
-
-INLINE void READXMM(UINT32 ea,XMM_REG &r)
-{
- r.q[0]=READ64( ea);
- r.q[1]=READ64( ea+8);
-}
-
-INLINE void WRITEXMM(UINT32 ea,XMM_REG &r)
-{
- WRITE64( ea, r.q[0]);
- WRITE64( ea+8, r.q[1]);
-}
-
-INLINE void READXMM_LO64(UINT32 ea,XMM_REG &r)
-{
- r.q[0]=READ64( ea);
-}
-
-INLINE void WRITEXMM_LO64(UINT32 ea,XMM_REG &r)
-{
- WRITE64( ea, r.q[0]);
-}
-
-INLINE void READXMM_HI64(UINT32 ea,XMM_REG &r)
-{
- r.q[1]=READ64( ea);
-}
-
-INLINE void WRITEXMM_HI64(UINT32 ea,XMM_REG &r)
-{
- WRITE64( ea, r.q[1]);
-}
-
-void I386_OPS_BASE::PENTIUMOP(rdmsr)() // Opcode 0x0f 32
-{
- UINT64 data;
- UINT8 valid_msr = 0;
-
- data = MSR_READ(REG32(ECX),&valid_msr);
- REG32(EDX) = data >> 32;
- REG32(EAX) = data & 0xffffffff;
-
- if(cpustate->CPL != 0 || valid_msr == 0) // if current privilege level isn't 0 or the register isn't recognized ...
- FAULT(FAULT_GP,0) // ... throw a general exception fault
-
- CYCLES(CYCLES_RDMSR);
-}
-
- void I386_OPS_BASE::PENTIUMOP(wrmsr)() // Opcode 0x0f 30
-{
- UINT64 data;
- UINT8 valid_msr = 0;
-
- data = (UINT64)REG32(EAX);
- data |= (UINT64)(REG32(EDX)) << 32;
-
- MSR_WRITE(REG32(ECX),data,&valid_msr);
-
- if(cpustate->CPL != 0 || valid_msr == 0) // if current privilege level isn't 0 or the register isn't recognized
- FAULT(FAULT_GP,0) // ... throw a general exception fault
-
- CYCLES(1); // TODO: correct cycle count (~30-45)
-}
-
- void I386_OPS_BASE::PENTIUMOP(rdtsc)() // Opcode 0x0f 31
-{
- UINT64 ts = cpustate->tsc + (cpustate->base_cycles - cpustate->cycles);
- REG32(EAX) = (UINT32)(ts);
- REG32(EDX) = (UINT32)(ts >> 32);
-
- CYCLES(CYCLES_RDTSC);
-}
-
- void I386_OPS_BASE::PENTIUMOP(ud2)() // Opcode 0x0f 0b
-{
- i386_trap( 6, 0, 0);
-}
-
- void I386_OPS_BASE::PENTIUMOP(rsm)()
-{
- UINT32 smram_state = cpustate->smbase + 0xfe00;
- if(!cpustate->smm)
- {
- logerror("i386: Invalid RSM outside SMM at %08X\n", cpustate->pc - 1);
- i386_trap( 6, 0, 0);
- return;
- }
-
- // load state, no sanity checks anywhere
- cpustate->smbase = READ32(smram_state+SMRAM_SMBASE);
- cpustate->cr[4] = READ32(smram_state+SMRAM_IP5_CR4);
- cpustate->sreg[ES].limit = READ32(smram_state+SMRAM_IP5_ESLIM);
- cpustate->sreg[ES].base = READ32(smram_state+SMRAM_IP5_ESBASE);
- cpustate->sreg[ES].flags = READ32(smram_state+SMRAM_IP5_ESACC);
- cpustate->sreg[CS].limit = READ32(smram_state+SMRAM_IP5_CSLIM);
- cpustate->sreg[CS].base = READ32(smram_state+SMRAM_IP5_CSBASE);
- cpustate->sreg[CS].flags = READ32(smram_state+SMRAM_IP5_CSACC);
- cpustate->sreg[SS].limit = READ32(smram_state+SMRAM_IP5_SSLIM);
- cpustate->sreg[SS].base = READ32(smram_state+SMRAM_IP5_SSBASE);
- cpustate->sreg[SS].flags = READ32(smram_state+SMRAM_IP5_SSACC);
- cpustate->sreg[DS].limit = READ32(smram_state+SMRAM_IP5_DSLIM);
- cpustate->sreg[DS].base = READ32(smram_state+SMRAM_IP5_DSBASE);
- cpustate->sreg[DS].flags = READ32(smram_state+SMRAM_IP5_DSACC);
- cpustate->sreg[FS].limit = READ32(smram_state+SMRAM_IP5_FSLIM);
- cpustate->sreg[FS].base = READ32(smram_state+SMRAM_IP5_FSBASE);
- cpustate->sreg[FS].flags = READ32(smram_state+SMRAM_IP5_FSACC);
- cpustate->sreg[GS].limit = READ32(smram_state+SMRAM_IP5_GSLIM);
- cpustate->sreg[GS].base = READ32(smram_state+SMRAM_IP5_GSBASE);
- cpustate->sreg[GS].flags = READ32(smram_state+SMRAM_IP5_GSACC);
- cpustate->ldtr.flags = READ32(smram_state+SMRAM_IP5_LDTACC);
- cpustate->ldtr.limit = READ32(smram_state+SMRAM_IP5_LDTLIM);
- cpustate->ldtr.base = READ32(smram_state+SMRAM_IP5_LDTBASE);
- cpustate->gdtr.limit = READ32(smram_state+SMRAM_IP5_GDTLIM);
- cpustate->gdtr.base = READ32(smram_state+SMRAM_IP5_GDTBASE);
- cpustate->idtr.limit = READ32(smram_state+SMRAM_IP5_IDTLIM);
- cpustate->idtr.base = READ32(smram_state+SMRAM_IP5_IDTBASE);
- cpustate->task.limit = READ32(smram_state+SMRAM_IP5_TRLIM);
- cpustate->task.base = READ32(smram_state+SMRAM_IP5_TRBASE);
- cpustate->task.flags = READ32(smram_state+SMRAM_IP5_TRACC);
-
- cpustate->sreg[ES].selector = READ32(smram_state+SMRAM_ES);
- cpustate->sreg[CS].selector = READ32(smram_state+SMRAM_CS);
- cpustate->sreg[SS].selector = READ32(smram_state+SMRAM_SS);
- cpustate->sreg[DS].selector = READ32(smram_state+SMRAM_DS);
- cpustate->sreg[FS].selector = READ32(smram_state+SMRAM_FS);
- cpustate->sreg[GS].selector = READ32(smram_state+SMRAM_GS);
- cpustate->ldtr.segment = READ32(smram_state+SMRAM_LDTR);
- cpustate->task.segment = READ32(smram_state+SMRAM_TR);
-
- cpustate->dr[7] = READ32(smram_state+SMRAM_DR7);
- cpustate->dr[6] = READ32(smram_state+SMRAM_DR6);
- REG32(EAX) = READ32(smram_state+SMRAM_EAX);
- REG32(ECX) = READ32(smram_state+SMRAM_ECX);
- REG32(EDX) = READ32(smram_state+SMRAM_EDX);
- REG32(EBX) = READ32(smram_state+SMRAM_EBX);
- REG32(ESP) = READ32(smram_state+SMRAM_ESP);
- REG32(EBP) = READ32(smram_state+SMRAM_EBP);
- REG32(ESI) = READ32(smram_state+SMRAM_ESI);
- REG32(EDI) = READ32(smram_state+SMRAM_EDI);
- cpustate->eip = READ32(smram_state+SMRAM_EIP);
- cpustate->eflags = READ32(smram_state+SMRAM_EAX);
- cpustate->cr[3] = READ32(smram_state+SMRAM_CR3);
- cpustate->cr[0] = READ32(smram_state+SMRAM_CR0);
-
- cpustate->CPL = (cpustate->sreg[SS].flags >> 13) & 3; // cpl == dpl of ss
-
- for(int i = 0; i < GS; i++)
- {
- if(PROTECTED_MODE && !V8086_MODE)
- {
- cpustate->sreg[i].valid = cpustate->sreg[i].selector ? true : false;
- cpustate->sreg[i].d = (cpustate->sreg[i].flags & 0x4000) ? 1 : 0;
- }
- else
- cpustate->sreg[i].valid = true;
- }
-
-// if(!cpustate->smiact.isnull())
-// cpustate->smiact(false);
- cpustate->smm = false;
-
- CHANGE_PC(cpustate->eip);
- cpustate->nmi_masked = false;
- if(cpustate->smi_latched)
- {
- pentium_smi();
- return;
- }
- if(cpustate->nmi_latched)
- {
- cpustate->nmi_latched = false;
- i386_trap( 2, 1, 0);
- }
-}
-
- void I386_OPS_BASE::PENTIUMOP(prefetch_m8)() // Opcode 0x0f 18
-{
- UINT8 modrm = FETCH();
- UINT32 ea = GetEA(modrm,0);
- CYCLES(1+(ea & 1)); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::PENTIUMOP(cmovo_r16_rm16)() // Opcode 0x0f 40
-{
- UINT16 src;
- UINT8 modrm = FETCH();
-
- if( modrm >= 0xc0 )
- {
- if (cpustate->OF == 1)
- {
- src = LOAD_RM16(modrm);
- STORE_REG16(modrm, src);
- }
- CYCLES(1); // TODO: correct cycle count
- }
- else
- {
- UINT32 ea = GetEA(modrm,0);
- if (cpustate->OF == 1)
- {
- src = READ16(ea);
- STORE_REG16(modrm, src);
- }
- CYCLES(1); // TODO: correct cycle count
- }
-}
-
- void I386_OPS_BASE::PENTIUMOP(cmovo_r32_rm32)() // Opcode 0x0f 40
-{
- UINT32 src;
- UINT8 modrm = FETCH();
-
- if( modrm >= 0xc0 )
- {
- if (cpustate->OF == 1)
- {
- src = LOAD_RM32(modrm);
- STORE_REG32(modrm, src);
- }
- CYCLES(1); // TODO: correct cycle count
- }
- else
- {
- UINT32 ea = GetEA(modrm,0);
- if (cpustate->OF == 1)
- {
- src = READ32(ea);
- STORE_REG32(modrm, src);
- }
- CYCLES(1); // TODO: correct cycle count
- }
-}
-
- void I386_OPS_BASE::PENTIUMOP(cmovno_r16_rm16)() // Opcode 0x0f 41
-{
- UINT16 src;
- UINT8 modrm = FETCH();
-
- if( modrm >= 0xc0 )
- {
- if (cpustate->OF == 0)
- {
- src = LOAD_RM16(modrm);
- STORE_REG16(modrm, src);
- }
- CYCLES(1); // TODO: correct cycle count
- }
- else
- {
- UINT32 ea = GetEA(modrm,0);
- if (cpustate->OF == 0)
- {
- src = READ16(ea);
- STORE_REG16(modrm, src);
- }
- CYCLES(1); // TODO: correct cycle count
- }
-}
-
- void I386_OPS_BASE::PENTIUMOP(cmovno_r32_rm32)() // Opcode 0x0f 41
-{
- UINT32 src;
- UINT8 modrm = FETCH();
-
- if( modrm >= 0xc0 )
- {
- if (cpustate->OF == 0)
- {
- src = LOAD_RM32(modrm);
- STORE_REG32(modrm, src);
- }
- CYCLES(1); // TODO: correct cycle count
- }
- else
- {
- UINT32 ea = GetEA(modrm,0);
- if (cpustate->OF == 0)
- {
- src = READ32(ea);
- STORE_REG32(modrm, src);
- }
- CYCLES(1); // TODO: correct cycle count
- }
-}
-
- void I386_OPS_BASE::PENTIUMOP(cmovb_r16_rm16)() // Opcode 0x0f 42
-{
- UINT16 src;
- UINT8 modrm = FETCH();
-
- if( modrm >= 0xc0 )
- {
- if (cpustate->CF == 1)
- {
- src = LOAD_RM16(modrm);
- STORE_REG16(modrm, src);
- }
- CYCLES(1); // TODO: correct cycle count
- }
- else
- {
- UINT32 ea = GetEA(modrm,0);
- if (cpustate->CF == 1)
- {
- src = READ16(ea);
- STORE_REG16(modrm, src);
- }
- CYCLES(1); // TODO: correct cycle count
- }
-}
-
- void I386_OPS_BASE::PENTIUMOP(cmovb_r32_rm32)() // Opcode 0x0f 42
-{
- UINT32 src;
- UINT8 modrm = FETCH();
-
- if( modrm >= 0xc0 )
- {
- if (cpustate->CF == 1)
- {
- src = LOAD_RM32(modrm);
- STORE_REG32(modrm, src);
- }
- CYCLES(1); // TODO: correct cycle count
- }
- else
- {
- UINT32 ea = GetEA(modrm,0);
- if (cpustate->CF == 1)
- {
- src = READ32(ea);
- STORE_REG32(modrm, src);
- }
- CYCLES(1); // TODO: correct cycle count
- }
-}
-
- void I386_OPS_BASE::PENTIUMOP(cmovae_r16_rm16)() // Opcode 0x0f 43
-{
- UINT16 src;
- UINT8 modrm = FETCH();
-
- if( modrm >= 0xc0 )
- {
- if (cpustate->CF == 0)
- {
- src = LOAD_RM16(modrm);
- STORE_REG16(modrm, src);
- }
- CYCLES(1); // TODO: correct cycle count
- }
- else
- {
- UINT32 ea = GetEA(modrm,0);
- if (cpustate->CF == 0)
- {
- src = READ16(ea);
- STORE_REG16(modrm, src);
- }
- CYCLES(1); // TODO: correct cycle count
- }
-}
-
- void I386_OPS_BASE::PENTIUMOP(cmovae_r32_rm32)() // Opcode 0x0f 43
-{
- UINT32 src;
- UINT8 modrm = FETCH();
-
- if( modrm >= 0xc0 )
- {
- if (cpustate->CF == 0)
- {
- src = LOAD_RM32(modrm);
- STORE_REG32(modrm, src);
- }
- CYCLES(1); // TODO: correct cycle count
- }
- else
- {
- UINT32 ea = GetEA(modrm,0);
- if (cpustate->CF == 0)
- {
- src = READ32(ea);
- STORE_REG32(modrm, src);
- }
- CYCLES(1); // TODO: correct cycle count
- }
-}
-
- void I386_OPS_BASE::PENTIUMOP(cmove_r16_rm16)() // Opcode 0x0f 44
-{
- UINT16 src;
- UINT8 modrm = FETCH();
-
- if( modrm >= 0xc0 )
- {
- if (cpustate->ZF == 1)
- {
- src = LOAD_RM16(modrm);
- STORE_REG16(modrm, src);
- }
- CYCLES(1); // TODO: correct cycle count
- }
- else
- {
- UINT32 ea = GetEA(modrm,0);
- if (cpustate->ZF == 1)
- {
- src = READ16(ea);
- STORE_REG16(modrm, src);
- }
- CYCLES(1); // TODO: correct cycle count
- }
-}
-
- void I386_OPS_BASE::PENTIUMOP(cmove_r32_rm32)() // Opcode 0x0f 44
-{
- UINT32 src;
- UINT8 modrm = FETCH();
-
- if( modrm >= 0xc0 )
- {
- if (cpustate->ZF == 1)
- {
- src = LOAD_RM32(modrm);
- STORE_REG32(modrm, src);
- }
- CYCLES(1); // TODO: correct cycle count
- }
- else
- {
- UINT32 ea = GetEA(modrm,0);
- if (cpustate->ZF == 1)
- {
- src = READ32(ea);
- STORE_REG32(modrm, src);
- }
- CYCLES(1); // TODO: correct cycle count
- }
-}
-
- void I386_OPS_BASE::PENTIUMOP(cmovne_r16_rm16)() // Opcode 0x0f 45
-{
- UINT16 src;
- UINT8 modrm = FETCH();
-
- if( modrm >= 0xc0 )
- {
- if (cpustate->ZF == 0)
- {
- src = LOAD_RM16(modrm);
- STORE_REG16(modrm, src);
- }
- CYCLES(1); // TODO: correct cycle count
- }
- else
- {
- UINT32 ea = GetEA(modrm,0);
- if (cpustate->ZF == 0)
- {
- src = READ16(ea);
- STORE_REG16(modrm, src);
- }
- CYCLES(1); // TODO: correct cycle count
- }
-}
-
- void I386_OPS_BASE::PENTIUMOP(cmovne_r32_rm32)() // Opcode 0x0f 45
-{
- UINT32 src;
- UINT8 modrm = FETCH();
-
- if( modrm >= 0xc0 )
- {
- if (cpustate->ZF == 0)
- {
- src = LOAD_RM32(modrm);
- STORE_REG32(modrm, src);
- }
- CYCLES(1); // TODO: correct cycle count
- }
- else
- {
- UINT32 ea = GetEA(modrm,0);
- if (cpustate->ZF == 0)
- {
- src = READ32(ea);
- STORE_REG32(modrm, src);
- }
- CYCLES(1); // TODO: correct cycle count
- }
-}
-
- void I386_OPS_BASE::PENTIUMOP(cmovbe_r16_rm16)() // Opcode 0x0f 46
-{
- UINT16 src;
- UINT8 modrm = FETCH();
-
- if( modrm >= 0xc0 )
- {
- if ((cpustate->CF == 1) || (cpustate->ZF == 1))
- {
- src = LOAD_RM16(modrm);
- STORE_REG16(modrm, src);
- }
- CYCLES(1); // TODO: correct cycle count
- }
- else
- {
- UINT32 ea = GetEA(modrm,0);
- if ((cpustate->CF == 1) || (cpustate->ZF == 1))
- {
- src = READ16(ea);
- STORE_REG16(modrm, src);
- }
- CYCLES(1); // TODO: correct cycle count
- }
-}
-
- void I386_OPS_BASE::PENTIUMOP(cmovbe_r32_rm32)() // Opcode 0x0f 46
-{
- UINT32 src;
- UINT8 modrm = FETCH();
-
- if( modrm >= 0xc0 )
- {
- if ((cpustate->CF == 1) || (cpustate->ZF == 1))
- {
- src = LOAD_RM32(modrm);
- STORE_REG32(modrm, src);
- }
- CYCLES(1); // TODO: correct cycle count
- }
- else
- {
- UINT32 ea = GetEA(modrm,0);
- if ((cpustate->CF == 1) || (cpustate->ZF == 1))
- {
- src = READ32(ea);
- STORE_REG32(modrm, src);
- }
- CYCLES(1); // TODO: correct cycle count
- }
-}
-
- void I386_OPS_BASE::PENTIUMOP(cmova_r16_rm16)() // Opcode 0x0f 47
-{
- UINT16 src;
- UINT8 modrm = FETCH();
-
- if( modrm >= 0xc0 )
- {
- if ((cpustate->CF == 0) && (cpustate->ZF == 0))
- {
- src = LOAD_RM16(modrm);
- STORE_REG16(modrm, src);
- }
- CYCLES(1); // TODO: correct cycle count
- }
- else
- {
- UINT32 ea = GetEA(modrm,0);
- if ((cpustate->CF == 0) && (cpustate->ZF == 0))
- {
- src = READ16(ea);
- STORE_REG16(modrm, src);
- }
- CYCLES(1); // TODO: correct cycle count
- }
-}
-
- void I386_OPS_BASE::PENTIUMOP(cmova_r32_rm32)() // Opcode 0x0f 47
-{
- UINT32 src;
- UINT8 modrm = FETCH();
-
- if( modrm >= 0xc0 )
- {
- if ((cpustate->CF == 0) && (cpustate->ZF == 0))
- {
- src = LOAD_RM32(modrm);
- STORE_REG32(modrm, src);
- }
- CYCLES(1); // TODO: correct cycle count
- }
- else
- {
- UINT32 ea = GetEA(modrm,0);
- if ((cpustate->CF == 0) && (cpustate->ZF == 0))
- {
- src = READ32(ea);
- STORE_REG32(modrm, src);
- }
- CYCLES(1); // TODO: correct cycle count
- }
-}
-
- void I386_OPS_BASE::PENTIUMOP(cmovs_r16_rm16)() // Opcode 0x0f 48
-{
- UINT16 src;
- UINT8 modrm = FETCH();
-
- if( modrm >= 0xc0 )
- {
- if (cpustate->SF == 1)
- {
- src = LOAD_RM16(modrm);
- STORE_REG16(modrm, src);
- }
- CYCLES(1); // TODO: correct cycle count
- }
- else
- {
- UINT32 ea = GetEA(modrm,0);
- if (cpustate->SF == 1)
- {
- src = READ16(ea);
- STORE_REG16(modrm, src);
- }
- CYCLES(1); // TODO: correct cycle count
- }
-}
-
- void I386_OPS_BASE::PENTIUMOP(cmovs_r32_rm32)() // Opcode 0x0f 48
-{
- UINT32 src;
- UINT8 modrm = FETCH();
-
- if( modrm >= 0xc0 )
- {
- if (cpustate->SF == 1)
- {
- src = LOAD_RM32(modrm);
- STORE_REG32(modrm, src);
- }
- CYCLES(1); // TODO: correct cycle count
- }
- else
- {
- UINT32 ea = GetEA(modrm,0);
- if (cpustate->SF == 1)
- {
- src = READ32(ea);
- STORE_REG32(modrm, src);
- }
- CYCLES(1); // TODO: correct cycle count
- }
-}
-
- void I386_OPS_BASE::PENTIUMOP(cmovns_r16_rm16)() // Opcode 0x0f 49
-{
- UINT16 src;
- UINT8 modrm = FETCH();
-
- if( modrm >= 0xc0 )
- {
- if (cpustate->SF == 0)
- {
- src = LOAD_RM16(modrm);
- STORE_REG16(modrm, src);
- }
- CYCLES(1); // TODO: correct cycle count
- }
- else
- {
- UINT32 ea = GetEA(modrm,0);
- if (cpustate->SF == 0)
- {
- src = READ16(ea);
- STORE_REG16(modrm, src);
- }
- CYCLES(1); // TODO: correct cycle count
- }
-}
-
- void I386_OPS_BASE::PENTIUMOP(cmovns_r32_rm32)() // Opcode 0x0f 49
-{
- UINT32 src;
- UINT8 modrm = FETCH();
-
- if( modrm >= 0xc0 )
- {
- if (cpustate->SF == 0)
- {
- src = LOAD_RM32(modrm);
- STORE_REG32(modrm, src);
- }
- CYCLES(1); // TODO: correct cycle count
- }
- else
- {
- UINT32 ea = GetEA(modrm,0);
- if (cpustate->SF == 0)
- {
- src = READ32(ea);
- STORE_REG32(modrm, src);
- }
- CYCLES(1); // TODO: correct cycle count
- }
-}
-
- void I386_OPS_BASE::PENTIUMOP(cmovp_r16_rm16)() // Opcode 0x0f 4a
-{
- UINT16 src;
- UINT8 modrm = FETCH();
-
- if( modrm >= 0xc0 )
- {
- if (cpustate->PF == 1)
- {
- src = LOAD_RM16(modrm);
- STORE_REG16(modrm, src);
- }
- CYCLES(1); // TODO: correct cycle count
- }
- else
- {
- UINT32 ea = GetEA(modrm,0);
- if (cpustate->PF == 1)
- {
- src = READ16(ea);
- STORE_REG16(modrm, src);
- }
- CYCLES(1); // TODO: correct cycle count
- }
-}
-
- void I386_OPS_BASE::PENTIUMOP(cmovp_r32_rm32)() // Opcode 0x0f 4a
-{
- UINT32 src;
- UINT8 modrm = FETCH();
-
- if( modrm >= 0xc0 )
- {
- if (cpustate->PF == 1)
- {
- src = LOAD_RM32(modrm);
- STORE_REG32(modrm, src);
- }
- CYCLES(1); // TODO: correct cycle count
- }
- else
- {
- UINT32 ea = GetEA(modrm,0);
- if (cpustate->PF == 1)
- {
- src = READ32(ea);
- STORE_REG32(modrm, src);
- }
- CYCLES(1); // TODO: correct cycle count
- }
-}
-
- void I386_OPS_BASE::PENTIUMOP(cmovnp_r16_rm16)() // Opcode 0x0f 4b
-{
- UINT16 src;
- UINT8 modrm = FETCH();
-
- if( modrm >= 0xc0 )
- {
- if (cpustate->PF == 0)
- {
- src = LOAD_RM16(modrm);
- STORE_REG16(modrm, src);
- }
- CYCLES(1); // TODO: correct cycle count
- }
- else
- {
- UINT32 ea = GetEA(modrm,0);
- if (cpustate->PF == 0)
- {
- src = READ16(ea);
- STORE_REG16(modrm, src);
- }
- CYCLES(1); // TODO: correct cycle count
- }
-}
-
- void I386_OPS_BASE::PENTIUMOP(cmovnp_r32_rm32)() // Opcode 0x0f 4b
-{
- UINT32 src;
- UINT8 modrm = FETCH();
-
- if( modrm >= 0xc0 )
- {
- if (cpustate->PF == 0)
- {
- src = LOAD_RM32(modrm);
- STORE_REG32(modrm, src);
- }
- CYCLES(1); // TODO: correct cycle count
- }
- else
- {
- UINT32 ea = GetEA(modrm,0);
- if (cpustate->PF == 0)
- {
- src = READ32(ea);
- STORE_REG32(modrm, src);
- }
- CYCLES(1); // TODO: correct cycle count
- }
-}
-
- void I386_OPS_BASE::PENTIUMOP(cmovl_r16_rm16)() // Opcode 0x0f 4c
-{
- UINT16 src;
- UINT8 modrm = FETCH();
-
- if( modrm >= 0xc0 )
- {
- if (cpustate->SF != cpustate->OF)
- {
- src = LOAD_RM16(modrm);
- STORE_REG16(modrm, src);
- }
- CYCLES(1); // TODO: correct cycle count
- }
- else
- {
- UINT32 ea = GetEA(modrm,0);
- if (cpustate->SF != cpustate->OF)
- {
- src = READ16(ea);
- STORE_REG16(modrm, src);
- }
- CYCLES(1); // TODO: correct cycle count
- }
-}
-
- void I386_OPS_BASE::PENTIUMOP(cmovl_r32_rm32)() // Opcode 0x0f 4c
-{
- UINT32 src;
- UINT8 modrm = FETCH();
-
- if( modrm >= 0xc0 )
- {
- if (cpustate->SF != cpustate->OF)
- {
- src = LOAD_RM32(modrm);
- STORE_REG32(modrm, src);
- }
- CYCLES(1); // TODO: correct cycle count
- }
- else
- {
- UINT32 ea = GetEA(modrm,0);
- if (cpustate->SF != cpustate->OF)
- {
- src = READ32(ea);
- STORE_REG32(modrm, src);
- }
- CYCLES(1); // TODO: correct cycle count
- }
-}
-
- void I386_OPS_BASE::PENTIUMOP(cmovge_r16_rm16)() // Opcode 0x0f 4d
-{
- UINT16 src;
- UINT8 modrm = FETCH();
-
- if( modrm >= 0xc0 )
- {
- if (cpustate->SF == cpustate->OF)
- {
- src = LOAD_RM16(modrm);
- STORE_REG16(modrm, src);
- }
- CYCLES(1); // TODO: correct cycle count
- }
- else
- {
- UINT32 ea = GetEA(modrm,0);
- if (cpustate->SF == cpustate->OF)
- {
- src = READ16(ea);
- STORE_REG16(modrm, src);
- }
- CYCLES(1); // TODO: correct cycle count
- }
-}
-
- void I386_OPS_BASE::PENTIUMOP(cmovge_r32_rm32)() // Opcode 0x0f 4d
-{
- UINT32 src;
- UINT8 modrm = FETCH();
-
- if( modrm >= 0xc0 )
- {
- if (cpustate->SF == cpustate->OF)
- {
- src = LOAD_RM32(modrm);
- STORE_REG32(modrm, src);
- }
- CYCLES(1); // TODO: correct cycle count
- }
- else
- {
- UINT32 ea = GetEA(modrm,0);
- if (cpustate->SF == cpustate->OF)
- {
- src = READ32(ea);
- STORE_REG32(modrm, src);
- }
- CYCLES(1); // TODO: correct cycle count
- }
-}
-
- void I386_OPS_BASE::PENTIUMOP(cmovle_r16_rm16)() // Opcode 0x0f 4e
-{
- UINT16 src;
- UINT8 modrm = FETCH();
-
- if( modrm >= 0xc0 )
- {
- if ((cpustate->ZF == 1) || (cpustate->SF != cpustate->OF))
- {
- src = LOAD_RM16(modrm);
- STORE_REG16(modrm, src);
- }
- CYCLES(1); // TODO: correct cycle count
- }
- else
- {
- UINT32 ea = GetEA(modrm,0);
- if ((cpustate->ZF == 1) || (cpustate->SF != cpustate->OF))
- {
- src = READ16(ea);
- STORE_REG16(modrm, src);
- }
- CYCLES(1); // TODO: correct cycle count
- }
-}
-
- void I386_OPS_BASE::PENTIUMOP(cmovle_r32_rm32)() // Opcode 0x0f 4e
-{
- UINT32 src;
- UINT8 modrm = FETCH();
-
- if( modrm >= 0xc0 )
- {
- if ((cpustate->ZF == 1) || (cpustate->SF != cpustate->OF))
- {
- src = LOAD_RM32(modrm);
- STORE_REG32(modrm, src);
- }
- CYCLES(1); // TODO: correct cycle count
- }
- else
- {
- UINT32 ea = GetEA(modrm,0);
- if ((cpustate->ZF == 1) || (cpustate->SF != cpustate->OF))
- {
- src = READ32(ea);
- STORE_REG32(modrm, src);
- }
- CYCLES(1); // TODO: correct cycle count
- }
-}
-
- void I386_OPS_BASE::PENTIUMOP(cmovg_r16_rm16)() // Opcode 0x0f 4f
-{
- UINT16 src;
- UINT8 modrm = FETCH();
-
- if( modrm >= 0xc0 )
- {
- if ((cpustate->ZF == 0) && (cpustate->SF == cpustate->OF))
- {
- src = LOAD_RM16(modrm);
- STORE_REG16(modrm, src);
- }
- CYCLES(1); // TODO: correct cycle count
- }
- else
- {
- UINT32 ea = GetEA(modrm,0);
- if ((cpustate->ZF == 0) && (cpustate->SF == cpustate->OF))
- {
- src = READ16(ea);
- STORE_REG16(modrm, src);
- }
- CYCLES(1); // TODO: correct cycle count
- }
-}
-
- void I386_OPS_BASE::PENTIUMOP(cmovg_r32_rm32)() // Opcode 0x0f 4f
-{
- UINT32 src;
- UINT8 modrm = FETCH();
-
- if( modrm >= 0xc0 )
- {
- if ((cpustate->ZF == 0) && (cpustate->SF == cpustate->OF))
- {
- src = LOAD_RM32(modrm);
- STORE_REG32(modrm, src);
- }
- CYCLES(1); // TODO: correct cycle count
- }
- else
- {
- UINT32 ea = GetEA(modrm,0);
- if ((cpustate->ZF == 0) && (cpustate->SF == cpustate->OF))
- {
- src = READ32(ea);
- STORE_REG32(modrm, src);
- }
- CYCLES(1); // TODO: correct cycle count
- }
-}
-
- void I386_OPS_BASE::PENTIUMOP(movnti_m16_r16)() // Opcode 0f c3
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- // unsupported by cpu
- CYCLES(1); // TODO: correct cycle count
- } else {
- // since cache is not implemented
- UINT32 ea = GetEA(modrm, 0);
- WRITE16(ea,LOAD_RM16(modrm));
- CYCLES(1); // TODO: correct cycle count
- }
-}
-
- void I386_OPS_BASE::PENTIUMOP(movnti_m32_r32)() // Opcode 0f c3
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- // unsupported by cpu
- CYCLES(1); // TODO: correct cycle count
- } else {
- // since cache is not implemented
- UINT32 ea = GetEA(modrm, 0);
- WRITE32(ea,LOAD_RM32(modrm));
- CYCLES(1); // TODO: correct cycle count
- }
-}
-
- void I386OP(cyrix_special)() // Opcode 0x0f 3a-3d
-{
-/*
-0f 3a BB0_RESET (set BB0 pointer = base)
-0f 3b BB1_RESET (set BB1 pointer = base)
-0f 3c CPU_WRITE (write special CPU memory-mapped register, [ebx] = eax)
-0f 3d CPU_READ (read special CPU memory-mapped register, eax, = [ebx])
-*/
-
- CYCLES(1);
-}
-
- void I386OP(cyrix_unknown)() // Opcode 0x0f 74
-{
- logerror("Unemulated 0x0f 0x74 opcode called\n");
-
- CYCLES(1);
-}
-
- void I386_OPS_BASE::PENTIUMOP(cmpxchg8b_m64)() // Opcode 0x0f c7
-{
- UINT8 modm = FETCH();
- if( modm >= 0xc0 ) {
- report_invalid_modrm( "cmpxchg8b_m64", modm);
- } else {
- UINT32 ea = GetEA(modm, 0);
- UINT64 value = READ64( ea);
- UINT64 edx_eax = (((UINT64) REG32(EDX)) << 32) | REG32(EAX);
- UINT64 ecx_ebx = (((UINT64) REG32(ECX)) << 32) | REG32(EBX);
-
- if( value == edx_eax ) {
- WRITE64( ea, ecx_ebx);
- cpustate->ZF = 1;
- CYCLES(CYCLES_CMPXCHG_REG_MEM_T);
- } else {
- REG32(EDX) = (UINT32) (value >> 32);
- REG32(EAX) = (UINT32) (value >> 0);
- cpustate->ZF = 0;
- CYCLES(CYCLES_CMPXCHG_REG_MEM_F);
- }
- }
-}
-
- void I386_OPS_BASE::PENTIUMOP(movntq_m64_r64)() // Opcode 0f e7
-{
- //MMXPROLOG(); // TODO: check if needed
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- CYCLES(1); // unsupported
- } else {
- // since cache is not implemented
- UINT32 ea = GetEA(modrm, 0);
- WRITEMMX( ea, MMX((modrm >> 3) & 0x7));
- CYCLES(1); // TODO: correct cycle count
- }
-}
-
- void I386_OPS_BASE::PENTIUMOP(maskmovq_r64_r64)() // Opcode 0f f7
-{
- int s,m,n;
- UINT8 modm = FETCH();
- UINT32 ea = GetEA(7, 0); // ds:di/edi/rdi register
- MMXPROLOG();
- s=(modm >> 3) & 7;
- m=modm & 7;
- for (n=0;n <= 7;n++)
- if (MMX(m).b[n] & 127)
- WRITE8(ea+n, MMX(s).b[n]);
-}
-
- void I386_OPS_BASE::SSEOP(maskmovdqu_r128_r128)() // Opcode 66 0f f7
-{
- int s,m,n;
- UINT8 modm = FETCH();
- UINT32 ea = GetEA(7, 0); // ds:di/edi/rdi register
- s=(modm >> 3) & 7;
- m=modm & 7;
- for (n=0;n < 16;n++)
- if (XMM(m).b[n] & 127)
- WRITE8(ea+n, XMM(s).b[n]);
-}
-
- void I386_OPS_BASE::PENTIUMOP(popcnt_r16_rm16)() // Opcode f3 0f b8
-{
- UINT16 src;
- UINT8 modrm = FETCH();
- int n,count;
-
- if( modrm >= 0xc0 ) {
- src = LOAD_RM16(modrm);
- } else {
- UINT32 ea = GetEA(modrm,0);
- src = READ16(ea);
- }
- count=0;
- for (n=0;n < 16;n++) {
- count=count+(src & 1);
- src=src >> 1;
- }
- STORE_REG16(modrm, count);
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::PENTIUMOP(popcnt_r32_rm32)() // Opcode f3 0f b8
-{
- UINT32 src;
- UINT8 modrm = FETCH();
- int n,count;
-
- if( modrm >= 0xc0 ) {
- src = LOAD_RM32(modrm);
- } else {
- UINT32 ea = GetEA(modrm,0);
- src = READ32(ea);
- }
- count=0;
- for (n=0;n < 32;n++) {
- count=count+(src & 1);
- src=src >> 1;
- }
- STORE_REG32(modrm, count);
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::PENTIUMOP(tzcnt_r16_rm16)()
-{
- // for CPUs that don't support TZCNT, fall back to BSF
- i386_bsf_r16_rm16();
- // TODO: actually implement TZCNT
-}
-
- void I386_OPS_BASE::PENTIUMOP(tzcnt_r32_rm32)()
-{
- // for CPUs that don't support TZCNT, fall back to BSF
- i386_bsf_r32_rm32();
- // TODO: actually implement TZCNT
-}
-
-INLINE INT8 I386_OPS_BASE::SaturatedSignedWordToSignedByte(INT16 word)
-{
- if (word > 127)
- return 127;
- if (word < -128)
- return -128;
- return (INT8)word;
-}
-
-INLINE UINT8 I386_OPS_BASE::SaturatedSignedWordToUnsignedByte(INT16 word)
-{
- if (word > 255)
- return 255;
- if (word < 0)
- return 0;
- return (UINT8)word;
-}
-
-INLINE INT16 I386_OPS_BASE::SaturatedSignedDwordToSignedWord(INT32 dword)
-{
- if (dword > 32767)
- return 32767;
- if (dword < -32768)
- return -32768;
- return (INT16)dword;
-}
-
-INLINE UINT16 I386_OPS_BASE::SaturatedSignedDwordToUnsignedWord(INT32 dword)
-{
- if (dword > 65535)
- return 65535;
- if (dword < 0)
- return 0;
- return (UINT16)dword;
-}
-
- void I386_OPS_BASE::MMXOP(group_0f71)() // Opcode 0f 71
-{
- UINT8 modm = FETCH();
- UINT8 imm8 = FETCH();
- MMXPROLOG();
- if( modm >= 0xc0 ) {
- switch ( (modm & 0x38) >> 3 )
- {
- case 2: // psrlw
- MMX(modm & 7).w[0]=MMX(modm & 7).w[0] >> imm8;
- MMX(modm & 7).w[1]=MMX(modm & 7).w[1] >> imm8;
- MMX(modm & 7).w[2]=MMX(modm & 7).w[2] >> imm8;
- MMX(modm & 7).w[3]=MMX(modm & 7).w[3] >> imm8;
- break;
- case 4: // psraw
- MMX(modm & 7).s[0]=MMX(modm & 7).s[0] >> imm8;
- MMX(modm & 7).s[1]=MMX(modm & 7).s[1] >> imm8;
- MMX(modm & 7).s[2]=MMX(modm & 7).s[2] >> imm8;
- MMX(modm & 7).s[3]=MMX(modm & 7).s[3] >> imm8;
- break;
- case 6: // psllw
- MMX(modm & 7).w[0]=MMX(modm & 7).w[0] << imm8;
- MMX(modm & 7).w[1]=MMX(modm & 7).w[1] << imm8;
- MMX(modm & 7).w[2]=MMX(modm & 7).w[2] << imm8;
- MMX(modm & 7).w[3]=MMX(modm & 7).w[3] << imm8;
- break;
- default:
- report_invalid_modrm( "mmx_group0f71", modm);
- }
- }
-}
-
- void I386_OPS_BASE::I386_OPS_BASE::SSEOP(group_660f71)() // Opcode 66 0f 71
-{
- UINT8 modm = FETCH();
- UINT8 imm8 = FETCH();
- if (modm >= 0xc0) {
- switch ((modm & 0x38) >> 3)
- {
- case 2: // psrlw
- for (int n = 0; n < 8;n++)
- XMM(modm & 7).w[n] = XMM(modm & 7).w[n] >> imm8;
- break;
- case 4: // psraw
- for (int n = 0; n < 8;n++)
- XMM(modm & 7).s[n] = XMM(modm & 7).s[n] >> imm8;
- break;
- case 6: // psllw
- for (int n = 0; n < 8;n++)
- XMM(modm & 7).w[n] = XMM(modm & 7).w[n] << imm8;
- break;
- default:
- report_invalid_modrm( "mmx_group660f71", modm);
- }
- }
-}
-
- void I386_OPS_BASE::MMXOP(group_0f72)() // Opcode 0f 72
-{
- UINT8 modm = FETCH();
- UINT8 imm8 = FETCH();
- MMXPROLOG();
- if( modm >= 0xc0 ) {
- switch ( (modm & 0x38) >> 3 )
- {
- case 2: // psrld
- MMX(modm & 7).d[0]=MMX(modm & 7).d[0] >> imm8;
- MMX(modm & 7).d[1]=MMX(modm & 7).d[1] >> imm8;
- break;
- case 4: // psrad
- MMX(modm & 7).i[0]=MMX(modm & 7).i[0] >> imm8;
- MMX(modm & 7).i[1]=MMX(modm & 7).i[1] >> imm8;
- break;
- case 6: // pslld
- MMX(modm & 7).d[0]=MMX(modm & 7).d[0] << imm8;
- MMX(modm & 7).d[1]=MMX(modm & 7).d[1] << imm8;
- break;
- default:
- report_invalid_modrm( "mmx_group0f72", modm);
- }
- }
-}
-
- void I386_OPS_BASE::SSEOP(group_660f72)() // Opcode 66 0f 72
-{
- UINT8 modm = FETCH();
- UINT8 imm8 = FETCH();
- if (modm >= 0xc0) {
- switch ((modm & 0x38) >> 3)
- {
- case 2: // psrld
- for (int n = 0; n < 4;n++)
- XMM(modm & 7).d[n] = XMM(modm & 7).d[n] >> imm8;
- break;
- case 4: // psrad
- for (int n = 0; n < 4;n++)
- XMM(modm & 7).i[n] = XMM(modm & 7).i[n] >> imm8;
- break;
- case 6: // pslld
- for (int n = 0; n < 4;n++)
- XMM(modm & 7).d[n] = XMM(modm & 7).d[n] << imm8;
- break;
- default:
- report_invalid_modrm( "mmx_group660f72", modm);
- }
- }
-}
-
- void I386_OPS_BASE::MMXOP(group_0f73)() // Opcode 0f 73
-{
- UINT8 modm = FETCH();
- UINT8 imm8 = FETCH();
- MMXPROLOG();
- if( modm >= 0xc0 ) {
- switch ( (modm & 0x38) >> 3 )
- {
- case 2: // psrlq
- MMX(modm & 7).q = imm8 > 63 ? 0 : MMX(modm & 7).q >> imm8;
- break;
- case 6: // psllq
- MMX(modm & 7).q = imm8 > 63 ? 0 : MMX(modm & 7).q << imm8;
- break;
- default:
- report_invalid_modrm( "mmx_group0f73", modm);
- }
- }
-}
-
- void I386_OPS_BASE::SSEOP(group_660f73)() // Opcode 66 0f 73
-{
- UINT64 t0;
- UINT8 modm = FETCH();
- UINT8 imm8 = FETCH();
- if (modm >= 0xc0) {
- switch ((modm & 0x38) >> 3)
- {
- case 2: // psrlq
- XMM(modm & 7).q[0] = imm8 > 63 ? 0 : XMM(modm & 7).q[0] >> imm8;
- XMM(modm & 7).q[1] = imm8 > 63 ? 0 : XMM(modm & 7).q[1] >> imm8;
- break;
- case 3: // psrldq
- if (imm8 >= 16)
- {
- XMM(modm & 7).q[0] = 0;
- XMM(modm & 7).q[1] = 0;
- }
- else if (imm8 >= 8)
- {
- imm8 = (imm8 & 7) << 3;
- XMM(modm & 7).q[0] = XMM(modm & 7).q[1] >> imm8;
- XMM(modm & 7).q[1] = 0;
- }
- else if (imm8)
- {
- t0 = XMM(modm & 7).q[0];
- imm8 = imm8 << 3;
- XMM(modm & 7).q[0] = (XMM(modm & 7).q[1] << (64 - imm8)) | (t0 >> imm8);
- XMM(modm & 7).q[1] = t0 >> imm8;
- }
- break;
- case 6: // psllq
- XMM(modm & 7).q[0] = imm8 > 63 ? 0 : XMM(modm & 7).q[0] << imm8;
- XMM(modm & 7).q[1] = imm8 > 63 ? 0 : XMM(modm & 7).q[1] << imm8;
- break;
- case 7: // pslldq
- if (imm8 >= 16)
- {
- XMM(modm & 7).q[0] = 0;
- XMM(modm & 7).q[1] = 0;
- }
- else if (imm8 >= 8)
- {
- imm8 = (imm8 & 7) << 3;
- XMM(modm & 7).q[1] = XMM(modm & 7).q[0] << imm8;
- XMM(modm & 7).q[0] = 0;
- }
- else if (imm8)
- {
- imm8 = imm8 << 3;
- XMM(modm & 7).q[1] = (XMM(modm & 7).q[0] >> (64 - imm8)) | (XMM(modm & 7).q[1] << imm8);
- XMM(modm & 7).q[0] = XMM(modm & 7).q[0] << imm8;
- }
- break;
- default:
- report_invalid_modrm( "sse_group660f73", modm);
- }
- }
-}
-
- void I386_OPS_BASE::MMXOP(psrlw_r64_rm64)() // Opcode 0f d1
-{
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- int count=(int)MMX(modrm & 7).q;
- MMX((modrm >> 3) & 0x7).w[0]=MMX((modrm >> 3) & 0x7).w[0] >> count;
- MMX((modrm >> 3) & 0x7).w[1]=MMX((modrm >> 3) & 0x7).w[1] >> count;
- MMX((modrm >> 3) & 0x7).w[2]=MMX((modrm >> 3) & 0x7).w[2] >> count;
- MMX((modrm >> 3) & 0x7).w[3]=MMX((modrm >> 3) & 0x7).w[3] >> count;
- } else {
- MMX_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READMMX( ea, src);
- int count=(int)src.q;
- MMX((modrm >> 3) & 0x7).w[0]=MMX((modrm >> 3) & 0x7).w[0] >> count;
- MMX((modrm >> 3) & 0x7).w[1]=MMX((modrm >> 3) & 0x7).w[1] >> count;
- MMX((modrm >> 3) & 0x7).w[2]=MMX((modrm >> 3) & 0x7).w[2] >> count;
- MMX((modrm >> 3) & 0x7).w[3]=MMX((modrm >> 3) & 0x7).w[3] >> count;
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::MMXOP(psrld_r64_rm64)() // Opcode 0f d2
-{
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- int count=(int)MMX(modrm & 7).q;
- MMX((modrm >> 3) & 0x7).d[0]=MMX((modrm >> 3) & 0x7).d[0] >> count;
- MMX((modrm >> 3) & 0x7).d[1]=MMX((modrm >> 3) & 0x7).d[1] >> count;
- } else {
- MMX_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READMMX( ea, src);
- int count=(int)src.q;
- MMX((modrm >> 3) & 0x7).d[0]=MMX((modrm >> 3) & 0x7).d[0] >> count;
- MMX((modrm >> 3) & 0x7).d[1]=MMX((modrm >> 3) & 0x7).d[1] >> count;
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::MMXOP(psrlq_r64_rm64)() // Opcode 0f d3
-{
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- int count=(int)MMX(modrm & 7).q;
- MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q >> count;
- } else {
- MMX_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READMMX( ea, src);
- int count=(int)src.q;
- MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q >> count;
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::MMXOP(paddq_r64_rm64)() // Opcode 0f d4
-{
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q+MMX(modrm & 7).q;
- } else {
- MMX_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READMMX( ea, src);
- MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q+src.q;
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::MMXOP(pmullw_r64_rm64)() // Opcode 0f d5
-{
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- MMX((modrm >> 3) & 0x7).w[0]=(UINT32)((INT32)MMX((modrm >> 3) & 0x7).s[0]*(INT32)MMX(modrm & 7).s[0]) & 0xffff;
- MMX((modrm >> 3) & 0x7).w[1]=(UINT32)((INT32)MMX((modrm >> 3) & 0x7).s[1]*(INT32)MMX(modrm & 7).s[1]) & 0xffff;
- MMX((modrm >> 3) & 0x7).w[2]=(UINT32)((INT32)MMX((modrm >> 3) & 0x7).s[2]*(INT32)MMX(modrm & 7).s[2]) & 0xffff;
- MMX((modrm >> 3) & 0x7).w[3]=(UINT32)((INT32)MMX((modrm >> 3) & 0x7).s[3]*(INT32)MMX(modrm & 7).s[3]) & 0xffff;
- } else {
- MMX_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READMMX( ea, src);
- MMX((modrm >> 3) & 0x7).w[0]=(UINT32)((INT32)MMX((modrm >> 3) & 0x7).s[0]*(INT32)src.s[0]) & 0xffff;
- MMX((modrm >> 3) & 0x7).w[1]=(UINT32)((INT32)MMX((modrm >> 3) & 0x7).s[1]*(INT32)src.s[1]) & 0xffff;
- MMX((modrm >> 3) & 0x7).w[2]=(UINT32)((INT32)MMX((modrm >> 3) & 0x7).s[2]*(INT32)src.s[2]) & 0xffff;
- MMX((modrm >> 3) & 0x7).w[3]=(UINT32)((INT32)MMX((modrm >> 3) & 0x7).s[3]*(INT32)src.s[3]) & 0xffff;
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::MMXOP(psubusb_r64_rm64)() // Opcode 0f d8
-{
- int n;
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- for (n=0;n < 8;n++)
- MMX((modrm >> 3) & 0x7).b[n]=MMX((modrm >> 3) & 0x7).b[n] < MMX(modrm & 7).b[n] ? 0 : MMX((modrm >> 3) & 0x7).b[n]-MMX(modrm & 7).b[n];
- } else {
- MMX_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READMMX( ea, src);
- for (n=0;n < 8;n++)
- MMX((modrm >> 3) & 0x7).b[n]=MMX((modrm >> 3) & 0x7).b[n] < src.b[n] ? 0 : MMX((modrm >> 3) & 0x7).b[n]-src.b[n];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::MMXOP(psubusw_r64_rm64)() // Opcode 0f d9
-{
- int n;
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- for (n=0;n < 4;n++)
- MMX((modrm >> 3) & 0x7).w[n]=MMX((modrm >> 3) & 0x7).w[n] < MMX(modrm & 7).w[n] ? 0 : MMX((modrm >> 3) & 0x7).w[n]-MMX(modrm & 7).w[n];
- } else {
- MMX_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READMMX( ea, src);
- for (n=0;n < 4;n++)
- MMX((modrm >> 3) & 0x7).w[n]=MMX((modrm >> 3) & 0x7).w[n] < src.w[n] ? 0 : MMX((modrm >> 3) & 0x7).w[n]-src.w[n];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::MMXOP(pand_r64_rm64)() // Opcode 0f db
-{
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q & MMX(modrm & 7).q;
- } else {
- MMX_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READMMX( ea, src);
- MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q & src.q;
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::MMXOP(paddusb_r64_rm64)() // Opcode 0f dc
-{
- int n;
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- for (n=0;n < 8;n++)
- MMX((modrm >> 3) & 0x7).b[n]=MMX((modrm >> 3) & 0x7).b[n] > (0xff-MMX(modrm & 7).b[n]) ? 0xff : MMX((modrm >> 3) & 0x7).b[n]+MMX(modrm & 7).b[n];
- } else {
- MMX_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READMMX( ea, src);
- for (n=0;n < 8;n++)
- MMX((modrm >> 3) & 0x7).b[n]=MMX((modrm >> 3) & 0x7).b[n] > (0xff-src.b[n]) ? 0xff : MMX((modrm >> 3) & 0x7).b[n]+src.b[n];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::MMXOP(paddusw_r64_rm64)() // Opcode 0f dd
-{
- int n;
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- for (n=0;n < 4;n++)
- MMX((modrm >> 3) & 0x7).w[n]=MMX((modrm >> 3) & 0x7).w[n] > (0xffff-MMX(modrm & 7).w[n]) ? 0xffff : MMX((modrm >> 3) & 0x7).w[n]+MMX(modrm & 7).w[n];
- } else {
- MMX_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READMMX( ea, src);
- for (n=0;n < 4;n++)
- MMX((modrm >> 3) & 0x7).w[n]=MMX((modrm >> 3) & 0x7).w[n] > (0xffff-src.w[n]) ? 0xffff : MMX((modrm >> 3) & 0x7).w[n]+src.w[n];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::MMXOP(pandn_r64_rm64)() // Opcode 0f df
-{
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- MMX((modrm >> 3) & 0x7).q=(~MMX((modrm >> 3) & 0x7).q) & MMX(modrm & 7).q;
- } else {
- MMX_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READMMX( ea, src);
- MMX((modrm >> 3) & 0x7).q=(~MMX((modrm >> 3) & 0x7).q) & src.q;
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::MMXOP(psraw_r64_rm64)() // Opcode 0f e1
-{
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- int count=(int)MMX(modrm & 7).q;
- MMX((modrm >> 3) & 0x7).s[0]=MMX((modrm >> 3) & 0x7).s[0] >> count;
- MMX((modrm >> 3) & 0x7).s[1]=MMX((modrm >> 3) & 0x7).s[1] >> count;
- MMX((modrm >> 3) & 0x7).s[2]=MMX((modrm >> 3) & 0x7).s[2] >> count;
- MMX((modrm >> 3) & 0x7).s[3]=MMX((modrm >> 3) & 0x7).s[3] >> count;
- } else {
- MMX_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READMMX( ea, src);
- int count=(int)src.q;
- MMX((modrm >> 3) & 0x7).s[0]=MMX((modrm >> 3) & 0x7).s[0] >> count;
- MMX((modrm >> 3) & 0x7).s[1]=MMX((modrm >> 3) & 0x7).s[1] >> count;
- MMX((modrm >> 3) & 0x7).s[2]=MMX((modrm >> 3) & 0x7).s[2] >> count;
- MMX((modrm >> 3) & 0x7).s[3]=MMX((modrm >> 3) & 0x7).s[3] >> count;
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::MMXOP(psrad_r64_rm64)() // Opcode 0f e2
-{
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- int count=(int)MMX(modrm & 7).q;
- MMX((modrm >> 3) & 0x7).i[0]=MMX((modrm >> 3) & 0x7).i[0] >> count;
- MMX((modrm >> 3) & 0x7).i[1]=MMX((modrm >> 3) & 0x7).i[1] >> count;
- } else {
- MMX_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READMMX( ea, src);
- int count=(int)src.q;
- MMX((modrm >> 3) & 0x7).i[0]=MMX((modrm >> 3) & 0x7).i[0] >> count;
- MMX((modrm >> 3) & 0x7).i[1]=MMX((modrm >> 3) & 0x7).i[1] >> count;
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::MMXOP(pmulhw_r64_rm64)() // Opcode 0f e5
-{
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- MMX((modrm >> 3) & 0x7).w[0]=(UINT32)((INT32)MMX((modrm >> 3) & 0x7).s[0]*(INT32)MMX(modrm & 7).s[0]) >> 16;
- MMX((modrm >> 3) & 0x7).w[1]=(UINT32)((INT32)MMX((modrm >> 3) & 0x7).s[1]*(INT32)MMX(modrm & 7).s[1]) >> 16;
- MMX((modrm >> 3) & 0x7).w[2]=(UINT32)((INT32)MMX((modrm >> 3) & 0x7).s[2]*(INT32)MMX(modrm & 7).s[2]) >> 16;
- MMX((modrm >> 3) & 0x7).w[3]=(UINT32)((INT32)MMX((modrm >> 3) & 0x7).s[3]*(INT32)MMX(modrm & 7).s[3]) >> 16;
- } else {
- MMX_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READMMX( ea, src);
- MMX((modrm >> 3) & 0x7).w[0]=(UINT32)((INT32)MMX((modrm >> 3) & 0x7).s[0]*(INT32)src.s[0]) >> 16;
- MMX((modrm >> 3) & 0x7).w[1]=(UINT32)((INT32)MMX((modrm >> 3) & 0x7).s[1]*(INT32)src.s[1]) >> 16;
- MMX((modrm >> 3) & 0x7).w[2]=(UINT32)((INT32)MMX((modrm >> 3) & 0x7).s[2]*(INT32)src.s[2]) >> 16;
- MMX((modrm >> 3) & 0x7).w[3]=(UINT32)((INT32)MMX((modrm >> 3) & 0x7).s[3]*(INT32)src.s[3]) >> 16;
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::MMXOP(psubsb_r64_rm64)() // Opcode 0f e8
-{
- int n;
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- for (n=0;n < 8;n++)
- MMX((modrm >> 3) & 0x7).c[n]=SaturatedSignedWordToSignedByte((INT16)MMX((modrm >> 3) & 0x7).c[n] - (INT16)MMX(modrm & 7).c[n]);
- } else {
- MMX_REG s;
- UINT32 ea = GetEA(modrm, 0);
- READMMX( ea, s);
- for (n=0;n < 8;n++)
- MMX((modrm >> 3) & 0x7).c[n]=SaturatedSignedWordToSignedByte((INT16)MMX((modrm >> 3) & 0x7).c[n] - (INT16)s.c[n]);
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::MMXOP(psubsw_r64_rm64)() // Opcode 0f e9
-{
- int n;
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- for (n=0;n < 4;n++)
- MMX((modrm >> 3) & 0x7).s[n]=SaturatedSignedDwordToSignedWord((INT32)MMX((modrm >> 3) & 0x7).s[n] - (INT32)MMX(modrm & 7).s[n]);
- } else {
- MMX_REG s;
- UINT32 ea = GetEA(modrm, 0);
- READMMX( ea, s);
- for (n=0;n < 4;n++)
- MMX((modrm >> 3) & 0x7).s[n]=SaturatedSignedDwordToSignedWord((INT32)MMX((modrm >> 3) & 0x7).s[n] - (INT32)s.s[n]);
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::MMXOP(por_r64_rm64)() // Opcode 0f eb
-{
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q | MMX(modrm & 7).q;
- } else {
- MMX_REG s;
- UINT32 ea = GetEA(modrm, 0);
- READMMX( ea, s);
- MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q | s.q;
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::MMXOP(paddsb_r64_rm64)() // Opcode 0f ec
-{
- int n;
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- for (n=0;n < 8;n++)
- MMX((modrm >> 3) & 0x7).c[n]=SaturatedSignedWordToSignedByte((INT16)MMX((modrm >> 3) & 0x7).c[n] + (INT16)MMX(modrm & 7).c[n]);
- } else {
- MMX_REG s;
- UINT32 ea = GetEA(modrm, 0);
- READMMX( ea, s);
- for (n=0;n < 8;n++)
- MMX((modrm >> 3) & 0x7).c[n]=SaturatedSignedWordToSignedByte((INT16)MMX((modrm >> 3) & 0x7).c[n] + (INT16)s.c[n]);
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::MMXOP(paddsw_r64_rm64)() // Opcode 0f ed
-{
- int n;
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- for (n=0;n < 4;n++)
- MMX((modrm >> 3) & 0x7).s[n]=SaturatedSignedDwordToSignedWord((INT32)MMX((modrm >> 3) & 0x7).s[n] + (INT32)MMX(modrm & 7).s[n]);
- } else {
- MMX_REG s;
- UINT32 ea = GetEA(modrm, 0);
- READMMX( ea, s);
- for (n=0;n < 4;n++)
- MMX((modrm >> 3) & 0x7).s[n]=SaturatedSignedDwordToSignedWord((INT32)MMX((modrm >> 3) & 0x7).s[n] + (INT32)s.s[n]);
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::MMXOP(pxor_r64_rm64)() // Opcode 0f ef
-{
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q ^ MMX(modrm & 7).q;
- } else {
- MMX_REG s;
- UINT32 ea = GetEA(modrm, 0);
- READMMX( ea, s);
- MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q ^ s.q;
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::MMXOP(psllw_r64_rm64)() // Opcode 0f f1
-{
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- int count=(int)MMX(modrm & 7).q;
- MMX((modrm >> 3) & 0x7).w[0]=MMX((modrm >> 3) & 0x7).w[0] << count;
- MMX((modrm >> 3) & 0x7).w[1]=MMX((modrm >> 3) & 0x7).w[1] << count;
- MMX((modrm >> 3) & 0x7).w[2]=MMX((modrm >> 3) & 0x7).w[2] << count;
- MMX((modrm >> 3) & 0x7).w[3]=MMX((modrm >> 3) & 0x7).w[3] << count;
- } else {
- MMX_REG s;
- UINT32 ea = GetEA(modrm, 0);
- READMMX( ea, s);
- int count=(int)s.q;
- MMX((modrm >> 3) & 0x7).w[0]=MMX((modrm >> 3) & 0x7).w[0] << count;
- MMX((modrm >> 3) & 0x7).w[1]=MMX((modrm >> 3) & 0x7).w[1] << count;
- MMX((modrm >> 3) & 0x7).w[2]=MMX((modrm >> 3) & 0x7).w[2] << count;
- MMX((modrm >> 3) & 0x7).w[3]=MMX((modrm >> 3) & 0x7).w[3] << count;
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::MMXOP(pslld_r64_rm64)() // Opcode 0f f2
-{
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- int count=(int)MMX(modrm & 7).q;
- MMX((modrm >> 3) & 0x7).d[0]=MMX((modrm >> 3) & 0x7).d[0] << count;
- MMX((modrm >> 3) & 0x7).d[1]=MMX((modrm >> 3) & 0x7).d[1] << count;
- } else {
- MMX_REG s;
- UINT32 ea = GetEA(modrm, 0);
- READMMX( ea, s);
- int count=(int)s.q;
- MMX((modrm >> 3) & 0x7).d[0]=MMX((modrm >> 3) & 0x7).d[0] << count;
- MMX((modrm >> 3) & 0x7).d[1]=MMX((modrm >> 3) & 0x7).d[1] << count;
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::MMXOP(psllq_r64_rm64)() // Opcode 0f f3
-{
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- int count=(int)MMX(modrm & 7).q;
- MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q << count;
- } else {
- MMX_REG s;
- UINT32 ea = GetEA(modrm, 0);
- READMMX( ea, s);
- int count=(int)s.q;
- MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q << count;
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::MMXOP(pmaddwd_r64_rm64)() // Opcode 0f f5
-{
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- MMX((modrm >> 3) & 0x7).i[0]=(INT32)MMX((modrm >> 3) & 0x7).s[0]*(INT32)MMX(modrm & 7).s[0]+
- (INT32)MMX((modrm >> 3) & 0x7).s[1]*(INT32)MMX(modrm & 7).s[1];
- MMX((modrm >> 3) & 0x7).i[1]=(INT32)MMX((modrm >> 3) & 0x7).s[2]*(INT32)MMX(modrm & 7).s[2]+
- (INT32)MMX((modrm >> 3) & 0x7).s[3]*(INT32)MMX(modrm & 7).s[3];
- } else {
- MMX_REG s;
- UINT32 ea = GetEA(modrm, 0);
- READMMX( ea, s);
- MMX((modrm >> 3) & 0x7).i[0]=(INT32)MMX((modrm >> 3) & 0x7).s[0]*(INT32)s.s[0]+
- (INT32)MMX((modrm >> 3) & 0x7).s[1]*(INT32)s.s[1];
- MMX((modrm >> 3) & 0x7).i[1]=(INT32)MMX((modrm >> 3) & 0x7).s[2]*(INT32)s.s[2]+
- (INT32)MMX((modrm >> 3) & 0x7).s[3]*(INT32)s.s[3];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::MMXOP(psubb_r64_rm64)() // Opcode 0f f8
-{
- int n;
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- for (n=0;n < 8;n++)
- MMX((modrm >> 3) & 0x7).b[n]=MMX((modrm >> 3) & 0x7).b[n] - MMX(modrm & 7).b[n];
- } else {
- MMX_REG s;
- UINT32 ea = GetEA(modrm, 0);
- READMMX( ea, s);
- for (n=0;n < 8;n++)
- MMX((modrm >> 3) & 0x7).b[n]=MMX((modrm >> 3) & 0x7).b[n] - s.b[n];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::MMXOP(psubw_r64_rm64)() // Opcode 0f f9
-{
- int n;
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- for (n=0;n < 4;n++)
- MMX((modrm >> 3) & 0x7).w[n]=MMX((modrm >> 3) & 0x7).w[n] - MMX(modrm & 7).w[n];
- } else {
- MMX_REG s;
- UINT32 ea = GetEA(modrm, 0);
- READMMX( ea, s);
- for (n=0;n < 4;n++)
- MMX((modrm >> 3) & 0x7).w[n]=MMX((modrm >> 3) & 0x7).w[n] - s.w[n];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::MMXOP(psubd_r64_rm64)() // Opcode 0f fa
-{
- int n;
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- for (n=0;n < 2;n++)
- MMX((modrm >> 3) & 0x7).d[n]=MMX((modrm >> 3) & 0x7).d[n] - MMX(modrm & 7).d[n];
- } else {
- MMX_REG s;
- UINT32 ea = GetEA(modrm, 0);
- READMMX( ea, s);
- for (n=0;n < 2;n++)
- MMX((modrm >> 3) & 0x7).d[n]=MMX((modrm >> 3) & 0x7).d[n] - s.d[n];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::MMXOP(paddb_r64_rm64)() // Opcode 0f fc
-{
- int n;
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- for (n=0;n < 8;n++)
- MMX((modrm >> 3) & 0x7).b[n]=MMX((modrm >> 3) & 0x7).b[n] + MMX(modrm & 7).b[n];
- } else {
- MMX_REG s;
- UINT32 ea = GetEA(modrm, 0);
- READMMX( ea, s);
- for (n=0;n < 8;n++)
- MMX((modrm >> 3) & 0x7).b[n]=MMX((modrm >> 3) & 0x7).b[n] + s.b[n];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::MMXOP(paddw_r64_rm64)() // Opcode 0f fd
-{
- int n;
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- for (n=0;n < 4;n++)
- MMX((modrm >> 3) & 0x7).w[n]=MMX((modrm >> 3) & 0x7).w[n] + MMX(modrm & 7).w[n];
- } else {
- MMX_REG s;
- UINT32 ea = GetEA(modrm, 0);
- READMMX( ea, s);
- for (n=0;n < 4;n++)
- MMX((modrm >> 3) & 0x7).w[n]=MMX((modrm >> 3) & 0x7).w[n] + s.w[n];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::MMXOP(paddd_r64_rm64)() // Opcode 0f fe
-{
- int n;
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- for (n=0;n < 2;n++)
- MMX((modrm >> 3) & 0x7).d[n]=MMX((modrm >> 3) & 0x7).d[n] + MMX(modrm & 7).d[n];
- } else {
- MMX_REG s;
- UINT32 ea = GetEA(modrm, 0);
- READMMX( ea, s);
- for (n=0;n < 2;n++)
- MMX((modrm >> 3) & 0x7).d[n]=MMX((modrm >> 3) & 0x7).d[n] + s.d[n];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::MMXOP(emms)() // Opcode 0f 77
-{
- cpustate->x87_tw = 0xffff; // tag word = 0xffff
- // TODO
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386OP(cyrix_svdc)() // Opcode 0f 78
-{
- UINT8 modrm = FETCH();
-
- if( modrm < 0xc0 ) {
- UINT32 ea = GetEA(modrm,0);
- int index = (modrm >> 3) & 7;
- int limit;
- switch (index)
- {
- case 0:
- {
- index = ES;
- break;
- }
-
- case 2:
- {
- index = SS;
- break;
- }
-
- case 3:
- {
- index = DS;
- break;
- }
-
- case 4:
- {
- index = FS;
- break;
- }
-
- case 5:
- {
- index = GS;
- break;
- }
-
- default:
- {
- i386_trap( 6, 0, 0);
- }
- }
-
- limit = cpustate->sreg[index].limit;
-
- if (cpustate->sreg[index].flags & 0x8000) //G bit
- {
- limit >>= 12;
- }
-
- WRITE16(ea + 0, limit);
- WRITE32(ea + 2, cpustate->sreg[index].base);
- WRITE16(ea + 5, cpustate->sreg[index].flags); //replace top 8 bits of base
- WRITE8(ea + 7, cpustate->sreg[index].base >> 24);
- WRITE16(ea + 8, cpustate->sreg[index].selector);
- } else {
- i386_trap( 6, 0, 0);
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386OP(cyrix_rsdc)() // Opcode 0f 79
-{
- UINT8 modrm = FETCH();
-
- if( modrm < 0xc0 ) {
- UINT32 ea = GetEA(modrm,0);
- int index = (modrm >> 3) & 7;
- UINT16 flags;
- UINT32 base;
- UINT32 limit;
- switch (index)
- {
- case 0:
- {
- index = ES;
- break;
- }
-
- case 2:
- {
- index = SS;
- break;
- }
-
- case 3:
- {
- index = DS;
- break;
- }
-
- case 4:
- {
- index = FS;
- break;
- }
-
- case 5:
- {
- index = GS;
- break;
- }
-
- default:
- {
- i386_trap( 6, 0, 0);
- }
- }
-
- base = (READ32(ea + 2) & 0x00ffffff) | (READ8(ea + 7) << 24);
- flags = READ16(ea + 5);
- limit = READ16(ea + 0) | ((flags & 3) << 16);
-
- if (flags & 0x8000) //G bit
- {
- limit = (limit << 12) | 0xfff;
- }
-
- cpustate->sreg[index].selector = READ16(ea + 8);
- cpustate->sreg[index].flags = flags;
- cpustate->sreg[index].base = base;
- cpustate->sreg[index].limit = limit;
- } else {
- i386_trap( 6, 0, 0);
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386OP(cyrix_svldt)() // Opcode 0f 7a
-{
- if ( PROTECTED_MODE && !V8086_MODE )
- {
- UINT8 modrm = FETCH();
-
- if( !(modrm & 0xf8) ) {
- UINT32 ea = GetEA(modrm,0);
- UINT32 limit = cpustate->ldtr.limit;
-
- if (cpustate->ldtr.flags & 0x8000) //G bit
- {
- limit >>= 12;
- }
-
- WRITE16(ea + 0, limit);
- WRITE32(ea + 2, cpustate->ldtr.base);
- WRITE16(ea + 5, cpustate->ldtr.flags); //replace top 8 bits of base
- WRITE8(ea + 7, cpustate->ldtr.base >> 24);
- WRITE16(ea + 8, cpustate->ldtr.segment);
- } else {
- i386_trap( 6, 0, 0);
- }
- } else {
- i386_trap( 6, 0, 0);
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386OP(cyrix_rsldt)() // Opcode 0f 7b
-{
- if ( PROTECTED_MODE && !V8086_MODE )
- {
- if(cpustate->CPL)
- FAULT(FAULT_GP,0)
-
- UINT8 modrm = FETCH();
-
- if( !(modrm & 0xf8) ) {
- UINT32 ea = GetEA(modrm,0);
- UINT16 flags = READ16(ea + 5);
- UINT32 base = (READ32(ea + 2) | 0x00ffffff) | (READ8(ea + 7) << 24);
- UINT32 limit = READ16(ea + 0) | ((flags & 3) << 16);
- I386_SREG seg;
-
- if (flags & 0x8000) //G bit
- {
- limit = (limit << 12) | 0xfff;
- }
-
- memset(&seg, 0, sizeof(seg));
- seg.selector = READ16(ea + 8);
- i386_load_protected_mode_segment(&seg,NULL);
- cpustate->ldtr.limit = limit;
- cpustate->ldtr.base = base;
- cpustate->ldtr.flags = flags;
- } else {
- i386_trap( 6, 0, 0);
- }
- } else {
- i386_trap( 6, 0, 0);
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386OP(cyrix_svts)() // Opcode 0f 7c
-{
- if ( PROTECTED_MODE )
- {
- UINT8 modrm = FETCH();
-
- if( !(modrm & 0xf8) ) {
- UINT32 ea = GetEA(modrm,0);
- UINT32 limit = cpustate->task.limit;
-
- if (cpustate->task.flags & 0x8000) //G bit
- {
- limit >>= 12;
- }
-
- WRITE16(ea + 0, limit);
- WRITE32(ea + 2, cpustate->task.base);
- WRITE16(ea + 5, cpustate->task.flags); //replace top 8 bits of base
- WRITE8(ea + 7, cpustate->task.base >> 24);
- WRITE16(ea + 8, cpustate->task.segment);
- } else {
- i386_trap( 6, 0, 0);
- }
- } else {
- i386_trap( 6, 0, 0);
- }
-}
-
- void I386OP(cyrix_rsts)() // Opcode 0f 7d
-{
- if ( PROTECTED_MODE )
- {
- if(cpustate->CPL)
- FAULT(FAULT_GP,0)
-
- UINT8 modrm = FETCH();
-
- if( !(modrm & 0xf8) ) {
- UINT32 ea = GetEA(modrm,0);
- UINT16 flags = READ16(ea + 5);
- UINT32 base = (READ32(ea + 2) | 0x00ffffff) | (READ8(ea + 7) << 24);
- UINT32 limit = READ16(ea + 0) | ((flags & 3) << 16);
-
- if (flags & 0x8000) //G bit
- {
- limit = (limit << 12) | 0xfff;
- }
- cpustate->task.segment = READ16(ea + 8);
- cpustate->task.limit = limit;
- cpustate->task.base = base;
- cpustate->task.flags = flags;
- } else {
- i386_trap( 6, 0, 0);
- }
- } else {
- i386_trap( 6, 0, 0);
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::MMXOP(movd_r64_rm32)() // Opcode 0f 6e
-{
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- MMX((modrm >> 3) & 0x7).d[0]=LOAD_RM32(modrm);
- } else {
- UINT32 ea = GetEA(modrm, 0);
- MMX((modrm >> 3) & 0x7).d[0]=READ32(ea);
- }
- MMX((modrm >> 3) & 0x7).d[1]=0;
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::MMXOP(movq_r64_rm64)() // Opcode 0f 6f
-{
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- MMX((modrm >> 3) & 0x7).l=MMX(modrm & 0x7).l;
- } else {
- UINT32 ea = GetEA(modrm, 0);
- READMMX( ea, MMX((modrm >> 3) & 0x7));
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::MMXOP(movd_rm32_r64)() // Opcode 0f 7e
-{
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- STORE_RM32(modrm, MMX((modrm >> 3) & 0x7).d[0]);
- } else {
- UINT32 ea = GetEA(modrm, 0);
- WRITE32(ea, MMX((modrm >> 3) & 0x7).d[0]);
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::MMXOP(movq_rm64_r64)() // Opcode 0f 7f
-{
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- MMX(modrm & 0x7)=MMX((modrm >> 3) & 0x7);
- } else {
- UINT32 ea = GetEA(modrm, 0);
- WRITEMMX( ea, MMX((modrm >> 3) & 0x7));
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::MMXOP(pcmpeqb_r64_rm64)() // Opcode 0f 74
-{
- int c;
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- int s,d;
- s=modrm & 0x7;
- d=(modrm >> 3) & 0x7;
- for (c=0;c <= 7;c++)
- MMX(d).b[c]=(MMX(d).b[c] == MMX(s).b[c]) ? 0xff : 0;
- } else {
- MMX_REG s;
- int d=(modrm >> 3) & 0x7;
- UINT32 ea = GetEA(modrm, 0);
- READMMX( ea, s);
- for (c=0;c <= 7;c++)
- MMX(d).b[c]=(MMX(d).b[c] == s.b[c]) ? 0xff : 0;
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::MMXOP(pcmpeqw_r64_rm64)() // Opcode 0f 75
-{
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- int s,d;
- s=modrm & 0x7;
- d=(modrm >> 3) & 0x7;
- MMX(d).w[0]=(MMX(d).w[0] == MMX(s).w[0]) ? 0xffff : 0;
- MMX(d).w[1]=(MMX(d).w[1] == MMX(s).w[1]) ? 0xffff : 0;
- MMX(d).w[2]=(MMX(d).w[2] == MMX(s).w[2]) ? 0xffff : 0;
- MMX(d).w[3]=(MMX(d).w[3] == MMX(s).w[3]) ? 0xffff : 0;
- } else {
- MMX_REG s;
- int d=(modrm >> 3) & 0x7;
- UINT32 ea = GetEA(modrm, 0);
- READMMX( ea, s);
- MMX(d).w[0]=(MMX(d).w[0] == s.w[0]) ? 0xffff : 0;
- MMX(d).w[1]=(MMX(d).w[1] == s.w[1]) ? 0xffff : 0;
- MMX(d).w[2]=(MMX(d).w[2] == s.w[2]) ? 0xffff : 0;
- MMX(d).w[3]=(MMX(d).w[3] == s.w[3]) ? 0xffff : 0;
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::MMXOP(pcmpeqd_r64_rm64)() // Opcode 0f 76
-{
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- int s,d;
- s=modrm & 0x7;
- d=(modrm >> 3) & 0x7;
- MMX(d).d[0]=(MMX(d).d[0] == MMX(s).d[0]) ? 0xffffffff : 0;
- MMX(d).d[1]=(MMX(d).d[1] == MMX(s).d[1]) ? 0xffffffff : 0;
- } else {
- MMX_REG s;
- int d=(modrm >> 3) & 0x7;
- UINT32 ea = GetEA(modrm, 0);
- READMMX( ea, s);
- MMX(d).d[0]=(MMX(d).d[0] == s.d[0]) ? 0xffffffff : 0;
- MMX(d).d[1]=(MMX(d).d[1] == s.d[1]) ? 0xffffffff : 0;
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::MMXOP(pshufw_r64_rm64_i8)() // Opcode 0f 70
-{
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- MMX_REG t;
- int s,d;
- UINT8 imm8 = FETCH();
- s=modrm & 0x7;
- d=(modrm >> 3) & 0x7;
- t.q=MMX(s).q;
- MMX(d).w[0]=t.w[imm8 & 3];
- MMX(d).w[1]=t.w[(imm8 >> 2) & 3];
- MMX(d).w[2]=t.w[(imm8 >> 4) & 3];
- MMX(d).w[3]=t.w[(imm8 >> 6) & 3];
- } else {
- MMX_REG s;
- int d=(modrm >> 3) & 0x7;
- UINT32 ea = GetEA(modrm, 0);
- UINT8 imm8 = FETCH();
- READMMX( ea, s);
- MMX(d).w[0]=s.w[imm8 & 3];
- MMX(d).w[1]=s.w[(imm8 >> 2) & 3];
- MMX(d).w[2]=s.w[(imm8 >> 4) & 3];
- MMX(d).w[3]=s.w[(imm8 >> 6) & 3];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(punpcklbw_r128_rm128)() // Opcode 66 0f 60
-{
- UINT8 modrm = FETCH();
- if (modrm >= 0xc0) {
- XMM_REG xd,xs;
- int s, d;
- s = modrm & 0x7;
- d = (modrm >> 3) & 0x7;
- xd.l[0] = XMM(d).l[0];
- xs.l[0] = XMM(s).l[0];
- XMM(d).b[0] = xd.b[0];
- XMM(d).b[1] = xs.b[0];
- XMM(d).b[2] = xd.b[1];
- XMM(d).b[3] = xs.b[1];
- XMM(d).b[4] = xd.b[2];
- XMM(d).b[5] = xs.b[2];
- XMM(d).b[6] = xd.b[3];
- XMM(d).b[7] = xs.b[3];
- XMM(d).b[8] = xd.b[4];
- XMM(d).b[9] = xs.b[4];
- XMM(d).b[10] = xd.b[5];
- XMM(d).b[11] = xs.b[5];
- XMM(d).b[12] = xd.b[6];
- XMM(d).b[13] = xs.b[6];
- XMM(d).b[14] = xd.b[7];
- XMM(d).b[15] = xs.b[7];
- }
- else {
- XMM_REG xd, xs;
- int d = (modrm >> 3) & 0x7;
- UINT32 ea = GetEA(modrm, 0);
- xd.l[0] = XMM(d).l[0];
- xs.q[0] = READ64( ea);
- for (int n = 0; n < 8; n++) {
- XMM(d).b[n << 1] = xd.b[n];
- XMM(d).b[(n << 1) | 1] = xs.b[n];
- }
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(punpcklwd_r128_rm128)()
-{
- UINT8 modrm = FETCH();
- if (modrm >= 0xc0) {
- XMM_REG xd, xs;
- int s, d;
- s = modrm & 0x7;
- d = (modrm >> 3) & 0x7;
- xd.l[0] = XMM(d).l[0];
- xs.l[0] = XMM(s).l[0];
- for (int n = 0; n < 4; n++) {
- XMM(d).w[n << 1] = xd.w[n];
- XMM(d).w[(n << 1) | 1] = xs.w[n];
- }
- }
- else {
- XMM_REG xd, xs;
- int d = (modrm >> 3) & 0x7;
- UINT32 ea = GetEA(modrm, 0);
- xd.l[0] = XMM(d).l[0];
- xs.q[0] = READ64( ea);
- for (int n = 0; n < 4; n++) {
- XMM(d).w[n << 1] = xd.w[n];
- XMM(d).w[(n << 1) | 1] = xs.w[n];
- }
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(punpckldq_r128_rm128)()
-{
- UINT8 modrm = FETCH();
- if (modrm >= 0xc0) {
- XMM_REG xd, xs;
- int s, d;
- s = modrm & 0x7;
- d = (modrm >> 3) & 0x7;
- xd.l[0] = XMM(d).l[0];
- xs.l[0] = XMM(s).l[0];
- for (int n = 0; n < 2; n++) {
- XMM(d).d[n << 1] = xd.d[n];
- XMM(d).d[(n << 1) | 1] = xs.d[n];
- }
- }
- else {
- XMM_REG xd, xs;
- int d = (modrm >> 3) & 0x7;
- UINT32 ea = GetEA(modrm, 0);
- xd.l[0] = XMM(d).l[0];
- xs.q[0] = READ64( ea);
- for (int n = 0; n < 2; n++) {
- XMM(d).d[n << 1] = xd.d[n];
- XMM(d).d[(n << 1) | 1] = xs.d[n];
- }
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(punpcklqdq_r128_rm128)()
-{
- UINT8 modrm = FETCH();
- if (modrm >= 0xc0) {
- XMM_REG xd, xs;
- int s, d;
- s = modrm & 0x7;
- d = (modrm >> 3) & 0x7;
- xd.l[0] = XMM(d).l[0];
- xs.l[0] = XMM(s).l[0];
- XMM(d).q[0] = xd.q[0];
- XMM(d).q[1] = xs.q[0];
- }
- else {
- XMM_REG xd, xs;
- int d = (modrm >> 3) & 0x7;
- UINT32 ea = GetEA(modrm, 0);
- xd.l[0] = XMM(d).l[0];
- xs.q[0] = READ64( ea);
- XMM(d).q[0] = xd.q[0];
- XMM(d).q[1] = xs.q[0];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::MMXOP(punpcklbw_r64_r64m32)() // Opcode 0f 60
-{
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- UINT32 t;
- int s,d;
- s=modrm & 0x7;
- d=(modrm >> 3) & 0x7;
- t=MMX(d).d[0];
- MMX(d).b[0]=t & 0xff;
- MMX(d).b[1]=MMX(s).b[0];
- MMX(d).b[2]=(t >> 8) & 0xff;
- MMX(d).b[3]=MMX(s).b[1];
- MMX(d).b[4]=(t >> 16) & 0xff;
- MMX(d).b[5]=MMX(s).b[2];
- MMX(d).b[6]=(t >> 24) & 0xff;
- MMX(d).b[7]=MMX(s).b[3];
- } else {
- UINT32 s,t;
- int d=(modrm >> 3) & 0x7;
- UINT32 ea = GetEA(modrm, 0);
- s = READ32(ea);
- t=MMX(d).d[0];
- MMX(d).b[0]=t & 0xff;
- MMX(d).b[1]=s & 0xff;
- MMX(d).b[2]=(t >> 8) & 0xff;
- MMX(d).b[3]=(s >> 8) & 0xff;
- MMX(d).b[4]=(t >> 16) & 0xff;
- MMX(d).b[5]=(s >> 16) & 0xff;
- MMX(d).b[6]=(t >> 24) & 0xff;
- MMX(d).b[7]=(s >> 24) & 0xff;
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::MMXOP(punpcklwd_r64_r64m32)() // Opcode 0f 61
-{
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- UINT16 t;
- int s,d;
- s=modrm & 0x7;
- d=(modrm >> 3) & 0x7;
- t=MMX(d).w[1];
- MMX(d).w[0]=MMX(d).w[0];
- MMX(d).w[1]=MMX(s).w[0];
- MMX(d).w[2]=t;
- MMX(d).w[3]=MMX(s).w[1];
- } else {
- UINT32 s;
- UINT16 t;
- int d=(modrm >> 3) & 0x7;
- UINT32 ea = GetEA(modrm, 0);
- s = READ32(ea);
- t=MMX(d).w[1];
- MMX(d).w[0]=MMX(d).w[0];
- MMX(d).w[1]=s & 0xffff;
- MMX(d).w[2]=t;
- MMX(d).w[3]=(s >> 16) & 0xffff;
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::MMXOP(punpckldq_r64_r64m32)() // Opcode 0f 62
-{
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- int s,d;
- s=modrm & 0x7;
- d=(modrm >> 3) & 0x7;
- MMX(d).d[0]=MMX(d).d[0];
- MMX(d).d[1]=MMX(s).d[0];
- } else {
- UINT32 s;
- int d=(modrm >> 3) & 0x7;
- UINT32 ea = GetEA(modrm, 0);
- s = READ32(ea);
- MMX(d).d[0]=MMX(d).d[0];
- MMX(d).d[1]=s;
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::MMXOP(packsswb_r64_rm64)() // Opcode 0f 63
-{
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- int s,d;
- s=modrm & 0x7;
- d=(modrm >> 3) & 0x7;
- MMX(d).c[0]=SaturatedSignedWordToSignedByte(MMX(d).s[0]);
- MMX(d).c[1]=SaturatedSignedWordToSignedByte(MMX(d).s[1]);
- MMX(d).c[2]=SaturatedSignedWordToSignedByte(MMX(d).s[2]);
- MMX(d).c[3]=SaturatedSignedWordToSignedByte(MMX(d).s[3]);
- MMX(d).c[4]=SaturatedSignedWordToSignedByte(MMX(s).s[0]);
- MMX(d).c[5]=SaturatedSignedWordToSignedByte(MMX(s).s[1]);
- MMX(d).c[6]=SaturatedSignedWordToSignedByte(MMX(s).s[2]);
- MMX(d).c[7]=SaturatedSignedWordToSignedByte(MMX(s).s[3]);
- } else {
- MMX_REG s;
- int d=(modrm >> 3) & 0x7;
- UINT32 ea = GetEA(modrm, 0);
- READMMX( ea, s);
- MMX(d).c[0]=SaturatedSignedWordToSignedByte(MMX(d).s[0]);
- MMX(d).c[1]=SaturatedSignedWordToSignedByte(MMX(d).s[1]);
- MMX(d).c[2]=SaturatedSignedWordToSignedByte(MMX(d).s[2]);
- MMX(d).c[3]=SaturatedSignedWordToSignedByte(MMX(d).s[3]);
- MMX(d).c[4]=SaturatedSignedWordToSignedByte(s.s[0]);
- MMX(d).c[5]=SaturatedSignedWordToSignedByte(s.s[1]);
- MMX(d).c[6]=SaturatedSignedWordToSignedByte(s.s[2]);
- MMX(d).c[7]=SaturatedSignedWordToSignedByte(s.s[3]);
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::MMXOP(pcmpgtb_r64_rm64)() // Opcode 0f 64
-{
- int c;
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- int s,d;
- s=modrm & 0x7;
- d=(modrm >> 3) & 0x7;
- for (c=0;c <= 7;c++)
- MMX(d).b[c]=(MMX(d).c[c] > MMX(s).c[c]) ? 0xff : 0;
- } else {
- MMX_REG s;
- int d=(modrm >> 3) & 0x7;
- UINT32 ea = GetEA(modrm, 0);
- READMMX( ea, s);
- for (c=0;c <= 7;c++)
- MMX(d).b[c]=(MMX(d).c[c] > s.c[c]) ? 0xff : 0;
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::MMXOP(pcmpgtw_r64_rm64)() // Opcode 0f 65
-{
- int c;
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- int s,d;
- s=modrm & 0x7;
- d=(modrm >> 3) & 0x7;
- for (c=0;c <= 3;c++)
- MMX(d).w[c]=(MMX(d).s[c] > MMX(s).s[c]) ? 0xffff : 0;
- } else {
- MMX_REG s;
- int d=(modrm >> 3) & 0x7;
- UINT32 ea = GetEA(modrm, 0);
- READMMX( ea, s);
- for (c=0;c <= 3;c++)
- MMX(d).w[c]=(MMX(d).s[c] > s.s[c]) ? 0xffff : 0;
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::MMXOP(pcmpgtd_r64_rm64)() // Opcode 0f 66
-{
- int c;
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- int s,d;
- s=modrm & 0x7;
- d=(modrm >> 3) & 0x7;
- for (c=0;c <= 1;c++)
- MMX(d).d[c]=(MMX(d).i[c] > MMX(s).i[c]) ? 0xffffffff : 0;
- } else {
- MMX_REG s;
- int d=(modrm >> 3) & 0x7;
- UINT32 ea = GetEA(modrm, 0);
- READMMX( ea, s);
- for (c=0;c <= 1;c++)
- MMX(d).d[c]=(MMX(d).i[c] > s.i[c]) ? 0xffffffff : 0;
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::MMXOP(packuswb_r64_rm64)() // Opcode 0f 67
-{
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- MMX_REG ds, sd;
- int s,d;
- s=modrm & 0x7;
- d=(modrm >> 3) & 0x7;
- ds.q = MMX(d).q;
- sd.q = MMX(s).q;
- MMX(d).b[0]=SaturatedSignedWordToUnsignedByte(ds.s[0]);
- MMX(d).b[1]=SaturatedSignedWordToUnsignedByte(ds.s[1]);
- MMX(d).b[2]=SaturatedSignedWordToUnsignedByte(ds.s[2]);
- MMX(d).b[3]=SaturatedSignedWordToUnsignedByte(ds.s[3]);
- MMX(d).b[4]=SaturatedSignedWordToUnsignedByte(sd.s[0]);
- MMX(d).b[5]=SaturatedSignedWordToUnsignedByte(sd.s[1]);
- MMX(d).b[6]=SaturatedSignedWordToUnsignedByte(sd.s[2]);
- MMX(d).b[7]=SaturatedSignedWordToUnsignedByte(sd.s[3]);
- } else {
- MMX_REG s,t;
- int d=(modrm >> 3) & 0x7;
- UINT32 ea = GetEA(modrm, 0);
- READMMX( ea, s);
- t.q = MMX(d).q;
- MMX(d).b[0]=SaturatedSignedWordToUnsignedByte(t.s[0]);
- MMX(d).b[1]=SaturatedSignedWordToUnsignedByte(t.s[1]);
- MMX(d).b[2]=SaturatedSignedWordToUnsignedByte(t.s[2]);
- MMX(d).b[3]=SaturatedSignedWordToUnsignedByte(t.s[3]);
- MMX(d).b[4]=SaturatedSignedWordToUnsignedByte(s.s[0]);
- MMX(d).b[5]=SaturatedSignedWordToUnsignedByte(s.s[1]);
- MMX(d).b[6]=SaturatedSignedWordToUnsignedByte(s.s[2]);
- MMX(d).b[7]=SaturatedSignedWordToUnsignedByte(s.s[3]);
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::MMXOP(punpckhbw_r64_rm64)() // Opcode 0f 68
-{
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- int s,d;
- s=modrm & 0x7;
- d=(modrm >> 3) & 0x7;
- MMX(d).b[0]=MMX(d).b[4];
- MMX(d).b[1]=MMX(s).b[4];
- MMX(d).b[2]=MMX(d).b[5];
- MMX(d).b[3]=MMX(s).b[5];
- MMX(d).b[4]=MMX(d).b[6];
- MMX(d).b[5]=MMX(s).b[6];
- MMX(d).b[6]=MMX(d).b[7];
- MMX(d).b[7]=MMX(s).b[7];
- } else {
- MMX_REG s;
- int d=(modrm >> 3) & 0x7;
- UINT32 ea = GetEA(modrm, 0);
- READMMX( ea, s);
- MMX(d).b[0]=MMX(d).b[4];
- MMX(d).b[1]=s.b[4];
- MMX(d).b[2]=MMX(d).b[5];
- MMX(d).b[3]=s.b[5];
- MMX(d).b[4]=MMX(d).b[6];
- MMX(d).b[5]=s.b[6];
- MMX(d).b[6]=MMX(d).b[7];
- MMX(d).b[7]=s.b[7];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::MMXOP(punpckhwd_r64_rm64)() // Opcode 0f 69
-{
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- int s,d;
- s=modrm & 0x7;
- d=(modrm >> 3) & 0x7;
- MMX(d).w[0]=MMX(d).w[2];
- MMX(d).w[1]=MMX(s).w[2];
- MMX(d).w[2]=MMX(d).w[3];
- MMX(d).w[3]=MMX(s).w[3];
- } else {
- MMX_REG s;
- int d=(modrm >> 3) & 0x7;
- UINT32 ea = GetEA(modrm, 0);
- READMMX( ea, s);
- MMX(d).w[0]=MMX(d).w[2];
- MMX(d).w[1]=s.w[2];
- MMX(d).w[2]=MMX(d).w[3];
- MMX(d).w[3]=s.w[3];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::MMXOP(punpckhdq_r64_rm64)() // Opcode 0f 6a
-{
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- int s,d;
- s=modrm & 0x7;
- d=(modrm >> 3) & 0x7;
- MMX(d).d[0]=MMX(d).d[1];
- MMX(d).d[1]=MMX(s).d[1];
- } else {
- MMX_REG s;
- int d=(modrm >> 3) & 0x7;
- UINT32 ea = GetEA(modrm, 0);
- READMMX( ea, s);
- MMX(d).d[0]=MMX(d).d[1];
- MMX(d).d[1]=s.d[1];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::MMXOP(packssdw_r64_rm64)() // Opcode 0f 6b
-{
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- int s,d;
- INT32 t1, t2, t3, t4;
- s=modrm & 0x7;
- d=(modrm >> 3) & 0x7;
- t1 = MMX(d).i[0];
- t2 = MMX(d).i[1];
- t3 = MMX(s).i[0];
- t4 = MMX(s).i[1];
- MMX(d).s[0] = SaturatedSignedDwordToSignedWord(t1);
- MMX(d).s[1] = SaturatedSignedDwordToSignedWord(t2);
- MMX(d).s[2] = SaturatedSignedDwordToSignedWord(t3);
- MMX(d).s[3] = SaturatedSignedDwordToSignedWord(t4);
- }
- else {
- MMX_REG s;
- INT32 t1, t2;
- int d=(modrm >> 3) & 0x7;
- UINT32 ea = GetEA(modrm, 0);
- READMMX( ea, s);
- t1 = MMX(d).i[0];
- t2 = MMX(d).i[1];
- MMX(d).s[0] = SaturatedSignedDwordToSignedWord(t1);
- MMX(d).s[1] = SaturatedSignedDwordToSignedWord(t2);
- MMX(d).s[2] = SaturatedSignedDwordToSignedWord(s.i[0]);
- MMX(d).s[3] = SaturatedSignedDwordToSignedWord(s.i[1]);
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(group_0fae)() // Opcode 0f ae
-{
- UINT8 modm = FETCH();
- if( modm == 0xf8 ) {
- logerror("Unemulated SFENCE opcode called\n");
- CYCLES(1); // sfence instruction
- } else if( modm == 0xf0 ) {
- CYCLES(1); // mfence instruction
- } else if( modm == 0xe8 ) {
- CYCLES(1); // lfence instruction
- } else if( modm < 0xc0 ) {
- UINT32 ea;
- switch ( (modm & 0x38) >> 3 )
- {
- case 2: // ldmxcsr m32
- ea = GetEA(modm, 0);
- cpustate->mxcsr = READ32(ea);
- break;
- case 3: // stmxcsr m32
- ea = GetEA(modm, 0);
- WRITE32(ea, cpustate->mxcsr);
- break;
- case 7: // clflush m8
- GetNonTranslatedEA(modm, NULL);
- break;
- default:
- report_invalid_modrm( "sse_group_0fae", modm);
- }
- } else {
- report_invalid_modrm( "sse_group_0fae", modm);
- }
-}
-
- void I386_OPS_BASE::SSEOP(cvttps2dq_r128_rm128)() // Opcode f3 0f 5b
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).i[0]=(INT32)XMM(modrm & 0x7).f[0];
- XMM((modrm >> 3) & 0x7).i[1]=(INT32)XMM(modrm & 0x7).f[1];
- XMM((modrm >> 3) & 0x7).i[2]=(INT32)XMM(modrm & 0x7).f[2];
- XMM((modrm >> 3) & 0x7).i[3]=(INT32)XMM(modrm & 0x7).f[3];
- } else {
- XMM_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, src);
- XMM((modrm >> 3) & 0x7).i[0]=(INT32)src.f[0];
- XMM((modrm >> 3) & 0x7).i[1]=(INT32)src.f[1];
- XMM((modrm >> 3) & 0x7).i[2]=(INT32)src.f[2];
- XMM((modrm >> 3) & 0x7).i[3]=(INT32)src.f[3];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(cvtss2sd_r128_r128m32)() // Opcode f3 0f 5a
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).f64[0] = XMM(modrm & 0x7).f[0];
- } else {
- XMM_REG s;
- UINT32 ea = GetEA(modrm, 0);
- s.d[0] = READ32(ea);
- XMM((modrm >> 3) & 0x7).f64[0] = s.f[0];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(cvttss2si_r32_r128m32)() // Opcode f3 0f 2c
-{
- INT32 src;
- UINT8 modrm = FETCH(); // get mordm byte
- if( modrm >= 0xc0 ) { // if bits 7-6 are 11 the source is a xmm register (low doubleword)
- src = (INT32)XMM(modrm & 0x7).f[0^NATIVE_ENDIAN_VALUE_LE_BE(0,1)];
- } else { // otherwise is a memory address
- XMM_REG t;
- UINT32 ea = GetEA(modrm, 0);
- t.d[0] = READ32(ea);
- src = (INT32)t.f[0];
- }
- STORE_REG32(modrm, (UINT32)src);
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(cvtss2si_r32_r128m32)() // Opcode f3 0f 2d
-{
- INT32 src;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- src = (INT32)XMM(modrm & 0x7).f[0];
- } else {
- XMM_REG t;
- UINT32 ea = GetEA(modrm, 0);
- t.d[0] = READ32(ea);
- src = (INT32)t.f[0];
- }
- STORE_REG32(modrm, (UINT32)src);
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(cvtsi2ss_r128_rm32)() // Opcode f3 0f 2a
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).f[0] = (INT32)LOAD_RM32(modrm);
- } else {
- UINT32 ea = GetEA(modrm, 0);
- XMM((modrm >> 3) & 0x7).f[0] = (INT32)READ32(ea);
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(cvtpi2ps_r128_rm64)() // Opcode 0f 2a
-{
- UINT8 modrm = FETCH();
- MMXPROLOG();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).f[0] = (float)MMX(modrm & 0x7).i[0];
- XMM((modrm >> 3) & 0x7).f[1] = (float)MMX(modrm & 0x7).i[1];
- } else {
- MMX_REG r;
- UINT32 ea = GetEA(modrm, 0);
- READMMX( ea, r);
- XMM((modrm >> 3) & 0x7).f[0] = (float)r.i[0];
- XMM((modrm >> 3) & 0x7).f[1] = (float)r.i[1];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(cvttps2pi_r64_r128m64)() // Opcode 0f 2c
-{
- UINT8 modrm = FETCH();
- MMXPROLOG();
- if( modrm >= 0xc0 ) {
- MMX((modrm >> 3) & 0x7).i[0] = XMM(modrm & 0x7).f[0];
- MMX((modrm >> 3) & 0x7).i[1] = XMM(modrm & 0x7).f[1];
- } else {
- XMM_REG r;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, r);
- XMM((modrm >> 3) & 0x7).i[0] = r.f[0];
- XMM((modrm >> 3) & 0x7).i[1] = r.f[1];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(cvtps2pi_r64_r128m64)() // Opcode 0f 2d
-{
- UINT8 modrm = FETCH();
- MMXPROLOG();
- if( modrm >= 0xc0 ) {
- MMX((modrm >> 3) & 0x7).i[0] = XMM(modrm & 0x7).f[0];
- MMX((modrm >> 3) & 0x7).i[1] = XMM(modrm & 0x7).f[1];
- } else {
- XMM_REG r;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, r);
- XMM((modrm >> 3) & 0x7).i[0] = r.f[0];
- XMM((modrm >> 3) & 0x7).i[1] = r.f[1];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(cvtps2pd_r128_r128m64)() // Opcode 0f 5a
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).f64[0] = (double)XMM(modrm & 0x7).f[0];
- XMM((modrm >> 3) & 0x7).f64[1] = (double)XMM(modrm & 0x7).f[1];
- } else {
- MMX_REG r;
- UINT32 ea = GetEA(modrm, 0);
- READMMX( ea, r);
- XMM((modrm >> 3) & 0x7).f64[0] = (double)r.f[0];
- XMM((modrm >> 3) & 0x7).f64[1] = (double)r.f[1];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(cvtdq2ps_r128_rm128)() // Opcode 0f 5b
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).f[0] = (float)XMM(modrm & 0x7).i[0];
- XMM((modrm >> 3) & 0x7).f[1] = (float)XMM(modrm & 0x7).i[1];
- XMM((modrm >> 3) & 0x7).f[2] = (float)XMM(modrm & 0x7).i[2];
- XMM((modrm >> 3) & 0x7).f[3] = (float)XMM(modrm & 0x7).i[3];
- } else {
- XMM_REG r;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, r);
- XMM((modrm >> 3) & 0x7).f[0] = (float)r.i[0];
- XMM((modrm >> 3) & 0x7).f[1] = (float)r.i[1];
- XMM((modrm >> 3) & 0x7).f[2] = (float)r.i[2];
- XMM((modrm >> 3) & 0x7).f[3] = (float)r.i[3];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(cvtdq2pd_r128_r128m64)() // Opcode f3 0f e6
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).f64[0] = (double)XMM(modrm & 0x7).i[0];
- XMM((modrm >> 3) & 0x7).f64[1] = (double)XMM(modrm & 0x7).i[1];
- } else {
- MMX_REG s;
- UINT32 ea = GetEA(modrm, 0);
- READMMX( ea, s);
- XMM((modrm >> 3) & 0x7).f64[0] = (double)s.i[0];
- XMM((modrm >> 3) & 0x7).f64[1] = (double)s.i[1];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(movss_r128_rm128)() // Opcode f3 0f 10
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).d[0] = XMM(modrm & 0x7).d[0];
- } else {
- UINT32 ea = GetEA(modrm, 0);
- XMM((modrm >> 3) & 0x7).d[0] = READ32(ea);
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(movss_rm128_r128)() // Opcode f3 0f 11
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM(modrm & 0x7).d[0] = XMM((modrm >> 3) & 0x7).d[0];
- } else {
- UINT32 ea = GetEA(modrm, 0);
- WRITE32(ea, XMM((modrm >> 3) & 0x7).d[0]);
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(movsldup_r128_rm128)() // Opcode f3 0f 12
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).d[0] = XMM(modrm & 0x7).d[0];
- XMM((modrm >> 3) & 0x7).d[1] = XMM(modrm & 0x7).d[0];
- XMM((modrm >> 3) & 0x7).d[2] = XMM(modrm & 0x7).d[2];
- XMM((modrm >> 3) & 0x7).d[3] = XMM(modrm & 0x7).d[2];
- } else {
- XMM_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, src);
- XMM((modrm >> 3) & 0x7).d[0] = src.d[0];
- XMM((modrm >> 3) & 0x7).d[1] = src.d[0];
- XMM((modrm >> 3) & 0x7).d[2] = src.d[2];
- XMM((modrm >> 3) & 0x7).d[3] = src.d[2];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(movshdup_r128_rm128)() // Opcode f3 0f 16
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).d[0] = XMM(modrm & 0x7).d[1];
- XMM((modrm >> 3) & 0x7).d[1] = XMM(modrm & 0x7).d[1];
- XMM((modrm >> 3) & 0x7).d[2] = XMM(modrm & 0x7).d[3];
- XMM((modrm >> 3) & 0x7).d[3] = XMM(modrm & 0x7).d[3];
- } else {
- XMM_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, src);
- XMM((modrm >> 3) & 0x7).d[0] = src.d[1];
- XMM((modrm >> 3) & 0x7).d[1] = src.d[1];
- XMM((modrm >> 3) & 0x7).d[2] = src.d[3];
- XMM((modrm >> 3) & 0x7).d[3] = src.d[3];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(movaps_r128_rm128)() // Opcode 0f 28
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7) = XMM(modrm & 0x7);
- } else {
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, XMM((modrm >> 3) & 0x7));
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(movaps_rm128_r128)() // Opcode 0f 29
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM(modrm & 0x7) = XMM((modrm >> 3) & 0x7);
- } else {
- UINT32 ea = GetEA(modrm, 0);
- WRITEXMM( ea, XMM((modrm >> 3) & 0x7));
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(movups_r128_rm128)() // Opcode 0f 10
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7) = XMM(modrm & 0x7);
- } else {
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, XMM((modrm >> 3) & 0x7)); // address does not need to be 16-byte aligned
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(movupd_r128_rm128)() // Opcode 66 0f 10
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7) = XMM(modrm & 0x7);
- } else {
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, XMM((modrm >> 3) & 0x7)); // address does not need to be 16-byte aligned
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(movups_rm128_r128)() // Opcode 0f 11
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM(modrm & 0x7) = XMM((modrm >> 3) & 0x7);
- } else {
- UINT32 ea = GetEA(modrm, 0);
- WRITEXMM( ea, XMM((modrm >> 3) & 0x7)); // address does not need to be 16-byte aligned
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(movupd_rm128_r128)() // Opcode 66 0f 11
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM(modrm & 0x7) = XMM((modrm >> 3) & 0x7);
- } else {
- UINT32 ea = GetEA(modrm, 0);
- WRITEXMM( ea, XMM((modrm >> 3) & 0x7)); // address does not need to be 16-byte aligned
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(movlps_r128_m64)() // Opcode 0f 12
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- // MOVHLPS opcode
- XMM((modrm >> 3) & 0x7).q[0] = XMM(modrm & 0x7).q[1];
- CYCLES(1); // TODO: correct cycle count
- } else {
- // MOVLPS opcode
- UINT32 ea = GetEA(modrm, 0);
- READXMM_LO64( ea, XMM((modrm >> 3) & 0x7));
- CYCLES(1); // TODO: correct cycle count
- }
-}
-
- void I386_OPS_BASE::SSEOP(movlpd_r128_m64)() // Opcode 66 0f 12
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- CYCLES(1); // TODO: correct cycle count
- } else {
- // MOVLPS opcode
- UINT32 ea = GetEA(modrm, 0);
- READXMM_LO64( ea, XMM((modrm >> 3) & 0x7));
- CYCLES(1); // TODO: correct cycle count
- }
-}
-
- void I386_OPS_BASE::SSEOP(movlps_m64_r128)() // Opcode 0f 13
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- // unsupported by cpu
- CYCLES(1); // TODO: correct cycle count
- } else {
- UINT32 ea = GetEA(modrm, 0);
- WRITEXMM_LO64( ea, XMM((modrm >> 3) & 0x7));
- CYCLES(1); // TODO: correct cycle count
- }
-}
-
- void I386_OPS_BASE::SSEOP(movlpd_m64_r128)() // Opcode 66 0f 13
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- // unsupported by cpu
- CYCLES(1); // TODO: correct cycle count
- } else {
- UINT32 ea = GetEA(modrm, 0);
- WRITEXMM_LO64( ea, XMM((modrm >> 3) & 0x7));
- CYCLES(1); // TODO: correct cycle count
- }
-}
-
- void I386_OPS_BASE::SSEOP(movhps_r128_m64)() // Opcode 0f 16
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- // MOVLHPS opcode
- XMM((modrm >> 3) & 0x7).q[1] = XMM(modrm & 0x7).q[0];
- CYCLES(1); // TODO: correct cycle count
- } else {
- // MOVHPS opcode
- UINT32 ea = GetEA(modrm, 0);
- READXMM_HI64( ea, XMM((modrm >> 3) & 0x7));
- CYCLES(1); // TODO: correct cycle count
- }
-}
-
- void I386_OPS_BASE::SSEOP(movhpd_r128_m64)() // Opcode 66 0f 16
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- // unsupported by cpu
- CYCLES(1); // TODO: correct cycle count
- } else {
- // MOVHPS opcode
- UINT32 ea = GetEA(modrm, 0);
- READXMM_HI64( ea, XMM((modrm >> 3) & 0x7));
- CYCLES(1); // TODO: correct cycle count
- }
-}
-
- void I386_OPS_BASE::SSEOP(movhps_m64_r128)() // Opcode 0f 17
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- // unsupported by cpu
- CYCLES(1); // TODO: correct cycle count
- } else {
- UINT32 ea = GetEA(modrm, 0);
- WRITEXMM_HI64( ea, XMM((modrm >> 3) & 0x7));
- CYCLES(1); // TODO: correct cycle count
- }
-}
-
- void I386_OPS_BASE::SSEOP(movhpd_m64_r128)() // Opcode 66 0f 17
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- // unsupported by cpu
- CYCLES(1); // TODO: correct cycle count
- } else {
- UINT32 ea = GetEA(modrm, 0);
- WRITEXMM_HI64( ea, XMM((modrm >> 3) & 0x7));
- CYCLES(1); // TODO: correct cycle count
- }
-}
-
- void I386_OPS_BASE::SSEOP(movntps_m128_r128)() // Opcode 0f 2b
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- // unsupported by cpu
- CYCLES(1); // TODO: correct cycle count
- } else {
- // since cache is not implemented
- UINT32 ea = GetEA(modrm, 0);
- WRITEXMM( ea, XMM((modrm >> 3) & 0x7));
- CYCLES(1); // TODO: correct cycle count
- }
-}
-
- void I386_OPS_BASE::SSEOP(movmskps_r16_r128)() // Opcode 0f 50
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- int b;
- b=(XMM(modrm & 0x7).d[0] >> 31) & 1;
- b=b | ((XMM(modrm & 0x7).d[1] >> 30) & 2);
- b=b | ((XMM(modrm & 0x7).d[2] >> 29) & 4);
- b=b | ((XMM(modrm & 0x7).d[3] >> 28) & 8);
- STORE_REG16(modrm, b);
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(movmskps_r32_r128)() // Opcode 0f 50
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- int b;
- b=(XMM(modrm & 0x7).d[0] >> 31) & 1;
- b=b | ((XMM(modrm & 0x7).d[1] >> 30) & 2);
- b=b | ((XMM(modrm & 0x7).d[2] >> 29) & 4);
- b=b | ((XMM(modrm & 0x7).d[3] >> 28) & 8);
- STORE_REG32(modrm, b);
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(movmskpd_r32_r128)() // Opcode 66 0f 50
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- int b;
- b=(XMM(modrm & 0x7).q[0] >> 63) & 1;
- b=b | ((XMM(modrm & 0x7).q[1] >> 62) & 2);
- STORE_REG32(modrm, b);
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(movq2dq_r128_r64)() // Opcode f3 0f d6
-{
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).q[0] = MMX(modrm & 7).q;
- XMM((modrm >> 3) & 0x7).q[1] = 0;
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(movdqu_r128_rm128)() // Opcode f3 0f 6f
-{
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).q[0] = XMM(modrm & 0x7).q[0];
- XMM((modrm >> 3) & 0x7).q[1] = XMM(modrm & 0x7).q[1];
- } else {
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, XMM((modrm >> 3) & 0x7));
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(movdqu_rm128_r128)() // Opcode f3 0f 7f
-{
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM(modrm & 0x7).q[0] = XMM((modrm >> 3) & 0x7).q[0];
- XMM(modrm & 0x7).q[1] = XMM((modrm >> 3) & 0x7).q[1];
- } else {
- UINT32 ea = GetEA(modrm, 0);
- WRITEXMM( ea, XMM((modrm >> 3) & 0x7));
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(movd_m128_rm32)() // Opcode 66 0f 6e
-{
- UINT8 modrm = FETCH();
- if (modrm >= 0xc0) {
- XMM((modrm >> 3) & 0x7).d[0] = LOAD_RM32(modrm);
- }
- else {
- UINT32 ea = GetEA(modrm, 0);
- XMM((modrm >> 3) & 0x7).d[0] = READ32(ea);
- }
- XMM((modrm >> 3) & 0x7).d[1] = 0;
- XMM((modrm >> 3) & 0x7).q[1] = 0;
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(movdqa_m128_rm128)() // Opcode 66 0f 6f
-{
- UINT8 modrm = FETCH();
- if (modrm >= 0xc0) {
- XMM((modrm >> 3) & 0x7).q[0] = XMM(modrm & 0x7).q[0];
- XMM((modrm >> 3) & 0x7).q[1] = XMM(modrm & 0x7).q[1];
- }
- else {
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, XMM((modrm >> 3) & 0x7));
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(movq_r128_r128m64)() // Opcode f3 0f 7e
-{
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).q[0] = XMM(modrm & 0x7).q[0];
- XMM((modrm >> 3) & 0x7).q[1] = 0;
- } else {
- UINT32 ea = GetEA(modrm, 0);
- XMM((modrm >> 3) & 0x7).q[0] = READ64( ea);
- XMM((modrm >> 3) & 0x7).q[1] = 0;
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(movd_rm32_r128)() // Opcode 66 0f 7e
-{
- UINT8 modrm = FETCH();
- if (modrm >= 0xc0) {
- STORE_RM32(modrm, XMM((modrm >> 3) & 0x7).d[0]);
- }
- else {
- UINT32 ea = GetEA(modrm, 0);
- WRITE32(ea, XMM((modrm >> 3) & 0x7).d[0]);
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(movdqa_rm128_r128)() // Opcode 66 0f 7f
-{
- UINT8 modrm = FETCH();
- if (modrm >= 0xc0) {
- XMM(modrm & 0x7).q[0] = XMM((modrm >> 3) & 0x7).q[0];
- XMM(modrm & 0x7).q[1] = XMM((modrm >> 3) & 0x7).q[1];
- }
- else {
- UINT32 ea = GetEA(modrm, 0);
- WRITEXMM( ea, XMM((modrm >> 3) & 0x7));
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(pmovmskb_r16_r64)() // Opcode 0f d7
-{
- //MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- int b;
- b=(MMX(modrm & 0x7).b[0] >> 7) & 1;
- b=b | ((MMX(modrm & 0x7).b[1] >> 6) & 2);
- b=b | ((MMX(modrm & 0x7).b[2] >> 5) & 4);
- b=b | ((MMX(modrm & 0x7).b[3] >> 4) & 8);
- b=b | ((MMX(modrm & 0x7).b[4] >> 3) & 16);
- b=b | ((MMX(modrm & 0x7).b[5] >> 2) & 32);
- b=b | ((MMX(modrm & 0x7).b[6] >> 1) & 64);
- b=b | ((MMX(modrm & 0x7).b[7] >> 0) & 128);
- STORE_REG16(modrm, b);
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(pmovmskb_r32_r64)() // Opcode 0f d7
-{
- //MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- int b;
- b=(MMX(modrm & 0x7).b[0] >> 7) & 1;
- b=b | ((MMX(modrm & 0x7).b[1] >> 6) & 2);
- b=b | ((MMX(modrm & 0x7).b[2] >> 5) & 4);
- b=b | ((MMX(modrm & 0x7).b[3] >> 4) & 8);
- b=b | ((MMX(modrm & 0x7).b[4] >> 3) & 16);
- b=b | ((MMX(modrm & 0x7).b[5] >> 2) & 32);
- b=b | ((MMX(modrm & 0x7).b[6] >> 1) & 64);
- b=b | ((MMX(modrm & 0x7).b[7] >> 0) & 128);
- STORE_REG32(modrm, b);
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(pmovmskb_r32_r128)() // Opcode 66 0f d7
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- UINT32 b;
- b=(XMM(modrm & 0x7).b[0] >> 7) & 1;
- b=b | ((XMM(modrm & 0x7).b[1] >> 6) & 2);
- b=b | ((XMM(modrm & 0x7).b[2] >> 5) & 4);
- b=b | ((XMM(modrm & 0x7).b[3] >> 4) & 8);
- b=b | ((XMM(modrm & 0x7).b[4] >> 3) & 16);
- b=b | ((XMM(modrm & 0x7).b[5] >> 2) & 32);
- b=b | ((XMM(modrm & 0x7).b[6] >> 1) & 64);
- b=b | ((XMM(modrm & 0x7).b[7] >> 0) & 128);
- b=b | ((XMM(modrm & 0x7).b[8] << 1) & 256);
- b=b | ((XMM(modrm & 0x7).b[9] << 2) & 512);
- b=b | ((XMM(modrm & 0x7).b[10] << 3) & 1024);
- b=b | ((XMM(modrm & 0x7).b[11] << 4) & 2048);
- b=b | ((XMM(modrm & 0x7).b[12] << 5) & 4096);
- b=b | ((XMM(modrm & 0x7).b[13] << 6) & 8192);
- b=b | ((XMM(modrm & 0x7).b[14] << 7) & 16384);
- b=b | ((XMM(modrm & 0x7).b[15] << 8) & 32768);
- STORE_REG32(modrm, b);
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(xorps)() // Opcode 0f 57
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).d[0] = XMM((modrm >> 3) & 0x7).d[0] ^ XMM(modrm & 0x7).d[0];
- XMM((modrm >> 3) & 0x7).d[1] = XMM((modrm >> 3) & 0x7).d[1] ^ XMM(modrm & 0x7).d[1];
- XMM((modrm >> 3) & 0x7).d[2] = XMM((modrm >> 3) & 0x7).d[2] ^ XMM(modrm & 0x7).d[2];
- XMM((modrm >> 3) & 0x7).d[3] = XMM((modrm >> 3) & 0x7).d[3] ^ XMM(modrm & 0x7).d[3];
- } else {
- XMM_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, src);
- XMM((modrm >> 3) & 0x7).d[0] = XMM((modrm >> 3) & 0x7).d[0] ^ src.d[0];
- XMM((modrm >> 3) & 0x7).d[1] = XMM((modrm >> 3) & 0x7).d[1] ^ src.d[1];
- XMM((modrm >> 3) & 0x7).d[2] = XMM((modrm >> 3) & 0x7).d[2] ^ src.d[2];
- XMM((modrm >> 3) & 0x7).d[3] = XMM((modrm >> 3) & 0x7).d[3] ^ src.d[3];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(xorpd_r128_rm128)() // Opcode 66 0f 57
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).q[0] = XMM((modrm >> 3) & 0x7).q[0] ^ XMM(modrm & 0x7).q[0];
- XMM((modrm >> 3) & 0x7).q[1] = XMM((modrm >> 3) & 0x7).q[1] ^ XMM(modrm & 0x7).q[1];
- } else {
- XMM_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, src);
- XMM((modrm >> 3) & 0x7).q[0] = XMM((modrm >> 3) & 0x7).q[0] ^ src.q[0];
- XMM((modrm >> 3) & 0x7).q[1] = XMM((modrm >> 3) & 0x7).q[1] ^ src.q[1];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(addps)() // Opcode 0f 58
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] + XMM(modrm & 0x7).f[0];
- XMM((modrm >> 3) & 0x7).f[1] = XMM((modrm >> 3) & 0x7).f[1] + XMM(modrm & 0x7).f[1];
- XMM((modrm >> 3) & 0x7).f[2] = XMM((modrm >> 3) & 0x7).f[2] + XMM(modrm & 0x7).f[2];
- XMM((modrm >> 3) & 0x7).f[3] = XMM((modrm >> 3) & 0x7).f[3] + XMM(modrm & 0x7).f[3];
- } else {
- XMM_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, src);
- XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] + src.f[0];
- XMM((modrm >> 3) & 0x7).f[1] = XMM((modrm >> 3) & 0x7).f[1] + src.f[1];
- XMM((modrm >> 3) & 0x7).f[2] = XMM((modrm >> 3) & 0x7).f[2] + src.f[2];
- XMM((modrm >> 3) & 0x7).f[3] = XMM((modrm >> 3) & 0x7).f[3] + src.f[3];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(sqrtps_r128_rm128)() // Opcode 0f 51
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).f[0] = sqrt(XMM(modrm & 0x7).f[0]);
- XMM((modrm >> 3) & 0x7).f[1] = sqrt(XMM(modrm & 0x7).f[1]);
- XMM((modrm >> 3) & 0x7).f[2] = sqrt(XMM(modrm & 0x7).f[2]);
- XMM((modrm >> 3) & 0x7).f[3] = sqrt(XMM(modrm & 0x7).f[3]);
- } else {
- XMM_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, src);
- XMM((modrm >> 3) & 0x7).f[0] = sqrt(src.f[0]);
- XMM((modrm >> 3) & 0x7).f[1] = sqrt(src.f[1]);
- XMM((modrm >> 3) & 0x7).f[2] = sqrt(src.f[2]);
- XMM((modrm >> 3) & 0x7).f[3] = sqrt(src.f[3]);
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(rsqrtps_r128_rm128)() // Opcode 0f 52
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).f[0] = 1.0 / sqrt(XMM(modrm & 0x7).f[0]);
- XMM((modrm >> 3) & 0x7).f[1] = 1.0 / sqrt(XMM(modrm & 0x7).f[1]);
- XMM((modrm >> 3) & 0x7).f[2] = 1.0 / sqrt(XMM(modrm & 0x7).f[2]);
- XMM((modrm >> 3) & 0x7).f[3] = 1.0 / sqrt(XMM(modrm & 0x7).f[3]);
- } else {
- XMM_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, src);
- XMM((modrm >> 3) & 0x7).f[0] = 1.0 / sqrt(src.f[0]);
- XMM((modrm >> 3) & 0x7).f[1] = 1.0 / sqrt(src.f[1]);
- XMM((modrm >> 3) & 0x7).f[2] = 1.0 / sqrt(src.f[2]);
- XMM((modrm >> 3) & 0x7).f[3] = 1.0 / sqrt(src.f[3]);
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(rcpps_r128_rm128)() // Opcode 0f 53
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).f[0] = 1.0 / XMM(modrm & 0x7).f[0];
- XMM((modrm >> 3) & 0x7).f[1] = 1.0 / XMM(modrm & 0x7).f[1];
- XMM((modrm >> 3) & 0x7).f[2] = 1.0 / XMM(modrm & 0x7).f[2];
- XMM((modrm >> 3) & 0x7).f[3] = 1.0 / XMM(modrm & 0x7).f[3];
- } else {
- XMM_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, src);
- XMM((modrm >> 3) & 0x7).f[0] = 1.0 / src.f[0];
- XMM((modrm >> 3) & 0x7).f[1] = 1.0 / src.f[1];
- XMM((modrm >> 3) & 0x7).f[2] = 1.0 / src.f[2];
- XMM((modrm >> 3) & 0x7).f[3] = 1.0 / src.f[3];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(andps_r128_rm128)() // Opcode 0f 54
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).q[0] = XMM((modrm >> 3) & 0x7).q[0] & XMM(modrm & 0x7).q[0];
- XMM((modrm >> 3) & 0x7).q[1] = XMM((modrm >> 3) & 0x7).q[1] & XMM(modrm & 0x7).q[1];
- } else {
- XMM_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, src);
- XMM((modrm >> 3) & 0x7).q[0] = XMM((modrm >> 3) & 0x7).q[0] & src.q[0];
- XMM((modrm >> 3) & 0x7).q[1] = XMM((modrm >> 3) & 0x7).q[1] & src.q[1];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(andpd_r128_rm128)() // Opcode 66 0f 54
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).q[0] = XMM((modrm >> 3) & 0x7).q[0] & XMM(modrm & 0x7).q[0];
- XMM((modrm >> 3) & 0x7).q[1] = XMM((modrm >> 3) & 0x7).q[1] & XMM(modrm & 0x7).q[1];
- } else {
- XMM_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, src);
- XMM((modrm >> 3) & 0x7).q[0] = XMM((modrm >> 3) & 0x7).q[0] & src.q[0];
- XMM((modrm >> 3) & 0x7).q[1] = XMM((modrm >> 3) & 0x7).q[1] & src.q[1];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(andnps_r128_rm128)() // Opcode 0f 55
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).q[0] = ~(XMM((modrm >> 3) & 0x7).q[0]) & XMM(modrm & 0x7).q[0];
- XMM((modrm >> 3) & 0x7).q[1] = ~(XMM((modrm >> 3) & 0x7).q[1]) & XMM(modrm & 0x7).q[1];
- } else {
- XMM_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, src);
- XMM((modrm >> 3) & 0x7).q[0] = ~(XMM((modrm >> 3) & 0x7).q[0]) & src.q[0];
- XMM((modrm >> 3) & 0x7).q[1] = ~(XMM((modrm >> 3) & 0x7).q[1]) & src.q[1];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(andnpd_r128_rm128)() // Opcode 66 0f 55
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).q[0] = ~(XMM((modrm >> 3) & 0x7).q[0]) & XMM(modrm & 0x7).q[0];
- XMM((modrm >> 3) & 0x7).q[1] = ~(XMM((modrm >> 3) & 0x7).q[1]) & XMM(modrm & 0x7).q[1];
- } else {
- XMM_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, src);
- XMM((modrm >> 3) & 0x7).q[0] = ~(XMM((modrm >> 3) & 0x7).q[0]) & src.q[0];
- XMM((modrm >> 3) & 0x7).q[1] = ~(XMM((modrm >> 3) & 0x7).q[1]) & src.q[1];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(orps_r128_rm128)() // Opcode 0f 56
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).q[0] = XMM((modrm >> 3) & 0x7).q[0] | XMM(modrm & 0x7).q[0];
- XMM((modrm >> 3) & 0x7).q[1] = XMM((modrm >> 3) & 0x7).q[1] | XMM(modrm & 0x7).q[1];
- } else {
- XMM_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, src);
- XMM((modrm >> 3) & 0x7).q[0] = XMM((modrm >> 3) & 0x7).q[0] | src.q[0];
- XMM((modrm >> 3) & 0x7).q[1] = XMM((modrm >> 3) & 0x7).q[1] | src.q[1];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(orpd_r128_rm128)() // Opcode 66 0f 56
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).q[0] = XMM((modrm >> 3) & 0x7).q[0] | XMM(modrm & 0x7).q[0];
- XMM((modrm >> 3) & 0x7).q[1] = XMM((modrm >> 3) & 0x7).q[1] | XMM(modrm & 0x7).q[1];
- } else {
- XMM_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, src);
- XMM((modrm >> 3) & 0x7).q[0] = XMM((modrm >> 3) & 0x7).q[0] | src.q[0];
- XMM((modrm >> 3) & 0x7).q[1] = XMM((modrm >> 3) & 0x7).q[1] | src.q[1];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(mulps)() // Opcode 0f 59 ????
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] * XMM(modrm & 0x7).f[0];
- XMM((modrm >> 3) & 0x7).f[1] = XMM((modrm >> 3) & 0x7).f[1] * XMM(modrm & 0x7).f[1];
- XMM((modrm >> 3) & 0x7).f[2] = XMM((modrm >> 3) & 0x7).f[2] * XMM(modrm & 0x7).f[2];
- XMM((modrm >> 3) & 0x7).f[3] = XMM((modrm >> 3) & 0x7).f[3] * XMM(modrm & 0x7).f[3];
- } else {
- XMM_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, src);
- XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] * src.f[0];
- XMM((modrm >> 3) & 0x7).f[1] = XMM((modrm >> 3) & 0x7).f[1] * src.f[1];
- XMM((modrm >> 3) & 0x7).f[2] = XMM((modrm >> 3) & 0x7).f[2] * src.f[2];
- XMM((modrm >> 3) & 0x7).f[3] = XMM((modrm >> 3) & 0x7).f[3] * src.f[3];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(subps)() // Opcode 0f 5c
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] - XMM(modrm & 0x7).f[0];
- XMM((modrm >> 3) & 0x7).f[1] = XMM((modrm >> 3) & 0x7).f[1] - XMM(modrm & 0x7).f[1];
- XMM((modrm >> 3) & 0x7).f[2] = XMM((modrm >> 3) & 0x7).f[2] - XMM(modrm & 0x7).f[2];
- XMM((modrm >> 3) & 0x7).f[3] = XMM((modrm >> 3) & 0x7).f[3] - XMM(modrm & 0x7).f[3];
- } else {
- XMM_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, src);
- XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] - src.f[0];
- XMM((modrm >> 3) & 0x7).f[1] = XMM((modrm >> 3) & 0x7).f[1] - src.f[1];
- XMM((modrm >> 3) & 0x7).f[2] = XMM((modrm >> 3) & 0x7).f[2] - src.f[2];
- XMM((modrm >> 3) & 0x7).f[3] = XMM((modrm >> 3) & 0x7).f[3] - src.f[3];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
-INLINE float sse_min_single(float src1, float src2)
-{
- /*if ((src1 == 0) && (src2 == 0))
- return src2;
- if (src1 = SNaN)
- return src2;
- if (src2 = SNaN)
- return src2;*/
- if (src1 < src2)
- return src1;
- return src2;
-}
-
-INLINE double sse_min_double(double src1, double src2)
-{
- /*if ((src1 == 0) && (src2 == 0))
- return src2;
- if (src1 = SNaN)
- return src2;
- if (src2 = SNaN)
- return src2;*/
- if (src1 < src2)
- return src1;
- return src2;
-}
-
- void I386_OPS_BASE::SSEOP(minps)() // Opcode 0f 5d
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).f[0] = sse_min_single(XMM((modrm >> 3) & 0x7).f[0], XMM(modrm & 0x7).f[0]);
- XMM((modrm >> 3) & 0x7).f[1] = sse_min_single(XMM((modrm >> 3) & 0x7).f[1], XMM(modrm & 0x7).f[1]);
- XMM((modrm >> 3) & 0x7).f[2] = sse_min_single(XMM((modrm >> 3) & 0x7).f[2], XMM(modrm & 0x7).f[2]);
- XMM((modrm >> 3) & 0x7).f[3] = sse_min_single(XMM((modrm >> 3) & 0x7).f[3], XMM(modrm & 0x7).f[3]);
- } else {
- XMM_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, src);
- XMM((modrm >> 3) & 0x7).f[0] = sse_min_single(XMM((modrm >> 3) & 0x7).f[0], src.f[0]);
- XMM((modrm >> 3) & 0x7).f[1] = sse_min_single(XMM((modrm >> 3) & 0x7).f[1], src.f[1]);
- XMM((modrm >> 3) & 0x7).f[2] = sse_min_single(XMM((modrm >> 3) & 0x7).f[2], src.f[2]);
- XMM((modrm >> 3) & 0x7).f[3] = sse_min_single(XMM((modrm >> 3) & 0x7).f[3], src.f[3]);
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(divps)() // Opcode 0f 5e
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] / XMM(modrm & 0x7).f[0];
- XMM((modrm >> 3) & 0x7).f[1] = XMM((modrm >> 3) & 0x7).f[1] / XMM(modrm & 0x7).f[1];
- XMM((modrm >> 3) & 0x7).f[2] = XMM((modrm >> 3) & 0x7).f[2] / XMM(modrm & 0x7).f[2];
- XMM((modrm >> 3) & 0x7).f[3] = XMM((modrm >> 3) & 0x7).f[3] / XMM(modrm & 0x7).f[3];
- } else {
- XMM_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, src);
- XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] / src.f[0];
- XMM((modrm >> 3) & 0x7).f[1] = XMM((modrm >> 3) & 0x7).f[1] / src.f[1];
- XMM((modrm >> 3) & 0x7).f[2] = XMM((modrm >> 3) & 0x7).f[2] / src.f[2];
- XMM((modrm >> 3) & 0x7).f[3] = XMM((modrm >> 3) & 0x7).f[3] / src.f[3];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
-INLINE float sse_max_single(float src1, float src2)
-{
- /*if ((src1 == 0) && (src2 == 0))
- return src2;
- if (src1 = SNaN)
- return src2;
- if (src2 = SNaN)
- return src2;*/
- if (src1 > src2)
- return src1;
- return src2;
-}
-
-INLINE double sse_max_double(double src1, double src2)
-{
- /*if ((src1 == 0) && (src2 == 0))
- return src2;
- if (src1 = SNaN)
- return src2;
- if (src2 = SNaN)
- return src2;*/
- if (src1 > src2)
- return src1;
- return src2;
-}
-
- void I386_OPS_BASE::SSEOP(maxps)() // Opcode 0f 5f
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).f[0] = sse_max_single(XMM((modrm >> 3) & 0x7).f[0], XMM(modrm & 0x7).f[0]);
- XMM((modrm >> 3) & 0x7).f[1] = sse_max_single(XMM((modrm >> 3) & 0x7).f[1], XMM(modrm & 0x7).f[1]);
- XMM((modrm >> 3) & 0x7).f[2] = sse_max_single(XMM((modrm >> 3) & 0x7).f[2], XMM(modrm & 0x7).f[2]);
- XMM((modrm >> 3) & 0x7).f[3] = sse_max_single(XMM((modrm >> 3) & 0x7).f[3], XMM(modrm & 0x7).f[3]);
- } else {
- XMM_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, src);
- XMM((modrm >> 3) & 0x7).f[0] = sse_max_single(XMM((modrm >> 3) & 0x7).f[0], src.f[0]);
- XMM((modrm >> 3) & 0x7).f[1] = sse_max_single(XMM((modrm >> 3) & 0x7).f[1], src.f[1]);
- XMM((modrm >> 3) & 0x7).f[2] = sse_max_single(XMM((modrm >> 3) & 0x7).f[2], src.f[2]);
- XMM((modrm >> 3) & 0x7).f[3] = sse_max_single(XMM((modrm >> 3) & 0x7).f[3], src.f[3]);
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(maxss_r128_r128m32)() // Opcode f3 0f 5f
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).f[0] = sse_max_single(XMM((modrm >> 3) & 0x7).f[0], XMM(modrm & 0x7).f[0]);
- } else {
- XMM_REG src;
- UINT32 ea = GetEA(modrm, 0);
- src.d[0]=READ32(ea);
- XMM((modrm >> 3) & 0x7).f[0] = sse_max_single(XMM((modrm >> 3) & 0x7).f[0], src.f[0]);
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(addss)() // Opcode f3 0f 58
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] + XMM(modrm & 0x7).f[0];
- } else {
- XMM_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, src);
- XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] + src.f[0];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(subss)() // Opcode f3 0f 5c
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] - XMM(modrm & 0x7).f[0];
- } else {
- XMM_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, src);
- XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] - src.f[0];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(mulss)() // Opcode f3 0f 5e
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] * XMM(modrm & 0x7).f[0];
- } else {
- XMM_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, src);
- XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] * src.f[0];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(divss)() // Opcode 0f 59
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] / XMM(modrm & 0x7).f[0];
- } else {
- XMM_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, src);
- XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] / src.f[0];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(rcpss_r128_r128m32)() // Opcode f3 0f 53
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).f[0] = 1.0 / XMM(modrm & 0x7).f[0];
- } else {
- XMM_REG s;
- UINT32 ea = GetEA(modrm, 0);
- s.d[0]=READ32(ea);
- XMM((modrm >> 3) & 0x7).f[0] = 1.0 / s.f[0];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(sqrtss_r128_r128m32)() // Opcode f3 0f 51
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).f[0] = sqrt(XMM(modrm & 0x7).f[0]);
- } else {
- XMM_REG s;
- UINT32 ea = GetEA(modrm, 0);
- s.d[0]=READ32(ea);
- XMM((modrm >> 3) & 0x7).f[0] = sqrt(s.f[0]);
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(rsqrtss_r128_r128m32)() // Opcode f3 0f 52
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).f[0] = 1.0 / sqrt(XMM(modrm & 0x7).f[0]);
- } else {
- XMM_REG s;
- UINT32 ea = GetEA(modrm, 0);
- s.d[0]=READ32(ea);
- XMM((modrm >> 3) & 0x7).f[0] = 1.0 / sqrt(s.f[0]);
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(minss_r128_r128m32)() // Opcode f3 0f 5d
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] < XMM(modrm & 0x7).f[0] ? XMM((modrm >> 3) & 0x7).f[0] : XMM(modrm & 0x7).f[0];
- } else {
- XMM_REG s;
- UINT32 ea = GetEA(modrm, 0);
- s.d[0] = READ32(ea);
- XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] < s.f[0] ? XMM((modrm >> 3) & 0x7).f[0] : s.f[0];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(comiss_r128_r128m32)() // Opcode 0f 2f
-{
- float32 a,b;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- a = XMM((modrm >> 3) & 0x7).d[0];
- b = XMM(modrm & 0x7).d[0];
- } else {
- XMM_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, src);
- a = XMM((modrm >> 3) & 0x7).d[0];
- b = src.d[0];
- }
- cpustate->OF=0;
- cpustate->SF=0;
- cpustate->AF=0;
- if (float32_is_nan(a) || float32_is_nan(b))
- {
- cpustate->ZF = 1;
- cpustate->PF = 1;
- cpustate->CF = 1;
- }
- else
- {
- cpustate->ZF = 0;
- cpustate->PF = 0;
- cpustate->CF = 0;
- if (float32_eq(a, b))
- cpustate->ZF = 1;
- if (float32_lt(a, b))
- cpustate->CF = 1;
- }
- // should generate exception when at least one of the operands is either QNaN or SNaN
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(comisd_r128_r128m64)() // Opcode 66 0f 2f
-{
- float64 a,b;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- a = XMM((modrm >> 3) & 0x7).q[0];
- b = XMM(modrm & 0x7).q[0];
- } else {
- XMM_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, src);
- a = XMM((modrm >> 3) & 0x7).q[0];
- b = src.q[0];
- }
- cpustate->OF=0;
- cpustate->SF=0;
- cpustate->AF=0;
- if (float64_is_nan(a) || float64_is_nan(b))
- {
- cpustate->ZF = 1;
- cpustate->PF = 1;
- cpustate->CF = 1;
- }
- else
- {
- cpustate->ZF = 0;
- cpustate->PF = 0;
- cpustate->CF = 0;
- if (float64_eq(a, b))
- cpustate->ZF = 1;
- if (float64_lt(a, b))
- cpustate->CF = 1;
- }
- // should generate exception when at least one of the operands is either QNaN or SNaN
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(ucomiss_r128_r128m32)() // Opcode 0f 2e
-{
- float32 a,b;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- a = XMM((modrm >> 3) & 0x7).d[0];
- b = XMM(modrm & 0x7).d[0];
- } else {
- XMM_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, src);
- a = XMM((modrm >> 3) & 0x7).d[0];
- b = src.d[0];
- }
- cpustate->OF=0;
- cpustate->SF=0;
- cpustate->AF=0;
- if (float32_is_nan(a) || float32_is_nan(b))
- {
- cpustate->ZF = 1;
- cpustate->PF = 1;
- cpustate->CF = 1;
- }
- else
- {
- cpustate->ZF = 0;
- cpustate->PF = 0;
- cpustate->CF = 0;
- if (float32_eq(a, b))
- cpustate->ZF = 1;
- if (float32_lt(a, b))
- cpustate->CF = 1;
- }
- // should generate exception when at least one of the operands is SNaN
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(ucomisd_r128_r128m64)() // Opcode 66 0f 2e
-{
- float64 a,b;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- a = XMM((modrm >> 3) & 0x7).q[0];
- b = XMM(modrm & 0x7).q[0];
- } else {
- XMM_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, src);
- a = XMM((modrm >> 3) & 0x7).q[0];
- b = src.q[0];
- }
- cpustate->OF=0;
- cpustate->SF=0;
- cpustate->AF=0;
- if (float64_is_nan(a) || float64_is_nan(b))
- {
- cpustate->ZF = 1;
- cpustate->PF = 1;
- cpustate->CF = 1;
- }
- else
- {
- cpustate->ZF = 0;
- cpustate->PF = 0;
- cpustate->CF = 0;
- if (float64_eq(a, b))
- cpustate->ZF = 1;
- if (float64_lt(a, b))
- cpustate->CF = 1;
- }
- // should generate exception when at least one of the operands is SNaN
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(shufps)() // Opcode 0f c6
-{
- UINT8 modrm = FETCH();
- UINT8 sel = FETCH();
- int m1,m2,m3,m4;
- int s,d;
- m1=sel & 3;
- m2=(sel >> 2) & 3;
- m3=(sel >> 4) & 3;
- m4=(sel >> 6) & 3;
- s=modrm & 0x7;
- d=(modrm >> 3) & 0x7;
- if( modrm >= 0xc0 ) {
- UINT32 t1,t2,t3,t4;
- t1=XMM(d).d[m1];
- t2=XMM(d).d[m2];
- t3=XMM(s).d[m3];
- t4=XMM(s).d[m4];
- XMM(d).d[0]=t1;
- XMM(d).d[1]=t2;
- XMM(d).d[2]=t3;
- XMM(d).d[3]=t4;
- } else {
- UINT32 t1,t2;
- XMM_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, src);
- t1=XMM(d).d[m1];
- t2=XMM(d).d[m2];
- XMM(d).d[0]=t1;
- XMM(d).d[1]=t2;
- XMM(d).d[2]=src.d[m3];
- XMM(d).d[3]=src.d[m4];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(shufpd_r128_rm128_i8)() // Opcode 66 0f c6
-{
- UINT8 modrm = FETCH();
- UINT8 sel = FETCH();
- int m1,m2;
- int s,d;
- m1=sel & 1;
- m2=(sel >> 1) & 1;
- s=modrm & 0x7;
- d=(modrm >> 3) & 0x7;
- if( modrm >= 0xc0 ) {
- UINT64 t1,t2;
- t1=XMM(d).q[m1];
- t2=XMM(s).q[m2];
- XMM(d).q[0]=t1;
- XMM(d).q[1]=t2;
- } else {
- UINT64 t1;
- XMM_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, src);
- t1=XMM(d).q[m1];
- XMM(d).q[0]=t1;
- XMM(d).q[1]=src.q[m2];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(unpcklps_r128_rm128)() // Opcode 0f 14
-{
- UINT8 modrm = FETCH();
- int s,d;
- UINT32 t1, t2, t3, t4;
- s=modrm & 0x7;
- d=(modrm >> 3) & 0x7;
- if( modrm >= 0xc0 ) {
- t1 = XMM(s).d[1];
- t2 = XMM(d).d[1];
- t3 = XMM(s).d[0];
- t4 = XMM(d).d[0];
- XMM(d).d[3]=t1;
- XMM(d).d[2]=t2;
- XMM(d).d[1]=t3;
- XMM(d).d[0]=t4;
- } else {
- XMM_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, src);
- t2 = XMM(d).d[1];
- XMM(d).d[3]=src.d[1];
- XMM(d).d[2]=t2;
- XMM(d).d[1]=src.d[0];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(unpcklpd_r128_rm128)() // Opcode 66 0f 14
-{
- UINT8 modrm = FETCH();
- int s,d;
- s=modrm & 0x7;
- d=(modrm >> 3) & 0x7;
- if( modrm >= 0xc0 ) {
- XMM(d).q[1]=XMM(s).q[0];
- XMM(d).q[0]=XMM(d).q[0];
- } else {
- XMM_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, src);
- XMM(d).q[1]=src.q[0];
- XMM(d).q[0]=XMM(d).q[0];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(unpckhps_r128_rm128)() // Opcode 0f 15
-{
- UINT8 modrm = FETCH();
- int s,d;
- UINT32 t1, t2, t3, t4;
- s=modrm & 0x7;
- d=(modrm >> 3) & 0x7;
- if( modrm >= 0xc0 ) {
- t1 = XMM(d).d[2];
- t2 = XMM(s).d[2];
- t3 = XMM(d).d[3];
- t4 = XMM(s).d[3];
- XMM(d).d[0]=t1;
- XMM(d).d[1]=t2;
- XMM(d).d[2]=t3;
- XMM(d).d[3]=t4;
- } else {
- XMM_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, src);
- t1 = XMM(d).d[2];
- t2 = XMM(d).d[3];
- XMM(d).d[0]=t1;
- XMM(d).d[1]=src.d[2];
- XMM(d).d[2]=t2;
- XMM(d).d[3]=src.d[3];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(unpckhpd_r128_rm128)() // Opcode 66 0f 15
-{
- UINT8 modrm = FETCH();
- int s,d;
- s=modrm & 0x7;
- d=(modrm >> 3) & 0x7;
- if( modrm >= 0xc0 ) {
- XMM(d).q[0]=XMM(d).q[1];
- XMM(d).q[1]=XMM(s).q[1];
- } else {
- XMM_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, src);
- XMM(d).q[0]=XMM(d).q[1];
- XMM(d).q[1]=src.q[1];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
-INLINE bool sse_issingleordered(float op1, float op2)
-{
- // TODO: true when at least one of the two source operands being compared is a NaN
- return (op1 != op1) || (op1 != op2);
-}
-
-INLINE bool sse_issingleunordered(float op1, float op2)
-{
- // TODO: true when neither source operand is a NaN
- return !((op1 != op1) || (op1 != op2));
-}
-
-INLINE bool sse_isdoubleordered(double op1, double op2)
-{
- // TODO: true when at least one of the two source operands being compared is a NaN
- return (op1 != op1) || (op1 != op2);
-}
-
-INLINE bool sse_isdoubleunordered(double op1, double op2)
-{
- // TODO: true when neither source operand is a NaN
- return !((op1 != op1) || (op1 != op2));
-}
-
- void I386_OPS_BASE::SSEOP(predicate_compare_single)(UINT8 imm8, XMM_REG d, XMM_REG s)
-{
- switch (imm8 & 7)
- {
- case 0:
- d.d[0]=d.f[0] == s.f[0] ? 0xffffffff : 0;
- d.d[1]=d.f[1] == s.f[1] ? 0xffffffff : 0;
- d.d[2]=d.f[2] == s.f[2] ? 0xffffffff : 0;
- d.d[3]=d.f[3] == s.f[3] ? 0xffffffff : 0;
- break;
- case 1:
- d.d[0]=d.f[0] < s.f[0] ? 0xffffffff : 0;
- d.d[1]=d.f[1] < s.f[1] ? 0xffffffff : 0;
- d.d[2]=d.f[2] < s.f[2] ? 0xffffffff : 0;
- d.d[3]=d.f[3] < s.f[3] ? 0xffffffff : 0;
- break;
- case 2:
- d.d[0]=d.f[0] <= s.f[0] ? 0xffffffff : 0;
- d.d[1]=d.f[1] <= s.f[1] ? 0xffffffff : 0;
- d.d[2]=d.f[2] <= s.f[2] ? 0xffffffff : 0;
- d.d[3]=d.f[3] <= s.f[3] ? 0xffffffff : 0;
- break;
- case 3:
- d.d[0]=sse_issingleunordered(d.f[0], s.f[0]) ? 0xffffffff : 0;
- d.d[1]=sse_issingleunordered(d.f[1], s.f[1]) ? 0xffffffff : 0;
- d.d[2]=sse_issingleunordered(d.f[2], s.f[2]) ? 0xffffffff : 0;
- d.d[3]=sse_issingleunordered(d.f[3], s.f[3]) ? 0xffffffff : 0;
- break;
- case 4:
- d.d[0]=d.f[0] != s.f[0] ? 0xffffffff : 0;
- d.d[1]=d.f[1] != s.f[1] ? 0xffffffff : 0;
- d.d[2]=d.f[2] != s.f[2] ? 0xffffffff : 0;
- d.d[3]=d.f[3] != s.f[3] ? 0xffffffff : 0;
- break;
- case 5:
- d.d[0]=d.f[0] < s.f[0] ? 0 : 0xffffffff;
- d.d[1]=d.f[1] < s.f[1] ? 0 : 0xffffffff;
- d.d[2]=d.f[2] < s.f[2] ? 0 : 0xffffffff;
- d.d[3]=d.f[3] < s.f[3] ? 0 : 0xffffffff;
- break;
- case 6:
- d.d[0]=d.f[0] <= s.f[0] ? 0 : 0xffffffff;
- d.d[1]=d.f[1] <= s.f[1] ? 0 : 0xffffffff;
- d.d[2]=d.f[2] <= s.f[2] ? 0 : 0xffffffff;
- d.d[3]=d.f[3] <= s.f[3] ? 0 : 0xffffffff;
- break;
- case 7:
- d.d[0]=sse_issingleordered(d.f[0], s.f[0]) ? 0xffffffff : 0;
- d.d[1]=sse_issingleordered(d.f[1], s.f[1]) ? 0xffffffff : 0;
- d.d[2]=sse_issingleordered(d.f[2], s.f[2]) ? 0xffffffff : 0;
- d.d[3]=sse_issingleordered(d.f[3], s.f[3]) ? 0xffffffff : 0;
- break;
- }
-}
-
- void I386_OPS_BASE::SSEOP(predicate_compare_double)(UINT8 imm8, XMM_REG d, XMM_REG s)
-{
- switch (imm8 & 7)
- {
- case 0:
- d.q[0]=d.f64[0] == s.f64[0] ? 0xffffffffffffffff : 0;
- d.q[1]=d.f64[1] == s.f64[1] ? 0xffffffffffffffff : 0;
- break;
- case 1:
- d.q[0]=d.f64[0] < s.f64[0] ? 0xffffffffffffffff : 0;
- d.q[1]=d.f64[1] < s.f64[1] ? 0xffffffffffffffff : 0;
- break;
- case 2:
- d.q[0]=d.f64[0] <= s.f64[0] ? 0xffffffffffffffff : 0;
- d.q[1]=d.f64[1] <= s.f64[1] ? 0xffffffffffffffff : 0;
- break;
- case 3:
- d.q[0]=sse_isdoubleunordered(d.f64[0], s.f64[0]) ? 0xffffffffffffffff : 0;
- d.q[1]=sse_isdoubleunordered(d.f64[1], s.f64[1]) ? 0xffffffffffffffff : 0;
- break;
- case 4:
- d.q[0]=d.f64[0] != s.f64[0] ? 0xffffffffffffffff : 0;
- d.q[1]=d.f64[1] != s.f64[1] ? 0xffffffffffffffff : 0;
- break;
- case 5:
- d.q[0]=d.f64[0] < s.f64[0] ? 0 : 0xffffffffffffffff;
- d.q[1]=d.f64[1] < s.f64[1] ? 0 : 0xffffffffffffffff;
- break;
- case 6:
- d.q[0]=d.f64[0] <= s.f64[0] ? 0 : 0xffffffffffffffff;
- d.q[1]=d.f64[1] <= s.f64[1] ? 0 : 0xffffffffffffffff;
- break;
- case 7:
- d.q[0]=sse_isdoubleordered(d.f64[0], s.f64[0]) ? 0xffffffffffffffff : 0;
- d.q[1]=sse_isdoubleordered(d.f64[1], s.f64[1]) ? 0xffffffffffffffff : 0;
- break;
- }
-}
-
- void I386_OPS_BASE::SSEOP(predicate_compare_single_scalar)(UINT8 imm8, XMM_REG d, XMM_REG s)
-{
- switch (imm8 & 7)
- {
- case 0:
- d.d[0]=d.f[0] == s.f[0] ? 0xffffffff : 0;
- break;
- case 1:
- d.d[0]=d.f[0] < s.f[0] ? 0xffffffff : 0;
- break;
- case 2:
- d.d[0]=d.f[0] <= s.f[0] ? 0xffffffff : 0;
- break;
- case 3:
- d.d[0]=sse_issingleunordered(d.f[0], s.f[0]) ? 0xffffffff : 0;
- break;
- case 4:
- d.d[0]=d.f[0] != s.f[0] ? 0xffffffff : 0;
- break;
- case 5:
- d.d[0]=d.f[0] < s.f[0] ? 0 : 0xffffffff;
- break;
- case 6:
- d.d[0]=d.f[0] <= s.f[0] ? 0 : 0xffffffff;
- break;
- case 7:
- d.d[0]=sse_issingleordered(d.f[0], s.f[0]) ? 0xffffffff : 0;
- break;
- }
-}
-
- void I386_OPS_BASE::SSEOP(predicate_compare_double_scalar)(UINT8 imm8, XMM_REG d, XMM_REG s)
-{
- switch (imm8 & 7)
- {
- case 0:
- d.q[0]=d.f64[0] == s.f64[0] ? 0xffffffffffffffff : 0;
- break;
- case 1:
- d.q[0]=d.f64[0] < s.f64[0] ? 0xffffffffffffffff : 0;
- break;
- case 2:
- d.q[0]=d.f64[0] <= s.f64[0] ? 0xffffffffffffffff : 0;
- break;
- case 3:
- d.q[0]=sse_isdoubleunordered(d.f64[0], s.f64[0]) ? 0xffffffffffffffff : 0;
- break;
- case 4:
- d.q[0]=d.f64[0] != s.f64[0] ? 0xffffffffffffffff : 0;
- break;
- case 5:
- d.q[0]=d.f64[0] < s.f64[0] ? 0 : 0xffffffffffffffff;
- break;
- case 6:
- d.q[0]=d.f64[0] <= s.f64[0] ? 0 : 0xffffffffffffffff;
- break;
- case 7:
- d.q[0]=sse_isdoubleordered(d.f64[0], s.f64[0]) ? 0xffffffffffffffff : 0;
- break;
- }
-}
-
- void I386_OPS_BASE::SSEOP(cmpps_r128_rm128_i8)() // Opcode 0f c2
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- int s,d;
- UINT8 imm8 = FETCH();
- s=modrm & 0x7;
- d=(modrm >> 3) & 0x7;
- sse_predicate_compare_single(imm8, XMM(d), XMM(s));
- } else {
- int d;
- XMM_REG s;
- UINT32 ea = GetEA(modrm, 0);
- UINT8 imm8 = FETCH();
- READXMM( ea, s);
- d=(modrm >> 3) & 0x7;
- sse_predicate_compare_single(imm8, XMM(d), s);
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(cmppd_r128_rm128_i8)() // Opcode 66 0f c2
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- int s,d;
- UINT8 imm8 = FETCH();
- s=modrm & 0x7;
- d=(modrm >> 3) & 0x7;
- sse_predicate_compare_double(imm8, XMM(d), XMM(s));
- } else {
- int d;
- XMM_REG s;
- UINT32 ea = GetEA(modrm, 0);
- UINT8 imm8 = FETCH();
- READXMM( ea, s);
- d=(modrm >> 3) & 0x7;
- sse_predicate_compare_double(imm8, XMM(d), s);
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(cmpss_r128_r128m32_i8)() // Opcode f3 0f c2
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- int s,d;
- UINT8 imm8 = FETCH();
- s=modrm & 0x7;
- d=(modrm >> 3) & 0x7;
- sse_predicate_compare_single_scalar(imm8, XMM(d), XMM(s));
- } else {
- int d;
- XMM_REG s;
- UINT32 ea = GetEA(modrm, 0);
- UINT8 imm8 = FETCH();
- s.d[0]=READ32(ea);
- d=(modrm >> 3) & 0x7;
- sse_predicate_compare_single_scalar(imm8, XMM(d), s);
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(pinsrw_r64_r16m16_i8)() // Opcode 0f c4, 16bit register
-{
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- UINT8 imm8 = FETCH();
- UINT16 v = LOAD_RM16(modrm);
- if (cpustate->xmm_operand_size)
- XMM((modrm >> 3) & 0x7).w[imm8 & 7] = v;
- else
- MMX((modrm >> 3) & 0x7).w[imm8 & 3] = v;
- } else {
- UINT32 ea = GetEA(modrm, 0);
- UINT8 imm8 = FETCH();
- UINT16 v = READ16(ea);
- if (cpustate->xmm_operand_size)
- XMM((modrm >> 3) & 0x7).w[imm8 & 7] = v;
- else
- MMX((modrm >> 3) & 0x7).w[imm8 & 3] = v;
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(pinsrw_r64_r32m16_i8)() // Opcode 0f c4, 32bit register
-{
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- UINT8 imm8 = FETCH();
- UINT16 v = (UINT16)LOAD_RM32(modrm);
- MMX((modrm >> 3) & 0x7).w[imm8 & 3] = v;
- } else {
- UINT32 ea = GetEA(modrm, 0);
- UINT8 imm8 = FETCH();
- UINT16 v = READ16(ea);
- MMX((modrm >> 3) & 0x7).w[imm8 & 3] = v;
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(pinsrw_r128_r32m16_i8)() // Opcode 66 0f c4
-{
- UINT8 modrm = FETCH();
- if (modrm >= 0xc0) {
- UINT8 imm8 = FETCH();
- UINT16 v = (UINT16)LOAD_RM32(modrm);
- XMM((modrm >> 3) & 0x7).w[imm8 & 7] = v;
- }
- else {
- UINT32 ea = GetEA(modrm, 0);
- UINT8 imm8 = FETCH();
- UINT16 v = READ16(ea);
- XMM((modrm >> 3) & 0x7).w[imm8 & 7] = v;
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(pextrw_r16_r64_i8)() // Opcode 0f c5
-{
- //MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- UINT8 imm8 = FETCH();
- if (cpustate->xmm_operand_size)
- STORE_REG16(modrm, XMM(modrm & 0x7).w[imm8 & 7]);
- else
- STORE_REG16(modrm, MMX(modrm & 0x7).w[imm8 & 3]);
- } else {
- //UINT8 imm8 = FETCH();
- report_invalid_modrm( "pextrw_r16_r64_i8", modrm);
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(pextrw_r32_r64_i8)() // Opcode 0f c5
-{
- //MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- UINT8 imm8 = FETCH();
- STORE_REG32(modrm, MMX(modrm & 0x7).w[imm8 & 3]);
- } else {
- //UINT8 imm8 = FETCH();
- report_invalid_modrm( "pextrw_r32_r64_i8", modrm);
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(pextrw_reg_r128_i8)() // Opcode 66 0f c5
-{
- UINT8 modrm = FETCH();
- if (modrm >= 0xc0) {
- UINT8 imm8 = FETCH();
- STORE_REG32(modrm, XMM(modrm & 0x7).w[imm8 & 7]);
- }
- else {
- //UINT8 imm8 = FETCH();
- report_invalid_modrm( "sse_pextrw_reg_r128_i8", modrm);
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(pminub_r64_rm64)() // Opcode 0f da
-{
- int n;
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- for (n=0;n < 8;n++)
- MMX((modrm >> 3) & 0x7).b[n] = MMX((modrm >> 3) & 0x7).b[n] < MMX(modrm & 0x7).b[n] ? MMX((modrm >> 3) & 0x7).b[n] : MMX(modrm & 0x7).b[n];
- } else {
- MMX_REG s;
- UINT32 ea = GetEA(modrm, 0);
- READMMX( ea, s);
- for (n=0;n < 8;n++)
- MMX((modrm >> 3) & 0x7).b[n] = MMX((modrm >> 3) & 0x7).b[n] < s.b[n] ? MMX((modrm >> 3) & 0x7).b[n] : s.b[n];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(pminub_r128_rm128)() // Opcode 66 0f da
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- for (int n=0;n < 16;n++)
- XMM((modrm >> 3) & 0x7).b[n] = XMM((modrm >> 3) & 0x7).b[n] < XMM(modrm & 0x7).b[n] ? XMM((modrm >> 3) & 0x7).b[n] : XMM(modrm & 0x7).b[n];
- } else {
- XMM_REG s;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, s);
- for (int n=0;n < 16;n++)
- XMM((modrm >> 3) & 0x7).b[n] = XMM((modrm >> 3) & 0x7).b[n] < s.b[n] ? XMM((modrm >> 3) & 0x7).b[n] : s.b[n];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(pmaxub_r64_rm64)() // Opcode 0f de
-{
- int n;
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- for (n=0;n < 8;n++)
- MMX((modrm >> 3) & 0x7).b[n] = MMX((modrm >> 3) & 0x7).b[n] > MMX(modrm & 0x7).b[n] ? MMX((modrm >> 3) & 0x7).b[n] : MMX(modrm & 0x7).b[n];
- } else {
- MMX_REG s;
- UINT32 ea = GetEA(modrm, 0);
- READMMX( ea, s);
- for (n=0;n < 8;n++)
- MMX((modrm >> 3) & 0x7).b[n] = MMX((modrm >> 3) & 0x7).b[n] > s.b[n] ? MMX((modrm >> 3) & 0x7).b[n] : s.b[n];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(pavgb_r64_rm64)() // Opcode 0f e0
-{
- int n;
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- for (n=0;n < 8;n++)
- MMX((modrm >> 3) & 0x7).b[n] = ((UINT16)MMX((modrm >> 3) & 0x7).b[n] + (UINT16)MMX(modrm & 0x7).b[n] + 1) >> 1;
- } else {
- MMX_REG s;
- UINT32 ea = GetEA(modrm, 0);
- READMMX( ea, s);
- for (n=0;n < 8;n++)
- MMX((modrm >> 3) & 0x7).b[n] = ((UINT16)MMX((modrm >> 3) & 0x7).b[n] + (UINT16)s.b[n] + 1) >> 1;
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(pavgw_r64_rm64)() // Opcode 0f e3
-{
- int n;
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- for (n=0;n < 4;n++)
- MMX((modrm >> 3) & 0x7).w[n] = ((UINT32)MMX((modrm >> 3) & 0x7).w[n] + (UINT32)MMX(modrm & 0x7).w[n] + 1) >> 1;
- } else {
- MMX_REG s;
- UINT32 ea = GetEA(modrm, 0);
- READMMX( ea, s);
- for (n=0;n < 4;n++)
- MMX((modrm >> 3) & 0x7).w[n] = ((UINT32)MMX((modrm >> 3) & 0x7).w[n] + (UINT32)s.w[n] + 1) >> 1;
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(pmulhuw_r64_rm64)() // Opcode 0f e4
-{
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- MMX((modrm >> 3) & 0x7).w[0]=((UINT32)MMX((modrm >> 3) & 0x7).w[0]*(UINT32)MMX(modrm & 7).w[0]) >> 16;
- MMX((modrm >> 3) & 0x7).w[1]=((UINT32)MMX((modrm >> 3) & 0x7).w[1]*(UINT32)MMX(modrm & 7).w[1]) >> 16;
- MMX((modrm >> 3) & 0x7).w[2]=((UINT32)MMX((modrm >> 3) & 0x7).w[2]*(UINT32)MMX(modrm & 7).w[2]) >> 16;
- MMX((modrm >> 3) & 0x7).w[3]=((UINT32)MMX((modrm >> 3) & 0x7).w[3]*(UINT32)MMX(modrm & 7).w[3]) >> 16;
- } else {
- MMX_REG s;
- UINT32 ea = GetEA(modrm, 0);
- READMMX( ea, s);
- MMX((modrm >> 3) & 0x7).w[0]=((UINT32)MMX((modrm >> 3) & 0x7).w[0]*(UINT32)s.w[0]) >> 16;
- MMX((modrm >> 3) & 0x7).w[1]=((UINT32)MMX((modrm >> 3) & 0x7).w[1]*(UINT32)s.w[1]) >> 16;
- MMX((modrm >> 3) & 0x7).w[2]=((UINT32)MMX((modrm >> 3) & 0x7).w[2]*(UINT32)s.w[2]) >> 16;
- MMX((modrm >> 3) & 0x7).w[3]=((UINT32)MMX((modrm >> 3) & 0x7).w[3]*(UINT32)s.w[3]) >> 16;
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(pminsw_r64_rm64)() // Opcode 0f ea
-{
- int n;
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- for (n=0;n < 4;n++)
- MMX((modrm >> 3) & 0x7).s[n] = MMX((modrm >> 3) & 0x7).s[n] < MMX(modrm & 0x7).s[n] ? MMX((modrm >> 3) & 0x7).s[n] : MMX(modrm & 0x7).s[n];
- } else {
- MMX_REG s;
- UINT32 ea = GetEA(modrm, 0);
- READMMX( ea, s);
- for (n=0;n < 4;n++)
- MMX((modrm >> 3) & 0x7).s[n] = MMX((modrm >> 3) & 0x7).s[n] < s.s[n] ? MMX((modrm >> 3) & 0x7).s[n] : s.s[n];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(pmaxsw_r64_rm64)() // Opcode 0f ee
-{
- int n;
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- for (n=0;n < 4;n++)
- MMX((modrm >> 3) & 0x7).s[n] = MMX((modrm >> 3) & 0x7).s[n] > MMX(modrm & 0x7).s[n] ? MMX((modrm >> 3) & 0x7).s[n] : MMX(modrm & 0x7).s[n];
- } else {
- MMX_REG s;
- UINT32 ea = GetEA(modrm, 0);
- READMMX( ea, s);
- for (n=0;n < 4;n++)
- MMX((modrm >> 3) & 0x7).s[n] = MMX((modrm >> 3) & 0x7).s[n] > s.s[n] ? MMX((modrm >> 3) & 0x7).s[n] : s.s[n];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(pmuludq_r64_rm64)() // Opcode 0f f4
-{
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- MMX((modrm >> 3) & 0x7).q = (UINT64)MMX((modrm >> 3) & 0x7).d[0] * (UINT64)MMX(modrm & 0x7).d[0];
- } else {
- MMX_REG s;
- UINT32 ea = GetEA(modrm, 0);
- READMMX( ea, s);
- MMX((modrm >> 3) & 0x7).q = (UINT64)MMX((modrm >> 3) & 0x7).d[0] * (UINT64)s.d[0];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(pmuludq_r128_rm128)() // Opcode 66 0f f4
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).q[0] = (UINT64)XMM((modrm >> 3) & 0x7).d[0] * (UINT64)XMM(modrm & 0x7).d[0];
- XMM((modrm >> 3) & 0x7).q[1] = (UINT64)XMM((modrm >> 3) & 0x7).d[2] * (UINT64)XMM(modrm & 0x7).d[2];
- } else {
- XMM_REG s;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, s);
- XMM((modrm >> 3) & 0x7).q[0] = (UINT64)XMM((modrm >> 3) & 0x7).d[0] * (UINT64)s.d[0];
- XMM((modrm >> 3) & 0x7).q[1] = (UINT64)XMM((modrm >> 3) & 0x7).d[2] * (UINT64)s.d[2];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(psadbw_r64_rm64)() // Opcode 0f f6
-{
- int n;
- INT32 temp;
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- temp=0;
- for (n=0;n < 8;n++)
- temp += abs((INT32)MMX((modrm >> 3) & 0x7).b[n] - (INT32)MMX(modrm & 0x7).b[n]);
- MMX((modrm >> 3) & 0x7).l=(UINT64)temp & 0xffff;
- } else {
- MMX_REG s;
- UINT32 ea = GetEA(modrm, 0);
- READMMX( ea, s);
- temp=0;
- for (n=0;n < 8;n++)
- temp += abs((INT32)MMX((modrm >> 3) & 0x7).b[n] - (INT32)s.b[n]);
- MMX((modrm >> 3) & 0x7).l=(UINT64)temp & 0xffff;
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(psubq_r64_rm64)() // Opcode 0f fb
-{
- MMXPROLOG();
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q - MMX(modrm & 7).q;
- } else {
- MMX_REG s;
- UINT32 ea = GetEA(modrm, 0);
- READMMX( ea, s);
- MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q - s.q;
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(psubq_r128_rm128)() // Opcode 66 0f fb
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).q[0]=XMM((modrm >> 3) & 0x7).q[0] - XMM(modrm & 7).q[0];
- XMM((modrm >> 3) & 0x7).q[1]=XMM((modrm >> 3) & 0x7).q[1] - XMM(modrm & 7).q[1];
- } else {
- XMM_REG s;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, s);
- XMM((modrm >> 3) & 0x7).q[0]=XMM((modrm >> 3) & 0x7).q[0] - s.q[0];
- XMM((modrm >> 3) & 0x7).q[1]=XMM((modrm >> 3) & 0x7).q[1] - s.q[1];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(pshufd_r128_rm128_i8)() // Opcode 66 0f 70
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM_REG t;
- int s,d;
- UINT8 imm8 = FETCH();
- s=modrm & 0x7;
- d=(modrm >> 3) & 0x7;
- t.q[0]=XMM(s).q[0];
- t.q[1]=XMM(s).q[1];
- XMM(d).d[0]=t.d[imm8 & 3];
- XMM(d).d[1]=t.d[(imm8 >> 2) & 3];
- XMM(d).d[2]=t.d[(imm8 >> 4) & 3];
- XMM(d).d[3]=t.d[(imm8 >> 6) & 3];
- } else {
- XMM_REG s;
- int d=(modrm >> 3) & 0x7;
- UINT32 ea = GetEA(modrm, 0);
- UINT8 imm8 = FETCH();
- READXMM( ea, s);
- XMM(d).d[0]=s.d[(imm8 & 3)];
- XMM(d).d[1]=s.d[((imm8 >> 2) & 3)];
- XMM(d).d[2]=s.d[((imm8 >> 4) & 3)];
- XMM(d).d[3]=s.d[((imm8 >> 6) & 3)];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(pshuflw_r128_rm128_i8)() // Opcode f2 0f 70
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM_REG t;
- int s,d;
- UINT8 imm8 = FETCH();
- s=modrm & 0x7;
- d=(modrm >> 3) & 0x7;
- t.q[0]=XMM(s).q[0];
- XMM(d).q[1]=XMM(s).q[1];
- XMM(d).w[0]=t.w[imm8 & 3];
- XMM(d).w[1]=t.w[(imm8 >> 2) & 3];
- XMM(d).w[2]=t.w[(imm8 >> 4) & 3];
- XMM(d).w[3]=t.w[(imm8 >> 6) & 3];
- } else {
- XMM_REG s;
- int d=(modrm >> 3) & 0x7;
- UINT32 ea = GetEA(modrm, 0);
- UINT8 imm8 = FETCH();
- READXMM( ea, s);
- XMM(d).q[1]=s.q[1];
- XMM(d).w[0]=s.w[imm8 & 3];
- XMM(d).w[1]=s.w[(imm8 >> 2) & 3];
- XMM(d).w[2]=s.w[(imm8 >> 4) & 3];
- XMM(d).w[3]=s.w[(imm8 >> 6) & 3];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(pshufhw_r128_rm128_i8)() // Opcode f3 0f 70
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM_REG t;
- int s,d;
- UINT8 imm8 = FETCH();
- s=modrm & 0x7;
- d=(modrm >> 3) & 0x7;
- t.q[0]=XMM(s).q[1];
- XMM(d).q[0]=XMM(s).q[0];
- XMM(d).w[4]=t.w[imm8 & 3];
- XMM(d).w[5]=t.w[(imm8 >> 2) & 3];
- XMM(d).w[6]=t.w[(imm8 >> 4) & 3];
- XMM(d).w[7]=t.w[(imm8 >> 6) & 3];
- } else {
- XMM_REG s;
- int d=(modrm >> 3) & 0x7;
- UINT32 ea = GetEA(modrm, 0);
- UINT8 imm8 = FETCH();
- READXMM( ea, s);
- XMM(d).q[0]=s.q[0];
- XMM(d).w[4]=s.w[4 + (imm8 & 3)];
- XMM(d).w[5]=s.w[4 + ((imm8 >> 2) & 3)];
- XMM(d).w[6]=s.w[4 + ((imm8 >> 4) & 3)];
- XMM(d).w[7]=s.w[4 + ((imm8 >> 6) & 3)];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(packsswb_r128_rm128)() // Opcode 66 0f 63
-{
- UINT8 modrm = FETCH();
- if (modrm >= 0xc0) {
- XMM_REG t;
- int s, d;
- s = modrm & 0x7;
- d = (modrm >> 3) & 0x7;
- t.q[0] = XMM(s).q[0];
- t.q[1] = XMM(s).q[1];
- for (int n = 0; n < 8; n++)
- XMM(d).c[n] = SaturatedSignedWordToSignedByte(XMM(d).s[n]);
- for (int n = 0; n < 8; n++)
- XMM(d).c[n+8] = SaturatedSignedWordToSignedByte(t.s[n]);
- }
- else {
- XMM_REG s;
- int d = (modrm >> 3) & 0x7;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, s);
- for (int n = 0; n < 8; n++)
- XMM(d).c[n] = SaturatedSignedWordToSignedByte(XMM(d).s[n]);
- for (int n = 0; n < 8; n++)
- XMM(d).c[n + 8] = SaturatedSignedWordToSignedByte(s.s[n]);
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(packssdw_r128_rm128)() // Opcode 66 0f 6b
-{
- UINT8 modrm = FETCH();
- if (modrm >= 0xc0) {
- XMM_REG t;
- int s, d;
- s = modrm & 0x7;
- d = (modrm >> 3) & 0x7;
- t.q[0] = XMM(s).q[0];
- t.q[1] = XMM(s).q[1];
- XMM(d).s[0] = SaturatedSignedDwordToSignedWord(XMM(d).i[0]);
- XMM(d).s[1] = SaturatedSignedDwordToSignedWord(XMM(d).i[1]);
- XMM(d).s[2] = SaturatedSignedDwordToSignedWord(XMM(d).i[2]);
- XMM(d).s[3] = SaturatedSignedDwordToSignedWord(XMM(d).i[3]);
- XMM(d).s[4] = SaturatedSignedDwordToSignedWord(t.i[0]);
- XMM(d).s[5] = SaturatedSignedDwordToSignedWord(t.i[1]);
- XMM(d).s[6] = SaturatedSignedDwordToSignedWord(t.i[2]);
- XMM(d).s[7] = SaturatedSignedDwordToSignedWord(t.i[3]);
- }
- else {
- XMM_REG s;
- int d = (modrm >> 3) & 0x7;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, s);
- XMM(d).s[0] = SaturatedSignedDwordToSignedWord(XMM(d).i[0]);
- XMM(d).s[1] = SaturatedSignedDwordToSignedWord(XMM(d).i[1]);
- XMM(d).s[2] = SaturatedSignedDwordToSignedWord(XMM(d).i[2]);
- XMM(d).s[3] = SaturatedSignedDwordToSignedWord(XMM(d).i[3]);
- XMM(d).s[4] = SaturatedSignedDwordToSignedWord(s.i[0]);
- XMM(d).s[5] = SaturatedSignedDwordToSignedWord(s.i[1]);
- XMM(d).s[6] = SaturatedSignedDwordToSignedWord(s.i[2]);
- XMM(d).s[7] = SaturatedSignedDwordToSignedWord(s.i[3]);
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(pcmpgtb_r128_rm128)() // Opcode 66 0f 64
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- int s,d;
- s=modrm & 0x7;
- d=(modrm >> 3) & 0x7;
- for (int c=0;c <= 15;c++)
- XMM(d).b[c]=(XMM(d).c[c] > XMM(s).c[c]) ? 0xff : 0;
- } else {
- XMM_REG s;
- int d=(modrm >> 3) & 0x7;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, s);
- for (int c=0;c <= 15;c++)
- XMM(d).b[c]=(XMM(d).c[c] > s.c[c]) ? 0xff : 0;
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(pcmpgtw_r128_rm128)() // Opcode 66 0f 65
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- int s,d;
- s=modrm & 0x7;
- d=(modrm >> 3) & 0x7;
- for (int c=0;c <= 7;c++)
- XMM(d).w[c]=(XMM(d).s[c] > XMM(s).s[c]) ? 0xffff : 0;
- } else {
- XMM_REG s;
- int d=(modrm >> 3) & 0x7;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, s);
- for (int c=0;c <= 7;c++)
- XMM(d).w[c]=(XMM(d).s[c] > s.s[c]) ? 0xffff : 0;
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(pcmpgtd_r128_rm128)() // Opcode 66 0f 66
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- int s,d;
- s=modrm & 0x7;
- d=(modrm >> 3) & 0x7;
- for (int c=0;c <= 3;c++)
- XMM(d).d[c]=(XMM(d).i[c] > XMM(s).i[c]) ? 0xffffffff : 0;
- } else {
- XMM_REG s;
- int d=(modrm >> 3) & 0x7;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, s);
- for (int c=0;c <= 3;c++)
- XMM(d).d[c]=(XMM(d).i[c] > s.i[c]) ? 0xffffffff : 0;
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(packuswb_r128_rm128)() // Opcode 66 0f 67
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM_REG t;
- int s,d;
- s=modrm & 0x7;
- d=(modrm >> 3) & 0x7;
- t.q[0] = XMM(s).q[0];
- t.q[1] = XMM(s).q[1];
- for (int n = 0; n < 8;n++)
- XMM(d).b[n]=SaturatedSignedWordToUnsignedByte(XMM(d).s[n]);
- for (int n = 0; n < 8;n++)
- XMM(d).b[n+8]=SaturatedSignedWordToUnsignedByte(t.s[n]);
- } else {
- XMM_REG s;
- int d=(modrm >> 3) & 0x7;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, s);
- for (int n = 0; n < 8;n++)
- XMM(d).b[n]=SaturatedSignedWordToUnsignedByte(XMM(d).s[n]);
- for (int n = 0; n < 8;n++)
- XMM(d).b[n+8]=SaturatedSignedWordToUnsignedByte(s.s[n]);
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(punpckhbw_r128_rm128)() // Opcode 66 0f 68
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM_REG t;
- int s,d;
- s=modrm & 0x7;
- d=(modrm >> 3) & 0x7;
- t.q[1] = XMM(s).q[1];
- for (int n = 0; n < 16; n += 2) {
- XMM(d).b[n]=XMM(d).b[8+(n >> 1)];
- XMM(d).b[n+1]=t.b[8+(n >> 1)];
- }
- } else {
- XMM_REG s;
- int d=(modrm >> 3) & 0x7;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, s);
- for (int n = 0; n < 16; n += 2) {
- XMM(d).b[n]=XMM(d).b[8+(n >> 1)];
- XMM(d).b[n+1]=s.b[8+(n >> 1)];
- }
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(punpckhwd_r128_rm128)() // Opcode 66 0f 69
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM_REG t;
- int s,d;
- s=modrm & 0x7;
- d=(modrm >> 3) & 0x7;
- t.q[1] = XMM(s).q[1];
- for (int n = 0; n < 8; n += 2) {
- XMM(d).w[n]=XMM(d).w[4+(n >> 1)];
- XMM(d).w[n+1]=t.w[4+(n >> 1)];
- }
- } else {
- XMM_REG s;
- int d=(modrm >> 3) & 0x7;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, s);
- for (int n = 0; n < 8; n += 2) {
- XMM(d).w[n]=XMM(d).w[4+(n >> 1)];
- XMM(d).w[n+1]=s.w[4+(n >> 1)];
- }
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(unpckhdq_r128_rm128)() // Opcode 66 0f 6a
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM_REG t;
- int s,d;
- s=modrm & 0x7;
- d=(modrm >> 3) & 0x7;
- t.q[1] = XMM(s).q[1];
- XMM(d).d[0]=XMM(d).d[2];
- XMM(d).d[1]=t.d[2];
- XMM(d).d[2]=XMM(d).d[3];
- XMM(d).d[3]=t.d[3];
- } else {
- XMM_REG s;
- int d=(modrm >> 3) & 0x7;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, s);
- XMM(d).d[0]=XMM(d).d[2];
- XMM(d).d[1]=s.d[2];
- XMM(d).d[2]=XMM(d).d[3];
- XMM(d).d[3]=s.d[3];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(punpckhqdq_r128_rm128)() // Opcode 66 0f 6d
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM_REG t;
- int s,d;
- s=modrm & 0x7;
- d=(modrm >> 3) & 0x7;
- t.q[1] = XMM(s).q[1];
- XMM(d).q[0]=XMM(d).q[1];
- XMM(d).q[1]=t.q[1];
- } else {
- XMM_REG s;
- int d=(modrm >> 3) & 0x7;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, s);
- XMM(d).q[0]=XMM(d).q[1];
- XMM(d).q[1]=s.q[1];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(pcmpeqb_r128_rm128)() // Opcode 66 0f 74
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- int s,d;
- s=modrm & 0x7;
- d=(modrm >> 3) & 0x7;
- for (int c=0;c <= 15;c++)
- XMM(d).b[c]=(XMM(d).c[c] == XMM(s).c[c]) ? 0xff : 0;
- } else {
- XMM_REG s;
- int d=(modrm >> 3) & 0x7;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, s);
- for (int c=0;c <= 15;c++)
- XMM(d).b[c]=(XMM(d).c[c] == s.c[c]) ? 0xff : 0;
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(pcmpeqw_r128_rm128)() // Opcode 66 0f 75
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- int s,d;
- s=modrm & 0x7;
- d=(modrm >> 3) & 0x7;
- for (int c=0;c <= 7;c++)
- XMM(d).w[c]=(XMM(d).s[c] == XMM(s).s[c]) ? 0xffff : 0;
- } else {
- XMM_REG s;
- int d=(modrm >> 3) & 0x7;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, s);
- for (int c=0;c <= 7;c++)
- XMM(d).w[c]=(XMM(d).s[c] == s.s[c]) ? 0xffff : 0;
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(pcmpeqd_r128_rm128)() // Opcode 66 0f 76
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- int s,d;
- s=modrm & 0x7;
- d=(modrm >> 3) & 0x7;
- for (int c=0;c <= 3;c++)
- XMM(d).d[c]=(XMM(d).i[c] == XMM(s).i[c]) ? 0xffffffff : 0;
- } else {
- XMM_REG s;
- int d=(modrm >> 3) & 0x7;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, s);
- for (int c=0;c <= 3;c++)
- XMM(d).d[c]=(XMM(d).i[c] == s.i[c]) ? 0xffffffff : 0;
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(paddq_r128_rm128)() // Opcode 66 0f d4
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- int s,d;
- s=modrm & 0x7;
- d=(modrm >> 3) & 0x7;
- XMM(d).q[0]=XMM(d).q[0]+XMM(s).q[0];
- XMM(d).q[1]=XMM(d).q[1]+XMM(s).q[1];
- } else {
- XMM_REG src;
- int d=(modrm >> 3) & 0x7;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, src);
- XMM(d).q[0]=XMM(d).q[0]+src.q[0];
- XMM(d).q[1]=XMM(d).q[1]+src.q[1];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(pmullw_r128_rm128)() // Opcode 66 0f d5
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- int s,d;
- s=modrm & 0x7;
- d=(modrm >> 3) & 0x7;
- for (int n = 0; n < 8;n++)
- XMM(d).w[n]=(UINT32)((INT32)XMM(d).s[n]*(INT32)XMM(s).s[n]) & 0xffff;
- } else {
- XMM_REG src;
- int d;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, src);
- d=(modrm >> 3) & 0x7;
- for (int n = 0; n < 8;n++)
- XMM(d).w[n]=(UINT32)((INT32)XMM(d).s[n]*(INT32)src.s[n]) & 0xffff;
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(paddb_r128_rm128)() // Opcode 66 0f fc
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- for (int n=0;n < 16;n++)
- XMM((modrm >> 3) & 0x7).b[n]=XMM((modrm >> 3) & 0x7).b[n] + XMM(modrm & 7).b[n];
- } else {
- XMM_REG s;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, s);
- for (int n=0;n < 16;n++)
- XMM((modrm >> 3) & 0x7).b[n]=XMM((modrm >> 3) & 0x7).b[n] + s.b[n];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(paddw_r128_rm128)() // Opcode 66 0f fd
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- for (int n=0;n < 8;n++)
- XMM((modrm >> 3) & 0x7).w[n]=XMM((modrm >> 3) & 0x7).w[n] + XMM(modrm & 7).w[n];
- } else {
- XMM_REG s;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, s);
- for (int n=0;n < 8;n++)
- XMM((modrm >> 3) & 0x7).w[n]=XMM((modrm >> 3) & 0x7).w[n] + s.w[n];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(paddd_r128_rm128)() // Opcode 66 0f fe
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- for (int n=0;n < 4;n++)
- XMM((modrm >> 3) & 0x7).d[n]=XMM((modrm >> 3) & 0x7).d[n] + XMM(modrm & 7).d[n];
- } else {
- XMM_REG s;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, s);
- for (int n=0;n < 4;n++)
- XMM((modrm >> 3) & 0x7).d[n]=XMM((modrm >> 3) & 0x7).d[n] + s.d[n];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(psubusb_r128_rm128)() // Opcode 66 0f d8
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- for (int n=0;n < 16;n++)
- XMM((modrm >> 3) & 0x7).b[n]=XMM((modrm >> 3) & 0x7).b[n] < XMM(modrm & 7).b[n] ? 0 : XMM((modrm >> 3) & 0x7).b[n]-XMM(modrm & 7).b[n];
- } else {
- XMM_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, src);
- for (int n=0;n < 16;n++)
- XMM((modrm >> 3) & 0x7).b[n]=XMM((modrm >> 3) & 0x7).b[n] < src.b[n] ? 0 : XMM((modrm >> 3) & 0x7).b[n]-src.b[n];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(psubusw_r128_rm128)() // Opcode 66 0f d9
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- for (int n=0;n < 8;n++)
- XMM((modrm >> 3) & 0x7).w[n]=XMM((modrm >> 3) & 0x7).w[n] < XMM(modrm & 7).w[n] ? 0 : XMM((modrm >> 3) & 0x7).w[n]-XMM(modrm & 7).w[n];
- } else {
- XMM_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, src);
- for (int n=0;n < 8;n++)
- XMM((modrm >> 3) & 0x7).w[n]=XMM((modrm >> 3) & 0x7).w[n] < src.w[n] ? 0 : XMM((modrm >> 3) & 0x7).w[n]-src.w[n];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(pand_r128_rm128)() // Opcode 66 0f db
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).q[0]=XMM((modrm >> 3) & 0x7).q[0] & XMM(modrm & 7).q[0];
- XMM((modrm >> 3) & 0x7).q[1]=XMM((modrm >> 3) & 0x7).q[1] & XMM(modrm & 7).q[1];
- } else {
- XMM_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, src);
- XMM((modrm >> 3) & 0x7).q[0]=XMM((modrm >> 3) & 0x7).q[0] & src.q[0];
- XMM((modrm >> 3) & 0x7).q[1]=XMM((modrm >> 3) & 0x7).q[1] & src.q[1];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(pandn_r128_rm128)() // Opcode 66 0f df
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).q[0]=(~XMM((modrm >> 3) & 0x7).q[0]) & XMM(modrm & 7).q[0];
- XMM((modrm >> 3) & 0x7).q[1]=(~XMM((modrm >> 3) & 0x7).q[1]) & XMM(modrm & 7).q[1];
- } else {
- XMM_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, src);
- XMM((modrm >> 3) & 0x7).q[0]=(~XMM((modrm >> 3) & 0x7).q[0]) & src.q[0];
- XMM((modrm >> 3) & 0x7).q[1]=(~XMM((modrm >> 3) & 0x7).q[1]) & src.q[1];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(paddusb_r128_rm128)() // Opcode 66 0f dc
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- for (int n=0;n < 16;n++)
- XMM((modrm >> 3) & 0x7).b[n]=XMM((modrm >> 3) & 0x7).b[n] > (0xff-XMM(modrm & 7).b[n]) ? 0xff : XMM((modrm >> 3) & 0x7).b[n]+XMM(modrm & 7).b[n];
- } else {
- XMM_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, src);
- for (int n=0;n < 16;n++)
- XMM((modrm >> 3) & 0x7).b[n]=XMM((modrm >> 3) & 0x7).b[n] > (0xff-src.b[n]) ? 0xff : XMM((modrm >> 3) & 0x7).b[n]+src.b[n];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(paddusw_r128_rm128)() // Opcode 66 0f dd
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- for (int n=0;n < 8;n++)
- XMM((modrm >> 3) & 0x7).w[n]=XMM((modrm >> 3) & 0x7).w[n] > (0xffff-XMM(modrm & 7).w[n]) ? 0xffff : XMM((modrm >> 3) & 0x7).w[n]+XMM(modrm & 7).w[n];
- } else {
- XMM_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, src);
- for (int n=0;n < 8;n++)
- XMM((modrm >> 3) & 0x7).w[n]=XMM((modrm >> 3) & 0x7).w[n] > (0xffff-src.w[n]) ? 0xffff : XMM((modrm >> 3) & 0x7).w[n]+src.w[n];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(pmaxub_r128_rm128)() // Opcode 66 0f de
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- for (int n=0;n < 16;n++)
- XMM((modrm >> 3) & 0x7).b[n] = XMM((modrm >> 3) & 0x7).b[n] > XMM(modrm & 0x7).b[n] ? XMM((modrm >> 3) & 0x7).b[n] : XMM(modrm & 0x7).b[n];
- } else {
- XMM_REG s;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, s);
- for (int n=0;n < 16;n++)
- XMM((modrm >> 3) & 0x7).b[n] = XMM((modrm >> 3) & 0x7).b[n] > s.b[n] ? XMM((modrm >> 3) & 0x7).b[n] : s.b[n];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(pmulhuw_r128_rm128)() // Opcode 66 0f e4
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- for (int n=0;n < 8;n++)
- XMM((modrm >> 3) & 0x7).w[n]=((UINT32)XMM((modrm >> 3) & 0x7).w[n]*(UINT32)XMM(modrm & 7).w[n]) >> 16;
- } else {
- XMM_REG s;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, s);
- for (int n=0;n < 8;n++)
- XMM((modrm >> 3) & 0x7).w[n]=((UINT32)XMM((modrm >> 3) & 0x7).w[n]*(UINT32)s.w[n]) >> 16;
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(pmulhw_r128_rm128)() // Opcode 66 0f e5
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- for (int n=0;n < 8;n++)
- XMM((modrm >> 3) & 0x7).w[n]=(UINT32)((INT32)XMM((modrm >> 3) & 0x7).s[n]*(INT32)XMM(modrm & 7).s[n]) >> 16;
- } else {
- XMM_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, src);
- for (int n=0;n < 8;n++)
- XMM((modrm >> 3) & 0x7).w[n]=(UINT32)((INT32)XMM((modrm >> 3) & 0x7).s[n]*(INT32)src.s[n]) >> 16;
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(psubsb_r128_rm128)() // Opcode 66 0f e8
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- for (int n=0;n < 16;n++)
- XMM((modrm >> 3) & 0x7).c[n]=SaturatedSignedWordToSignedByte((INT16)XMM((modrm >> 3) & 0x7).c[n] - (INT16)XMM(modrm & 7).c[n]);
- } else {
- XMM_REG s;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, s);
- for (int n=0;n < 16;n++)
- XMM((modrm >> 3) & 0x7).c[n]=SaturatedSignedWordToSignedByte((INT16)XMM((modrm >> 3) & 0x7).c[n] - (INT16)s.c[n]);
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(psubsw_r128_rm128)() // Opcode 66 0f e9
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- for (int n=0;n < 8;n++)
- XMM((modrm >> 3) & 0x7).s[n]=SaturatedSignedDwordToSignedWord((INT32)XMM((modrm >> 3) & 0x7).s[n] - (INT32)XMM(modrm & 7).s[n]);
- } else {
- XMM_REG s;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, s);
- for (int n=0;n < 8;n++)
- XMM((modrm >> 3) & 0x7).s[n]=SaturatedSignedDwordToSignedWord((INT32)XMM((modrm >> 3) & 0x7).s[n] - (INT32)s.s[n]);
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(pminsw_r128_rm128)() // Opcode 66 0f ea
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- for (int n=0;n < 8;n++)
- XMM((modrm >> 3) & 0x7).s[n] = XMM((modrm >> 3) & 0x7).s[n] < XMM(modrm & 0x7).s[n] ? XMM((modrm >> 3) & 0x7).s[n] : XMM(modrm & 0x7).s[n];
- } else {
- XMM_REG s;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, s);
- for (int n=0;n < 8;n++)
- XMM((modrm >> 3) & 0x7).s[n] = XMM((modrm >> 3) & 0x7).s[n] < s.s[n] ? XMM((modrm >> 3) & 0x7).s[n] : s.s[n];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(pmaxsw_r128_rm128)() // Opcode 66 0f ee
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- for (int n=0;n < 8;n++)
- XMM((modrm >> 3) & 0x7).s[n] = XMM((modrm >> 3) & 0x7).s[n] > XMM(modrm & 0x7).s[n] ? XMM((modrm >> 3) & 0x7).s[n] : XMM(modrm & 0x7).s[n];
- } else {
- XMM_REG s;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, s);
- for (int n=0;n < 8;n++)
- XMM((modrm >> 3) & 0x7).s[n] = XMM((modrm >> 3) & 0x7).s[n] > s.s[n] ? XMM((modrm >> 3) & 0x7).s[n] : s.s[n];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(paddsb_r128_rm128)() // Opcode 66 0f ec
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- for (int n=0;n < 16;n++)
- XMM((modrm >> 3) & 0x7).c[n]=SaturatedSignedWordToSignedByte((INT16)XMM((modrm >> 3) & 0x7).c[n] + (INT16)XMM(modrm & 7).c[n]);
- } else {
- XMM_REG s;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, s);
- for (int n=0;n < 16;n++)
- XMM((modrm >> 3) & 0x7).c[n]=SaturatedSignedWordToSignedByte((INT16)XMM((modrm >> 3) & 0x7).c[n] + (INT16)s.c[n]);
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(paddsw_r128_rm128)() // Opcode 66 0f ed
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- for (int n=0;n < 8;n++)
- XMM((modrm >> 3) & 0x7).s[n]=SaturatedSignedDwordToSignedWord((INT32)XMM((modrm >> 3) & 0x7).s[n] + (INT32)XMM(modrm & 7).s[n]);
- } else {
- XMM_REG s;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, s);
- for (int n=0;n < 8;n++)
- XMM((modrm >> 3) & 0x7).s[n]=SaturatedSignedDwordToSignedWord((INT32)XMM((modrm >> 3) & 0x7).s[n] + (INT32)s.s[n]);
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(por_r128_rm128)() // Opcode 66 0f eb
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).q[0]=XMM((modrm >> 3) & 0x7).q[0] | XMM(modrm & 7).q[0];
- XMM((modrm >> 3) & 0x7).q[1]=XMM((modrm >> 3) & 0x7).q[1] | XMM(modrm & 7).q[1];
- } else {
- XMM_REG s;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, s);
- XMM((modrm >> 3) & 0x7).q[0]=XMM((modrm >> 3) & 0x7).q[0] | s.q[0];
- XMM((modrm >> 3) & 0x7).q[1]=XMM((modrm >> 3) & 0x7).q[1] | s.q[1];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(pxor_r128_rm128)() // Opcode 66 0f ef
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).q[0]=XMM((modrm >> 3) & 0x7).q[0] ^ XMM(modrm & 7).q[0];
- XMM((modrm >> 3) & 0x7).q[1]=XMM((modrm >> 3) & 0x7).q[1] ^ XMM(modrm & 7).q[1];
- } else {
- XMM_REG s;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, s);
- XMM((modrm >> 3) & 0x7).q[0]=XMM((modrm >> 3) & 0x7).q[0] ^ s.q[0];
- XMM((modrm >> 3) & 0x7).q[1]=XMM((modrm >> 3) & 0x7).q[1] ^ s.q[1];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(pmaddwd_r128_rm128)() // Opcode 66 0f f5
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- for (int n=0;n < 4;n++)
- XMM((modrm >> 3) & 0x7).i[n]=(INT32)XMM((modrm >> 3) & 0x7).s[n]*(INT32)XMM(modrm & 7).s[n]+
- (INT32)XMM((modrm >> 3) & 0x7).s[n]*(INT32)XMM(modrm & 7).s[n];
- } else {
- XMM_REG s;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, s);
- for (int n=0;n < 4;n++)
- XMM((modrm >> 3) & 0x7).i[n]=(INT32)XMM((modrm >> 3) & 0x7).s[n]*(INT32)s.s[n]+
- (INT32)XMM((modrm >> 3) & 0x7).s[n]*(INT32)s.s[n];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(psubb_r128_rm128)() // Opcode 66 0f f8
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- for (int n=0;n < 16;n++)
- XMM((modrm >> 3) & 0x7).b[n]=XMM((modrm >> 3) & 0x7).b[n] - XMM(modrm & 7).b[n];
- } else {
- XMM_REG s;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, s);
- for (int n=0;n < 16;n++)
- XMM((modrm >> 3) & 0x7).b[n]=XMM((modrm >> 3) & 0x7).b[n] - s.b[n];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(psubw_r128_rm128)() // Opcode 66 0f f9
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- for (int n=0;n < 8;n++)
- XMM((modrm >> 3) & 0x7).w[n]=XMM((modrm >> 3) & 0x7).w[n] - XMM(modrm & 7).w[n];
- } else {
- XMM_REG s;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, s);
- for (int n=0;n < 8;n++)
- XMM((modrm >> 3) & 0x7).w[n]=XMM((modrm >> 3) & 0x7).w[n] - s.w[n];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(psubd_r128_rm128)() // Opcode 66 0f fa
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- for (int n=0;n < 4;n++)
- XMM((modrm >> 3) & 0x7).d[n]=XMM((modrm >> 3) & 0x7).d[n] - XMM(modrm & 7).d[n];
- } else {
- XMM_REG s;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, s);
- for (int n=0;n < 4;n++)
- XMM((modrm >> 3) & 0x7).d[n]=XMM((modrm >> 3) & 0x7).d[n] - s.d[n];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(psadbw_r128_rm128)() // Opcode 66 0f f6
-{
- INT32 temp;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- temp=0;
- for (int n=0;n < 8;n++)
- temp += abs((INT32)XMM((modrm >> 3) & 0x7).b[n] - (INT32)XMM(modrm & 0x7).b[n]);
- XMM((modrm >> 3) & 0x7).l[0]=(UINT64)temp & 0xffff;
- temp=0;
- for (int n=8;n < 16;n++)
- temp += abs((INT32)XMM((modrm >> 3) & 0x7).b[n] - (INT32)XMM(modrm & 0x7).b[n]);
- XMM((modrm >> 3) & 0x7).l[1]=(UINT64)temp & 0xffff;
- } else {
- XMM_REG s;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, s);
- temp=0;
- for (int n=0;n < 8;n++)
- temp += abs((INT32)XMM((modrm >> 3) & 0x7).b[n] - (INT32)s.b[n]);
- XMM((modrm >> 3) & 0x7).l[0]=(UINT64)temp & 0xffff;
- temp=0;
- for (int n=8;n < 16;n++)
- temp += abs((INT32)XMM((modrm >> 3) & 0x7).b[n] - (INT32)s.b[n]);
- XMM((modrm >> 3) & 0x7).l[1]=(UINT64)temp & 0xffff;
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(pavgb_r128_rm128)() // Opcode 66 0f e0
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- for (int n=0;n < 16;n++)
- XMM((modrm >> 3) & 0x7).b[n] = ((UINT16)XMM((modrm >> 3) & 0x7).b[n] + (UINT16)XMM(modrm & 0x7).b[n] + 1) >> 1;
- } else {
- XMM_REG s;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, s);
- for (int n=0;n < 16;n++)
- XMM((modrm >> 3) & 0x7).b[n] = ((UINT16)XMM((modrm >> 3) & 0x7).b[n] + (UINT16)s.b[n] + 1) >> 1;
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(pavgw_r128_rm128)() // Opcode 66 0f e3
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- for (int n=0;n < 8;n++)
- XMM((modrm >> 3) & 0x7).w[n] = ((UINT32)XMM((modrm >> 3) & 0x7).w[n] + (UINT32)XMM(modrm & 0x7).w[n] + 1) >> 1;
- } else {
- XMM_REG s;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, s);
- for (int n=0;n < 8;n++)
- XMM((modrm >> 3) & 0x7).w[n] = ((UINT32)XMM((modrm >> 3) & 0x7).w[n] + (UINT32)s.w[n] + 1) >> 1;
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(psrlw_r128_rm128)() // Opcode 66 0f d1
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- int count=(int)XMM(modrm & 7).q[0];
- for (int n=0; n < 8;n++)
- XMM((modrm >> 3) & 0x7).w[n]=XMM((modrm >> 3) & 0x7).w[n] >> count;
- } else {
- XMM_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, src);
- int count=(int)src.q[0];
- for (int n=0; n < 8;n++)
- XMM((modrm >> 3) & 0x7).w[n]=XMM((modrm >> 3) & 0x7).w[n] >> count;
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(psrld_r128_rm128)() // Opcode 66 0f d2
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- int count=(int)XMM(modrm & 7).q[0];
- XMM((modrm >> 3) & 0x7).d[0]=XMM((modrm >> 3) & 0x7).d[0] >> count;
- XMM((modrm >> 3) & 0x7).d[1]=XMM((modrm >> 3) & 0x7).d[1] >> count;
- XMM((modrm >> 3) & 0x7).d[2]=XMM((modrm >> 3) & 0x7).d[2] >> count;
- XMM((modrm >> 3) & 0x7).d[3]=XMM((modrm >> 3) & 0x7).d[3] >> count;
- } else {
- XMM_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, src);
- int count=(int)src.q[0];
- XMM((modrm >> 3) & 0x7).d[0]=XMM((modrm >> 3) & 0x7).d[0] >> count;
- XMM((modrm >> 3) & 0x7).d[1]=XMM((modrm >> 3) & 0x7).d[1] >> count;
- XMM((modrm >> 3) & 0x7).d[2]=XMM((modrm >> 3) & 0x7).d[2] >> count;
- XMM((modrm >> 3) & 0x7).d[3]=XMM((modrm >> 3) & 0x7).d[3] >> count;
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(psrlq_r128_rm128)() // Opcode 66 0f d3
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- int count=(int)XMM(modrm & 7).q[0];
- XMM((modrm >> 3) & 0x7).q[0]=XMM((modrm >> 3) & 0x7).q[0] >> count;
- XMM((modrm >> 3) & 0x7).q[1]=XMM((modrm >> 3) & 0x7).q[1] >> count;
- } else {
- XMM_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, src);
- int count=(int)src.q[0];
- XMM((modrm >> 3) & 0x7).q[0]=XMM((modrm >> 3) & 0x7).q[0] >> count;
- XMM((modrm >> 3) & 0x7).q[1]=XMM((modrm >> 3) & 0x7).q[1] >> count;
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(psllw_r128_rm128)() // Opcode 66 0f f1
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- int count=(int)XMM(modrm & 7).q[0];
- for (int n=0; n < 8;n++)
- XMM((modrm >> 3) & 0x7).w[n]=XMM((modrm >> 3) & 0x7).w[n] << count;
- } else {
- XMM_REG s;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, s);
- int count=(int)s.q[0];
- for (int n=0; n < 8;n++)
- XMM((modrm >> 3) & 0x7).w[n]=XMM((modrm >> 3) & 0x7).w[n] << count;
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(pslld_r128_rm128)() // Opcode 66 0f f2
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- int count=(int)XMM(modrm & 7).q[0];
- XMM((modrm >> 3) & 0x7).d[0]=XMM((modrm >> 3) & 0x7).d[0] << count;
- XMM((modrm >> 3) & 0x7).d[1]=XMM((modrm >> 3) & 0x7).d[1] << count;
- XMM((modrm >> 3) & 0x7).d[2]=XMM((modrm >> 3) & 0x7).d[2] << count;
- XMM((modrm >> 3) & 0x7).d[3]=XMM((modrm >> 3) & 0x7).d[3] << count;
- } else {
- XMM_REG s;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, s);
- int count=(int)s.q[0];
- XMM((modrm >> 3) & 0x7).d[0]=XMM((modrm >> 3) & 0x7).d[0] << count;
- XMM((modrm >> 3) & 0x7).d[1]=XMM((modrm >> 3) & 0x7).d[1] << count;
- XMM((modrm >> 3) & 0x7).d[2]=XMM((modrm >> 3) & 0x7).d[2] << count;
- XMM((modrm >> 3) & 0x7).d[3]=XMM((modrm >> 3) & 0x7).d[3] << count;
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(psllq_r128_rm128)() // Opcode 66 0f f3
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- int count=(int)XMM(modrm & 7).q[0];
- XMM((modrm >> 3) & 0x7).q[0]=XMM((modrm >> 3) & 0x7).q[0] << count;
- XMM((modrm >> 3) & 0x7).q[1]=XMM((modrm >> 3) & 0x7).q[1] << count;
- } else {
- XMM_REG s;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, s);
- int count=(int)s.q[0];
- XMM((modrm >> 3) & 0x7).q[0]=XMM((modrm >> 3) & 0x7).q[0] << count;
- XMM((modrm >> 3) & 0x7).q[1]=XMM((modrm >> 3) & 0x7).q[1] << count;
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(psraw_r128_rm128)() // Opcode 66 0f e1
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- int count=(int)XMM(modrm & 7).q[0];
- for (int n=0; n < 8;n++)
- XMM((modrm >> 3) & 0x7).s[n]=XMM((modrm >> 3) & 0x7).s[n] >> count;
- } else {
- XMM_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, src);
- int count=(int)src.q[0];
- for (int n=0; n < 8;n++)
- XMM((modrm >> 3) & 0x7).s[n]=XMM((modrm >> 3) & 0x7).s[n] >> count;
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(psrad_r128_rm128)() // Opcode 66 0f e2
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- int count=(int)XMM(modrm & 7).q[0];
- XMM((modrm >> 3) & 0x7).i[0]=XMM((modrm >> 3) & 0x7).i[0] >> count;
- XMM((modrm >> 3) & 0x7).i[1]=XMM((modrm >> 3) & 0x7).i[1] >> count;
- XMM((modrm >> 3) & 0x7).i[2]=XMM((modrm >> 3) & 0x7).i[2] >> count;
- XMM((modrm >> 3) & 0x7).i[3]=XMM((modrm >> 3) & 0x7).i[3] >> count;
- } else {
- XMM_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, src);
- int count=(int)src.q[0];
- XMM((modrm >> 3) & 0x7).i[0]=XMM((modrm >> 3) & 0x7).i[0] >> count;
- XMM((modrm >> 3) & 0x7).i[1]=XMM((modrm >> 3) & 0x7).i[1] >> count;
- XMM((modrm >> 3) & 0x7).i[2]=XMM((modrm >> 3) & 0x7).i[2] >> count;
- XMM((modrm >> 3) & 0x7).i[3]=XMM((modrm >> 3) & 0x7).i[3] >> count;
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(movntdq_m128_r128)() // Opcode 66 0f e7
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- CYCLES(1); // unsupported
- } else {
- // since cache is not implemented
- UINT32 ea = GetEA(modrm, 0);
- WRITEXMM( ea, XMM((modrm >> 3) & 0x7));
- CYCLES(1); // TODO: correct cycle count
- }
-}
-
- void I386_OPS_BASE::SSEOP(cvttpd2dq_r128_rm128)() // Opcode 66 0f e6
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).i[0]=(INT32)XMM((modrm >> 3) & 0x7).f64[0];
- XMM((modrm >> 3) & 0x7).i[1]=(INT32)XMM((modrm >> 3) & 0x7).f64[1];
- XMM((modrm >> 3) & 0x7).q[1] = 0;
- } else {
- XMM_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, src);
- XMM((modrm >> 3) & 0x7).i[0]=(INT32)src.f64[0];
- XMM((modrm >> 3) & 0x7).i[1]=(INT32)src.f64[1];
- XMM((modrm >> 3) & 0x7).q[1] = 0;
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(movq_r128m64_r128)() // Opcode 66 0f d6
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM(modrm & 0x7).q[0]=XMM((modrm >> 3) & 0x7).q[0];
- XMM(modrm & 0x7).q[1] = 0;
- } else {
- UINT32 ea = GetEA(modrm, 0);
- WRITE64( ea, XMM((modrm >> 3) & 0x7).q[0]);
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(addsubpd_r128_rm128)() // Opcode 66 0f d0
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- int s, d;
- s=modrm & 0x7;
- d=(modrm >> 3) & 0x7;
- XMM(d).f64[0]=XMM(d).f64[0]-XMM(s).f64[0];
- XMM(d).f64[1]=XMM(d).f64[1]+XMM(s).f64[1];
- } else {
- XMM_REG src;
- int d;
- UINT32 ea = GetEA(modrm, 0);
- d=(modrm >> 3) & 0x7;
- READXMM( ea, src);
- XMM(d).f64[0]=XMM(d).f64[0]-src.f64[0];
- XMM(d).f64[1]=XMM(d).f64[1]+src.f64[1];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(haddpd_r128_rm128)() // Opcode 66 0f 7c
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- int s, d;
- s=modrm & 0x7;
- d=(modrm >> 3) & 0x7;
- XMM(d).f64[0]=XMM(d).f64[0]+XMM(d).f64[1];
- XMM(d).f64[1]=XMM(s).f64[0]+XMM(s).f64[1];
- } else {
- XMM_REG src;
- int d;
- UINT32 ea = GetEA(modrm, 0);
- d=(modrm >> 3) & 0x7;
- READXMM( ea, src);
- XMM(d).f64[0]=XMM(d).f64[0]+XMM(d).f64[1];
- XMM(d).f64[1]=src.f64[0]+src.f64[1];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(hsubpd_r128_rm128)() // Opcode 66 0f 7d
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- int s, d;
- s=modrm & 0x7;
- d=(modrm >> 3) & 0x7;
- XMM(d).f64[0]=XMM(d).f64[0]-XMM(d).f64[1];
- XMM(d).f64[1]=XMM(s).f64[0]-XMM(s).f64[1];
- } else {
- XMM_REG src;
- int d;
- UINT32 ea = GetEA(modrm, 0);
- d=(modrm >> 3) & 0x7;
- READXMM( ea, src);
- XMM(d).f64[0]=XMM(d).f64[0]-XMM(d).f64[1];
- XMM(d).f64[1]=src.f64[0]-src.f64[1];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(sqrtpd_r128_rm128)() // Opcode 66 0f 51
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- int s, d;
- s=modrm & 0x7;
- d=(modrm >> 3) & 0x7;
- XMM(d).f64[0]=sqrt(XMM(s).f64[0]);
- XMM(d).f64[1]=sqrt(XMM(s).f64[1]);
- } else {
- XMM_REG src;
- int d;
- UINT32 ea = GetEA(modrm, 0);
- d=(modrm >> 3) & 0x7;
- READXMM( ea, src);
- XMM(d).f64[0]=sqrt(src.f64[0]);
- XMM(d).f64[1]=sqrt(src.f64[1]);
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(cvtpi2pd_r128_rm64)() // Opcode 66 0f 2a
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- MMXPROLOG();
- XMM((modrm >> 3) & 0x7).f64[0] = (double)MMX(modrm & 0x7).i[0];
- XMM((modrm >> 3) & 0x7).f64[1] = (double)MMX(modrm & 0x7).i[1];
- } else {
- MMX_REG r;
- UINT32 ea = GetEA(modrm, 0);
- READMMX( ea, r);
- XMM((modrm >> 3) & 0x7).f64[0] = (double)r.i[0];
- XMM((modrm >> 3) & 0x7).f64[1] = (double)r.i[1];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(cvttpd2pi_r64_rm128)() // Opcode 66 0f 2c
-{
- UINT8 modrm = FETCH();
- MMXPROLOG();
- if( modrm >= 0xc0 ) {
- MMX((modrm >> 3) & 0x7).i[0] = XMM(modrm & 0x7).f64[0];
- MMX((modrm >> 3) & 0x7).i[1] = XMM(modrm & 0x7).f64[1];
- } else {
- XMM_REG r;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, r);
- MMX((modrm >> 3) & 0x7).i[0] = r.f64[0];
- MMX((modrm >> 3) & 0x7).i[1] = r.f64[1];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(cvtpd2pi_r64_rm128)() // Opcode 66 0f 2d
-{
- UINT8 modrm = FETCH();
- MMXPROLOG();
- if( modrm >= 0xc0 ) {
- MMX((modrm >> 3) & 0x7).i[0] = XMM(modrm & 0x7).f64[0];
- MMX((modrm >> 3) & 0x7).i[1] = XMM(modrm & 0x7).f64[1];
- } else {
- XMM_REG r;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, r);
- MMX((modrm >> 3) & 0x7).i[0] = r.f64[0];
- MMX((modrm >> 3) & 0x7).i[1] = r.f64[1];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(cvtpd2ps_r128_rm128)() // Opcode 66 0f 5a
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).f[0] = (float)XMM(modrm & 0x7).f64[0];
- XMM((modrm >> 3) & 0x7).f[1] = (float)XMM(modrm & 0x7).f64[1];
- XMM((modrm >> 3) & 0x7).q[1] = 0;
- } else {
- XMM_REG r;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, r);
- XMM((modrm >> 3) & 0x7).f[0] = (float)r.f64[0];
- XMM((modrm >> 3) & 0x7).f[1] = (float)r.f64[1];
- XMM((modrm >> 3) & 0x7).q[1] = 0;
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(cvtps2dq_r128_rm128)() // Opcode 66 0f 5b
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).i[0] = XMM(modrm & 0x7).f[0];
- XMM((modrm >> 3) & 0x7).i[1] = XMM(modrm & 0x7).f[1];
- XMM((modrm >> 3) & 0x7).i[2] = XMM(modrm & 0x7).f[2];
- XMM((modrm >> 3) & 0x7).i[3] = XMM(modrm & 0x7).f[3];
- } else {
- XMM_REG r;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, r);
- XMM((modrm >> 3) & 0x7).i[0] = r.f[0];
- XMM((modrm >> 3) & 0x7).i[1] = r.f[1];
- XMM((modrm >> 3) & 0x7).i[2] = r.f[2];
- XMM((modrm >> 3) & 0x7).i[3] = r.f[3];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(addpd_r128_rm128)() // Opcode 66 0f 58
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).f64[0] = XMM((modrm >> 3) & 0x7).f64[0] + XMM(modrm & 0x7).f64[0];
- XMM((modrm >> 3) & 0x7).f64[1] = XMM((modrm >> 3) & 0x7).f64[1] + XMM(modrm & 0x7).f64[1];
- } else {
- XMM_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, src);
- XMM((modrm >> 3) & 0x7).f64[0] = XMM((modrm >> 3) & 0x7).f64[0] + src.f64[0];
- XMM((modrm >> 3) & 0x7).f64[1] = XMM((modrm >> 3) & 0x7).f64[1] + src.f64[1];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(mulpd_r128_rm128)() // Opcode 66 0f 59
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).f64[0] = XMM((modrm >> 3) & 0x7).f64[0] * XMM(modrm & 0x7).f64[0];
- XMM((modrm >> 3) & 0x7).f64[1] = XMM((modrm >> 3) & 0x7).f64[1] * XMM(modrm & 0x7).f64[1];
- } else {
- XMM_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, src);
- XMM((modrm >> 3) & 0x7).f64[0] = XMM((modrm >> 3) & 0x7).f64[0] * src.f64[0];
- XMM((modrm >> 3) & 0x7).f64[1] = XMM((modrm >> 3) & 0x7).f64[1] * src.f64[1];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(subpd_r128_rm128)() // Opcode 66 0f 5c
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).f64[0] = XMM((modrm >> 3) & 0x7).f64[0] - XMM(modrm & 0x7).f64[0];
- XMM((modrm >> 3) & 0x7).f64[1] = XMM((modrm >> 3) & 0x7).f64[1] - XMM(modrm & 0x7).f64[1];
- } else {
- XMM_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, src);
- XMM((modrm >> 3) & 0x7).f64[0] = XMM((modrm >> 3) & 0x7).f64[0] - src.f64[0];
- XMM((modrm >> 3) & 0x7).f64[1] = XMM((modrm >> 3) & 0x7).f64[1] - src.f64[1];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(minpd_r128_rm128)() // Opcode 66 0f 5d
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).f64[0] = sse_min_double(XMM((modrm >> 3) & 0x7).f64[0], XMM(modrm & 0x7).f64[0]);
- XMM((modrm >> 3) & 0x7).f64[1] = sse_min_double(XMM((modrm >> 3) & 0x7).f64[1], XMM(modrm & 0x7).f64[1]);
- } else {
- XMM_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, src);
- XMM((modrm >> 3) & 0x7).f64[0] = sse_min_double(XMM((modrm >> 3) & 0x7).f64[0], src.f64[0]);
- XMM((modrm >> 3) & 0x7).f64[1] = sse_min_double(XMM((modrm >> 3) & 0x7).f64[1], src.f64[1]);
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(divpd_r128_rm128)() // Opcode 66 0f 5e
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).f64[0] = XMM((modrm >> 3) & 0x7).f64[0] / XMM(modrm & 0x7).f64[0];
- XMM((modrm >> 3) & 0x7).f64[1] = XMM((modrm >> 3) & 0x7).f64[1] / XMM(modrm & 0x7).f64[1];
- } else {
- XMM_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, src);
- XMM((modrm >> 3) & 0x7).f64[0] = XMM((modrm >> 3) & 0x7).f64[0] / src.f64[0];
- XMM((modrm >> 3) & 0x7).f64[1] = XMM((modrm >> 3) & 0x7).f64[1] / src.f64[1];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(maxpd_r128_rm128)() // Opcode 66 0f 5f
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).f64[0] = sse_max_double(XMM((modrm >> 3) & 0x7).f64[0], XMM(modrm & 0x7).f64[0]);
- XMM((modrm >> 3) & 0x7).f64[1] = sse_max_double(XMM((modrm >> 3) & 0x7).f64[1], XMM(modrm & 0x7).f64[1]);
- } else {
- XMM_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, src);
- XMM((modrm >> 3) & 0x7).f64[0] = sse_max_double(XMM((modrm >> 3) & 0x7).f64[0], src.f64[0]);
- XMM((modrm >> 3) & 0x7).f64[1] = sse_max_double(XMM((modrm >> 3) & 0x7).f64[1], src.f64[1]);
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(movntpd_m128_r128)() // Opcode 66 0f 2b
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- // unsupported by cpu
- CYCLES(1); // TODO: correct cycle count
- } else {
- // since cache is not implemented
- UINT32 ea = GetEA(modrm, 0);
- WRITEXMM( ea, XMM((modrm >> 3) & 0x7));
- CYCLES(1); // TODO: correct cycle count
- }
-}
-
- void I386_OPS_BASE::SSEOP(movapd_r128_rm128)() // Opcode 66 0f 28
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7) = XMM(modrm & 0x7);
- } else {
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, XMM((modrm >> 3) & 0x7));
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(movapd_rm128_r128)() // Opcode 66 0f 29
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM(modrm & 0x7) = XMM((modrm >> 3) & 0x7);
- } else {
- UINT32 ea = GetEA(modrm, 0);
- WRITEXMM( ea, XMM((modrm >> 3) & 0x7));
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(movsd_r128_r128m64)() // Opcode f2 0f 10
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).q[0] = XMM(modrm & 0x7).q[0];
- } else {
- UINT32 ea = GetEA(modrm, 0);
- READXMM_LO64( ea, XMM((modrm >> 3) & 0x7));
- XMM((modrm >> 3) & 0x7).q[1] = 0;
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(movsd_r128m64_r128)() // Opcode f2 0f 11
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM(modrm & 0x7).q[0] = XMM((modrm >> 3) & 0x7).q[0];
- } else {
- UINT32 ea = GetEA(modrm, 0);
- WRITEXMM_LO64( ea, XMM((modrm >> 3) & 0x7));
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(movddup_r128_r128m64)() // Opcode f2 0f 12
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).q[0] = XMM(modrm & 0x7).q[0];
- XMM((modrm >> 3) & 0x7).q[1] = XMM((modrm >> 3) & 0x7).q[0];
- } else {
- UINT32 ea = GetEA(modrm, 0);
- READXMM_LO64( ea, XMM((modrm >> 3) & 0x7));
- XMM((modrm >> 3) & 0x7).q[1] = XMM((modrm >> 3) & 0x7).q[0];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(cvtsi2sd_r128_rm32)() // Opcode f2 0f 2a
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).f64[0] = (INT32)LOAD_RM32(modrm);
- } else {
- UINT32 ea = GetEA(modrm, 0);
- XMM((modrm >> 3) & 0x7).f64[0] = (INT32)READ32(ea);
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(cvttsd2si_r32_r128m64)() // Opcode f2 0f 2c
-{
- INT32 src;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- src = (INT32)XMM(modrm & 0x7).f64[0];
- } else { // otherwise is a memory address
- XMM_REG t;
- UINT32 ea = GetEA(modrm, 0);
- READXMM_LO64( ea, t);
- src = (INT32)t.f64[0];
- }
- STORE_REG32(modrm, (UINT32)src);
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(cvtsd2si_r32_r128m64)() // Opcode f2 0f 2d
-{
- INT32 src;
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- src = (INT32)XMM(modrm & 0x7).f64[0];
- } else { // otherwise is a memory address
- XMM_REG t;
- UINT32 ea = GetEA(modrm, 0);
- READXMM_LO64( ea, t);
- src = (INT32)t.f64[0];
- }
- STORE_REG32(modrm, (UINT32)src);
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(sqrtsd_r128_r128m64)() // Opcode f2 0f 51
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- int s, d;
- s=modrm & 0x7;
- d=(modrm >> 3) & 0x7;
- XMM(d).f64[0]=sqrt(XMM(s).f64[0]);
- } else {
- XMM_REG src;
- int d;
- UINT32 ea = GetEA(modrm, 0);
- d=(modrm >> 3) & 0x7;
- READXMM( ea, src);
- XMM(d).f64[0]=sqrt(src.f64[0]);
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(addsd_r128_r128m64)() // Opcode f2 0f 58
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).f64[0] = XMM((modrm >> 3) & 0x7).f64[0] + XMM(modrm & 0x7).f64[0];
- } else {
- XMM_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, src);
- XMM((modrm >> 3) & 0x7).f64[0] = XMM((modrm >> 3) & 0x7).f64[0] + src.f64[0];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(mulsd_r128_r128m64)() // Opcode f2 0f 59
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).f64[0] = XMM((modrm >> 3) & 0x7).f64[0] * XMM(modrm & 0x7).f64[0];
- } else {
- XMM_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, src);
- XMM((modrm >> 3) & 0x7).f64[0] = XMM((modrm >> 3) & 0x7).f64[0] * src.f64[0];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(cvtsd2ss_r128_r128m64)() // Opcode f2 0f 5a
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).f[0] = XMM(modrm & 0x7).f64[0];
- } else {
- XMM_REG s;
- UINT32 ea = GetEA(modrm, 0);
- READXMM_LO64( ea, s);
- XMM((modrm >> 3) & 0x7).f[0] = s.f64[0];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(subsd_r128_r128m64)() // Opcode f2 0f 5c
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).f64[0] = XMM((modrm >> 3) & 0x7).f64[0] - XMM(modrm & 0x7).f64[0];
- } else {
- XMM_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, src);
- XMM((modrm >> 3) & 0x7).f64[0] = XMM((modrm >> 3) & 0x7).f64[0] - src.f64[0];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(minsd_r128_r128m64)() // Opcode f2 0f 5d
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).f64[0] = sse_min_double(XMM((modrm >> 3) & 0x7).f64[0], XMM(modrm & 0x7).f64[0]);
- } else {
- XMM_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, src);
- XMM((modrm >> 3) & 0x7).f64[0] = sse_min_double(XMM((modrm >> 3) & 0x7).f64[0], src.f64[0]);
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(divsd_r128_r128m64)() // Opcode f2 0f 5e
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).f64[0] = XMM((modrm >> 3) & 0x7).f64[0] / XMM(modrm & 0x7).f64[0];
- } else {
- XMM_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, src);
- XMM((modrm >> 3) & 0x7).f64[0] = XMM((modrm >> 3) & 0x7).f64[0] / src.f64[0];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(maxsd_r128_r128m64)() // Opcode f2 0f 5f
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).f64[0] = sse_max_double(XMM((modrm >> 3) & 0x7).f64[0], XMM(modrm & 0x7).f64[0]);
- } else {
- XMM_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, src);
- XMM((modrm >> 3) & 0x7).f64[0] = sse_max_double(XMM((modrm >> 3) & 0x7).f64[0], src.f64[0]);
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(haddps_r128_rm128)() // Opcode f2 0f 7c
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- int s, d;
- float f1, f2, f3, f4;
- s=modrm & 0x7;
- d=(modrm >> 3) & 0x7;
- f1=XMM(d).f[0]+XMM(d).f[1];
- f2=XMM(d).f[2]+XMM(d).f[3];
- f3=XMM(s).f[0]+XMM(s).f[1];
- f4=XMM(s).f[2]+XMM(s).f[3];
- XMM(d).f[0]=f1;
- XMM(d).f[1]=f2;
- XMM(d).f[2]=f3;
- XMM(d).f[3]=f4;
- } else {
- XMM_REG src;
- int d;
- float f1, f2;
- UINT32 ea = GetEA(modrm, 0);
- d=(modrm >> 3) & 0x7;
- READXMM( ea, src);
- f1=XMM(d).f[0]+XMM(d).f[1];
- f2=XMM(d).f[2]+XMM(d).f[3];
- XMM(d).f[0]=f1;
- XMM(d).f[1]=f2;
- XMM(d).f[2]=src.f[0]+src.f[1];
- XMM(d).f[3]=src.f[2]+src.f[3];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(hsubps_r128_rm128)() // Opcode f2 0f 7d
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- int s, d;
- float f1, f2, f3, f4;
- s=modrm & 0x7;
- d=(modrm >> 3) & 0x7;
- f1=XMM(d).f[0]-XMM(d).f[1];
- f2=XMM(d).f[2]-XMM(d).f[3];
- f3=XMM(s).f[0]-XMM(s).f[1];
- f4=XMM(s).f[2]-XMM(s).f[3];
- XMM(d).f[0]=f1;
- XMM(d).f[1]=f2;
- XMM(d).f[2]=f3;
- XMM(d).f[3]=f4;
- } else {
- XMM_REG src;
- int d;
- float f1, f2;
- UINT32 ea = GetEA(modrm, 0);
- d=(modrm >> 3) & 0x7;
- READXMM( ea, src);
- f1=XMM(d).f[0]-XMM(d).f[1];
- f2=XMM(d).f[2]-XMM(d).f[3];
- XMM(d).f[0]=f1;
- XMM(d).f[1]=f2;
- XMM(d).f[2]=src.f[0]-src.f[1];
- XMM(d).f[3]=src.f[2]-src.f[3];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(cmpsd_r128_r128m64_i8)() // Opcode f2 0f c2
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- int s,d;
- UINT8 imm8 = FETCH();
- s=modrm & 0x7;
- d=(modrm >> 3) & 0x7;
- sse_predicate_compare_double_scalar(imm8, XMM(d), XMM(s));
- } else {
- int d;
- XMM_REG s;
- UINT32 ea = GetEA(modrm, 0);
- UINT8 imm8 = FETCH();
- READXMM_LO64( ea, s);
- d=(modrm >> 3) & 0x7;
- sse_predicate_compare_double_scalar(imm8, XMM(d), s);
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(addsubps_r128_rm128)() // Opcode f2 0f d0
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).f[0]=XMM((modrm >> 3) & 0x7).f[0] - XMM(modrm & 0x7).f[0];
- XMM((modrm >> 3) & 0x7).f[1]=XMM((modrm >> 3) & 0x7).f[1] + XMM(modrm & 0x7).f[1];
- XMM((modrm >> 3) & 0x7).f[2]=XMM((modrm >> 3) & 0x7).f[2] - XMM(modrm & 0x7).f[2];
- XMM((modrm >> 3) & 0x7).f[3]=XMM((modrm >> 3) & 0x7).f[3] + XMM(modrm & 0x7).f[3];
- } else {
- XMM_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, src);
- XMM((modrm >> 3) & 0x7).f[0]=XMM((modrm >> 3) & 0x7).f[0] - src.f[0];
- XMM((modrm >> 3) & 0x7).f[1]=XMM((modrm >> 3) & 0x7).f[1] + src.f[1];
- XMM((modrm >> 3) & 0x7).f[2]=XMM((modrm >> 3) & 0x7).f[2] - src.f[2];
- XMM((modrm >> 3) & 0x7).f[3]=XMM((modrm >> 3) & 0x7).f[3] + src.f[3];
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
- void I386_OPS_BASE::SSEOP(movdq2q_r64_r128)() // Opcode f2 0f d6
-{
- UINT8 modrm = FETCH();
- MMXPROLOG();
- if( modrm >= 0xc0 ) {
- MMX((modrm >> 3) & 0x7).q = XMM(modrm & 0x7).q[0];
- CYCLES(1); // TODO: correct cycle count
- } else {
- // unsupported by cpu
- CYCLES(1); // TODO: correct cycle count
- }
-}
-
- void I386_OPS_BASE::SSEOP(cvtpd2dq_r128_rm128)() // Opcode f2 0f e6
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- XMM((modrm >> 3) & 0x7).i[0]=(INT32)XMM((modrm >> 3) & 0x7).f64[0];
- XMM((modrm >> 3) & 0x7).i[1]=(INT32)XMM((modrm >> 3) & 0x7).f64[1];
- XMM((modrm >> 3) & 0x7).q[1] = 0;
- } else {
- XMM_REG src;
- UINT32 ea = GetEA(modrm, 0);
- READXMM( ea, src);
- XMM((modrm >> 3) & 0x7).i[0]=(INT32)src.f64[0];
- XMM((modrm >> 3) & 0x7).i[1]=(INT32)src.f64[1];
- XMM((modrm >> 3) & 0x7).q[1] = 0;
- }
- CYCLES(1); // TODO: correct cycle count
-}
-
-void I386_OPS_BASE::SSEOP(lddqu_r128_m128)() // Opcode f2 0f f0
-{
- UINT8 modrm = FETCH();
- if( modrm >= 0xc0 ) {
- // unsupported by cpu
- CYCLES(1); // TODO: correct cycle count
- } else {
- UINT32 ea = GetEA(modrm, 0);
- READXMM(ea, XMM((modrm >> 3) & 0x7));
- }
-}
+++ /dev/null
-Based on MAME 0.152.
-Fixes in MAME 0.154 to 0.160 are applied.
-
-cycle_table_rm/pm are changed from dynamic array to static array.
-convert char to _TCHAR in disassembler.
+++ /dev/null
-// license:BSD-3-Clause
-// copyright-holders:Aaron Giles
-/***************************************************************************
-
- vtlb.c
-
- Generic virtual TLB implementation.
-
-***************************************************************************/
-
-//#include "emu.h"
-#include "vtlb.h"
-
-
-
-/***************************************************************************
- DEBUGGING
-***************************************************************************/
-
-#define PRINTF_TLB (0)
-
-
-
-/***************************************************************************
- TYPE DEFINITIONS
-***************************************************************************/
-
-/* VTLB state */
-struct vtlb_state
-{
- void * cpudevice; /* CPU device */
- address_spacenum space; /* address space */
- int dynamic; /* number of dynamic entries */
- int fixed; /* number of fixed entries */
- int dynindex; /* index of next dynamic entry */
- int pageshift; /* bits to shift to get page index */
- int addrwidth; /* logical address bus width */
- offs_t * live; /* array of live entries by table index */
- int * fixedpages; /* number of pages each fixed entry covers */
- vtlb_entry * table; /* table of entries by address */
- vtlb_entry * save; /* cache of live table entries for saving */
-};
-
-
-
-/***************************************************************************
- INITIALIZATION/TEARDOWN
-***************************************************************************/
-
-/*-------------------------------------------------
- vtlb_alloc - allocate a new VTLB for the
- given CPU
--------------------------------------------------*/
-
-vtlb_state *vtlb_alloc(void *cpu, address_spacenum space, int fixed_entries, int dynamic_entries)
-{
- vtlb_state *vtlb;
-
- /* allocate memory for the core structure */
- vtlb = (vtlb_state *)calloc(1, sizeof(vtlb_state));
-
- /* fill in CPU information */
- vtlb->cpudevice = cpu;
- vtlb->space = space;
- vtlb->dynamic = dynamic_entries;
- vtlb->fixed = fixed_entries;
-// const address_space_config *spaceconfig = device_get_space_config(*cpu, space);
-// assert(spaceconfig != NULL);
-// vtlb->pageshift = spaceconfig->m_page_shift;
-// vtlb->addrwidth = spaceconfig->m_logaddr_width;
- /* for i386 */
- vtlb->pageshift = 12;
- vtlb->addrwidth = 32;
-
- /* validate CPU information */
- assert((1 << vtlb->pageshift) > VTLB_FLAGS_MASK);
- assert(vtlb->addrwidth > vtlb->pageshift);
-
- /* allocate the entry array */
- vtlb->live = (offs_t *)calloc(fixed_entries + dynamic_entries, sizeof(offs_t));
-// cpu->save_pointer(NAME(vtlb->live), fixed_entries + dynamic_entries, space);
-
- /* allocate the lookup table */
- vtlb->table = (vtlb_entry *)calloc((size_t) 1 << (vtlb->addrwidth - vtlb->pageshift), sizeof(vtlb_entry));
-// cpu->save_pointer(NAME(vtlb->table), 1 << (vtlb->addrwidth - vtlb->pageshift), space);
-
- /* allocate the fixed page count array */
- if (fixed_entries > 0)
- {
- vtlb->fixedpages = (int *)calloc(fixed_entries, sizeof(int));
-// cpu->save_pointer(NAME(vtlb->fixedpages), fixed_entries, space);
- }
- return vtlb;
-}
-
-
-/*-------------------------------------------------
- vtlb_free - free an allocated VTLB
--------------------------------------------------*/
-
-void vtlb_free(vtlb_state *vtlb)
-{
- /* free the fixed pages if allocated */
- if (vtlb->fixedpages != NULL)
- free(vtlb->fixedpages);
-
- /* free the table and array if they exist */
- if (vtlb->live != NULL)
- free(vtlb->live);
- if (vtlb->table != NULL)
- free(vtlb->table);
-
- /* and then the VTLB object itself */
- free(vtlb);
-}
-
-
-
-/***************************************************************************
- FILLING
-***************************************************************************/
-
-/*-------------------------------------------------
- vtlb_fill - rcalled by the CPU core in
- response to an unmapped access
--------------------------------------------------*/
-
-static int cpu_translate_i386(void *cpudevice, address_spacenum space, int intention, offs_t *address);
-
-int vtlb_fill(vtlb_state *vtlb, offs_t address, int intention)
-{
- offs_t tableindex = address >> vtlb->pageshift;
- vtlb_entry entry = vtlb->table[tableindex];
- offs_t taddress;
-
-// if (PRINTF_TLB)
-// printf("vtlb_fill: %08X(%X) ... ", address, intention);
-
- /* should not be called here if the entry is in the table already */
-// assert((entry & (1 << intention)) == 0);
-
- /* if we have no dynamic entries, we always fail */
- if (vtlb->dynamic == 0)
- {
-// if (PRINTF_TLB)
-// printf("failed: no dynamic entries\n");
- return FALSE;
- }
-
- /* ask the CPU core to translate for us */
- taddress = address;
-// if (!vtlb->cpudevice->translate(vtlb->space, intention, taddress))
- if (!CPU_TRANSLATE_NAME(i386)(vtlb->cpudevice, vtlb->space, intention, &taddress))
- {
-// if (PRINTF_TLB)
-// printf("failed: no translation\n");
- return FALSE;
- }
-
- /* if this is the first successful translation for this address, allocate a new entry */
- if ((entry & VTLB_FLAGS_MASK) == 0)
- {
- int liveindex = vtlb->dynindex++ % vtlb->dynamic;
-
- /* if an entry already exists at this index, free it */
- if (vtlb->live[liveindex] != 0)
- vtlb->table[vtlb->live[liveindex] - 1] = 0;
-
- /* claim this new entry */
- vtlb->live[liveindex] = tableindex + 1;
-
- /* form a new blank entry */
- entry = (taddress >> vtlb->pageshift) << vtlb->pageshift;
- entry |= VTLB_FLAG_VALID;
-
-// if (PRINTF_TLB)
-// printf("success (%08X), new entry\n", taddress);
- }
-
- /* otherwise, ensure that different intentions do not produce different addresses */
- else
- {
- assert((entry >> vtlb->pageshift) == (taddress >> vtlb->pageshift));
- assert(entry & VTLB_FLAG_VALID);
-
-// if (PRINTF_TLB)
-// printf("success (%08X), existing entry\n", taddress);
- }
-
- /* add the intention to the list of valid intentions and store */
- entry |= 1 << (intention & (TRANSLATE_TYPE_MASK | TRANSLATE_USER_MASK));
- vtlb->table[tableindex] = entry;
- return TRUE;
-}
-
-
-/*-------------------------------------------------
- vtlb_load - load a fixed VTLB entry
--------------------------------------------------*/
-
-void vtlb_load(vtlb_state *vtlb, int entrynum, int numpages, offs_t address, vtlb_entry value)
-{
- offs_t tableindex = address >> vtlb->pageshift;
- int liveindex = vtlb->dynamic + entrynum;
- int pagenum;
-
- /* must be in range */
- assert(entrynum >= 0 && entrynum < vtlb->fixed);
-
-// if (PRINTF_TLB)
-// printf("vtlb_load %d for %d pages at %08X == %08X\n", entrynum, numpages, address, value);
-
- /* if an entry already exists at this index, free it */
- if (vtlb->live[liveindex] != 0)
- {
- int pagecount = vtlb->fixedpages[entrynum];
- int oldtableindex = vtlb->live[liveindex] - 1;
- for (pagenum = 0; pagenum < pagecount; pagenum++)
- vtlb->table[oldtableindex + pagenum] = 0;
- }
-
- /* claim this new entry */
- vtlb->live[liveindex] = tableindex + 1;
-
- /* store the raw value, making sure the "fixed" flag is set */
- value |= VTLB_FLAG_FIXED;
- vtlb->fixedpages[entrynum] = numpages;
- for (pagenum = 0; pagenum < numpages; pagenum++)
- vtlb->table[tableindex + pagenum] = value + (pagenum << vtlb->pageshift);
-}
-
-/*-------------------------------------------------
- vtlb_dynload - load a dynamic VTLB entry
--------------------------------------------------*/
-
-void vtlb_dynload(vtlb_state *vtlb, UINT32 index, offs_t address, vtlb_entry value)
-{
- vtlb_entry entry = vtlb->table[index];
-
- if (vtlb->dynamic == 0)
- {
-// if (PRINTF_TLB)
-// printf("failed: no dynamic entries\n");
- return;
- }
-
- int liveindex = vtlb->dynindex++ % vtlb->dynamic;
- /* is entry already live? */
- if (!(entry & VTLB_FLAG_VALID))
- {
- /* if an entry already exists at this index, free it */
- if (vtlb->live[liveindex] != 0)
- vtlb->table[vtlb->live[liveindex] - 1] = 0;
-
- /* claim this new entry */
- vtlb->live[liveindex] = index + 1;
- }
- /* form a new blank entry */
- entry = (address >> vtlb->pageshift) << vtlb->pageshift;
- entry |= VTLB_FLAG_VALID | value;
-
-// if (PRINTF_TLB)
-// printf("success (%08X), new entry\n", address);
-
- vtlb->table[index] = entry;
-}
-
-/***************************************************************************
- FLUSHING
-***************************************************************************/
-
-/*-------------------------------------------------
- vtlb_flush_dynamic - flush all knowledge
- from the dynamic part of the VTLB
--------------------------------------------------*/
-
-void vtlb_flush_dynamic(vtlb_state *vtlb)
-{
- int liveindex;
-
-// if (PRINTF_TLB)
-// printf("vtlb_flush_dynamic\n");
-
- /* loop over live entries and release them from the table */
- for (liveindex = 0; liveindex < vtlb->dynamic; liveindex++)
- if (vtlb->live[liveindex] != 0)
- {
- offs_t tableindex = vtlb->live[liveindex] - 1;
- vtlb->table[tableindex] = 0;
- vtlb->live[liveindex] = 0;
- }
-}
-
-
-/*-------------------------------------------------
- vtlb_flush_address - flush knowledge of a
- particular address from the VTLB
--------------------------------------------------*/
-
-void vtlb_flush_address(vtlb_state *vtlb, offs_t address)
-{
- offs_t tableindex = address >> vtlb->pageshift;
-
-// if (PRINTF_TLB)
-// printf("vtlb_flush_address %08X\n", address);
-
- /* free the entry in the table; for speed, we leave the entry in the live array */
- vtlb->table[tableindex] = 0;
-}
-
-
-
-/***************************************************************************
- ACCESSORS
-***************************************************************************/
-
-/*-------------------------------------------------
- vtlb_table - return a pointer to the base of
- the linear VTLB lookup table
--------------------------------------------------*/
-
-const vtlb_entry *vtlb_table(vtlb_state *vtlb)
-{
- return vtlb->table;
-}
+++ /dev/null
-// license:BSD-3-Clause
-// copyright-holders:Aaron Giles
-/***************************************************************************
-
- vtlb.h
-
- Generic virtual TLB implementation.
-
-***************************************************************************/
-
-#pragma once
-
-#ifndef __VTLB_H__
-#define __VTLB_H__
-
-
-
-/***************************************************************************
- CONSTANTS
-***************************************************************************/
-
-#define VTLB_FLAGS_MASK 0xff
-
-#define VTLB_READ_ALLOWED 0x01 /* (1 << TRANSLATE_READ) */
-#define VTLB_WRITE_ALLOWED 0x02 /* (1 << TRANSLATE_WRITE) */
-#define VTLB_FETCH_ALLOWED 0x04 /* (1 << TRANSLATE_FETCH) */
-#define VTLB_FLAG_VALID 0x08
-#define VTLB_USER_READ_ALLOWED 0x10 /* (1 << TRANSLATE_READ_USER) */
-#define VTLB_USER_WRITE_ALLOWED 0x20 /* (1 << TRANSLATE_WRITE_USER) */
-#define VTLB_USER_FETCH_ALLOWED 0x40 /* (1 << TRANSLATE_FETCH_USER) */
-#define VTLB_FLAG_FIXED 0x80
-
-
-
-/***************************************************************************
- TYPE DEFINITIONS
-***************************************************************************/
-
-/* represents an entry in the VTLB */
-typedef UINT32 vtlb_entry;
-
-
-/* opaque structure describing VTLB state */
-struct vtlb_state;
-
-
-
-/***************************************************************************
- FUNCTION PROTOTYPES
-***************************************************************************/
-
-
-/* ----- initialization/teardown ----- */
-
-/* allocate a new VTLB for the given CPU */
-vtlb_state *vtlb_alloc(void *cpu, address_spacenum space, int fixed_entries, int dynamic_entries);
-
-/* free an allocated VTLB */
-void vtlb_free(vtlb_state *vtlb);
-
-
-/* ----- filling ----- */
-
-/* called by the CPU core in response to an unmapped access */
-int vtlb_fill(vtlb_state *vtlb, offs_t address, int intention);
-
-/* load a fixed VTLB entry */
-void vtlb_load(vtlb_state *vtlb, int entrynum, int numpages, offs_t address, vtlb_entry value);
-
-/* load a dynamic VTLB entry */
-void vtlb_dynload(vtlb_state *vtlb, UINT32 index, offs_t address, vtlb_entry value);
-
-/* ----- flushing ----- */
-
-/* flush all knowledge from the dynamic part of the VTLB */
-void vtlb_flush_dynamic(vtlb_state *vtlb);
-
-/* flush knowledge of a particular address from the VTLB */
-void vtlb_flush_address(vtlb_state *vtlb, offs_t address);
-
-
-/* ----- accessors ----- */
-
-/* return a pointer to the base of the linear VTLB lookup table */
-const vtlb_entry *vtlb_table(vtlb_state *vtlb);
-
-
-#endif /* __VTLB_H__ */
+++ /dev/null
-// license:BSD-3-Clause
-// copyright-holders:Phil Bennett
-/***************************************************************************
-
- x87 FPU emulation
-
- TODO:
- - 80-bit precision for F2XM1, FYL2X, FPATAN
- - Figure out why SoftFloat trig extensions produce bad values
- - Cycle counts for all processors (currently using 486 counts)
- - Precision-dependent cycle counts for divide instructions
- - Last instruction, operand pointers etc.
- - Fix FLDENV, FSTENV, FSAVE, FRSTOR and FPREM
- - Status word C2 updates to reflect round up/down
- - Handling of invalid and denormal numbers
- - Remove redundant operand checks
- - Exceptions
-
-***************************************************************************/
-
-#include <math.h>
-
-
-/*************************************
- *
- * Defines
- *
- *************************************/
-
-#define X87_SW_IE 0x0001
-#define X87_SW_DE 0x0002
-#define X87_SW_ZE 0x0004
-#define X87_SW_OE 0x0008
-#define X87_SW_UE 0x0010
-#define X87_SW_PE 0x0020
-#define X87_SW_SF 0x0040
-#define X87_SW_ES 0x0080
-#define X87_SW_C0 0x0100
-#define X87_SW_C1 0x0200
-#define X87_SW_C2 0x0400
-#define X87_SW_TOP_SHIFT 11
-#define X87_SW_TOP_MASK 7
-#define X87_SW_C3 0x4000
-#define X87_SW_BUSY 0x8000
-
-#define X87_CW_IM 0x0001
-#define X87_CW_DM 0x0002
-#define X87_CW_ZM 0x0004
-#define X87_CW_OM 0x0008
-#define X87_CW_UM 0x0010
-#define X87_CW_PM 0x0020
-#define X87_CW_PC_SHIFT 8
-#define X87_CW_PC_MASK 3
-#define X87_CW_PC_SINGLE 0
-#define X87_CW_PC_DOUBLE 2
-#define X87_CW_PC_EXTEND 3
-#define X87_CW_RC_SHIFT 10
-#define X87_CW_RC_MASK 3
-#define X87_CW_RC_NEAREST 0
-#define X87_CW_RC_DOWN 1
-#define X87_CW_RC_UP 2
-#define X87_CW_RC_ZERO 3
-
-#define X87_TW_MASK 3
-#define X87_TW_VALID 0
-#define X87_TW_ZERO 1
-#define X87_TW_SPECIAL 2
-#define X87_TW_EMPTY 3
-
-
-/*************************************
- *
- * Macros
- *
- *************************************/
-
-#define ST_TO_PHYS(x) (((cpustate->x87_sw >> X87_SW_TOP_SHIFT) + (x)) & X87_SW_TOP_MASK)
-#define ST(x) (cpustate->x87_reg[ST_TO_PHYS(x)])
-#define X87_TW_FIELD_SHIFT(x) ((x) << 1)
-#define X87_TAG(x) ((cpustate->x87_tw >> X87_TW_FIELD_SHIFT(x)) & X87_TW_MASK)
-#define X87_RC ((cpustate->x87_cw >> X87_CW_RC_SHIFT) & X87_CW_RC_MASK)
-#define X87_IS_ST_EMPTY(x) (X87_TAG(ST_TO_PHYS(x)) == X87_TW_EMPTY)
-#define X87_SW_C3_0 X87_SW_C0
-
-#define UNIMPLEMENTED fatalerror("Unimplemented x87 op: %s (PC:%x)\n", __FUNCTION__, cpustate->pc)
-
-
-/*************************************
- *
- * Constants
- *
- *************************************/
-
-const floatx80 I386_OPS_BASE::ffx80_zero = { 0x0000, U64(0x0000000000000000) };
-const floatx80 I386_OPS_BASE::ffx80_one = { 0x3fff, U64(0x8000000000000000) };
-
-const floatx80 I386_OPS_BASE::ffx80_ninf = { 0xffff, U64(0x8000000000000000) };
-const floatx80 I386_OPS_BASE::ffx80_inan = { 0xffff, U64(0xc000000000000000) };
-
-/* Maps x87 round modes to SoftFloat round modes */
-const int I386_OPS_BASE::fx87_to_sf_rc[4] =
-{
- float_round_nearest_even,
- float_round_down,
- float_round_up,
- float_round_to_zero,
-};
-
-
-/*************************************
- *
- * SoftFloat helpers
- *
- *************************************/
-
-extern flag I386_OPS_BASE::ffloatx80_is_nan( floatx80 a );
-
-extern flag I386_OPS_BASE::ffloatx80_is_signaling_nan(floatx80 a);
-
-INLINE flag I386_OPS_BASE::floatx80_is_quiet_nan(floatx80 a)
-{
- bits64 aLow;
-
- aLow = a.low & ~LIT64(0x4000000000000000);
- return
- ((a.high & 0x7FFF) == 0x7FFF)
- && (bits64)(aLow << 1)
- && (a.low != aLow);
-}
-
-INLINE int I386_OPS_BASE::floatx80_is_zero(floatx80 fx)
-{
- return (((fx.high & 0x7fff) == 0) && ((fx.low << 1) == 0));
-}
-
-INLINE int I386_OPS_BASE::floatx80_is_inf(floatx80 fx)
-{
- return (((fx.high & 0x7fff) == 0x7fff) && ((fx.low << 1) == 0));
-}
-
-INLINE int I386_OPS_BASE::floatx80_is_denormal(floatx80 fx)
-{
- return (((fx.high & 0x7fff) == 0) &&
- ((fx.low & U64(0x8000000000000000)) == 0) &&
- ((fx.low << 1) != 0));
-}
-
-INLINE floatx80 I386_OPS_BASE::ffloatx80_abs(floatx80 fx)
-{
- fx.high &= 0x7fff;
- return fx;
-}
-
-INLINE double I386_OPS_BASE::ffx80_to_double(floatx80 fx)
-{
- UINT64 d = floatx80_to_float64(fx);
- return *(double*)&d;
-}
-
-INLINE floatx80 I386_OPS_BASE::fdouble_to_fx80(double in)
-{
- return float64_to_floatx80(*(UINT64*)&in);
-}
-
-INLINE floatx80 I386_OPS_BASE::fREAD80( UINT32 ea)
-{
- floatx80 t;
-
- t.low = READ64( ea);
- t.high = READ16( ea + 8);
-
- return t;
-}
-
-INLINE void I386_OPS_BASE::WRITE80( UINT32 ea, floatx80 t)
-{
- WRITE64( ea, t.low);
- WRITE16( ea + 8, t.high);
-}
-
-
-/*************************************
- *
- * x87 stack handling
- *
- *************************************/
-
-INLINE void I386_OPS_BASE::x87_set_stack_top( int I386_OPS_BASE::top)
-{
- cpustate->x87_sw &= ~(X87_SW_TOP_MASK << X87_SW_TOP_SHIFT);
- cpustate->x87_sw |= (top << X87_SW_TOP_SHIFT);
-}
-
-INLINE void I386_OPS_BASE::x87_set_tag( int I386_OPS_BASE::reg, int I386_OPS_BASE::tag)
-{
- int I386_OPS_BASE::shift = X87_TW_FIELD_SHIFT(reg);
-
- cpustate->x87_tw &= ~(X87_TW_MASK << shift);
- cpustate->x87_tw |= (tag << shift);
-}
-
-void I386_OPS_BASE::x87_write_stack( int I386_OPS_BASE::i, floatx80 value, int I386_OPS_BASE::update_tag)
-{
- ST(i) = value;
-
- if (update_tag)
- {
- int I386_OPS_BASE::tag;
-
- if (floatx80_is_zero(value))
- {
- tag = X87_TW_ZERO;
- }
- else if (floatx80_is_inf(value) || floatx80_is_nan(value))
- {
- tag = X87_TW_SPECIAL;
- }
- else
- {
- tag = X87_TW_VALID;
- }
-
- x87_set_tag( ST_TO_PHYS(i), tag);
- }
-}
-
-INLINE void I386_OPS_BASE::x87_set_stack_underflow()
-{
- cpustate->x87_sw &= ~X87_SW_C1;
- cpustate->x87_sw |= X87_SW_IE | X87_SW_SF;
-}
-
-INLINE void I386_OPS_BASE::x87_set_stack_overflow()
-{
- cpustate->x87_sw |= X87_SW_C1 | X87_SW_IE | X87_SW_SF;
-}
-
-int I386_OPS_BASE::x87_inc_stack()
-{
- int I386_OPS_BASE::ret = 1;
-
- // Check for stack underflow
- if (X87_IS_ST_EMPTY(0))
- {
- ret = 0;
- x87_set_stack_underflow();
-
- // Don't update the stack if the exception is unmasked
- if (~cpustate->x87_cw & X87_CW_IM)
- return ret;
- }
-
- x87_set_tag( ST_TO_PHYS(0), X87_TW_EMPTY);
- x87_set_stack_top( ST_TO_PHYS(1));
- return ret;
-}
-
-int I386_OPS_BASE::x87_dec_stack()
-{
- int I386_OPS_BASE::ret = 1;
-
- // Check for stack overflow
- if (!X87_IS_ST_EMPTY(7))
- {
- ret = 0;
- x87_set_stack_overflow();
-
- // Don't update the stack if the exception is unmasked
- if (~cpustate->x87_cw & X87_CW_IM)
- return ret;
- }
-
- x87_set_stack_top( ST_TO_PHYS(7));
- return ret;
-}
-
-
-/*************************************
- *
- * Exception handling
- *
- *************************************/
-
-int I386_OPS_BASE::x87_check_exceptions()
-{
- /* Update the exceptions from SoftFloat */
- if (float_exception_flags & float_flag_invalid)
- {
- cpustate->x87_sw |= X87_SW_IE;
- float_exception_flags &= ~float_flag_invalid;
- }
- if (float_exception_flags & float_flag_overflow)
- {
- cpustate->x87_sw |= X87_SW_OE;
- float_exception_flags &= ~float_flag_overflow;
- }
- if (float_exception_flags & float_flag_underflow)
- {
- cpustate->x87_sw |= X87_SW_UE;
- float_exception_flags &= ~float_flag_underflow;
- }
- if (float_exception_flags & float_flag_inexact)
- {
- cpustate->x87_sw |= X87_SW_PE;
- float_exception_flags &= ~float_flag_inexact;
- }
-
- if ((cpustate->x87_sw & ~cpustate->x87_cw) & 0x3f)
- {
- // cpustate->device->execute().set_input_line(INPUT_LINE_FERR, RAISE_LINE);
- logerror("Unmasked x87 exception (CW:%.4x, SW:%.4x)\n", cpustate->x87_cw, cpustate->x87_sw);
- if (cpustate->cr[0] & 0x20) // FIXME: 486 and up only
- {
- cpustate->ext = 1;
- i386_trap( FAULT_MF, 0, 0);
- }
- return 0;
- }
-
- return 1;
-}
-
-INLINE void I386_OPS_BASE::x87_write_cw( UINT16 cw)
-{
- cpustate->x87_cw = cw;
-
- /* Update the SoftFloat rounding mode */
- float_rounding_mode = x87_to_sf_rc[(cpustate->x87_cw >> X87_CW_RC_SHIFT) & X87_CW_RC_MASK];
-}
-
-void I386_OPS_BASE::x87_reset()
-{
- x87_write_cw( 0x0037f);
-
- cpustate->x87_sw = 0;
- cpustate->x87_tw = 0xffff;
-
- // TODO: FEA=0, FDS=0, FIP=0 FOP=0 FCS=0
- cpustate->x87_data_ptr = 0;
- cpustate->x87_inst_ptr = 0;
- cpustate->x87_opcode = 0;
-}
-
-
-/*************************************
- *
- * Core arithmetic
- *
- *************************************/
-
-floatx80 I386_OPS_BASE::fx87_add( floatx80 a, floatx80 b)
-{
- floatx80 result = { 0 };
-
- switch ((cpustate->x87_cw >> X87_CW_PC_SHIFT) & X87_CW_PC_MASK)
- {
- case X87_CW_PC_SINGLE:
- {
- float32 a32 = floatx80_to_float32(a);
- float32 b32 = floatx80_to_float32(b);
- result = float32_to_floatx80(float32_add(a32, b32));
- break;
- }
- case X87_CW_PC_DOUBLE:
- {
- float64 a64 = floatx80_to_float64(a);
- float64 b64 = floatx80_to_float64(b);
- result = float64_to_floatx80(float64_add(a64, b64));
- break;
- }
- case X87_CW_PC_EXTEND:
- {
- result = floatx80_add(a, b);
- break;
- }
- }
-
- return result;
-}
-
-floatx80 I386_OPS_BASE::fx87_sub( floatx80 a, floatx80 b)
-{
- floatx80 result = { 0 };
-
- switch ((cpustate->x87_cw >> X87_CW_PC_SHIFT) & X87_CW_PC_MASK)
- {
- case X87_CW_PC_SINGLE:
- {
- float32 a32 = floatx80_to_float32(a);
- float32 b32 = floatx80_to_float32(b);
- result = float32_to_floatx80(float32_sub(a32, b32));
- break;
- }
- case X87_CW_PC_DOUBLE:
- {
- float64 a64 = floatx80_to_float64(a);
- float64 b64 = floatx80_to_float64(b);
- result = float64_to_floatx80(float64_sub(a64, b64));
- break;
- }
- case X87_CW_PC_EXTEND:
- {
- result = floatx80_sub(a, b);
- break;
- }
- }
-
- return result;
-}
-
-floatx80 I386_OPS_BASE::x87_mul( floatx80 a, floatx80 b)
-{
- floatx80 val = { 0 };
-
- switch ((cpustate->x87_cw >> X87_CW_PC_SHIFT) & X87_CW_PC_MASK)
- {
- case X87_CW_PC_SINGLE:
- {
- float32 a32 = floatx80_to_float32(a);
- float32 b32 = floatx80_to_float32(b);
- val = float32_to_floatx80(float32_mul(a32, b32));
- break;
- }
- case X87_CW_PC_DOUBLE:
- {
- float64 a64 = floatx80_to_float64(a);
- float64 b64 = floatx80_to_float64(b);
- val = float64_to_floatx80(float64_mul(a64, b64));
- break;
- }
- case X87_CW_PC_EXTEND:
- {
- val = floatx80_mul(a, b);
- break;
- }
- }
-
- return val;
-}
-
-
-floatx80 I386_OPS_BASE::x87_div( floatx80 a, floatx80 b)
-{
- floatx80 val = { 0 };
-
- switch ((cpustate->x87_cw >> X87_CW_PC_SHIFT) & X87_CW_PC_MASK)
- {
- case X87_CW_PC_SINGLE:
- {
- float32 a32 = floatx80_to_float32(a);
- float32 b32 = floatx80_to_float32(b);
- val = float32_to_floatx80(float32_div(a32, b32));
- break;
- }
- case X87_CW_PC_DOUBLE:
- {
- float64 a64 = floatx80_to_float64(a);
- float64 b64 = floatx80_to_float64(b);
- val = float64_to_floatx80(float64_div(a64, b64));
- break;
- }
- case X87_CW_PC_EXTEND:
- {
- val = floatx80_div(a, b);
- break;
- }
- }
- return val;
-}
-
-
-/*************************************
- *
- * Instructions
- *
- *************************************/
-
-/*************************************
- *
- * Add
- *
- *************************************/
-
-void I386_OPS_BASE::x87_fadd_m32real( UINT8 modrm)
-{
- floatx80 result;
-
- UINT32 ea = GetEA( modrm, 0);
- if (X87_IS_ST_EMPTY(0))
- {
- x87_set_stack_underflow();
- result = fx80_inan;
- }
- else
- {
- UINT32 m32real = READ32( ea);
-
- floatx80 a = ST(0);
- floatx80 b = float32_to_floatx80(m32real);
-
- if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
- || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
- {
- cpustate->x87_sw |= X87_SW_IE;
- result = fx80_inan;
- }
- else
- {
- result = x87_add( a, b);
- }
- }
-
- if (x87_check_exceptions())
- x87_write_stack( 0, result, TRUE);
-
- CYCLES( 8);
-}
-
-void I386_OPS_BASE::x87_fadd_m64real( UINT8 modrm)
-{
- floatx80 result;
-
- UINT32 ea = GetEA( modrm, 0);
- if (X87_IS_ST_EMPTY(0))
- {
- x87_set_stack_underflow();
- result = fx80_inan;
- }
- else
- {
- UINT64 m64real = READ64( ea);
-
- floatx80 a = ST(0);
- floatx80 b = float64_to_floatx80(m64real);
-
- if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
- || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
- {
- cpustate->x87_sw |= X87_SW_IE;
- result = fx80_inan;
- }
- else
- {
- result = x87_add( a, b);
- }
- }
-
- if (x87_check_exceptions())
- x87_write_stack( 0, result, TRUE);
-
- CYCLES( 8);
-}
-
-void I386_OPS_BASE::x87_fadd_st_sti( UINT8 modrm)
-{
- floatx80 result;
- int I386_OPS_BASE::i = modrm & 7;
-
- if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
- {
- x87_set_stack_underflow();
- result = fx80_inan;
- }
- else
- {
- floatx80 a = ST(0);
- floatx80 b = ST(i);
-
- if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
- || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
- {
- cpustate->x87_sw |= X87_SW_IE;
- result = fx80_inan;
- }
- else
- {
- result = x87_add( a, b);
- }
- }
-
- if (x87_check_exceptions())
- x87_write_stack( 0, result, TRUE);
-
- CYCLES( 8);
-}
-
-void I386_OPS_BASE::x87_fadd_sti_st( UINT8 modrm)
-{
- floatx80 result;
- int I386_OPS_BASE::i = modrm & 7;
-
- if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
- {
- x87_set_stack_underflow();
- result = fx80_inan;
- }
- else
- {
- floatx80 a = ST(0);
- floatx80 b = ST(i);
-
- if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
- || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
- {
- cpustate->x87_sw |= X87_SW_IE;
- result = fx80_inan;
- }
- else
- {
- result = x87_add( a, b);
- }
- }
-
- if (x87_check_exceptions())
- x87_write_stack( i, result, TRUE);
-
- CYCLES( 8);
-}
-
-void I386_OPS_BASE::x87_faddp( UINT8 modrm)
-{
- floatx80 result;
- int I386_OPS_BASE::i = modrm & 7;
-
- if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
- {
- x87_set_stack_underflow();
- result = fx80_inan;
- }
- else
- {
- floatx80 a = ST(0);
- floatx80 b = ST(i);
-
- if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
- || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
- {
- cpustate->x87_sw |= X87_SW_IE;
- result = fx80_inan;
- }
- else
- {
- result = x87_add( a, b);
- }
- }
-
- if (x87_check_exceptions())
- {
- x87_write_stack( i, result, TRUE);
- x87_inc_stack();
- }
-
- CYCLES( 8);
-}
-
-void I386_OPS_BASE::x87_fiadd_m32int( UINT8 modrm)
-{
- floatx80 result;
-
- UINT32 ea = GetEA( modrm, 0);
- if (X87_IS_ST_EMPTY(0))
- {
- x87_set_stack_underflow();
- result = fx80_inan;
- }
- else
- {
- INT32 m32int I386_OPS_BASE::= READ32( ea);
-
- floatx80 a = ST(0);
- floatx80 b = int32_to_floatx80(m32int);
-
- if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
- || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
- {
- cpustate->x87_sw |= X87_SW_IE;
- result = fx80_inan;
- }
- else
- {
- result = x87_add( a, b);
- }
- }
-
- if (x87_check_exceptions())
- x87_write_stack( 0, result, TRUE);
-
- CYCLES( 19);
-}
-
-void I386_OPS_BASE::x87_fiadd_m16int( UINT8 modrm)
-{
- floatx80 result;
-
- UINT32 ea = GetEA( modrm, 0);
- if (X87_IS_ST_EMPTY(0))
- {
- x87_set_stack_underflow();
- result = fx80_inan;
- }
- else
- {
- INT16 m16int I386_OPS_BASE::= READ16( ea);
-
- floatx80 a = ST(0);
- floatx80 b = int32_to_floatx80(m16int);
-
- if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
- || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
- {
- cpustate->x87_sw |= X87_SW_IE;
- result = fx80_inan;
- }
- else
- {
- result = x87_add( a, b);
- }
- }
-
- if (x87_check_exceptions())
- x87_write_stack( 0, result, TRUE);
-
- CYCLES( 20);
-}
-
-
-/*************************************
- *
- * Subtract
- *
- *************************************/
-
-void I386_OPS_BASE::x87_fsub_m32real( UINT8 modrm)
-{
- floatx80 result;
-
- UINT32 ea = GetEA( modrm, 0);
- if (X87_IS_ST_EMPTY(0))
- {
- x87_set_stack_underflow();
- result = fx80_inan;
- }
- else
- {
- UINT32 m32real = READ32( ea);
-
- floatx80 a = ST(0);
- floatx80 b = float32_to_floatx80(m32real);
-
- if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
- || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
- {
- cpustate->x87_sw |= X87_SW_IE;
- result = fx80_inan;
- }
- else
- {
- result = x87_sub( a, b);
- }
- }
-
- if (x87_check_exceptions())
- x87_write_stack( 0, result, TRUE);
-
- CYCLES( 8);
-}
-
-void I386_OPS_BASE::x87_fsub_m64real( UINT8 modrm)
-{
- floatx80 result;
-
- UINT32 ea = GetEA( modrm, 0);
- if (X87_IS_ST_EMPTY(0))
- {
- x87_set_stack_underflow();
- result = fx80_inan;
- }
- else
- {
- UINT64 m64real = READ64( ea);
-
- floatx80 a = ST(0);
- floatx80 b = float64_to_floatx80(m64real);
-
- if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
- || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
- {
- cpustate->x87_sw |= X87_SW_IE;
- result = fx80_inan;
- }
- else
- {
- result = x87_sub( a, b);
- }
- }
-
- if (x87_check_exceptions())
- x87_write_stack( 0, result, TRUE);
-
- CYCLES( 8);
-}
-
-void I386_OPS_BASE::x87_fsub_st_sti( UINT8 modrm)
-{
- floatx80 result;
- int i = modrm & 7;
-
- if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
- {
- x87_set_stack_underflow();
- result = fx80_inan;
- }
- else
- {
- floatx80 a = ST(0);
- floatx80 b = ST(i);
-
- if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
- || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
- {
- cpustate->x87_sw |= X87_SW_IE;
- result = fx80_inan;
- }
- else
- {
- result = x87_sub( a, b);
- }
- }
-
- if (x87_check_exceptions())
- x87_write_stack( 0, result, TRUE);
-
- CYCLES( 8);
-}
-
-void I386_OPS_BASE::x87_fsub_sti_st( UINT8 modrm)
-{
- floatx80 result;
- int i = modrm & 7;
-
- if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
- {
- x87_set_stack_underflow();
- result = fx80_inan;
- }
- else
- {
- floatx80 a = ST(i);
- floatx80 b = ST(0);
-
- if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
- || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
- {
- cpustate->x87_sw |= X87_SW_IE;
- result = fx80_inan;
- }
- else
- {
- result = x87_sub( a, b);
- }
- }
-
- if (x87_check_exceptions())
- x87_write_stack( i, result, TRUE);
-
- CYCLES( 8);
-}
-
-void I386_OPS_BASE::x87_fsubp( UINT8 modrm)
-{
- floatx80 result;
- int i = modrm & 7;
-
- if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
- {
- x87_set_stack_underflow();
- result = fx80_inan;
- }
- else
- {
- floatx80 a = ST(i);
- floatx80 b = ST(0);
-
- if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
- || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
- {
- cpustate->x87_sw |= X87_SW_IE;
- result = fx80_inan;
- }
- else
- {
- result = x87_sub( a, b);
- }
- }
-
- if (x87_check_exceptions())
- {
- x87_write_stack( i, result, TRUE);
- x87_inc_stack();
- }
-
- CYCLES( 8);
-}
-
-void I386_OPS_BASE::x87_fisub_m32int( UINT8 modrm)
-{
- floatx80 result;
-
- UINT32 ea = GetEA( modrm, 0);
- if (X87_IS_ST_EMPTY(0))
- {
- x87_set_stack_underflow();
- result = fx80_inan;
- }
- else
- {
- INT32 m32int = READ32( ea);
-
- floatx80 a = ST(0);
- floatx80 b = int32_to_floatx80(m32int);
-
- if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
- || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
- {
- cpustate->x87_sw |= X87_SW_IE;
- result = fx80_inan;
- }
- else
- {
- result = x87_sub( a, b);
- }
- }
-
- if (x87_check_exceptions())
- x87_write_stack( 0, result, TRUE);
-
- CYCLES( 19);
-}
-
-void I386_OPS_BASE::x87_fisub_m16int( UINT8 modrm)
-{
- floatx80 result;
-
- UINT32 ea = GetEA( modrm, 0);
- if (X87_IS_ST_EMPTY(0))
- {
- x87_set_stack_underflow();
- result = fx80_inan;
- }
- else
- {
- INT16 m16int = READ16( ea);
-
- floatx80 a = ST(0);
- floatx80 b = int32_to_floatx80(m16int);
-
- if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
- || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
- {
- cpustate->x87_sw |= X87_SW_IE;
- result = fx80_inan;
- }
- else
- {
- result = x87_sub( a, b);
- }
- }
-
- if (x87_check_exceptions())
- x87_write_stack( 0, result, TRUE);
-
- CYCLES( 20);
-}
-
-
-/*************************************
- *
- * Reverse Subtract
- *
- *************************************/
-
-void I386_OPS_BASE::x87_fsubr_m32real( UINT8 modrm)
-{
- floatx80 result;
-
- UINT32 ea = GetEA( modrm, 0);
- if (X87_IS_ST_EMPTY(0))
- {
- x87_set_stack_underflow();
- result = fx80_inan;
- }
- else
- {
- UINT32 m32real = READ32( ea);
-
- floatx80 a = float32_to_floatx80(m32real);
- floatx80 b = ST(0);
-
- if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
- || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
- {
- cpustate->x87_sw |= X87_SW_IE;
- result = fx80_inan;
- }
- else
- {
- result = x87_sub( a, b);
- }
- }
-
- if (x87_check_exceptions())
- x87_write_stack( 0, result, TRUE);
-
- CYCLES( 8);
-}
-
-void I386_OPS_BASE::x87_fsubr_m64real( UINT8 modrm)
-{
- floatx80 result;
-
- UINT32 ea = GetEA( modrm, 0);
- if (X87_IS_ST_EMPTY(0))
- {
- x87_set_stack_underflow();
- result = fx80_inan;
- }
- else
- {
- UINT64 m64real = READ64( ea);
-
- floatx80 a = float64_to_floatx80(m64real);
- floatx80 b = ST(0);
-
- if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
- || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
- {
- cpustate->x87_sw |= X87_SW_IE;
- result = fx80_inan;
- }
- else
- {
- result = x87_sub( a, b);
- }
- }
-
- if (x87_check_exceptions())
- x87_write_stack( 0, result, TRUE);
-
- CYCLES( 8);
-}
-
-void I386_OPS_BASE::x87_fsubr_st_sti( UINT8 modrm)
-{
- floatx80 result;
- int i = modrm & 7;
-
- if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
- {
- x87_set_stack_underflow();
- result = fx80_inan;
- }
- else
- {
- floatx80 a = ST(i);
- floatx80 b = ST(0);
-
- if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
- || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
- {
- cpustate->x87_sw |= X87_SW_IE;
- result = fx80_inan;
- }
- else
- {
- result = x87_sub( a, b);
- }
- }
-
- if (x87_check_exceptions())
- x87_write_stack( 0, result, TRUE);
-
- CYCLES( 8);
-}
-
-void I386_OPS_BASE::x87_fsubr_sti_st( UINT8 modrm)
-{
- floatx80 result;
- int i = modrm & 7;
-
- if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
- {
- x87_set_stack_underflow();
- result = fx80_inan;
- }
- else
- {
- floatx80 a = ST(0);
- floatx80 b = ST(i);
-
- if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
- || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
- {
- cpustate->x87_sw |= X87_SW_IE;
- result = fx80_inan;
- }
- else
- {
- result = x87_sub( a, b);
- }
- }
-
- if (x87_check_exceptions())
- x87_write_stack( i, result, TRUE);
-
- CYCLES( 8);
-}
-
-void I386_OPS_BASE::x87_fsubrp( UINT8 modrm)
-{
- floatx80 result;
- int i = modrm & 7;
-
- if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
- {
- x87_set_stack_underflow();
- result = fx80_inan;
- }
- else
- {
- floatx80 a = ST(0);
- floatx80 b = ST(i);
-
- if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
- || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
- {
- cpustate->x87_sw |= X87_SW_IE;
- result = fx80_inan;
- }
- else
- {
- result = x87_sub( a, b);
- }
- }
-
- if (x87_check_exceptions())
- {
- x87_write_stack( i, result, TRUE);
- x87_inc_stack();
- }
-
- CYCLES( 8);
-}
-
-void I386_OPS_BASE::x87_fisubr_m32int( UINT8 modrm)
-{
- floatx80 result;
-
- UINT32 ea = GetEA( modrm, 0);
- if (X87_IS_ST_EMPTY(0))
- {
- x87_set_stack_underflow();
- result = fx80_inan;
- }
- else
- {
- INT32 m32int = READ32( ea);
-
- floatx80 a = int32_to_floatx80(m32int);
- floatx80 b = ST(0);
-
- if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
- || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
- {
- cpustate->x87_sw |= X87_SW_IE;
- result = fx80_inan;
- }
- else
- {
- result = x87_sub( a, b);
- }
- }
-
- if (x87_check_exceptions())
- x87_write_stack( 0, result, TRUE);
-
- CYCLES( 19);
-}
-
-void I386_OPS_BASE::x87_fisubr_m16int( UINT8 modrm)
-{
- floatx80 result;
-
- UINT32 ea = GetEA( modrm, 0);
- if (X87_IS_ST_EMPTY(0))
- {
- x87_set_stack_underflow();
- result = fx80_inan;
- }
- else
- {
- INT16 m16int = READ16( ea);
-
- floatx80 a = int32_to_floatx80(m16int);
- floatx80 b = ST(0);
-
- if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
- || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
- {
- cpustate->x87_sw |= X87_SW_IE;
- result = fx80_inan;
- }
- else
- {
- result = x87_sub( a, b);
- }
- }
-
- if (x87_check_exceptions())
- x87_write_stack( 0, result, TRUE);
-
- CYCLES( 20);
-}
-
-
-/*************************************
- *
- * Divide
- *
- *************************************/
-
-void I386_OPS_BASE::x87_fdiv_m32real( UINT8 modrm)
-{
- floatx80 result;
-
- UINT32 ea = GetEA( modrm, 0);
- if (X87_IS_ST_EMPTY(0))
- {
- x87_set_stack_underflow();
- result = fx80_inan;
- }
- else
- {
- UINT32 m32real = READ32( ea);
-
- floatx80 a = ST(0);
- floatx80 b = float32_to_floatx80(m32real);
-
- if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
- {
- cpustate->x87_sw |= X87_SW_IE;
- result = fx80_inan;
- }
- else
- {
- result = x87_div( a, b);
- }
- }
-
- if (x87_check_exceptions())
- x87_write_stack( 0, result, TRUE);
-
- // 73, 62, 35
- CYCLES( 73);
-}
-
-void I386_OPS_BASE::x87_fdiv_m64real( UINT8 modrm)
-{
- floatx80 result;
-
- UINT32 ea = GetEA( modrm, 0);
- if (X87_IS_ST_EMPTY(0))
- {
- x87_set_stack_underflow();
- result = fx80_inan;
- }
- else
- {
- UINT64 m64real = READ64( ea);
-
- floatx80 a = ST(0);
- floatx80 b = float64_to_floatx80(m64real);
-
- if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
- {
- cpustate->x87_sw |= X87_SW_IE;
- result = fx80_inan;
- }
- else
- {
- result = x87_div( a, b);
- }
- }
-
- if (x87_check_exceptions())
- x87_write_stack( 0, result, TRUE);
-
- // 73, 62, 35
- CYCLES( 73);
-}
-
-void I386_OPS_BASE::x87_fdiv_st_sti( UINT8 modrm)
-{
- int i = modrm & 7;
- floatx80 result;
-
- if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
- {
- x87_set_stack_underflow();
- result = fx80_inan;
- }
- else
- {
- floatx80 a = ST(0);
- floatx80 b = ST(i);
-
- if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
- {
- cpustate->x87_sw |= X87_SW_IE;
- result = fx80_inan;
- }
- else
- {
- result = x87_div( a, b);
- }
- }
-
- if (x87_check_exceptions())
- {
- x87_write_stack( 0, result, TRUE);
- }
-
- // 73, 62, 35
- CYCLES( 73);
-}
-
-void I386_OPS_BASE::I386_OPS_BASE::fx87_fdiv_sti_st( UINT8 modrm)
-{
- int i = modrm & 7;
- floatx80 result;
-
- if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
- {
- x87_set_stack_underflow();
- result = fx80_inan;
- }
- else
- {
- floatx80 a = ST(i);
- floatx80 b = ST(0);
-
- if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
- {
- cpustate->x87_sw |= X87_SW_IE;
- result = fx80_inan;
- }
- else
- {
- result = x87_div( a, b);
- }
- }
-
- if (x87_check_exceptions())
- {
- x87_write_stack( i, result, TRUE);
- }
-
- // 73, 62, 35
- CYCLES( 73);
-}
-
-void I386_OPS_BASE::x87_fdivp( UINT8 modrm)
-{
- int i = modrm & 7;
- floatx80 result;
-
- if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
- {
- x87_set_stack_underflow();
- result = fx80_inan;
- }
- else
- {
- floatx80 a = ST(i);
- floatx80 b = ST(0);
-
- if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
- {
- cpustate->x87_sw |= X87_SW_IE;
- result = fx80_inan;
- }
- else
- {
- result = x87_div( a, b);
- }
- }
-
- if (x87_check_exceptions())
- {
- x87_write_stack( i, result, TRUE);
- x87_inc_stack();
- }
-
- // 73, 62, 35
- CYCLES( 73);
-}
-
-void I386_OPS_BASE::x87_fidiv_m32int( UINT8 modrm)
-{
- floatx80 result;
-
- UINT32 ea = GetEA( modrm, 0);
- if (X87_IS_ST_EMPTY(0))
- {
- x87_set_stack_underflow();
- result = fx80_inan;
- }
- else
- {
- INT32 m32int = READ32( ea);
-
- floatx80 a = ST(0);
- floatx80 b = int32_to_floatx80(m32int);
-
- if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
- {
- cpustate->x87_sw |= X87_SW_IE;
- result = fx80_inan;
- }
- else
- {
- result = x87_div( a, b);
- }
- }
-
- if (x87_check_exceptions())
- x87_write_stack( 0, result, TRUE);
-
- // 73, 62, 35
- CYCLES( 73);
-}
-
-void I386_OPS_BASE::x87_fidiv_m16int( UINT8 modrm)
-{
- floatx80 result;
-
- UINT32 ea = GetEA( modrm, 0);
- if (X87_IS_ST_EMPTY(0))
- {
- x87_set_stack_underflow();
- result = fx80_inan;
- }
- else
- {
- INT16 m16int = READ32( ea);
-
- floatx80 a = ST(0);
- floatx80 b = int32_to_floatx80(m16int);
-
- if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
- {
- cpustate->x87_sw |= X87_SW_IE;
- result = fx80_inan;
- }
- else
- {
- result = x87_div( a, b);
- }
- }
-
- if (x87_check_exceptions())
- x87_write_stack( 0, result, TRUE);
-
- // 73, 62, 35
- CYCLES( 73);
-}
-
-
-/*************************************
- *
- * Reverse Divide
- *
- *************************************/
-
-void I386_OPS_BASE::x87_fdivr_m32real( UINT8 modrm)
-{
- floatx80 result;
-
- UINT32 ea = GetEA( modrm, 0);
- if (X87_IS_ST_EMPTY(0))
- {
- x87_set_stack_underflow();
- result = fx80_inan;
- }
- else
- {
- UINT32 m32real = READ32( ea);
-
- floatx80 a = float32_to_floatx80(m32real);
- floatx80 b = ST(0);
-
- if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
- {
- cpustate->x87_sw |= X87_SW_IE;
- result = fx80_inan;
- }
- else
- {
- result = x87_div( a, b);
- }
- }
-
- if (x87_check_exceptions())
- x87_write_stack( 0, result, TRUE);
-
- // 73, 62, 35
- CYCLES( 73);
-}
-
-void I386_OPS_BASE::x87_fdivr_m64real( UINT8 modrm)
-{
- floatx80 result;
-
- UINT32 ea = GetEA( modrm, 0);
- if (X87_IS_ST_EMPTY(0))
- {
- x87_set_stack_underflow();
- result = fx80_inan;
- }
- else
- {
- UINT64 m64real = READ64( ea);
-
- floatx80 a = float64_to_floatx80(m64real);
- floatx80 b = ST(0);
-
- if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
- {
- cpustate->x87_sw |= X87_SW_IE;
- result = fx80_inan;
- }
- else
- {
- result = x87_div( a, b);
- }
- }
-
- if (x87_check_exceptions())
- x87_write_stack( 0, result, TRUE);
-
- // 73, 62, 35
- CYCLES( 73);
-}
-
-void I386_OPS_BASE::x87_fdivr_st_sti( UINT8 modrm)
-{
- int i = modrm & 7;
- floatx80 result;
-
- if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
- {
- x87_set_stack_underflow();
- result = fx80_inan;
- }
- else
- {
- floatx80 a = ST(i);
- floatx80 b = ST(0);
-
- if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
- {
- cpustate->x87_sw |= X87_SW_IE;
- result = fx80_inan;
- }
- else
- {
- result = x87_div( a, b);
- }
- }
-
- if (x87_check_exceptions())
- {
- x87_write_stack( 0, result, TRUE);
- }
-
- // 73, 62, 35
- CYCLES( 73);
-}
-
-void I386_OPS_BASE::x87_fdivr_sti_st( UINT8 modrm)
-{
- int i = modrm & 7;
- floatx80 result;
-
- if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
- {
- x87_set_stack_underflow();
- result = fx80_inan;
- }
- else
- {
- floatx80 a = ST(0);
- floatx80 b = ST(i);
-
- if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
- {
- cpustate->x87_sw |= X87_SW_IE;
- result = fx80_inan;
- }
- else
- {
- result = x87_div( a, b);
- }
- }
-
- if (x87_check_exceptions())
- {
- x87_write_stack( i, result, TRUE);
- }
-
- // 73, 62, 35
- CYCLES( 73);
-}
-
-void I386_OPS_BASE::x87_fdivrp( UINT8 modrm)
-{
- int i = modrm & 7;
- floatx80 result;
-
- if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
- {
- x87_set_stack_underflow();
- result = fx80_inan;
- }
- else
- {
- floatx80 a = ST(0);
- floatx80 b = ST(i);
-
- if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
- {
- cpustate->x87_sw |= X87_SW_IE;
- result = fx80_inan;
- }
- else
- {
- result = x87_div( a, b);
- }
- }
-
- if (x87_check_exceptions())
- {
- x87_write_stack( i, result, TRUE);
- x87_inc_stack();
- }
-
- // 73, 62, 35
- CYCLES( 73);
-}
-
-
-void I386_OPS_BASE::x87_fidivr_m32int( UINT8 modrm)
-{
- floatx80 result;
-
- UINT32 ea = GetEA( modrm, 0);
- if (X87_IS_ST_EMPTY(0))
- {
- x87_set_stack_underflow();
- result = fx80_inan;
- }
- else
- {
- INT32 m32int = READ32( ea);
-
- floatx80 a = int32_to_floatx80(m32int);
- floatx80 b = ST(0);
-
- if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
- {
- cpustate->x87_sw |= X87_SW_IE;
- result = fx80_inan;
- }
- else
- {
- result = x87_div( a, b);
- }
- }
-
- if (x87_check_exceptions())
- x87_write_stack( 0, result, TRUE);
-
- // 73, 62, 35
- CYCLES( 73);
-}
-
-void I386_OPS_BASE::x87_fidivr_m16int( UINT8 modrm)
-{
- floatx80 result;
-
- UINT32 ea = GetEA( modrm, 0);
- if (X87_IS_ST_EMPTY(0))
- {
- x87_set_stack_underflow();
- result = fx80_inan;
- }
- else
- {
- INT16 m16int = READ32( ea);
-
- floatx80 a = int32_to_floatx80(m16int);
- floatx80 b = ST(0);
-
- if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
- {
- cpustate->x87_sw |= X87_SW_IE;
- result = fx80_inan;
- }
- else
- {
- result = x87_div( a, b);
- }
- }
-
- if (x87_check_exceptions())
- x87_write_stack( 0, result, TRUE);
-
- // 73, 62, 35
- CYCLES( 73);
-}
-
-
-/*************************************
- *
- * Multiply
- *
- *************************************/
-
-void I386_OPS_BASE::x87_fmul_m32real( UINT8 modrm)
-{
- floatx80 result;
-
- UINT32 ea = GetEA( modrm, 0);
- if (X87_IS_ST_EMPTY(0))
- {
- x87_set_stack_underflow();
- result = fx80_inan;
- }
- else
- {
- UINT32 m32real = READ32( ea);
-
- floatx80 a = ST(0);
- floatx80 b = float32_to_floatx80(m32real);
-
- if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
- {
- cpustate->x87_sw |= X87_SW_IE;
- result = fx80_inan;
- }
- else
- {
- result = x87_mul( a, b);
- }
- }
-
- if (x87_check_exceptions())
- x87_write_stack( 0, result, TRUE);
-
- CYCLES( 11);
-}
-
-void I386_OPS_BASE::x87_fmul_m64real( UINT8 modrm)
-{
- floatx80 result;
-
- UINT32 ea = GetEA( modrm, 0);
- if (X87_IS_ST_EMPTY(0))
- {
- x87_set_stack_underflow();
- result = fx80_inan;
- }
- else
- {
- UINT64 m64real = READ64( ea);
-
- floatx80 a = ST(0);
- floatx80 b = float64_to_floatx80(m64real);
-
- if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
- {
- cpustate->x87_sw |= X87_SW_IE;
- result = fx80_inan;
- }
- else
- {
- result = x87_mul( a, b);
- }
- }
-
- if (x87_check_exceptions())
- x87_write_stack( 0, result, TRUE);
-
- CYCLES( 14);
-}
-
-void I386_OPS_BASE::x87_fmul_st_sti( UINT8 modrm)
-{
- floatx80 result;
- int i = modrm & 7;
-
- if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
- {
- x87_set_stack_underflow();
- result = fx80_inan;
- }
- else
- {
- floatx80 a = ST(0);
- floatx80 b = ST(i);
-
- if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
- {
- cpustate->x87_sw |= X87_SW_IE;
- result = fx80_inan;
- }
- else
- {
- result = x87_mul( a, b);
- }
- }
-
- if (x87_check_exceptions())
- x87_write_stack( 0, result, TRUE);
-
- CYCLES( 16);
-}
-
-void I386_OPS_BASE::x87_fmul_sti_st( UINT8 modrm)
-{
- floatx80 result;
- int i = modrm & 7;
-
- if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
- {
- x87_set_stack_underflow();
- result = fx80_inan;
- }
- else
- {
- floatx80 a = ST(0);
- floatx80 b = ST(i);
-
- if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
- {
- cpustate->x87_sw |= X87_SW_IE;
- result = fx80_inan;
- }
- else
- {
- result = x87_mul( a, b);
- }
- }
-
- if (x87_check_exceptions())
- x87_write_stack( i, result, TRUE);
-
- CYCLES( 16);
-}
-
-void I386_OPS_BASE::x87_fmulp( UINT8 modrm)
-{
- floatx80 result;
- int i = modrm & 7;
-
- if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
- {
- x87_set_stack_underflow();
- result = fx80_inan;
- }
- else
- {
- floatx80 a = ST(0);
- floatx80 b = ST(i);
-
- if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
- {
- cpustate->x87_sw |= X87_SW_IE;
- result = fx80_inan;
- }
- else
- {
- result = x87_mul( a, b);
- }
- }
-
- if (x87_check_exceptions())
- {
- x87_write_stack( i, result, TRUE);
- x87_inc_stack();
- }
-
- CYCLES( 16);
-}
-
-void I386_OPS_BASE::x87_fimul_m32int( UINT8 modrm)
-{
- floatx80 result;
-
- UINT32 ea = GetEA( modrm, 0);
- if (X87_IS_ST_EMPTY(0))
- {
- x87_set_stack_underflow();
- result = fx80_inan;
- }
- else
- {
- INT32 m32int = READ32( ea);
-
- floatx80 a = ST(0);
- floatx80 b = int32_to_floatx80(m32int);
-
- if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
- {
- cpustate->x87_sw |= X87_SW_IE;
- result = fx80_inan;
- }
- else
- {
- result = x87_mul( a, b);
- }
- }
-
- if (x87_check_exceptions())
- x87_write_stack( 0, result, TRUE);
-
- CYCLES( 22);
-}
-
-void I386_OPS_BASE::x87_fimul_m16int( UINT8 modrm)
-{
- floatx80 result;
-
- UINT32 ea = GetEA( modrm, 0);
- if (X87_IS_ST_EMPTY(0))
- {
- x87_set_stack_underflow();
- result = fx80_inan;
- }
- else
- {
- INT16 m16int = READ16( ea);
-
- floatx80 a = ST(0);
- floatx80 b = int32_to_floatx80(m16int);
-
- if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
- {
- cpustate->x87_sw |= X87_SW_IE;
- result = fx80_inan;
- }
- else
- {
- result = x87_mul( a, b);
- }
- }
-
- if (x87_check_exceptions())
- x87_write_stack( 0, result, TRUE);
-
- CYCLES( 22);
-}
-
-
-/*************************************
-*
-* Conditional Move
-*
-*************************************/
-
-void I386_OPS_BASE::x87_fcmovb_sti( UINT8 modrm)
-{
- floatx80 result;
- int i = modrm & 7;
-
- if (cpustate->CF == 1)
- {
- if (X87_IS_ST_EMPTY(i))
- {
- x87_set_stack_underflow();
- result = fx80_inan;
- }
- else
- result = ST(i);
-
- if (x87_check_exceptions())
- {
- ST(0) = result;
- }
- }
-
- CYCLES( 4);
-}
-
-void I386_OPS_BASE::x87_fcmove_sti( UINT8 modrm)
-{
- floatx80 result;
- int i = modrm & 7;
-
- if (cpustate->ZF == 1)
- {
- if (X87_IS_ST_EMPTY(i))
- {
- x87_set_stack_underflow();
- result = fx80_inan;
- }
- else
- result = ST(i);
-
- if (x87_check_exceptions())
- {
- ST(0) = result;
- }
- }
-
- CYCLES( 4);
-}
-
-void I386_OPS_BASE::x87_fcmovbe_sti( UINT8 modrm)
-{
- floatx80 result;
- int i = modrm & 7;
-
- if ((cpustate->CF | cpustate->ZF) == 1)
- {
- if (X87_IS_ST_EMPTY(i))
- {
- x87_set_stack_underflow();
- result = fx80_inan;
- }
- else
- result = ST(i);
-
- if (x87_check_exceptions())
- {
- ST(0) = result;
- }
- }
-
- CYCLES( 4);
-}
-
-void I386_OPS_BASE::x87_fcmovu_sti( UINT8 modrm)
-{
- floatx80 result;
- int i = modrm & 7;
-
- if (cpustate->PF == 1)
- {
- if (X87_IS_ST_EMPTY(i))
- {
- x87_set_stack_underflow();
- result = fx80_inan;
- }
- else
- result = ST(i);
-
- if (x87_check_exceptions())
- {
- ST(0) = result;
- }
- }
-
- CYCLES( 4);
-}
-
-void I386_OPS_BASE::x87_fcmovnb_sti( UINT8 modrm)
-{
- floatx80 result;
- int i = modrm & 7;
-
- if (cpustate->CF == 0)
- {
- if (X87_IS_ST_EMPTY(i))
- {
- x87_set_stack_underflow();
- result = fx80_inan;
- }
- else
- result = ST(i);
-
- if (x87_check_exceptions())
- {
- ST(0) = result;
- }
- }
-
- CYCLES( 4);
-}
-
-void I386_OPS_BASE::x87_fcmovne_sti( UINT8 modrm)
-{
- floatx80 result;
- int i = modrm & 7;
-
- if (cpustate->ZF == 0)
- {
- if (X87_IS_ST_EMPTY(i))
- {
- x87_set_stack_underflow();
- result = fx80_inan;
- }
- else
- result = ST(i);
-
- if (x87_check_exceptions())
- {
- ST(0) = result;
- }
- }
-
- CYCLES( 4);
-}
-
-void I386_OPS_BASE::x87_fcmovnbe_sti( UINT8 modrm)
-{
- floatx80 result;
- int i = modrm & 7;
-
- if ((cpustate->CF == 0) && (cpustate->ZF == 0))
- {
- if (X87_IS_ST_EMPTY(i))
- {
- x87_set_stack_underflow();
- result = fx80_inan;
- }
- else
- result = ST(i);
-
- if (x87_check_exceptions())
- {
- ST(0) = result;
- }
- }
-
- CYCLES( 4);
-}
-
-void I386_OPS_BASE::x87_fcmovnu_sti( UINT8 modrm)
-{
- floatx80 result;
- int i = modrm & 7;
-
- if (cpustate->PF == 0)
- {
- if (X87_IS_ST_EMPTY(i))
- {
- x87_set_stack_underflow();
- result = fx80_inan;
- }
- else
- result = ST(i);
-
- if (x87_check_exceptions())
- {
- ST(0) = result;
- }
- }
-
- CYCLES( 4);
-}
-
-/*************************************
- *
- * Miscellaneous arithmetic
- *
- *************************************/
-
-void I386_OPS_BASE::x87_fprem( UINT8 modrm)
-{
- floatx80 result;
-
- if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(1))
- {
- x87_set_stack_underflow();
- result = fx80_inan;
- }
- else
- {
- floatx80 a0 = ST(0);
- floatx80 b1 = ST(1);
-
- cpustate->x87_sw &= ~X87_SW_C2;
-
- //int d=extractFloatx80Exp(a0)-extractFloatx80Exp(b1);
- int d = (a0.high & 0x7FFF) - (b1.high & 0x7FFF);
- if (d < 64) {
- floatx80 t=floatx80_div(a0, b1);
- int64 q = floatx80_to_int64_round_to_zero(t);
- floatx80 qf = int64_to_floatx80(q);
- floatx80 tt = floatx80_mul(b1, qf);
- result = floatx80_sub(a0, tt);
- // C2 already 0
- cpustate->x87_sw &= ~(X87_SW_C0|X87_SW_C3|X87_SW_C1);
- if (q & 1)
- cpustate->x87_sw |= X87_SW_C1;
- if (q & 2)
- cpustate->x87_sw |= X87_SW_C3;
- if (q & 4)
- cpustate->x87_sw |= X87_SW_C0;
- }
- else {
- cpustate->x87_sw |= X87_SW_C2;
- int n = 63;
- int e = 1 << (d - n);
- floatx80 ef = int32_to_floatx80(e);
- floatx80 t=floatx80_div(a0, b1);
- floatx80 td = floatx80_div(t, ef);
- int64 qq = floatx80_to_int64_round_to_zero(td);
- floatx80 qqf = int64_to_floatx80(qq);
- floatx80 tt = floatx80_mul(b1, qqf);
- floatx80 ttt = floatx80_mul(tt, ef);
- result = floatx80_sub(a0, ttt);
- }
- }
-
- if (x87_check_exceptions())
- x87_write_stack( 0, result, TRUE);
-
- CYCLES( 84);
-}
-
-void I386_OPS_BASE::x87_fprem1( UINT8 modrm)
-{
- floatx80 result;
-
- if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(1))
- {
- x87_set_stack_underflow();
- result = fx80_inan;
- }
- else
- {
- floatx80 a = ST(0);
- floatx80 b = ST(1);
-
- cpustate->x87_sw &= ~X87_SW_C2;
-
- // TODO: Implement Cx bits
- result = floatx80_rem(a, b);
- }
-
- if (x87_check_exceptions())
- x87_write_stack( 0, result, TRUE);
-
- CYCLES( 94);
-}
-
-void I386_OPS_BASE::x87_fsqrt( UINT8 modrm)
-{
- floatx80 result;
-
- if (X87_IS_ST_EMPTY(0))
- {
- x87_set_stack_underflow();
- result = fx80_inan;
- }
- else
- {
- floatx80 value = ST(0);
-
- if ((!floatx80_is_zero(value) && (value.high & 0x8000)) ||
- floatx80_is_denormal(value))
- {
- cpustate->x87_sw |= X87_SW_IE;
- result = fx80_inan;
- }
- else
- {
- result = floatx80_sqrt(value);
- }
- }
-
- if (x87_check_exceptions())
- x87_write_stack( 0, result, TRUE);
-
- CYCLES( 8);
-}
-
-/*************************************
- *
- * Trigonometric
- *
- *************************************/
-
-void I386_OPS_BASE::x87_f2xm1( UINT8 modrm)
-{
- floatx80 result;
-
- if (X87_IS_ST_EMPTY(0))
- {
- x87_set_stack_underflow();
- result = fx80_inan;
- }
- else
- {
- // TODO: Inaccurate
- double x = fx80_to_double(ST(0));
- double res = pow(2.0, x) - 1;
- result = double_to_fx80(res);
- }
-
- if (x87_check_exceptions())
- {
- x87_write_stack( 0, result, TRUE);
- }
-
- CYCLES( 242);
-}
-
-void I386_OPS_BASE::x87_fyl2x( UINT8 modrm)
-{
- floatx80 result;
-
- if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(1))
- {
- x87_set_stack_underflow();
- result = fx80_inan;
- }
- else
- {
- floatx80 x = ST(0);
- floatx80 y = ST(1);
-
- if (x.high & 0x8000)
- {
- cpustate->x87_sw |= X87_SW_IE;
- result = fx80_inan;
- }
- else
- {
- // TODO: Inaccurate
- double d64 = fx80_to_double(x);
- double l2x = log(d64)/log(2.0);
- result = floatx80_mul(double_to_fx80(l2x), y);
- }
- }
-
- if (x87_check_exceptions())
- {
- x87_write_stack( 1, result, TRUE);
- x87_inc_stack();
- }
-
- CYCLES( 250);
-}
-
-void I386_OPS_BASE::x87_fyl2xp1( UINT8 modrm)
-{
- floatx80 result;
-
- if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(1))
- {
- x87_set_stack_underflow();
- result = fx80_inan;
- }
- else
- {
- floatx80 x = ST(0);
- floatx80 y = ST(1);
-
- // TODO: Inaccurate
- double d64 = fx80_to_double(x);
- double l2x1 = log(d64 + 1.0)/log(2.0);
- result = floatx80_mul(double_to_fx80(l2x1), y);
- }
-
- if (x87_check_exceptions())
- {
- x87_write_stack( 1, result, TRUE);
- x87_inc_stack();
- }
-
- CYCLES( 313);
-}
-
-void I386_OPS_BASE::x87_fptan( UINT8 modrm)
-{
- floatx80 result1, result2;
-
- if (X87_IS_ST_EMPTY(0))
- {
- x87_set_stack_underflow();
- result1 = fx80_inan;
- result2 = fx80_inan;
- }
- else if (!X87_IS_ST_EMPTY(7))
- {
- x87_set_stack_overflow();
- result1 = fx80_inan;
- result2 = fx80_inan;
- }
- else
- {
- result1 = ST(0);
- result2 = fx80_one;
-
-#if 0 // TODO: Function produces bad values
- if (floatx80_ftan(result1) != -1)
- cpustate->x87_sw &= ~X87_SW_C2;
- else
- cpustate->x87_sw |= X87_SW_C2;
-#else
- double x = fx80_to_double(result1);
- x = tan(x);
- result1 = double_to_fx80(x);
-
- cpustate->x87_sw &= ~X87_SW_C2;
-#endif
- }
-
- if (x87_check_exceptions())
- {
- x87_write_stack( 0, result1, TRUE);
- x87_dec_stack();
- x87_write_stack( 0, result2, TRUE);
- }
-
- CYCLES( 244);
-}
-
-void I386_OPS_BASE::x87_fpatan( UINT8 modrm)
-{
- floatx80 result;
-
- if (X87_IS_ST_EMPTY(0))
- {
- x87_set_stack_underflow();
- result = fx80_inan;
- }
- else
- {
- // TODO: Inaccurate
- double val = atan2(fx80_to_double(ST(1)) , fx80_to_double(ST(0)));
- result = double_to_fx80(val);
- }
-
- if (x87_check_exceptions())
- {
- x87_write_stack( 1, result, TRUE);
- x87_inc_stack();
- }
-
- CYCLES( 289);
-}
-
-void I386_OPS_BASE::x87_fsin( UINT8 modrm)
-{
- floatx80 result;
-
- if (X87_IS_ST_EMPTY(0))
- {
- x87_set_stack_underflow();
- result = fx80_inan;
- }
- else
- {
- result = ST(0);
-
-#if 0 // TODO: Function produces bad values
- if (floatx80_fsin(result) != -1)
- cpustate->x87_sw &= ~X87_SW_C2;
- else
- cpustate->x87_sw |= X87_SW_C2;
-#else
- double x = fx80_to_double(result);
- x = sin(x);
- result = double_to_fx80(x);
-
- cpustate->x87_sw &= ~X87_SW_C2;
-#endif
- }
-
- if (x87_check_exceptions())
- x87_write_stack( 0, result, TRUE);
-
- CYCLES( 241);
-}
-
-void I386_OPS_BASE::x87_fcos( UINT8 modrm)
-{
- floatx80 result;
-
- if (X87_IS_ST_EMPTY(0))
- {
- x87_set_stack_underflow();
- result = fx80_inan;
- }
- else
- {
- result = ST(0);
-
-#if 0 // TODO: Function produces bad values
- if (floatx80_fcos(result) != -1)
- cpustate->x87_sw &= ~X87_SW_C2;
- else
- cpustate->x87_sw |= X87_SW_C2;
-#else
- double x = fx80_to_double(result);
- x = cos(x);
- result = double_to_fx80(x);
-
- cpustate->x87_sw &= ~X87_SW_C2;
-#endif
- }
-
- if (x87_check_exceptions())
- x87_write_stack( 0, result, TRUE);
-
- CYCLES( 241);
-}
-
-void I386_OPS_BASE::x87_fsincos( UINT8 modrm)
-{
- floatx80 s_result, c_result;
-
- if (X87_IS_ST_EMPTY(0))
- {
- x87_set_stack_underflow();
- s_result = c_result = fx80_inan;
- }
- else if (!X87_IS_ST_EMPTY(7))
- {
- x87_set_stack_overflow();
- s_result = c_result = fx80_inan;
- }
- else
- {
- extern int sf_fsincos(floatx80 a, floatx80 *sin_a, floatx80 *cos_a);
-
- s_result = c_result = ST(0);
-
-#if 0 // TODO: Function produces bad values
- if (sf_fsincos(s_result, &s_result, &c_result) != -1)
- cpustate->x87_sw &= ~X87_SW_C2;
- else
- cpustate->x87_sw |= X87_SW_C2;
-#else
- double s = fx80_to_double(s_result);
- double c = fx80_to_double(c_result);
- s = sin(s);
- c = cos(c);
-
- s_result = double_to_fx80(s);
- c_result = double_to_fx80(c);
-
- cpustate->x87_sw &= ~X87_SW_C2;
-#endif
- }
-
- if (x87_check_exceptions())
- {
- x87_write_stack( 0, s_result, TRUE);
- x87_dec_stack();
- x87_write_stack( 0, c_result, TRUE);
- }
-
- CYCLES( 291);
-}
-
-
-/*************************************
- *
- * Load data
- *
- *************************************/
-
-void I386_OPS_BASE::x87_fld_m32real( UINT8 modrm)
-{
- floatx80 value;
-
- UINT32 ea = GetEA( modrm, 0);
- if (x87_dec_stack())
- {
- UINT32 m32real = READ32( ea);
-
- value = float32_to_floatx80(m32real);
-
- cpustate->x87_sw &= ~X87_SW_C1;
-
- if (floatx80_is_signaling_nan(value) || floatx80_is_denormal(value))
- {
- cpustate->x87_sw |= X87_SW_IE;
- value = fx80_inan;
- }
- }
- else
- {
- value = fx80_inan;
- }
-
- if (x87_check_exceptions())
- x87_write_stack( 0, value, TRUE);
-
- CYCLES( 3);
-}
-
-void I386_OPS_BASE::x87_fld_m64real( UINT8 modrm)
-{
- floatx80 value;
-
- UINT32 ea = GetEA( modrm, 0);
- if (x87_dec_stack())
- {
- UINT64 m64real = READ64( ea);
-
- value = float64_to_floatx80(m64real);
-
- cpustate->x87_sw &= ~X87_SW_C1;
-
- if (floatx80_is_signaling_nan(value) || floatx80_is_denormal(value))
- {
- cpustate->x87_sw |= X87_SW_IE;
- value = fx80_inan;
- }
- }
- else
- {
- value = fx80_inan;
- }
-
- if (x87_check_exceptions())
- x87_write_stack( 0, value, TRUE);
-
- CYCLES( 3);
-}
-
-void I386_OPS_BASE::x87_fld_m80real( UINT8 modrm)
-{
- floatx80 value;
-
- UINT32 ea = GetEA( modrm, 0);
- if (x87_dec_stack())
- {
- cpustate->x87_sw &= ~X87_SW_C1;
- value = READ80( ea);
- }
- else
- {
- value = fx80_inan;
- }
-
- if (x87_check_exceptions())
- x87_write_stack( 0, value, TRUE);
-
- CYCLES( 6);
-}
-
-void I386_OPS_BASE::x87_fld_sti( UINT8 modrm)
-{
- floatx80 value;
-
- if (x87_dec_stack())
- {
- cpustate->x87_sw &= ~X87_SW_C1;
- value = ST((modrm + 1) & 7);
- }
- else
- {
- value = fx80_inan;
- }
-
- if (x87_check_exceptions())
- x87_write_stack( 0, value, TRUE);
-
- CYCLES( 4);
-}
-
-void I386_OPS_BASE::x87_fild_m16int( UINT8 modrm)
-{
- floatx80 value;
-
- UINT32 ea = GetEA( modrm, 0);
- if (!x87_dec_stack())
- {
- value = fx80_inan;
- }
- else
- {
- cpustate->x87_sw &= ~X87_SW_C1;
-
- INT16 m16int = READ16( ea);
- value = int32_to_floatx80(m16int);
- }
-
- if (x87_check_exceptions())
- x87_write_stack( 0, value, TRUE);
-
- CYCLES( 13);
-}
-
-void I386_OPS_BASE::x87_fild_m32int( UINT8 modrm)
-{
- floatx80 value;
-
- UINT32 ea = GetEA( modrm, 0);
- if (!x87_dec_stack())
- {
- value = fx80_inan;
- }
- else
- {
- cpustate->x87_sw &= ~X87_SW_C1;
-
- INT32 m32int = READ32( ea);
- value = int32_to_floatx80(m32int);
- }
-
- if (x87_check_exceptions())
- x87_write_stack( 0, value, TRUE);
-
- CYCLES( 9);
-}
-
-void I386_OPS_BASE::x87_fild_m64int( UINT8 modrm)
-{
- floatx80 value;
-
- UINT32 ea = GetEA( modrm, 0);
- if (!x87_dec_stack())
- {
- value = fx80_inan;
- }
- else
- {
- cpustate->x87_sw &= ~X87_SW_C1;
-
- INT64 m64int = READ64( ea);
- value = int64_to_floatx80(m64int);
- }
-
- if (x87_check_exceptions())
- x87_write_stack( 0, value, TRUE);
-
- CYCLES( 10);
-}
-
-void I386_OPS_BASE::x87_fbld( UINT8 modrm)
-{
- floatx80 value;
-
- UINT32 ea = GetEA( modrm, 0);
- if (!x87_dec_stack())
- {
- value = fx80_inan;
- }
- else
- {
- cpustate->x87_sw &= ~X87_SW_C1;
-
- UINT64 m64val = 0;
- UINT16 sign;
-
- value = READ80( ea);
-
- sign = value.high & 0x8000;
- m64val += ((value.high >> 4) & 0xf) * 10;
- m64val += ((value.high >> 0) & 0xf);
-
- for (int i = 60; i >= 0; i -= 4)
- {
- m64val *= 10;
- m64val += (value.low >> i) & 0xf;
- }
-
- value = int64_to_floatx80(m64val);
- value.high |= sign;
- }
-
- if (x87_check_exceptions())
- x87_write_stack( 0, value, TRUE);
-
- CYCLES( 75);
-}
-
-
-/*************************************
- *
- * Store data
- *
- *************************************/
-
-void I386_OPS_BASE::x87_fst_m32real( UINT8 modrm)
-{
- floatx80 value;
-
- UINT32 ea = GetEA( modrm, 1);
- if (X87_IS_ST_EMPTY(0))
- {
- x87_set_stack_underflow();
- value = fx80_inan;
- }
- else
- {
- cpustate->x87_sw &= ~X87_SW_C1;
- value = ST(0);
- }
-
- if (x87_check_exceptions())
- {
- UINT32 m32real = floatx80_to_float32(value);
- WRITE32( ea, m32real);
- }
-
- CYCLES( 7);
-}
-
-void I386_OPS_BASE::x87_fst_m64real( UINT8 modrm)
-{
- floatx80 value;
-
- UINT32 ea = GetEA( modrm, 1);
- if (X87_IS_ST_EMPTY(0))
- {
- x87_set_stack_underflow();
- value = fx80_inan;
- }
- else
- {
- cpustate->x87_sw &= ~X87_SW_C1;
- value = ST(0);
- }
-
- if (x87_check_exceptions())
- {
- UINT64 m64real = floatx80_to_float64(value);
- WRITE64( ea, m64real);
- }
-
- CYCLES( 8);
-}
-
-void I386_OPS_BASE::x87_fst_sti( UINT8 modrm)
-{
- int i = modrm & 7;
- floatx80 value;
-
- if (X87_IS_ST_EMPTY(0))
- {
- x87_set_stack_underflow();
- value = fx80_inan;
- }
- else
- {
- cpustate->x87_sw &= ~X87_SW_C1;
- value = ST(0);
- }
-
- if (x87_check_exceptions())
- x87_write_stack( i, value, TRUE);
-
- CYCLES( 3);
-}
-
-void I386_OPS_BASE::x87_fstp_m32real( UINT8 modrm)
-{
- floatx80 value;
-
- UINT32 ea = GetEA( modrm, 1);
- if (X87_IS_ST_EMPTY(0))
- {
- x87_set_stack_underflow();
- value = fx80_inan;
- }
- else
- {
- cpustate->x87_sw &= ~X87_SW_C1;
- value = ST(0);
- }
-
- if (x87_check_exceptions())
- {
- UINT32 m32real = floatx80_to_float32(value);
- WRITE32( ea, m32real);
- x87_inc_stack();
- }
-
- CYCLES( 7);
-}
-
-void I386_OPS_BASE::x87_fstp_m64real( UINT8 modrm)
-{
- floatx80 value;
-
- if (X87_IS_ST_EMPTY(0))
- {
- x87_set_stack_underflow();
- value = fx80_inan;
- }
- else
- {
- cpustate->x87_sw &= ~X87_SW_C1;
- value = ST(0);
- }
-
-
- UINT32 ea = GetEA( modrm, 1);
- if (x87_check_exceptions())
- {
- UINT64 m64real = floatx80_to_float64(value);
- WRITE64( ea, m64real);
- x87_inc_stack();
- }
-
- CYCLES( 8);
-}
-
-void I386_OPS_BASE::x87_fstp_m80real( UINT8 modrm)
-{
- floatx80 value;
-
- if (X87_IS_ST_EMPTY(0))
- {
- x87_set_stack_underflow();
- value = fx80_inan;
- }
- else
- {
- cpustate->x87_sw &= ~X87_SW_C1;
- value = ST(0);
- }
-
- UINT32 ea = GetEA( modrm, 1);
- if (x87_check_exceptions())
- {
- WRITE80( ea, value);
- x87_inc_stack();
- }
-
- CYCLES( 6);
-}
-
-void I386_OPS_BASE::x87_fstp_sti( UINT8 modrm)
-{
- int i = modrm & 7;
- floatx80 value;
-
- if (X87_IS_ST_EMPTY(0))
- {
- x87_set_stack_underflow();
- value = fx80_inan;
- }
- else
- {
- cpustate->x87_sw &= ~X87_SW_C1;
- value = ST(0);
- }
-
- if (x87_check_exceptions())
- {
- x87_write_stack( i, value, TRUE);
- x87_inc_stack();
- }
-
- CYCLES( 3);
-}
-
-void I386_OPS_BASE::x87_fist_m16int( UINT8 modrm)
-{
- INT16 m16int;
-
- if (X87_IS_ST_EMPTY(0))
- {
- x87_set_stack_underflow();
- m16int = -32768;
- }
- else
- {
- floatx80 fx80 = floatx80_round_to_int(ST(0));
-
- floatx80 lowerLim = int32_to_floatx80(-32768);
- floatx80 upperLim = int32_to_floatx80(32767);
-
- cpustate->x87_sw &= ~X87_SW_C1;
-
- if (!floatx80_lt(fx80, lowerLim) && floatx80_le(fx80, upperLim))
- m16int = floatx80_to_int32(fx80);
- else
- m16int = -32768;
- }
-
- UINT32 ea = GetEA( modrm, 1);
- if (x87_check_exceptions())
- {
- WRITE16( ea, m16int);
- }
-
- CYCLES( 29);
-}
-
-void I386_OPS_BASE::x87_fist_m32int( UINT8 modrm)
-{
- INT32 m32int;
-
- if (X87_IS_ST_EMPTY(0))
- {
- x87_set_stack_underflow();
- m32int = 0x80000000;
- }
- else
- {
- floatx80 fx80 = floatx80_round_to_int(ST(0));
-
- floatx80 lowerLim = int32_to_floatx80(0x80000000);
- floatx80 upperLim = int32_to_floatx80(0x7fffffff);
-
- cpustate->x87_sw &= ~X87_SW_C1;
-
- if (!floatx80_lt(fx80, lowerLim) && floatx80_le(fx80, upperLim))
- m32int = floatx80_to_int32(fx80);
- else
- m32int = 0x80000000;
- }
-
- UINT32 ea = GetEA( modrm, 1);
- if (x87_check_exceptions())
- {
- WRITE32( ea, m32int);
- }
-
- CYCLES( 28);
-}
-
-void I386_OPS_BASE::x87_fistp_m16int( UINT8 modrm)
-{
- INT16 m16int;
-
- if (X87_IS_ST_EMPTY(0))
- {
- x87_set_stack_underflow();
- m16int = (UINT16)0x8000;
- }
- else
- {
- floatx80 fx80 = floatx80_round_to_int(ST(0));
-
- floatx80 lowerLim = int32_to_floatx80(-32768);
- floatx80 upperLim = int32_to_floatx80(32767);
-
- cpustate->x87_sw &= ~X87_SW_C1;
-
- if (!floatx80_lt(fx80, lowerLim) && floatx80_le(fx80, upperLim))
- m16int = floatx80_to_int32(fx80);
- else
- m16int = (UINT16)0x8000;
- }
-
- UINT32 ea = GetEA( modrm, 1);
- if (x87_check_exceptions())
- {
- WRITE16( ea, m16int);
- x87_inc_stack();
- }
-
- CYCLES( 29);
-}
-
-void I386_OPS_BASE::x87_fistp_m32int( UINT8 modrm)
-{
- INT32 m32int;
-
- if (X87_IS_ST_EMPTY(0))
- {
- x87_set_stack_underflow();
- m32int = 0x80000000;
- }
- else
- {
- floatx80 fx80 = floatx80_round_to_int(ST(0));
-
- floatx80 lowerLim = int32_to_floatx80(0x80000000);
- floatx80 upperLim = int32_to_floatx80(0x7fffffff);
-
- cpustate->x87_sw &= ~X87_SW_C1;
-
- if (!floatx80_lt(fx80, lowerLim) && floatx80_le(fx80, upperLim))
- m32int = floatx80_to_int32(fx80);
- else
- m32int = 0x80000000;
- }
-
- UINT32 ea = GetEA( modrm, 1);
- if (x87_check_exceptions())
- {
- WRITE32( ea, m32int);
- x87_inc_stack();
- }
-
- CYCLES( 29);
-}
-
-void I386_OPS_BASE::x87_fistp_m64int( UINT8 modrm)
-{
- INT64 m64int;
-
- if (X87_IS_ST_EMPTY(0))
- {
- x87_set_stack_underflow();
- m64int = U64(0x8000000000000000);
- }
- else
- {
- floatx80 fx80 = floatx80_round_to_int(ST(0));
-
- floatx80 lowerLim = int64_to_floatx80(U64(0x8000000000000000));
- floatx80 upperLim = int64_to_floatx80(U64(0x7fffffffffffffff));
-
- cpustate->x87_sw &= ~X87_SW_C1;
-
- if (!floatx80_lt(fx80, lowerLim) && floatx80_le(fx80, upperLim))
- m64int = floatx80_to_int64(fx80);
- else
- m64int = U64(0x8000000000000000);
- }
-
- UINT32 ea = GetEA( modrm, 1);
- if (x87_check_exceptions())
- {
- WRITE64( ea, m64int);
- x87_inc_stack();
- }
-
- CYCLES( 29);
-}
-
-void I386_OPS_BASE::x87_fbstp( UINT8 modrm)
-{
- floatx80 result;
-
- if (X87_IS_ST_EMPTY(0))
- {
- x87_set_stack_underflow();
- result = fx80_inan;
- }
- else
- {
- UINT64 u64 = floatx80_to_int64(floatx80_abs(ST(0)));
- result.low = 0;
-
- for (int i = 0; i < 64; i += 4)
- {
- result.low += (u64 % 10) << i;
- u64 /= 10;
- }
-
- result.high = (u64 % 10);
- result.high += ((u64 / 10) % 10) << 4;
- result.high |= ST(0).high & 0x8000;
- }
-
- UINT32 ea = GetEA( modrm, 1);
- if (x87_check_exceptions())
- {
- WRITE80( ea, result);
- x87_inc_stack();
- }
-
- CYCLES( 175);
-}
-
-
-/*************************************
- *
- * Constant load
- *
- *************************************/
-
-void I386_OPS_BASE::x87_fld1( UINT8 modrm)
-{
- floatx80 value;
- int tag;
-
- if (x87_dec_stack())
- {
- cpustate->x87_sw &= ~X87_SW_C1;
- value = fx80_one;
- tag = X87_TW_VALID;
- }
- else
- {
- value = fx80_inan;
- tag = X87_TW_SPECIAL;
- }
-
- if (x87_check_exceptions())
- {
- x87_set_tag( ST_TO_PHYS(0), tag);
- x87_write_stack( 0, value, FALSE);
- }
-
- CYCLES( 4);
-}
-
-void I386_OPS_BASE::x87_fldl2t( UINT8 modrm)
-{
- floatx80 value;
- int tag;
-
- if (x87_dec_stack())
- {
- tag = X87_TW_VALID;
- value.high = 0x4000;
-
- if (X87_RC == X87_CW_RC_UP)
- value.low = U64(0xd49a784bcd1b8aff);
- else
- value.low = U64(0xd49a784bcd1b8afe);
-
- cpustate->x87_sw &= ~X87_SW_C1;
- }
- else
- {
- value = fx80_inan;
- tag = X87_TW_SPECIAL;
- }
-
- if (x87_check_exceptions())
- {
- x87_set_tag( ST_TO_PHYS(0), tag);
- x87_write_stack( 0, value, FALSE);
- }
-
- CYCLES( 8);
-}
-
-void I386_OPS_BASE::x87_fldl2e( UINT8 modrm)
-{
- floatx80 value;
- int tag;
-
- if (x87_dec_stack())
- {
- int rc = X87_RC;
- tag = X87_TW_VALID;
- value.high = 0x3fff;
-
- if (rc == X87_CW_RC_UP || rc == X87_CW_RC_NEAREST)
- value.low = U64(0xb8aa3b295c17f0bc);
- else
- value.low = U64(0xb8aa3b295c17f0bb);
-
- cpustate->x87_sw &= ~X87_SW_C1;
- }
- else
- {
- value = fx80_inan;
- tag = X87_TW_SPECIAL;
- }
-
- if (x87_check_exceptions())
- {
- x87_set_tag( ST_TO_PHYS(0), tag);
- x87_write_stack( 0, value, FALSE);
- }
-
- CYCLES( 8);
-}
-
-void I386_OPS_BASE::x87_fldpi( UINT8 modrm)
-{
- floatx80 value;
- int tag;
-
- if (x87_dec_stack())
- {
- int rc = X87_RC;
- tag = X87_TW_VALID;
- value.high = 0x4000;
-
- if (rc == X87_CW_RC_UP || rc == X87_CW_RC_NEAREST)
- value.low = U64(0xc90fdaa22168c235);
- else
- value.low = U64(0xc90fdaa22168c234);
-
- cpustate->x87_sw &= ~X87_SW_C1;
- }
- else
- {
- value = fx80_inan;
- tag = X87_TW_SPECIAL;
- }
-
- if (x87_check_exceptions())
- {
- x87_set_tag( ST_TO_PHYS(0), tag);
- x87_write_stack( 0, value, FALSE);
- }
-
- CYCLES( 8);
-}
-
-void I386_OPS_BASE::x87_fldlg2( UINT8 modrm)
-{
- floatx80 value;
- int tag;
-
- if (x87_dec_stack())
- {
- int rc = X87_RC;
- tag = X87_TW_VALID;
- value.high = 0x3ffd;
-
- if (rc == X87_CW_RC_UP || rc == X87_CW_RC_NEAREST)
- value.low = U64(0x9a209a84fbcff799);
- else
- value.low = U64(0x9a209a84fbcff798);
-
- cpustate->x87_sw &= ~X87_SW_C1;
- }
- else
- {
- value = fx80_inan;
- tag = X87_TW_SPECIAL;
- }
-
- if (x87_check_exceptions())
- {
- x87_set_tag( ST_TO_PHYS(0), tag);
- x87_write_stack( 0, value, FALSE);
- }
-
- CYCLES( 8);
-}
-
-void I386_OPS_BASE::x87_fldln2( UINT8 modrm)
-{
- floatx80 value;
- int tag;
-
- if (x87_dec_stack())
- {
- int rc = X87_RC;
- tag = X87_TW_VALID;
- value.high = 0x3ffe;
-
- if (rc == X87_CW_RC_UP || rc == X87_CW_RC_NEAREST)
- value.low = U64(0xb17217f7d1cf79ac);
- else
- value.low = U64(0xb17217f7d1cf79ab);
-
- cpustate->x87_sw &= ~X87_SW_C1;
- }
- else
- {
- value = fx80_inan;
- tag = X87_TW_SPECIAL;
- }
-
- if (x87_check_exceptions())
- {
- x87_set_tag( ST_TO_PHYS(0), tag);
- x87_write_stack( 0, value, FALSE);
- }
-
- CYCLES( 8);
-}
-
-void I386_OPS_BASE::x87_fldz( UINT8 modrm)
-{
- floatx80 value;
- int tag;
-
- if (x87_dec_stack())
- {
- value = fx80_zero;
- tag = X87_TW_ZERO;
- cpustate->x87_sw &= ~X87_SW_C1;
- }
- else
- {
- value = fx80_inan;
- tag = X87_TW_SPECIAL;
- }
-
- if (x87_check_exceptions())
- {
- x87_set_tag( ST_TO_PHYS(0), tag);
- x87_write_stack( 0, value, FALSE);
- }
-
- CYCLES( 4);
-}
-
-
-/*************************************
- *
- * Miscellaneous
- *
- *************************************/
-
-void I386_OPS_BASE::x87_fnop( UINT8 modrm)
-{
- CYCLES( 3);
-}
-
-void I386_OPS_BASE::x87_fchs( UINT8 modrm)
-{
- floatx80 value;
-
- if (X87_IS_ST_EMPTY(0))
- {
- x87_set_stack_underflow();
- value = fx80_inan;
- }
- else
- {
- cpustate->x87_sw &= ~X87_SW_C1;
-
- value = ST(0);
- value.high ^= 0x8000;
- }
-
- if (x87_check_exceptions())
- x87_write_stack( 0, value, FALSE);
-
- CYCLES( 6);
-}
-
-void I386_OPS_BASE::x87_fabs( UINT8 modrm)
-{
- floatx80 value;
-
- if (X87_IS_ST_EMPTY(0))
- {
- x87_set_stack_underflow();
- value = fx80_inan;
- }
- else
- {
- cpustate->x87_sw &= ~X87_SW_C1;
-
- value = ST(0);
- value.high &= 0x7fff;
- }
-
- if (x87_check_exceptions())
- x87_write_stack( 0, value, FALSE);
-
- CYCLES( 6);
-}
-
-void I386_OPS_BASE::x87_fscale( UINT8 modrm)
-{
- floatx80 value;
-
- if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(1))
- {
- x87_set_stack_underflow();
- value = fx80_inan;
- }
- else
- {
- cpustate->x87_sw &= ~X87_SW_C1;
- value = ST(0);
-
- // Set the rounding mode to truncate
- UINT16 old_cw = cpustate->x87_cw;
- UINT16 new_cw = (old_cw & ~(X87_CW_RC_MASK << X87_CW_RC_SHIFT)) | (X87_CW_RC_ZERO << X87_CW_RC_SHIFT);
- x87_write_cw( new_cw);
-
- // Interpret ST(1) as an integer
- UINT32 st1 = floatx80_to_int32(floatx80_round_to_int(ST(1)));
-
- // Restore the rounding mode
- x87_write_cw( old_cw);
-
- // Get the unbiased exponent of ST(0)
- INT16 exp = (ST(0).high & 0x7fff) - 0x3fff;
-
- // Calculate the new exponent
- exp = (exp + st1 + 0x3fff) & 0x7fff;
-
- // Write it back
- value.high = (value.high & ~0x7fff) + exp;
- }
-
- if (x87_check_exceptions())
- x87_write_stack( 0, value, FALSE);
-
- CYCLES( 31);
-}
-
-void I386_OPS_BASE::x87_frndint( UINT8 modrm)
-{
- floatx80 value;
-
- if (X87_IS_ST_EMPTY(0))
- {
- x87_set_stack_underflow();
- value = fx80_inan;
- }
- else
- {
- cpustate->x87_sw &= ~X87_SW_C1;
-
- value = floatx80_round_to_int(ST(0));
- }
-
- if (x87_check_exceptions())
- x87_write_stack( 0, value, TRUE);
-
- CYCLES( 21);
-}
-
-void I386_OPS_BASE::x87_fxtract( UINT8 modrm)
-{
- floatx80 sig80, exp80;
-
- if (X87_IS_ST_EMPTY(0))
- {
- x87_set_stack_underflow();
- sig80 = exp80 = fx80_inan;
- }
- else if (!X87_IS_ST_EMPTY(7))
- {
- x87_set_stack_overflow();
- sig80 = exp80 = fx80_inan;
- }
- else
- {
- floatx80 value = ST(0);
-
- if (floatx80_eq(value, fx80_zero))
- {
- cpustate->x87_sw |= X87_SW_ZE;
-
- exp80 = fx80_ninf;
- sig80 = fx80_zero;
- }
- else
- {
- // Extract the unbiased exponent
- exp80 = int32_to_floatx80((value.high & 0x7fff) - 0x3fff);
-
- // For the significand, replicate the original value and set its true exponent to 0.
- sig80 = value;
- sig80.high &= ~0x7fff;
- sig80.high |= 0x3fff;
- }
- }
-
- if (x87_check_exceptions())
- {
- x87_write_stack( 0, exp80, TRUE);
- x87_dec_stack();
- x87_write_stack( 0, sig80, TRUE);
- }
-
- CYCLES( 21);
-}
-
-/*************************************
- *
- * Comparison
- *
- *************************************/
-
-void I386_OPS_BASE::x87_ftst( UINT8 modrm)
-{
- if (X87_IS_ST_EMPTY(0))
- {
- x87_set_stack_underflow();
- cpustate->x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
- }
- else
- {
- cpustate->x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
-
- if (floatx80_is_nan(ST(0)))
- {
- cpustate->x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
- cpustate->x87_sw |= X87_SW_IE;
- }
- else
- {
- if (floatx80_eq(ST(0), fx80_zero))
- cpustate->x87_sw |= X87_SW_C3;
-
- if (floatx80_lt(ST(0), fx80_zero))
- cpustate->x87_sw |= X87_SW_C0;
- }
- }
-
- x87_check_exceptions();
-
- CYCLES( 4);
-}
-
-void I386_OPS_BASE::x87_fxam( UINT8 modrm)
-{
- floatx80 value = ST(0);
-
- cpustate->x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
-
- // TODO: Unsupported and denormal values
- if (X87_IS_ST_EMPTY(0))
- {
- cpustate->x87_sw |= X87_SW_C3 | X87_SW_C0;
- }
- else if (floatx80_is_zero(value))
- {
- cpustate->x87_sw |= X87_SW_C3;
- }
- if (floatx80_is_nan(value))
- {
- cpustate->x87_sw |= X87_SW_C0;
- }
- else if (floatx80_is_inf(value))
- {
- cpustate->x87_sw |= X87_SW_C2 | X87_SW_C0;
- }
- else
- {
- cpustate->x87_sw |= X87_SW_C2;
- }
-
- if (value.high & 0x8000)
- cpustate->x87_sw |= X87_SW_C1;
-
- CYCLES( 8);
-}
-
-void I386_OPS_BASE::x87_ficom_m16int( UINT8 modrm)
-{
- UINT32 ea = GetEA( modrm, 0);
- if (X87_IS_ST_EMPTY(0))
- {
- x87_set_stack_underflow();
- cpustate->x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
- }
- else
- {
- cpustate->x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
-
- INT16 m16int = READ16( ea);
-
- floatx80 a = ST(0);
- floatx80 b = int32_to_floatx80(m16int);
-
- if (floatx80_is_nan(a))
- {
- cpustate->x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
- cpustate->x87_sw |= X87_SW_IE;
- }
- else
- {
- if (floatx80_eq(a, b))
- cpustate->x87_sw |= X87_SW_C3;
-
- if (floatx80_lt(a, b))
- cpustate->x87_sw |= X87_SW_C0;
- }
- }
-
- x87_check_exceptions();
-
- CYCLES( 16);
-}
-
-void I386_OPS_BASE::x87_ficom_m32int( UINT8 modrm)
-{
- UINT32 ea = GetEA( modrm, 0);
- if (X87_IS_ST_EMPTY(0))
- {
- x87_set_stack_underflow();
- cpustate->x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
- }
- else
- {
- cpustate->x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
-
- INT32 m32int = READ32( ea);
-
- floatx80 a = ST(0);
- floatx80 b = int32_to_floatx80(m32int);
-
- if (floatx80_is_nan(a))
- {
- cpustate->x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
- cpustate->x87_sw |= X87_SW_IE;
- }
- else
- {
- if (floatx80_eq(a, b))
- cpustate->x87_sw |= X87_SW_C3;
-
- if (floatx80_lt(a, b))
- cpustate->x87_sw |= X87_SW_C0;
- }
- }
-
- x87_check_exceptions();
-
- CYCLES( 15);
-}
-
-void I386_OPS_BASE::x87_ficomp_m16int( UINT8 modrm)
-{
- UINT32 ea = GetEA( modrm, 0);
- if (X87_IS_ST_EMPTY(0))
- {
- x87_set_stack_underflow();
- cpustate->x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
- }
- else
- {
- cpustate->x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
-
- INT16 m16int = READ16( ea);
-
- floatx80 a = ST(0);
- floatx80 b = int32_to_floatx80(m16int);
-
- if (floatx80_is_nan(a))
- {
- cpustate->x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
- cpustate->x87_sw |= X87_SW_IE;
- }
- else
- {
- if (floatx80_eq(a, b))
- cpustate->x87_sw |= X87_SW_C3;
-
- if (floatx80_lt(a, b))
- cpustate->x87_sw |= X87_SW_C0;
- }
- }
-
- if (x87_check_exceptions())
- x87_inc_stack();
-
- CYCLES( 16);
-}
-
-void I386_OPS_BASE::x87_ficomp_m32int( UINT8 modrm)
-{
- UINT32 ea = GetEA( modrm, 0);
- if (X87_IS_ST_EMPTY(0))
- {
- x87_set_stack_underflow();
- cpustate->x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
- }
- else
- {
- cpustate->x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
-
- INT32 m32int = READ32( ea);
-
- floatx80 a = ST(0);
- floatx80 b = int32_to_floatx80(m32int);
-
- if (floatx80_is_nan(a))
- {
- cpustate->x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
- cpustate->x87_sw |= X87_SW_IE;
- }
- else
- {
- if (floatx80_eq(a, b))
- cpustate->x87_sw |= X87_SW_C3;
-
- if (floatx80_lt(a, b))
- cpustate->x87_sw |= X87_SW_C0;
- }
- }
-
- if (x87_check_exceptions())
- x87_inc_stack();
-
- CYCLES( 15);
-}
-
-
-void I386_OPS_BASE::x87_fcom_m32real( UINT8 modrm)
-{
- UINT32 ea = GetEA( modrm, 0);
- if (X87_IS_ST_EMPTY(0))
- {
- x87_set_stack_underflow();
- cpustate->x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
- }
- else
- {
- cpustate->x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
-
- UINT32 m32real = READ32( ea);
-
- floatx80 a = ST(0);
- floatx80 b = float32_to_floatx80(m32real);
-
- if (floatx80_is_nan(a) || floatx80_is_nan(b))
- {
- cpustate->x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
- cpustate->x87_sw |= X87_SW_IE;
- }
- else
- {
- if (floatx80_eq(a, b))
- cpustate->x87_sw |= X87_SW_C3;
-
- if (floatx80_lt(a, b))
- cpustate->x87_sw |= X87_SW_C0;
- }
- }
-
- x87_check_exceptions();
-
- CYCLES( 4);
-}
-
-void I386_OPS_BASE::x87_fcom_m64real( UINT8 modrm)
-{
- UINT32 ea = GetEA( modrm, 0);
- if (X87_IS_ST_EMPTY(0))
- {
- x87_set_stack_underflow();
- cpustate->x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
- }
- else
- {
- cpustate->x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
-
- UINT64 m64real = READ64( ea);
-
- floatx80 a = ST(0);
- floatx80 b = float64_to_floatx80(m64real);
-
- if (floatx80_is_nan(a) || floatx80_is_nan(b))
- {
- cpustate->x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
- cpustate->x87_sw |= X87_SW_IE;
- }
- else
- {
- if (floatx80_eq(a, b))
- cpustate->x87_sw |= X87_SW_C3;
-
- if (floatx80_lt(a, b))
- cpustate->x87_sw |= X87_SW_C0;
- }
- }
-
- x87_check_exceptions();
-
- CYCLES( 4);
-}
-
-void I386_OPS_BASE::x87_fcom_sti( UINT8 modrm)
-{
- int i = modrm & 7;
-
- if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
- {
- x87_set_stack_underflow();
- cpustate->x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
- }
- else
- {
- cpustate->x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
-
- floatx80 a = ST(0);
- floatx80 b = ST(i);
-
- if (floatx80_is_nan(a) || floatx80_is_nan(b))
- {
- cpustate->x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
- cpustate->x87_sw |= X87_SW_IE;
- }
- else
- {
- if (floatx80_eq(a, b))
- cpustate->x87_sw |= X87_SW_C3;
-
- if (floatx80_lt(a, b))
- cpustate->x87_sw |= X87_SW_C0;
- }
- }
-
- x87_check_exceptions();
-
- CYCLES( 4);
-}
-
-void I386_OPS_BASE::x87_fcomp_m32real( UINT8 modrm)
-{
- UINT32 ea = GetEA( modrm, 0);
- if (X87_IS_ST_EMPTY(0))
- {
- x87_set_stack_underflow();
- cpustate->x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
- }
- else
- {
- cpustate->x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
-
- UINT32 m32real = READ32( ea);
-
- floatx80 a = ST(0);
- floatx80 b = float32_to_floatx80(m32real);
-
- if (floatx80_is_nan(a) || floatx80_is_nan(b))
- {
- cpustate->x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
- cpustate->x87_sw |= X87_SW_IE;
- }
- else
- {
- if (floatx80_eq(a, b))
- cpustate->x87_sw |= X87_SW_C3;
-
- if (floatx80_lt(a, b))
- cpustate->x87_sw |= X87_SW_C0;
- }
- }
-
- if (x87_check_exceptions())
- x87_inc_stack();
-
- CYCLES( 4);
-}
-
-void I386_OPS_BASE::x87_fcomp_m64real( UINT8 modrm)
-{
- UINT32 ea = GetEA( modrm, 0);
- if (X87_IS_ST_EMPTY(0))
- {
- x87_set_stack_underflow();
- cpustate->x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
- }
- else
- {
- cpustate->x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
-
- UINT64 m64real = READ64( ea);
-
- floatx80 a = ST(0);
- floatx80 b = float64_to_floatx80(m64real);
-
- if (floatx80_is_nan(a) || floatx80_is_nan(b))
- {
- cpustate->x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
- cpustate->x87_sw |= X87_SW_IE;
- }
- else
- {
- if (floatx80_eq(a, b))
- cpustate->x87_sw |= X87_SW_C3;
-
- if (floatx80_lt(a, b))
- cpustate->x87_sw |= X87_SW_C0;
- }
- }
-
- if (x87_check_exceptions())
- x87_inc_stack();
-
- CYCLES( 4);
-}
-
-void I386_OPS_BASE::x87_fcomp_sti( UINT8 modrm)
-{
- int i = modrm & 7;
-
- if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
- {
- x87_set_stack_underflow();
- cpustate->x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
- }
- else
- {
- cpustate->x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
-
- floatx80 a = ST(0);
- floatx80 b = ST(i);
-
- if (floatx80_is_nan(a) || floatx80_is_nan(b))
- {
- cpustate->x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
- cpustate->x87_sw |= X87_SW_IE;
- }
- else
- {
- if (floatx80_eq(a, b))
- cpustate->x87_sw |= X87_SW_C3;
-
- if (floatx80_lt(a, b))
- cpustate->x87_sw |= X87_SW_C0;
- }
- }
-
- if (x87_check_exceptions())
- x87_inc_stack();
-
- CYCLES( 4);
-}
-
-void I386_OPS_BASE::x87_fcomi_sti( UINT8 modrm)
-{
- int i = modrm & 7;
-
- if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
- {
- x87_set_stack_underflow();
- cpustate->ZF = 1;
- cpustate->PF = 1;
- cpustate->CF = 1;
- }
- else
- {
- cpustate->x87_sw &= ~X87_SW_C1;
-
- floatx80 a = ST(0);
- floatx80 b = ST(i);
-
- if (floatx80_is_nan(a) || floatx80_is_nan(b))
- {
- cpustate->ZF = 1;
- cpustate->PF = 1;
- cpustate->CF = 1;
- cpustate->x87_sw |= X87_SW_IE;
- }
- else
- {
- cpustate->ZF = 0;
- cpustate->PF = 0;
- cpustate->CF = 0;
-
- if (floatx80_eq(a, b))
- cpustate->ZF = 1;
-
- if (floatx80_lt(a, b))
- cpustate->CF = 1;
- }
- }
-
- x87_check_exceptions();
-
- CYCLES( 4); // TODO: correct cycle count
-}
-
-void I386_OPS_BASE::x87_fcomip_sti( UINT8 modrm)
-{
- int i = modrm & 7;
-
- if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
- {
- x87_set_stack_underflow();
- cpustate->ZF = 1;
- cpustate->PF = 1;
- cpustate->CF = 1;
- }
- else
- {
- cpustate->x87_sw &= ~X87_SW_C1;
-
- floatx80 a = ST(0);
- floatx80 b = ST(i);
-
- if (floatx80_is_nan(a) || floatx80_is_nan(b))
- {
- cpustate->ZF = 1;
- cpustate->PF = 1;
- cpustate->CF = 1;
- cpustate->x87_sw |= X87_SW_IE;
- }
- else
- {
- cpustate->ZF = 0;
- cpustate->PF = 0;
- cpustate->CF = 0;
-
- if (floatx80_eq(a, b))
- cpustate->ZF = 1;
-
- if (floatx80_lt(a, b))
- cpustate->CF = 1;
- }
- }
-
- if (x87_check_exceptions())
- x87_inc_stack();
-
- CYCLES( 4); // TODO: correct cycle count
-}
-
-void I386_OPS_BASE::x87_fucomi_sti( UINT8 modrm)
-{
- int i = modrm & 7;
-
- if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
- {
- x87_set_stack_underflow();
- cpustate->ZF = 1;
- cpustate->PF = 1;
- cpustate->CF = 1;
- }
- else
- {
- cpustate->x87_sw &= ~X87_SW_C1;
-
- floatx80 a = ST(0);
- floatx80 b = ST(i);
-
- if (floatx80_is_quiet_nan(a) || floatx80_is_quiet_nan(b))
- {
- cpustate->ZF = 1;
- cpustate->PF = 1;
- cpustate->CF = 1;
- }
- else if (floatx80_is_nan(a) || floatx80_is_nan(b))
- {
- cpustate->ZF = 1;
- cpustate->PF = 1;
- cpustate->CF = 1;
- cpustate->x87_sw |= X87_SW_IE;
- }
- else
- {
- cpustate->ZF = 0;
- cpustate->PF = 0;
- cpustate->CF = 0;
-
- if (floatx80_eq(a, b))
- cpustate->ZF = 1;
-
- if (floatx80_lt(a, b))
- cpustate->CF = 1;
- }
- }
-
- x87_check_exceptions();
-
- CYCLES( 4); // TODO: correct cycle count
-}
-
-void I386_OPS_BASE::x87_fucomip_sti( UINT8 modrm)
-{
- int i = modrm & 7;
-
- if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
- {
- x87_set_stack_underflow();
- cpustate->ZF = 1;
- cpustate->PF = 1;
- cpustate->CF = 1;
- }
- else
- {
- cpustate->x87_sw &= ~X87_SW_C1;
-
- floatx80 a = ST(0);
- floatx80 b = ST(i);
-
- if (floatx80_is_quiet_nan(a) || floatx80_is_quiet_nan(b))
- {
- cpustate->ZF = 1;
- cpustate->PF = 1;
- cpustate->CF = 1;
- }
- else if (floatx80_is_nan(a) || floatx80_is_nan(b))
- {
- cpustate->ZF = 1;
- cpustate->PF = 1;
- cpustate->CF = 1;
- cpustate->x87_sw |= X87_SW_IE;
- }
- else
- {
- cpustate->ZF = 0;
- cpustate->PF = 0;
- cpustate->CF = 0;
-
- if (floatx80_eq(a, b))
- cpustate->ZF = 1;
-
- if (floatx80_lt(a, b))
- cpustate->CF = 1;
- }
- }
-
- if (x87_check_exceptions())
- x87_inc_stack();
-
- CYCLES( 4); // TODO: correct cycle count
-}
-
-void I386_OPS_BASE::x87_fcompp( UINT8 modrm)
-{
- if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(1))
- {
- x87_set_stack_underflow();
- cpustate->x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
- }
- else
- {
- cpustate->x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
-
- floatx80 a = ST(0);
- floatx80 b = ST(1);
-
- if (floatx80_is_nan(a) || floatx80_is_nan(b))
- {
- cpustate->x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
- cpustate->x87_sw |= X87_SW_IE;
- }
- else
- {
- if (floatx80_eq(a, b))
- cpustate->x87_sw |= X87_SW_C3;
-
- if (floatx80_lt(a, b))
- cpustate->x87_sw |= X87_SW_C0;
- }
- }
-
- if (x87_check_exceptions())
- {
- x87_inc_stack();
- x87_inc_stack();
- }
-
- CYCLES( 5);
-}
-
-
-/*************************************
- *
- * Unordererd comparison
- *
- *************************************/
-
-void I386_OPS_BASE::x87_fucom_sti( UINT8 modrm)
-{
- int i = modrm & 7;
-
- if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
- {
- x87_set_stack_underflow();
- cpustate->x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
- }
- else
- {
- cpustate->x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
-
- floatx80 a = ST(0);
- floatx80 b = ST(i);
-
- if (floatx80_is_nan(a) || floatx80_is_nan(b))
- {
- cpustate->x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
-
- if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
- cpustate->x87_sw |= X87_SW_IE;
- }
- else
- {
- if (floatx80_eq(a, b))
- cpustate->x87_sw |= X87_SW_C3;
-
- if (floatx80_lt(a, b))
- cpustate->x87_sw |= X87_SW_C0;
- }
- }
-
- x87_check_exceptions();
-
- CYCLES( 4);
-}
-
-void I386_OPS_BASE::x87_fucomp_sti( UINT8 modrm)
-{
- int i = modrm & 7;
-
- if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
- {
- x87_set_stack_underflow();
- cpustate->x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
- }
- else
- {
- cpustate->x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
-
- floatx80 a = ST(0);
- floatx80 b = ST(i);
-
- if (floatx80_is_nan(a) || floatx80_is_nan(b))
- {
- cpustate->x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
-
- if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
- cpustate->x87_sw |= X87_SW_IE;
- }
- else
- {
- if (floatx80_eq(a, b))
- cpustate->x87_sw |= X87_SW_C3;
-
- if (floatx80_lt(a, b))
- cpustate->x87_sw |= X87_SW_C0;
- }
- }
-
- if (x87_check_exceptions())
- x87_inc_stack();
-
- CYCLES( 4);
-}
-
-void I386_OPS_BASE::x87_fucompp( UINT8 modrm)
-{
- if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(1))
- {
- x87_set_stack_underflow();
- cpustate->x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
- }
- else
- {
- cpustate->x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
-
- floatx80 a = ST(0);
- floatx80 b = ST(1);
-
- if (floatx80_is_nan(a) || floatx80_is_nan(b))
- {
- cpustate->x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
-
- if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
- cpustate->x87_sw |= X87_SW_IE;
- }
- else
- {
- if (floatx80_eq(a, b))
- cpustate->x87_sw |= X87_SW_C3;
-
- if (floatx80_lt(a, b))
- cpustate->x87_sw |= X87_SW_C0;
- }
- }
-
- if (x87_check_exceptions())
- {
- x87_inc_stack();
- x87_inc_stack();
- }
-
- CYCLES( 4);
-}
-
-
-/*************************************
- *
- * Control
- *
- *************************************/
-
-void I386_OPS_BASE::x87_fdecstp( UINT8 modrm)
-{
- cpustate->x87_sw &= ~X87_SW_C1;
-
- x87_dec_stack();
- x87_check_exceptions();
-
- CYCLES( 3);
-}
-
-void I386_OPS_BASE::x87_fincstp( UINT8 modrm)
-{
- cpustate->x87_sw &= ~X87_SW_C1;
-
- x87_inc_stack();
- x87_check_exceptions();
-
- CYCLES( 3);
-}
-
-void I386_OPS_BASE::x87_fclex( UINT8 modrm)
-{
- cpustate->x87_sw &= ~0x80ff;
-
- CYCLES( 7);
-}
-
-void I386_OPS_BASE::x87_ffree( UINT8 modrm)
-{
- x87_set_tag( ST_TO_PHYS(modrm & 7), X87_TW_EMPTY);
-
- CYCLES( 3);
-}
-
-void I386_OPS_BASE::x87_finit( UINT8 modrm)
-{
- x87_reset();
-
- CYCLES( 17);
-}
-
-void I386_OPS_BASE::x87_fldcw( UINT8 modrm)
-{
- UINT32 ea = GetEA( modrm, 0);
- UINT16 cw = READ16( ea);
-
- x87_write_cw( cw);
-
- x87_check_exceptions();
-
- CYCLES( 4);
-}
-
-void I386_OPS_BASE::x87_fstcw( UINT8 modrm)
-{
- UINT32 ea = GetEA( modrm, 1);
- WRITE16( ea, cpustate->x87_cw);
-
- CYCLES( 3);
-}
-
-void I386_OPS_BASE::x87_fldenv( UINT8 modrm)
-{
- // TODO: Pointers and selectors
- UINT32 ea = GetEA( modrm, 0);
-
- if (cpustate->operand_size)
- {
- // 32-bit real/protected mode
- x87_write_cw( READ16( ea));
- cpustate->x87_sw = READ16( ea + 4);
- cpustate->x87_tw = READ16( ea + 8);
- }
- else
- {
- // 16-bit real/protected mode
- x87_write_cw( READ16( ea));
- cpustate->x87_sw = READ16( ea + 2);
- cpustate->x87_tw = READ16( ea + 4);
- }
-
- x87_check_exceptions();
-
- CYCLES((cpustate->cr[0] & 1) ? 34 : 44);
-}
-
-void I386_OPS_BASE::x87_fstenv( UINT8 modrm)
-{
- UINT32 ea = GetEA( modrm, 1);
-
- // TODO: Pointers and selectors
- switch((cpustate->cr[0] & 1)|(cpustate->operand_size & 1)<<1)
- {
- case 0: // 16-bit real mode
- WRITE16( ea + 0, cpustate->x87_cw);
- WRITE16( ea + 2, cpustate->x87_sw);
- WRITE16( ea + 4, cpustate->x87_tw);
-// WRITE16( ea + 6, cpustate->fpu_inst_ptr & 0xffff);
-// WRITE16( ea + 8, (cpustate->fpu_opcode & 0x07ff) | ((cpustate->fpu_inst_ptr & 0x0f0000) >> 4));
-// WRITE16( ea + 10, cpustate->fpu_data_ptr & 0xffff);
-// WRITE16( ea + 12, (cpustate->fpu_inst_ptr & 0x0f0000) >> 4);
- break;
- case 1: // 16-bit protected mode
- WRITE16(ea + 0, cpustate->x87_cw);
- WRITE16(ea + 2, cpustate->x87_sw);
- WRITE16(ea + 4, cpustate->x87_tw);
-// WRITE16(ea + 6, cpustate->fpu_inst_ptr & 0xffff);
-// WRITE16(ea + 8, (cpustate->fpu_opcode & 0x07ff) | ((cpustate->fpu_inst_ptr & 0x0f0000) >> 4));
-// WRITE16(ea + 10, cpustate->fpu_data_ptr & 0xffff);
-// WRITE16(ea + 12, (cpustate->fpu_inst_ptr & 0x0f0000) >> 4);
- break;
- case 2: // 32-bit real mode
- WRITE16( ea + 0, cpustate->x87_cw);
- WRITE16( ea + 4, cpustate->x87_sw);
- WRITE16( ea + 8, cpustate->x87_tw);
-// WRITE16( ea + 12, cpustate->fpu_inst_ptr & 0xffff);
-// WRITE16( ea + 8, (cpustate->fpu_opcode & 0x07ff) | ((cpustate->fpu_inst_ptr & 0x0f0000) >> 4));
-// WRITE16( ea + 20, cpustate->fpu_data_ptr & 0xffff);
-// WRITE16( ea + 12, ((cpustate->fpu_inst_ptr & 0x0f0000) >> 4));
-// WRITE32( ea + 24, (cpustate->fpu_data_ptr >> 16) << 12);
- break;
- case 3: // 32-bit protected mode
- WRITE16( ea + 0, cpustate->x87_cw);
- WRITE16( ea + 4, cpustate->x87_sw);
- WRITE16( ea + 8, cpustate->x87_tw);
-// WRITE32( ea + 12, cpustate->fpu_inst_ptr);
-// WRITE32( ea + 16, cpustate->fpu_opcode);
-// WRITE32( ea + 20, cpustate->fpu_data_ptr);
-// WRITE32( ea + 24, cpustate->fpu_inst_ptr);
- break;
- }
-
- CYCLES((cpustate->cr[0] & 1) ? 56 : 67);
-}
-
-void I386_OPS_BASE::x87_fsave( UINT8 modrm)
-{
- UINT32 ea = GetEA( modrm, 1);
-
- // TODO: Pointers and selectors
- switch((cpustate->cr[0] & 1)|(cpustate->operand_size & 1)<<1)
- {
- case 0: // 16-bit real mode
- WRITE16( ea + 0, cpustate->x87_cw);
- WRITE16( ea + 2, cpustate->x87_sw);
- WRITE16( ea + 4, cpustate->x87_tw);
-// WRITE16( ea + 6, cpustate->fpu_inst_ptr & 0xffff);
-// WRITE16( ea + 8, (cpustate->fpu_opcode & 0x07ff) | ((cpustate->fpu_inst_ptr & 0x0f0000) >> 4));
-// WRITE16( ea + 10, cpustate->fpu_data_ptr & 0xffff);
-// WRITE16( ea + 12, (cpustate->fpu_inst_ptr & 0x0f0000) >> 4);
- ea += 14;
- break;
- case 1: // 16-bit protected mode
- WRITE16(ea + 0, cpustate->x87_cw);
- WRITE16(ea + 2, cpustate->x87_sw);
- WRITE16(ea + 4, cpustate->x87_tw);
-// WRITE16(ea + 6, cpustate->fpu_inst_ptr & 0xffff);
-// WRITE16(ea + 8, (cpustate->fpu_opcode & 0x07ff) | ((cpustate->fpu_inst_ptr & 0x0f0000) >> 4));
-// WRITE16(ea + 10, cpustate->fpu_data_ptr & 0xffff);
-// WRITE16(ea + 12, (cpustate->fpu_inst_ptr & 0x0f0000) >> 4);
- ea += 14;
- break;
- case 2: // 32-bit real mode
- WRITE16( ea + 0, cpustate->x87_cw);
- WRITE16( ea + 4, cpustate->x87_sw);
- WRITE16( ea + 8, cpustate->x87_tw);
-// WRITE16( ea + 12, cpustate->fpu_inst_ptr & 0xffff);
-// WRITE16( ea + 8, (cpustate->fpu_opcode & 0x07ff) | ((cpustate->fpu_inst_ptr & 0x0f0000) >> 4));
-// WRITE16( ea + 20, cpustate->fpu_data_ptr & 0xffff);
-// WRITE16( ea + 12, ((cpustate->fpu_inst_ptr & 0x0f0000) >> 4));
-// WRITE32( ea + 24, (cpustate->fpu_data_ptr >> 16) << 12);
- ea += 28;
- break;
- case 3: // 32-bit protected mode
- WRITE16( ea + 0, cpustate->x87_cw);
- WRITE16( ea + 4, cpustate->x87_sw);
- WRITE16( ea + 8, cpustate->x87_tw);
-// WRITE32( ea + 12, cpustate->fpu_inst_ptr);
-// WRITE32( ea + 16, cpustate->fpu_opcode);
-// WRITE32( ea + 20, cpustate->fpu_data_ptr);
-// WRITE32( ea + 24, cpustate->fpu_inst_ptr);
- ea += 28;
- break;
- }
-
- for (int i = 0; i < 8; ++i)
- WRITE80( ea + i*10, ST(i));
-
- CYCLES((cpustate->cr[0] & 1) ? 56 : 67);
-}
-
-void I386_OPS_BASE::x87_frstor( UINT8 modrm)
-{
- UINT32 ea = GetEA( modrm, 0);
-
- // TODO: Pointers and selectors
- switch((cpustate->cr[0] & 1)|(cpustate->operand_size & 1)<<1)
- {
- case 0: // 16-bit real mode
- x87_write_cw( READ16( ea));
- cpustate->x87_sw = READ16( ea + 2);
- cpustate->x87_tw = READ16( ea + 4);
-// WRITE16( ea + 6, cpustate->fpu_inst_ptr & 0xffff);
-// WRITE16( ea + 8, (cpustate->fpu_opcode & 0x07ff) | ((cpustate->fpu_inst_ptr & 0x0f0000) >> 4));
-// WRITE16( ea + 10, cpustate->fpu_data_ptr & 0xffff);
-// WRITE16( ea + 12, (cpustate->fpu_inst_ptr & 0x0f0000) >> 4);
- ea += 14;
- break;
- case 1: // 16-bit protected mode
- x87_write_cw( READ16( ea));
- cpustate->x87_sw = READ16( ea + 2);
- cpustate->x87_tw = READ16( ea + 4);
-// WRITE16(ea + 6, cpustate->fpu_inst_ptr & 0xffff);
-// WRITE16(ea + 8, (cpustate->fpu_opcode & 0x07ff) | ((cpustate->fpu_inst_ptr & 0x0f0000) >> 4));
-// WRITE16(ea + 10, cpustate->fpu_data_ptr & 0xffff);
-// WRITE16(ea + 12, (cpustate->fpu_inst_ptr & 0x0f0000) >> 4);
- ea += 14;
- break;
- case 2: // 32-bit real mode
- x87_write_cw( READ16( ea));
- cpustate->x87_sw = READ16( ea + 4);
- cpustate->x87_tw = READ16( ea + 8);
-// WRITE16( ea + 12, cpustate->fpu_inst_ptr & 0xffff);
-// WRITE16( ea + 8, (cpustate->fpu_opcode & 0x07ff) | ((cpustate->fpu_inst_ptr & 0x0f0000) >> 4));
-// WRITE16( ea + 20, cpustate->fpu_data_ptr & 0xffff);
-// WRITE16( ea + 12, ((cpustate->fpu_inst_ptr & 0x0f0000) >> 4));
-// WRITE32( ea + 24, (cpustate->fpu_data_ptr >> 16) << 12);
- ea += 28;
- break;
- case 3: // 32-bit protected mode
- x87_write_cw( READ16( ea));
- cpustate->x87_sw = READ16( ea + 4);
- cpustate->x87_tw = READ16( ea + 8);
-// WRITE32( ea + 12, cpustate->fpu_inst_ptr);
-// WRITE32( ea + 16, cpustate->fpu_opcode);
-// WRITE32( ea + 20, cpustate->fpu_data_ptr);
-// WRITE32( ea + 24, cpustate->fpu_inst_ptr);
- ea += 28;
- break;
- }
-
- for (int i = 0; i < 8; ++i)
- x87_write_stack( i, READ80( ea + i*10), FALSE);
-
- CYCLES((cpustate->cr[0] & 1) ? 34 : 44);
-}
-
-void I386_OPS_BASE::x87_fxch( UINT8 modrm)
-{
- if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(1))
- x87_set_stack_underflow();
-
- if (x87_check_exceptions())
- {
- floatx80 tmp = ST(0);
- ST(0) = ST(1);
- ST(1) = tmp;
-
- // Swap the tags
- int tag0 = X87_TAG(ST_TO_PHYS(0));
- x87_set_tag( ST_TO_PHYS(0), X87_TAG(ST_TO_PHYS(1)));
- x87_set_tag( ST_TO_PHYS(1), tag0);
- }
-
- CYCLES( 4);
-}
-
-void I386_OPS_BASE::x87_fxch_sti( UINT8 modrm)
-{
- int i = modrm & 7;
-
- if (X87_IS_ST_EMPTY(0))
- {
- ST(0) = fx80_inan;
- x87_set_tag( ST_TO_PHYS(0), X87_TW_SPECIAL);
- x87_set_stack_underflow();
- }
- if (X87_IS_ST_EMPTY(i))
- {
- ST(i) = fx80_inan;
- x87_set_tag( ST_TO_PHYS(i), X87_TW_SPECIAL);
- x87_set_stack_underflow();
- }
-
- if (x87_check_exceptions())
- {
- floatx80 tmp = ST(0);
- ST(0) = ST(i);
- ST(i) = tmp;
-
- // Swap the tags
- int tag0 = X87_TAG(ST_TO_PHYS(0));
- x87_set_tag( ST_TO_PHYS(0), X87_TAG(ST_TO_PHYS(i)));
- x87_set_tag( ST_TO_PHYS(i), tag0);
- }
-
- CYCLES( 4);
-}
-
-void I386_OPS_BASE::x87_fstsw_ax( UINT8 modrm)
-{
- REG16(AX) = cpustate->x87_sw;
-
- CYCLES( 3);
-}
-
-void I386_OPS_BASE::x87_fstsw_m2byte( UINT8 modrm)
-{
- UINT32 ea = GetEA( modrm, 1);
-
- WRITE16( ea, cpustate->x87_sw);
-
- CYCLES( 3);
-}
-
-void I386_OPS_BASE::x87_invalid( UINT8 modrm)
-{
- // TODO
- fatalerror("x87 invalid instruction (PC:%.4x)\n", cpustate->pc);
-}
-
-
-
-/*************************************
- *
- * Instruction dispatch
- *
- *************************************/
-
-void I386_OPS_BASE::I386OP(x87_group_d8)()
-{
- UINT8 modrm = FETCH();
- cpustate->opcode_table_x87_d8[modrm]( modrm);
-}
-
-void I386_OPS_BASE::I386OP(x87_group_d9)()
-{
- UINT8 modrm = FETCH();
- cpustate->opcode_table_x87_d9[modrm]( modrm);
-}
-
-void I386_OPS_BASE::I386OP(x87_group_da)()
-{
- UINT8 modrm = FETCH();
- cpustate->opcode_table_x87_da[modrm]( modrm);
-}
-
-void I386_OPS_BASE::I386OP(x87_group_db)()
-{
- UINT8 modrm = FETCH();
- cpustate->opcode_table_x87_db[modrm]( modrm);
-}
-
-void I386_OPS_BASE::I386OP(x87_group_dc)()
-{
- UINT8 modrm = FETCH();
- cpustate->opcode_table_x87_dc[modrm]( modrm);
-}
-
-void I386_OPS_BASE::I386OP(x87_group_dd)()
-{
- UINT8 modrm = FETCH();
- cpustate->opcode_table_x87_dd[modrm]( modrm);
-}
-
-void I386_OPS_BASE::I386OP(x87_group_de)()
-{
- UINT8 modrm = FETCH();
- cpustate->opcode_table_x87_de[modrm]( modrm);
-}
-
-void I386_OPS_BASE::I386OP(x87_group_df)()
-{
- UINT8 modrm = FETCH();
- cpustate->opcode_table_x87_df[modrm](modrm);
-}
-
-
-/*************************************
- *
- * Opcode table building
- *
- *************************************/
-
-void I386_OPS_BASE::build_x87_opcode_table_d8()
-{
- int modrm = 0;
-
- for (modrm = 0; modrm < 0x100; ++modrm)
- {
- void I386_OPS_BASE::(*ptr)( UINT8 modrm) = x87_invalid;
-
- if (modrm < 0xc0)
- {
- switch ((modrm >> 3) & 0x7)
- {
- case 0x00: ptr = x87_fadd_m32real; break;
- case 0x01: ptr = x87_fmul_m32real; break;
- case 0x02: ptr = x87_fcom_m32real; break;
- case 0x03: ptr = x87_fcomp_m32real; break;
- case 0x04: ptr = x87_fsub_m32real; break;
- case 0x05: ptr = x87_fsubr_m32real; break;
- case 0x06: ptr = x87_fdiv_m32real; break;
- case 0x07: ptr = x87_fdivr_m32real; break;
- }
- }
- else
- {
- switch (modrm)
- {
- case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7: ptr = x87_fadd_st_sti; break;
- case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf: ptr = x87_fmul_st_sti; break;
- case 0xd0: case 0xd1: case 0xd2: case 0xd3: case 0xd4: case 0xd5: case 0xd6: case 0xd7: ptr = x87_fcom_sti; break;
- case 0xd8: case 0xd9: case 0xda: case 0xdb: case 0xdc: case 0xdd: case 0xde: case 0xdf: ptr = x87_fcomp_sti; break;
- case 0xe0: case 0xe1: case 0xe2: case 0xe3: case 0xe4: case 0xe5: case 0xe6: case 0xe7: ptr = x87_fsub_st_sti; break;
- case 0xe8: case 0xe9: case 0xea: case 0xeb: case 0xec: case 0xed: case 0xee: case 0xef: ptr = x87_fsubr_st_sti; break;
- case 0xf0: case 0xf1: case 0xf2: case 0xf3: case 0xf4: case 0xf5: case 0xf6: case 0xf7: ptr = x87_fdiv_st_sti; break;
- case 0xf8: case 0xf9: case 0xfa: case 0xfb: case 0xfc: case 0xfd: case 0xfe: case 0xff: ptr = x87_fdivr_st_sti; break;
- }
- }
-
- cpustate->opcode_table_x87_d8[modrm] = ptr;
- }
-}
-
-
-void I386_OPS_BASE::build_x87_opcode_table_d9()
-{
- int modrm = 0;
-
- for (modrm = 0; modrm < 0x100; ++modrm)
- {
- void I386_OPS_BASE::(*ptr)( UINT8 modrm) = x87_invalid;
-
- if (modrm < 0xc0)
- {
- switch ((modrm >> 3) & 0x7)
- {
- case 0x00: ptr = x87_fld_m32real; break;
- case 0x02: ptr = x87_fst_m32real; break;
- case 0x03: ptr = x87_fstp_m32real; break;
- case 0x04: ptr = x87_fldenv; break;
- case 0x05: ptr = x87_fldcw; break;
- case 0x06: ptr = x87_fstenv; break;
- case 0x07: ptr = x87_fstcw; break;
- }
- }
- else
- {
- switch (modrm)
- {
- case 0xc0:
- case 0xc1:
- case 0xc2:
- case 0xc3:
- case 0xc4:
- case 0xc5:
- case 0xc6:
- case 0xc7: ptr = x87_fld_sti; break;
-
- case 0xc8:
- case 0xc9:
- case 0xca:
- case 0xcb:
- case 0xcc:
- case 0xcd:
- case 0xce:
- case 0xcf: ptr = x87_fxch_sti; break;
-
- case 0xd0: ptr = x87_fnop; break;
- case 0xe0: ptr = x87_fchs; break;
- case 0xe1: ptr = x87_fabs; break;
- case 0xe4: ptr = x87_ftst; break;
- case 0xe5: ptr = x87_fxam; break;
- case 0xe8: ptr = x87_fld1; break;
- case 0xe9: ptr = x87_fldl2t; break;
- case 0xea: ptr = x87_fldl2e; break;
- case 0xeb: ptr = x87_fldpi; break;
- case 0xec: ptr = x87_fldlg2; break;
- case 0xed: ptr = x87_fldln2; break;
- case 0xee: ptr = x87_fldz; break;
- case 0xf0: ptr = x87_f2xm1; break;
- case 0xf1: ptr = x87_fyl2x; break;
- case 0xf2: ptr = x87_fptan; break;
- case 0xf3: ptr = x87_fpatan; break;
- case 0xf4: ptr = x87_fxtract; break;
- case 0xf5: ptr = x87_fprem1; break;
- case 0xf6: ptr = x87_fdecstp; break;
- case 0xf7: ptr = x87_fincstp; break;
- case 0xf8: ptr = x87_fprem; break;
- case 0xf9: ptr = x87_fyl2xp1; break;
- case 0xfa: ptr = x87_fsqrt; break;
- case 0xfb: ptr = x87_fsincos; break;
- case 0xfc: ptr = x87_frndint; break;
- case 0xfd: ptr = x87_fscale; break;
- case 0xfe: ptr = x87_fsin; break;
- case 0xff: ptr = x87_fcos; break;
- }
- }
-
- cpustate->opcode_table_x87_d9[modrm] = ptr;
- }
-}
-
-void I386_OPS_BASE::build_x87_opcode_table_da()
-{
- int modrm = 0;
-
- for (modrm = 0; modrm < 0x100; ++modrm)
- {
- void I386_OPS_BASE::(*ptr)( UINT8 modrm) = x87_invalid;
-
- if (modrm < 0xc0)
- {
- switch ((modrm >> 3) & 0x7)
- {
- case 0x00: ptr = x87_fiadd_m32int; break;
- case 0x01: ptr = x87_fimul_m32int; break;
- case 0x02: ptr = x87_ficom_m32int; break;
- case 0x03: ptr = x87_ficomp_m32int; break;
- case 0x04: ptr = x87_fisub_m32int; break;
- case 0x05: ptr = x87_fisubr_m32int; break;
- case 0x06: ptr = x87_fidiv_m32int; break;
- case 0x07: ptr = x87_fidivr_m32int; break;
- }
- }
- else
- {
- switch (modrm)
- {
- case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7: ptr = x87_fcmovb_sti; break;
- case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf: ptr = x87_fcmove_sti; break;
- case 0xd0: case 0xd1: case 0xd2: case 0xd3: case 0xd4: case 0xd5: case 0xd6: case 0xd7: ptr = x87_fcmovbe_sti; break;
- case 0xd8: case 0xd9: case 0xda: case 0xdb: case 0xdc: case 0xdd: case 0xde: case 0xdf: ptr = x87_fcmovu_sti; break;
- case 0xe9: ptr = x87_fucompp; break;
- }
- }
-
- cpustate->opcode_table_x87_da[modrm] = ptr;
- }
-}
-
-
-void I386_OPS_BASE::build_x87_opcode_table_db()
-{
- int modrm = 0;
-
- for (modrm = 0; modrm < 0x100; ++modrm)
- {
- void I386_OPS_BASE::(*ptr)( UINT8 modrm) = x87_invalid;
-
- if (modrm < 0xc0)
- {
- switch ((modrm >> 3) & 0x7)
- {
- case 0x00: ptr = x87_fild_m32int; break;
- case 0x02: ptr = x87_fist_m32int; break;
- case 0x03: ptr = x87_fistp_m32int; break;
- case 0x05: ptr = x87_fld_m80real; break;
- case 0x07: ptr = x87_fstp_m80real; break;
- }
- }
- else
- {
- switch (modrm)
- {
- case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7: ptr = x87_fcmovnb_sti; break;
- case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf: ptr = x87_fcmovne_sti; break;
- case 0xd0: case 0xd1: case 0xd2: case 0xd3: case 0xd4: case 0xd5: case 0xd6: case 0xd7: ptr = x87_fcmovnbe_sti; break;
- case 0xd8: case 0xd9: case 0xda: case 0xdb: case 0xdc: case 0xdd: case 0xde: case 0xdf: ptr = x87_fcmovnu_sti; break;
- case 0xe0: ptr = x87_fnop; break; /* FENI */
- case 0xe1: ptr = x87_fnop; break; /* FDISI */
- case 0xe2: ptr = x87_fclex; break;
- case 0xe3: ptr = x87_finit; break;
- case 0xe4: ptr = x87_fnop; break; /* FSETPM */
- case 0xe8: case 0xe9: case 0xea: case 0xeb: case 0xec: case 0xed: case 0xee: case 0xef: ptr = x87_fucomi_sti; break;
- case 0xf0: case 0xf1: case 0xf2: case 0xf3: case 0xf4: case 0xf5: case 0xf6: case 0xf7: ptr = x87_fcomi_sti; break;
- }
- }
-
- cpustate->opcode_table_x87_db[modrm] = ptr;
- }
-}
-
-
-void I386_OPS_BASE::build_x87_opcode_table_dc()
-{
- int modrm = 0;
-
- for (modrm = 0; modrm < 0x100; ++modrm)
- {
- void I386_OPS_BASE::(*ptr)( UINT8 modrm) = x87_invalid;
-
- if (modrm < 0xc0)
- {
- switch ((modrm >> 3) & 0x7)
- {
- case 0x00: ptr = x87_fadd_m64real; break;
- case 0x01: ptr = x87_fmul_m64real; break;
- case 0x02: ptr = x87_fcom_m64real; break;
- case 0x03: ptr = x87_fcomp_m64real; break;
- case 0x04: ptr = x87_fsub_m64real; break;
- case 0x05: ptr = x87_fsubr_m64real; break;
- case 0x06: ptr = x87_fdiv_m64real; break;
- case 0x07: ptr = x87_fdivr_m64real; break;
- }
- }
- else
- {
- switch (modrm)
- {
- case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7: ptr = x87_fadd_sti_st; break;
- case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf: ptr = x87_fmul_sti_st; break;
- case 0xe0: case 0xe1: case 0xe2: case 0xe3: case 0xe4: case 0xe5: case 0xe6: case 0xe7: ptr = x87_fsubr_sti_st; break;
- case 0xe8: case 0xe9: case 0xea: case 0xeb: case 0xec: case 0xed: case 0xee: case 0xef: ptr = x87_fsub_sti_st; break;
- case 0xf0: case 0xf1: case 0xf2: case 0xf3: case 0xf4: case 0xf5: case 0xf6: case 0xf7: ptr = x87_fdivr_sti_st; break;
- case 0xf8: case 0xf9: case 0xfa: case 0xfb: case 0xfc: case 0xfd: case 0xfe: case 0xff: ptr = x87_fdiv_sti_st; break;
- }
- }
-
- cpustate->opcode_table_x87_dc[modrm] = ptr;
- }
-}
-
-
-void I386_OPS_BASE::build_x87_opcode_table_dd()
-{
- int modrm = 0;
-
- for (modrm = 0; modrm < 0x100; ++modrm)
- {
- void I386_OPS_BASE::(*ptr)( UINT8 modrm) = x87_invalid;
-
- if (modrm < 0xc0)
- {
- switch ((modrm >> 3) & 0x7)
- {
- case 0x00: ptr = x87_fld_m64real; break;
- case 0x02: ptr = x87_fst_m64real; break;
- case 0x03: ptr = x87_fstp_m64real; break;
- case 0x04: ptr = x87_frstor; break;
- case 0x06: ptr = x87_fsave; break;
- case 0x07: ptr = x87_fstsw_m2byte; break;
- }
- }
- else
- {
- switch (modrm)
- {
- case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7: ptr = x87_ffree; break;
- case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf: ptr = x87_fxch_sti; break;
- case 0xd0: case 0xd1: case 0xd2: case 0xd3: case 0xd4: case 0xd5: case 0xd6: case 0xd7: ptr = x87_fst_sti; break;
- case 0xd8: case 0xd9: case 0xda: case 0xdb: case 0xdc: case 0xdd: case 0xde: case 0xdf: ptr = x87_fstp_sti; break;
- case 0xe0: case 0xe1: case 0xe2: case 0xe3: case 0xe4: case 0xe5: case 0xe6: case 0xe7: ptr = x87_fucom_sti; break;
- case 0xe8: case 0xe9: case 0xea: case 0xeb: case 0xec: case 0xed: case 0xee: case 0xef: ptr = x87_fucomp_sti; break;
- }
- }
-
- cpustate->opcode_table_x87_dd[modrm] = ptr;
- }
-}
-
-
-void I386_OPS_BASE::build_x87_opcode_table_de()
-{
- int modrm = 0;
-
- for (modrm = 0; modrm < 0x100; ++modrm)
- {
- void I386_OPS_BASE::(*ptr)( UINT8 modrm) = x87_invalid;
-
- if (modrm < 0xc0)
- {
- switch ((modrm >> 3) & 0x7)
- {
- case 0x00: ptr = x87_fiadd_m16int; break;
- case 0x01: ptr = x87_fimul_m16int; break;
- case 0x02: ptr = x87_ficom_m16int; break;
- case 0x03: ptr = x87_ficomp_m16int; break;
- case 0x04: ptr = x87_fisub_m16int; break;
- case 0x05: ptr = x87_fisubr_m16int; break;
- case 0x06: ptr = x87_fidiv_m16int; break;
- case 0x07: ptr = x87_fidivr_m16int; break;
- }
- }
- else
- {
- switch (modrm)
- {
- case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7: ptr = x87_faddp; break;
- case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf: ptr = x87_fmulp; break;
- case 0xd9: ptr = x87_fcompp; break;
- case 0xe0: case 0xe1: case 0xe2: case 0xe3: case 0xe4: case 0xe5: case 0xe6: case 0xe7: ptr = x87_fsubrp; break;
- case 0xe8: case 0xe9: case 0xea: case 0xeb: case 0xec: case 0xed: case 0xee: case 0xef: ptr = x87_fsubp; break;
- case 0xf0: case 0xf1: case 0xf2: case 0xf3: case 0xf4: case 0xf5: case 0xf6: case 0xf7: ptr = x87_fdivrp; break;
- case 0xf8: case 0xf9: case 0xfa: case 0xfb: case 0xfc: case 0xfd: case 0xfe: case 0xff: ptr = x87_fdivp; break;
- }
- }
-
- cpustate->opcode_table_x87_de[modrm] = ptr;
- }
-}
-
-
-void I386_OPS_BASE::build_x87_opcode_table_df()
-{
- int modrm = 0;
-
- for (modrm = 0; modrm < 0x100; ++modrm)
- {
- void I386_OPS_BASE::(*ptr)(UINT8 modrm) = x87_invalid;
-
- if (modrm < 0xc0)
- {
- switch ((modrm >> 3) & 0x7)
- {
- case 0x00: ptr = x87_fild_m16int; break;
- case 0x02: ptr = x87_fist_m16int; break;
- case 0x03: ptr = x87_fistp_m16int; break;
- case 0x04: ptr = x87_fbld; break;
- case 0x05: ptr = x87_fild_m64int; break;
- case 0x06: ptr = x87_fbstp; break;
- case 0x07: ptr = x87_fistp_m64int; break;
- }
- }
- else
- {
- switch (modrm)
- {
- case 0xe0: ptr = x87_fstsw_ax; break;
- case 0xe8: case 0xe9: case 0xea: case 0xeb: case 0xec: case 0xed: case 0xee: case 0xef: ptr = x87_fucomip_sti; break;
- case 0xf0: case 0xf1: case 0xf2: case 0xf3: case 0xf4: case 0xf5: case 0xf6: case 0xf7: ptr = x87_fcomip_sti; break;
- }
- }
-
- cpustate->opcode_table_x87_df[modrm] = ptr;
- }
-}
-
-void I386_OPS_BASE::build_x87_opcode_table()
-{
- build_x87_opcode_table_d8();
- build_x87_opcode_table_d9();
- build_x87_opcode_table_da();
- build_x87_opcode_table_db();
- build_x87_opcode_table_dc();
- build_x87_opcode_table_dd();
- build_x87_opcode_table_de();
- build_x87_opcode_table_df();
-}