diff --git a/include/cpu.h b/include/cpu.h index 8677340b0..06f41572b 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -358,6 +358,15 @@ struct TSS_32 { uint32_t ldt; /* The local descriptor table */ } GCC_ATTRIBUTE(packed); +/* Last prefix encountered, needed for Pentium III "mandatory opcode prefixes" needed to differentiate SSE instructions given the opcode. + * Keeping it small and sequential should help your C++ compiler optimize the switch statement you're probably going to use in the normal core code. */ +enum { + MP_NONE=0, + MP_66, + MP_F2, + MP_F3 +}; + #ifdef _MSC_VER #pragma pack() #endif diff --git a/src/cpu/core_normal.cpp b/src/cpu/core_normal.cpp index 27e53fc27..936831e8d 100644 --- a/src/cpu/core_normal.cpp +++ b/src/cpu/core_normal.cpp @@ -100,6 +100,10 @@ Bitu cycle_count; core.rep_zero=_ZERO; \ goto restart_opcode; +#define REMEMBER_PREFIX(_x) last_prefix = (_x) + +static uint8_t last_prefix; + typedef PhysPt (*GetEAHandler)(void); static const uint32_t AddrMaskTable[2]={0x0000ffffu,0xffffffffu}; @@ -167,6 +171,7 @@ Bits CPU_Core_Normal_Run(void) { while (CPU_Cycles-->0) { LOADIP; + last_prefix=MP_NONE; core.opcode_index=cpu.code.big*(Bitu)0x200u; core.prefixes=cpu.code.big; core.ea_table=&EATable[cpu.code.big*256u]; diff --git a/src/cpu/core_normal/prefix_none.h b/src/cpu/core_normal/prefix_none.h index 97231a9c2..4957e8a7c 100644 --- a/src/cpu/core_normal/prefix_none.h +++ b/src/cpu/core_normal/prefix_none.h @@ -337,6 +337,7 @@ goto illegal_opcode; #endif #if CPU_CORE >= CPU_ARCHTYPE_386 + REMEMBER_PREFIX(MP_66); core.opcode_index=(cpu.code.big^0x1u)*0x200u; goto restart_opcode; #endif @@ -1282,9 +1283,11 @@ goto opcode_f0; #endif CASE_B(0xf2) /* REPNZ */ + REMEMBER_PREFIX(MP_F2); DO_PREFIX_REP(false); break; CASE_B(0xf3) /* REPZ */ + REMEMBER_PREFIX(MP_F3); DO_PREFIX_REP(true); break; CASE_B(0xf4) /* HLT */ diff --git a/src/cpu/core_normal_286.cpp b/src/cpu/core_normal_286.cpp index ed1cf84f8..e34e35346 100644 --- a/src/cpu/core_normal_286.cpp +++ b/src/cpu/core_normal_286.cpp @@ -119,6 +119,8 @@ extern Bitu cycle_count; core.rep_zero=_ZERO; \ goto restart_opcode; +#define REMEMBER_PREFIX(_x) + typedef PhysPt (*GetEAHandler)(void); static const uint32_t AddrMaskTable[2]={0x0000ffffu,0x0000ffffu}; diff --git a/src/cpu/core_normal_8086.cpp b/src/cpu/core_normal_8086.cpp index 40d36937d..c9bb7db38 100644 --- a/src/cpu/core_normal_8086.cpp +++ b/src/cpu/core_normal_8086.cpp @@ -149,6 +149,8 @@ extern Bitu cycle_count; core.rep_zero=_ZERO; \ goto restart_opcode; +#define REMEMBER_PREFIX(_x) + typedef PhysPt (*GetEAHandler)(void); static const uint32_t AddrMaskTable[2]={0x0000ffffu,0x0000ffffu}; diff --git a/src/cpu/core_prefetch.cpp b/src/cpu/core_prefetch.cpp index 5962d1733..b6dcecbbf 100644 --- a/src/cpu/core_prefetch.cpp +++ b/src/cpu/core_prefetch.cpp @@ -98,6 +98,10 @@ extern Bitu cycle_count; core.rep_zero=_ZERO; \ goto restart_opcode; +#define REMEMBER_PREFIX(_x) last_prefix = (_x) + +static uint8_t last_prefix; + typedef PhysPt (*GetEAHandler)(void); static const uint32_t AddrMaskTable[2]={0x0000ffffu,0xffffffffu}; @@ -203,6 +207,7 @@ Bits CPU_Core_Prefetch_Run(void) { invalidate_pq=false; } LOADIP; + last_prefix=MP_NONE; core.opcode_index=cpu.code.big*(Bitu)0x200u; core.prefixes=cpu.code.big; core.ea_table=&EATable[cpu.code.big*256u]; diff --git a/src/cpu/core_prefetch_286.cpp b/src/cpu/core_prefetch_286.cpp index f9b094149..b2b847b19 100644 --- a/src/cpu/core_prefetch_286.cpp +++ b/src/cpu/core_prefetch_286.cpp @@ -122,6 +122,8 @@ Bits CPU_Core_Prefetch_Trap_Run(void); core.rep_zero=_ZERO; \ goto restart_opcode; +#define REMEMBER_PREFIX(_x) + typedef PhysPt (*GetEAHandler)(void); static const uint32_t AddrMaskTable[2]={0x0000ffffu,0x0000ffffu}; diff --git a/src/cpu/core_prefetch_8086.cpp b/src/cpu/core_prefetch_8086.cpp index cbd4c1c1d..cca2a3201 100644 --- a/src/cpu/core_prefetch_8086.cpp +++ b/src/cpu/core_prefetch_8086.cpp @@ -178,6 +178,8 @@ static struct { #define BaseDS core.base_ds #define BaseSS core.base_ss +#define REMEMBER_PREFIX(_x) + //#define PREFETCH_DEBUG #define MAX_PQ_SIZE 32 diff --git a/src/cpu/core_simple.cpp b/src/cpu/core_simple.cpp index 40396c410..8097cf855 100644 --- a/src/cpu/core_simple.cpp +++ b/src/cpu/core_simple.cpp @@ -85,6 +85,10 @@ extern Bitu cycle_count; core.rep_zero=_ZERO; \ goto restart_opcode; +#define REMEMBER_PREFIX(_x) last_prefix = (_x) + +static uint8_t last_prefix; + typedef PhysPt (*GetEAHandler)(void); static const uint32_t AddrMaskTable[2]={0x0000ffffu,0xffffffffu}; @@ -176,6 +180,7 @@ Bits CPU_Core_Simple_Run(void) { /* Simple core optimizes for non-paged linear memory access and can break (segfault) if beyond end of memory */ if (core.cseip >= safety_limit) break; + last_prefix=MP_NONE; core.opcode_index=cpu.code.big*0x200u; core.prefixes=cpu.code.big; core.ea_table=&EATable[cpu.code.big*256u];