diff --git a/src/cpu/386.c b/src/cpu/386.c index 3a3e36d58..ea29d2570 100644 --- a/src/cpu/386.c +++ b/src/cpu/386.c @@ -134,9 +134,9 @@ static inline void fetch_ea_32_long(uint32_t rmdat) if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) { uint32_t addr = easeg + cpu_state.eaaddr; - if ( readlookup2[addr >> 12] != -1) + if ( readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); - if (writelookup2[addr >> 12] != -1) + if (writelookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); } } @@ -174,9 +174,9 @@ static inline void fetch_ea_16_long(uint32_t rmdat) if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) { uint32_t addr = easeg + cpu_state.eaaddr; - if ( readlookup2[addr >> 12] != -1) + if ( readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); - if (writelookup2[addr >> 12] != -1) + if (writelookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); } } @@ -271,7 +271,7 @@ exec386(int cycs) CS = oldcs; #endif cpu_state.pc = cpu_state.oldpc; - x386_log("Double fault %i\n", ins); + x386_log("Double fault\n"); pmodeint(8, 0); if (cpu_state.abrt) { cpu_state.abrt = 0; diff --git a/src/cpu/386_common.c b/src/cpu/386_common.c index 1800aad71..9324976af 100644 --- a/src/cpu/386_common.c +++ b/src/cpu/386_common.c @@ -65,10 +65,17 @@ uint32_t old_rammask = 0xffffffff; int soft_reset_mask = 0; +int in_smm = 0, smi_line = 0, smi_latched = 0, smm_in_hlt = 0; +int smi_block = 0; +uint32_t smbase = 0x30000; -#define AMD_SYSCALL_EIP (star & 0xFFFFFFFF) -#define AMD_SYSCALL_SB ((star >> 32) & 0xFFFF) -#define AMD_SYSRET_SB ((star >> 48) & 0xFFFF) +uint32_t addr64, addr64_2; +uint32_t addr64a[8], addr64a_2[8]; + + +#define AMD_SYSCALL_EIP (msr.star & 0xFFFFFFFF) +#define AMD_SYSCALL_SB ((msr.star >> 32) & 0xFFFF) +#define AMD_SYSRET_SB ((msr.star >> 48) & 0xFFFF) /* These #define's and enum have been borrowed from Bochs. */ @@ -1312,7 +1319,7 @@ x86_int(int num) else { addr = (num << 2) + idt.base; - if ((num << 2) + 3 > idt.limit) { + if ((num << 2UL) + 3UL > idt.limit) { if (idt.limit < 35) { cpu_state.abrt = 0; softresetx86(); @@ -1363,7 +1370,7 @@ x86_int_sw(int num) else { addr = (num << 2) + idt.base; - if ((num << 2) + 3 > idt.limit) + if ((num << 2UL) + 3UL > idt.limit) x86_int(0x0d); else { if (stack32) { @@ -1447,7 +1454,7 @@ x86illegal() int -checkio(int port) +checkio(uint32_t port) { uint16_t t; uint8_t d; @@ -1459,7 +1466,7 @@ checkio(int port) if (cpu_state.abrt) return 0; - if ((t + (port >> 3)) > tr.limit) + if ((t + (port >> 3UL)) > tr.limit) return 1; cpl_override = 1; @@ -1599,7 +1606,7 @@ sysenter(uint32_t fetchdat) return cpu_state.abrt; } - if (!(cs_msr & 0xFFF8)) { + if (!(msr.sysenter_cs & 0xFFF8)) { #ifdef ENABLE_386_COMMON_LOG x386_common_log("SYSENTER: CS MSR is zero"); #endif @@ -1611,7 +1618,7 @@ sysenter(uint32_t fetchdat) x386_common_log("SYSENTER started:\n"); x386_common_log(" CS %04X/%i: b=%08X l=%08X (%08X-%08X) a=%02X%02X; EIP=%08X\n", cpu_state.seg_cs.seg, !!cpu_state.seg_cs.checked, cpu_state.seg_cs.base, cpu_state.seg_cs.limit, cpu_state.seg_cs.limit_low, cpu_state.seg_cs.limit_high, cpu_state.seg_cs.ar_high, cpu_state.seg_cs.access, cpu_state.pc); x386_common_log(" SS %04X/%i: b=%08X l=%08X (%08X-%08X) a=%02X%02X; ESP=%08X\n", cpu_state.seg_ss.seg, !!cpu_state.seg_ss.checked, cpu_state.seg_ss.base, cpu_state.seg_ss.limit, cpu_state.seg_ss.limit_low, cpu_state.seg_ss.limit_high, cpu_state.seg_ss.ar_high, cpu_state.seg_ss.access, ESP); - x386_common_log(" Misc. : MSR (CS/ESP/EIP)=%04X/%08X/%08X pccache=%08X/%08X\n", cs_msr, esp_msr, eip_msr, pccache, pccache2); + x386_common_log(" Misc. : MSR (CS/ESP/EIP)=%04X/%08X/%08X pccache=%08X/%08X\n", msr.sysenter_cs, msr.sysenter_esp, msr.sysenter_eip, pccache, pccache2); x386_common_log(" EFLAGS=%04X%04X/%i 32=%i/%i ECX=%08X EDX=%08X abrt=%02X\n", cpu_state.eflags, cpu_state.flags, !!trap, !!use32, !!stack32, ECX, EDX, cpu_state.abrt); #endif @@ -1623,10 +1630,10 @@ sysenter(uint32_t fetchdat) oldcs = CS; #endif cpu_state.oldpc = cpu_state.pc; - ESP = esp_msr; - cpu_state.pc = eip_msr; + ESP = msr.sysenter_esp; + cpu_state.pc = msr.sysenter_eip; - cpu_state.seg_cs.seg = (cs_msr & 0xfffc); + cpu_state.seg_cs.seg = (msr.sysenter_cs & 0xfffc); cpu_state.seg_cs.base = 0; cpu_state.seg_cs.limit_low = 0; cpu_state.seg_cs.limit = 0xffffffff; @@ -1637,7 +1644,7 @@ sysenter(uint32_t fetchdat) cpu_state.seg_cs.checked = 1; oldcpl = 0; - cpu_state.seg_ss.seg = ((cs_msr + 8) & 0xfffc); + cpu_state.seg_ss.seg = ((msr.sysenter_cs + 8) & 0xfffc); cpu_state.seg_ss.base = 0; cpu_state.seg_ss.limit_low = 0; cpu_state.seg_ss.limit = 0xffffffff; @@ -1661,7 +1668,7 @@ sysenter(uint32_t fetchdat) x386_common_log("SYSENTER completed:\n"); x386_common_log(" CS %04X/%i: b=%08X l=%08X (%08X-%08X) a=%02X%02X; EIP=%08X\n", cpu_state.seg_cs.seg, !!cpu_state.seg_cs.checked, cpu_state.seg_cs.base, cpu_state.seg_cs.limit, cpu_state.seg_cs.limit_low, cpu_state.seg_cs.limit_high, cpu_state.seg_cs.ar_high, cpu_state.seg_cs.access, cpu_state.pc); x386_common_log(" SS %04X/%i: b=%08X l=%08X (%08X-%08X) a=%02X%02X; ESP=%08X\n", cpu_state.seg_ss.seg, !!cpu_state.seg_ss.checked, cpu_state.seg_ss.base, cpu_state.seg_ss.limit, cpu_state.seg_ss.limit_low, cpu_state.seg_ss.limit_high, cpu_state.seg_ss.ar_high, cpu_state.seg_ss.access, ESP); - x386_common_log(" Misc. : MSR (CS/ESP/EIP)=%04X/%08X/%08X pccache=%08X/%08X\n", cs_msr, esp_msr, eip_msr, pccache, pccache2); + x386_common_log(" Misc. : MSR (CS/ESP/EIP)=%04X/%08X/%08X pccache=%08X/%08X\n", msr.sysenter_cs, msr.sysenter_esp, msr.sysenter_eip, pccache, pccache2); x386_common_log(" EFLAGS=%04X%04X/%i 32=%i/%i ECX=%08X EDX=%08X abrt=%02X\n", cpu_state.eflags, cpu_state.flags, !!trap, !!use32, !!stack32, ECX, EDX, cpu_state.abrt); #endif @@ -1676,7 +1683,7 @@ sysexit(uint32_t fetchdat) x386_common_log("SYSEXIT called\n"); #endif - if (!(cs_msr & 0xFFF8)) { + if (!(msr.sysenter_cs & 0xFFF8)) { #ifdef ENABLE_386_COMMON_LOG x386_common_log("SYSEXIT: CS MSR is zero"); #endif @@ -1704,7 +1711,7 @@ sysexit(uint32_t fetchdat) x386_common_log("SYSEXIT start:\n"); x386_common_log(" CS %04X/%i: b=%08X l=%08X (%08X-%08X) a=%02X%02X; EIP=%08X\n", cpu_state.seg_cs.seg, !!cpu_state.seg_cs.checked, cpu_state.seg_cs.base, cpu_state.seg_cs.limit, cpu_state.seg_cs.limit_low, cpu_state.seg_cs.limit_high, cpu_state.seg_cs.ar_high, cpu_state.seg_cs.access, cpu_state.pc); x386_common_log(" SS %04X/%i: b=%08X l=%08X (%08X-%08X) a=%02X%02X; ESP=%08X\n", cpu_state.seg_ss.seg, !!cpu_state.seg_ss.checked, cpu_state.seg_ss.base, cpu_state.seg_ss.limit, cpu_state.seg_ss.limit_low, cpu_state.seg_ss.limit_high, cpu_state.seg_ss.ar_high, cpu_state.seg_ss.access, ESP); - x386_common_log(" Misc. : MSR (CS/ESP/EIP)=%04X/%08X/%08X pccache=%08X/%08X\n", cs_msr, esp_msr, eip_msr, pccache, pccache2); + x386_common_log(" Misc. : MSR (CS/ESP/EIP)=%04X/%08X/%08X pccache=%08X/%08X\n", msr.sysenter_cs, msr.sysenter_esp, msr.sysenter_eip, pccache, pccache2); x386_common_log(" EFLAGS=%04X%04X/%i 32=%i/%i ECX=%08X EDX=%08X abrt=%02X\n", cpu_state.eflags, cpu_state.flags, !!trap, !!use32, !!stack32, ECX, EDX, cpu_state.abrt); #endif @@ -1715,7 +1722,7 @@ sysexit(uint32_t fetchdat) ESP = ECX; cpu_state.pc = EDX; - cpu_state.seg_cs.seg = (((cs_msr + 16) & 0xfffc) | 3); + cpu_state.seg_cs.seg = (((msr.sysenter_cs + 16) & 0xfffc) | 3); cpu_state.seg_cs.base = 0; cpu_state.seg_cs.limit_low = 0; cpu_state.seg_cs.limit = 0xffffffff; @@ -1726,7 +1733,7 @@ sysexit(uint32_t fetchdat) cpu_state.seg_cs.checked = 1; oldcpl = 3; - cpu_state.seg_ss.seg = (((cs_msr + 24) & 0xfffc) | 3); + cpu_state.seg_ss.seg = (((msr.sysenter_cs + 24) & 0xfffc) | 3); cpu_state.seg_ss.base = 0; cpu_state.seg_ss.limit_low = 0; cpu_state.seg_ss.limit = 0xffffffff; @@ -1751,7 +1758,7 @@ sysexit(uint32_t fetchdat) x386_common_log("SYSEXIT completed:\n"); x386_common_log(" CS %04X/%i: b=%08X l=%08X (%08X-%08X) a=%02X%02X; EIP=%08X\n", cpu_state.seg_cs.seg, !!cpu_state.seg_cs.checked, cpu_state.seg_cs.base, cpu_state.seg_cs.limit, cpu_state.seg_cs.limit_low, cpu_state.seg_cs.limit_high, cpu_state.seg_cs.ar_high, cpu_state.seg_cs.access, cpu_state.pc); x386_common_log(" SS %04X/%i: b=%08X l=%08X (%08X-%08X) a=%02X%02X; ESP=%08X\n", cpu_state.seg_ss.seg, !!cpu_state.seg_ss.checked, cpu_state.seg_ss.base, cpu_state.seg_ss.limit, cpu_state.seg_ss.limit_low, cpu_state.seg_ss.limit_high, cpu_state.seg_ss.ar_high, cpu_state.seg_ss.access, ESP); - x386_common_log(" Misc. : MSR (CS/ESP/EIP)=%04X/%08X/%08X pccache=%08X/%08X\n", cs_msr, esp_msr, eip_msr, pccache, pccache2); + x386_common_log(" Misc. : MSR (CS/ESP/EIP)=%04X/%08X/%08X pccache=%08X/%08X\n", msr.sysenter_cs, msr.sysenter_esp, msr.sysenter_eip, pccache, pccache2); x386_common_log(" EFLAGS=%04X%04X/%i 32=%i/%i ECX=%08X EDX=%08X abrt=%02X\n", cpu_state.eflags, cpu_state.flags, !!trap, !!use32, !!stack32, ECX, EDX, cpu_state.abrt); #endif diff --git a/src/cpu/386_common.h b/src/cpu/386_common.h index 61f68b693..4d182d4c0 100644 --- a/src/cpu/386_common.h +++ b/src/cpu/386_common.h @@ -15,38 +15,37 @@ * Copyright 2008-2019 Sarah Walker. * Copyright 2016-2019 Miran Grca. */ - #ifndef _386_COMMON_H_ #define _386_COMMON_H_ #include -#define readmemb_n(s,a,b) ((readlookup2[(uint32_t)((s)+(a))>>12]==LOOKUP_INV || (s)==0xFFFFFFFF)?readmembl_no_mmut((s)+(a),b): *(uint8_t *)(readlookup2[(uint32_t)((s)+(a))>>12] + (uintptr_t)((s) + (a))) ) -#define readmemw_n(s,a,b) ((readlookup2[(uint32_t)((s)+(a))>>12]==LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1))?readmemwl_no_mmut((s)+(a),b):*(uint16_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a)))) -#define readmeml_n(s,a,b) ((readlookup2[(uint32_t)((s)+(a))>>12]==LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3))?readmemll_no_mmut((s)+(a),b):*(uint32_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a)))) -#define readmemb(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==LOOKUP_INV || (s)==0xFFFFFFFF)?readmembl((s)+(a)): *(uint8_t *)(readlookup2[(uint32_t)((s)+(a))>>12] + (uintptr_t)((s) + (a))) ) -#define readmemw(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1))?readmemwl((s)+(a)):*(uint16_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a)))) -#define readmeml(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3))?readmemll((s)+(a)):*(uint32_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a)))) -#define readmemq(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 7))?readmemql((s)+(a)):*(uint64_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uintptr_t)((s)+(a)))) +#define readmemb_n(s,a,b) ((readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF)?readmembl_no_mmut((s)+(a),b): *(uint8_t *)(readlookup2[(uint32_t)((s)+(a))>>12] + (uintptr_t)((s) + (a))) ) +#define readmemw_n(s,a,b) ((readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1))?readmemwl_no_mmut((s)+(a),b):*(uint16_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a)))) +#define readmeml_n(s,a,b) ((readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3))?readmemll_no_mmut((s)+(a),b):*(uint32_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a)))) +#define readmemb(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF)?readmembl((s)+(a)): *(uint8_t *)(readlookup2[(uint32_t)((s)+(a))>>12] + (uintptr_t)((s) + (a))) ) +#define readmemw(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1))?readmemwl((s)+(a)):*(uint16_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a)))) +#define readmeml(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3))?readmemll((s)+(a)):*(uint32_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a)))) +#define readmemq(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 7))?readmemql((s)+(a)):*(uint64_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uintptr_t)((s)+(a)))) -#define writememb_n(s,a,b,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==LOOKUP_INV || (s)==0xFFFFFFFF) writemembl_no_mmut((s)+(a),b,v); else *(uint8_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uintptr_t)((s) + (a))) = v -#define writememw_n(s,a,b,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1)) writememwl_no_mmut((s)+(a),b,v); else *(uint16_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uintptr_t)((s) + (a))) = v -#define writememl_n(s,a,b,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3)) writememll_no_mmut((s)+(a),b,v); else *(uint32_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uintptr_t)((s) + (a))) = v -#define writememb(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==LOOKUP_INV || (s)==0xFFFFFFFF) writemembl((s)+(a),v); else *(uint8_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uintptr_t)((s) + (a))) = v -#define writememw(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1)) writememwl((s)+(a),v); else *(uint16_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uintptr_t)((s) + (a))) = v -#define writememl(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3)) writememll((s)+(a),v); else *(uint32_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uintptr_t)((s) + (a))) = v -#define writememq(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 7)) writememql((s)+(a),v); else *(uint64_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uintptr_t)((s) + (a))) = v +#define writememb_n(s,a,b,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF) writemembl_no_mmut((s)+(a),b,v); else *(uint8_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uintptr_t)((s) + (a))) = v +#define writememw_n(s,a,b,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1)) writememwl_no_mmut((s)+(a),b,v); else *(uint16_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uintptr_t)((s) + (a))) = v +#define writememl_n(s,a,b,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3)) writememll_no_mmut((s)+(a),b,v); else *(uint32_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uintptr_t)((s) + (a))) = v +#define writememb(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF) writemembl((s)+(a),v); else *(uint8_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uintptr_t)((s) + (a))) = v +#define writememw(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1)) writememwl((s)+(a),v); else *(uint16_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uintptr_t)((s) + (a))) = v +#define writememl(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3)) writememll((s)+(a),v); else *(uint32_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uintptr_t)((s) + (a))) = v +#define writememq(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 7)) writememql((s)+(a),v); else *(uint64_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uintptr_t)((s) + (a))) = v -#define do_mmut_rb(s,a,b) if (readlookup2[(uint32_t)((s)+(a))>>12]==LOOKUP_INV || (s)==0xFFFFFFFF) do_mmutranslate((s)+(a), b, 1, 0) -#define do_mmut_rw(s,a,b) if (readlookup2[(uint32_t)((s)+(a))>>12]==LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1)) do_mmutranslate((s)+(a), b, 2, 0) -#define do_mmut_rl(s,a,b) if (readlookup2[(uint32_t)((s)+(a))>>12]==LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3)) do_mmutranslate((s)+(a), b, 4, 0) +#define do_mmut_rb(s,a,b) if (readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF) do_mmutranslate((s)+(a), b, 1, 0) +#define do_mmut_rw(s,a,b) if (readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1)) do_mmutranslate((s)+(a), b, 2, 0) +#define do_mmut_rl(s,a,b) if (readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3)) do_mmutranslate((s)+(a), b, 4, 0) -#define do_mmut_wb(s,a,b) if (writelookup2[(uint32_t)((s)+(a))>>12]==LOOKUP_INV || (s)==0xFFFFFFFF) do_mmutranslate((s)+(a), b, 1, 1) -#define do_mmut_ww(s,a,b) if (writelookup2[(uint32_t)((s)+(a))>>12]==LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1)) do_mmutranslate((s)+(a), b, 2, 1) -#define do_mmut_wl(s,a,b) if (writelookup2[(uint32_t)((s)+(a))>>12]==LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3)) do_mmutranslate((s)+(a), b, 4, 1) +#define do_mmut_wb(s,a,b) if (writelookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF) do_mmutranslate((s)+(a), b, 1, 1) +#define do_mmut_ww(s,a,b) if (writelookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1)) do_mmutranslate((s)+(a), b, 2, 1) +#define do_mmut_wl(s,a,b) if (writelookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3)) do_mmutranslate((s)+(a), b, 4, 1) -int checkio(int port); +int checkio(uint32_t port); #define check_io_perm(port) if (msw&1 && ((CPL > IOPL) || (cpu_state.eflags&VM_FLAG))) \ diff --git a/src/cpu/386_dynarec.c b/src/cpu/386_dynarec.c index 4a8b3637e..ab1572c85 100644 --- a/src/cpu/386_dynarec.c +++ b/src/cpu/386_dynarec.c @@ -121,9 +121,9 @@ static __inline void fetch_ea_32_long(uint32_t rmdat) if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) { uint32_t addr = easeg + cpu_state.eaaddr; - if ( readlookup2[addr >> 12] != -1) + if ( readlookup2[addr >> 12] != (uintptr_t) -1) eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); - if (writelookup2[addr >> 12] != -1) + if (writelookup2[addr >> 12] != (uintptr_t) -1) eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); } } @@ -161,9 +161,9 @@ static __inline void fetch_ea_16_long(uint32_t rmdat) if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) { uint32_t addr = easeg + cpu_state.eaaddr; - if ( readlookup2[addr >> 12] != -1) + if (readlookup2[addr >> 12] != (uintptr_t) -1) eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); - if (writelookup2[addr >> 12] != -1) + if (writelookup2[addr >> 12] != (uintptr_t) -1) eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); } } diff --git a/src/cpu/386_dynarec_ops.c b/src/cpu/386_dynarec_ops.c index 9854f24bf..ef18c2558 100644 --- a/src/cpu/386_dynarec_ops.c +++ b/src/cpu/386_dynarec_ops.c @@ -33,9 +33,9 @@ static __inline void fetch_ea_32_long(uint32_t rmdat) if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) { uint32_t addr = easeg + cpu_state.eaaddr; - if ( readlookup2[addr >> 12] != -1) + if ( readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); - if (writelookup2[addr >> 12] != -1) + if (writelookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); } } @@ -47,9 +47,9 @@ static __inline void fetch_ea_16_long(uint32_t rmdat) if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) { uint32_t addr = easeg + cpu_state.eaaddr; - if ( readlookup2[addr >> 12] != -1) + if ( readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); - if (writelookup2[addr >> 12] != -1) + if (writelookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); } } diff --git a/src/cpu/808x.c b/src/cpu/808x.c index c14a2b604..329ebe25f 100644 --- a/src/cpu/808x.c +++ b/src/cpu/808x.c @@ -35,43 +35,9 @@ #include <86box/ppi.h> #include <86box/timer.h> -/* The opcode of the instruction currently being executed. */ -uint8_t opcode; - -/* The tables to speed up the setting of the Z, N, and P cpu_state.flags. */ -uint8_t znptable8[256]; -uint16_t znptable16[65536]; - -/* A 16-bit zero, needed because some speed-up arrays contain pointers to it. */ -uint16_t zero = 0; - -/* MOD and R/M stuff. */ -uint16_t *mod1add[2][8]; -uint32_t *mod1seg[8]; -uint32_t rmdat; - -/* XT CPU multiplier. */ -uint64_t xt_cpu_multi; - /* Is the CPU 8088 or 8086. */ int is8086 = 0; -/* Variables for handling the non-maskable interrupts. */ -int nmi = 0, nmi_auto_clear = 0; - -/* Was the CPU ever reset? */ -int x86_was_reset = 0; - -/* Amount of instructions executed - used to calculate the % shown in the title bar. */ -int ins = 0; - -/* Is the TRAP flag on? */ -int trap = 0; - -/* The current effective address's segment. */ -uint32_t easeg; - - /* The prefetch queue (4 bytes for 8088, 6 bytes for 8086). */ static uint8_t pfq[6]; @@ -148,50 +114,6 @@ x808x_log(const char *fmt, ...) va_end(ap); } } - - -void -dumpregs(int force) -{ - int c; - char *seg_names[4] = { "ES", "CS", "SS", "DS" }; - - /* Only dump when needed, and only once.. */ - if (indump || (!force && !dump_on_exit)) - return; - - x808x_log("EIP=%08X CS=%04X DS=%04X ES=%04X SS=%04X FLAGS=%04X\n", - cpu_state.pc, CS, DS, ES, SS, cpu_state.flags); - x808x_log("Old CS:EIP: %04X:%08X; %i ins\n", oldcs, cpu_state.oldpc, ins); - for (c = 0; c < 4; c++) { - x808x_log("%s : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n", - seg_names[c], _opseg[c]->base, _opseg[c]->limit, - _opseg[c]->access, _opseg[c]->limit_low, _opseg[c]->limit_high); - } - if (is386) { - x808x_log("FS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n", - seg_fs, cpu_state.seg_fs.limit, cpu_state.seg_fs.access, cpu_state.seg_fs.limit_low, cpu_state.seg_fs.limit_high); - x808x_log("GS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n", - gs, cpu_state.seg_gs.limit, cpu_state.seg_gs.access, cpu_state.seg_gs.limit_low, cpu_state.seg_gs.limit_high); - x808x_log("GDT : base=%06X limit=%04X\n", gdt.base, gdt.limit); - x808x_log("LDT : base=%06X limit=%04X\n", ldt.base, ldt.limit); - x808x_log("IDT : base=%06X limit=%04X\n", idt.base, idt.limit); - x808x_log("TR : base=%06X limit=%04X\n", tr.base, tr.limit); - x808x_log("386 in %s mode: %i-bit data, %-i-bit stack\n", - (msw & 1) ? ((cpu_state.eflags & VM_FLAG) ? "V86" : "protected") : "real", - (use32) ? 32 : 16, (stack32) ? 32 : 16); - x808x_log("CR0=%08X CR2=%08X CR3=%08X CR4=%08x\n", cr0, cr2, cr3, cr4); - x808x_log("EAX=%08X EBX=%08X ECX=%08X EDX=%08X\nEDI=%08X ESI=%08X EBP=%08X ESP=%08X\n", - EAX, EBX, ECX, EDX, EDI, ESI, EBP, ESP); - } else { - x808x_log("808x/286 in %s mode\n", (msw & 1) ? "protected" : "real"); - x808x_log("AX=%04X BX=%04X CX=%04X DX=%04X DI=%04X SI=%04X BP=%04X SP=%04X\n", - AX, BX, CX, DX, DI, SI, BP, SP); - } - x808x_log("Entries in readlookup : %i writelookup : %i\n", readlnum, writelnum); - x87_dumpregs(); - indump = 0; -} #else #define x808x_log(fmt, ...) #endif @@ -602,6 +524,63 @@ pfq_clear() } +static void +load_cs(uint16_t seg) +{ + cpu_state.seg_cs.base = seg << 4; + cpu_state.seg_cs.seg = seg & 0xffff; +} + + +static void +load_seg(uint16_t seg, x86seg *s) +{ + s->base = seg << 4; + s->seg = seg & 0xffff; +} + + +void +reset_808x(int hard) +{ + biu_cycles = 0; + in_rep = 0; + in_lock = 0; + completed = 1; + repeating = 0; + clear_lock = 0; + refresh = 0; + ovr_seg = NULL; + + if (hard) { + opseg[0] = &es; + opseg[1] = &cs; + opseg[2] = &ss; + opseg[3] = &ds; + _opseg[0] = &cpu_state.seg_es; + _opseg[1] = &cpu_state.seg_cs; + _opseg[2] = &cpu_state.seg_ss; + _opseg[3] = &cpu_state.seg_ds; + + pfq_size = (is8086) ? 6 : 4; + pfq_clear(); + } + + if (AT) { + load_cs(0xF000); + cpu_state.pc = 0xFFF0; + rammask = cpu_16bitbus ? 0xFFFFFF : 0xFFFFFFFF; + } else { + load_cs(0xFFFF); + cpu_state.pc = 0; + rammask = 0xfffff; + } + + prefetching = 1; + cpu_alu_op = 0; +} + + static void set_ip(uint16_t new_ip) { pfq_ip = cpu_state.pc = new_ip; @@ -616,45 +595,6 @@ refreshread(void) { } -/* Preparation of the various arrays needed to speed up the MOD and R/M work. */ -static void -makemod1table(void) -{ - mod1add[0][0] = &BX; - mod1add[0][1] = &BX; - mod1add[0][2] = &BP; - mod1add[0][3] = &BP; - mod1add[0][4] = &SI; - mod1add[0][5] = &DI; - mod1add[0][6] = &BP; - mod1add[0][7] = &BX; - mod1add[1][0] = &SI; - mod1add[1][1] = &DI; - mod1add[1][2] = &SI; - mod1add[1][3] = &DI; - mod1add[1][4] = &zero; - mod1add[1][5] = &zero; - mod1add[1][6] = &zero; - mod1add[1][7] = &zero; - mod1seg[0] = &ds; - mod1seg[1] = &ds; - mod1seg[2] = &ss; - mod1seg[3] = &ss; - mod1seg[4] = &ds; - mod1seg[5] = &ds; - mod1seg[6] = &ss; - mod1seg[7] = &ds; - opseg[0] = &es; - opseg[1] = &cs; - opseg[2] = &ss; - opseg[3] = &ds; - _opseg[0] = &cpu_state.seg_es; - _opseg[1] = &cpu_state.seg_cs; - _opseg[2] = &cpu_state.seg_ss; - _opseg[3] = &cpu_state.seg_ds; -} - - static uint16_t get_accum(int bits) { @@ -865,176 +805,6 @@ seteaq(uint64_t val) #undef FPU_8087 -/* Prepare the ZNP table needed to speed up the setting of the Z, N, and P cpu_state.flags. */ -static void -makeznptable(void) -{ - int c, d, e; - for (c = 0; c < 256; c++) { - d = 0; - for (e = 0; e < 8; e++) { - if (c & (1 << e)) - d++; - } - if (d & 1) - znptable8[c] = 0; - else - znptable8[c] = P_FLAG; -#ifdef ENABLE_808X_LOG - if (c == 0xb1) - x808x_log("znp8 b1 = %i %02X\n", d, znptable8[c]); -#endif - if (!c) - znptable8[c] |= Z_FLAG; - if (c & 0x80) - znptable8[c] |= N_FLAG; - } - - for (c = 0; c < 65536; c++) { - d = 0; - for (e = 0; e < 8; e++) { - if (c & (1 << e)) - d++; - } - if (d & 1) - znptable16[c] = 0; - else - znptable16[c] = P_FLAG; -#ifdef ENABLE_808X_LOG - if (c == 0xb1) - x808x_log("znp16 b1 = %i %02X\n", d, znptable16[c]); - if (c == 0x65b1) - x808x_log("znp16 65b1 = %i %02X\n", d, znptable16[c]); -#endif - if (!c) - znptable16[c] |= Z_FLAG; - if (c & 0x8000) - znptable16[c] |= N_FLAG; - } -} - - -static void load_cs(uint16_t seg) -{ - cpu_state.seg_cs.base = seg << 4; - CS = seg & 0xffff; -} - - -/* Common reset function. */ -static void -reset_common(int hard) -{ - /* Make sure to gracefully leave SMM. */ - if (in_smm) - leave_smm(); - - biu_cycles = 0; - in_rep = 0; - in_lock = 0; - completed = 1; - repeating = 0; - clear_lock = 0; - refresh = 0; - - if (hard) { -#ifdef ENABLE_808X_LOG - x808x_log("x86 reset\n"); -#endif - ins = 0; - } - use32 = 0; - cpu_cur_status = 0; - stack32 = 0; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - msw = 0; - if (hascache) - cr0 = 1 << 30; - else - cr0 = 0; - cpu_cache_int_enabled = 0; - cpu_update_waitstates(); - cr4 = 0; - cpu_state.eflags = 0; - cgate32 = 0; - if (AT) { - load_cs(0xF000); - cpu_state.pc = 0xFFF0; - rammask = cpu_16bitbus ? 0xFFFFFF : 0xFFFFFFFF; - } else { - load_cs(0xFFFF); - cpu_state.pc = 0; - rammask = 0xfffff; - } - idt.base = 0; - idt.limit = is386 ? 0x03FF : 0xFFFF; - cpu_state.flags = 2; - trap = 0; - ovr_seg = NULL; - - EAX = EBX = ECX = EDX = ESI = EDI = EBP = ESP = 0; - - if (hard) { - makeznptable(); - resetreadlookup(); - makemod1table(); - pfq_clear(); - cpu_set_edx(); - mmu_perm = 4; - pfq_size = (is8086) ? 6 : 4; - } - x86seg_reset(); -#ifdef USE_DYNAREC - if (hard) - codegen_reset(); -#endif - if (!hard) - flushmmucache(); - x86_was_reset = 1; - cpu_alt_reset = 0; - - prefetching = 1; - - cpu_ven_reset(); - - cpu_alu_op = 0; - - in_smm = smi_latched = 0; - smi_line = smm_in_hlt = 0; - smi_block = 0; - - if (hard) { - smbase = is_am486 ? 0x00060000 : 0x00030000; - ppi_reset(); - } - in_sys = 0; - - shadowbios = shadowbios_write = 0; - alt_access = cpu_end_block_after_ins = 0; -} - - -/* Hard reset. */ -void -resetx86(void) -{ - reset_common(1); - - soft_reset_mask = 0; -} - - -/* Soft reset. */ -void -softresetx86(void) -{ - if (soft_reset_mask) - return; - - reset_common(0); -} - - /* Pushes a word to the stack. */ static void push(uint16_t *val) @@ -1867,7 +1637,7 @@ execx86(int cycs) load_cs(pop()); pfq_pos = 0; } else - loadseg(pop(), _opseg[(opcode >> 3) & 0x03]); + load_seg(pop(), _opseg[(opcode >> 3) & 0x03]); wait(1, 0); /* All POP segment instructions suppress interrupts for one instruction. */ noint = 1; @@ -2201,7 +1971,7 @@ execx86(int cycs) load_cs(tempw); pfq_pos = 0; } else - loadseg(tempw, _opseg[(rmdat & 0x18) >> 3]); + load_seg(tempw, _opseg[(rmdat & 0x18) >> 3]); wait(1, 0); if (cpu_mod != 3) wait(2, 0); @@ -2482,7 +2252,7 @@ execx86(int cycs) cpu_state.regs[cpu_reg].w = cpu_data; access(57, bits); read_ea2(bits); - loadseg(cpu_data, (opcode & 0x01) ? &cpu_state.seg_ds : &cpu_state.seg_es); + load_seg(cpu_data, (opcode & 0x01) ? &cpu_state.seg_ds : &cpu_state.seg_es); wait(1, 0); break; @@ -2985,7 +2755,5 @@ execx86(int cycs) cpu_alu_op = 0; } - - ins++; } } diff --git a/src/cpu/CMakeLists.txt b/src/cpu/CMakeLists.txt index 6fe97a35c..ab27b77c0 100644 --- a/src/cpu/CMakeLists.txt +++ b/src/cpu/CMakeLists.txt @@ -13,7 +13,7 @@ # Copyright 2020,2021 David Hrdlička. # -add_library(cpu OBJECT cpu.c cpu_table.c 808x.c 386.c 386_common.c 386_dynarec.c +add_library(cpu OBJECT cpu.c cpu_table.c fpu.c x86.c 808x.c 386.c 386_common.c 386_dynarec.c 386_dynarec_ops.c x86seg.c x87.c x87_timings.c) if(AMD_K5) diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index 1d17496fa..4f31ab5ad 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -1,42 +1,22 @@ /* - * VARCem Virtual ARchaeological Computer EMulator. - * An emulator of (mostly) x86-based PC systems and devices, - * using the ISA,EISA,VLB,MCA and PCI system buses, roughly - * spanning the era between 1981 and 1995. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the VARCem Project. + * This file is part of the 86Box distribution. * * CPU type handler. * - * - * - * Authors: Fred N. van Kempen, - * Sarah Walker, + * Authors: Sarah Walker, * leilei, * Miran Grca, + * Fred N. van Kempen, * - * Copyright 2018 Fred N. van Kempen. * Copyright 2008-2018 Sarah Walker. * Copyright 2016-2018 leilei. * Copyright 2016-2018 Miran Grca. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the: - * - * Free Software Foundation, Inc. - * 59 Temple Place - Suite 330 - * Boston, MA 02111-1307 - * USA. + * Copyright 2018 Fred N. van Kempen. */ #include #include @@ -69,13 +49,6 @@ #define CCR3_NMI_EN (1 << 1) -cyrix_t cyrix; - - -static void cpu_write(uint16_t addr, uint8_t val, void *priv); -static uint8_t cpu_read(uint16_t addr, void *priv); - - enum { CPUID_FPU = (1 << 0), CPUID_VME = (1 << 1), @@ -93,174 +66,75 @@ enum { }; /*Addition flags returned by CPUID function 0x80000001*/ -enum -{ - CPUID_3DNOW = (1 << 31) -}; +#define CPUID_3DNOW (1UL << 31UL) #ifdef USE_DYNAREC -const OpFn *x86_dynarec_opcodes; -const OpFn *x86_dynarec_opcodes_0f; -const OpFn *x86_dynarec_opcodes_d8_a16; -const OpFn *x86_dynarec_opcodes_d8_a32; -const OpFn *x86_dynarec_opcodes_d9_a16; -const OpFn *x86_dynarec_opcodes_d9_a32; -const OpFn *x86_dynarec_opcodes_da_a16; -const OpFn *x86_dynarec_opcodes_da_a32; -const OpFn *x86_dynarec_opcodes_db_a16; -const OpFn *x86_dynarec_opcodes_db_a32; -const OpFn *x86_dynarec_opcodes_dc_a16; -const OpFn *x86_dynarec_opcodes_dc_a32; -const OpFn *x86_dynarec_opcodes_dd_a16; -const OpFn *x86_dynarec_opcodes_dd_a32; -const OpFn *x86_dynarec_opcodes_de_a16; -const OpFn *x86_dynarec_opcodes_de_a32; -const OpFn *x86_dynarec_opcodes_df_a16; -const OpFn *x86_dynarec_opcodes_df_a32; -const OpFn *x86_dynarec_opcodes_REPE; -const OpFn *x86_dynarec_opcodes_REPNE; -const OpFn *x86_dynarec_opcodes_3DNOW; +const OpFn *x86_dynarec_opcodes, *x86_dynarec_opcodes_0f, + *x86_dynarec_opcodes_d8_a16, *x86_dynarec_opcodes_d8_a32, + *x86_dynarec_opcodes_d9_a16, *x86_dynarec_opcodes_d9_a32, + *x86_dynarec_opcodes_da_a16, *x86_dynarec_opcodes_da_a32, + *x86_dynarec_opcodes_db_a16, *x86_dynarec_opcodes_db_a32, + *x86_dynarec_opcodes_dc_a16, *x86_dynarec_opcodes_dc_a32, + *x86_dynarec_opcodes_dd_a16, *x86_dynarec_opcodes_dd_a32, + *x86_dynarec_opcodes_de_a16, *x86_dynarec_opcodes_de_a32, + *x86_dynarec_opcodes_df_a16, *x86_dynarec_opcodes_df_a32, + *x86_dynarec_opcodes_REPE, *x86_dynarec_opcodes_REPNE, + *x86_dynarec_opcodes_3DNOW; #endif -const OpFn *x86_opcodes; -const OpFn *x86_opcodes_0f; -const OpFn *x86_opcodes_d8_a16; -const OpFn *x86_opcodes_d8_a32; -const OpFn *x86_opcodes_d9_a16; -const OpFn *x86_opcodes_d9_a32; -const OpFn *x86_opcodes_da_a16; -const OpFn *x86_opcodes_da_a32; -const OpFn *x86_opcodes_db_a16; -const OpFn *x86_opcodes_db_a32; -const OpFn *x86_opcodes_dc_a16; -const OpFn *x86_opcodes_dc_a32; -const OpFn *x86_opcodes_dd_a16; -const OpFn *x86_opcodes_dd_a32; -const OpFn *x86_opcodes_de_a16; -const OpFn *x86_opcodes_de_a32; -const OpFn *x86_opcodes_df_a16; -const OpFn *x86_opcodes_df_a32; -const OpFn *x86_opcodes_REPE; -const OpFn *x86_opcodes_REPNE; -const OpFn *x86_opcodes_3DNOW; +const OpFn *x86_opcodes, *x86_opcodes_0f, + *x86_opcodes_d8_a16, *x86_opcodes_d8_a32, + *x86_opcodes_d9_a16, *x86_opcodes_d9_a32, + *x86_opcodes_da_a16, *x86_opcodes_da_a32, + *x86_opcodes_db_a16, *x86_opcodes_db_a32, + *x86_opcodes_dc_a16, *x86_opcodes_dc_a32, + *x86_opcodes_dd_a16, *x86_opcodes_dd_a32, + *x86_opcodes_de_a16, *x86_opcodes_de_a32, + *x86_opcodes_df_a16, *x86_opcodes_df_a32, + *x86_opcodes_REPE, *x86_opcodes_REPNE, + *x86_opcodes_3DNOW; -int in_smm = 0, smi_line = 0, smi_latched = 0, smm_in_hlt = 0; -int smi_block = 0; -uint32_t smbase = 0x30000; +uint16_t cpu_fast_off_count, cpu_fast_off_val; +uint16_t temp_seg_data[4] = {0, 0, 0, 0}; + +int isa_cycles, + + cpu_cycles_read, cpu_cycles_read_l, cpu_cycles_write, cpu_cycles_write_l, + cpu_prefetch_cycles, cpu_prefetch_width, cpu_mem_prefetch_cycles, cpu_rom_prefetch_cycles, + cpu_waitstates, cpu_cache_int_enabled, cpu_cache_ext_enabled, + cpu_isa_speed, cpu_pci_speed, cpu_isa_pci_div, cpu_agp_speed, cpu_alt_reset, + + cpu_override, cpu_effective, cpu_multi, cpu_16bitbus, cpu_64bitbus, cpu_busspeed, + cpu_cyrix_alignment, CPUID, + + is286, is386, is486 = 1, is486sx, is486dx, is486sx2, is486dx2, isdx4, + cpu_isintel, cpu_iscyrix, hascache, isibm486, israpidcad, is_vpc, + is_am486, is_pentium, is_k5, is_k6, is_p6, is_cx6x86, hasfpu, + + timing_rr, timing_mr, timing_mrl, timing_rm, timing_rml, + timing_mm, timing_mml, timing_bt, timing_bnt, + timing_int, timing_int_rm, timing_int_v86, timing_int_pm, + timing_int_pm_outer, timing_iret_rm, timing_iret_v86, timing_iret_pm, + timing_iret_pm_outer, timing_call_rm, timing_call_pm, timing_call_pm_gate, + timing_call_pm_gate_inner, timing_retf_rm, timing_retf_pm, timing_retf_pm_outer, + timing_jmp_rm, timing_jmp_pm, timing_jmp_pm_gate, timing_misaligned; + +uint32_t cpu_features, cpu_fast_off_flags; + +uint64_t cpu_CR4_mask, tsc = 0; +uint64_t pmc[2] = {0, 0}; + +double cpu_dmulti; + +msr_t msr; + +cpu_state_t cpu_state; + +cyrix_t cyrix; cpu_family_t *cpu_f; CPU *cpu_s; -int cpu_override; -int cpu_effective; -int cpu_multi; -double cpu_dmulti; -int cpu_16bitbus, cpu_64bitbus; -int cpu_busspeed; -int cpu_cyrix_alignment; -int CPUID; -uint64_t cpu_CR4_mask; -int isa_cycles; -int cpu_cycles_read, cpu_cycles_read_l, - cpu_cycles_write, cpu_cycles_write_l; -int cpu_prefetch_cycles, cpu_prefetch_width, - cpu_mem_prefetch_cycles, cpu_rom_prefetch_cycles; -int cpu_waitstates; -int cpu_cache_int_enabled, cpu_cache_ext_enabled; -int cpu_isa_speed, cpu_pci_speed, cpu_isa_pci_div, cpu_agp_speed, cpu_alt_reset; -uint16_t cpu_fast_off_count, cpu_fast_off_val; -uint32_t cpu_fast_off_flags; -int is_vpc; - -uint32_t cpu_features; - -int is286, - is386, - is486 = 1, - is486sx, is486dx, is486sx2, is486dx2, isdx4, - cpu_isintel, cpu_iscyrix, - hascache, - isibm486, - israpidcad, - is_am486, is_pentium, is_k5, is_k6, is_p6, is_cx6x86; - -int hasfpu; - -uint64_t tsc = 0; -msr_t msr; -cpu_state_t cpu_state; -uint64_t pmc[2] = {0, 0}; - -uint16_t temp_seg_data[4] = {0, 0, 0, 0}; - -uint64_t mtrr_cap_msr = 0x00000508; -uint64_t mtrr_physbase_msr[8] = {0, 0, 0, 0, 0, 0, 0, 0}; -uint64_t mtrr_physmask_msr[8] = {0, 0, 0, 0, 0, 0, 0, 0}; -uint64_t mtrr_fix64k_8000_msr = 0; -uint64_t mtrr_fix16k_8000_msr = 0; -uint64_t mtrr_fix16k_a000_msr = 0; -uint64_t mtrr_fix4k_msr[8] = {0, 0, 0, 0, 0, 0, 0, 0}; -uint64_t mtrr_deftype_msr = 0; - -uint64_t ibm_por_msr = 0; /*Processor Operation Register*/ -uint64_t ibm_crcr_msr = 0; /*Cache Region Control Register*/ -uint64_t ibm_por2_msr = 0; /*Processor Operation Register*/ - -uint16_t cs_msr = 0; -uint32_t esp_msr = 0; -uint32_t eip_msr = 0; -uint64_t apic_base_msr = 0; -uint64_t pat_msr = 0; -uint64_t msr_ia32_pmc[8] = {0, 0, 0, 0, 0, 0, 0, 0}; -uint64_t ecx17_msr = 0; -uint64_t ecx2a_msr = 0; -uint64_t ecx79_msr = 0; -uint64_t ecx8x_msr[4] = {0, 0, 0, 0}; -uint64_t ecx116_msr = 0; -uint64_t ecx11x_msr[4] = {0, 0, 0, 0}; -uint64_t ecx11e_msr = 0; -uint64_t ecx186_msr = 0; -uint64_t ecx187_msr = 0; -uint64_t ecx1e0_msr = 0; - -/* Model Identification MSR's used by some Acer BIOSes*/ -uint64_t ecx404_msr = 0; -uint64_t ecx408_msr = 0; -uint64_t ecx40c_msr = 0; -uint64_t ecx410_msr = 0; -uint64_t ecx570_msr = 0; - -uint64_t ecx83_msr = 0; /* AMD K5 and K6 MSR's. */ - -/* MSR used by some Intel AMI boards */ -uint64_t ecx1002ff_msr = 0; - -/* Some weird long MSR's used by i686 AMI & some Phoenix BIOSes */ -uint64_t ecxf0f00250_msr = 0; -uint64_t ecxf0f00258_msr = 0; -uint64_t ecxf0f00259_msr = 0; - -uint64_t star = 0; /* AMD K6-2+. */ - -uint64_t amd_efer = 0, amd_whcr = 0, - amd_uwccr = 0, amd_epmr = 0, /* AMD K6-2+ registers. */ - amd_psor = 0, amd_pfir = 0, - amd_l2aar = 0; - -int timing_rr; -int timing_mr, timing_mrl; -int timing_rm, timing_rml; -int timing_mm, timing_mml; -int timing_bt, timing_bnt; -int timing_int, timing_int_rm, timing_int_v86, timing_int_pm, - timing_int_pm_outer; -int timing_iret_rm, timing_iret_v86, timing_iret_pm, - timing_iret_pm_outer; -int timing_call_rm, timing_call_pm, timing_call_pm_gate, - timing_call_pm_gate_inner; -int timing_retf_rm, timing_retf_pm, timing_retf_pm_outer; -int timing_jmp_rm, timing_jmp_pm, timing_jmp_pm_gate; -int timing_misaligned; uint8_t do_translate = 0, do_translate2 = 0; @@ -269,7 +143,11 @@ void (*cpu_exec)(int cycs); static uint8_t ccr0, ccr1, ccr2, ccr3, ccr4, ccr5, ccr6; -static int cyrix_addr; +static int cyrix_addr; + + +static void cpu_write(uint16_t addr, uint8_t val, void *priv); +static uint8_t cpu_read(uint16_t addr, void *priv); #ifdef ENABLE_CPU_LOG @@ -295,1599 +173,1204 @@ cpu_log(const char *fmt, ...) int cpu_has_feature(int feature) { - return cpu_features & feature; + return cpu_features & feature; } void cpu_dynamic_switch(int new_cpu) { - if (cpu_effective == new_cpu) - return; + int c; - int c = cpu; - cpu = new_cpu; - cpu_set(); - pc_speed_changed(); - cpu = c; + if (cpu_effective == new_cpu) + return; + + c = cpu; + cpu = new_cpu; + cpu_set(); + pc_speed_changed(); + cpu = c; } void cpu_set_edx(void) { - EDX = cpu_s->edx_reset; + EDX = cpu_s->edx_reset; } + cpu_family_t * cpu_get_family(const char *internal_name) { - int c = 0; - while (cpu_families[c].package) { - if (!strcmp(internal_name, cpu_families[c].internal_name)) - return (cpu_family_t *) &cpu_families[c]; - c++; - } + int c = 0; - return NULL; + while (cpu_families[c].package) { + if (!strcmp(internal_name, cpu_families[c].internal_name)) + return (cpu_family_t *) &cpu_families[c]; + c++; + } + + return NULL; } uint8_t cpu_is_eligible(const cpu_family_t *cpu_family, int cpu, int machine) { - if (cpu_override > 1) /* full override */ - return 1; - - /* Get machine. */ - const machine_t *machine_s = &machines[machine]; - - /* Add implicit CPU package compatibility. */ - uint32_t packages = machine_s->cpu_package; - if (packages & CPU_PKG_SOCKET3) - packages |= CPU_PKG_SOCKET1; - else if (packages & CPU_PKG_SLOT1) - packages |= CPU_PKG_SOCKET370; - - if (!(cpu_family->package & packages)) /* package type */ - return 0; - - if (cpu_override) /* partial override */ - return 1; - - const CPU *cpu_s = &cpu_family->cpus[cpu]; - - /* Check CPU blocklist. */ - if (machine_s->cpu_block) { - uint8_t i = 0; - while (machine_s->cpu_block[i]) { - if (machine_s->cpu_block[i++] == cpu_s->cpu_type) - return 0; - } - } - - uint32_t bus_speed = cpu_s->rspeed / cpu_s->multi; - - if (machine_s->cpu_min_bus && (bus_speed < (machine_s->cpu_min_bus - 840907))) /* minimum bus speed with ~0.84 MHz (for 8086) tolerance */ - return 0; - - if (machine_s->cpu_max_bus && (bus_speed > (machine_s->cpu_max_bus + 840907))) /* maximum bus speed with ~0.84 MHz (for 8086) tolerance */ - return 0; - - if (machine_s->cpu_min_voltage && (cpu_s->voltage < (machine_s->cpu_min_voltage - 100))) /* minimum voltage with 0.1V tolerance */ - return 0; - - if (machine_s->cpu_max_voltage && (cpu_s->voltage > (machine_s->cpu_max_voltage + 100))) /* maximum voltage with 0.1V tolerance */ - return 0; - - /* Account for CPUs which use a different internal multiplier than specified by jumpers. */ - double multi = cpu_s->multi; - if (cpu_s->cpu_flags & CPU_FIXED_MULTIPLIER) { - return 1; /* don't care about multiplier compatibility on fixed multiplier CPUs */ - } else if (cpu_family->package & CPU_PKG_SOCKET5_7) { - if ((multi == 1.5) && (cpu_s->cpu_type == CPU_5K86) && (machine_s->cpu_min_multi > 1.5)) /* K5 5k86 */ - multi = 2.0; - else if (multi == 1.75) /* K5 5k86 */ - multi = 2.5; - else if (multi == 2.0) { - if (cpu_s->cpu_type == CPU_5K86) /* K5 5k86 */ - multi = 3.0; - else if (cpu_s->cpu_type == CPU_K6_2P || cpu_s->cpu_type == CPU_K6_3P) /* K6-2+ / K6-3+ */ - multi = 2.5; - else if ((cpu_s->cpu_type == CPU_WINCHIP || cpu_s->cpu_type == CPU_WINCHIP2) && (machine_s->cpu_min_multi > 2.0)) /* WinChip (2) */ - multi = 2.5; - } - else if (multi == (7.0 / 3.0)) /* WinChip 2A - 2.33x */ - multi = 5.0; - else if (multi == (8.0 / 3.0)) /* WinChip 2A - 2.66x */ - multi = 5.5; - else if ((multi == 3.0) && (cpu_s->cpu_type == CPU_Cx6x86 || cpu_s->cpu_type == CPU_Cx6x86L)) /* 6x86(L) */ - multi = 1.5; - else if (multi == (10.0 / 3.0)) /* WinChip 2A - 3.33x */ - multi = 2.0; - else if ((multi == 3.5) && (machine_s->cpu_min_multi < 3.5)) /* standard set by the Pentium MMX */ - multi = 1.5; - else if (multi == 4.0) { - if (cpu_s->cpu_type == CPU_WINCHIP || cpu_s->cpu_type == CPU_WINCHIP2) { /* WinChip (2) */ - if (machine_s->cpu_min_multi >= 1.5) - multi = 1.5; - else if (machine_s->cpu_min_multi >= 3.5) - multi = 3.5; - else if (machine_s->cpu_min_multi >= 4.5) - multi = 4.5; - } else if (cpu_s->cpu_type == CPU_Cx6x86 || cpu_s->cpu_type == CPU_Cx6x86L) /* 6x86(L) */ - multi = 3.0; - } - else if ((multi == 5.0) && (cpu_s->cpu_type == CPU_WINCHIP || cpu_s->cpu_type == CPU_WINCHIP2) && (machine_s->cpu_min_multi > 5.0)) /* WinChip (2) */ - multi = 5.5; - else if ((multi == 6.0) && (machine_s->cpu_max_multi < 6.0)) /* K6-2(+) / K6-3(+) */ - multi = 2.0; - } - - if (multi < machine_s->cpu_min_multi) /* minimum multiplier */ - return 0; - - if (machine_s->cpu_max_multi && (multi > machine_s->cpu_max_multi)) /* maximum multiplier */ - return 0; + const machine_t *machine_s = &machines[machine]; + const CPU *cpu_s = &cpu_family->cpus[cpu]; + uint32_t packages, bus_speed; + uint8_t i; + double multi; + /* Full override. */ + if (cpu_override > 1) return 1; + + /* Add implicit CPU package compatibility. */ + packages = machine_s->cpu_package; + if (packages & CPU_PKG_SOCKET3) + packages |= CPU_PKG_SOCKET1; + else if (packages & CPU_PKG_SLOT1) + packages |= CPU_PKG_SOCKET370; + + /* Package type. */ + if (!(cpu_family->package & packages)) + return 0; + + /* Partial override. */ + if (cpu_override) + return 1; + + /* Check CPU blocklist. */ + if (machine_s->cpu_block) { + i = 0; + + while (machine_s->cpu_block[i]) { + if (machine_s->cpu_block[i++] == cpu_s->cpu_type) + return 0; + } + } + + bus_speed = cpu_s->rspeed / cpu_s->multi; + + /* Minimum bus speed with ~0.84 MHz (for 8086) tolerance. */ + if (machine_s->cpu_min_bus && (bus_speed < (machine_s->cpu_min_bus - 840907))) + return 0; + + /* Maximum bus speed with ~0.84 MHz (for 8086) tolerance. */ + if (machine_s->cpu_max_bus && (bus_speed > (machine_s->cpu_max_bus + 840907))) + return 0; + + /* Minimum voltage with 0.1V tolerance. */ + if (machine_s->cpu_min_voltage && (cpu_s->voltage < (machine_s->cpu_min_voltage - 100))) + return 0; + + /* Maximum voltage with 0.1V tolerance. */ + if (machine_s->cpu_max_voltage && (cpu_s->voltage > (machine_s->cpu_max_voltage + 100))) + return 0; + + /* Account for CPUs which use a different internal multiplier than specified by jumpers. */ + multi = cpu_s->multi; + + /* Don't care about multiplier compatibility on fixed multiplier CPUs. */ + if (cpu_s->cpu_flags & CPU_FIXED_MULTIPLIER) + return 1; + else if (cpu_family->package & CPU_PKG_SOCKET5_7) { + if ((multi == 1.5) && (cpu_s->cpu_type == CPU_5K86) && (machine_s->cpu_min_multi > 1.5)) /* K5 5k86 */ + multi = 2.0; + else if (multi == 1.75) /* K5 5k86 */ + multi = 2.5; + else if (multi == 2.0) { + if (cpu_s->cpu_type == CPU_5K86) /* K5 5k86 */ + multi = 3.0; + /* K6-2+ / K6-3+ */ + else if ((cpu_s->cpu_type == CPU_K6_2P) || (cpu_s->cpu_type == CPU_K6_3P)) + multi = 2.5; + else if (((cpu_s->cpu_type == CPU_WINCHIP) || (cpu_s->cpu_type == CPU_WINCHIP2)) && + (machine_s->cpu_min_multi > 2.0)) /* WinChip (2) */ + multi = 2.5; + } + else if (multi == (7.0 / 3.0)) /* WinChip 2A - 2.33x */ + multi = 5.0; + else if (multi == (8.0 / 3.0)) /* WinChip 2A - 2.66x */ + multi = 5.5; + else if ((multi == 3.0) && (cpu_s->cpu_type == CPU_Cx6x86 || cpu_s->cpu_type == CPU_Cx6x86L)) /* 6x86(L) */ + multi = 1.5; + else if (multi == (10.0 / 3.0)) /* WinChip 2A - 3.33x */ + multi = 2.0; + else if ((multi == 3.5) && (machine_s->cpu_min_multi < 3.5)) /* standard set by the Pentium MMX */ + multi = 1.5; + else if (multi == 4.0) { + /* WinChip (2) */ + if ((cpu_s->cpu_type == CPU_WINCHIP) || (cpu_s->cpu_type == CPU_WINCHIP2)) { + if (machine_s->cpu_min_multi >= 1.5) + multi = 1.5; + else if (machine_s->cpu_min_multi >= 3.5) + multi = 3.5; + else if (machine_s->cpu_min_multi >= 4.5) + multi = 4.5; + } else if ((cpu_s->cpu_type == CPU_Cx6x86) || (cpu_s->cpu_type == CPU_Cx6x86L)) /* 6x86(L) */ + multi = 3.0; + } else if ((multi == 5.0) && ((cpu_s->cpu_type == CPU_WINCHIP) || (cpu_s->cpu_type == CPU_WINCHIP2)) && + (machine_s->cpu_min_multi > 5.0)) /* WinChip (2) */ + multi = 5.5; + else if ((multi == 6.0) && (machine_s->cpu_max_multi < 6.0)) /* K6-2(+) / K6-3(+) */ + multi = 2.0; + } + + /* Minimum multiplier, */ + if (multi < machine_s->cpu_min_multi) + return 0; + + /* Maximum multiplier. */ + if (machine_s->cpu_max_multi && (multi > machine_s->cpu_max_multi)) + return 0; + + return 1; } uint8_t cpu_family_is_eligible(const cpu_family_t *cpu_family, int machine) { - int c = 0; + int c = 0; - while (cpu_family->cpus[c].cpu_type) { - if (cpu_is_eligible(cpu_family, c, machine)) - return 1; - c++; - } + while (cpu_family->cpus[c].cpu_type) { + if (cpu_is_eligible(cpu_family, c, machine)) + return 1; + c++; + } - return 0; + return 0; } -int fpu_get_type(const cpu_family_t *cpu_family, int cpu, const char *internal_name) -{ - const CPU *cpu_s = &cpu_family->cpus[cpu]; - const FPU *fpus = cpu_s->fpus; - int fpu_type = fpus[0].type; - int c = 0; - - while (fpus[c].internal_name) - { - if (!strcmp(internal_name, fpus[c].internal_name)) - fpu_type = fpus[c].type; - c++; - } - - return fpu_type; -} - -const char *fpu_get_internal_name(const cpu_family_t *cpu_family, int cpu, int type) -{ - const CPU *cpu_s = &cpu_family->cpus[cpu]; - const FPU *fpus = cpu_s->fpus; - int c = 0; - - while (fpus[c].internal_name) - { - if (fpus[c].type == type) - return fpus[c].internal_name; - c++; - } - - return fpus[0].internal_name; -} - -const char *fpu_get_name_from_index(const cpu_family_t *cpu_family, int cpu, int c) -{ - const CPU *cpu_s = &cpu_family->cpus[cpu]; - const FPU *fpus = cpu_s->fpus; - - return fpus[c].name; -} - -int fpu_get_type_from_index(const cpu_family_t *cpu_family, int cpu, int c) -{ - const CPU *cpu_s = &cpu_family->cpus[cpu]; - const FPU *fpus = cpu_s->fpus; - - return fpus[c].type; -} - void cpu_set(void) { - cpu_effective = cpu; - cpu_s = (CPU *) &cpu_f->cpus[cpu_effective]; + cpu_effective = cpu; + cpu_s = (CPU *) &cpu_f->cpus[cpu_effective]; #ifdef USE_ACYCS - acycs = 0; + acycs = 0; #endif - cpu_alt_reset = 0; - unmask_a20_in_smm = 0; + cpu_alt_reset = 0; + unmask_a20_in_smm = 0; - CPUID = cpu_s->cpuid_model; - is8086 = (cpu_s->cpu_type > CPU_8088); - is286 = (cpu_s->cpu_type >= CPU_286); - is386 = (cpu_s->cpu_type >= CPU_386SX); - israpidcad = (cpu_s->cpu_type == CPU_RAPIDCAD); - isibm486 = (cpu_s->cpu_type == CPU_IBM386SLC) || (cpu_s->cpu_type == CPU_IBM486SLC) || (cpu_s->cpu_type == CPU_IBM486BL); - is486 = (cpu_s->cpu_type >= CPU_i486SX) || (cpu_s->cpu_type == CPU_486SLC || cpu_s->cpu_type == CPU_486DLC || cpu_s->cpu_type == CPU_RAPIDCAD); - is486sx = (cpu_s->cpu_type >= CPU_i486SX) && (cpu_s->cpu_type < CPU_i486SX2); - is486sx2 = (cpu_s->cpu_type >= CPU_i486SX2) && (cpu_s->cpu_type < CPU_i486DX); - is486dx = (cpu_s->cpu_type >= CPU_i486DX) && (cpu_s->cpu_type < CPU_i486DX2); - is486dx2 = (cpu_s->cpu_type >= CPU_i486DX2) && (cpu_s->cpu_type < CPU_iDX4); - isdx4 = (cpu_s->cpu_type >= CPU_iDX4) && (cpu_s->cpu_type < CPU_WINCHIP); - is_am486 = (cpu_s->cpu_type == CPU_Am486SX) || (cpu_s->cpu_type == CPU_Am486SX2) || (cpu_s->cpu_type == CPU_Am486DX) || - (cpu_s->cpu_type == CPU_Am486DX2) || (cpu_s->cpu_type == CPU_Am486DX4) || (cpu_s->cpu_type == CPU_Am5x86); - is_pentium = (cpu_s->cpu_type == CPU_P24T) || (cpu_s->cpu_type == CPU_PENTIUM) || (cpu_s->cpu_type == CPU_PENTIUMMMX); - /* Not Pentiums, but they share the same SMM save state table layout. */ - is_pentium |= (cpu_s->cpu_type == CPU_i486DX2) || (cpu_s->cpu_type == CPU_iDX4); - /* The WinChip datasheet claims these are Pentium-compatible. */ - is_pentium |= (cpu_s->cpu_type == CPU_WINCHIP) || (cpu_s->cpu_type == CPU_WINCHIP2); -#if defined(DEV_BRANCH) && defined(USE_AMD_K5) - is_k5 = (cpu_s->cpu_type == CPU_K5) || (cpu_s->cpu_type == CPU_5K86); + CPUID = cpu_s->cpuid_model; + is8086 = (cpu_s->cpu_type > CPU_8088); + is286 = (cpu_s->cpu_type >= CPU_286); + is386 = (cpu_s->cpu_type >= CPU_386SX); + israpidcad = (cpu_s->cpu_type == CPU_RAPIDCAD); + isibm486 = (cpu_s->cpu_type == CPU_IBM386SLC) || (cpu_s->cpu_type == CPU_IBM486SLC) || + (cpu_s->cpu_type == CPU_IBM486BL); + is486 = (cpu_s->cpu_type >= CPU_RAPIDCAD); + is486sx = (cpu_s->cpu_type >= CPU_i486SX) && (cpu_s->cpu_type < CPU_i486SX2); + is486sx2 = (cpu_s->cpu_type >= CPU_i486SX2) && (cpu_s->cpu_type < CPU_i486DX); + is486dx = (cpu_s->cpu_type >= CPU_i486DX) && (cpu_s->cpu_type < CPU_i486DX2); + is486dx2 = (cpu_s->cpu_type >= CPU_i486DX2) && (cpu_s->cpu_type < CPU_iDX4); + isdx4 = (cpu_s->cpu_type >= CPU_iDX4) && (cpu_s->cpu_type < CPU_WINCHIP); + is_am486 = !strcmp(cpu_f->manufacturer, "AMD") && (cpu_s->cpu_type >= CPU_Am486SX) && (cpu_s->cpu_type <= CPU_Am5x86); + + cpu_isintel = !strcmp(cpu_f->manufacturer, "Intel"); + cpu_iscyrix = !strcmp(cpu_f->manufacturer, "Cyrix"); + + /* The 486DX2 and iDX4 have the same SMM save state table layout as Pentiums, + and the WinChip datasheet claims those are Pentium-compatible as well. */ + is_pentium = (cpu_isintel && (cpu_s->cpu_type >= CPU_i486DX2) && (cpu_s->cpu_type < CPU_PENTIUMPRO)) || + !strcmp(cpu_f->manufacturer, "IDT"); + is_k5 = !strcmp(cpu_f->manufacturer, "AMD") && (cpu_s->cpu_type > CPU_Am5x86); + is_k6 = (cpu_s->cpu_type >= CPU_K6) && !strcmp(cpu_f->manufacturer, "AMD"); + /* The Samuel 2 datasheet claims it's Celeron-compatible. */ + is_p6 = (cpu_isintel && (cpu_s->cpu_type >= CPU_PENTIUMPRO)) || !strcmp(cpu_f->manufacturer, "VIA"); + is_cx6x86 = !strcmp(cpu_f->manufacturer, "Cyrix") && (cpu_s->cpu_type > CPU_Cx5x86); + + hasfpu = (fpu_type != FPU_NONE); + hascache = (cpu_s->cpu_type >= CPU_486SLC) || (cpu_s->cpu_type == CPU_IBM386SLC) || + (cpu_s->cpu_type == CPU_IBM486SLC) || (cpu_s->cpu_type == CPU_IBM486BL); + + cpu_16bitbus = (cpu_s->cpu_type == CPU_286) || (cpu_s->cpu_type == CPU_386SX) || + (cpu_s->cpu_type == CPU_486SLC) || (cpu_s->cpu_type == CPU_IBM386SLC) || + (cpu_s->cpu_type == CPU_IBM486SLC); + cpu_64bitbus = (cpu_s->cpu_type >= CPU_WINCHIP); + + if (cpu_s->multi) + cpu_busspeed = cpu_s->rspeed / cpu_s->multi; + else + cpu_busspeed = cpu_s->rspeed; + cpu_multi = (int) ceil(cpu_s->multi); + cpu_dmulti = cpu_s->multi; + ccr0 = ccr1 = ccr2 = ccr3 = ccr4 = ccr5 = ccr6 = 0; + + cpu_update_waitstates(); + + isa_cycles = cpu_s->atclk_div; + + if (cpu_s->rspeed <= 8000000) + cpu_rom_prefetch_cycles = cpu_mem_prefetch_cycles; + else + cpu_rom_prefetch_cycles = cpu_s->rspeed / 1000000; + + cpu_set_isa_pci_div(0); + cpu_set_pci_speed(0); + cpu_set_agp_speed(0); + + io_handler(cpu_iscyrix, 0x0022, 0x0002, cpu_read, NULL, NULL, cpu_write, NULL, NULL, NULL); + + io_handler(hasfpu, 0x00f0, 0x000f, cpu_read, NULL, NULL, cpu_write, NULL, NULL, NULL); + io_handler(hasfpu, 0xf007, 0x0001, cpu_read, NULL, NULL, cpu_write, NULL, NULL, NULL); + +#ifdef USE_DYNAREC + x86_setopcodes(ops_386, ops_386_0f, dynarec_ops_386, dynarec_ops_386_0f); #else - is_k5 = 0; + x86_setopcodes(ops_386, ops_386_0f); #endif - is_k6 = (cpu_s->cpu_type == CPU_K6) || (cpu_s->cpu_type == CPU_K6_2) || - (cpu_s->cpu_type == CPU_K6_2C) || (cpu_s->cpu_type == CPU_K6_3) || - (cpu_s->cpu_type == CPU_K6_2P) || (cpu_s->cpu_type == CPU_K6_3P); - is_p6 = (cpu_s->cpu_type == CPU_PENTIUMPRO) || (cpu_s->cpu_type == CPU_PENTIUM2) || - (cpu_s->cpu_type == CPU_PENTIUM2D); - /* The Samuel 2 datasheet claims it's Celeron-compatible. */ - is_p6 |= (cpu_s->cpu_type == CPU_CYRIX3S) || (cpu_s->cpu_type == CPU_EDEN); -#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) - is_cx6x86 = (cpu_s->cpu_type == CPU_Cx6x86) || (cpu_s->cpu_type == CPU_Cx6x86MX) || - (cpu_s->cpu_type == CPU_Cx6x86L) || (cpu_s->cpu_type == CPU_CxGX1); + x86_opcodes_REPE = ops_REPE; + x86_opcodes_REPNE = ops_REPNE; + x86_opcodes_3DNOW = ops_3DNOW; +#ifdef USE_DYNAREC + x86_dynarec_opcodes_REPE = dynarec_ops_REPE; + x86_dynarec_opcodes_REPNE = dynarec_ops_REPNE; + x86_dynarec_opcodes_3DNOW = dynarec_ops_3DNOW; +#endif + + if (hasfpu) { +#ifdef USE_DYNAREC + x86_dynarec_opcodes_d8_a16 = dynarec_ops_fpu_d8_a16; + x86_dynarec_opcodes_d8_a32 = dynarec_ops_fpu_d8_a32; + x86_dynarec_opcodes_d9_a16 = dynarec_ops_fpu_d9_a16; + x86_dynarec_opcodes_d9_a32 = dynarec_ops_fpu_d9_a32; + x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_da_a16; + x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_da_a32; + x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_db_a16; + x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_db_a32; + x86_dynarec_opcodes_dc_a16 = dynarec_ops_fpu_dc_a16; + x86_dynarec_opcodes_dc_a32 = dynarec_ops_fpu_dc_a32; + x86_dynarec_opcodes_dd_a16 = dynarec_ops_fpu_dd_a16; + x86_dynarec_opcodes_dd_a32 = dynarec_ops_fpu_dd_a32; + x86_dynarec_opcodes_de_a16 = dynarec_ops_fpu_de_a16; + x86_dynarec_opcodes_de_a32 = dynarec_ops_fpu_de_a32; + x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_df_a16; + x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_df_a32; +#endif + x86_opcodes_d8_a16 = ops_fpu_d8_a16; + x86_opcodes_d8_a32 = ops_fpu_d8_a32; + x86_opcodes_d9_a16 = ops_fpu_d9_a16; + x86_opcodes_d9_a32 = ops_fpu_d9_a32; + x86_opcodes_da_a16 = ops_fpu_da_a16; + x86_opcodes_da_a32 = ops_fpu_da_a32; + x86_opcodes_db_a16 = ops_fpu_db_a16; + x86_opcodes_db_a32 = ops_fpu_db_a32; + x86_opcodes_dc_a16 = ops_fpu_dc_a16; + x86_opcodes_dc_a32 = ops_fpu_dc_a32; + x86_opcodes_dd_a16 = ops_fpu_dd_a16; + x86_opcodes_dd_a32 = ops_fpu_dd_a32; + x86_opcodes_de_a16 = ops_fpu_de_a16; + x86_opcodes_de_a32 = ops_fpu_de_a32; + x86_opcodes_df_a16 = ops_fpu_df_a16; + x86_opcodes_df_a32 = ops_fpu_df_a32; + } else { +#ifdef USE_DYNAREC + x86_dynarec_opcodes_d8_a16 = dynarec_ops_nofpu_a16; + x86_dynarec_opcodes_d8_a32 = dynarec_ops_nofpu_a32; + x86_dynarec_opcodes_d9_a16 = dynarec_ops_nofpu_a16; + x86_dynarec_opcodes_d9_a32 = dynarec_ops_nofpu_a32; + x86_dynarec_opcodes_da_a16 = dynarec_ops_nofpu_a16; + x86_dynarec_opcodes_da_a32 = dynarec_ops_nofpu_a32; + x86_dynarec_opcodes_db_a16 = dynarec_ops_nofpu_a16; + x86_dynarec_opcodes_db_a32 = dynarec_ops_nofpu_a32; + x86_dynarec_opcodes_dc_a16 = dynarec_ops_nofpu_a16; + x86_dynarec_opcodes_dc_a32 = dynarec_ops_nofpu_a32; + x86_dynarec_opcodes_dd_a16 = dynarec_ops_nofpu_a16; + x86_dynarec_opcodes_dd_a32 = dynarec_ops_nofpu_a32; + x86_dynarec_opcodes_de_a16 = dynarec_ops_nofpu_a16; + x86_dynarec_opcodes_de_a32 = dynarec_ops_nofpu_a32; + x86_dynarec_opcodes_df_a16 = dynarec_ops_nofpu_a16; + x86_dynarec_opcodes_df_a32 = dynarec_ops_nofpu_a32; +#endif + x86_opcodes_d8_a16 = ops_nofpu_a16; + x86_opcodes_d8_a32 = ops_nofpu_a32; + x86_opcodes_d9_a16 = ops_nofpu_a16; + x86_opcodes_d9_a32 = ops_nofpu_a32; + x86_opcodes_da_a16 = ops_nofpu_a16; + x86_opcodes_da_a32 = ops_nofpu_a32; + x86_opcodes_db_a16 = ops_nofpu_a16; + x86_opcodes_db_a32 = ops_nofpu_a32; + x86_opcodes_dc_a16 = ops_nofpu_a16; + x86_opcodes_dc_a32 = ops_nofpu_a32; + x86_opcodes_dd_a16 = ops_nofpu_a16; + x86_opcodes_dd_a32 = ops_nofpu_a32; + x86_opcodes_de_a16 = ops_nofpu_a16; + x86_opcodes_de_a32 = ops_nofpu_a32; + x86_opcodes_df_a16 = ops_nofpu_a16; + x86_opcodes_df_a32 = ops_nofpu_a32; + } + +#ifdef USE_DYNAREC + codegen_timing_set(&codegen_timing_486); +#endif + + memset(&msr, 0, sizeof(msr)); + + timing_misaligned = 0; + cpu_cyrix_alignment = 0; + cpu_CR4_mask = 0; + + switch (cpu_s->cpu_type) { + case CPU_8088: + case CPU_8086: + break; + + case CPU_286: +#ifdef USE_DYNAREC + x86_setopcodes(ops_286, ops_286_0f, dynarec_ops_286, dynarec_ops_286_0f); #else - is_cx6x86 = 0; + x86_setopcodes(ops_286, ops_286_0f); #endif - hasfpu = (fpu_type != FPU_NONE); - hascache = (cpu_s->cpu_type >= CPU_486SLC) || (cpu_s->cpu_type == CPU_IBM386SLC || cpu_s->cpu_type == CPU_IBM486SLC || cpu_s->cpu_type == CPU_IBM486BL); - cpu_isintel = !strcmp(cpu_f->manufacturer, "Intel"); - cpu_iscyrix = (cpu_s->cpu_type == CPU_486SLC || cpu_s->cpu_type == CPU_486DLC || cpu_s->cpu_type == CPU_Cx486S || cpu_s->cpu_type == CPU_Cx486DX || cpu_s->cpu_type == CPU_Cx486DX2 || cpu_s->cpu_type == CPU_Cx486DX4 || cpu_s->cpu_type == CPU_Cx5x86 || cpu_s->cpu_type == CPU_Cx6x86 || cpu_s->cpu_type == CPU_Cx6x86MX || cpu_s->cpu_type == CPU_Cx6x86L || cpu_s->cpu_type == CPU_CxGX1); - - cpu_16bitbus = (cpu_s->cpu_type == CPU_286 || cpu_s->cpu_type == CPU_386SX || cpu_s->cpu_type == CPU_486SLC || cpu_s->cpu_type == CPU_IBM386SLC || cpu_s->cpu_type == CPU_IBM486SLC ); - cpu_64bitbus = (cpu_s->cpu_type >= CPU_WINCHIP); - - if (cpu_s->multi) - cpu_busspeed = cpu_s->rspeed / cpu_s->multi; - else - cpu_busspeed = cpu_s->rspeed; - cpu_multi = (int) ceil(cpu_s->multi); - cpu_dmulti = cpu_s->multi; - ccr0 = ccr1 = ccr2 = ccr3 = ccr4 = ccr5 = ccr6 = 0; - - - - cpu_update_waitstates(); - - isa_cycles = cpu_s->atclk_div; - - if (cpu_s->rspeed <= 8000000) - cpu_rom_prefetch_cycles = cpu_mem_prefetch_cycles; - else - cpu_rom_prefetch_cycles = cpu_s->rspeed / 1000000; - - cpu_set_isa_pci_div(0); - cpu_set_pci_speed(0); - cpu_set_agp_speed(0); - - if (cpu_iscyrix) - io_sethandler(0x0022, 0x0002, cpu_read, NULL, NULL, cpu_write, NULL, NULL, NULL); - else - io_removehandler(0x0022, 0x0002, cpu_read, NULL, NULL, cpu_write, NULL, NULL, NULL); - - if (hasfpu) { - io_sethandler(0x00f0, 0x000f, cpu_read, NULL, NULL, cpu_write, NULL, NULL, NULL); - io_sethandler(0xf007, 0x0001, cpu_read, NULL, NULL, cpu_write, NULL, NULL, NULL); - } else { - io_removehandler(0x00f0, 0x000f, cpu_read, NULL, NULL, cpu_write, NULL, NULL, NULL); - io_removehandler(0xf007, 0x0001, cpu_read, NULL, NULL, cpu_write, NULL, NULL, NULL); - } + if (fpu_type == FPU_287) { #ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_386_0f, dynarec_ops_386, dynarec_ops_386_0f); -#else - x86_setopcodes(ops_386, ops_386_0f); + x86_dynarec_opcodes_d9_a16 = dynarec_ops_fpu_287_d9_a16; + x86_dynarec_opcodes_d9_a32 = dynarec_ops_fpu_287_d9_a32; + x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_287_da_a16; + x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_287_da_a32; + x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_287_db_a16; + x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_287_db_a32; + x86_dynarec_opcodes_dc_a16 = dynarec_ops_fpu_287_dc_a16; + x86_dynarec_opcodes_dc_a32 = dynarec_ops_fpu_287_dc_a32; + x86_dynarec_opcodes_dd_a16 = dynarec_ops_fpu_287_dd_a16; + x86_dynarec_opcodes_dd_a32 = dynarec_ops_fpu_287_dd_a32; + x86_dynarec_opcodes_de_a16 = dynarec_ops_fpu_287_de_a16; + x86_dynarec_opcodes_de_a32 = dynarec_ops_fpu_287_de_a32; + x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_287_df_a16; + x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_287_df_a32; #endif - x86_opcodes_REPE = ops_REPE; - x86_opcodes_REPNE = ops_REPNE; - x86_opcodes_3DNOW = ops_3DNOW; -#ifdef USE_DYNAREC - x86_dynarec_opcodes_REPE = dynarec_ops_REPE; - x86_dynarec_opcodes_REPNE = dynarec_ops_REPNE; - x86_dynarec_opcodes_3DNOW = dynarec_ops_3DNOW; -#endif - -#ifdef USE_DYNAREC - if (hasfpu) - { - x86_dynarec_opcodes_d8_a16 = dynarec_ops_fpu_d8_a16; - x86_dynarec_opcodes_d8_a32 = dynarec_ops_fpu_d8_a32; - x86_dynarec_opcodes_d9_a16 = dynarec_ops_fpu_d9_a16; - x86_dynarec_opcodes_d9_a32 = dynarec_ops_fpu_d9_a32; - x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_da_a16; - x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_da_a32; - x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_db_a16; - x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_db_a32; - x86_dynarec_opcodes_dc_a16 = dynarec_ops_fpu_dc_a16; - x86_dynarec_opcodes_dc_a32 = dynarec_ops_fpu_dc_a32; - x86_dynarec_opcodes_dd_a16 = dynarec_ops_fpu_dd_a16; - x86_dynarec_opcodes_dd_a32 = dynarec_ops_fpu_dd_a32; - x86_dynarec_opcodes_de_a16 = dynarec_ops_fpu_de_a16; - x86_dynarec_opcodes_de_a32 = dynarec_ops_fpu_de_a32; - x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_df_a16; - x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_df_a32; - } - else - { - x86_dynarec_opcodes_d8_a16 = dynarec_ops_nofpu_a16; - x86_dynarec_opcodes_d8_a32 = dynarec_ops_nofpu_a32; - x86_dynarec_opcodes_d9_a16 = dynarec_ops_nofpu_a16; - x86_dynarec_opcodes_d9_a32 = dynarec_ops_nofpu_a32; - x86_dynarec_opcodes_da_a16 = dynarec_ops_nofpu_a16; - x86_dynarec_opcodes_da_a32 = dynarec_ops_nofpu_a32; - x86_dynarec_opcodes_db_a16 = dynarec_ops_nofpu_a16; - x86_dynarec_opcodes_db_a32 = dynarec_ops_nofpu_a32; - x86_dynarec_opcodes_dc_a16 = dynarec_ops_nofpu_a16; - x86_dynarec_opcodes_dc_a32 = dynarec_ops_nofpu_a32; - x86_dynarec_opcodes_dd_a16 = dynarec_ops_nofpu_a16; - x86_dynarec_opcodes_dd_a32 = dynarec_ops_nofpu_a32; - x86_dynarec_opcodes_de_a16 = dynarec_ops_nofpu_a16; - x86_dynarec_opcodes_de_a32 = dynarec_ops_nofpu_a32; - x86_dynarec_opcodes_df_a16 = dynarec_ops_nofpu_a16; - x86_dynarec_opcodes_df_a32 = dynarec_ops_nofpu_a32; - } - codegen_timing_set(&codegen_timing_486); -#endif - - if (hasfpu) - { - x86_opcodes_d8_a16 = ops_fpu_d8_a16; - x86_opcodes_d8_a32 = ops_fpu_d8_a32; - x86_opcodes_d9_a16 = ops_fpu_d9_a16; - x86_opcodes_d9_a32 = ops_fpu_d9_a32; - x86_opcodes_da_a16 = ops_fpu_da_a16; - x86_opcodes_da_a32 = ops_fpu_da_a32; - x86_opcodes_db_a16 = ops_fpu_db_a16; - x86_opcodes_db_a32 = ops_fpu_db_a32; - x86_opcodes_dc_a16 = ops_fpu_dc_a16; - x86_opcodes_dc_a32 = ops_fpu_dc_a32; - x86_opcodes_dd_a16 = ops_fpu_dd_a16; - x86_opcodes_dd_a32 = ops_fpu_dd_a32; - x86_opcodes_de_a16 = ops_fpu_de_a16; - x86_opcodes_de_a32 = ops_fpu_de_a32; - x86_opcodes_df_a16 = ops_fpu_df_a16; - x86_opcodes_df_a32 = ops_fpu_df_a32; - } - else - { - x86_opcodes_d8_a16 = ops_nofpu_a16; - x86_opcodes_d8_a32 = ops_nofpu_a32; - x86_opcodes_d9_a16 = ops_nofpu_a16; - x86_opcodes_d9_a32 = ops_nofpu_a32; - x86_opcodes_da_a16 = ops_nofpu_a16; - x86_opcodes_da_a32 = ops_nofpu_a32; - x86_opcodes_db_a16 = ops_nofpu_a16; - x86_opcodes_db_a32 = ops_nofpu_a32; - x86_opcodes_dc_a16 = ops_nofpu_a16; - x86_opcodes_dc_a32 = ops_nofpu_a32; - x86_opcodes_dd_a16 = ops_nofpu_a16; - x86_opcodes_dd_a32 = ops_nofpu_a32; - x86_opcodes_de_a16 = ops_nofpu_a16; - x86_opcodes_de_a32 = ops_nofpu_a32; - x86_opcodes_df_a16 = ops_nofpu_a16; - x86_opcodes_df_a32 = ops_nofpu_a32; - } - - memset(&msr, 0, sizeof(msr)); - - timing_misaligned = 0; - cpu_cyrix_alignment = 0; - cpu_CR4_mask = 0; - - switch (cpu_s->cpu_type) - { - case CPU_8088: - case CPU_8086: - break; - - case CPU_286: -#ifdef USE_DYNAREC - x86_setopcodes(ops_286, ops_286_0f, dynarec_ops_286, dynarec_ops_286_0f); -#else - x86_setopcodes(ops_286, ops_286_0f); -#endif - if (fpu_type == FPU_287) - { -#ifdef USE_DYNAREC - x86_dynarec_opcodes_d9_a16 = dynarec_ops_fpu_287_d9_a16; - x86_dynarec_opcodes_d9_a32 = dynarec_ops_fpu_287_d9_a32; - x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_287_da_a16; - x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_287_da_a32; - x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_287_db_a16; - x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_287_db_a32; - x86_dynarec_opcodes_dc_a16 = dynarec_ops_fpu_287_dc_a16; - x86_dynarec_opcodes_dc_a32 = dynarec_ops_fpu_287_dc_a32; - x86_dynarec_opcodes_dd_a16 = dynarec_ops_fpu_287_dd_a16; - x86_dynarec_opcodes_dd_a32 = dynarec_ops_fpu_287_dd_a32; - x86_dynarec_opcodes_de_a16 = dynarec_ops_fpu_287_de_a16; - x86_dynarec_opcodes_de_a32 = dynarec_ops_fpu_287_de_a32; - x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_287_df_a16; - x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_287_df_a32; -#endif - x86_opcodes_d9_a16 = ops_fpu_287_d9_a16; - x86_opcodes_d9_a32 = ops_fpu_287_d9_a32; - x86_opcodes_da_a16 = ops_fpu_287_da_a16; - x86_opcodes_da_a32 = ops_fpu_287_da_a32; - x86_opcodes_db_a16 = ops_fpu_287_db_a16; - x86_opcodes_db_a32 = ops_fpu_287_db_a32; - x86_opcodes_dc_a16 = ops_fpu_287_dc_a16; - x86_opcodes_dc_a32 = ops_fpu_287_dc_a32; - x86_opcodes_dd_a16 = ops_fpu_287_dd_a16; - x86_opcodes_dd_a32 = ops_fpu_287_dd_a32; - x86_opcodes_de_a16 = ops_fpu_287_de_a16; - x86_opcodes_de_a32 = ops_fpu_287_de_a32; - x86_opcodes_df_a16 = ops_fpu_287_df_a16; - x86_opcodes_df_a32 = ops_fpu_287_df_a32; + x86_opcodes_d9_a16 = ops_fpu_287_d9_a16; + x86_opcodes_d9_a32 = ops_fpu_287_d9_a32; + x86_opcodes_da_a16 = ops_fpu_287_da_a16; + x86_opcodes_da_a32 = ops_fpu_287_da_a32; + x86_opcodes_db_a16 = ops_fpu_287_db_a16; + x86_opcodes_db_a32 = ops_fpu_287_db_a32; + x86_opcodes_dc_a16 = ops_fpu_287_dc_a16; + x86_opcodes_dc_a32 = ops_fpu_287_dc_a32; + x86_opcodes_dd_a16 = ops_fpu_287_dd_a16; + x86_opcodes_dd_a32 = ops_fpu_287_dd_a32; + x86_opcodes_de_a16 = ops_fpu_287_de_a16; + x86_opcodes_de_a32 = ops_fpu_287_de_a32; + x86_opcodes_df_a16 = ops_fpu_287_df_a16; + x86_opcodes_df_a32 = ops_fpu_287_df_a32; } - timing_rr = 2; /*register dest - register src*/ - timing_rm = 7; /*register dest - memory src*/ - timing_mr = 7; /*memory dest - register src*/ - timing_mm = 7; /*memory dest - memory src*/ - timing_rml = 9; /*register dest - memory src long*/ - timing_mrl = 11; /*memory dest - register src long*/ - timing_mml = 11; /*memory dest - memory src*/ - timing_bt = 7-3; /*branch taken*/ - timing_bnt = 3; /*branch not taken*/ - timing_int = 0; - timing_int_rm = 23; - timing_int_v86 = 0; - timing_int_pm = 40; - timing_int_pm_outer = 78; - timing_iret_rm = 17; - timing_iret_v86 = 0; - timing_iret_pm = 31; - timing_iret_pm_outer = 55; - timing_call_rm = 13; - timing_call_pm = 26; - timing_call_pm_gate = 52; - timing_call_pm_gate_inner = 82; - timing_retf_rm = 15; - timing_retf_pm = 25; - timing_retf_pm_outer = 55; - timing_jmp_rm = 11; - timing_jmp_pm = 23; - timing_jmp_pm_gate = 38; - break; - - case CPU_IBM486SLC: - case CPU_IBM386SLC: + + timing_rr = 2; /* register dest - register src */ + timing_rm = 7; /* register dest - memory src */ + timing_mr = 7; /* memory dest - register src */ + timing_mm = 7; /* memory dest - memory src */ + timing_rml = 9; /* register dest - memory src long */ + timing_mrl = 11; /* memory dest - register src long */ + timing_mml = 11; /* memory dest - memory src */ + timing_bt = 4; /* branch taken */ + timing_bnt = 3; /* branch not taken */ + + timing_int = 0; + timing_int_rm = 23; + timing_int_v86 = 0; + timing_int_pm = 40; + timing_int_pm_outer = 78; + timing_iret_rm = 17; + timing_iret_v86 = 0; + timing_iret_pm = 31; + timing_iret_pm_outer = 55; + timing_call_rm = 13; + timing_call_pm = 26; + timing_call_pm_gate = 52; + timing_call_pm_gate_inner = 82; + timing_retf_rm = 15; + timing_retf_pm = 25; + timing_retf_pm_outer = 55; + timing_jmp_rm = 11; + timing_jmp_pm = 23; + timing_jmp_pm_gate = 38; + break; + + case CPU_IBM486SLC: + case CPU_IBM386SLC: + case CPU_IBM486BL: #ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_ibm486_0f, dynarec_ops_386, dynarec_ops_ibm486_0f); + x86_setopcodes(ops_386, ops_ibm486_0f, dynarec_ops_386, dynarec_ops_ibm486_0f); #else - x86_setopcodes(ops_386, ops_ibm486_0f); + x86_setopcodes(ops_386, ops_ibm486_0f); #endif - cpu_features = CPU_FEATURE_MSR; - case CPU_386SX: - timing_rr = 2; /*register dest - register src*/ - timing_rm = 6; /*register dest - memory src*/ - timing_mr = 7; /*memory dest - register src*/ - timing_mm = 6; /*memory dest - memory src*/ - timing_rml = 8; /*register dest - memory src long*/ - timing_mrl = 11; /*memory dest - register src long*/ - timing_mml = 10; /*memory dest - memory src*/ - timing_bt = 7-3; /*branch taken*/ - timing_bnt = 3; /*branch not taken*/ - timing_int = 0; - timing_int_rm = 37; - timing_int_v86 = 59; - timing_int_pm = 99; - timing_int_pm_outer = 119; - timing_iret_rm = 22; - timing_iret_v86 = 60; - timing_iret_pm = 38; - timing_iret_pm_outer = 82; - timing_call_rm = 17; - timing_call_pm = 34; - timing_call_pm_gate = 52; - timing_call_pm_gate_inner = 86; - timing_retf_rm = 18; - timing_retf_pm = 32; - timing_retf_pm_outer = 68; - timing_jmp_rm = 12; - timing_jmp_pm = 27; - timing_jmp_pm_gate = 45; - break; - - case CPU_IBM486BL: + cpu_features = CPU_FEATURE_MSR; + /* FALLTHROUGH */ + case CPU_386SX: + case CPU_386DX: + if (fpu_type == FPU_287) { /* In case we get Deskpro 386 emulation */ #ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_ibm486_0f, dynarec_ops_386, dynarec_ops_ibm486_0f); + x86_dynarec_opcodes_d9_a16 = dynarec_ops_fpu_287_d9_a16; + x86_dynarec_opcodes_d9_a32 = dynarec_ops_fpu_287_d9_a32; + x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_287_da_a16; + x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_287_da_a32; + x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_287_db_a16; + x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_287_db_a32; + x86_dynarec_opcodes_dc_a16 = dynarec_ops_fpu_287_dc_a16; + x86_dynarec_opcodes_dc_a32 = dynarec_ops_fpu_287_dc_a32; + x86_dynarec_opcodes_dd_a16 = dynarec_ops_fpu_287_dd_a16; + x86_dynarec_opcodes_dd_a32 = dynarec_ops_fpu_287_dd_a32; + x86_dynarec_opcodes_de_a16 = dynarec_ops_fpu_287_de_a16; + x86_dynarec_opcodes_de_a32 = dynarec_ops_fpu_287_de_a32; + x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_287_df_a16; + x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_287_df_a32; +#endif + x86_opcodes_d9_a16 = ops_fpu_287_d9_a16; + x86_opcodes_d9_a32 = ops_fpu_287_d9_a32; + x86_opcodes_da_a16 = ops_fpu_287_da_a16; + x86_opcodes_da_a32 = ops_fpu_287_da_a32; + x86_opcodes_db_a16 = ops_fpu_287_db_a16; + x86_opcodes_db_a32 = ops_fpu_287_db_a32; + x86_opcodes_dc_a16 = ops_fpu_287_dc_a16; + x86_opcodes_dc_a32 = ops_fpu_287_dc_a32; + x86_opcodes_dd_a16 = ops_fpu_287_dd_a16; + x86_opcodes_dd_a32 = ops_fpu_287_dd_a32; + x86_opcodes_de_a16 = ops_fpu_287_de_a16; + x86_opcodes_de_a32 = ops_fpu_287_de_a32; + x86_opcodes_df_a16 = ops_fpu_287_df_a16; + x86_opcodes_df_a32 = ops_fpu_287_df_a32; + } + + timing_rr = 2; /* register dest - register src */ + timing_rm = 6; /* register dest - memory src */ + timing_mr = 7; /* memory dest - register src */ + timing_mm = 6; /* memory dest - memory src */ + if (cpu_s->cpu_type >= CPU_386DX) { + timing_rml = 6; /* register dest - memory src long */ + timing_mrl = 7; /* memory dest - register src long */ + timing_mml = 6; /* memory dest - memory src */ + } else { + timing_rml = 8; /* register dest - memory src long */ + timing_mrl = 11; /* memory dest - register src long */ + timing_mml = 10; /* memory dest - memory src */ + } + timing_bt = 4; /* branch taken */ + timing_bnt = 3; /* branch not taken */ + + timing_int = 0; + timing_int_rm = 37; + timing_int_v86 = 59; + timing_int_pm = 99; + timing_int_pm_outer = 119; + timing_iret_rm = 22; + timing_iret_v86 = 60; + timing_iret_pm = 38; + timing_iret_pm_outer = 82; + timing_call_rm = 17; + timing_call_pm = 34; + timing_call_pm_gate = 52; + timing_call_pm_gate_inner = 86; + timing_retf_rm = 18; + timing_retf_pm = 32; + timing_retf_pm_outer = 68; + timing_jmp_rm = 12; + timing_jmp_pm = 27; + timing_jmp_pm_gate = 45; + break; + + case CPU_486SLC: +#ifdef USE_DYNAREC + x86_setopcodes(ops_386, ops_486_0f, dynarec_ops_386, dynarec_ops_486_0f); #else - x86_setopcodes(ops_386, ops_ibm486_0f); + x86_setopcodes(ops_386, ops_486_0f); #endif - cpu_features = CPU_FEATURE_MSR; - case CPU_386DX: - if (fpu_type == FPU_287) /*In case we get Deskpro 386 emulation*/ - { + + timing_rr = 1; /* register dest - register src */ + timing_rm = 3; /* register dest - memory src */ + timing_mr = 5; /* memory dest - register src */ + timing_mm = 3; + timing_rml = 5; /* register dest - memory src long */ + timing_mrl = 7; /* memory dest - register src long */ + timing_mml = 7; + timing_bt = 5; /* branch taken */ + timing_bnt = 1; /* branch not taken */ + + timing_int = 4; /* unknown */ + timing_int_rm = 14; + timing_int_v86 = 82; + timing_int_pm = 49; + timing_int_pm_outer = 77; + timing_iret_rm = 14; + timing_iret_v86 = 66; + timing_iret_pm = 31; + timing_iret_pm_outer = 66; + timing_call_rm = 12; + timing_call_pm = 30; + timing_call_pm_gate = 41; + timing_call_pm_gate_inner = 83; + timing_retf_rm = 13; + timing_retf_pm = 26; + timing_retf_pm_outer = 61; + timing_jmp_rm = 9; + timing_jmp_pm = 26; + timing_jmp_pm_gate = 37; + timing_misaligned = 3; + break; + + case CPU_486DLC: #ifdef USE_DYNAREC - x86_dynarec_opcodes_d9_a16 = dynarec_ops_fpu_287_d9_a16; - x86_dynarec_opcodes_d9_a32 = dynarec_ops_fpu_287_d9_a32; - x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_287_da_a16; - x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_287_da_a32; - x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_287_db_a16; - x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_287_db_a32; - x86_dynarec_opcodes_dc_a16 = dynarec_ops_fpu_287_dc_a16; - x86_dynarec_opcodes_dc_a32 = dynarec_ops_fpu_287_dc_a32; - x86_dynarec_opcodes_dd_a16 = dynarec_ops_fpu_287_dd_a16; - x86_dynarec_opcodes_dd_a32 = dynarec_ops_fpu_287_dd_a32; - x86_dynarec_opcodes_de_a16 = dynarec_ops_fpu_287_de_a16; - x86_dynarec_opcodes_de_a32 = dynarec_ops_fpu_287_de_a32; - x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_287_df_a16; - x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_287_df_a32; -#endif - x86_opcodes_d9_a16 = ops_fpu_287_d9_a16; - x86_opcodes_d9_a32 = ops_fpu_287_d9_a32; - x86_opcodes_da_a16 = ops_fpu_287_da_a16; - x86_opcodes_da_a32 = ops_fpu_287_da_a32; - x86_opcodes_db_a16 = ops_fpu_287_db_a16; - x86_opcodes_db_a32 = ops_fpu_287_db_a32; - x86_opcodes_dc_a16 = ops_fpu_287_dc_a16; - x86_opcodes_dc_a32 = ops_fpu_287_dc_a32; - x86_opcodes_dd_a16 = ops_fpu_287_dd_a16; - x86_opcodes_dd_a32 = ops_fpu_287_dd_a32; - x86_opcodes_de_a16 = ops_fpu_287_de_a16; - x86_opcodes_de_a32 = ops_fpu_287_de_a32; - x86_opcodes_df_a16 = ops_fpu_287_df_a16; - x86_opcodes_df_a32 = ops_fpu_287_df_a32; - } - timing_rr = 2; /*register dest - register src*/ - timing_rm = 6; /*register dest - memory src*/ - timing_mr = 7; /*memory dest - register src*/ - timing_mm = 6; /*memory dest - memory src*/ - timing_rml = 6; /*register dest - memory src long*/ - timing_mrl = 7; /*memory dest - register src long*/ - timing_mml = 6; /*memory dest - memory src*/ - timing_bt = 7-3; /*branch taken*/ - timing_bnt = 3; /*branch not taken*/ - timing_int = 0; - timing_int_rm = 37; - timing_int_v86 = 59; - timing_int_pm = 99; - timing_int_pm_outer = 119; - timing_iret_rm = 22; - timing_iret_v86 = 60; - timing_iret_pm = 38; - timing_iret_pm_outer = 82; - timing_call_rm = 17; - timing_call_pm = 34; - timing_call_pm_gate = 52; - timing_call_pm_gate_inner = 86; - timing_retf_rm = 18; - timing_retf_pm = 32; - timing_retf_pm_outer = 68; - timing_jmp_rm = 12; - timing_jmp_pm = 27; - timing_jmp_pm_gate = 45; - break; - - - case CPU_RAPIDCAD: -#ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_486_0f, dynarec_ops_386, dynarec_ops_486_0f); + x86_setopcodes(ops_386, ops_486_0f, dynarec_ops_386, dynarec_ops_486_0f); #else - x86_setopcodes(ops_386, ops_486_0f); + x86_setopcodes(ops_386, ops_486_0f); #endif - timing_rr = 1; /*register dest - register src*/ - timing_rm = 2; /*register dest - memory src*/ - timing_mr = 3; /*memory dest - register src*/ - timing_mm = 3; - timing_rml = 2; /*register dest - memory src long*/ - timing_mrl = 3; /*memory dest - register src long*/ - timing_mml = 3; - timing_bt = 3-1; /*branch taken*/ - timing_bnt = 1; /*branch not taken*/ - timing_int = 4; - timing_int_rm = 26; - timing_int_v86 = 82; - timing_int_pm = 44; - timing_int_pm_outer = 71; - timing_iret_rm = 15; - timing_iret_v86 = 36; /*unknown*/ - timing_iret_pm = 20; - timing_iret_pm_outer = 36; - timing_call_rm = 18; - timing_call_pm = 20; - timing_call_pm_gate = 35; - timing_call_pm_gate_inner = 69; - timing_retf_rm = 13; - timing_retf_pm = 17; - timing_retf_pm_outer = 35; - timing_jmp_rm = 17; - timing_jmp_pm = 19; - timing_jmp_pm_gate = 32; - timing_misaligned = 3; - break; - - case CPU_486SLC: -#ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_486_0f, dynarec_ops_386, dynarec_ops_486_0f); -#else - x86_setopcodes(ops_386, ops_486_0f); -#endif - timing_rr = 1; /*register dest - register src*/ - timing_rm = 3; /*register dest - memory src*/ - timing_mr = 5; /*memory dest - register src*/ - timing_mm = 3; - timing_rml = 5; /*register dest - memory src long*/ - timing_mrl = 7; /*memory dest - register src long*/ - timing_mml = 7; - timing_bt = 6-1; /*branch taken*/ - timing_bnt = 1; /*branch not taken*/ - /*unknown*/ - timing_int = 4; - timing_int_rm = 14; - timing_int_v86 = 82; - timing_int_pm = 49; - timing_int_pm_outer = 77; - timing_iret_rm = 14; - timing_iret_v86 = 66; - timing_iret_pm = 31; - timing_iret_pm_outer = 66; - timing_call_rm = 12; - timing_call_pm = 30; - timing_call_pm_gate = 41; - timing_call_pm_gate_inner = 83; - timing_retf_rm = 13; - timing_retf_pm = 26; - timing_retf_pm_outer = 61; - timing_jmp_rm = 9; - timing_jmp_pm = 26; - timing_jmp_pm_gate = 37; - timing_misaligned = 3; - break; - - case CPU_486DLC: -#ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_486_0f, dynarec_ops_386, dynarec_ops_486_0f); -#else - x86_setopcodes(ops_386, ops_486_0f); -#endif - timing_rr = 1; /*register dest - register src*/ - timing_rm = 3; /*register dest - memory src*/ - timing_mr = 3; /*memory dest - register src*/ - timing_mm = 3; - timing_rml = 3; /*register dest - memory src long*/ - timing_mrl = 3; /*memory dest - register src long*/ - timing_mml = 3; - timing_bt = 6-1; /*branch taken*/ - timing_bnt = 1; /*branch not taken*/ - /*unknown*/ - timing_int = 4; - timing_int_rm = 14; - timing_int_v86 = 82; - timing_int_pm = 49; - timing_int_pm_outer = 77; - timing_iret_rm = 14; - timing_iret_v86 = 66; - timing_iret_pm = 31; - timing_iret_pm_outer = 66; - timing_call_rm = 12; - timing_call_pm = 30; - timing_call_pm_gate = 41; - timing_call_pm_gate_inner = 83; - timing_retf_rm = 13; - timing_retf_pm = 26; - timing_retf_pm_outer = 61; - timing_jmp_rm = 9; - timing_jmp_pm = 26; - timing_jmp_pm_gate = 37; - timing_misaligned = 3; - break; - - case CPU_iDX4: + + timing_rr = 1; /* register dest - register src */ + timing_rm = 3; /* register dest - memory src */ + timing_mr = 3; /* memory dest - register src */ + timing_mm = 3; + timing_rml = 3; /* register dest - memory src long */ + timing_mrl = 3; /* memory dest - register src long */ + timing_mml = 3; + timing_bt = 5; /* branch taken */ + timing_bnt = 1; /* branch not taken */ + + timing_int = 4; /* unknown */ + timing_int_rm = 14; + timing_int_v86 = 82; + timing_int_pm = 49; + timing_int_pm_outer = 77; + timing_iret_rm = 14; + timing_iret_v86 = 66; + timing_iret_pm = 31; + timing_iret_pm_outer = 66; + timing_call_rm = 12; + timing_call_pm = 30; + timing_call_pm_gate = 41; + timing_call_pm_gate_inner = 83; + timing_retf_rm = 13; + timing_retf_pm = 26; + timing_retf_pm_outer = 61; + timing_jmp_rm = 9; + timing_jmp_pm = 26; + timing_jmp_pm_gate = 37; + + timing_misaligned = 3; + break; + + case CPU_iDX4: cpu_features = CPU_FEATURE_CR4 | CPU_FEATURE_VME; cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_VME; - /*FALLTHROUGH*/ - case CPU_i486SX: - case CPU_i486SX2: - case CPU_i486DX: - case CPU_i486DX2: + /* FALLTHROUGH */ + case CPU_RAPIDCAD: + case CPU_i486SX: + case CPU_i486SX2: + case CPU_i486DX: + case CPU_i486DX2: + case CPU_Am486SX: + case CPU_Am486SX2: + case CPU_Am486DX: + case CPU_Am486DX2: + case CPU_Am486DX4: + case CPU_Am5x86: + /*AMD timing identical to Intel*/ #ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_486_0f, dynarec_ops_386, dynarec_ops_486_0f); + x86_setopcodes(ops_386, ops_486_0f, dynarec_ops_386, dynarec_ops_486_0f); #else - x86_setopcodes(ops_386, ops_486_0f); + x86_setopcodes(ops_386, ops_486_0f); #endif - timing_rr = 1; /*register dest - register src*/ - timing_rm = 2; /*register dest - memory src*/ - timing_mr = 3; /*memory dest - register src*/ - timing_mm = 3; - timing_rml = 2; /*register dest - memory src long*/ - timing_mrl = 3; /*memory dest - register src long*/ - timing_mml = 3; - timing_bt = 3-1; /*branch taken*/ - timing_bnt = 1; /*branch not taken*/ - timing_int = 4; - timing_int_rm = 26; - timing_int_v86 = 82; - timing_int_pm = 44; - timing_int_pm_outer = 71; - timing_iret_rm = 15; - timing_iret_v86 = 36; /*unknown*/ - timing_iret_pm = 20; - timing_iret_pm_outer = 36; - timing_call_rm = 18; - timing_call_pm = 20; - timing_call_pm_gate = 35; - timing_call_pm_gate_inner = 69; - timing_retf_rm = 13; - timing_retf_pm = 17; - timing_retf_pm_outer = 35; - timing_jmp_rm = 17; - timing_jmp_pm = 19; - timing_jmp_pm_gate = 32; - timing_misaligned = 3; - break; - case CPU_Am486SX: - case CPU_Am486SX2: - case CPU_Am486DX: - case CPU_Am486DX2: - case CPU_Am486DX4: - case CPU_Am5x86: - /*AMD timing identical to Intel*/ -#ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_486_0f, dynarec_ops_386, dynarec_ops_486_0f); -#else - x86_setopcodes(ops_386, ops_486_0f); -#endif - timing_rr = 1; /*register dest - register src*/ - timing_rm = 2; /*register dest - memory src*/ - timing_mr = 3; /*memory dest - register src*/ - timing_mm = 3; - timing_rml = 2; /*register dest - memory src long*/ - timing_mrl = 3; /*memory dest - register src long*/ - timing_mml = 3; - timing_bt = 3-1; /*branch taken*/ - timing_bnt = 1; /*branch not taken*/ - timing_int = 4; - timing_int_rm = 26; - timing_int_v86 = 82; - timing_int_pm = 44; - timing_int_pm_outer = 71; - timing_iret_rm = 15; - timing_iret_v86 = 36; /*unknown*/ - timing_iret_pm = 20; - timing_iret_pm_outer = 36; - timing_call_rm = 18; - timing_call_pm = 20; - timing_call_pm_gate = 35; - timing_call_pm_gate_inner = 69; - timing_retf_rm = 13; - timing_retf_pm = 17; - timing_retf_pm_outer = 35; - timing_jmp_rm = 17; - timing_jmp_pm = 19; - timing_jmp_pm_gate = 32; - timing_misaligned = 3; - break; - - case CPU_Cx486S: - case CPU_Cx486DX: - case CPU_Cx486DX2: - case CPU_Cx486DX4: -#ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_486_0f, dynarec_ops_386, dynarec_ops_486_0f); -#else - x86_setopcodes(ops_386, ops_486_0f); -#endif - timing_rr = 1; /*register dest - register src*/ - timing_rm = 3; /*register dest - memory src*/ - timing_mr = 3; /*memory dest - register src*/ - timing_mm = 3; - timing_rml = 3; /*register dest - memory src long*/ - timing_mrl = 3; /*memory dest - register src long*/ - timing_mml = 3; - timing_bt = 4-1; /*branch taken*/ - timing_bnt = 1; /*branch not taken*/ - timing_int = 4; - timing_int_rm = 14; - timing_int_v86 = 82; - timing_int_pm = 49; - timing_int_pm_outer = 77; - timing_iret_rm = 14; - timing_iret_v86 = 66; /*unknown*/ - timing_iret_pm = 31; - timing_iret_pm_outer = 66; - timing_call_rm = 12; - timing_call_pm = 30; - timing_call_pm_gate = 41; - timing_call_pm_gate_inner = 83; - timing_retf_rm = 13; - timing_retf_pm = 26; - timing_retf_pm_outer = 61; - timing_jmp_rm = 9; - timing_jmp_pm = 26; - timing_jmp_pm_gate = 37; - timing_misaligned = 3; - break; - - case CPU_Cx5x86: -#ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_486_0f, dynarec_ops_386, dynarec_ops_486_0f); -#else - x86_setopcodes(ops_386, ops_486_0f); -#endif - timing_rr = 1; /*register dest - register src*/ - timing_rm = 1; /*register dest - memory src*/ - timing_mr = 2; /*memory dest - register src*/ - timing_mm = 2; - timing_rml = 1; /*register dest - memory src long*/ - timing_mrl = 2; /*memory dest - register src long*/ - timing_mml = 2; - timing_bt = 5-1; /*branch taken*/ - timing_bnt = 1; /*branch not taken*/ - timing_int = 0; - timing_int_rm = 9; - timing_int_v86 = 82; /*unknown*/ - timing_int_pm = 21; - timing_int_pm_outer = 32; - timing_iret_rm = 7; - timing_iret_v86 = 26; /*unknown*/ - timing_iret_pm = 10; - timing_iret_pm_outer = 26; - timing_call_rm = 4; - timing_call_pm = 15; - timing_call_pm_gate = 26; - timing_call_pm_gate_inner = 35; - timing_retf_rm = 4; - timing_retf_pm = 7; - timing_retf_pm_outer = 23; - timing_jmp_rm = 5; - timing_jmp_pm = 7; - timing_jmp_pm_gate = 17; - timing_misaligned = 2; - cpu_cyrix_alignment = 1; - break; + timing_rr = 1; /* register dest - register src */ + timing_rm = 2; /* register dest - memory src */ + timing_mr = 3; /* memory dest - register src */ + timing_mm = 3; + timing_rml = 2; /* register dest - memory src long */ + timing_mrl = 3; /* memory dest - register src long */ + timing_mml = 3; + timing_bt = 2; /* branch taken */ + timing_bnt = 1; /* branch not taken */ - case CPU_WINCHIP: + timing_int = 4; + timing_int_rm = 26; + timing_int_v86 = 82; + timing_int_pm = 44; + timing_int_pm_outer = 71; + timing_iret_rm = 15; + timing_iret_v86 = 36; /* unknown */ + timing_iret_pm = 20; + timing_iret_pm_outer = 36; + timing_call_rm = 18; + timing_call_pm = 20; + timing_call_pm_gate = 35; + timing_call_pm_gate_inner = 69; + timing_retf_rm = 13; + timing_retf_pm = 17; + timing_retf_pm_outer = 35; + timing_jmp_rm = 17; + timing_jmp_pm = 19; + timing_jmp_pm_gate = 32; + + timing_misaligned = 3; + break; + + case CPU_Cx486S: + case CPU_Cx486DX: + case CPU_Cx486DX2: + case CPU_Cx486DX4: #ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_winchip_0f, dynarec_ops_386, dynarec_ops_winchip_0f); + x86_setopcodes(ops_386, ops_486_0f, dynarec_ops_386, dynarec_ops_486_0f); #else - x86_setopcodes(ops_386, ops_winchip_0f); + x86_setopcodes(ops_386, ops_486_0f); #endif - timing_rr = 1; /*register dest - register src*/ - timing_rm = 2; /*register dest - memory src*/ - timing_mr = 2; /*memory dest - register src*/ - timing_mm = 3; - timing_rml = 2; /*register dest - memory src long*/ - timing_mrl = 2; /*memory dest - register src long*/ - timing_mml = 3; - timing_bt = 3-1; /*branch taken*/ - timing_bnt = 1; /*branch not taken*/ - cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MMX | CPU_FEATURE_MSR | CPU_FEATURE_CR4; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE; + + timing_rr = 1; /* register dest - register src */ + timing_rm = 3; /* register dest - memory src */ + timing_mr = 3; /* memory dest - register src */ + timing_mm = 3; + timing_rml = 3; /* register dest - memory src long */ + timing_mrl = 3; /* memory dest - register src long */ + timing_mml = 3; + timing_bt = 3; /* branch taken */ + timing_bnt = 1; /* branch not taken */ + + timing_int = 4; + timing_int_rm = 14; + timing_int_v86 = 82; + timing_int_pm = 49; + timing_int_pm_outer = 77; + timing_iret_rm = 14; + timing_iret_v86 = 66; /* unknown */ + timing_iret_pm = 31; + timing_iret_pm_outer = 66; + timing_call_rm = 12; + timing_call_pm = 30; + timing_call_pm_gate = 41; + timing_call_pm_gate_inner = 83; + timing_retf_rm = 13; + timing_retf_pm = 26; + timing_retf_pm_outer = 61; + timing_jmp_rm = 9; + timing_jmp_pm = 26; + timing_jmp_pm_gate = 37; + + timing_misaligned = 3; + break; + + case CPU_Cx5x86: +#ifdef USE_DYNAREC + x86_setopcodes(ops_386, ops_486_0f, dynarec_ops_386, dynarec_ops_486_0f); +#else + x86_setopcodes(ops_386, ops_486_0f); +#endif + + timing_rr = 1; /* register dest - register src */ + timing_rm = 1; /* register dest - memory src */ + timing_mr = 2; /* memory dest - register src */ + timing_mm = 2; + timing_rml = 1; /* register dest - memory src long */ + timing_mrl = 2; /* memory dest - register src long */ + timing_mml = 2; + timing_bt = 4; /* branch taken */ + timing_bnt = 1; /* branch not taken */ + + timing_int = 0; + timing_int_rm = 9; + timing_int_v86 = 82; /* unknown */ + timing_int_pm = 21; + timing_int_pm_outer = 32; + timing_iret_rm = 7; + timing_iret_v86 = 26; /* unknown */ + timing_iret_pm = 10; + timing_iret_pm_outer = 26; + timing_call_rm = 4; + timing_call_pm = 15; + timing_call_pm_gate = 26; + timing_call_pm_gate_inner = 35; + timing_retf_rm = 4; + timing_retf_pm = 7; + timing_retf_pm_outer = 23; + timing_jmp_rm = 5; + timing_jmp_pm = 7; + timing_jmp_pm_gate = 17; + + timing_misaligned = 2; + + cpu_cyrix_alignment = 1; + break; + + case CPU_WINCHIP: + case CPU_WINCHIP2: +#ifdef USE_DYNAREC + if (cpu_s->cpu_type == CPU_WINCHIP2) + x86_setopcodes(ops_386, ops_winchip2_0f, dynarec_ops_386, dynarec_ops_winchip2_0f); + else + x86_setopcodes(ops_386, ops_winchip_0f, dynarec_ops_386, dynarec_ops_winchip_0f); +#else + if (cpu_s->cpu_type == CPU_WINCHIP2) + x86_setopcodes(ops_386, ops_winchip2_0f); + else + x86_setopcodes(ops_386, ops_winchip_0f); +#endif + + timing_rr = 1; /* register dest - register src */ + timing_rm = 2; /* register dest - memory src */ + timing_mr = 2; /* memory dest - register src */ + timing_mm = 3; + timing_rml = 2; /* register dest - memory src long */ + timing_mrl = 2; /* memory dest - register src long */ + timing_mml = 3; + timing_bt = 2; /* branch taken */ + timing_bnt = 1; /* branch not taken */ + /*unknown*/ - timing_int_rm = 26; - timing_int_v86 = 82; - timing_int_pm = 44; - timing_int_pm_outer = 71; - timing_iret_rm = 7; - timing_iret_v86 = 26; - timing_iret_pm = 10; - timing_iret_pm_outer = 26; - timing_call_rm = 4; - timing_call_pm = 15; - timing_call_pm_gate = 26; - timing_call_pm_gate_inner = 35; - timing_retf_rm = 4; - timing_retf_pm = 7; - timing_retf_pm_outer = 23; - timing_jmp_rm = 5; - timing_jmp_pm = 7; - timing_jmp_pm_gate = 17; -#ifdef USE_DYNAREC - codegen_timing_set(&codegen_timing_winchip); -#endif - timing_misaligned = 2; - cpu_cyrix_alignment = 1; - break; + timing_int_rm = 26; + timing_int_v86 = 82; + timing_int_pm = 44; + timing_int_pm_outer = 71; + timing_iret_rm = 7; + timing_iret_v86 = 26; + timing_iret_pm = 10; + timing_iret_pm_outer = 26; + timing_call_rm = 4; + timing_call_pm = 15; + timing_call_pm_gate = 26; + timing_call_pm_gate_inner = 35; + timing_retf_rm = 4; + timing_retf_pm = 7; + timing_retf_pm_outer = 23; + timing_jmp_rm = 5; + timing_jmp_pm = 7; + timing_jmp_pm_gate = 17; + + timing_misaligned = 2; + + cpu_cyrix_alignment = 1; + + cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MMX | CPU_FEATURE_MSR | CPU_FEATURE_CR4; + if (cpu_s->cpu_type == CPU_WINCHIP2) + cpu_features |= CPU_FEATURE_3DNOW; + msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); + if (cpu_s->cpu_type == CPU_WINCHIP2) + msr.fcr |= (1 << 18) | (1 << 20); + cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE; - case CPU_WINCHIP2: -#ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_winchip2_0f, dynarec_ops_386, dynarec_ops_winchip2_0f); -#else - x86_setopcodes(ops_386, ops_winchip2_0f); -#endif - timing_rr = 1; /*register dest - register src*/ - timing_rm = 2; /*register dest - memory src*/ - timing_mr = 2; /*memory dest - register src*/ - timing_mm = 3; - timing_rml = 2; /*register dest - memory src long*/ - timing_mrl = 2; /*memory dest - register src long*/ - timing_mml = 3; - timing_bt = 3-1; /*branch taken*/ - timing_bnt = 1; /*branch not taken*/ - cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MMX | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_3DNOW; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 18) | (1 << 19) | (1 << 20) | (1 << 21); - cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE; - /*unknown*/ - timing_int_rm = 26; - timing_int_v86 = 82; - timing_int_pm = 44; - timing_int_pm_outer = 71; - timing_iret_rm = 7; - timing_iret_v86 = 26; - timing_iret_pm = 10; - timing_iret_pm_outer = 26; - timing_call_rm = 4; - timing_call_pm = 15; - timing_call_pm_gate = 26; - timing_call_pm_gate_inner = 35; - timing_retf_rm = 4; - timing_retf_pm = 7; - timing_retf_pm_outer = 23; - timing_jmp_rm = 5; - timing_jmp_pm = 7; - timing_jmp_pm_gate = 17; - timing_misaligned = 2; - cpu_cyrix_alignment = 1; #ifdef USE_DYNAREC - codegen_timing_set(&codegen_timing_winchip2); + if (cpu_s->cpu_type == CPU_WINCHIP2) + codegen_timing_set(&codegen_timing_winchip2); + else + codegen_timing_set(&codegen_timing_winchip); #endif - break; + break; - case CPU_P24T: - case CPU_PENTIUM: + case CPU_P24T: + case CPU_PENTIUM: + case CPU_PENTIUMMMX: #ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_pentium_0f, dynarec_ops_386, dynarec_ops_pentium_0f); + if (cpu_s->cpu_type == CPU_PENTIUMMMX) + x86_setopcodes(ops_386, ops_pentiummmx_0f, dynarec_ops_386, dynarec_ops_pentiummmx_0f); + else + x86_setopcodes(ops_386, ops_pentium_0f, dynarec_ops_386, dynarec_ops_pentium_0f); #else - x86_setopcodes(ops_386, ops_pentium_0f); + if (cpu_s->cpu_type == CPU_PENTIUMMMX) + x86_setopcodes(ops_386, ops_pentiummmx_0f); + else + x86_setopcodes(ops_386, ops_pentium_0f); #endif - timing_rr = 1; /*register dest - register src*/ - timing_rm = 2; /*register dest - memory src*/ - timing_mr = 3; /*memory dest - register src*/ - timing_mm = 3; - timing_rml = 2; /*register dest - memory src long*/ - timing_mrl = 3; /*memory dest - register src long*/ - timing_mml = 3; - timing_bt = 0; /*branch taken*/ - timing_bnt = 2; /*branch not taken*/ - timing_int = 6; - timing_int_rm = 11; - timing_int_v86 = 54; - timing_int_pm = 25; - timing_int_pm_outer = 42; - timing_iret_rm = 7; - timing_iret_v86 = 27; /*unknown*/ - timing_iret_pm = 10; - timing_iret_pm_outer = 27; - timing_call_rm = 4; - timing_call_pm = 4; - timing_call_pm_gate = 22; - timing_call_pm_gate_inner = 44; - timing_retf_rm = 4; - timing_retf_pm = 4; - timing_retf_pm_outer = 23; - timing_jmp_rm = 3; - timing_jmp_pm = 3; - timing_jmp_pm_gate = 18; - timing_misaligned = 3; - cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE; -#ifdef USE_DYNAREC - codegen_timing_set(&codegen_timing_pentium); -#endif - break; - case CPU_PENTIUMMMX: + timing_rr = 1; /* register dest - register src */ + timing_rm = 2; /* register dest - memory src */ + timing_mr = 3; /* memory dest - register src */ + timing_mm = 3; + timing_rml = 2; /* register dest - memory src long */ + timing_mrl = 3; /* memory dest - register src long */ + timing_mml = 3; + timing_bt = 0; /* branch taken */ + if (cpu_s->cpu_type == CPU_PENTIUMMMX) + timing_bnt = 1; /* branch not taken */ + else + timing_bnt = 2; /* branch not taken */ + + timing_int = 6; + timing_int_rm = 11; + timing_int_v86 = 54; + timing_int_pm = 25; + timing_int_pm_outer = 42; + timing_iret_rm = 7; + timing_iret_v86 = 27; /* unknown */ + timing_iret_pm = 10; + timing_iret_pm_outer = 27; + timing_call_rm = 4; + timing_call_pm = 4; + timing_call_pm_gate = 22; + timing_call_pm_gate_inner = 44; + timing_retf_rm = 4; + timing_retf_pm = 4; + timing_retf_pm_outer = 23; + timing_jmp_rm = 3; + timing_jmp_pm = 3; + timing_jmp_pm_gate = 18; + + timing_misaligned = 3; + + cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME; + if (cpu_s->cpu_type == CPU_PENTIUMMMX) + cpu_features |= CPU_FEATURE_MMX; + msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); + cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE; #ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_pentiummmx_0f, dynarec_ops_386, dynarec_ops_pentiummmx_0f); -#else - x86_setopcodes(ops_386, ops_pentiummmx_0f); + codegen_timing_set(&codegen_timing_pentium); #endif - timing_rr = 1; /*register dest - register src*/ - timing_rm = 2; /*register dest - memory src*/ - timing_mr = 3; /*memory dest - register src*/ - timing_mm = 3; - timing_rml = 2; /*register dest - memory src long*/ - timing_mrl = 3; /*memory dest - register src long*/ - timing_mml = 3; - timing_bt = 0; /*branch taken*/ - timing_bnt = 1; /*branch not taken*/ - timing_int = 6; - timing_int_rm = 11; - timing_int_v86 = 54; - timing_int_pm = 25; - timing_int_pm_outer = 42; - timing_iret_rm = 7; - timing_iret_v86 = 27; /*unknown*/ - timing_iret_pm = 10; - timing_iret_pm_outer = 27; - timing_call_rm = 4; - timing_call_pm = 4; - timing_call_pm_gate = 22; - timing_call_pm_gate_inner = 44; - timing_retf_rm = 4; - timing_retf_pm = 4; - timing_retf_pm_outer = 23; - timing_jmp_rm = 3; - timing_jmp_pm = 3; - timing_jmp_pm_gate = 18; - timing_misaligned = 3; - cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_MMX; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE; -#ifdef USE_DYNAREC - codegen_timing_set(&codegen_timing_pentium); -#endif - break; + break; #if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) - case CPU_Cx6x86: + case CPU_Cx6x86: + case CPU_Cx6x86L: + case CPU_CxGX1: + case CPU_Cx6x86MX: + if (cpu_s->cpu_type == CPU_Cx6x86MX) { #ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_c6x86_0f, dynarec_ops_386, dynarec_ops_c6x86_0f); -#else - x86_setopcodes(ops_386, ops_c6x86_0f); + x86_setopcodes(ops_386, ops_c6x86mx_0f, dynarec_ops_386, dynarec_ops_c6x86mx_0f); + x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_686_da_a16; + x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_686_da_a32; + x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_686_db_a16; + x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_686_db_a32; + x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_686_df_a16; + x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_686_df_a32; #endif - timing_rr = 1; /*register dest - register src*/ - timing_rm = 1; /*register dest - memory src*/ - timing_mr = 2; /*memory dest - register src*/ - timing_mm = 2; - timing_rml = 1; /*register dest - memory src long*/ - timing_mrl = 2; /*memory dest - register src long*/ - timing_mml = 2; - timing_bt = 0; /*branch taken*/ - timing_bnt = 2; /*branch not taken*/ - timing_int_rm = 9; - timing_int_v86 = 46; - timing_int_pm = 21; - timing_int_pm_outer = 32; - timing_iret_rm = 7; - timing_iret_v86 = 26; - timing_iret_pm = 10; - timing_iret_pm_outer = 26; - timing_call_rm = 3; - timing_call_pm = 4; - timing_call_pm_gate = 15; - timing_call_pm_gate_inner = 26; - timing_retf_rm = 4; - timing_retf_pm = 4; - timing_retf_pm_outer = 23; - timing_jmp_rm = 1; - timing_jmp_pm = 4; - timing_jmp_pm_gate = 14; - timing_misaligned = 2; - cpu_cyrix_alignment = 1; - cpu_features = CPU_FEATURE_RDTSC; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); -#ifdef USE_DYNAREC - codegen_timing_set(&codegen_timing_686); -#endif - CPUID = 0; /*Disabled on powerup by default*/ - break; + x86_opcodes_da_a16 = ops_fpu_686_da_a16; + x86_opcodes_da_a32 = ops_fpu_686_da_a32; + x86_opcodes_db_a16 = ops_fpu_686_db_a16; + x86_opcodes_db_a32 = ops_fpu_686_db_a32; + x86_opcodes_df_a16 = ops_fpu_686_df_a16; + x86_opcodes_df_a32 = ops_fpu_686_df_a32; + } - case CPU_Cx6x86L: #ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_pentium_0f, dynarec_ops_386, dynarec_ops_pentium_0f); + if (cpu_s->cpu_type == CPU_Cx6x86MX) + x86_setopcodes(ops_386, ops_c6x86mx_0f, dynarec_ops_386, dynarec_ops_c6x86mx_0f); + else if (cpu_s->cpu_type == CPU_Cx6x86L) + x86_setopcodes(ops_386, ops_pentium_0f, dynarec_ops_386, dynarec_ops_pentium_0f); + else + x86_setopcodes(ops_386, ops_c6x86_0f, dynarec_ops_386, dynarec_ops_c6x86_0f); #else - x86_setopcodes(ops_386, ops_pentium_0f); + if (cpu_s->cpu_type == CPU_Cx6x86MX) + x86_setopcodes(ops_386, ops_c6x86mx_0f); + else if (cpu_s->cpu_type == CPU_Cx6x86L) + x86_setopcodes(ops_386, ops_pentium_0f); + else + x86_setopcodes(ops_386, ops_c6x86_0f); #endif - timing_rr = 1; /*register dest - register src*/ - timing_rm = 1; /*register dest - memory src*/ - timing_mr = 2; /*memory dest - register src*/ - timing_mm = 2; - timing_rml = 1; /*register dest - memory src long*/ - timing_mrl = 2; /*memory dest - register src long*/ - timing_mml = 2; - timing_bt = 0; /*branch taken*/ - timing_bnt = 2; /*branch not taken*/ - timing_int_rm = 9; - timing_int_v86 = 46; - timing_int_pm = 21; - timing_int_pm_outer = 32; - timing_iret_rm = 7; - timing_iret_v86 = 26; - timing_iret_pm = 10; - timing_iret_pm_outer = 26; - timing_call_rm = 3; - timing_call_pm = 4; - timing_call_pm_gate = 15; - timing_call_pm_gate_inner = 26; - timing_retf_rm = 4; - timing_retf_pm = 4; - timing_retf_pm_outer = 23; - timing_jmp_rm = 1; - timing_jmp_pm = 4; - timing_jmp_pm_gate = 14; - timing_misaligned = 2; - cpu_cyrix_alignment = 1; - cpu_features = CPU_FEATURE_RDTSC; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); -#ifdef USE_DYNAREC - codegen_timing_set(&codegen_timing_686); -#endif - ccr4 = 0x80; - break; + timing_rr = 1; /* register dest - register src */ + timing_rm = 1; /* register dest - memory src */ + timing_mr = 2; /* memory dest - register src */ + timing_mm = 2; + timing_rml = 1; /* register dest - memory src long */ + timing_mrl = 2; /* memory dest - register src long */ + timing_mml = 2; + if (cpu_s->cpu_type == CPU_CxGX1) { + timing_bt = 4; /* branch taken */ + timing_bnt = 1; /* branch not taken */ + } else { + timing_bt = 0; /* branch taken */ + timing_bnt = 2; /* branch not taken */ + } - case CPU_CxGX1: -#ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_pentium_0f, dynarec_ops_386, dynarec_ops_pentium_0f); -#else - x86_setopcodes(ops_386, ops_pentium_0f); -#endif - timing_rr = 1; /*register dest - register src*/ - timing_rm = 1; /*register dest - memory src*/ - timing_mr = 2; /*memory dest - register src*/ - timing_mm = 2; - timing_rml = 1; /*register dest - memory src long*/ - timing_mrl = 2; /*memory dest - register src long*/ - timing_mml = 2; - timing_bt = 5-1; /*branch taken*/ - timing_bnt = 1; /*branch not taken*/ - timing_misaligned = 2; - cpu_cyrix_alignment = 1; - cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_PCE; -#ifdef USE_DYNAREC - codegen_timing_set(&codegen_timing_686); -#endif - break; + /* Make the CxGX1 share the timings with most other Cyrix C6x86's due to the real + ones still being unknown. */ + timing_int_rm = 9; + timing_int_v86 = 46; + timing_int_pm = 21; + timing_int_pm_outer = 32; + timing_iret_rm = 7; + timing_iret_v86 = 26; + timing_iret_pm = 10; + timing_iret_pm_outer = 26; + timing_call_rm = 3; + timing_call_pm = 4; + timing_call_pm_gate = 15; + timing_call_pm_gate_inner = 26; + timing_retf_rm = 4; + timing_retf_pm = 4; + timing_retf_pm_outer = 23; + timing_jmp_rm = 1; + timing_jmp_pm = 4; + timing_jmp_pm_gate = 14; + + timing_misaligned = 2; + + cpu_cyrix_alignment = 1; + + cpu_features = CPU_FEATURE_RDTSC; + if (cpu_s->cpu_type >= CPU_CxGX1) + cpu_features |= CPU_FEATURE_MSR | CPU_FEATURE_CR4; + if (cpu_s->cpu_type == CPU_Cx6x86MX) + cpu_features |= CPU_FEATURE_MMX; + msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); + if (cpu_s->cpu_type >= CPU_CxGX1) + cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_PCE; - - case CPU_Cx6x86MX: #ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_c6x86mx_0f, dynarec_ops_386, dynarec_ops_c6x86mx_0f); - x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_686_da_a16; - x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_686_da_a32; - x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_686_db_a16; - x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_686_db_a32; - x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_686_df_a16; - x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_686_df_a32; -#else - x86_setopcodes(ops_386, ops_c6x86mx_0f); + codegen_timing_set(&codegen_timing_686); #endif - x86_opcodes_da_a16 = ops_fpu_686_da_a16; - x86_opcodes_da_a32 = ops_fpu_686_da_a32; - x86_opcodes_db_a16 = ops_fpu_686_db_a16; - x86_opcodes_db_a32 = ops_fpu_686_db_a32; - x86_opcodes_df_a16 = ops_fpu_686_df_a16; - x86_opcodes_df_a32 = ops_fpu_686_df_a32; - timing_rr = 1; /*register dest - register src*/ - timing_rm = 1; /*register dest - memory src*/ - timing_mr = 2; /*memory dest - register src*/ - timing_mm = 2; - timing_rml = 1; /*register dest - memory src long*/ - timing_mrl = 2; /*memory dest - register src long*/ - timing_mml = 2; - timing_bt = 0; /*branch taken*/ - timing_bnt = 2; /*branch not taken*/ - timing_int_rm = 9; - timing_int_v86 = 46; - timing_int_pm = 21; - timing_int_pm_outer = 32; - timing_iret_rm = 7; - timing_iret_v86 = 26; - timing_iret_pm = 10; - timing_iret_pm_outer = 26; - timing_call_rm = 3; - timing_call_pm = 4; - timing_call_pm_gate = 15; - timing_call_pm_gate_inner = 26; - timing_retf_rm = 4; - timing_retf_pm = 4; - timing_retf_pm_outer = 23; - timing_jmp_rm = 1; - timing_jmp_pm = 4; - timing_jmp_pm_gate = 14; - timing_misaligned = 2; - cpu_cyrix_alignment = 1; - cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_MMX; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_PCE; -#ifdef USE_DYNAREC - codegen_timing_set(&codegen_timing_686); -#endif - ccr4 = 0x80; - break; + + if ((cpu_s->cpu_type == CPU_Cx6x86L) || (cpu_s->cpu_type == CPU_Cx6x86MX)) + ccr4 = 0x80; + else if (CPU_Cx6x86) + CPUID = 0; /* Disabled on powerup by default */ + break; #endif #if defined(DEV_BRANCH) && defined(USE_AMD_K5) - case CPU_K5: - case CPU_5K86: -#ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_pentiummmx_0f, dynarec_ops_386, dynarec_ops_pentiummmx_0f); -#else - x86_setopcodes(ops_386, ops_pentiummmx_0f); + case CPU_K5: + case CPU_5K86: #endif - timing_rr = 1; /*register dest - register src*/ - timing_rm = 2; /*register dest - memory src*/ - timing_mr = 3; /*memory dest - register src*/ - timing_mm = 3; - timing_rml = 2; /*register dest - memory src long*/ - timing_mrl = 3; /*memory dest - register src long*/ - timing_mml = 3; - timing_bt = 0; /*branch taken*/ - timing_bnt = 1; /*branch not taken*/ - timing_int = 6; - timing_int_rm = 11; - timing_int_v86 = 54; - timing_int_pm = 25; - timing_int_pm_outer = 42; - timing_iret_rm = 7; - timing_iret_v86 = 27; /*unknown*/ - timing_iret_pm = 10; - timing_iret_pm_outer = 27; - timing_call_rm = 4; - timing_call_pm = 4; - timing_call_pm_gate = 22; - timing_call_pm_gate_inner = 44; - timing_retf_rm = 4; - timing_retf_pm = 4; - timing_retf_pm_outer = 23; - timing_jmp_rm = 3; - timing_jmp_pm = 3; - timing_jmp_pm_gate = 18; - timing_misaligned = 3; - cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_MMX; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE; + case CPU_K6: + case CPU_K6_2: + case CPU_K6_2C: + case CPU_K6_3: + case CPU_K6_2P: + case CPU_K6_3P: #ifdef USE_DYNAREC - codegen_timing_set(&codegen_timing_k6); -#endif - break; -#endif - - case CPU_K6: -#ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_k6_0f, dynarec_ops_386, dynarec_ops_k6_0f); -#else - x86_setopcodes(ops_386, ops_k6_0f); -#endif - timing_rr = 1; /*register dest - register src*/ - timing_rm = 2; /*register dest - memory src*/ - timing_mr = 3; /*memory dest - register src*/ - timing_mm = 3; - timing_rml = 2; /*register dest - memory src long*/ - timing_mrl = 3; /*memory dest - register src long*/ - timing_mml = 3; - timing_bt = 0; /*branch taken*/ - timing_bnt = 1; /*branch not taken*/ - timing_int = 6; - timing_int_rm = 11; - timing_int_v86 = 54; - timing_int_pm = 25; - timing_int_pm_outer = 42; - timing_iret_rm = 7; - timing_iret_v86 = 27; /*unknown*/ - timing_iret_pm = 10; - timing_iret_pm_outer = 27; - timing_call_rm = 4; - timing_call_pm = 4; - timing_call_pm_gate = 22; - timing_call_pm_gate_inner = 44; - timing_retf_rm = 4; - timing_retf_pm = 4; - timing_retf_pm_outer = 23; - timing_jmp_rm = 3; - timing_jmp_pm = 3; - timing_jmp_pm_gate = 18; - timing_misaligned = 3; - cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_MMX; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE; -#ifdef USE_DYNAREC - codegen_timing_set(&codegen_timing_k6); -#endif - break; - - case CPU_K6_2: - case CPU_K6_2C: - case CPU_K6_3: - case CPU_K6_2P: - case CPU_K6_3P: -#ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_k62_0f, dynarec_ops_386, dynarec_ops_k62_0f); -#else - x86_setopcodes(ops_386, ops_k62_0f); -#endif - timing_rr = 1; /*register dest - register src*/ - timing_rm = 2; /*register dest - memory src*/ - timing_mr = 3; /*memory dest - register src*/ - timing_mm = 3; - timing_rml = 2; /*register dest - memory src long*/ - timing_mrl = 3; /*memory dest - register src long*/ - timing_mml = 3; - timing_bt = 0; /*branch taken*/ - timing_bnt = 1; /*branch not taken*/ - timing_int = 6; - timing_int_rm = 11; - timing_int_v86 = 54; - timing_int_pm = 25; - timing_int_pm_outer = 42; - timing_iret_rm = 7; - timing_iret_v86 = 27; /*unknown*/ - timing_iret_pm = 10; - timing_iret_pm_outer = 27; - timing_call_rm = 4; - timing_call_pm = 4; - timing_call_pm_gate = 22; - timing_call_pm_gate_inner = 44; - timing_retf_rm = 4; - timing_retf_pm = 4; - timing_retf_pm_outer = 23; - timing_jmp_rm = 3; - timing_jmp_pm = 3; - timing_jmp_pm_gate = 18; - timing_misaligned = 3; - cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_MMX | CPU_FEATURE_3DNOW; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE; -#ifdef USE_DYNAREC - codegen_timing_set(&codegen_timing_k6); -#endif - break; - - case CPU_PENTIUMPRO: -#ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_pentiumpro_0f, dynarec_ops_386, dynarec_ops_pentiumpro_0f); - x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_686_da_a16; - x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_686_da_a32; - x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_686_db_a16; - x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_686_db_a32; - x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_686_df_a16; - x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_686_df_a32; -#else - x86_setopcodes(ops_386, ops_pentiumpro_0f); -#endif - x86_opcodes_da_a16 = ops_fpu_686_da_a16; - x86_opcodes_da_a32 = ops_fpu_686_da_a32; - x86_opcodes_db_a16 = ops_fpu_686_db_a16; - x86_opcodes_db_a32 = ops_fpu_686_db_a32; - x86_opcodes_df_a16 = ops_fpu_686_df_a16; - x86_opcodes_df_a32 = ops_fpu_686_df_a32; - timing_rr = 1; /*register dest - register src*/ - timing_rm = 2; /*register dest - memory src*/ - timing_mr = 3; /*memory dest - register src*/ - timing_mm = 3; - timing_rml = 2; /*register dest - memory src long*/ - timing_mrl = 3; /*memory dest - register src long*/ - timing_mml = 3; - timing_bt = 0; /*branch taken*/ - timing_bnt = 1; /*branch not taken*/ - timing_int = 6; - timing_int_rm = 11; - timing_int_v86 = 54; - timing_int_pm = 25; - timing_int_pm_outer = 42; - timing_iret_rm = 7; - timing_iret_v86 = 27; /*unknown*/ - timing_iret_pm = 10; - timing_iret_pm_outer = 27; - timing_call_rm = 4; - timing_call_pm = 4; - timing_call_pm_gate = 22; - timing_call_pm_gate_inner = 44; - timing_retf_rm = 4; - timing_retf_pm = 4; - timing_retf_pm_outer = 23; - timing_jmp_rm = 3; - timing_jmp_pm = 3; - timing_jmp_pm_gate = 18; - timing_misaligned = 3; - cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_PAE | CR4_MCE | CR4_PCE; -#ifdef USE_DYNAREC - codegen_timing_set(&codegen_timing_p6); -#endif - break; - - case CPU_PENTIUM2: -#ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_pentium2_0f, dynarec_ops_386, dynarec_ops_pentium2_0f); - x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_686_da_a16; - x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_686_da_a32; - x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_686_db_a16; - x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_686_db_a32; - x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_686_df_a16; - x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_686_df_a32; -#else - x86_setopcodes(ops_386, ops_pentium2_0f); -#endif - x86_opcodes_da_a16 = ops_fpu_686_da_a16; - x86_opcodes_da_a32 = ops_fpu_686_da_a32; - x86_opcodes_db_a16 = ops_fpu_686_db_a16; - x86_opcodes_db_a32 = ops_fpu_686_db_a32; - x86_opcodes_df_a16 = ops_fpu_686_df_a16; - x86_opcodes_df_a32 = ops_fpu_686_df_a32; - timing_rr = 1; /*register dest - register src*/ - timing_rm = 2; /*register dest - memory src*/ - timing_mr = 3; /*memory dest - register src*/ - timing_mm = 3; - timing_rml = 2; /*register dest - memory src long*/ - timing_mrl = 3; /*memory dest - register src long*/ - timing_mml = 3; - timing_bt = 0; /*branch taken*/ - timing_bnt = 1; /*branch not taken*/ - timing_int = 6; - timing_int_rm = 11; - timing_int_v86 = 54; - timing_int_pm = 25; - timing_int_pm_outer = 42; - timing_iret_rm = 7; - timing_iret_v86 = 27; /*unknown*/ - timing_iret_pm = 10; - timing_iret_pm_outer = 27; - timing_call_rm = 4; - timing_call_pm = 4; - timing_call_pm_gate = 22; - timing_call_pm_gate_inner = 44; - timing_retf_rm = 4; - timing_retf_pm = 4; - timing_retf_pm_outer = 23; - timing_jmp_rm = 3; - timing_jmp_pm = 3; - timing_jmp_pm_gate = 18; - timing_misaligned = 3; - cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_MMX; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_PAE | CR4_MCE | CR4_PCE; -#ifdef USE_DYNAREC - codegen_timing_set(&codegen_timing_p6); -#endif - break; - - case CPU_PENTIUM2D: -#ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_pentium2d_0f, dynarec_ops_386, dynarec_ops_pentium2d_0f); - x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_686_da_a16; - x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_686_da_a32; - x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_686_db_a16; - x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_686_db_a32; - x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_686_df_a16; - x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_686_df_a32; -#else - x86_setopcodes(ops_386, ops_pentium2d_0f); -#endif - x86_opcodes_da_a16 = ops_fpu_686_da_a16; - x86_opcodes_da_a32 = ops_fpu_686_da_a32; - x86_opcodes_db_a16 = ops_fpu_686_db_a16; - x86_opcodes_db_a32 = ops_fpu_686_db_a32; - x86_opcodes_df_a16 = ops_fpu_686_df_a16; - x86_opcodes_df_a32 = ops_fpu_686_df_a32; - timing_rr = 1; /*register dest - register src*/ - timing_rm = 2; /*register dest - memory src*/ - timing_mr = 3; /*memory dest - register src*/ - timing_mm = 3; - timing_rml = 2; /*register dest - memory src long*/ - timing_mrl = 3; /*memory dest - register src long*/ - timing_mml = 3; - timing_bt = 0; /*branch taken*/ - timing_bnt = 1; /*branch not taken*/ - timing_int = 6; - timing_int_rm = 11; - timing_int_v86 = 54; - timing_int_pm = 25; - timing_int_pm_outer = 42; - timing_iret_rm = 7; - timing_iret_v86 = 27; /*unknown*/ - timing_iret_pm = 10; - timing_iret_pm_outer = 27; - timing_call_rm = 4; - timing_call_pm = 4; - timing_call_pm_gate = 22; - timing_call_pm_gate_inner = 44; - timing_retf_rm = 4; - timing_retf_pm = 4; - timing_retf_pm_outer = 23; - timing_jmp_rm = 3; - timing_jmp_pm = 3; - timing_jmp_pm_gate = 18; - timing_misaligned = 3; - cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_MMX; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PAE | CR4_PCE | CR4_OSFXSR; -#ifdef USE_DYNAREC - codegen_timing_set(&codegen_timing_p6); -#endif - break; - - case CPU_CYRIX3S: - case CPU_EDEN: /* This till proper timings get discovered */ -#ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_winchip2_0f, dynarec_ops_386, dynarec_ops_winchip2_0f); -#else - x86_setopcodes(ops_386, ops_winchip2_0f); -#endif - timing_rr = 1; /*register dest - register src*/ - timing_rm = 2; /*register dest - memory src*/ - timing_mr = 2; /*memory dest - register src*/ - timing_mm = 3; - timing_rml = 2; /*register dest - memory src long*/ - timing_mrl = 2; /*memory dest - register src long*/ - timing_mml = 3; - timing_bt = 3-1; /*branch taken*/ - timing_bnt = 1; /*branch not taken*/ - cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MMX | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_3DNOW; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 18) | (1 << 19) | (1 << 20) | (1 << 21); - cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE; - /*unknown*/ - timing_int_rm = 26; - timing_int_v86 = 82; - timing_int_pm = 44; - timing_int_pm_outer = 71; - timing_iret_rm = 7; - timing_iret_v86 = 26; - timing_iret_pm = 10; - timing_iret_pm_outer = 26; - timing_call_rm = 4; - timing_call_pm = 15; - timing_call_pm_gate = 26; - timing_call_pm_gate_inner = 35; - timing_retf_rm = 4; - timing_retf_pm = 7; - timing_retf_pm_outer = 23; - timing_jmp_rm = 5; - timing_jmp_pm = 7; - timing_jmp_pm_gate = 17; - timing_misaligned = 2; - cpu_cyrix_alignment = 1; -#ifdef USE_DYNAREC - codegen_timing_set(&codegen_timing_winchip); -#endif - break; - - default: - fatal("cpu_set : unknown CPU type %i\n", cpu_s->cpu_type); - } - - - switch (fpu_type) - { - case FPU_NONE: - break; - - case FPU_8087: - x87_timings = x87_timings_8087; - break; - - case FPU_287: - x87_timings = x87_timings_287; - break; - - case FPU_287XL: - case FPU_387: - x87_timings = x87_timings_387; - break; - - case FPU_487SX: - default: - x87_timings = x87_timings_486; - } - - if (is386) { -#ifdef USE_DYNAREC - if (cpu_use_dynarec) - cpu_exec = exec386_dynarec; + if (cpu_s->cpu_type >= CPU_K6_2) + x86_setopcodes(ops_386, ops_k62_0f, dynarec_ops_386, dynarec_ops_k62_0f); +#if defined(DEV_BRANCH) && defined(USE_AMD_K5) + else if (cpu_s->cpu_type == CPU_K6) + x86_setopcodes(ops_386, ops_k6_0f, dynarec_ops_386, dynarec_ops_k6_0f); else + x86_setopcodes(ops_386, ops_pentiummmx_0f, dynarec_ops_386, dynarec_ops_pentiummmx_0f); +#else + else + x86_setopcodes(ops_386, ops_k6_0f, dynarec_ops_386, dynarec_ops_k6_0f); #endif - cpu_exec = exec386; - } else if (cpu_s->cpu_type >= CPU_286) - cpu_exec = exec386; +#else + if (cpu_s->cpu_type >= CPU_K6_2) + x86_setopcodes(ops_386, ops_k62_0f); +#if defined(DEV_BRANCH) && defined(USE_AMD_K5) + else if (cpu_s->cpu_type = CPU_K6) + x86_setopcodes(ops_386, ops_k6_0f); + else + x86_setopcodes(ops_386, ops_pentiummmx_0f); +#else + else + x86_setopcodes(ops_386, ops_k6_0f); +#endif +#endif + + timing_rr = 1; /* register dest - register src */ + timing_rm = 2; /* register dest - memory src */ + timing_mr = 3; /* memory dest - register src */ + timing_mm = 3; + timing_rml = 2; /* register dest - memory src long */ + timing_mrl = 3; /* memory dest - register src long */ + timing_mml = 3; + timing_bt = 0; /* branch taken */ + timing_bnt = 1; /* branch not taken */ + + timing_int = 6; + timing_int_rm = 11; + timing_int_v86 = 54; + timing_int_pm = 25; + timing_int_pm_outer = 42; + timing_iret_rm = 7; + timing_iret_v86 = 27; /* unknown */ + timing_iret_pm = 10; + timing_iret_pm_outer = 27; + timing_call_rm = 4; + timing_call_pm = 4; + timing_call_pm_gate = 22; + timing_call_pm_gate_inner = 44; + timing_retf_rm = 4; + timing_retf_pm = 4; + timing_retf_pm_outer = 23; + timing_jmp_rm = 3; + timing_jmp_pm = 3; + timing_jmp_pm_gate = 18; + + timing_misaligned = 3; + + cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_MMX; + if (cpu_s->cpu_type >= CPU_K6_2) + cpu_features |= CPU_FEATURE_3DNOW; + msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); +#if defined(DEV_BRANCH) && defined(USE_AMD_K5) + cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE; + if (cpu_s->cpu_type >= CPU_K6) { + cpu_CR4_mask |= (CR4_VME | CR4_PVI | CR4_PSE); + if (cpu_s->cpu_type <= CPU_K6) + cpu_CR4_mask |= CR4_PCE; + } +#else + cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE; + if (cpu_s->cpu_type == CPU_K6) + cpu_CR4_mask |= CR4_PCE; +#endif + +#ifdef USE_DYNAREC + codegen_timing_set(&codegen_timing_k6); +#endif + break; + + case CPU_PENTIUMPRO: + case CPU_PENTIUM2: + case CPU_PENTIUM2D: +#ifdef USE_DYNAREC + /* TODO: Perhaps merge the three opcode tables with some instructions UD#'ing depending on + CPU type. */ + if (cpu_s->cpu_type == CPU_PENTIUM2D) + x86_setopcodes(ops_386, ops_pentium2d_0f, dynarec_ops_386, dynarec_ops_pentium2d_0f); + else if (cpu_s->cpu_type == CPU_PENTIUM2) + x86_setopcodes(ops_386, ops_pentium2_0f, dynarec_ops_386, dynarec_ops_pentium2_0f); + else + x86_setopcodes(ops_386, ops_pentiumpro_0f, dynarec_ops_386, dynarec_ops_pentiumpro_0f); + x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_686_da_a16; + x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_686_da_a32; + x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_686_db_a16; + x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_686_db_a32; + x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_686_df_a16; + x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_686_df_a32; +#else + if (cpu_s->cpu_type == CPU_PENTIUM2D) + x86_setopcodes(ops_386, ops_pentium2d_0f); + else + x86_setopcodes(ops_386, ops_pentium2_0f); +#endif + x86_opcodes_da_a16 = ops_fpu_686_da_a16; + x86_opcodes_da_a32 = ops_fpu_686_da_a32; + x86_opcodes_db_a16 = ops_fpu_686_db_a16; + x86_opcodes_db_a32 = ops_fpu_686_db_a32; + x86_opcodes_df_a16 = ops_fpu_686_df_a16; + x86_opcodes_df_a32 = ops_fpu_686_df_a32; + + timing_rr = 1; /* register dest - register src */ + timing_rm = 2; /* register dest - memory src */ + timing_mr = 3; /* memory dest - register src */ + timing_mm = 3; + timing_rml = 2; /* register dest - memory src long */ + timing_mrl = 3; /* memory dest - register src long */ + timing_mml = 3; + timing_bt = 0; /* branch taken */ + timing_bnt = 1; /* branch not taken */ + + timing_int = 6; + timing_int_rm = 11; + timing_int_v86 = 54; + timing_int_pm = 25; + timing_int_pm_outer = 42; + timing_iret_rm = 7; + timing_iret_v86 = 27; /* unknown */ + timing_iret_pm = 10; + timing_iret_pm_outer = 27; + timing_call_rm = 4; + timing_call_pm = 4; + timing_call_pm_gate = 22; + timing_call_pm_gate_inner = 44; + timing_retf_rm = 4; + timing_retf_pm = 4; + timing_retf_pm_outer = 23; + timing_jmp_rm = 3; + timing_jmp_pm = 3; + timing_jmp_pm_gate = 18; + + timing_misaligned = 3; + + cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME; + if (cpu_s->cpu_type >= CPU_PENTIUM2) + cpu_features |= CPU_FEATURE_MMX; + msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); + cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PAE | CR4_PCE; + if (cpu_s->cpu_type == CPU_PENTIUM2D) + cpu_CR4_mask |= CR4_OSFXSR; + +#ifdef USE_DYNAREC + codegen_timing_set(&codegen_timing_p6); +#endif + break; + + case CPU_CYRIX3S: + case CPU_EDEN: /* This until proper timings get discovered */ +#ifdef USE_DYNAREC + x86_setopcodes(ops_386, ops_winchip2_0f, dynarec_ops_386, dynarec_ops_winchip2_0f); +#else + x86_setopcodes(ops_386, ops_winchip2_0f); +#endif + timing_rr = 1; /* register dest - register src */ + timing_rm = 2; /* register dest - memory src */ + timing_mr = 2; /* memory dest - register src */ + timing_mm = 3; + timing_rml = 2; /* register dest - memory src long */ + timing_mrl = 2; /* memory dest - register src long */ + timing_mml = 3; + timing_bt = 2; /* branch taken */ + timing_bnt = 1; /* branch not taken */ + + timing_int_rm = 26; /* unknown */ + timing_int_v86 = 82; + timing_int_pm = 44; + timing_int_pm_outer = 71; + timing_iret_rm = 7; + timing_iret_v86 = 26; + timing_iret_pm = 10; + timing_iret_pm_outer = 26; + timing_call_rm = 4; + timing_call_pm = 15; + timing_call_pm_gate = 26; + timing_call_pm_gate_inner = 35; + timing_retf_rm = 4; + timing_retf_pm = 7; + timing_retf_pm_outer = 23; + timing_jmp_rm = 5; + timing_jmp_pm = 7; + timing_jmp_pm_gate = 17; + + timing_misaligned = 2; + + cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MMX | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_3DNOW; + msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 18) | (1 << 19) | (1 << 20) | (1 << 21); + cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE; + + cpu_cyrix_alignment = 1; + +#ifdef USE_DYNAREC + codegen_timing_set(&codegen_timing_winchip); +#endif + break; + + default: + fatal("cpu_set : unknown CPU type %i\n", cpu_s->cpu_type); + } + + switch (fpu_type) { + case FPU_NONE: + break; + + case FPU_8087: + x87_timings = x87_timings_8087; + break; + + case FPU_287: + x87_timings = x87_timings_287; + break; + + case FPU_287XL: + case FPU_387: + x87_timings = x87_timings_387; + break; + + case FPU_487SX: + default: + x87_timings = x87_timings_486; + } + + if (is386) { +#ifdef USE_DYNAREC + if (cpu_use_dynarec) + cpu_exec = exec386_dynarec; else - cpu_exec = execx86; +#endif + cpu_exec = exec386; + } else if (cpu_s->cpu_type >= CPU_286) + cpu_exec = exec386; + else + cpu_exec = execx86; } @@ -1982,1991 +1465,1569 @@ cpu_current_pc(char *bufp) void cpu_CPUID(void) { - switch (cpu_s->cpu_type) - { - case CPU_RAPIDCAD: - case CPU_i486DX: - case CPU_i486DX2: - if (!EAX) - { - EAX = 0x00000001; - EBX = 0x756e6547; - EDX = 0x49656e69; - ECX = 0x6c65746e; - } - else if (EAX == 1) - { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU; /*FPU*/ - } - else - EAX = EBX = ECX = EDX = 0; - break; + switch (cpu_s->cpu_type) { + case CPU_RAPIDCAD: + case CPU_i486DX: + case CPU_i486DX2: + if (!EAX) { + EAX = 0x00000001; + EBX = 0x756e6547; + EDX = 0x49656e69; + ECX = 0x6c65746e; + } else if (EAX == 1) { + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU; /*FPU*/ + } else + EAX = EBX = ECX = EDX = 0; + break; - case CPU_iDX4: - if (!EAX) - { - EAX = 0x00000001; - EBX = 0x756e6547; - EDX = 0x49656e69; - ECX = 0x6c65746e; - } - else if (EAX == 1) - { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME; - } - else - EAX = EBX = ECX = EDX = 0; - break; + case CPU_iDX4: + if (!EAX) { + EAX = 0x00000001; + EBX = 0x756e6547; + EDX = 0x49656e69; + ECX = 0x6c65746e; + } else if (EAX == 1) { + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_VME; + } else + EAX = EBX = ECX = EDX = 0; + break; - case CPU_Am486SX: - case CPU_Am486SX2: - if (!EAX) - { - EAX = 1; - EBX = 0x68747541; - ECX = 0x444D4163; - EDX = 0x69746E65; - } - else if (EAX == 1) - { - EAX = CPUID; - EBX = ECX = EDX = 0; /*No FPU*/ - } - else - EAX = EBX = ECX = EDX = 0; - break; + case CPU_Am486SX: + case CPU_Am486SX2: + if (!EAX) { + EAX = 1; + EBX = 0x68747541; + ECX = 0x444D4163; + EDX = 0x69746E65; + } else if (EAX == 1) { + EAX = CPUID; + EBX = ECX = EDX = 0; /*No FPU*/ + } else + EAX = EBX = ECX = EDX = 0; + break; - case CPU_Am486DX: - case CPU_Am486DX2: - case CPU_Am486DX4: - case CPU_Am5x86: - if (!EAX) - { - EAX = 1; - EBX = 0x68747541; - ECX = 0x444D4163; - EDX = 0x69746E65; - } - else if (EAX == 1) - { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU; /*FPU*/ - } - else - EAX = EBX = ECX = EDX = 0; - break; - - case CPU_WINCHIP: - if (!EAX) - { - EAX = 1; - if (msr.fcr2 & (1 << 14)) - { - EBX = msr.fcr3 >> 32; - ECX = msr.fcr3 & 0xffffffff; - EDX = msr.fcr2 >> 32; - } - else - { - EBX = 0x746e6543; /*CentaurHauls*/ - ECX = 0x736c7561; - EDX = 0x48727561; - } - } - else if (EAX == 1) - { - EAX = 0x540; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR; - if (cpu_has_feature(CPU_FEATURE_CX8)) - EDX |= CPUID_CMPXCHG8B; - if (msr.fcr & (1 << 9)) - EDX |= CPUID_MMX; - } - else - EAX = EBX = ECX = EDX = 0; - break; + case CPU_Am486DX: + case CPU_Am486DX2: + case CPU_Am486DX4: + case CPU_Am5x86: + if (!EAX) { + EAX = 1; + EBX = 0x68747541; + ECX = 0x444D4163; + EDX = 0x69746E65; + } else if (EAX == 1) { + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU; /*FPU*/ + } else + EAX = EBX = ECX = EDX = 0; + break; - case CPU_WINCHIP2: - switch (EAX) - { - case 0: - EAX = 1; - if (msr.fcr2 & (1 << 14)) - { - EBX = msr.fcr3 >> 32; - ECX = msr.fcr3 & 0xffffffff; - EDX = msr.fcr2 >> 32; - } - else - { - EBX = 0x746e6543; /*CentaurHauls*/ - ECX = 0x736c7561; - EDX = 0x48727561; - } - break; - case 1: - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR; - if (cpu_has_feature(CPU_FEATURE_CX8)) - EDX |= CPUID_CMPXCHG8B; - if (msr.fcr & (1 << 9)) - EDX |= CPUID_MMX; - break; - case 0x80000000: - EAX = 0x80000005; - break; - case 0x80000001: - EAX = CPUID; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR; + case CPU_WINCHIP: + if (!EAX) { + EAX = 1; + if (msr.fcr2 & (1 << 14)) { + EBX = msr.fcr3 >> 32; + ECX = msr.fcr3 & 0xffffffff; + EDX = msr.fcr2 >> 32; + } else { + EBX = 0x746e6543; /* CentaurHauls */ + ECX = 0x736c7561; + EDX = 0x48727561; + } + } else if (EAX == 1) { + EAX = 0x540; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR; if (cpu_has_feature(CPU_FEATURE_CX8)) EDX |= CPUID_CMPXCHG8B; - if (msr.fcr & (1 << 9)) - EDX |= CPUID_MMX; - if (cpu_has_feature(CPU_FEATURE_3DNOW)) - EDX |= CPUID_3DNOW; - break; - - case 0x80000002: /*Processor name string*/ - EAX = 0x20544449; /*IDT WinChip 2-3D*/ - EBX = 0x436e6957; - ECX = 0x20706968; - EDX = 0x44332d32; - break; - - case 0x80000005: /*Cache information*/ - EBX = 0x08800880; /*TLBs*/ - ECX = 0x20040120; /*L1 data cache*/ - EDX = 0x20020120; /*L1 instruction cache*/ - break; - - default: - EAX = EBX = ECX = EDX = 0; - break; - } - break; - - case CPU_P24T: - case CPU_PENTIUM: - if (!EAX) - { - EAX = 0x00000001; - EBX = 0x756e6547; - EDX = 0x49656e69; - ECX = 0x6c65746e; - } - else if (EAX == 1) - { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B; - } - else - EAX = EBX = ECX = EDX = 0; - break; + if (msr.fcr & (1 << 9)) + EDX |= CPUID_MMX; + } else + EAX = EBX = ECX = EDX = 0; + break; + + case CPU_WINCHIP2: + switch (EAX) { + case 0: + EAX = 1; + if (msr.fcr2 & (1 << 14)) { + EBX = msr.fcr3 >> 32; + ECX = msr.fcr3 & 0xffffffff; + EDX = msr.fcr2 >> 32; + } else { + EBX = 0x746e6543; /* CentaurHauls */ + ECX = 0x736c7561; + EDX = 0x48727561; + } + break; + case 1: + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR; + if (cpu_has_feature(CPU_FEATURE_CX8)) + EDX |= CPUID_CMPXCHG8B; + if (msr.fcr & (1 << 9)) + EDX |= CPUID_MMX; + break; + case 0x80000000: + EAX = 0x80000005; + break; + case 0x80000001: + EAX = CPUID; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR; + if (cpu_has_feature(CPU_FEATURE_CX8)) + EDX |= CPUID_CMPXCHG8B; + if (msr.fcr & (1 << 9)) + EDX |= CPUID_MMX; + if (cpu_has_feature(CPU_FEATURE_3DNOW)) + EDX |= CPUID_3DNOW; + break; + + case 0x80000002: /* Processor name string */ + EAX = 0x20544449; /* IDT WinChip 2-3D */ + EBX = 0x436e6957; + ECX = 0x20706968; + EDX = 0x44332d32; + break; + + case 0x80000005: /*Cache information*/ + EBX = 0x08800880; /*TLBs*/ + ECX = 0x20040120; /*L1 data cache*/ + EDX = 0x20020120; /*L1 instruction cache*/ + break; + + default: + EAX = EBX = ECX = EDX = 0; + break; + } + break; + + case CPU_P24T: + case CPU_PENTIUM: + if (!EAX) { + EAX = 0x00000001; + EBX = 0x756e6547; + EDX = 0x49656e69; + ECX = 0x6c65746e; + } else if (EAX == 1) { + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B; + } else + EAX = EBX = ECX = EDX = 0; + break; #if defined(DEV_BRANCH) && defined(USE_AMD_K5) - case CPU_K5: - if (!EAX) - { - EAX = 0x00000001; - EBX = 0x68747541; - EDX = 0x69746E65; - ECX = 0x444D4163; - } - else if (EAX == 1) - { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B; - } - else - EAX = EBX = ECX = EDX = 0; - break; + case CPU_K5: + if (!EAX) { + EAX = 0x00000001; + EBX = 0x68747541; + EDX = 0x69746E65; + ECX = 0x444D4163; + } else if (EAX == 1) { + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B; + } else + EAX = EBX = ECX = EDX = 0; + break; - case CPU_5K86: - if (!EAX) - { - EAX = 0x00000001; - EBX = 0x68747541; - EDX = 0x69746E65; - ECX = 0x444D4163; - } - else if (EAX == 1) - { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B; - } - else if (EAX == 0x80000000) - { - EAX = 0x80000005; - EBX = ECX = EDX = 0; - } - else if (EAX == 0x80000001) - { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B; - } - else if (EAX == 0x80000002) - { + case CPU_5K86: + if (!EAX) { + EAX = 0x00000001; + EBX = 0x68747541; + EDX = 0x69746E65; + ECX = 0x444D4163; + } else if (EAX == 1) { + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B; + } else if (EAX == 0x80000000) { + EAX = 0x80000005; + EBX = ECX = EDX = 0; + } else if (EAX == 0x80000001) { + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B; + } else if (EAX == 0x80000002) { EAX = 0x2D444D41; EBX = 0x7428354B; ECX = 0x5020296D; EDX = 0x65636F72; - } - else if (EAX == 0x80000003) - { + } else if (EAX == 0x80000003) { EAX = 0x726F7373; EBX = ECX = EDX = 0; - } - else if (EAX == 0x80000004) - { + } else if (EAX == 0x80000004) EAX = EBX = ECX = EDX = 0; - } - else if (EAX == 0x80000005) - { + else if (EAX == 0x80000005) { EAX = 0; EBX = 0x04800000; ECX = 0x08040120; EDX = 0x10040120; - } - else - EAX = EBX = ECX = EDX = 0; - break; + } else + EAX = EBX = ECX = EDX = 0; + break; #endif - case CPU_K6: - if (!EAX) - { - EAX = 0x00000001; - EBX = 0x68747541; - EDX = 0x69746E65; - ECX = 0x444D4163; - } - else if (EAX == 1) - { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX; - } - else if (EAX == 0x80000000) - { - EAX = 0x80000005; - EBX = ECX = EDX = 0; - } - else if (EAX == 0x80000001) - { - EAX = CPUID + 0x100; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX; - } - else if (EAX == 0x80000002) - { + case CPU_K6: + if (!EAX) { + EAX = 0x00000001; + EBX = 0x68747541; + EDX = 0x69746E65; + ECX = 0x444D4163; + } else if (EAX == 1) { + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX; + } else if (EAX == 0x80000000) { + EAX = 0x80000005; + EBX = ECX = EDX = 0; + } else if (EAX == 0x80000001) { + EAX = CPUID + 0x100; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX; + } else if (EAX == 0x80000002) { EAX = 0x2D444D41; EBX = 0x6D74364B; ECX = 0x202F7720; EDX = 0x746C756D; - } - else if (EAX == 0x80000003) - { + } else if (EAX == 0x80000003) { EAX = 0x64656D69; EBX = 0x65206169; ECX = 0x6E657478; EDX = 0x6E6F6973; - } - else if (EAX == 0x80000004) - { + } else if (EAX == 0x80000004) { EAX = 0x73; EBX = ECX = EDX = 0; - } - else if (EAX == 0x80000005) - { + } else if (EAX == 0x80000005) { EAX = 0; EBX = 0x02800140; ECX = 0x20020220; EDX = 0x20020220; - } - else if (EAX == 0x8FFFFFFF) - { + } else if (EAX == 0x8FFFFFFF) { EAX = 0x4778654E; EBX = 0x72656E65; ECX = 0x6F697461; EDX = 0x444D416E; + } else + EAX = EBX = ECX = EDX = 0; + break; + + case CPU_K6_2: + case CPU_K6_2C: + switch (EAX) { + case 0: + EAX = 1; + EBX = 0x68747541; /* AuthenticAMD */ + ECX = 0x444d4163; + EDX = 0x69746e65; + break; + case 1: + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX; + break; + case 0x80000000: + EAX = 0x80000005; + break; + case 0x80000001: + EAX = CPUID + 0x100; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX | CPUID_3DNOW; + break; + case 0x80000002: /* Processor name string */ + EAX = 0x2d444d41; /* AMD-K6(tm) 3D pr */ + EBX = 0x7428364b; + ECX = 0x3320296d; + EDX = 0x72702044; + break; + case 0x80000003: /* Processor name string */ + EAX = 0x7365636f; /* ocessor */ + EBX = 0x00726f73; + ECX = 0x00000000; + EDX = 0x00000000; + break; + case 0x80000005: /*Cache information*/ + EBX = 0x02800140; /*TLBs*/ + ECX = 0x20020220; /*L1 data cache*/ + EDX = 0x20020220; /*L1 instruction cache*/ + break; + default: + EAX = EBX = ECX = EDX = 0; + break; } - else - EAX = EBX = ECX = EDX = 0; - break; + break; - case CPU_K6_2: - case CPU_K6_2C: - switch (EAX) - { - case 0: - EAX = 1; - EBX = 0x68747541; /*AuthenticAMD*/ - ECX = 0x444d4163; - EDX = 0x69746e65; - break; - case 1: - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX; - break; - case 0x80000000: - EAX = 0x80000005; - break; - case 0x80000001: - EAX = CPUID+0x100; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX | CPUID_3DNOW; - break; + case CPU_K6_3: + switch (EAX) { + case 0: + EAX = 1; + EBX = 0x68747541; /* AuthenticAMD */ + ECX = 0x444d4163; + EDX = 0x69746e65; + break; + case 1: + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX; + break; + case 0x80000000: + EAX = 0x80000006; + break; + case 0x80000001: + EAX = CPUID + 0x100; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX | CPUID_3DNOW; + break; + case 0x80000002: /* Processor name string */ + EAX = 0x2d444d41; /* AMD-K6(tm) 3D+ P */ + EBX = 0x7428364b; + ECX = 0x3320296d; + EDX = 0x50202b44; + break; + case 0x80000003: /* Processor name string */ + EAX = 0x65636f72; /* rocessor */ + EBX = 0x726f7373; + ECX = 0x00000000; + EDX = 0x00000000; + break; + case 0x80000005: /* Cache information */ + EBX = 0x02800140; /* TLBs */ + ECX = 0x20020220; /*L1 data cache*/ + EDX = 0x20020220; /*L1 instruction cache*/ + break; + case 0x80000006: /* L2 Cache information */ + ECX = 0x01004220; + break; + default: + EAX = EBX = ECX = EDX = 0; + break; + } + break; - case 0x80000002: /*Processor name string*/ - EAX = 0x2d444d41; /*AMD-K6(tm) 3D pr*/ - EBX = 0x7428364b; - ECX = 0x3320296d; - EDX = 0x72702044; - break; - - case 0x80000003: /*Processor name string*/ - EAX = 0x7365636f; /*ocessor*/ - EBX = 0x00726f73; - ECX = 0x00000000; - EDX = 0x00000000; - break; - - case 0x80000005: /*Cache information*/ - EBX = 0x02800140; /*TLBs*/ - ECX = 0x20020220; /*L1 data cache*/ - EDX = 0x20020220; /*L1 instruction cache*/ - break; - - default: - EAX = EBX = ECX = EDX = 0; - break; - } - break; - - case CPU_K6_3: - switch (EAX) - { - case 0: - EAX = 1; - EBX = 0x68747541; /*AuthenticAMD*/ - ECX = 0x444d4163; - EDX = 0x69746e65; - break; - case 1: - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX; - break; - case 0x80000000: - EAX = 0x80000006; - break; - case 0x80000001: - EAX = CPUID+0x100; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX | CPUID_3DNOW; - break; - - case 0x80000002: /*Processor name string*/ - EAX = 0x2d444d41; /*AMD-K6(tm) 3D+ P*/ - EBX = 0x7428364b; - ECX = 0x3320296d; - EDX = 0x50202b44; - break; - - case 0x80000003: /*Processor name string*/ - EAX = 0x65636f72; /*rocessor*/ - EBX = 0x726f7373; - ECX = 0x00000000; - EDX = 0x00000000; - break; - - case 0x80000005: /*Cache information*/ - EBX = 0x02800140; /*TLBs*/ - ECX = 0x20020220; /*L1 data cache*/ - EDX = 0x20020220; /*L1 instruction cache*/ - break; - - case 0x80000006: /*L2 Cache information*/ - ECX = 0x01004220; - break; - - default: - EAX = EBX = ECX = EDX = 0; - break; - } - break; - - case CPU_K6_2P: - case CPU_K6_3P: - switch (EAX) - { - case 0: - EAX = 1; - EBX = 0x68747541; /*AuthenticAMD*/ - ECX = 0x444d4163; - EDX = 0x69746e65; - break; - case 1: - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX; - break; - case 0x80000000: - EAX = 0x80000007; - break; - case 0x80000001: - EAX = CPUID+0x100; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX | CPUID_3DNOW; - break; - - case 0x80000002: /*Processor name string*/ - EAX = 0x2d444d41; /*AMD-K6(tm)-III P*/ - EBX = 0x7428364b; - ECX = 0x492d296d; - EDX = 0x50204949; - break; - - case 0x80000003: /*Processor name string*/ - EAX = 0x65636f72; /*rocessor*/ - EBX = 0x726f7373; - ECX = 0x00000000; - EDX = 0x00000000; - break; - - case 0x80000005: /*Cache information*/ - EBX = 0x02800140; /*TLBs*/ - ECX = 0x20020220; /*L1 data cache*/ - EDX = 0x20020220; /*L1 instruction cache*/ - break; - - case 0x80000006: /*L2 Cache information*/ - if (cpu_s->cpu_type == CPU_K6_3P) - ECX = 0x01004220; - else - ECX = 0x00804220; - break; - - case 0x80000007: /*PowerNow information*/ - EDX = 7; - break; - - default: - EAX = EBX = ECX = EDX = 0; - break; - } - break; - - case CPU_PENTIUMMMX: - if (!EAX) - { - EAX = 0x00000001; - EBX = 0x756e6547; - EDX = 0x49656e69; - ECX = 0x6c65746e; - } - else if (EAX == 1) - { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX; - } - else - EAX = EBX = ECX = EDX = 0; - break; + case CPU_K6_2P: + case CPU_K6_3P: + switch (EAX) { + case 0: + EAX = 1; + EBX = 0x68747541; /* AuthenticAMD */ + ECX = 0x444d4163; + EDX = 0x69746e65; + break; + case 1: + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX; + break; + case 0x80000000: + EAX = 0x80000007; + break; + case 0x80000001: + EAX = CPUID + 0x100; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX | CPUID_3DNOW; + break; + case 0x80000002: /* Processor name string */ + EAX = 0x2d444d41; /* AMD-K6(tm)-III P */ + EBX = 0x7428364b; + ECX = 0x492d296d; + EDX = 0x50204949; + break; + case 0x80000003: /* Processor name string */ + EAX = 0x65636f72; /* rocessor */ + EBX = 0x726f7373; + ECX = 0x00000000; + EDX = 0x00000000; + break; + case 0x80000005: /* Cache information */ + EBX = 0x02800140; /* TLBs */ + ECX = 0x20020220; /* L1 data cache */ + EDX = 0x20020220; /* L1 instruction cache */ + break; + case 0x80000006: /* L2 Cache information */ + if (cpu_s->cpu_type == CPU_K6_3P) + ECX = 0x01004220; + else + ECX = 0x00804220; + break; + case 0x80000007: /* PowerNow information */ + EDX = 7; + break; + default: + EAX = EBX = ECX = EDX = 0; + break; + } + break; + case CPU_PENTIUMMMX: + if (!EAX) { + EAX = 0x00000001; + EBX = 0x756e6547; + EDX = 0x49656e69; + ECX = 0x6c65746e; + } else if (EAX == 1) { + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX; + } else + EAX = EBX = ECX = EDX = 0; + break; #if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) - case CPU_Cx6x86: - if (!EAX) - { - EAX = 0x00000001; - EBX = 0x69727943; - EDX = 0x736e4978; - ECX = 0x64616574; - } - else if (EAX == 1) - { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU; - } - else - EAX = EBX = ECX = EDX = 0; - break; + case CPU_Cx6x86: + if (!EAX) { + EAX = 0x00000001; + EBX = 0x69727943; + EDX = 0x736e4978; + ECX = 0x64616574; + } else if (EAX == 1) { + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU; + } else + EAX = EBX = ECX = EDX = 0; + break; + case CPU_Cx6x86L: + if (!EAX) { + EAX = 0x00000001; + EBX = 0x69727943; + EDX = 0x736e4978; + ECX = 0x64616574; + } else if (EAX == 1) { + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_CMPXCHG8B; + } else + EAX = EBX = ECX = EDX = 0; + break; - case CPU_Cx6x86L: - if (!EAX) - { - EAX = 0x00000001; - EBX = 0x69727943; - EDX = 0x736e4978; - ECX = 0x64616574; - } - else if (EAX == 1) - { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_CMPXCHG8B; - } - else - EAX = EBX = ECX = EDX = 0; - break; + case CPU_CxGX1: + if (!EAX) { + EAX = 0x00000001; + EBX = 0x69727943; + EDX = 0x736e4978; + ECX = 0x64616574; + } else if (EAX == 1) { + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B; + } else + EAX = EBX = ECX = EDX = 0; + break; - - case CPU_CxGX1: - if (!EAX) - { - EAX = 0x00000001; - EBX = 0x69727943; - EDX = 0x736e4978; - ECX = 0x64616574; - } - else if (EAX == 1) - { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B; - } - else - EAX = EBX = ECX = EDX = 0; - break; - - - - case CPU_Cx6x86MX: - if (!EAX) - { - EAX = 0x00000001; - EBX = 0x69727943; - EDX = 0x736e4978; - ECX = 0x64616574; - } - else if (EAX == 1) - { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_CMOV | CPUID_MMX; - } - else - EAX = EBX = ECX = EDX = 0; - break; + case CPU_Cx6x86MX: + if (!EAX) { + EAX = 0x00000001; + EBX = 0x69727943; + EDX = 0x736e4978; + ECX = 0x64616574; + } else if (EAX == 1) { + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_CMOV | CPUID_MMX; + } else + EAX = EBX = ECX = EDX = 0; + break; #endif - case CPU_PENTIUMPRO: - if (!EAX) - { - EAX = 0x00000002; - EBX = 0x756e6547; - EDX = 0x49656e69; - ECX = 0x6c65746e; - } - else if (EAX == 1) - { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_CMPXCHG8B | CPUID_MTRR | CPUID_SEP | CPUID_CMOV; - } - else if (EAX == 2) - { + case CPU_PENTIUMPRO: + if (!EAX) { + EAX = 0x00000002; + EBX = 0x756e6547; + EDX = 0x49656e69; + ECX = 0x6c65746e; + } else if (EAX == 1) { + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_CMPXCHG8B | CPUID_MTRR | CPUID_SEP | CPUID_CMOV; + } else if (EAX == 2) { EAX = 0x00000001; EBX = ECX = 0; EDX = 0x00000000; - } - else - EAX = EBX = ECX = EDX = 0; - break; + } else + EAX = EBX = ECX = EDX = 0; + break; - case CPU_PENTIUM2: - if (!EAX) - { - EAX = 0x00000002; - EBX = 0x756e6547; - EDX = 0x49656e69; - ECX = 0x6c65746e; - } - else if (EAX == 1) - { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_MTRR | CPUID_SEP | CPUID_CMOV; - } - else if (EAX == 2) - { + case CPU_PENTIUM2: + if (!EAX) { + EAX = 0x00000002; + EBX = 0x756e6547; + EDX = 0x49656e69; + ECX = 0x6c65746e; + } else if (EAX == 1) { + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_MTRR | CPUID_SEP | CPUID_CMOV; + } else if (EAX == 2) { EAX = 0x00000001; EBX = ECX = 0; EDX = 0x00000000; - } - else - EAX = EBX = ECX = EDX = 0; - break; + } else + EAX = EBX = ECX = EDX = 0; + break; - case CPU_PENTIUM2D: - if (!EAX) - { - EAX = 0x00000002; - EBX = 0x756e6547; - EDX = 0x49656e69; - ECX = 0x6c65746e; - } - else if (EAX == 1) - { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_MTRR | CPUID_SEP | CPUID_FXSR | CPUID_CMOV; - } - else if (EAX == 2) - { + case CPU_PENTIUM2D: + if (!EAX) { + EAX = 0x00000002; + EBX = 0x756e6547; + EDX = 0x49656e69; + ECX = 0x6c65746e; + } else if (EAX == 1) { + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_MTRR | CPUID_SEP | CPUID_FXSR | CPUID_CMOV; + } else if (EAX == 2) { EAX = 0x00000001; EBX = ECX = 0; EDX = 0x00000000; + } else + EAX = EBX = ECX = EDX = 0; + break; + + case CPU_CYRIX3S: + switch (EAX) { + case 0: + EAX = 1; + if (msr.fcr2 & (1 << 14)) { + EBX = msr.fcr3 >> 32; + ECX = msr.fcr3 & 0xffffffff; + EDX = msr.fcr2 >> 32; + } else { + EBX = 0x746e6543; /* CentaurHauls */ + ECX = 0x736c7561; + EDX = 0x48727561; + } + break; + case 1: + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MMX | CPUID_MTRR; + if (cpu_has_feature(CPU_FEATURE_CX8)) + EDX |= CPUID_CMPXCHG8B; + break; + case 0x80000000: + EAX = 0x80000005; + break; + case 0x80000001: + EAX = CPUID; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MMX | CPUID_MTRR | CPUID_3DNOW; + if (cpu_has_feature(CPU_FEATURE_CX8)) + EDX |= CPUID_CMPXCHG8B; + break; + case 0x80000002: /* Processor name string */ + EAX = 0x20414956; /* VIA Samuel */ + EBX = 0x756d6153; + ECX = 0x00006c65; + EDX = 0x00000000; + break; + case 0x80000005: /* Cache information */ + EBX = 0x08800880; /* TLBs */ + ECX = 0x40040120; /* L1 data cache */ + EDX = 0x40020120; /* L1 instruction cache */ + break; + default: + EAX = EBX = ECX = EDX = 0; + break; } - else - EAX = EBX = ECX = EDX = 0; - break; + break; - case CPU_CYRIX3S: - switch (EAX) - { - case 0: - EAX = 1; - if (msr.fcr2 & (1 << 14)) - { - EBX = msr.fcr3 >> 32; - ECX = msr.fcr3 & 0xffffffff; - EDX = msr.fcr2 >> 32; - } - else - { - EBX = 0x746e6543; /*CentaurHauls*/ - ECX = 0x736c7561; - EDX = 0x48727561; - } - break; - case 1: - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MMX | CPUID_MTRR; - if (cpu_has_feature(CPU_FEATURE_CX8)) - EDX |= CPUID_CMPXCHG8B; - break; - case 0x80000000: - EAX = 0x80000005; - break; - case 0x80000001: - EAX = CPUID; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MMX | CPUID_MTRR | CPUID_3DNOW; - if (cpu_has_feature(CPU_FEATURE_CX8)) - EDX |= CPUID_CMPXCHG8B; - break; - case 0x80000002: /*Processor name string*/ - EAX = 0x20414956; /*VIA Samuel*/ - EBX = 0x756d6153; - ECX = 0x00006c65; - EDX = 0x00000000; - break; - - case 0x80000005: /*Cache information*/ - EBX = 0x08800880; /*TLBs*/ - ECX = 0x40040120; /*L1 data cache*/ - EDX = 0x40020120; /*L1 instruction cache*/ - break; - - default: - EAX = EBX = ECX = EDX = 0; - break; - } - break; - - case CPU_EDEN: - switch (EAX) - { - case 0: - EAX = 1; - if (msr.fcr2 & (1 << 14)) - { - EBX = msr.fcr3 >> 32; - ECX = msr.fcr3 & 0xffffffff; - EDX = msr.fcr2 >> 32; - } - else - { - EBX = 0x746e6543; /*CentaurHauls*/ - ECX = 0x736c7561; - EDX = 0x48727561; - } - break; - case 1: - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MMX | CPUID_MTRR; - if (cpu_has_feature(CPU_FEATURE_CX8)) - EDX |= CPUID_CMPXCHG8B; - break; - case 0x80000000: - EAX = 0x80000006; - break; - case 0x80000001: - EAX = CPUID; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MMX | CPUID_MTRR | CPUID_3DNOW; - if (cpu_has_feature(CPU_FEATURE_CX8)) - EDX |= CPUID_CMPXCHG8B; - break; - case 0x80000002: /*Processor name string*/ - case 0x80000003: - case 0x80000004: - EAX = 0x20414956; /*VIA Samuel 2*/ - EBX = 0x756d6153; - ECX = 0x32206c65; - EDX = 0x00000000; - break; - - case 0x80000005: /*Cache information*/ - EBX = 0x08800880; /*TLBs*/ - ECX = 0x40040120; /*L1 data cache*/ - EDX = 0x40020120; /*L1 instruction cache*/ - break; - - case 0x80000006: - ECX = 0x40040120; /*L2 data cache*/ - break; - - default: - EAX = EBX = ECX = EDX = 0; - break; - } - break; - } + case CPU_EDEN: + switch (EAX) { + case 0: + EAX = 1; + if (msr.fcr2 & (1 << 14)) { + EBX = msr.fcr3 >> 32; + ECX = msr.fcr3 & 0xffffffff; + EDX = msr.fcr2 >> 32; + } else { + EBX = 0x746e6543; /* CentaurHauls */ + ECX = 0x736c7561; + EDX = 0x48727561; + } + break; + case 1: + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MMX | CPUID_MTRR; + if (cpu_has_feature(CPU_FEATURE_CX8)) + EDX |= CPUID_CMPXCHG8B; + break; + case 0x80000000: + EAX = 0x80000006; + break; + case 0x80000001: + EAX = CPUID; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MMX | CPUID_MTRR | CPUID_3DNOW; + if (cpu_has_feature(CPU_FEATURE_CX8)) + EDX |= CPUID_CMPXCHG8B; + break; + case 0x80000002: /* Processor name string */ + case 0x80000003: + case 0x80000004: + EAX = 0x20414956; /* VIA Samuel 2 */ + EBX = 0x756d6153; + ECX = 0x32206c65; + EDX = 0x00000000; + break; + case 0x80000005: /* Cache information */ + EBX = 0x08800880; /* TLBs */ + ECX = 0x40040120; /* L1 data cache */ + EDX = 0x40020120; /* L1 instruction cache */ + break; + case 0x80000006: + ECX = 0x40040120; /* L2 data cache */ + break; + default: + EAX = EBX = ECX = EDX = 0; + break; + } + break; + } } -void cpu_ven_reset(void) + +void +cpu_ven_reset(void) { - switch (cpu_s->cpu_type) - { + memset(&msr, 0, sizeof(msr)); + + switch (cpu_s->cpu_type) { + case CPU_K6_2P: + case CPU_K6_3P: + case CPU_K6_3: + case CPU_K6_2C: + msr.amd_psor = (cpu_s->cpu_type >= CPU_K6_3) ? 0x008cULL : 0x018cULL; + /* FALLTHROUGH */ + case CPU_K6_2: #if defined(DEV_BRANCH) && defined(USE_AMD_K5) - case CPU_K5: - case CPU_5K86: + case CPU_K5: + case CPU_5K86: #endif - case CPU_K6: - amd_efer = amd_whcr = 0ULL; - break; - case CPU_K6_2: - amd_efer = amd_whcr = 0ULL; - star = 0ULL; - break; - case CPU_K6_2C: - amd_efer = 2ULL; - amd_whcr = star = 0ULL; - amd_psor = 0x018cULL; - amd_uwccr = 0ULL; - break; - case CPU_K6_3: - amd_efer = 2ULL; - amd_whcr = star = 0ULL; - amd_psor = 0x008cULL; - amd_uwccr = 0ULL; - amd_pfir = amd_l2aar = 0ULL; - break; - case CPU_K6_2P: - case CPU_K6_3P: - amd_efer = 2ULL; - amd_whcr = star = 0ULL; - amd_psor = 0x008cULL; - amd_uwccr = 0ULL; - amd_pfir = amd_l2aar = 0ULL; - amd_epmr = 0ULL; - break; - } + case CPU_K6: + msr.amd_efer = (cpu_s->cpu_type >= CPU_K6_2C) ? 2ULL : 0ULL; + break; + + case CPU_PENTIUMPRO: + case CPU_PENTIUM2: + case CPU_PENTIUM2D: + msr.mtrr_cap = 0x00000508ULL; + /* FALLTHROUGH */ + break; + } } -void cpu_RDMSR() + +void +cpu_RDMSR(void) { - switch (cpu_s->cpu_type) - { - case CPU_IBM386SLC: - EAX = EDX = 0; - switch (ECX) - { - case 0x1000: - EAX = ibm_por_msr & 0xfeff; - break; - - case 0x1001: - EAX = ibm_crcr_msr & 0xffffffffff; - break; - } - break; - - case CPU_IBM486SLC: - case CPU_IBM486BL: - EAX = EDX = 0; - switch (ECX) - { - case 0x1000: - EAX = ibm_por_msr & 0xffeff; - break; - - case 0x1001: - EAX = ibm_crcr_msr & 0xffffffffff; - break; - - if (cpu_s->multi) { - case 0x1002: - EAX = ibm_por2_msr & 0x3f000000; - break; - } - } - break; - - case CPU_WINCHIP: - case CPU_WINCHIP2: - EAX = EDX = 0; - switch (ECX) - { - case 0x02: - EAX = msr.tr1; - break; - case 0x0e: - EAX = msr.tr12; - break; - case 0x10: - EAX = tsc & 0xffffffff; - EDX = tsc >> 32; - break; - case 0x11: - EAX = msr.cesr; - break; - case 0x107: - EAX = msr.fcr; - break; - case 0x108: - EAX = msr.fcr2 & 0xffffffff; - EDX = msr.fcr2 >> 32; - break; - case 0x10a: - EAX = cpu_multi & 3; - break; - } - break; - - case CPU_CYRIX3S: - case CPU_EDEN: - EAX = EDX = 0; - switch (ECX) - { - case 0x10: - EAX = tsc & 0xffffffff; - EDX = tsc >> 32; - break; - case 0x2A: - EAX = 0xC4000000; - EDX = 0; - if (cpu_dmulti == 3) - EAX |= ((0 << 25) | (0 << 24) | (0 << 23) | (1 << 22)); - else if (cpu_dmulti == 3.5) - EAX |= ((0 << 25) | (1 << 24) | (0 << 23) | (1 << 22)); - else if (cpu_dmulti == 4) - EAX |= ((0 << 25) | (0 << 24) | (1 << 23) | (0 << 22)); - else if (cpu_dmulti == 4.5) - EAX |= ((0 << 25) | (1 << 24) | (1 << 23) | (0 << 22)); - else if (cpu_dmulti == 5) - EAX |= 0; - else if (cpu_dmulti == 5.5) - EAX |= ((0 << 25) | (1 << 24) | (0 << 23) | (0 << 22)); - else if (cpu_dmulti == 6) - EAX |= ((1 << 25) | (0 << 24) | (1 << 23) | (1 << 22)); - else if (cpu_dmulti == 6.5) - EAX |= ((1 << 25) | (1 << 24) | (1 << 23) | (1 << 22)); - else if (cpu_dmulti == 7) - EAX |= ((1 << 25) | (0 << 24) | (0 << 23) | (1 << 22)); - else - EAX |= ((0 << 25) | (0 << 24) | (0 << 23) | (1 << 22)); - if (cpu_busspeed >= 84000000) - EAX |= (1 << 19); - break; - case 0x1107: - EAX = msr.fcr; - break; - case 0x1108: - EAX = msr.fcr2 & 0xffffffff; - EDX = msr.fcr2 >> 32; - break; - case 0x200: case 0x201: case 0x202: case 0x203: case 0x204: case 0x205: case 0x206: case 0x207: - case 0x208: case 0x209: case 0x20A: case 0x20B: case 0x20C: case 0x20D: case 0x20E: case 0x20F: - if (ECX & 1) - { - EAX = mtrr_physmask_msr[(ECX - 0x200) >> 1] & 0xffffffff; - EDX = mtrr_physmask_msr[(ECX - 0x200) >> 1] >> 32; - } - else - { - EAX = mtrr_physbase_msr[(ECX - 0x200) >> 1] & 0xffffffff; - EDX = mtrr_physbase_msr[(ECX - 0x200) >> 1] >> 32; - } - break; - case 0x250: - EAX = mtrr_fix64k_8000_msr & 0xffffffff; - EDX = mtrr_fix64k_8000_msr >> 32; - break; - case 0x258: - EAX = mtrr_fix16k_8000_msr & 0xffffffff; - EDX = mtrr_fix16k_8000_msr >> 32; - break; - case 0x259: - EAX = mtrr_fix16k_a000_msr & 0xffffffff; - EDX = mtrr_fix16k_a000_msr >> 32; - break; - case 0x268: case 0x269: case 0x26A: case 0x26B: case 0x26C: case 0x26D: case 0x26E: case 0x26F: - EAX = mtrr_fix4k_msr[ECX - 0x268] & 0xffffffff; - EDX = mtrr_fix4k_msr[ECX - 0x268] >> 32; - break; - case 0x2FF: - EAX = mtrr_deftype_msr & 0xffffffff; - EDX = mtrr_deftype_msr >> 32; - break; - } - break; - -#if defined(DEV_BRANCH) && defined(USE_AMD_K5) - case CPU_K5: - case CPU_5K86: -#endif - case CPU_K6: - EAX = EDX = 0; - switch (ECX) - { - case 0x0000000e: - EAX = msr.tr12; - break; - case 0x00000010: - EAX = tsc & 0xffffffff; - EDX = tsc >> 32; - break; - case 0x00000083: - EAX = ecx83_msr & 0xffffffff; - EDX = ecx83_msr >> 32; - break; - case 0xC0000080: - EAX = amd_efer & 0xffffffff; - EDX = amd_efer >> 32; - break; - case 0xC0000082: - EAX = amd_whcr & 0xffffffff; - EDX = amd_whcr >> 32; - break; - default: - x86gpf(NULL, 0); - break; - } - break; + switch (cpu_s->cpu_type) { + case CPU_IBM386SLC: + case CPU_IBM486SLC: + case CPU_IBM486BL: + EAX = EDX = 0; + switch (ECX) { + case 0x1000: + EAX = msr.ibm_por & ((cpu_s->cpu_type > CPU_IBM386SLC) ? 0xffeff : 0xfeff); + break; - case CPU_K6_2: - EAX = EDX = 0; - switch (ECX) - { - case 0x0000000e: - EAX = msr.tr12; - break; - case 0x00000010: - EAX = tsc & 0xffffffff; - EDX = tsc >> 32; - break; - case 0x00000083: - EAX = ecx83_msr & 0xffffffff; - EDX = ecx83_msr >> 32; - break; - case 0xC0000080: - EAX = amd_efer & 0xffffffff; - EDX = amd_efer >> 32; - break; - case 0xC0000081: - EAX = star & 0xffffffff; - EDX = star >> 32; - break; - case 0xC0000082: - EAX = amd_whcr & 0xffffffff; - EDX = amd_whcr >> 32; - break; - default: - x86gpf(NULL, 0); - break; - } - break; + case 0x1001: + EAX = msr.ibm_crcr & 0xffffffffff; + break; - case CPU_K6_2C: - EAX = EDX = 0; - switch (ECX) - { - case 0x0000000e: - EAX = msr.tr12; - break; - case 0x00000010: - EAX = tsc & 0xffffffff; - EDX = tsc >> 32; - break; - case 0x00000083: - EAX = ecx83_msr & 0xffffffff; - EDX = ecx83_msr >> 32; - break; - case 0xC0000080: - EAX = amd_efer & 0xffffffff; - EDX = amd_efer >> 32; - break; - case 0xC0000081: - EAX = star & 0xffffffff; - EDX = star >> 32; - break; - case 0xC0000082: - EAX = amd_whcr & 0xffffffff; - EDX = amd_whcr >> 32; - break; - case 0xC0000085: - EAX = amd_uwccr & 0xffffffff; - EDX = amd_uwccr >> 32; - break; - case 0xC0000087: - EAX = amd_psor & 0xffffffff; - EDX = amd_psor >> 32; - break; - case 0xC0000088: - EAX = amd_pfir & 0xffffffff; - EDX = amd_pfir >> 32; - break; - default: - x86gpf(NULL, 0); - break; - } - break; + case 0x1002: + if ((cpu_s->cpu_type > CPU_IBM386SLC) && cpu_s->multi) + EAX = msr.ibm_por2 & 0x3f000000; + break; + } + break; - case CPU_K6_3: - EAX = EDX = 0; - switch (ECX) - { - case 0x0000000e: - EAX = msr.tr12; - break; - case 0x00000010: - EAX = tsc & 0xffffffff; - EDX = tsc >> 32; - break; - case 0x00000083: - EAX = ecx83_msr & 0xffffffff; - EDX = ecx83_msr >> 32; - break; - case 0xC0000080: - EAX = amd_efer & 0xffffffff; - EDX = amd_efer >> 32; - break; - case 0xC0000081: - EAX = star & 0xffffffff; - EDX = star >> 32; - break; - case 0xC0000082: - EAX = amd_whcr & 0xffffffff; - EDX = amd_whcr >> 32; - break; - case 0xC0000085: - EAX = amd_uwccr & 0xffffffff; - EDX = amd_uwccr >> 32; - break; - case 0xC0000087: - EAX = amd_psor & 0xffffffff; - EDX = amd_psor >> 32; - break; - case 0xC0000088: - EAX = amd_pfir & 0xffffffff; - EDX = amd_pfir >> 32; - break; - case 0xC0000089: - EAX = amd_l2aar & 0xffffffff; - EDX = amd_l2aar >> 32; - break; - default: - x86gpf(NULL, 0); - break; - } - break; - - case CPU_K6_2P: - case CPU_K6_3P: - EAX = EDX = 0; - switch (ECX) - { - case 0x0000000e: - EAX = msr.tr12; - break; - case 0x00000010: - EAX = tsc & 0xffffffff; - EDX = tsc >> 32; - break; - case 0x00000083: - EAX = ecx83_msr & 0xffffffff; - EDX = ecx83_msr >> 32; - break; - case 0xC0000080: - EAX = amd_efer & 0xffffffff; - EDX = amd_efer >> 32; - break; - case 0xC0000081: - EAX = star & 0xffffffff; - EDX = star >> 32; - break; - case 0xC0000082: - EAX = amd_whcr & 0xffffffff; - EDX = amd_whcr >> 32; - break; - case 0xC0000085: - EAX = amd_uwccr & 0xffffffff; - EDX = amd_uwccr >> 32; - break; - case 0xC0000086: - EAX = amd_epmr & 0xffffffff; - EDX = amd_epmr >> 32; - break; - case 0xC0000087: - EAX = amd_psor & 0xffffffff; - EDX = amd_psor >> 32; - break; - case 0xC0000088: - EAX = amd_pfir & 0xffffffff; - EDX = amd_pfir >> 32; - break; - case 0xC0000089: - EAX = amd_l2aar & 0xffffffff; - EDX = amd_l2aar >> 32; - break; - default: - x86gpf(NULL, 0); - break; - } - break; - - case CPU_P24T: - case CPU_PENTIUM: - case CPU_PENTIUMMMX: - EAX = EDX = 0; - switch (ECX) - { - case 0x10: + case CPU_WINCHIP: + case CPU_WINCHIP2: + EAX = EDX = 0; + switch (ECX) { + case 0x02: + EAX = msr.tr1; + break; + case 0x0e: + EAX = msr.tr12; + break; + case 0x10: EAX = tsc & 0xffffffff; EDX = tsc >> 32; break; - } - break; -#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) - case CPU_Cx6x86: - case CPU_Cx6x86L: - case CPU_CxGX1: - case CPU_Cx6x86MX: - switch (ECX) - { - case 0x10: - EAX = tsc & 0xffffffff; - EDX = tsc >> 32; - break; - } - break; -#endif + case 0x11: + EAX = msr.cesr; + break; + case 0x107: + EAX = msr.fcr; + break; + case 0x108: + EAX = msr.fcr2 & 0xffffffff; + EDX = msr.fcr2 >> 32; + break; + case 0x10a: + EAX = cpu_multi & 3; + break; + } + break; - case CPU_PENTIUMPRO: - case CPU_PENTIUM2: - case CPU_PENTIUM2D: - EAX = EDX = 0; - switch (ECX) - { - case 0x10: - EAX = tsc & 0xffffffff; - EDX = tsc >> 32; - break; - case 0x17: - if (cpu_s->cpu_type != CPU_PENTIUM2D) goto i686_invalid_rdmsr; - EAX = ecx17_msr & 0xffffffff; - EDX = ecx17_msr >> 32; - break; - case 0x1B: - EAX = apic_base_msr & 0xffffffff; - EDX = apic_base_msr >> 32; - cpu_log("APIC_BASE read : %08X%08X\n", EDX, EAX); - break; - case 0x2A: - EAX = 0xC4000000; - EDX = 0; - if (cpu_dmulti == 2.5) - EAX |= ((0 << 25) | (1 << 24) | (1 << 23) | (1 << 22)); - else if (cpu_dmulti == 3) - EAX |= ((0 << 25) | (0 << 24) | (0 << 23) | (1 << 22)); - else if (cpu_dmulti == 3.5) - EAX |= ((0 << 25) | (1 << 24) | (0 << 23) | (1 << 22)); - else if (cpu_dmulti == 4) - EAX |= ((0 << 25) | (0 << 24) | (1 << 23) | (0 << 22)); - else if (cpu_dmulti == 4.5) - EAX |= ((0 << 25) | (1 << 24) | (1 << 23) | (0 << 22)); - else if (cpu_dmulti == 5) - EAX |= 0; - else if (cpu_dmulti == 5.5) - EAX |= ((0 << 25) | (1 << 24) | (0 << 23) | (0 << 22)); - else if (cpu_dmulti == 6) - EAX |= ((1 << 25) | (0 << 24) | (1 << 23) | (1 << 22)); - else if (cpu_dmulti == 6.5) - EAX |= ((1 << 25) | (1 << 24) | (1 << 23) | (1 << 22)); - else if (cpu_dmulti == 7) - EAX |= ((1 << 25) | (0 << 24) | (0 << 23) | (1 << 22)); - else if (cpu_dmulti == 7.5) - EAX |= ((1 << 25) | (1 << 24) | (0 << 23) | (1 << 22)); - else if (cpu_dmulti == 8) - EAX |= ((1 << 25) | (0 << 24) | (1 << 23) | (0 << 22)); - else - EAX |= ((0 << 25) | (1 << 24) | (1 << 23) | (1 << 22)); - if (cpu_s->cpu_type != CPU_PENTIUMPRO) { - if (cpu_busspeed >= 84000000) - EAX |= (1 << 19); - } - break; - case 0x79: - EAX = ecx79_msr & 0xffffffff; - EDX = ecx79_msr >> 32; - break; - case 0x88: case 0x89: case 0x8A: case 0x8B: - EAX = ecx8x_msr[ECX - 0x88] & 0xffffffff; - EDX = ecx8x_msr[ECX - 0x88] >> 32; - break; - case 0xC1: case 0xC2: case 0xC3: case 0xC4: case 0xC5: case 0xC6: case 0xC7: case 0xC8: - EAX = msr_ia32_pmc[ECX - 0xC1] & 0xffffffff; - EDX = msr_ia32_pmc[ECX - 0xC1] >> 32; - break; - case 0xFE: - EAX = mtrr_cap_msr & 0xffffffff; - EDX = mtrr_cap_msr >> 32; - break; - case 0x116: - EAX = ecx116_msr & 0xffffffff; - EDX = ecx116_msr >> 32; - break; - case 0x118: case 0x119: case 0x11A: case 0x11B: - EAX = ecx11x_msr[ECX - 0x118] & 0xffffffff; - EDX = ecx11x_msr[ECX - 0x118] >> 32; - break; - case 0x11E: - EAX = ecx11e_msr & 0xffffffff; - EDX = ecx11e_msr >> 32; - break; - case 0x174: - if (cpu_s->cpu_type == CPU_PENTIUMPRO) goto i686_invalid_rdmsr; - EAX &= 0xFFFF0000; - EAX |= cs_msr; - EDX = 0x00000000; - break; - case 0x175: - if (cpu_s->cpu_type == CPU_PENTIUMPRO) goto i686_invalid_rdmsr; - EAX = esp_msr; - EDX = 0x00000000; - break; - case 0x176: - if (cpu_s->cpu_type == CPU_PENTIUMPRO) goto i686_invalid_rdmsr; - EAX = eip_msr; - EDX = 0x00000000; - break; - case 0x179: - EAX = EDX = 0x00000000; - break; - case 0x186: - EAX = ecx186_msr & 0xffffffff; - EDX = ecx186_msr >> 32; - break; - case 0x187: - EAX = ecx187_msr & 0xffffffff; - EDX = ecx187_msr >> 32; - break; - case 0x1E0: - EAX = ecx1e0_msr & 0xffffffff; - EDX = ecx1e0_msr >> 32; - break; - case 0x200: case 0x201: case 0x202: case 0x203: case 0x204: case 0x205: case 0x206: case 0x207: - case 0x208: case 0x209: case 0x20A: case 0x20B: case 0x20C: case 0x20D: case 0x20E: case 0x20F: - if (ECX & 1) - { - EAX = mtrr_physmask_msr[(ECX - 0x200) >> 1] & 0xffffffff; - EDX = mtrr_physmask_msr[(ECX - 0x200) >> 1] >> 32; - } - else - { - EAX = mtrr_physbase_msr[(ECX - 0x200) >> 1] & 0xffffffff; - EDX = mtrr_physbase_msr[(ECX - 0x200) >> 1] >> 32; - } - break; + case CPU_CYRIX3S: + case CPU_EDEN: + EAX = EDX = 0; + switch (ECX) { + case 0x10: + EAX = tsc & 0xffffffff; + EDX = tsc >> 32; + break; + case 0x2a: + EAX = 0xc4000000; + EDX = 0; + if (cpu_dmulti == 3) + EAX |= ((0 << 25) | (0 << 24) | (0 << 23) | (1 << 22)); + else if (cpu_dmulti == 3.5) + EAX |= ((0 << 25) | (1 << 24) | (0 << 23) | (1 << 22)); + else if (cpu_dmulti == 4) + EAX |= ((0 << 25) | (0 << 24) | (1 << 23) | (0 << 22)); + else if (cpu_dmulti == 4.5) + EAX |= ((0 << 25) | (1 << 24) | (1 << 23) | (0 << 22)); + else if (cpu_dmulti == 5) + EAX |= 0; + else if (cpu_dmulti == 5.5) + EAX |= ((0 << 25) | (1 << 24) | (0 << 23) | (0 << 22)); + else if (cpu_dmulti == 6) + EAX |= ((1 << 25) | (0 << 24) | (1 << 23) | (1 << 22)); + else if (cpu_dmulti == 6.5) + EAX |= ((1 << 25) | (1 << 24) | (1 << 23) | (1 << 22)); + else if (cpu_dmulti == 7) + EAX |= ((1 << 25) | (0 << 24) | (0 << 23) | (1 << 22)); + else + EAX |= ((0 << 25) | (0 << 24) | (0 << 23) | (1 << 22)); + if (cpu_busspeed >= 84000000) + EAX |= (1 << 19); + break; + case 0x1107: + EAX = msr.fcr; + break; + case 0x1108: + EAX = msr.fcr2 & 0xffffffff; + EDX = msr.fcr2 >> 32; + break; + case 0x200: case 0x201: case 0x202: case 0x203: + case 0x204: case 0x205: case 0x206: case 0x207: + case 0x208: case 0x209: case 0x20a: case 0x20b: + case 0x20c: case 0x20d: case 0x20e: case 0x20f: + if (ECX & 1) { + EAX = msr.mtrr_physmask[(ECX - 0x200) >> 1] & 0xffffffff; + EDX = msr.mtrr_physmask[(ECX - 0x200) >> 1] >> 32; + } else { + EAX = msr.mtrr_physbase[(ECX - 0x200) >> 1] & 0xffffffff; + EDX = msr.mtrr_physbase[(ECX - 0x200) >> 1] >> 32; + } + break; case 0x250: - EAX = mtrr_fix64k_8000_msr & 0xffffffff; - EDX = mtrr_fix64k_8000_msr >> 32; - break; + EAX = msr.mtrr_fix64k_8000 & 0xffffffff; + EDX = msr.mtrr_fix64k_8000 >> 32; + break; case 0x258: - EAX = mtrr_fix16k_8000_msr & 0xffffffff; - EDX = mtrr_fix16k_8000_msr >> 32; - break; + EAX = msr.mtrr_fix16k_8000 & 0xffffffff; + EDX = msr.mtrr_fix16k_8000 >> 32; + break; case 0x259: - EAX = mtrr_fix16k_a000_msr & 0xffffffff; - EDX = mtrr_fix16k_a000_msr >> 32; - break; - case 0x268: case 0x269: case 0x26A: case 0x26B: case 0x26C: case 0x26D: case 0x26E: case 0x26F: - EAX = mtrr_fix4k_msr[ECX - 0x268] & 0xffffffff; - EDX = mtrr_fix4k_msr[ECX - 0x268] >> 32; - break; + EAX = msr.mtrr_fix16k_a000 & 0xffffffff; + EDX = msr.mtrr_fix16k_a000 >> 32; + break; + case 0x268: case 0x269: case 0x26a: case 0x26b: + case 0x26c: case 0x26d: case 0x26e: case 0x26f: + EAX = msr.mtrr_fix4k[ECX - 0x268] & 0xffffffff; + EDX = msr.mtrr_fix4k[ECX - 0x268] >> 32; + break; + case 0x2ff: + EAX = msr.mtrr_deftype & 0xffffffff; + EDX = msr.mtrr_deftype >> 32; + break; + } + break; + +#if defined(DEV_BRANCH) && defined(USE_AMD_K5) + case CPU_K5: + case CPU_5K86: +#endif + case CPU_K6: + case CPU_K6_2: + case CPU_K6_2C: + case CPU_K6_3: + case CPU_K6_2P: + case CPU_K6_3P: + EAX = EDX = 0; + switch (ECX) { + case 0x0000000e: + EAX = msr.tr12; + break; + case 0x00000010: + EAX = tsc & 0xffffffff; + EDX = tsc >> 32; + break; + case 0x00000083: + EAX = msr.ecx83 & 0xffffffff; + EDX = msr.ecx83 >> 32; + break; + case 0xc0000080: + EAX = msr.amd_efer & 0xffffffff; + EDX = msr.amd_efer >> 32; + break; + case 0xc0000081: + if (cpu_s->cpu_type < CPU_K6_2) + goto amd_k_invalid_rdmsr; + + EAX = msr.star & 0xffffffff; + EDX = msr.star >> 32; + break; + case 0xc0000082: + EAX = msr.amd_whcr & 0xffffffff; + EDX = msr.amd_whcr >> 32; + break; + case 0xc0000085: + if (cpu_s->cpu_type < CPU_K6_2C) + goto amd_k_invalid_rdmsr; + + EAX = msr.amd_uwccr & 0xffffffff; + EDX = msr.amd_uwccr >> 32; + break; + case 0xc0000086: + if (cpu_s->cpu_type < CPU_K6_2P) + goto amd_k_invalid_rdmsr; + + EAX = msr.amd_epmr & 0xffffffff; + EDX = msr.amd_epmr >> 32; + break; + case 0xc0000087: + if (cpu_s->cpu_type < CPU_K6_2C) + goto amd_k_invalid_rdmsr; + + EAX = msr.amd_psor & 0xffffffff; + EDX = msr.amd_psor >> 32; + break; + case 0xc0000088: + if (cpu_s->cpu_type < CPU_K6_2C) + goto amd_k_invalid_rdmsr; + + EAX = msr.amd_pfir & 0xffffffff; + EDX = msr.amd_pfir >> 32; + break; + case 0xc0000089: + if (cpu_s->cpu_type < CPU_K6_3) + goto amd_k_invalid_rdmsr; + + EAX = msr.amd_l2aar & 0xffffffff; + EDX = msr.amd_l2aar >> 32; + break; + default: +amd_k_invalid_rdmsr: + x86gpf(NULL, 0); + break; + } + break; + + case CPU_P24T: + case CPU_PENTIUM: + case CPU_PENTIUMMMX: +#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) + case CPU_Cx6x86: + case CPU_Cx6x86L: + case CPU_CxGX1: + case CPU_Cx6x86MX: + if (cpu_s->cpu_type < CPU_Cx6x86) +#endif + EAX = EDX = 0; + switch (ECX) { + case 0x10: + EAX = tsc & 0xffffffff; + EDX = tsc >> 32; + break; + } + break; + + case CPU_PENTIUMPRO: + case CPU_PENTIUM2: + case CPU_PENTIUM2D: + EAX = EDX = 0; + switch (ECX) { + case 0x10: + EAX = tsc & 0xffffffff; + EDX = tsc >> 32; + break; + case 0x17: + if (cpu_s->cpu_type != CPU_PENTIUM2D) + goto i686_invalid_rdmsr; + + EAX = msr.ecx17 & 0xffffffff; + EDX = msr.ecx17 >> 32; + break; + case 0x1B: + EAX = msr.apic_base & 0xffffffff; + EDX = msr.apic_base >> 32; + cpu_log("APIC_BASE read : %08X%08X\n", EDX, EAX); + break; + case 0x2a: + EAX = 0xc4000000; + EDX = 0; + if (cpu_dmulti == 2.5) + EAX |= ((0 << 25) | (1 << 24) | (1 << 23) | (1 << 22)); + else if (cpu_dmulti == 3) + EAX |= ((0 << 25) | (0 << 24) | (0 << 23) | (1 << 22)); + else if (cpu_dmulti == 3.5) + EAX |= ((0 << 25) | (1 << 24) | (0 << 23) | (1 << 22)); + else if (cpu_dmulti == 4) + EAX |= ((0 << 25) | (0 << 24) | (1 << 23) | (0 << 22)); + else if (cpu_dmulti == 4.5) + EAX |= ((0 << 25) | (1 << 24) | (1 << 23) | (0 << 22)); + else if (cpu_dmulti == 5) + EAX |= 0; + else if (cpu_dmulti == 5.5) + EAX |= ((0 << 25) | (1 << 24) | (0 << 23) | (0 << 22)); + else if (cpu_dmulti == 6) + EAX |= ((1 << 25) | (0 << 24) | (1 << 23) | (1 << 22)); + else if (cpu_dmulti == 6.5) + EAX |= ((1 << 25) | (1 << 24) | (1 << 23) | (1 << 22)); + else if (cpu_dmulti == 7) + EAX |= ((1 << 25) | (0 << 24) | (0 << 23) | (1 << 22)); + else if (cpu_dmulti == 7.5) + EAX |= ((1 << 25) | (1 << 24) | (0 << 23) | (1 << 22)); + else if (cpu_dmulti == 8) + EAX |= ((1 << 25) | (0 << 24) | (1 << 23) | (0 << 22)); + else + EAX |= ((0 << 25) | (1 << 24) | (1 << 23) | (1 << 22)); + if (cpu_s->cpu_type != CPU_PENTIUMPRO) { + if (cpu_busspeed >= 84000000) + EAX |= (1 << 19); + } + break; + case 0x79: + EAX = msr.ecx79 & 0xffffffff; + EDX = msr.ecx79 >> 32; + break; + case 0x88: case 0x89: case 0x8a: case 0x8b: + EAX = msr.ecx8x[ECX - 0x88] & 0xffffffff; + EDX = msr.ecx8x[ECX - 0x88] >> 32; + break; + case 0xc1: case 0xc2: case 0xc3: case 0xc4: + case 0xc5: case 0xc6: case 0xc7: case 0xc8: + EAX = msr.ia32_pmc[ECX - 0xC1] & 0xffffffff; + EDX = msr.ia32_pmc[ECX - 0xC1] >> 32; + break; + case 0xfe: + EAX = msr.mtrr_cap & 0xffffffff; + EDX = msr.mtrr_cap >> 32; + break; + case 0x116: + EAX = msr.ecx116 & 0xffffffff; + EDX = msr.ecx116 >> 32; + break; + case 0x118: case 0x119: case 0x11a: case 0x11b: + EAX = msr.ecx11x[ECX - 0x118] & 0xffffffff; + EDX = msr.ecx11x[ECX - 0x118] >> 32; + break; + case 0x11e: + EAX = msr.ecx11e & 0xffffffff; + EDX = msr.ecx11e >> 32; + break; + case 0x174: + if (cpu_s->cpu_type == CPU_PENTIUMPRO) + goto i686_invalid_rdmsr; + + EAX &= 0xffff0000; + EAX |= msr.sysenter_cs; + EDX = 0x00000000; + break; + case 0x175: + if (cpu_s->cpu_type == CPU_PENTIUMPRO) + goto i686_invalid_rdmsr; + + EAX = msr.sysenter_esp; + EDX = 0x00000000; + break; + case 0x176: + if (cpu_s->cpu_type == CPU_PENTIUMPRO) + goto i686_invalid_rdmsr; + + EAX = msr.sysenter_eip; + EDX = 0x00000000; + break; + case 0x179: + EAX = EDX = 0x00000000; + break; + case 0x186: + EAX = msr.ecx186 & 0xffffffff; + EDX = msr.ecx186 >> 32; + break; + case 0x187: + EAX = msr.ecx187 & 0xffffffff; + EDX = msr.ecx187 >> 32; + break; + case 0x1e0: + EAX = msr.ecx1e0 & 0xffffffff; + EDX = msr.ecx1e0 >> 32; + break; + case 0x200: case 0x201: case 0x202: case 0x203: + case 0x204: case 0x205: case 0x206: case 0x207: + case 0x208: case 0x209: case 0x20a: case 0x20b: + case 0x20c: case 0x20d: case 0x20e: case 0x20f: + if (ECX & 1) { + EAX = msr.mtrr_physmask[(ECX - 0x200) >> 1] & 0xffffffff; + EDX = msr.mtrr_physmask[(ECX - 0x200) >> 1] >> 32; + } else { + EAX = msr.mtrr_physbase[(ECX - 0x200) >> 1] & 0xffffffff; + EDX = msr.mtrr_physbase[(ECX - 0x200) >> 1] >> 32; + } + break; + case 0x250: + EAX = msr.mtrr_fix64k_8000 & 0xffffffff; + EDX = msr.mtrr_fix64k_8000 >> 32; + break; + case 0x258: + EAX = msr.mtrr_fix16k_8000 & 0xffffffff; + EDX = msr.mtrr_fix16k_8000 >> 32; + break; + case 0x259: + EAX = msr.mtrr_fix16k_a000 & 0xffffffff; + EDX = msr.mtrr_fix16k_a000 >> 32; + break; + case 0x268: case 0x269: case 0x26a: case 0x26b: + case 0x26c: case 0x26d: case 0x26e: case 0x26f: + EAX = msr.mtrr_fix4k[ECX - 0x268] & 0xffffffff; + EDX = msr.mtrr_fix4k[ECX - 0x268] >> 32; + break; case 0x277: - EAX = pat_msr & 0xffffffff; - EDX = pat_msr >> 32; - break; - case 0x2FF: - EAX = mtrr_deftype_msr & 0xffffffff; - EDX = mtrr_deftype_msr >> 32; - break; + EAX = msr.pat & 0xffffffff; + EDX = msr.pat >> 32; + break; + case 0x2ff: + EAX = msr.mtrr_deftype & 0xffffffff; + EDX = msr.mtrr_deftype >> 32; + break; case 0x404: - EAX = ecx404_msr & 0xffffffff; - EDX = ecx404_msr >> 32; - break; + EAX = msr.ecx404 & 0xffffffff; + EDX = msr.ecx404 >> 32; + break; case 0x408: - EAX = ecx408_msr & 0xffffffff; - EDX = ecx408_msr >> 32; - break; + EAX = msr.ecx408 & 0xffffffff; + EDX = msr.ecx408 >> 32; + break; case 0x40c: - EAX = ecx40c_msr & 0xffffffff; - EDX = ecx40c_msr >> 32; - break; + EAX = msr.ecx40c & 0xffffffff; + EDX = msr.ecx40c >> 32; + break; case 0x410: - EAX = ecx410_msr & 0xffffffff; - EDX = ecx410_msr >> 32; - break; + EAX = msr.ecx410 & 0xffffffff; + EDX = msr.ecx410 >> 32; + break; case 0x570: - EAX = ecx570_msr & 0xffffffff; - EDX = ecx570_msr >> 32; - break; + EAX = msr.ecx570 & 0xffffffff; + EDX = msr.ecx570 >> 32; + break; case 0x1002ff: - EAX = ecx1002ff_msr & 0xffffffff; - EDX = ecx1002ff_msr >> 32; - break; + EAX = msr.ecx1002ff & 0xffffffff; + EDX = msr.ecx1002ff >> 32; + break; case 0xf0f00250: - EAX = ecxf0f00250_msr & 0xffffffff; - EDX = ecxf0f00250_msr >> 32; - break; + EAX = msr.ecxf0f00250 & 0xffffffff; + EDX = msr.ecxf0f00250 >> 32; + break; case 0xf0f00258: - EAX = ecxf0f00258_msr & 0xffffffff; - EDX = ecxf0f00258_msr >> 32; - break; + EAX = msr.ecxf0f00258 & 0xffffffff; + EDX = msr.ecxf0f00258 >> 32; + break; case 0xf0f00259: - EAX = ecxf0f00259_msr & 0xffffffff; - EDX = ecxf0f00259_msr >> 32; - break; + EAX = msr.ecxf0f00259 & 0xffffffff; + EDX = msr.ecxf0f00259 >> 32; + break; default: i686_invalid_rdmsr: - cpu_log("RDMSR: Invalid MSR: %08X\n", ECX); - x86gpf(NULL, 0); - break; - } - break; - } + cpu_log("RDMSR: Invalid MSR: %08X\n", ECX); + x86gpf(NULL, 0); + break; + } + break; + } - cpu_log("RDMSR %08X %08X%08X\n", ECX, EDX, EAX); + cpu_log("RDMSR %08X %08X%08X\n", ECX, EDX, EAX); } -void cpu_WRMSR() + +void +cpu_WRMSR(void) { - uint64_t temp; + uint64_t temp; - cpu_log("WRMSR %08X %08X%08X\n", ECX, EDX, EAX); - switch (cpu_s->cpu_type) - { - case CPU_IBM386SLC: - switch (ECX) - { - case 0x1000: - ibm_por_msr = EAX & 0xfeff; - if (EAX & (1 << 7)) - cpu_cache_int_enabled = 1; - else - cpu_cache_int_enabled = 0; - break; - case 0x1001: - ibm_crcr_msr = EAX & 0xffffffffff; - break; - } - break; - - case CPU_IBM486BL: - case CPU_IBM486SLC: - switch (ECX) - { - case 0x1000: - ibm_por_msr = EAX & 0xffeff; - if (EAX & (1 << 7)) - cpu_cache_int_enabled = 1; - else - cpu_cache_int_enabled = 0; - break; - case 0x1001: - ibm_crcr_msr = EAX & 0xffffffffff; - break; - if (cpu_s->multi) { - case 0x1002: - ibm_por2_msr = EAX & 0x3f000000; - } - break; - } - break; - - case CPU_WINCHIP: - case CPU_WINCHIP2: - switch (ECX) - { - case 0x02: - msr.tr1 = EAX & 2; - break; - case 0x0e: - msr.tr12 = EAX & 0x228; - break; - case 0x10: - tsc = EAX | ((uint64_t)EDX << 32); - break; - case 0x11: - msr.cesr = EAX & 0xff00ff; - break; - case 0x107: - msr.fcr = EAX; - if (EAX & (1 << 9)) - cpu_features |= CPU_FEATURE_MMX; - else - cpu_features &= ~CPU_FEATURE_MMX; - if (EAX & (1 << 1)) - cpu_features |= CPU_FEATURE_CX8; - else - cpu_features &= ~CPU_FEATURE_CX8; - if ((EAX & (1 << 20)) && cpu_s->cpu_type >= CPU_WINCHIP2) - cpu_features |= CPU_FEATURE_3DNOW; - else - cpu_features &= ~CPU_FEATURE_3DNOW; - if (EAX & (1 << 29)) - CPUID = 0; - else - CPUID = cpu_s->cpuid_model; - break; - case 0x108: - msr.fcr2 = EAX | ((uint64_t)EDX << 32); - break; - case 0x109: - msr.fcr3 = EAX | ((uint64_t)EDX << 32); - break; - } - break; - case CPU_CYRIX3S: - case CPU_EDEN: - switch (ECX) - { - case 0x10: - tsc = EAX | ((uint64_t)EDX << 32); - break; - case 0x1107: - msr.fcr = EAX; - if (EAX & (1 << 1)) - cpu_features |= CPU_FEATURE_CX8; - else - cpu_features &= ~CPU_FEATURE_CX8; - break; - case 0x1108: - msr.fcr2 = EAX | ((uint64_t)EDX << 32); - break; - case 0x1109: - msr.fcr3 = EAX | ((uint64_t)EDX << 32); - break; - case 0x200: case 0x201: case 0x202: case 0x203: case 0x204: case 0x205: case 0x206: case 0x207: - case 0x208: case 0x209: case 0x20A: case 0x20B: case 0x20C: case 0x20D: case 0x20E: case 0x20F: - if (ECX & 1) - mtrr_physmask_msr[(ECX - 0x200) >> 1] = EAX | ((uint64_t)EDX << 32); - else - mtrr_physbase_msr[(ECX - 0x200) >> 1] = EAX | ((uint64_t)EDX << 32); - break; - case 0x250: - mtrr_fix64k_8000_msr = EAX | ((uint64_t)EDX << 32); - break; - case 0x258: - mtrr_fix16k_8000_msr = EAX | ((uint64_t)EDX << 32); - break; - case 0x259: - mtrr_fix16k_a000_msr = EAX | ((uint64_t)EDX << 32); - break; - case 0x268: case 0x269: case 0x26A: case 0x26B: case 0x26C: case 0x26D: case 0x26E: case 0x26F: - mtrr_fix4k_msr[ECX - 0x268] = EAX | ((uint64_t)EDX << 32); - break; - case 0x2FF: - mtrr_deftype_msr = EAX | ((uint64_t)EDX << 32); - break; - } - break; - -#if defined(DEV_BRANCH) && defined(USE_AMD_K5) - case CPU_K5: - case CPU_5K86: -#endif - case CPU_K6: - switch (ECX) - { - case 0x0e: - msr.tr12 = EAX & 0x228; - break; - case 0x10: - tsc = EAX | ((uint64_t)EDX << 32); - break; - case 0x83: - ecx83_msr = EAX | ((uint64_t)EDX << 32); - break; - case 0xC0000080: - temp = EAX | ((uint64_t)EDX << 32); - if (temp & ~1ULL) - x86gpf(NULL, 0); - else - amd_efer = temp; - break; - case 0xC0000082: - amd_whcr = EAX | ((uint64_t)EDX << 32); - break; - default: - x86gpf(NULL, 0); - break; - } - break; + cpu_log("WRMSR %08X %08X%08X\n", ECX, EDX, EAX); - case CPU_K6_2: - switch (ECX) - { - case 0x0e: - msr.tr12 = EAX & 0x228; - break; - case 0x10: - tsc = EAX | ((uint64_t)EDX << 32); - break; - case 0x83: - ecx83_msr = EAX | ((uint64_t)EDX << 32); - break; - case 0xC0000080: - temp = EAX | ((uint64_t)EDX << 32); - if (temp & ~1ULL) - x86gpf(NULL, 0); - else - amd_efer = temp; - break; - case 0xC0000081: - star = EAX | ((uint64_t)EDX << 32); - break; - case 0xC0000082: - amd_whcr = EAX | ((uint64_t)EDX << 32); - break; - default: - x86gpf(NULL, 0); - break; - } - break; + switch (cpu_s->cpu_type) { + case CPU_IBM386SLC: + case CPU_IBM486BL: + case CPU_IBM486SLC: + switch (ECX) { + case 0x1000: + msr.ibm_por = EAX & ((cpu_s->cpu_type > CPU_IBM386SLC) ? 0xffeff : 0xfeff); + cpu_cache_int_enabled = (EAX & (1 << 7)); + break; + case 0x1001: + msr.ibm_crcr = EAX & 0xffffffffff; + break; + case 0x1002: + if ((cpu_s->cpu_type > CPU_IBM386SLC) && cpu_s->multi) + msr.ibm_por2 = EAX & 0x3f000000; + break; + } + break; - case CPU_K6_2C: - switch (ECX) - { - case 0x0e: - msr.tr12 = EAX & 0x228; - break; - case 0x10: - tsc = EAX | ((uint64_t)EDX << 32); - break; - case 0x83: - ecx83_msr = EAX | ((uint64_t)EDX << 32); - break; - case 0xC0000080: - temp = EAX | ((uint64_t)EDX << 32); - if (temp & ~0xfULL) - x86gpf(NULL, 0); - else - amd_efer = temp; - break; - case 0xC0000081: - star = EAX | ((uint64_t)EDX << 32); - break; - case 0xC0000082: - amd_whcr = EAX | ((uint64_t)EDX << 32); - break; - case 0xC0000085: - amd_uwccr = EAX | ((uint64_t)EDX << 32); - break; - case 0xC0000087: - amd_psor = EAX | ((uint64_t)EDX << 32); - break; - case 0xC0000088: - amd_pfir = EAX | ((uint64_t)EDX << 32); - break; - default: - x86gpf(NULL, 0); - break; - } - break; - - case CPU_K6_3: - switch (ECX) - { - case 0x0e: - msr.tr12 = EAX & 0x228; - break; - case 0x10: - tsc = EAX | ((uint64_t)EDX << 32); - break; - case 0x83: - ecx83_msr = EAX | ((uint64_t)EDX << 32); - break; - case 0xC0000080: - temp = EAX | ((uint64_t)EDX << 32); - if (temp & ~0x1fULL) - x86gpf(NULL, 0); - else - amd_efer = temp; - break; - case 0xC0000081: - star = EAX | ((uint64_t)EDX << 32); - break; - case 0xC0000082: - amd_whcr = EAX | ((uint64_t)EDX << 32); - break; - case 0xC0000085: - amd_uwccr = EAX | ((uint64_t)EDX << 32); - break; - case 0xC0000087: - amd_psor = EAX | ((uint64_t)EDX << 32); - break; - case 0xC0000088: - amd_pfir = EAX | ((uint64_t)EDX << 32); - break; - case 0xC0000089: - amd_l2aar = EAX | ((uint64_t)EDX << 32); - break; - default: - x86gpf(NULL, 0); - break; - } - break; - - case CPU_K6_2P: - case CPU_K6_3P: - switch (ECX) - { - case 0x0e: - msr.tr12 = EAX & 0x228; - break; - case 0x10: - tsc = EAX | ((uint64_t)EDX << 32); - break; - case 0x83: - ecx83_msr = EAX | ((uint64_t)EDX << 32); - break; - case 0xC0000080: - temp = EAX | ((uint64_t)EDX << 32); - if (temp & ~0x1fULL) - x86gpf(NULL, 0); - else - amd_efer = temp; - break; - case 0xC0000081: - star = EAX | ((uint64_t)EDX << 32); - break; - case 0xC0000082: - amd_whcr = EAX | ((uint64_t)EDX << 32); - break; - case 0xC0000085: - amd_uwccr = EAX | ((uint64_t)EDX << 32); - break; - case 0xC0000086: - amd_epmr = EAX | ((uint64_t)EDX << 32); - break; - case 0xC0000087: - amd_psor = EAX | ((uint64_t)EDX << 32); - break; - case 0xC0000088: - amd_pfir = EAX | ((uint64_t)EDX << 32); - break; - case 0xC0000089: - amd_l2aar = EAX | ((uint64_t)EDX << 32); - break; - default: - x86gpf(NULL, 0); - break; - } - break; - - case CPU_P24T: - case CPU_PENTIUM: - case CPU_PENTIUMMMX: - switch (ECX) - { - case 0x10: + case CPU_WINCHIP: + case CPU_WINCHIP2: + switch (ECX) { + case 0x02: + msr.tr1 = EAX & 2; + break; + case 0x0e: + msr.tr12 = EAX & 0x228; + break; + case 0x10: tsc = EAX | ((uint64_t)EDX << 32); break; - case 0x8B: - cpu_log("WRMSR: Invalid MSR: 0x8B\n"); - x86gpf(NULL, 0); /*Needed for Vista to correctly break on Pentium*/ + case 0x11: + msr.cesr = EAX & 0xff00ff; break; - } - break; -#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) - case CPU_Cx6x86: - case CPU_Cx6x86L: - case CPU_CxGX1: - case CPU_Cx6x86MX: - switch (ECX) - { - case 0x10: - tsc = EAX | ((uint64_t)EDX << 32); - break; - } - break; -#endif + case 0x107: + msr.fcr = EAX; + if (EAX & (1 << 9)) + cpu_features |= CPU_FEATURE_MMX; + else + cpu_features &= ~CPU_FEATURE_MMX; + if (EAX & (1 << 1)) + cpu_features |= CPU_FEATURE_CX8; + else + cpu_features &= ~CPU_FEATURE_CX8; + if ((EAX & (1 << 20)) && cpu_s->cpu_type >= CPU_WINCHIP2) + cpu_features |= CPU_FEATURE_3DNOW; + else + cpu_features &= ~CPU_FEATURE_3DNOW; + if (EAX & (1 << 29)) + CPUID = 0; + else + CPUID = cpu_s->cpuid_model; + break; + case 0x108: + msr.fcr2 = EAX | ((uint64_t)EDX << 32); + break; + case 0x109: + msr.fcr3 = EAX | ((uint64_t)EDX << 32); + break; + } + break; - case CPU_PENTIUMPRO: - case CPU_PENTIUM2: - case CPU_PENTIUM2D: - switch (ECX) - { - case 0x10: - tsc = EAX | ((uint64_t)EDX << 32); - break; - case 0x17: - if (cpu_s->cpu_type != CPU_PENTIUM2D) goto i686_invalid_wrmsr; - ecx17_msr = EAX | ((uint64_t)EDX << 32); - break; - case 0x1B: - cpu_log("APIC_BASE write: %08X%08X\n", EDX, EAX); - // apic_base_msr = EAX | ((uint64_t)EDX << 32); - break; - case 0x2A: - ecx2a_msr = EAX | ((uint64_t)EDX << 32); - break; - case 0x79: - ecx79_msr = EAX | ((uint64_t)EDX << 32); - break; - case 0x88: case 0x89: case 0x8A: case 0x8B: - ecx8x_msr[ECX - 0x88] = EAX | ((uint64_t)EDX << 32); - break; - case 0xC1: case 0xC2: case 0xC3: case 0xC4: case 0xC5: case 0xC6: case 0xC7: case 0xC8: - msr_ia32_pmc[ECX - 0xC1] = EAX | ((uint64_t)EDX << 32); - break; - case 0xFE: - mtrr_cap_msr = EAX | ((uint64_t)EDX << 32); - break; - case 0x116: - ecx116_msr = EAX | ((uint64_t)EDX << 32); - break; - case 0x118: case 0x119: case 0x11A: case 0x11B: - ecx11x_msr[ECX - 0x118] = EAX | ((uint64_t)EDX << 32); - break; - case 0x11E: - ecx11e_msr = EAX | ((uint64_t)EDX << 32); - break; - case 0x174: - if (cpu_s->cpu_type == CPU_PENTIUMPRO) goto i686_invalid_wrmsr; - cs_msr = EAX & 0xFFFF; - break; - case 0x175: - if (cpu_s->cpu_type == CPU_PENTIUMPRO) goto i686_invalid_wrmsr; - esp_msr = EAX; - break; - case 0x176: - if (cpu_s->cpu_type == CPU_PENTIUMPRO) goto i686_invalid_wrmsr; - eip_msr = EAX; - break; - case 0x179: - break; - case 0x186: - ecx186_msr = EAX | ((uint64_t)EDX << 32); - break; - case 0x187: - ecx187_msr = EAX | ((uint64_t)EDX << 32); - break; - case 0x1E0: - ecx1e0_msr = EAX | ((uint64_t)EDX << 32); - break; - case 0x200: case 0x201: case 0x202: case 0x203: case 0x204: case 0x205: case 0x206: case 0x207: - case 0x208: case 0x209: case 0x20A: case 0x20B: case 0x20C: case 0x20D: case 0x20E: case 0x20F: - if (ECX & 1) - mtrr_physmask_msr[(ECX - 0x200) >> 1] = EAX | ((uint64_t)EDX << 32); - else - mtrr_physbase_msr[(ECX - 0x200) >> 1] = EAX | ((uint64_t)EDX << 32); - break; + case CPU_CYRIX3S: + case CPU_EDEN: + switch (ECX) { + case 0x10: + tsc = EAX | ((uint64_t)EDX << 32); + break; + case 0x1107: + msr.fcr = EAX; + if (EAX & (1 << 1)) + cpu_features |= CPU_FEATURE_CX8; + else + cpu_features &= ~CPU_FEATURE_CX8; + break; + case 0x1108: + msr.fcr2 = EAX | ((uint64_t)EDX << 32); + break; + case 0x1109: + msr.fcr3 = EAX | ((uint64_t)EDX << 32); + break; + case 0x200: case 0x201: case 0x202: case 0x203: + case 0x204: case 0x205: case 0x206: case 0x207: + case 0x208: case 0x209: case 0x20a: case 0x20b: + case 0x20c: case 0x20d: case 0x20e: case 0x20f: + if (ECX & 1) + msr.mtrr_physmask[(ECX - 0x200) >> 1] = EAX | ((uint64_t)EDX << 32); + else + msr.mtrr_physbase[(ECX - 0x200) >> 1] = EAX | ((uint64_t)EDX << 32); + break; case 0x250: - mtrr_fix64k_8000_msr = EAX | ((uint64_t)EDX << 32); - break; + msr.mtrr_fix64k_8000 = EAX | ((uint64_t)EDX << 32); + break; case 0x258: - mtrr_fix16k_8000_msr = EAX | ((uint64_t)EDX << 32); - break; + msr.mtrr_fix16k_8000 = EAX | ((uint64_t)EDX << 32); + break; case 0x259: - mtrr_fix16k_a000_msr = EAX | ((uint64_t)EDX << 32); - break; + msr.mtrr_fix16k_a000 = EAX | ((uint64_t)EDX << 32); + break; case 0x268: case 0x269: case 0x26A: case 0x26B: case 0x26C: case 0x26D: case 0x26E: case 0x26F: - mtrr_fix4k_msr[ECX - 0x268] = EAX | ((uint64_t)EDX << 32); - break; + msr.mtrr_fix4k[ECX - 0x268] = EAX | ((uint64_t)EDX << 32); + break; + case 0x2ff: + msr.mtrr_deftype = EAX | ((uint64_t)EDX << 32); + break; + } + break; + +#if defined(DEV_BRANCH) && defined(USE_AMD_K5) + case CPU_K5: + case CPU_5K86: +#endif + case CPU_K6: + case CPU_K6_2: + case CPU_K6_2C: + case CPU_K6_3: + case CPU_K6_2P: + case CPU_K6_3P: + switch (ECX) { + case 0x0e: + msr.tr12 = EAX & 0x228; + break; + case 0x10: + tsc = EAX | ((uint64_t)EDX << 32); + break; + case 0x83: + msr.ecx83 = EAX | ((uint64_t)EDX << 32); + break; + case 0xc0000080: + temp = EAX | ((uint64_t)EDX << 32); + if (temp & ~1ULL) + x86gpf(NULL, 0); + else + msr.amd_efer = temp; + break; + case 0xc0000081: + if (cpu_s->cpu_type < CPU_K6_2) + goto amd_k_invalid_wrmsr; + + msr.star = EAX | ((uint64_t)EDX << 32); + break; + case 0xc0000082: + msr.amd_whcr = EAX | ((uint64_t)EDX << 32); + break; + case 0xc0000085: + if (cpu_s->cpu_type < CPU_K6_2C) + goto amd_k_invalid_wrmsr; + + msr.amd_uwccr = EAX | ((uint64_t)EDX << 32); + break; + case 0xc0000086: + if (cpu_s->cpu_type < CPU_K6_2P) + goto amd_k_invalid_wrmsr; + + msr.amd_epmr = EAX | ((uint64_t)EDX << 32); + break; + case 0xc0000087: + if (cpu_s->cpu_type < CPU_K6_2C) + goto amd_k_invalid_wrmsr; + + msr.amd_psor = EAX | ((uint64_t)EDX << 32); + break; + case 0xc0000088: + if (cpu_s->cpu_type < CPU_K6_2C) + goto amd_k_invalid_wrmsr; + + msr.amd_pfir = EAX | ((uint64_t)EDX << 32); + break; + case 0xc0000089: + if (cpu_s->cpu_type < CPU_K6_3) + goto amd_k_invalid_wrmsr; + + msr.amd_l2aar = EAX | ((uint64_t)EDX << 32); + break; + default: +amd_k_invalid_wrmsr: + x86gpf(NULL, 0); + break; + } + break; + + case CPU_P24T: + case CPU_PENTIUM: + case CPU_PENTIUMMMX: +#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) + case CPU_Cx6x86: + case CPU_Cx6x86L: + case CPU_CxGX1: + case CPU_Cx6x86MX: +#endif + switch (ECX) { + case 0x10: + tsc = EAX | ((uint64_t)EDX << 32); + break; + case 0x8b: +#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) + if (cpu_s->cpu_type < CPU_Cx6x86) { +#endif + cpu_log("WRMSR: Invalid MSR: 0x8B\n"); + x86gpf(NULL, 0); /* Needed for Vista to correctly break on Pentium */ +#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) + } +#endif + break; + } + break; + + case CPU_PENTIUMPRO: + case CPU_PENTIUM2: + case CPU_PENTIUM2D: + switch (ECX) { + case 0x10: + tsc = EAX | ((uint64_t)EDX << 32); + break; + case 0x17: + if (cpu_s->cpu_type != CPU_PENTIUM2D) + goto i686_invalid_wrmsr; + + msr.ecx17 = EAX | ((uint64_t)EDX << 32); + break; + case 0x1b: + cpu_log("APIC_BASE write: %08X%08X\n", EDX, EAX); + // msr.apic_base = EAX | ((uint64_t)EDX << 32); + break; + case 0x2a: + break; + case 0x79: + msr.ecx79 = EAX | ((uint64_t)EDX << 32); + break; + case 0x88: case 0x89: case 0x8a: case 0x8b: + msr.ecx8x[ECX - 0x88] = EAX | ((uint64_t)EDX << 32); + break; + case 0xc1: case 0xc2: case 0xc3: case 0xc4: + case 0xc5: case 0xc6: case 0xc7: case 0xc8: + msr.ia32_pmc[ECX - 0xC1] = EAX | ((uint64_t)EDX << 32); + break; + case 0xfe: + msr.mtrr_cap = EAX | ((uint64_t)EDX << 32); + break; + case 0x116: + msr.ecx116 = EAX | ((uint64_t)EDX << 32); + break; + case 0x118: case 0x119: case 0x11a: case 0x11b: + msr.ecx11x[ECX - 0x118] = EAX | ((uint64_t)EDX << 32); + break; + case 0x11e: + msr.ecx11e = EAX | ((uint64_t)EDX << 32); + break; + case 0x174: + if (cpu_s->cpu_type == CPU_PENTIUMPRO) + goto i686_invalid_wrmsr; + + msr.sysenter_cs = EAX & 0xFFFF; + break; + case 0x175: + if (cpu_s->cpu_type == CPU_PENTIUMPRO) + goto i686_invalid_wrmsr; + + msr.sysenter_esp = EAX; + break; + case 0x176: + if (cpu_s->cpu_type == CPU_PENTIUMPRO) + goto i686_invalid_wrmsr; + + msr.sysenter_eip = EAX; + break; + case 0x179: + break; + case 0x186: + msr.ecx186 = EAX | ((uint64_t)EDX << 32); + break; + case 0x187: + msr.ecx187 = EAX | ((uint64_t)EDX << 32); + break; + case 0x1e0: + msr.ecx1e0 = EAX | ((uint64_t)EDX << 32); + break; + case 0x200: case 0x201: case 0x202: case 0x203: + case 0x204: case 0x205: case 0x206: case 0x207: + case 0x208: case 0x209: case 0x20a: case 0x20b: + case 0x20c: case 0x20d: case 0x20e: case 0x20f: + if (ECX & 1) + msr.mtrr_physmask[(ECX - 0x200) >> 1] = EAX | ((uint64_t)EDX << 32); + else + msr.mtrr_physbase[(ECX - 0x200) >> 1] = EAX | ((uint64_t)EDX << 32); + break; + case 0x250: + msr.mtrr_fix64k_8000 = EAX | ((uint64_t)EDX << 32); + break; + case 0x258: + msr.mtrr_fix16k_8000 = EAX | ((uint64_t)EDX << 32); + break; + case 0x259: + msr.mtrr_fix16k_a000 = EAX | ((uint64_t)EDX << 32); + break; + case 0x268: case 0x269: case 0x26a: case 0x26b: + case 0x26c: case 0x26d: case 0x26e: case 0x26f: + msr.mtrr_fix4k[ECX - 0x268] = EAX | ((uint64_t)EDX << 32); + break; case 0x277: - pat_msr = EAX | ((uint64_t)EDX << 32); - break; - case 0x2FF: - mtrr_deftype_msr = EAX | ((uint64_t)EDX << 32); - break; + msr.pat = EAX | ((uint64_t)EDX << 32); + break; + case 0x2ff: + msr.mtrr_deftype = EAX | ((uint64_t)EDX << 32); + break; case 0x404: - ecx404_msr = EAX | ((uint64_t)EDX << 32); - break; + msr.ecx404 = EAX | ((uint64_t)EDX << 32); + break; case 0x408: - ecx408_msr = EAX | ((uint64_t)EDX << 32); - break; + msr.ecx408 = EAX | ((uint64_t)EDX << 32); + break; case 0x40c: - ecx40c_msr = EAX | ((uint64_t)EDX << 32); - break; + msr.ecx40c = EAX | ((uint64_t)EDX << 32); + break; case 0x410: - ecx410_msr = EAX | ((uint64_t)EDX << 32); - break; + msr.ecx410 = EAX | ((uint64_t)EDX << 32); + break; case 0x570: - ecx570_msr = EAX | ((uint64_t)EDX << 32); - break; + msr.ecx570 = EAX | ((uint64_t)EDX << 32); + break; case 0x1002ff: - ecx1002ff_msr = EAX | ((uint64_t)EDX << 32); - break; + msr.ecx1002ff = EAX | ((uint64_t)EDX << 32); + break; case 0xf0f00250: - ecxf0f00250_msr = EAX | ((uint64_t)EDX << 32); - break; + msr.ecxf0f00250 = EAX | ((uint64_t)EDX << 32); + break; case 0xf0f00258: - ecxf0f00258_msr = EAX | ((uint64_t)EDX << 32); - break; + msr.ecxf0f00258 = EAX | ((uint64_t)EDX << 32); + break; case 0xf0f00259: - ecxf0f00259_msr = EAX | ((uint64_t)EDX << 32); - break; + msr.ecxf0f00259 = EAX | ((uint64_t)EDX << 32); + break; default: i686_invalid_wrmsr: - cpu_log("WRMSR: Invalid MSR: %08X\n", ECX); - x86gpf(NULL, 0); - break; - } - break; - } + cpu_log("WRMSR: Invalid MSR: %08X\n", ECX); + x86gpf(NULL, 0); + break; + } + break; + } } -static void cpu_write(uint16_t addr, uint8_t val, void *priv) + +static void +cpu_write(uint16_t addr, uint8_t val, void *priv) { - if (addr == 0xf0) { - /* Writes to F0 clear FPU error and deassert the interrupt. */ - if (is286) - picintc(1 << 13); - else - nmi = 0; - return; - } else if (addr >= 0xf1) - return; /* FPU stuff */ + if (addr == 0xf0) { + /* Writes to F0 clear FPU error and deassert the interrupt. */ + if (is286) + picintc(1 << 13); + else + nmi = 0; + return; + } else if (addr >= 0xf1) + return; /* FPU stuff */ - if (!(addr & 1)) - cyrix_addr = val; - else switch (cyrix_addr) - { - case 0xc0: /*CCR0*/ - ccr0 = val; - break; - case 0xc1: /*CCR1*/ - if ((ccr3 & CCR3_SMI_LOCK) && !in_smm) - val = (val & ~(CCR1_USE_SMI | CCR1_SMAC | CCR1_SM3)) | (ccr1 & (CCR1_USE_SMI | CCR1_SMAC | CCR1_SM3)); - ccr1 = val; - break; - case 0xc2: /*CCR2*/ - ccr2 = val; - break; - case 0xc3: /*CCR3*/ - if ((ccr3 & CCR3_SMI_LOCK) && !in_smm) - val = (val & ~(CCR3_NMI_EN)) | (ccr3 & CCR3_NMI_EN) | CCR3_SMI_LOCK; - ccr3 = val; - break; - case 0xcd: - if (!(ccr3 & CCR3_SMI_LOCK) || in_smm) - { - cyrix.arr[3].base = (cyrix.arr[3].base & ~0xff000000) | (val << 24); - cyrix.smhr &= ~SMHR_VALID; - } - break; - case 0xce: - if (!(ccr3 & CCR3_SMI_LOCK) || in_smm) - { - cyrix.arr[3].base = (cyrix.arr[3].base & ~0x00ff0000) | (val << 16); - cyrix.smhr &= ~SMHR_VALID; - } - break; - case 0xcf: - if (!(ccr3 & CCR3_SMI_LOCK) || in_smm) - { - cyrix.arr[3].base = (cyrix.arr[3].base & ~0x0000f000) | ((val & 0xf0) << 8); - if ((val & 0xf) == 0xf) - cyrix.arr[3].size = 1ull << 32; /*4 GB*/ - else if (val & 0xf) - cyrix.arr[3].size = 2048 << (val & 0xf); - else - cyrix.arr[3].size = 0; /*Disabled*/ - cyrix.smhr &= ~SMHR_VALID; - } - break; + if (!(addr & 1)) + cyrix_addr = val; + else switch (cyrix_addr) { + case 0xc0: /* CCR0 */ + ccr0 = val; + break; + case 0xc1: /* CCR1 */ + if ((ccr3 & CCR3_SMI_LOCK) && !in_smm) + val = (val & ~(CCR1_USE_SMI | CCR1_SMAC | CCR1_SM3)) | (ccr1 & (CCR1_USE_SMI | CCR1_SMAC | CCR1_SM3)); + ccr1 = val; + break; + case 0xc2: /* CCR2 */ + ccr2 = val; + break; + case 0xc3: /* CCR3 */ + if ((ccr3 & CCR3_SMI_LOCK) && !in_smm) + val = (val & ~(CCR3_NMI_EN)) | (ccr3 & CCR3_NMI_EN) | CCR3_SMI_LOCK; + ccr3 = val; + break; + case 0xcd: + if (!(ccr3 & CCR3_SMI_LOCK) || in_smm) { + cyrix.arr[3].base = (cyrix.arr[3].base & ~0xff000000) | (val << 24); + cyrix.smhr &= ~SMHR_VALID; + } + break; + case 0xce: + if (!(ccr3 & CCR3_SMI_LOCK) || in_smm) { + cyrix.arr[3].base = (cyrix.arr[3].base & ~0x00ff0000) | (val << 16); + cyrix.smhr &= ~SMHR_VALID; + } + break; + case 0xcf: + if (!(ccr3 & CCR3_SMI_LOCK) || in_smm) { + cyrix.arr[3].base = (cyrix.arr[3].base & ~0x0000f000) | ((val & 0xf0) << 8); + if ((val & 0xf) == 0xf) + cyrix.arr[3].size = 1ull << 32; /* 4 GB */ + else if (val & 0xf) + cyrix.arr[3].size = 2048 << (val & 0xf); + else + cyrix.arr[3].size = 0; /* Disabled */ + cyrix.smhr &= ~SMHR_VALID; + } + break; - case 0xe8: /*CCR4*/ - if ((ccr3 & 0xf0) == 0x10) - { - ccr4 = val; + case 0xe8: /* CCR4 */ + if ((ccr3 & 0xf0) == 0x10) { + ccr4 = val; #if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) - if (cpu_s->cpu_type >= CPU_Cx6x86) - { - if (val & 0x80) - CPUID = cpu_s->cpuid_model; - else - CPUID = 0; - } + if (cpu_s->cpu_type >= CPU_Cx6x86) { + if (val & 0x80) + CPUID = cpu_s->cpuid_model; + else + CPUID = 0; + } #endif - } - break; - case 0xe9: /*CCR5*/ - if ((ccr3 & 0xf0) == 0x10) - ccr5 = val; - break; - case 0xea: /*CCR6*/ - if ((ccr3 & 0xf0) == 0x10) - ccr6 = val; - break; - } + } + break; + case 0xe9: /* CCR5 */ + if ((ccr3 & 0xf0) == 0x10) + ccr5 = val; + break; + case 0xea: /* CCR6 */ + if ((ccr3 & 0xf0) == 0x10) + ccr6 = val; + break; + } } -static uint8_t cpu_read(uint16_t addr, void *priv) + +static uint8_t +cpu_read(uint16_t addr, void *priv) { - if (addr == 0xf007) - return 0x7f; + if (addr == 0xf007) + return 0x7f; - if (addr >= 0xf0) - return 0xff; /* FPU stuff */ + if (addr >= 0xf0) + return 0xff; /* FPU stuff */ - if (addr & 1) - { - switch (cyrix_addr) - { - case 0xc0: return ccr0; - case 0xc1: return ccr1; - case 0xc2: return ccr2; - case 0xc3: return ccr3; - case 0xe8: return ((ccr3 & 0xf0) == 0x10) ? ccr4 : 0xff; - case 0xe9: return ((ccr3 & 0xf0) == 0x10) ? ccr5 : 0xff; - case 0xea: return ((ccr3 & 0xf0) == 0x10) ? ccr6 : 0xff; - case 0xfe: return cpu_s->cyrix_id & 0xff; - case 0xff: return cpu_s->cyrix_id >> 8; - } - if ((cyrix_addr & 0xf0) == 0xc0) return 0xff; - if (cyrix_addr == 0x20 && cpu_s->cpu_type == CPU_Cx5x86) return 0xff; - } - return 0xff; + if (addr & 1) { + switch (cyrix_addr) { + case 0xc0: + return ccr0; + case 0xc1: + return ccr1; + case 0xc2: + return ccr2; + case 0xc3: + return ccr3; + case 0xe8: + return ((ccr3 & 0xf0) == 0x10) ? ccr4 : 0xff; + case 0xe9: + return ((ccr3 & 0xf0) == 0x10) ? ccr5 : 0xff; + case 0xea: + return ((ccr3 & 0xf0) == 0x10) ? ccr6 : 0xff; + case 0xfe: + return cpu_s->cyrix_id & 0xff; + case 0xff: + return cpu_s->cyrix_id >> 8; + } + + if ((cyrix_addr & 0xf0) == 0xc0) + return 0xff; + + if (cyrix_addr == 0x20 && cpu_s->cpu_type == CPU_Cx5x86) + return 0xff; + } + + return 0xff; } @@ -3975,16 +3036,16 @@ void x86_setopcodes(const OpFn *opcodes, const OpFn *opcodes_0f, const OpFn *dynarec_opcodes, const OpFn *dynarec_opcodes_0f) { - x86_opcodes = opcodes; - x86_opcodes_0f = opcodes_0f; - x86_dynarec_opcodes = dynarec_opcodes; - x86_dynarec_opcodes_0f = dynarec_opcodes_0f; + x86_opcodes = opcodes; + x86_opcodes_0f = opcodes_0f; + x86_dynarec_opcodes = dynarec_opcodes; + x86_dynarec_opcodes_0f = dynarec_opcodes_0f; } #else x86_setopcodes(const OpFn *opcodes, const OpFn *opcodes_0f) { - x86_opcodes = opcodes; - x86_opcodes_0f = opcodes_0f; + x86_opcodes = opcodes; + x86_opcodes_0f = opcodes_0f; } #endif @@ -3992,48 +3053,44 @@ x86_setopcodes(const OpFn *opcodes, const OpFn *opcodes_0f) void cpu_update_waitstates(void) { - cpu_s = (CPU *) &cpu_f->cpus[cpu_effective]; + cpu_s = (CPU *) &cpu_f->cpus[cpu_effective]; - if (is486) - cpu_prefetch_width = 16; - else - cpu_prefetch_width = cpu_16bitbus ? 2 : 4; + if (is486) + cpu_prefetch_width = 16; + else + cpu_prefetch_width = cpu_16bitbus ? 2 : 4; - if (cpu_cache_int_enabled) - { - /* Disable prefetch emulation */ - cpu_prefetch_cycles = 0; - } - else if (cpu_waitstates && (cpu_s->cpu_type >= CPU_286 && cpu_s->cpu_type <= CPU_386DX)) - { - /* Waitstates override */ - cpu_prefetch_cycles = cpu_waitstates+1; - cpu_cycles_read = cpu_waitstates+1; - cpu_cycles_read_l = (cpu_16bitbus ? 2 : 1) * (cpu_waitstates+1); - cpu_cycles_write = cpu_waitstates+1; - cpu_cycles_write_l = (cpu_16bitbus ? 2 : 1) * (cpu_waitstates+1); - } - else if (cpu_cache_ext_enabled) - { - /* Use cache timings */ - cpu_prefetch_cycles = cpu_s->cache_read_cycles; - cpu_cycles_read = cpu_s->cache_read_cycles; - cpu_cycles_read_l = (cpu_16bitbus ? 2 : 1) * cpu_s->cache_read_cycles; - cpu_cycles_write = cpu_s->cache_write_cycles; - cpu_cycles_write_l = (cpu_16bitbus ? 2 : 1) * cpu_s->cache_write_cycles; - } - else - { - /* Use memory timings */ - cpu_prefetch_cycles = cpu_s->mem_read_cycles; - cpu_cycles_read = cpu_s->mem_read_cycles; - cpu_cycles_read_l = (cpu_16bitbus ? 2 : 1) * cpu_s->mem_read_cycles; - cpu_cycles_write = cpu_s->mem_write_cycles; - cpu_cycles_write_l = (cpu_16bitbus ? 2 : 1) * cpu_s->mem_write_cycles; - } - if (is486) - cpu_prefetch_cycles = (cpu_prefetch_cycles * 11) / 16; - cpu_mem_prefetch_cycles = cpu_prefetch_cycles; - if (cpu_s->rspeed <= 8000000) - cpu_rom_prefetch_cycles = cpu_mem_prefetch_cycles; + if (cpu_cache_int_enabled) { + /* Disable prefetch emulation */ + cpu_prefetch_cycles = 0; + } else if (cpu_waitstates && (cpu_s->cpu_type >= CPU_286 && cpu_s->cpu_type <= CPU_386DX)) { + /* Waitstates override */ + cpu_prefetch_cycles = cpu_waitstates+1; + cpu_cycles_read = cpu_waitstates+1; + cpu_cycles_read_l = (cpu_16bitbus ? 2 : 1) * (cpu_waitstates+1); + cpu_cycles_write = cpu_waitstates+1; + cpu_cycles_write_l = (cpu_16bitbus ? 2 : 1) * (cpu_waitstates+1); + } else if (cpu_cache_ext_enabled) { + /* Use cache timings */ + cpu_prefetch_cycles = cpu_s->cache_read_cycles; + cpu_cycles_read = cpu_s->cache_read_cycles; + cpu_cycles_read_l = (cpu_16bitbus ? 2 : 1) * cpu_s->cache_read_cycles; + cpu_cycles_write = cpu_s->cache_write_cycles; + cpu_cycles_write_l = (cpu_16bitbus ? 2 : 1) * cpu_s->cache_write_cycles; + } else { + /* Use memory timings */ + cpu_prefetch_cycles = cpu_s->mem_read_cycles; + cpu_cycles_read = cpu_s->mem_read_cycles; + cpu_cycles_read_l = (cpu_16bitbus ? 2 : 1) * cpu_s->mem_read_cycles; + cpu_cycles_write = cpu_s->mem_write_cycles; + cpu_cycles_write_l = (cpu_16bitbus ? 2 : 1) * cpu_s->mem_write_cycles; + } + + if (is486) + cpu_prefetch_cycles = (cpu_prefetch_cycles * 11) / 16; + + cpu_mem_prefetch_cycles = cpu_prefetch_cycles; + + if (cpu_s->rspeed <= 8000000) + cpu_rom_prefetch_cycles = cpu_mem_prefetch_cycles; } diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index e3e90a845..2ebd1362e 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -40,9 +40,9 @@ enum { #endif CPU_286, /* 286 class CPUs */ CPU_386SX, /* 386 class CPUs */ - CPU_386DX, CPU_IBM386SLC, CPU_IBM486SLC, + CPU_386DX, CPU_IBM486BL, CPU_RAPIDCAD, CPU_486SLC, @@ -53,10 +53,10 @@ enum { CPU_i486SX2, CPU_Am486SX2, CPU_i486DX, - CPU_i486DX2, CPU_Am486DX, - CPU_Am486DX2, CPU_Cx486DX, + CPU_i486DX2, + CPU_Am486DX2, CPU_Cx486DX2, CPU_iDX4, CPU_Am486DX4, @@ -236,10 +236,99 @@ typedef union { } MMX_REG; typedef struct { - uint32_t tr1, tr12; - uint32_t cesr; - uint32_t fcr; - uint64_t fcr2, fcr3; + /* IDT WinChip and WinChip 2 MSR's */ + uint32_t tr1, tr12; /* 0x00000002, 0x0000000e */ + uint32_t cesr; /* 0x00000011 */ + + /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ + uint64_t ecx17; /* 0x00000017 - Only on Pentium II Deschutes */ + uint64_t apic_base; /* 0x0000001b - Should the Pentium not also have this? */ + uint64_t ecx79; /* 0x00000079 */ + + /* AMD K5, 5k86, K6, K6-2, K6-2C, K6-3, K6-2P, and K6-3P MSR's */ + uint64_t ecx83; /* 0x00000083 - AMD K5 and K6 MSR's. */ + + /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ + uint64_t ecx8x[4]; /* 0x00000088 - 0x0000008b */ + uint64_t ia32_pmc[8]; /* 0x000000c1 - 0x000000c8 */ + uint64_t mtrr_cap; /* 0x000000fe */ + + /* IDT WinChip and WinChip 2 MSR's that are also on the VIA Cyrix III and Eden */ + uint32_t fcr; /* 0x00000107 (IDT), 0x00001107 (VIA) */ + uint64_t fcr2, fcr3; /* 0x00000108 (IDT), 0x00001108 (VIA) */ + + /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ + uint64_t ecx116; /* 0x00000116 */ + uint64_t ecx11x[4]; /* 0x00000118 - 0x0000011b */ + uint64_t ecx11e; /* 0x0000011e */ + + /* Pentium II Klamath and Pentium II Deschutes MSR's */ + uint16_t sysenter_cs; /* 0x00000174 - SYSENTER/SYSEXIT MSR's */ + uint32_t sysenter_esp; /* 0x00000175 - SYSENTER/SYSEXIT MSR's */ + uint32_t sysenter_eip; /* 0x00000176 - SYSENTER/SYSEXIT MSR's */ + + /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ + uint64_t ecx186, ecx187; /* 0x00000186, 0x00000187 */ + uint64_t ecx1e0; /* 0x000001e0 */ + + /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's that are also + on the VIA Cyrix III and Eden */ + uint64_t mtrr_physbase[8]; /* 0x00000200 - 0x0000020f */ + uint64_t mtrr_physmask[8]; /* 0x00000200 - 0x0000020f (ECX & 1) */ + uint64_t mtrr_fix64k_8000; /* 0x00000250 */ + uint64_t mtrr_fix16k_8000; /* 0x00000258 */ + uint64_t mtrr_fix16k_a000; /* 0x00000259 */ + uint64_t mtrr_fix4k[8]; /* 0x00000268 - 0x0000026f */ + + /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ + uint64_t pat; /* 0x00000277 */ + + /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's that are also + on the VIA Cyrix III and Eden */ + uint64_t mtrr_deftype; /* 0x000002ff */ + + /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ + uint64_t ecx404; /* 0x00000404 - Model Identification MSR's used by some Acer BIOSes */ + uint64_t ecx408; /* 0x00000408 */ + uint64_t ecx40c; /* 0x0000040c */ + uint64_t ecx410; /* 0x00000410 */ + uint64_t ecx570; /* 0x00000570 */ + + /* IBM 386SLC, 486SLC, and 486BL MSR's */ + uint64_t ibm_por; /* 0x00001000 - Processor Operation Register */ + uint64_t ibm_crcr; /* 0x00001001 - Cache Region Control Register */ + + /* IBM 486SLC and 486BL MSR's */ + uint64_t ibm_por2; /* 0x00001002 - Processor Operation Register */ + + /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ + uint64_t ecx1002ff; /* 0x001002ff - MSR used by some Intel AMI boards */ + + /* AMD K5, 5k86, K6, K6-2, K6-2C, K6-3, K6-2P, and K6-3P MSR's */ + uint64_t amd_efer; /* 0xc0000080 */ + + /* AMD K6-2, K6-2C, K6-3, K6-2P, and K6-3P MSR's */ + uint64_t star; /* 0xc0000081 */ + + /* AMD K5, 5k86, K6, K6-2, K6-2C, K6-3, K6-2P, and K6-3P MSR's */ + uint64_t amd_whcr; /* 0xc0000082 */ + + /* AMD K6-2C, K6-3, K6-2P, and K6-3P MSR's */ + uint64_t amd_uwccr; /* 0xc0000085 */ + + /* AMD K6-2P and K6-3P MSR's */ + uint64_t amd_epmr; /* 0xc0000086 */ + + /* AMD K6-2C, K6-3, K6-2P, and K6-3P MSR's */ + uint64_t amd_psor, amd_pfir; /* 0xc0000087, 0xc0000088 */ + + /* K6-3, K6-2P, and K6-3P MSR's */ + uint64_t amd_l2aar; /* 0xc0000089 */ + + /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ + uint64_t ecxf0f00250; /* 0xf0f00250 - Some weird long MSR's used by i686 AMI & some Phoenix BIOSes */ + uint64_t ecxf0f00258; /* 0xf0f00258 */ + uint64_t ecxf0f00259; /* 0xf0f00259 */ } msr_t; typedef struct { @@ -532,7 +621,7 @@ extern void cpu_CPUID(void); extern void cpu_RDMSR(void); extern void cpu_WRMSR(void); -extern int checkio(int port); +extern int checkio(uint32_t port); extern void codegen_block_end(void); extern void codegen_reset(void); extern void cpu_set_edx(void); @@ -612,9 +701,14 @@ typedef struct } cyrix_t; +extern uint32_t addr64, addr64_2; +extern uint32_t addr64a[8], addr64a_2[8]; + extern cyrix_t cyrix; extern void (*cpu_exec)(int cycs); extern uint8_t do_translate, do_translate2; +extern void reset_808x(int hard); + #endif /*EMU_CPU_H*/ diff --git a/src/cpu/x86_ops_amd.h b/src/cpu/x86_ops_amd.h index 0674c8187..a378b9fe9 100644 --- a/src/cpu/x86_ops_amd.h +++ b/src/cpu/x86_ops_amd.h @@ -18,7 +18,7 @@ opSYSCALL(uint32_t fetchdat) { int ret; - ILLEGAL_ON(!(amd_efer & 0x0000000000000001)); + ILLEGAL_ON(!(msr.amd_efer & 0x0000000000000001)); ret = syscall_op(fetchdat); @@ -38,7 +38,7 @@ opSYSRET(uint32_t fetchdat) { int ret; - ILLEGAL_ON(!(amd_efer & 0x0000000000000001)); + ILLEGAL_ON(!(msr.amd_efer & 0x0000000000000001)); ret = sysret(fetchdat); diff --git a/src/cpu/x86_ops_arith.h b/src/cpu/x86_ops_arith.h index 489fd5e57..d837d3a64 100644 --- a/src/cpu/x86_ops_arith.h +++ b/src/cpu/x86_ops_arith.h @@ -309,8 +309,8 @@ static int opCMP_b_rmw_a16(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); dst = geteab(); if (cpu_state.abrt) return 1; setsub8(dst, getr8(cpu_reg)); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } + else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0); return 0; } @@ -322,8 +322,8 @@ static int opCMP_b_rmw_a32(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); dst = geteab(); if (cpu_state.abrt) return 1; setsub8(dst, getr8(cpu_reg)); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } + else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1); return 0; } @@ -336,8 +336,8 @@ static int opCMP_w_rmw_a16(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); dst = geteaw(); if (cpu_state.abrt) return 1; setsub16(dst, cpu_state.regs[cpu_reg].w); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } + else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0); return 0; } @@ -349,8 +349,8 @@ static int opCMP_w_rmw_a32(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); dst = geteaw(); if (cpu_state.abrt) return 1; setsub16(dst, cpu_state.regs[cpu_reg].w); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } + else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1); return 0; } @@ -363,8 +363,8 @@ static int opCMP_l_rmw_a16(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); dst = geteal(); if (cpu_state.abrt) return 1; setsub32(dst, cpu_state.regs[cpu_reg].l); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } + else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1,0,0, 0); return 0; } @@ -376,8 +376,8 @@ static int opCMP_l_rmw_a32(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); dst = geteal(); if (cpu_state.abrt) return 1; setsub32(dst, cpu_state.regs[cpu_reg].l); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } + else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1,0,0, 1); return 0; } @@ -493,8 +493,8 @@ static int opTEST_b_a16(uint32_t fetchdat) temp = geteab(); if (cpu_state.abrt) return 1; temp2 = getr8(cpu_reg); setznp8(temp & temp2); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } + else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0); return 0; } @@ -507,8 +507,8 @@ static int opTEST_b_a32(uint32_t fetchdat) temp = geteab(); if (cpu_state.abrt) return 1; temp2 = getr8(cpu_reg); setznp8(temp & temp2); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } + else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1); return 0; } @@ -522,8 +522,8 @@ static int opTEST_w_a16(uint32_t fetchdat) temp = geteaw(); if (cpu_state.abrt) return 1; temp2 = cpu_state.regs[cpu_reg].w; setznp16(temp & temp2); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } + else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0); return 0; } @@ -536,8 +536,8 @@ static int opTEST_w_a32(uint32_t fetchdat) temp = geteaw(); if (cpu_state.abrt) return 1; temp2 = cpu_state.regs[cpu_reg].w; setznp16(temp & temp2); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } + else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1); return 0; } @@ -551,8 +551,8 @@ static int opTEST_l_a16(uint32_t fetchdat) temp = geteal(); if (cpu_state.abrt) return 1; temp2 = cpu_state.regs[cpu_reg].l; setznp32(temp & temp2); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } + else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0,(cpu_mod == 3) ? 0 : 1,0,0, 0); return 0; } @@ -565,8 +565,8 @@ static int opTEST_l_a32(uint32_t fetchdat) temp = geteal(); if (cpu_state.abrt) return 1; temp2 = cpu_state.regs[cpu_reg].l; setznp32(temp & temp2); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } + else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0,(cpu_mod == 3) ? 0 : 1,0,0, 1); return 0; } @@ -643,8 +643,8 @@ static int opTEST_EAX(uint32_t fetchdat) break; \ case 0x38: /*CMP ea, #*/ \ setsub ## flag_width(dst, src); \ - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); \ - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 7); \ + if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } \ + else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 7); } \ break; \ } @@ -658,10 +658,11 @@ static int op80_a16(uint32_t fetchdat) SEG_CHECK_WRITE(cpu_state.ea_seg); src = getbyte(); if (cpu_state.abrt) return 1; ARITH_MULTI(b, 8); - if ((rmdat & 0x38) == 0x38) + if ((rmdat & 0x38) == 0x38) { PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - else + } else { PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); + } return 0; } @@ -674,10 +675,11 @@ static int op80_a32(uint32_t fetchdat) SEG_CHECK_WRITE(cpu_state.ea_seg); src = getbyte(); if (cpu_state.abrt) return 1; ARITH_MULTI(b, 8); - if ((rmdat & 0x38) == 0x38) + if ((rmdat & 0x38) == 0x38) { PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - else + } else { PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1); + } return 0; } @@ -690,10 +692,11 @@ static int op81_w_a16(uint32_t fetchdat) SEG_CHECK_WRITE(cpu_state.ea_seg); src = getword(); if (cpu_state.abrt) return 1; ARITH_MULTI(w, 16); - if ((rmdat & 0x38) == 0x38) + if ((rmdat & 0x38) == 0x38) { PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 4, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - else + } else { PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 4, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); + } return 0; } @@ -706,10 +709,11 @@ static int op81_w_a32(uint32_t fetchdat) SEG_CHECK_WRITE(cpu_state.ea_seg); src = getword(); if (cpu_state.abrt) return 1; ARITH_MULTI(w, 16); - if ((rmdat & 0x38) == 0x38) + if ((rmdat & 0x38) == 0x38) { PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 4, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - else + } else { PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 4, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1); + } return 0; } @@ -722,10 +726,11 @@ static int op81_l_a16(uint32_t fetchdat) SEG_CHECK_WRITE(cpu_state.ea_seg); src = getlong(); if (cpu_state.abrt) return 1; ARITH_MULTI(l, 32); - if ((rmdat & 0x38) == 0x38) + if ((rmdat & 0x38) == 0x38) { PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 6, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0); - else + } else { PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 6, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0); + } return 0; } @@ -738,10 +743,11 @@ static int op81_l_a32(uint32_t fetchdat) SEG_CHECK_WRITE(cpu_state.ea_seg); src = getlong(); if (cpu_state.abrt) return 1; ARITH_MULTI(l, 32); - if ((rmdat & 0x38) == 0x38) + if ((rmdat & 0x38) == 0x38) { PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 6, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1); - else + } else { PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 6, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1); + } return 0; } @@ -756,10 +762,11 @@ static int op83_w_a16(uint32_t fetchdat) src = getbyte(); if (cpu_state.abrt) return 1; if (src & 0x80) src |= 0xff00; ARITH_MULTI(w, 16); - if ((rmdat & 0x38) == 0x38) + if ((rmdat & 0x38) == 0x38) { PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - else + } else { PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); + } return 0; } @@ -773,10 +780,11 @@ static int op83_w_a32(uint32_t fetchdat) src = getbyte(); if (cpu_state.abrt) return 1; if (src & 0x80) src |= 0xff00; ARITH_MULTI(w, 16); - if ((rmdat & 0x38) == 0x38) + if ((rmdat & 0x38) == 0x38) { PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - else + } else { PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1); + } return 0; } @@ -791,10 +799,11 @@ static int op83_l_a16(uint32_t fetchdat) src = getbyte(); if (cpu_state.abrt) return 1; if (src & 0x80) src |= 0xffffff00; ARITH_MULTI(l, 32); - if ((rmdat & 0x38) == 0x38) + if ((rmdat & 0x38) == 0x38) { PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0); - else + } else { PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0); + } return 0; } @@ -808,10 +817,11 @@ static int op83_l_a32(uint32_t fetchdat) src = getbyte(); if (cpu_state.abrt) return 1; if (src & 0x80) src |= 0xffffff00; ARITH_MULTI(l, 32); - if ((rmdat & 0x38) == 0x38) + if ((rmdat & 0x38) == 0x38) { PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1); - else + } else { PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1); + } return 0; } diff --git a/src/cpu/x86_ops_call.h b/src/cpu/x86_ops_call.h index 57a5995b0..427d504fc 100644 --- a/src/cpu/x86_ops_call.h +++ b/src/cpu/x86_ops_call.h @@ -186,8 +186,8 @@ static int opFF_w_a16(uint32_t fetchdat) PUSH_W(cpu_state.pc); cpu_state.pc = new_pc; CPU_BLOCK_END(); - if (is486) CLOCK_CYCLES(5); - else CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); + if (is486) { CLOCK_CYCLES(5); } + else { CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); } PREFETCH_RUN((cpu_mod == 3) ? 7 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,1,0, 0); PREFETCH_FLUSH(); break; @@ -208,8 +208,8 @@ static int opFF_w_a16(uint32_t fetchdat) new_pc = geteaw(); if (cpu_state.abrt) return 1; cpu_state.pc = new_pc; CPU_BLOCK_END(); - if (is486) CLOCK_CYCLES(5); - else CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); + if (is486) { CLOCK_CYCLES(5); } + else { CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); } PREFETCH_RUN((cpu_mod == 3) ? 7 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); PREFETCH_FLUSH(); break; @@ -285,8 +285,8 @@ static int opFF_w_a32(uint32_t fetchdat) PUSH_W(cpu_state.pc); cpu_state.pc = new_pc; CPU_BLOCK_END(); - if (is486) CLOCK_CYCLES(5); - else CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); + if (is486) { CLOCK_CYCLES(5); } + else { CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); } PREFETCH_RUN((cpu_mod == 3) ? 7 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,1,0, 1); PREFETCH_FLUSH(); break; @@ -307,8 +307,8 @@ static int opFF_w_a32(uint32_t fetchdat) new_pc = geteaw(); if (cpu_state.abrt) return 1; cpu_state.pc = new_pc; CPU_BLOCK_END(); - if (is486) CLOCK_CYCLES(5); - else CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); + if (is486) { CLOCK_CYCLES(5); } + else { CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); } PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 1,0,0,0, 1); PREFETCH_FLUSH(); break; @@ -385,8 +385,8 @@ static int opFF_l_a16(uint32_t fetchdat) PUSH_L(cpu_state.pc); cpu_state.pc = new_pc; CPU_BLOCK_END(); - if (is486) CLOCK_CYCLES(5); - else CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); + if (is486) { CLOCK_CYCLES(5); } + else { CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); } PREFETCH_RUN((cpu_mod == 3) ? 7 : 10, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,1, 0); PREFETCH_FLUSH(); break; @@ -407,8 +407,8 @@ static int opFF_l_a16(uint32_t fetchdat) new_pc = geteal(); if (cpu_state.abrt) return 1; cpu_state.pc = new_pc; CPU_BLOCK_END(); - if (is486) CLOCK_CYCLES(5); - else CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); + if (is486) { CLOCK_CYCLES(5); } + else { CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); } PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 0,1,0,0, 0); PREFETCH_FLUSH(); break; @@ -484,8 +484,8 @@ static int opFF_l_a32(uint32_t fetchdat) PUSH_L(cpu_state.pc); if (cpu_state.abrt) return 1; cpu_state.pc = new_pc; CPU_BLOCK_END(); - if (is486) CLOCK_CYCLES(5); - else CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); + if (is486) { CLOCK_CYCLES(5); } + else { CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); } PREFETCH_RUN((cpu_mod == 3) ? 7 : 10, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,1, 1); PREFETCH_FLUSH(); break; @@ -506,8 +506,8 @@ static int opFF_l_a32(uint32_t fetchdat) new_pc = geteal(); if (cpu_state.abrt) return 1; cpu_state.pc = new_pc; CPU_BLOCK_END(); - if (is486) CLOCK_CYCLES(5); - else CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); + if (is486) { CLOCK_CYCLES(5); } + else { CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); } PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 1,1,0,0, 1); PREFETCH_FLUSH(); break; diff --git a/src/cpu/x86_ops_i686.h b/src/cpu/x86_ops_i686.h index dad86b410..3f2d85766 100644 --- a/src/cpu/x86_ops_i686.h +++ b/src/cpu/x86_ops_i686.h @@ -153,9 +153,6 @@ fx_save_stor_common(uint32_t fetchdat, int bits) x87_settag(rec_ftw); CLOCK_CYCLES((cr0 & 1) ? 34 : 44); - - if (cpu_state.abrt) - x386_dynarec_log("FXRSTOR: abrt != 0\n"); } else { /* FXSAVE */ if ((twd & 0x0003) == 0x0003) ftwb |= 0x01; @@ -217,9 +214,6 @@ fx_save_stor_common(uint32_t fetchdat, int bits) cpu_state.ismmx = 0; CLOCK_CYCLES((cr0 & 1) ? 56 : 67); - - if (cpu_state.abrt) - x386_dynarec_log("FXSAVE: abrt != 0\n"); } return cpu_state.abrt; diff --git a/src/cpu/x86_ops_misc.h b/src/cpu/x86_ops_misc.h index e326543a2..a64a3edbb 100644 --- a/src/cpu/x86_ops_misc.h +++ b/src/cpu/x86_ops_misc.h @@ -63,8 +63,8 @@ static int opF6_a16(uint32_t fetchdat) case 0x08: src = readmemb(cs, cpu_state.pc); cpu_state.pc++; if (cpu_state.abrt) return 1; setznp8(src & dst); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } + else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); break; case 0x10: /*NOT b*/ @@ -167,8 +167,8 @@ static int opF6_a32(uint32_t fetchdat) case 0x08: src = readmemb(cs, cpu_state.pc); cpu_state.pc++; if (cpu_state.abrt) return 1; setznp8(src & dst); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } + else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); break; case 0x10: /*NOT b*/ @@ -274,8 +274,8 @@ static int opF7_w_a16(uint32_t fetchdat) case 0x08: src = getword(); if (cpu_state.abrt) return 1; setznp16(src & dst); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } + else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 4, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); break; case 0x10: /*NOT w*/ @@ -371,8 +371,8 @@ static int opF7_w_a32(uint32_t fetchdat) case 0x08: src = getword(); if (cpu_state.abrt) return 1; setznp16(src & dst); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } + else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 4, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); break; case 0x10: /*NOT w*/ @@ -469,8 +469,8 @@ static int opF7_l_a16(uint32_t fetchdat) case 0x08: src = getlong(); if (cpu_state.abrt) return 1; setznp32(src & dst); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } + else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 5, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0); break; case 0x10: /*NOT l*/ @@ -544,8 +544,8 @@ static int opF7_l_a32(uint32_t fetchdat) case 0x08: src = getlong(); if (cpu_state.abrt) return 1; setznp32(src & dst); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } + else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 5, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1); break; case 0x10: /*NOT l*/ @@ -620,8 +620,9 @@ static int opHLT(uint32_t fetchdat) if (!((cpu_state.flags & I_FLAG) && pic.int_pending)) cpu_state.pc--; } - else + else { CLOCK_CYCLES(5); + } CPU_BLOCK_END(); PREFETCH_RUN(100, 1, -1, 0,0,0,0, 0); diff --git a/src/cpu/x86_ops_mov.h b/src/cpu/x86_ops_mov.h index 2c96317b7..8702578b1 100644 --- a/src/cpu/x86_ops_mov.h +++ b/src/cpu/x86_ops_mov.h @@ -281,7 +281,7 @@ static int opMOV_AX_a16(uint32_t fetchdat) uint16_t temp; uint16_t addr = getwordf(); SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, addr, addr+1); + CHECK_READ(cpu_state.ea_seg, addr, addr + 1UL); temp = readmemw(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1; AX = temp; CLOCK_CYCLES((is486) ? 1 : 4); @@ -305,7 +305,7 @@ static int opMOV_EAX_a16(uint32_t fetchdat) uint32_t temp; uint16_t addr = getwordf(); SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, addr, addr+3); + CHECK_READ(cpu_state.ea_seg, addr, addr + 3UL); temp = readmeml(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1; EAX = temp; CLOCK_CYCLES((is486) ? 1 : 4); @@ -349,7 +349,7 @@ static int opMOV_a16_AX(uint32_t fetchdat) { uint16_t addr = getwordf(); SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE_COMMON(cpu_state.ea_seg, addr, addr + 1); + CHECK_WRITE_COMMON(cpu_state.ea_seg, addr, addr + 1UL); writememw(cpu_state.ea_seg->base, addr, AX); CLOCK_CYCLES((is486) ? 1 : 2); PREFETCH_RUN(2, 3, -1, 0,0,1,0, 0); @@ -369,7 +369,7 @@ static int opMOV_a16_EAX(uint32_t fetchdat) { uint16_t addr = getwordf(); SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE_COMMON(cpu_state.ea_seg, addr, addr + 3); + CHECK_WRITE_COMMON(cpu_state.ea_seg, addr, addr + 3UL); writememl(cpu_state.ea_seg->base, addr, EAX); CLOCK_CYCLES((is486) ? 1 : 2); PREFETCH_RUN(2, 3, -1, 0,0,0,1, 0); diff --git a/src/cpu/x86_ops_rep.h b/src/cpu/x86_ops_rep.h index e276fe90e..4d1f0ea61 100644 --- a/src/cpu/x86_ops_rep.h +++ b/src/cpu/x86_ops_rep.h @@ -2,7 +2,8 @@ static int opREP_INSB_ ## size(uint32_t fetchdat) \ { \ int reads = 0, writes = 0, total_cycles = 0; \ - uint64_t addr64 = 0x0000000000000000ULL; \ + \ + addr64 = 0x00000000; \ \ if (CNT_REG > 0) \ { \ @@ -11,6 +12,7 @@ static int opREP_INSB_ ## size(uint32_t fetchdat) SEG_CHECK_WRITE(&cpu_state.seg_es); \ check_io_perm(DX); \ CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG); \ + high_page = 0; \ do_mmut_wb(es, DEST_REG, &addr64); \ if (cpu_state.abrt) return 1; \ temp = inb(DX); \ @@ -34,7 +36,8 @@ static int opREP_INSB_ ## size(uint32_t fetchdat) static int opREP_INSW_ ## size(uint32_t fetchdat) \ { \ int reads = 0, writes = 0, total_cycles = 0; \ - uint64_t addr64[2]; \ + \ + addr64a[0] = addr64a[1] = 0x00000000; \ \ if (CNT_REG > 0) \ { \ @@ -43,11 +46,12 @@ static int opREP_INSW_ ## size(uint32_t fetchdat) SEG_CHECK_WRITE(&cpu_state.seg_es); \ check_io_perm(DX); \ check_io_perm(DX+1); \ - CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG + 1); \ - do_mmut_ww(es, DEST_REG, addr64); \ + CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ + high_page = 0; \ + do_mmut_ww(es, DEST_REG, addr64a); \ if (cpu_state.abrt) return 1; \ temp = inw(DX); \ - writememw_n(es, DEST_REG, addr64, temp); if (cpu_state.abrt) return 1; \ + writememw_n(es, DEST_REG, addr64a, temp); if (cpu_state.abrt) return 1; \ \ if (cpu_state.flags & D_FLAG) DEST_REG -= 2; \ else DEST_REG += 2; \ @@ -67,7 +71,8 @@ static int opREP_INSW_ ## size(uint32_t fetchdat) static int opREP_INSL_ ## size(uint32_t fetchdat) \ { \ int reads = 0, writes = 0, total_cycles = 0; \ - uint64_t addr64[4]; \ + \ + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; \ \ if (CNT_REG > 0) \ { \ @@ -78,11 +83,12 @@ static int opREP_INSL_ ## size(uint32_t fetchdat) check_io_perm(DX+1); \ check_io_perm(DX+2); \ check_io_perm(DX+3); \ - CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG + 3); \ - do_mmut_wl(es, DEST_REG, addr64); \ + CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ + high_page = 0; \ + do_mmut_wl(es, DEST_REG, addr64a); \ if (cpu_state.abrt) return 1; \ temp = inl(DX); \ - writememl_n(es, DEST_REG, addr64, temp); if (cpu_state.abrt) return 1; \ + writememl_n(es, DEST_REG, addr64a, temp); if (cpu_state.abrt) return 1; \ \ if (cpu_state.flags & D_FLAG) DEST_REG -= 4; \ else DEST_REG += 4; \ @@ -135,7 +141,7 @@ static int opREP_OUTSW_ ## size(uint32_t fetchdat) { \ uint16_t temp; \ SEG_CHECK_READ(cpu_state.ea_seg); \ - CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 1); \ + CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \ temp = readmemw(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ check_io_perm(DX); \ check_io_perm(DX+1); \ @@ -163,7 +169,7 @@ static int opREP_OUTSL_ ## size(uint32_t fetchdat) { \ uint32_t temp; \ SEG_CHECK_READ(cpu_state.ea_seg); \ - CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 3); \ + CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \ temp = readmeml(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ check_io_perm(DX); \ check_io_perm(DX+1); \ @@ -190,27 +196,27 @@ static int opREP_MOVSB_ ## size(uint32_t fetchdat) { \ int reads = 0, writes = 0, total_cycles = 0; \ int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - uint64_t addr64r = 0x0000000000000000ULL; \ - uint64_t addr64w = 0x0000000000000000ULL; \ + addr64 = addr64_2 = 0x00000000; \ if (trap) \ cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ if (CNT_REG > 0) \ { \ SEG_CHECK_READ(cpu_state.ea_seg); \ SEG_CHECK_WRITE(&cpu_state.seg_es); \ - } \ + } \ while (CNT_REG > 0) \ { \ uint8_t temp; \ \ CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG); \ - do_mmut_rb(cpu_state.ea_seg->base, SRC_REG, &addr64r); \ + high_page = 0; \ + do_mmut_rb(cpu_state.ea_seg->base, SRC_REG, &addr64) ; \ if (cpu_state.abrt) break; \ CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG); \ - do_mmut_wb(es, DEST_REG, &addr64w); \ + do_mmut_wb(es, DEST_REG, &addr64_2); \ if (cpu_state.abrt) break; \ - temp = readmemb_n(cpu_state.ea_seg->base, SRC_REG, addr64r); if (cpu_state.abrt) return 1; \ - writememb_n(es, DEST_REG, addr64w, temp); if (cpu_state.abrt) return 1; \ + temp = readmemb_n(cpu_state.ea_seg->base, SRC_REG, addr64); if (cpu_state.abrt) return 1; \ + writememb_n(es, DEST_REG, addr64_2, temp); if (cpu_state.abrt) return 1; \ \ if (cpu_state.flags & D_FLAG) { DEST_REG--; SRC_REG--; } \ else { DEST_REG++; SRC_REG++; } \ @@ -233,27 +239,28 @@ static int opREP_MOVSW_ ## size(uint32_t fetchdat) { \ int reads = 0, writes = 0, total_cycles = 0; \ int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - uint64_t addr64r[2]; \ - uint64_t addr64w[2]; \ + addr64a[0] = addr64a[1] = 0x00000000; \ + addr64a_2[0] = addr64a_2[1] = 0x00000000; \ if (trap) \ cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ if (CNT_REG > 0) \ { \ SEG_CHECK_READ(cpu_state.ea_seg); \ SEG_CHECK_WRITE(&cpu_state.seg_es); \ - } \ + } \ while (CNT_REG > 0) \ { \ uint16_t temp; \ \ - CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 1); \ - do_mmut_rw(cpu_state.ea_seg->base, SRC_REG, addr64r); \ + CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \ + high_page = 0; \ + do_mmut_rw(cpu_state.ea_seg->base, SRC_REG, addr64a); \ if (cpu_state.abrt) break; \ - CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1); \ - do_mmut_ww(es, DEST_REG, addr64w); \ + CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ + do_mmut_ww(es, DEST_REG, addr64a_2); \ if (cpu_state.abrt) break; \ - temp = readmemw_n(cpu_state.ea_seg->base, SRC_REG, addr64r); if (cpu_state.abrt) return 1; \ - writememw_n(es, DEST_REG, addr64w, temp); if (cpu_state.abrt) return 1; \ + temp = readmemw_n(cpu_state.ea_seg->base, SRC_REG, addr64a); if (cpu_state.abrt) return 1; \ + writememw_n(es, DEST_REG, addr64a_2, temp); if (cpu_state.abrt) return 1; \ \ if (cpu_state.flags & D_FLAG) { DEST_REG -= 2; SRC_REG -= 2; } \ else { DEST_REG += 2; SRC_REG += 2; } \ @@ -276,27 +283,28 @@ static int opREP_MOVSL_ ## size(uint32_t fetchdat) { \ int reads = 0, writes = 0, total_cycles = 0; \ int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - uint64_t addr64r[4]; \ - uint64_t addr64w[4]; \ + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; \ + addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; \ if (trap) \ cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ if (CNT_REG > 0) \ { \ SEG_CHECK_READ(cpu_state.ea_seg); \ SEG_CHECK_WRITE(&cpu_state.seg_es); \ - } \ + } \ while (CNT_REG > 0) \ { \ uint32_t temp; \ \ - CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 3); \ - do_mmut_rl(cpu_state.ea_seg->base, SRC_REG, addr64r); \ + CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \ + high_page = 0; \ + do_mmut_rl(cpu_state.ea_seg->base, SRC_REG, addr64a); \ if (cpu_state.abrt) break; \ - CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3); \ - do_mmut_wl(es, DEST_REG, addr64w); \ + CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ + do_mmut_wl(es, DEST_REG, addr64a_2); \ if (cpu_state.abrt) break; \ - temp = readmeml_n(cpu_state.ea_seg->base, SRC_REG, addr64r); if (cpu_state.abrt) return 1; \ - writememl_n(es, DEST_REG, addr64w, temp); if (cpu_state.abrt) return 1; \ + temp = readmeml_n(cpu_state.ea_seg->base, SRC_REG, addr64a); if (cpu_state.abrt) return 1; \ + writememl_n(es, DEST_REG, addr64a_2, temp); if (cpu_state.abrt) return 1; \ \ if (cpu_state.flags & D_FLAG) { DEST_REG -= 4; SRC_REG -= 4; } \ else { DEST_REG += 4; SRC_REG += 4; } \ @@ -356,7 +364,7 @@ static int opREP_STOSW_ ## size(uint32_t fetchdat) SEG_CHECK_WRITE(&cpu_state.seg_es); \ while (CNT_REG > 0) \ { \ - CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1); \ + CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ writememw(es, DEST_REG, AX); if (cpu_state.abrt) return 1; \ if (cpu_state.flags & D_FLAG) DEST_REG -= 2; \ else DEST_REG += 2; \ @@ -385,7 +393,7 @@ static int opREP_STOSL_ ## size(uint32_t fetchdat) SEG_CHECK_WRITE(&cpu_state.seg_es); \ while (CNT_REG > 0) \ { \ - CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3); \ + CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ writememl(es, DEST_REG, EAX); if (cpu_state.abrt) return 1; \ if (cpu_state.flags & D_FLAG) DEST_REG -= 4; \ else DEST_REG += 4; \ @@ -444,7 +452,7 @@ static int opREP_LODSW_ ## size(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); \ while (CNT_REG > 0) \ { \ - CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 1); \ + CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \ AX = readmemw(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ if (cpu_state.flags & D_FLAG) SRC_REG -= 2; \ else SRC_REG += 2; \ @@ -473,7 +481,7 @@ static int opREP_LODSL_ ## size(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); \ while (CNT_REG > 0) \ { \ - CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 3); \ + CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \ EAX = readmeml(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ if (cpu_state.flags & D_FLAG) SRC_REG -= 4; \ else SRC_REG += 4; \ @@ -501,8 +509,8 @@ static int opREP_LODSL_ ## size(uint32_t fetchdat) static int opREP_CMPSB_ ## size(uint32_t fetchdat) \ { \ int reads = 0, total_cycles = 0, tempz; \ - uint64_t addr64 = 0x0000000000000000ULL; \ - uint64_t addr642 = 0x0000000000000000ULL; \ + \ + addr64 = addr64_2 = 0x00000000; \ \ tempz = FV; \ if ((CNT_REG > 0) && (FV == tempz)) \ @@ -511,12 +519,14 @@ static int opREP_CMPSB_ ## size(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); \ SEG_CHECK_READ(&cpu_state.seg_es); \ CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG); \ + high_page = 0; \ do_mmut_rb(cpu_state.ea_seg->base, SRC_REG, &addr64); \ - CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG); \ - do_mmut_rb(es, DEST_REG, &addr642); \ if (cpu_state.abrt) return 1; \ - temp = readmemb_n(cpu_state.ea_seg->base, SRC_REG, addr64); \ - temp2 = readmemb_n(es, DEST_REG, addr642); if (cpu_state.abrt) return 1; \ + CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG); \ + do_mmut_rb(es, DEST_REG, &addr64_2); \ + if (cpu_state.abrt) return 1; \ + temp = readmemb_n(cpu_state.ea_seg->base, SRC_REG, addr64); if (cpu_state.abrt) return 1; \ + temp2 = readmemb_n(es, DEST_REG, addr64_2); if (cpu_state.abrt) return 1; \ \ if (cpu_state.flags & D_FLAG) { DEST_REG--; SRC_REG--; } \ else { DEST_REG++; SRC_REG++; } \ @@ -538,8 +548,9 @@ static int opREP_CMPSB_ ## size(uint32_t fetchdat) static int opREP_CMPSW_ ## size(uint32_t fetchdat) \ { \ int reads = 0, total_cycles = 0, tempz; \ - uint64_t addr64[2]; \ - uint64_t addr642[2]; \ + \ + addr64a[0] = addr64a[1] = 0x00000000; \ + addr64a_2[0] = addr64a_2[1] = 0x00000000; \ \ tempz = FV; \ if ((CNT_REG > 0) && (FV == tempz)) \ @@ -547,13 +558,15 @@ static int opREP_CMPSW_ ## size(uint32_t fetchdat) uint16_t temp, temp2; \ SEG_CHECK_READ(cpu_state.ea_seg); \ SEG_CHECK_READ(&cpu_state.seg_es); \ - CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 1); \ - do_mmut_rw(cpu_state.ea_seg->base, SRC_REG, addr64); \ - CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG + 1); \ - do_mmut_rw(es, DEST_REG, addr642); \ + CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \ + high_page = 0; \ + do_mmut_rw(cpu_state.ea_seg->base, SRC_REG, addr64a); \ if (cpu_state.abrt) return 1; \ - temp = readmemw_n(cpu_state.ea_seg->base, SRC_REG, addr64); \ - temp2 = readmemw_n(es, DEST_REG, addr642); if (cpu_state.abrt) return 1; \ + CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ + do_mmut_rw(es, DEST_REG, addr64a_2); \ + if (cpu_state.abrt) return 1; \ + temp = readmemw_n(cpu_state.ea_seg->base, SRC_REG, addr64a); if (cpu_state.abrt) return 1; \ + temp2 = readmemw_n(es, DEST_REG, addr64a_2); if (cpu_state.abrt) return 1; \ \ if (cpu_state.flags & D_FLAG) { DEST_REG -= 2; SRC_REG -= 2; } \ else { DEST_REG += 2; SRC_REG += 2; } \ @@ -575,8 +588,9 @@ static int opREP_CMPSW_ ## size(uint32_t fetchdat) static int opREP_CMPSL_ ## size(uint32_t fetchdat) \ { \ int reads = 0, total_cycles = 0, tempz; \ - uint64_t addr64[4]; \ - uint64_t addr642[4]; \ + \ + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; \ + addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; \ \ tempz = FV; \ if ((CNT_REG > 0) && (FV == tempz)) \ @@ -584,13 +598,15 @@ static int opREP_CMPSL_ ## size(uint32_t fetchdat) uint32_t temp, temp2; \ SEG_CHECK_READ(cpu_state.ea_seg); \ SEG_CHECK_READ(&cpu_state.seg_es); \ - CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 3); \ - do_mmut_rl(cpu_state.ea_seg->base, SRC_REG, addr64); \ - CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG + 3); \ - do_mmut_rl(es, DEST_REG, addr642); \ + CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \ + high_page = 0; \ + do_mmut_rl(cpu_state.ea_seg->base, SRC_REG, addr64a); \ if (cpu_state.abrt) return 1; \ - temp = readmeml_n(cpu_state.ea_seg->base, SRC_REG, addr64); \ - temp2 = readmeml_n(es, DEST_REG, addr642); if (cpu_state.abrt) return 1; \ + CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ + do_mmut_rl(es, DEST_REG, addr64a_2); \ + if (cpu_state.abrt) return 1; \ + temp = readmeml_n(cpu_state.ea_seg->base, SRC_REG, addr64a); if (cpu_state.abrt) return 1; \ + temp2 = readmeml_n(es, DEST_REG, addr64a_2); if (cpu_state.abrt) return 1; \ \ if (cpu_state.flags & D_FLAG) { DEST_REG -= 4; SRC_REG -= 4; } \ else { DEST_REG += 4; SRC_REG += 4; } \ @@ -653,7 +669,7 @@ static int opREP_SCASW_ ## size(uint32_t fetchdat) SEG_CHECK_READ(&cpu_state.seg_es); \ while ((CNT_REG > 0) && (FV == tempz)) \ { \ - CHECK_READ_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1); \ + CHECK_READ_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ uint16_t temp = readmemw(es, DEST_REG); if (cpu_state.abrt) break;\ setsub16(AX, temp); \ tempz = (ZF_SET()) ? 1 : 0; \ @@ -685,7 +701,7 @@ static int opREP_SCASL_ ## size(uint32_t fetchdat) SEG_CHECK_READ(&cpu_state.seg_es); \ while ((CNT_REG > 0) && (FV == tempz)) \ { \ - CHECK_READ_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3); \ + CHECK_READ_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ uint32_t temp = readmeml(es, DEST_REG); if (cpu_state.abrt) break;\ setsub32(EAX, temp); \ tempz = (ZF_SET()) ? 1 : 0; \ diff --git a/src/cpu/x86_ops_stack.h b/src/cpu/x86_ops_stack.h index 9ca1171a0..5bed0b741 100644 --- a/src/cpu/x86_ops_stack.h +++ b/src/cpu/x86_ops_stack.h @@ -245,8 +245,8 @@ static int opPOPW_a16(uint32_t fetchdat) else SP -= 2; } - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 6); - else CLOCK_CYCLES((cpu_mod == 3) ? 4 : 5); + if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 6); } + else { CLOCK_CYCLES((cpu_mod == 3) ? 4 : 5); } PREFETCH_RUN((cpu_mod == 3) ? 4 : 5, 2, rmdat, 1,0,(cpu_mod == 3) ? 0:1,0, 0); return cpu_state.abrt; } @@ -266,8 +266,8 @@ static int opPOPW_a32(uint32_t fetchdat) else SP -= 2; } - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 6); - else CLOCK_CYCLES((cpu_mod == 3) ? 4 : 5); + if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 6); } + else { CLOCK_CYCLES((cpu_mod == 3) ? 4 : 5); } PREFETCH_RUN((cpu_mod == 3) ? 4 : 5, 2, rmdat, 1,0,(cpu_mod == 3) ? 0:1,0, 1); return cpu_state.abrt; } @@ -288,8 +288,8 @@ static int opPOPL_a16(uint32_t fetchdat) else SP -= 4; } - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 6); - else CLOCK_CYCLES((cpu_mod == 3) ? 4 : 5); + if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 6); } + else { CLOCK_CYCLES((cpu_mod == 3) ? 4 : 5); } PREFETCH_RUN((cpu_mod == 3) ? 4 : 5, 2, rmdat, 0,1,0,(cpu_mod == 3) ? 0:1, 0); return cpu_state.abrt; } @@ -309,8 +309,8 @@ static int opPOPL_a32(uint32_t fetchdat) else SP -= 4; } - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 6); - else CLOCK_CYCLES((cpu_mod == 3) ? 4 : 5); + if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 6); } + else { CLOCK_CYCLES((cpu_mod == 3) ? 4 : 5); } PREFETCH_RUN((cpu_mod == 3) ? 4 : 5, 2, rmdat, 0,1,0,(cpu_mod == 3) ? 0:1, 1); return cpu_state.abrt; } @@ -470,17 +470,16 @@ static int opLEAVE_l(uint32_t fetchdat) } -PUSH_SEG_OPS(CS); -PUSH_SEG_OPS(DS); -PUSH_SEG_OPS(ES); -PUSH_SEG_OPS(FS); -PUSH_SEG_OPS(GS); -PUSH_SEG_OPS(SS); - -POP_SEG_OPS(DS, &cpu_state.seg_ds); -POP_SEG_OPS(ES, &cpu_state.seg_es); -POP_SEG_OPS(FS, &cpu_state.seg_fs); -POP_SEG_OPS(GS, &cpu_state.seg_gs); +PUSH_SEG_OPS(CS) +PUSH_SEG_OPS(DS) +PUSH_SEG_OPS(ES) +PUSH_SEG_OPS(FS) +PUSH_SEG_OPS(GS) +PUSH_SEG_OPS(SS) +POP_SEG_OPS(DS, &cpu_state.seg_ds) +POP_SEG_OPS(ES, &cpu_state.seg_es) +POP_SEG_OPS(FS, &cpu_state.seg_fs) +POP_SEG_OPS(GS, &cpu_state.seg_gs) static int opPOP_SS_w(uint32_t fetchdat) diff --git a/src/cpu/x86_ops_string.h b/src/cpu/x86_ops_string.h index 2cdbd7959..675489aed 100644 --- a/src/cpu/x86_ops_string.h +++ b/src/cpu/x86_ops_string.h @@ -1,17 +1,18 @@ static int opMOVSB_a16(uint32_t fetchdat) { uint8_t temp; - uint64_t addr64r; - uint64_t addr64w; + + addr64 = addr64_2 = 0x00000000; SEG_CHECK_READ(cpu_state.ea_seg); - do_mmut_rb(cpu_state.ea_seg->base, SI, &addr64r); + high_page = 0; + do_mmut_rb(cpu_state.ea_seg->base, SI, &addr64); if (cpu_state.abrt) return 1; SEG_CHECK_WRITE(&cpu_state.seg_es); - do_mmut_wb(es, DI, &addr64w); + do_mmut_wb(es, DI, &addr64_2); if (cpu_state.abrt) return 1; - temp = readmemb_n(cpu_state.ea_seg->base, SI, addr64r); if (cpu_state.abrt) return 1; - writememb_n(es, DI, addr64w, temp); if (cpu_state.abrt) return 1; + temp = readmemb_n(cpu_state.ea_seg->base, SI, addr64); if (cpu_state.abrt) return 1; + writememb_n(es, DI, addr64_2, temp); if (cpu_state.abrt) return 1; if (cpu_state.flags & D_FLAG) { DI--; SI--; } else { DI++; SI++; } CLOCK_CYCLES(7); @@ -21,17 +22,18 @@ static int opMOVSB_a16(uint32_t fetchdat) static int opMOVSB_a32(uint32_t fetchdat) { uint8_t temp; - uint64_t addr64r; - uint64_t addr64w; + + addr64 = addr64_2 = 0x00000000; SEG_CHECK_READ(cpu_state.ea_seg); - do_mmut_rb(cpu_state.ea_seg->base, ESI, &addr64r); + high_page = 0; + do_mmut_rb(cpu_state.ea_seg->base, ESI, &addr64); if (cpu_state.abrt) return 1; SEG_CHECK_WRITE(&cpu_state.seg_es); - do_mmut_wb(es, EDI, &addr64w); + do_mmut_wb(es, EDI, &addr64_2); if (cpu_state.abrt) return 1; - temp = readmemb_n(cpu_state.ea_seg->base, ESI, addr64r); if (cpu_state.abrt) return 1; - writememb_n(es, EDI, addr64w, temp); if (cpu_state.abrt) return 1; + temp = readmemb_n(cpu_state.ea_seg->base, ESI, addr64); if (cpu_state.abrt) return 1; + writememb_n(es, EDI, addr64_2, temp); if (cpu_state.abrt) return 1; if (cpu_state.flags & D_FLAG) { EDI--; ESI--; } else { EDI++; ESI++; } CLOCK_CYCLES(7); @@ -42,17 +44,19 @@ static int opMOVSB_a32(uint32_t fetchdat) static int opMOVSW_a16(uint32_t fetchdat) { uint16_t temp; - uint64_t addr64r[2]; - uint64_t addr64w[2]; + + addr64a[0] = addr64a[1] = 0x00000000; + addr64a_2[0] = addr64a_2[1] = 0x00000000; SEG_CHECK_READ(cpu_state.ea_seg); - do_mmut_rw(cpu_state.ea_seg->base, SI, addr64r); + high_page = 0; + do_mmut_rw(cpu_state.ea_seg->base, SI, addr64a); if (cpu_state.abrt) return 1; SEG_CHECK_WRITE(&cpu_state.seg_es); - do_mmut_ww(es, DI, addr64w); + do_mmut_ww(es, DI, addr64a_2); if (cpu_state.abrt) return 1; - temp = readmemw_n(cpu_state.ea_seg->base, SI, addr64r); if (cpu_state.abrt) return 1; - writememw_n(es, DI, addr64w, temp); if (cpu_state.abrt) return 1; + temp = readmemw_n(cpu_state.ea_seg->base, SI, addr64a); if (cpu_state.abrt) return 1; + writememw_n(es, DI, addr64a_2, temp); if (cpu_state.abrt) return 1; if (cpu_state.flags & D_FLAG) { DI -= 2; SI -= 2; } else { DI += 2; SI += 2; } CLOCK_CYCLES(7); @@ -62,17 +66,19 @@ static int opMOVSW_a16(uint32_t fetchdat) static int opMOVSW_a32(uint32_t fetchdat) { uint16_t temp; - uint64_t addr64r[2]; - uint64_t addr64w[2]; + + addr64a[0] = addr64a[1] = 0x00000000; + addr64a_2[0] = addr64a_2[1] = 0x00000000; SEG_CHECK_READ(cpu_state.ea_seg); - do_mmut_rw(cpu_state.ea_seg->base, ESI, addr64r); + high_page = 0; + do_mmut_rw(cpu_state.ea_seg->base, ESI, addr64a); if (cpu_state.abrt) return 1; SEG_CHECK_WRITE(&cpu_state.seg_es); - do_mmut_ww(es, EDI, addr64w); + do_mmut_ww(es, EDI, addr64a_2); if (cpu_state.abrt) return 1; - temp = readmemw_n(cpu_state.ea_seg->base, ESI, addr64r); if (cpu_state.abrt) return 1; - writememw_n(es, EDI, addr64w, temp); if (cpu_state.abrt) return 1; + temp = readmemw_n(cpu_state.ea_seg->base, ESI, addr64a); if (cpu_state.abrt) return 1; + writememw_n(es, EDI, addr64a_2, temp); if (cpu_state.abrt) return 1; if (cpu_state.flags & D_FLAG) { EDI -= 2; ESI -= 2; } else { EDI += 2; ESI += 2; } CLOCK_CYCLES(7); @@ -83,17 +89,19 @@ static int opMOVSW_a32(uint32_t fetchdat) static int opMOVSL_a16(uint32_t fetchdat) { uint32_t temp; - uint64_t addr64r[4]; - uint64_t addr64w[4]; + + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; + addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; SEG_CHECK_READ(cpu_state.ea_seg); - do_mmut_rl(cpu_state.ea_seg->base, SI, addr64r); + high_page = 0; + do_mmut_rl(cpu_state.ea_seg->base, SI, addr64a); if (cpu_state.abrt) return 1; SEG_CHECK_WRITE(&cpu_state.seg_es); - do_mmut_wl(es, DI, addr64w); + do_mmut_wl(es, DI, addr64a_2); if (cpu_state.abrt) return 1; - temp = readmeml_n(cpu_state.ea_seg->base, SI, addr64r); if (cpu_state.abrt) return 1; - writememl_n(es, DI, addr64w, temp); if (cpu_state.abrt) return 1; + temp = readmeml_n(cpu_state.ea_seg->base, SI, addr64a); if (cpu_state.abrt) return 1; + writememl_n(es, DI, addr64a_2, temp); if (cpu_state.abrt) return 1; if (cpu_state.flags & D_FLAG) { DI -= 4; SI -= 4; } else { DI += 4; SI += 4; } CLOCK_CYCLES(7); @@ -103,17 +111,19 @@ static int opMOVSL_a16(uint32_t fetchdat) static int opMOVSL_a32(uint32_t fetchdat) { uint32_t temp; - uint64_t addr64r[4]; - uint64_t addr64w[4]; + + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; + addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; SEG_CHECK_READ(cpu_state.ea_seg); - do_mmut_rl(cpu_state.ea_seg->base, ESI, addr64r); + high_page = 0; + do_mmut_rl(cpu_state.ea_seg->base, ESI, addr64a); if (cpu_state.abrt) return 1; SEG_CHECK_WRITE(&cpu_state.seg_es); - do_mmut_wl(es, EDI, addr64w); + do_mmut_wl(es, EDI, addr64a_2); if (cpu_state.abrt) return 1; - temp = readmeml_n(cpu_state.ea_seg->base, ESI, addr64r); if (cpu_state.abrt) return 1; - writememl_n(es, EDI, addr64w, temp); if (cpu_state.abrt) return 1; + temp = readmeml_n(cpu_state.ea_seg->base, ESI, addr64a); if (cpu_state.abrt) return 1; + writememl_n(es, EDI, addr64a_2, temp); if (cpu_state.abrt) return 1; if (cpu_state.flags & D_FLAG) { EDI -= 4; ESI -= 4; } else { EDI += 4; ESI += 4; } CLOCK_CYCLES(7); @@ -125,17 +135,18 @@ static int opMOVSL_a32(uint32_t fetchdat) static int opCMPSB_a16(uint32_t fetchdat) { uint8_t src, dst; - uint64_t addr64; - uint64_t addr642; + + addr64 = addr64_2 = 0x00000000; SEG_CHECK_READ(cpu_state.ea_seg); + high_page = 0; do_mmut_rb(cpu_state.ea_seg->base, SI, &addr64); if (cpu_state.abrt) return 1; SEG_CHECK_READ(&cpu_state.seg_es); - do_mmut_rb(es, DI, &addr642); + do_mmut_rb(es, DI, &addr64_2); if (cpu_state.abrt) return 1; - src = readmemb_n(cpu_state.ea_seg->base, SI, addr64); - dst = readmemb_n(es, DI, addr642); if (cpu_state.abrt) return 1; + src = readmemb_n(cpu_state.ea_seg->base, SI, addr64); if (cpu_state.abrt) return 1; + dst = readmemb_n(es, DI, addr64_2); if (cpu_state.abrt) return 1; setsub8(src, dst); if (cpu_state.flags & D_FLAG) { DI--; SI--; } else { DI++; SI++; } @@ -146,17 +157,18 @@ static int opCMPSB_a16(uint32_t fetchdat) static int opCMPSB_a32(uint32_t fetchdat) { uint8_t src, dst; - uint64_t addr64; - uint64_t addr642; + + addr64 = addr64_2 = 0x00000000; SEG_CHECK_READ(cpu_state.ea_seg); + high_page = 0; do_mmut_rb(cpu_state.ea_seg->base, ESI, &addr64); if (cpu_state.abrt) return 1; SEG_CHECK_READ(&cpu_state.seg_es); - do_mmut_rb(es, EDI, &addr642); + do_mmut_rb(es, EDI, &addr64_2); if (cpu_state.abrt) return 1; - src = readmemb_n(cpu_state.ea_seg->base, ESI, addr64); - dst = readmemb_n(es, EDI, addr642); if (cpu_state.abrt) return 1; + src = readmemb_n(cpu_state.ea_seg->base, ESI, addr64); if (cpu_state.abrt) return 1; + dst = readmemb_n(es, EDI, addr64_2); if (cpu_state.abrt) return 1; setsub8(src, dst); if (cpu_state.flags & D_FLAG) { EDI--; ESI--; } else { EDI++; ESI++; } @@ -168,17 +180,19 @@ static int opCMPSB_a32(uint32_t fetchdat) static int opCMPSW_a16(uint32_t fetchdat) { uint16_t src, dst; - uint64_t addr64[2]; - uint64_t addr642[2]; + + addr64a[0] = addr64a[1] = 0x00000000; + addr64a_2[0] = addr64a_2[1] = 0x00000000; SEG_CHECK_READ(cpu_state.ea_seg); - do_mmut_rw(cpu_state.ea_seg->base, SI, addr64); + high_page = 0; + do_mmut_rw(cpu_state.ea_seg->base, SI, addr64a); if (cpu_state.abrt) return 1; SEG_CHECK_READ(&cpu_state.seg_es); - do_mmut_rw(es, DI, addr642); + do_mmut_rw(es, DI, addr64a_2); if (cpu_state.abrt) return 1; - src = readmemw_n(cpu_state.ea_seg->base, SI, addr64); - dst = readmemw_n(es, DI, addr642); if (cpu_state.abrt) return 1; + src = readmemw_n(cpu_state.ea_seg->base, SI, addr64a); if (cpu_state.abrt) return 1; + dst = readmemw_n(es, DI, addr64a_2); if (cpu_state.abrt) return 1; setsub16(src, dst); if (cpu_state.flags & D_FLAG) { DI -= 2; SI -= 2; } else { DI += 2; SI += 2; } @@ -189,17 +203,19 @@ static int opCMPSW_a16(uint32_t fetchdat) static int opCMPSW_a32(uint32_t fetchdat) { uint16_t src, dst; - uint64_t addr64[2]; - uint64_t addr642[2]; + + addr64a[0] = addr64a[1] = 0x00000000; + addr64a_2[0] = addr64a_2[1] = 0x00000000; SEG_CHECK_READ(cpu_state.ea_seg); - do_mmut_rw(cpu_state.ea_seg->base, ESI, addr64); + high_page = 0; + do_mmut_rw(cpu_state.ea_seg->base, ESI, addr64a); if (cpu_state.abrt) return 1; SEG_CHECK_READ(&cpu_state.seg_es); - do_mmut_rw(es, EDI, addr642); + do_mmut_rw(es, EDI, addr64a_2); if (cpu_state.abrt) return 1; - src = readmemw_n(cpu_state.ea_seg->base, ESI, addr64); - dst = readmemw_n(es, EDI, addr642); if (cpu_state.abrt) return 1; + src = readmemw_n(cpu_state.ea_seg->base, ESI, addr64a); if (cpu_state.abrt) return 1; + dst = readmemw_n(es, EDI, addr64a_2); if (cpu_state.abrt) return 1; setsub16(src, dst); if (cpu_state.flags & D_FLAG) { EDI -= 2; ESI -= 2; } else { EDI += 2; ESI += 2; } @@ -211,17 +227,19 @@ static int opCMPSW_a32(uint32_t fetchdat) static int opCMPSL_a16(uint32_t fetchdat) { uint32_t src, dst; - uint64_t addr64[4]; - uint64_t addr642[4]; + + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; + addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; SEG_CHECK_READ(cpu_state.ea_seg); - do_mmut_rl(cpu_state.ea_seg->base, SI, addr64); + high_page = 0; + do_mmut_rl(cpu_state.ea_seg->base, SI, addr64a); if (cpu_state.abrt) return 1; SEG_CHECK_READ(&cpu_state.seg_es); - do_mmut_rl(es, DI, addr642); + do_mmut_rl(es, DI, addr64a_2); if (cpu_state.abrt) return 1; - src = readmeml_n(cpu_state.ea_seg->base, SI, addr64); - dst = readmeml_n(es, DI, addr642); if (cpu_state.abrt) return 1; + src = readmeml_n(cpu_state.ea_seg->base, SI, addr64a); if (cpu_state.abrt) return 1; + dst = readmeml_n(es, DI, addr64a_2); if (cpu_state.abrt) return 1; setsub32(src, dst); if (cpu_state.flags & D_FLAG) { DI -= 4; SI -= 4; } else { DI += 4; SI += 4; } @@ -232,17 +250,19 @@ static int opCMPSL_a16(uint32_t fetchdat) static int opCMPSL_a32(uint32_t fetchdat) { uint32_t src, dst; - uint64_t addr64[4]; - uint64_t addr642[4]; + + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; + addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; SEG_CHECK_READ(cpu_state.ea_seg); - do_mmut_rl(cpu_state.ea_seg->base, ESI, addr64); + high_page = 0; + do_mmut_rl(cpu_state.ea_seg->base, ESI, addr64a); if (cpu_state.abrt) return 1; SEG_CHECK_READ(&cpu_state.seg_es); - do_mmut_rl(es, EDI, addr642); + do_mmut_rl(es, EDI, addr64a_2); if (cpu_state.abrt) return 1; - src = readmeml_n(cpu_state.ea_seg->base, ESI, addr64); - dst = readmeml_n(es, EDI, addr642); if (cpu_state.abrt) return 1; + src = readmeml_n(cpu_state.ea_seg->base, ESI, addr64a); if (cpu_state.abrt) return 1; + dst = readmeml_n(es, EDI, addr64a_2); if (cpu_state.abrt) return 1; setsub32(src, dst); if (cpu_state.flags & D_FLAG) { EDI -= 4; ESI -= 4; } else { EDI += 4; ESI += 4; } @@ -481,10 +501,12 @@ static int opSCASL_a32(uint32_t fetchdat) static int opINSB_a16(uint32_t fetchdat) { uint8_t temp; - uint64_t addr64 = 0x0000000000000000ULL; + + addr64 = 0x00000000; SEG_CHECK_WRITE(&cpu_state.seg_es); check_io_perm(DX); + high_page = 0; do_mmut_wb(es, DI, &addr64); if (cpu_state.abrt) return 1; temp = inb(DX); writememb_n(es, DI, addr64, temp); if (cpu_state.abrt) return 1; @@ -497,10 +519,12 @@ static int opINSB_a16(uint32_t fetchdat) static int opINSB_a32(uint32_t fetchdat) { uint8_t temp; - uint64_t addr64 = 0x0000000000000000ULL; + + addr64 = 0x00000000; SEG_CHECK_WRITE(&cpu_state.seg_es); check_io_perm(DX); + high_page = 0; do_mmut_wb(es, EDI, &addr64); if (cpu_state.abrt) return 1; temp = inb(DX); writememb_n(es, EDI, addr64, temp); if (cpu_state.abrt) return 1; @@ -514,14 +538,16 @@ static int opINSB_a32(uint32_t fetchdat) static int opINSW_a16(uint32_t fetchdat) { uint16_t temp; - uint64_t addr64[2]; + + addr64a[0] = addr64a[1] = 0x00000000; SEG_CHECK_WRITE(&cpu_state.seg_es); check_io_perm(DX); check_io_perm(DX + 1); - do_mmut_ww(es, DI, addr64); if (cpu_state.abrt) return 1; + high_page = 0; + do_mmut_ww(es, DI, addr64a); if (cpu_state.abrt) return 1; temp = inw(DX); - writememw_n(es, DI, addr64, temp); if (cpu_state.abrt) return 1; + writememw_n(es, DI, addr64a, temp); if (cpu_state.abrt) return 1; if (cpu_state.flags & D_FLAG) DI -= 2; else DI += 2; CLOCK_CYCLES(15); @@ -531,14 +557,16 @@ static int opINSW_a16(uint32_t fetchdat) static int opINSW_a32(uint32_t fetchdat) { uint16_t temp; - uint64_t addr64[2]; + + addr64a[0] = addr64a[1] = 0x00000000; SEG_CHECK_WRITE(&cpu_state.seg_es); + high_page = 0; check_io_perm(DX); check_io_perm(DX + 1); - do_mmut_ww(es, EDI, addr64); if (cpu_state.abrt) return 1; + do_mmut_ww(es, EDI, addr64a); if (cpu_state.abrt) return 1; temp = inw(DX); - writememw_n(es, EDI, addr64, temp); if (cpu_state.abrt) return 1; + writememw_n(es, EDI, addr64a, temp); if (cpu_state.abrt) return 1; if (cpu_state.flags & D_FLAG) EDI -= 2; else EDI += 2; CLOCK_CYCLES(15); @@ -549,16 +577,18 @@ static int opINSW_a32(uint32_t fetchdat) static int opINSL_a16(uint32_t fetchdat) { uint32_t temp; - uint64_t addr64[4]; + + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; SEG_CHECK_WRITE(&cpu_state.seg_es); check_io_perm(DX); check_io_perm(DX + 1); check_io_perm(DX + 2); check_io_perm(DX + 3); - do_mmut_wl(es, DI, addr64); if (cpu_state.abrt) return 1; + high_page = 0; + do_mmut_wl(es, DI, addr64a); if (cpu_state.abrt) return 1; temp = inl(DX); - writememl_n(es, DI, addr64, temp); if (cpu_state.abrt) return 1; + writememl_n(es, DI, addr64a, temp); if (cpu_state.abrt) return 1; if (cpu_state.flags & D_FLAG) DI -= 4; else DI += 4; CLOCK_CYCLES(15); @@ -568,16 +598,18 @@ static int opINSL_a16(uint32_t fetchdat) static int opINSL_a32(uint32_t fetchdat) { uint32_t temp; - uint64_t addr64[4]; + + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; SEG_CHECK_WRITE(&cpu_state.seg_es); check_io_perm(DX); check_io_perm(DX + 1); check_io_perm(DX + 2); check_io_perm(DX + 3); - do_mmut_wl(es, DI, addr64); if (cpu_state.abrt) return 1; + high_page = 0; + do_mmut_wl(es, DI, addr64a); if (cpu_state.abrt) return 1; temp = inl(DX); - writememl_n(es, EDI, addr64, temp); if (cpu_state.abrt) return 1; + writememl_n(es, EDI, addr64a, temp); if (cpu_state.abrt) return 1; if (cpu_state.flags & D_FLAG) EDI -= 4; else EDI += 4; CLOCK_CYCLES(15); diff --git a/src/cpu/x86seg.c b/src/cpu/x86seg.c index 64ea5dd6f..a9c3923c8 100644 --- a/src/cpu/x86seg.c +++ b/src/cpu/x86seg.c @@ -281,7 +281,7 @@ check_seg_valid(x86seg *s) int valid = 1; x86seg *dt = (s->seg & 0x0004) ? &ldt : &gdt; - if (((s->seg & 0xfff8) + 7) > dt->limit) + if (((s->seg & 0xfff8UL) + 7UL) > dt->limit) valid = 0; switch (s->access & 0x1f) { diff --git a/src/include/86box/mem.h b/src/include/86box/mem.h index 6410d6d30..52e1ba810 100644 --- a/src/include/86box/mem.h +++ b/src/include/86box/mem.h @@ -189,12 +189,10 @@ extern uint32_t rammask; extern uint8_t *rom; extern uint32_t biosmask, biosaddr; -extern int readlookup[256], - readlookupp[256]; +extern int readlookup[256]; extern uintptr_t * readlookup2; extern int readlnext; -extern int writelookup[256], - writelookupp[256]; +extern int writelookup[256]; extern uintptr_t * writelookup2; extern int writelnext; extern uint32_t ram_mapped_addr[64]; @@ -224,6 +222,7 @@ extern int readlnum, extern int memspeed[11]; extern int mmu_perm; +extern uint8_t high_page; /* if a high (> 4 gb) page was detected */ extern int mem_a20_state, mem_a20_alt, @@ -244,14 +243,14 @@ extern void writememll(uint32_t addr, uint32_t val); extern uint64_t readmemql(uint32_t addr); extern void writememql(uint32_t addr, uint64_t val); -extern uint8_t readmembl_no_mmut(uint32_t addr, uint64_t addr64); -extern void writemembl_no_mmut(uint32_t addr, uint64_t addr64, uint8_t val); -extern uint16_t readmemwl_no_mmut(uint32_t addr, uint64_t *addr64); -extern void writememwl_no_mmut(uint32_t addr, uint64_t *addr64, uint16_t val); -extern uint32_t readmemll_no_mmut(uint32_t addr, uint64_t *addr64); -extern void writememll_no_mmut(uint32_t addr, uint64_t *addr64, uint32_t val); +extern uint8_t readmembl_no_mmut(uint32_t addr, uint32_t a64); +extern void writemembl_no_mmut(uint32_t addr, uint32_t a64, uint8_t val); +extern uint16_t readmemwl_no_mmut(uint32_t addr, uint32_t *a64); +extern void writememwl_no_mmut(uint32_t addr, uint32_t *a64, uint16_t val); +extern uint32_t readmemll_no_mmut(uint32_t addr, uint32_t *a64); +extern void writememll_no_mmut(uint32_t addr, uint32_t *a64, uint32_t val); -extern void do_mmutranslate(uint32_t addr, uint64_t *addr64, int num, int write); +extern void do_mmutranslate(uint32_t addr, uint32_t *a64, int num, int write); extern uint8_t *getpccache(uint32_t a); extern uint64_t mmutranslatereal(uint32_t addr, int rw); diff --git a/src/mem/mem.c b/src/mem/mem.c index 062375994..73f89b3eb 100644 --- a/src/mem/mem.c +++ b/src/mem/mem.c @@ -80,12 +80,10 @@ uint32_t pccache; uint8_t *pccache2; int readlnext; -int readlookup[256], - readlookupp[256]; +int readlookup[256]; uintptr_t *readlookup2; int writelnext; -int writelookup[256], - writelookupp[256]; +int writelookup[256]; uintptr_t *writelookup2; uint32_t mem_logical_addr; @@ -112,8 +110,13 @@ uint64_t *byte_code_present_mask; uint32_t purgable_page_list_head = 0; int purgeable_page_count = 0; +uint8_t high_page = 0; /* if a high (> 4 gb) page was detected */ + /* FIXME: re-do this with a 'mem_ops' struct. */ +static uint8_t *page_lookupp; /* pagetable mmu_perm lookup */ +static uint8_t *readlookupp; +static uint8_t *writelookupp; static mem_mapping_t *base_mapping, *last_mapping; static mem_mapping_t *read_mapping[MEM_MAPPINGS_NO]; static mem_mapping_t *write_mapping[MEM_MAPPINGS_NO]; @@ -168,11 +171,15 @@ resetreadlookup(void) /* Initialize the tables for high (> 1024K) RAM. */ memset(readlookup2, 0xff, (1<<20)*sizeof(uintptr_t)); + memset(readlookupp, 0x04, (1<<20)*sizeof(uint8_t)); + memset(writelookup2, 0xff, (1<<20)*sizeof(uintptr_t)); + memset(writelookupp, 0x04, (1<<20)*sizeof(uint8_t)); readlnext = 0; writelnext = 0; pccache = 0xffffffff; + high_page = 0; } @@ -184,11 +191,14 @@ flushmmucache(void) for (c = 0; c < 256; c++) { if (readlookup[c] != (int) 0xffffffff) { readlookup2[readlookup[c]] = LOOKUP_INV; + readlookupp[readlookup[c]] = 4; readlookup[c] = 0xffffffff; } if (writelookup[c] != (int) 0xffffffff) { page_lookup[writelookup[c]] = NULL; + page_lookupp[writelookup[c]] = 4; writelookup2[writelookup[c]] = LOOKUP_INV; + writelookupp[writelookup[c]] = 4; writelookup[c] = 0xffffffff; } } @@ -211,11 +221,14 @@ flushmmucache_nopc(void) for (c = 0; c < 256; c++) { if (readlookup[c] != (int) 0xffffffff) { readlookup2[readlookup[c]] = LOOKUP_INV; + readlookupp[readlookup[c]] = 4; readlookup[c] = 0xffffffff; } if (writelookup[c] != (int) 0xffffffff) { page_lookup[writelookup[c]] = NULL; + page_lookupp[writelookup[c]] = 4; writelookup2[writelookup[c]] = LOOKUP_INV; + writelookupp[writelookup[c]] = 4; writelookup[c] = 0xffffffff; } } @@ -230,11 +243,14 @@ flushmmucache_cr3(void) for (c = 0; c < 256; c++) { if (readlookup[c] != (int) 0xffffffff) { readlookup2[readlookup[c]] = LOOKUP_INV; + readlookupp[readlookup[c]] = 4; readlookup[c] = 0xffffffff; } if (writelookup[c] != (int) 0xffffffff) { page_lookup[writelookup[c]] = NULL; + page_lookupp[writelookup[c]] = 4; writelookup2[writelookup[c]] = LOOKUP_INV; + writelookupp[writelookup[c]] = 4; writelookup[c] = 0xffffffff; } } @@ -277,7 +293,7 @@ mem_flush_write_page(uint32_t addr, uint32_t virt) static __inline uint64_t mmutranslatereal_normal(uint32_t addr, int rw) { - uint32_t temp,temp2,temp3; + uint32_t temp, temp2, temp3; uint32_t addr2; if (cpu_state.abrt) @@ -311,18 +327,20 @@ mmutranslatereal_normal(uint32_t addr, int rw) } mmu_perm = temp & 4; - rammap(addr2) |= 0x20; + rammap(addr2) |= (rw ? 0x60 : 0x20); return (temp & ~0x3fffff) + (addr & 0x3fffff); } temp = rammap((temp & ~0xfff) + ((addr >> 10) & 0xffc)); temp3 = temp & temp2; - if (!(temp&1) || ((CPL == 3) && !(temp3 & 4) && !cpl_override) || (rw && !(temp3 & 2) && (((CPL == 3) && !cpl_override) || (is486 && (cr0 & WP_FLAG))))) { + if (!(temp & 1) || ((CPL == 3) && !(temp3 & 4) && !cpl_override) || (rw && !(temp3 & 2) && (((CPL == 3) && !cpl_override) || (is486 && (cr0 & WP_FLAG))))) { cr2 = addr; temp &= 1; - if (CPL == 3) temp |= 4; - if (rw) temp |= 2; + if (CPL == 3) + temp |= 4; + if (rw) + temp |= 2; cpu_state.abrt = ABRT_PF; abrt_error = temp; return 0xffffffffffffffffULL; @@ -330,17 +348,17 @@ mmutranslatereal_normal(uint32_t addr, int rw) mmu_perm = temp & 4; rammap(addr2) |= 0x20; - rammap((temp2 & ~0xfff) + ((addr >> 10) & 0xffc)) |= (rw?0x60:0x20); + rammap((temp2 & ~0xfff) + ((addr >> 10) & 0xffc)) |= (rw ? 0x60 : 0x20); - return (uint64_t) ((temp&~0xfff)+(addr&0xfff)); + return (uint64_t) ((temp & ~0xfff) + (addr & 0xfff)); } static __inline uint64_t mmutranslatereal_pae(uint32_t addr, int rw) { - uint64_t temp,temp2,temp3,temp4; - uint64_t addr2,addr3,addr4; + uint64_t temp, temp2, temp3, temp4; + uint64_t addr2, addr3, addr4; if (cpu_state.abrt) return 0xffffffffffffffffULL; @@ -385,7 +403,7 @@ mmutranslatereal_pae(uint32_t addr, int rw) return 0xffffffffffffffffULL; } mmu_perm = temp & 4; - rammap64(addr3) |= 0x20; + rammap64(addr3) |= (rw ? 0x60 : 0x20); return ((temp & ~0x1fffffULL) + (addr & 0x1fffffULL)) & 0x000000ffffffffffULL; } @@ -405,7 +423,7 @@ mmutranslatereal_pae(uint32_t addr, int rw) mmu_perm = temp & 4; rammap64(addr3) |= 0x20; - rammap64(addr4) |= (rw? 0x60 : 0x20); + rammap64(addr4) |= (rw ? 0x60 : 0x20); return ((temp & ~0xfffULL) + ((uint64_t) (addr & 0xfff))) & 0x000000ffffffffffULL; } @@ -579,8 +597,8 @@ addreadlookup(uint32_t virt, uint32_t phys) readlookup2[virt>>12] = (uintptr_t)&ram2[a - (1 << 30)]; else readlookup2[virt>>12] = (uintptr_t)&ram[a]; + readlookupp[virt>>12] = mmu_perm; - readlookupp[readlnext] = mmu_perm; readlookup[readlnext++] = virt >> 12; readlnext &= (cachesize-1); @@ -608,19 +626,20 @@ addwritelookup(uint32_t virt, uint32_t phys) #ifdef USE_NEW_DYNAREC #ifdef USE_DYNAREC - if (pages[phys >> 12].block || (phys & ~0xfff) == recomp_page) + if (pages[phys >> 12].block || (phys & ~0xfff) == recomp_page) { #else - if (pages[phys >> 12].block) + if (pages[phys >> 12].block) { #endif #else #ifdef USE_DYNAREC - if (pages[phys >> 12].block[0] || pages[phys >> 12].block[1] || pages[phys >> 12].block[2] || pages[phys >> 12].block[3] || (phys & ~0xfff) == recomp_page) + if (pages[phys >> 12].block[0] || pages[phys >> 12].block[1] || pages[phys >> 12].block[2] || pages[phys >> 12].block[3] || (phys & ~0xfff) == recomp_page) { #else - if (pages[phys >> 12].block[0] || pages[phys >> 12].block[1] || pages[phys >> 12].block[2] || pages[phys >> 12].block[3]) + if (pages[phys >> 12].block[0] || pages[phys >> 12].block[1] || pages[phys >> 12].block[2] || pages[phys >> 12].block[3]) { #endif #endif page_lookup[virt >> 12] = &pages[phys >> 12]; - else { + page_lookupp[virt >> 12] = mmu_perm; + } else { #if (defined __amd64__ || defined _M_X64) a = ((uint64_t)(phys & ~0xfff) - (uint64_t)(virt & ~0xfff)); #else @@ -632,8 +651,8 @@ addwritelookup(uint32_t virt, uint32_t phys) else writelookup2[virt>>12] = (uintptr_t)&ram[a]; } + writelookupp[virt>>12] = mmu_perm; - writelookupp[writelnext] = mmu_perm; writelookup[writelnext++] = virt >> 12; writelnext &= (cachesize - 1); @@ -768,14 +787,19 @@ write_mem_w(uint32_t addr, uint16_t val) uint8_t readmembl(uint32_t addr) { - uint64_t addr64 = (uint64_t) addr; mem_mapping_t *map; + uint64_t a; + addr64 = (uint64_t) addr; mem_logical_addr = addr; + high_page = 0; + if (cr0 >> 31) { - addr64 = mmutranslate_read(addr); - if (addr64 > 0xffffffffULL) + a = mmutranslate_read(addr); + addr64 = (uint32_t) a; + + if (a > 0xffffffffULL) return 0xff; } addr = (uint32_t) (addr64 & rammask); @@ -791,19 +815,24 @@ readmembl(uint32_t addr) void writemembl(uint32_t addr, uint8_t val) { - uint64_t addr64 = (uint64_t) addr; mem_mapping_t *map; + uint64_t a; + addr64 = (uint64_t) addr; mem_logical_addr = addr; + high_page = 0; + if (page_lookup[addr>>12] && page_lookup[addr>>12]->write_b) { page_lookup[addr>>12]->write_b(addr, val, page_lookup[addr>>12]); return; } if (cr0 >> 31) { - addr64 = mmutranslate_write(addr); - if (addr64 > 0xffffffffULL) + a = mmutranslate_write(addr); + addr64 = (uint32_t) a; + + if (a > 0xffffffffULL) return; } addr = (uint32_t) (addr64 & rammask); @@ -816,17 +845,17 @@ writemembl(uint32_t addr, uint8_t val) /* Read a byte from memory without MMU translation - result of previous MMU translation passed as value. */ uint8_t -readmembl_no_mmut(uint32_t addr, uint64_t addr64) +readmembl_no_mmut(uint32_t addr, uint32_t a64) { mem_mapping_t *map; mem_logical_addr = addr; if (cr0 >> 31) { - if (addr64 > 0xffffffffULL) + if (cpu_state.abrt || high_page) return 0xff; - addr = (uint32_t) (addr64 & rammask); + addr = a64 & rammask; } else addr &= rammask; @@ -840,7 +869,7 @@ readmembl_no_mmut(uint32_t addr, uint64_t addr64) /* Write a byte to memory without MMU translation - result of previous MMU translation passed as value. */ void -writemembl_no_mmut(uint32_t addr, uint64_t addr64, uint8_t val) +writemembl_no_mmut(uint32_t addr, uint32_t a64, uint8_t val) { mem_mapping_t *map; @@ -852,10 +881,10 @@ writemembl_no_mmut(uint32_t addr, uint64_t addr64, uint8_t val) } if (cr0 >> 31) { - if (addr64 > 0xffffffffULL) + if (cpu_state.abrt || high_page) return; - addr = (uint32_t) (addr64 & rammask); + addr = a64 & rammask; } else addr &= rammask; @@ -868,42 +897,49 @@ writemembl_no_mmut(uint32_t addr, uint64_t addr64, uint8_t val) uint16_t readmemwl(uint32_t addr) { - uint64_t addr64[2]; mem_mapping_t *map; int i; + uint64_t a; - addr64[0] = (uint64_t) addr; - addr64[1] = (uint64_t) (addr + 1); + addr64a[0] = addr; + addr64a[1] = addr + 1; mem_logical_addr = addr; + high_page = 0; + if (addr & 1) { if (!cpu_cyrix_alignment || (addr & 7) == 7) cycles -= timing_misaligned; if ((addr & 0xfff) > 0xffe) { if (cr0 >> 31) { for (i = 0; i < 2; i++) { - addr64[i] = mmutranslate_read(addr + i); + a = mmutranslate_read(addr + i); + addr64a[i] = (uint32_t) a; - if (addr64[i] > 0xffffffffULL) + if (a > 0xffffffffULL) return 0xffff; } } - return readmembl_no_mmut(addr, addr64[0]) | - (((uint16_t) readmembl_no_mmut(addr + 1, addr64[1])) << 8); - } else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) + return readmembl_no_mmut(addr, addr64a[0]) | + (((uint16_t) readmembl_no_mmut(addr + 1, addr64a[1])) << 8); + } else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) { + mmu_perm = readlookupp[addr >> 12]; return *(uint16_t *)(readlookup2[addr >> 12] + addr); + } } if (cr0 >> 31) { - addr64[0] = mmutranslate_read(addr); - if (addr64[0] > 0xffffffffULL) + a = mmutranslate_read(addr); + addr64a[0] = (uint32_t) a; + + if (a > 0xffffffffULL) return 0xffff; } else - addr64[0] = (uint64_t) addr; + addr64a[0] = (uint64_t) addr; - addr = (uint32_t) (addr64[0] & rammask); + addr = addr64a[0] & rammask; map = read_mapping[addr >> MEM_GRANULARITY_BITS]; @@ -922,15 +958,17 @@ readmemwl(uint32_t addr) void writememwl(uint32_t addr, uint16_t val) { - uint64_t addr64[2]; mem_mapping_t *map; int i; + uint64_t a; - addr64[0] = (uint64_t) addr; - addr64[1] = (uint64_t) (addr + 1); + addr64a[0] = addr; + addr64a[1] = addr + 1; mem_logical_addr = addr; + high_page = 0; + if (addr & 1) { if (!cpu_cyrix_alignment || (addr & 7) == 7) cycles -= timing_misaligned; @@ -940,9 +978,10 @@ writememwl(uint32_t addr, uint16_t val) /* Do not translate a page that has a valid lookup, as that is by definition valid and the whole purpose of the lookup is to avoid repeat identical translations. */ if (!page_lookup[(addr + i) >> 12] || !page_lookup[(addr + i) >> 12]->write_b) { - addr64[i] = mmutranslate_write(addr + i); + a = mmutranslate_write(addr + i); + addr64a[i] = (uint32_t) a; - if (addr64[i] > 0xffffffffULL) + if (a > 0xffffffffULL) return; } } @@ -950,10 +989,11 @@ writememwl(uint32_t addr, uint16_t val) /* No need to waste precious CPU host cycles on mmutranslate's that were already done, just pass their result as a parameter to be used if needed. */ - writemembl_no_mmut(addr, addr64[0], val); - writemembl_no_mmut(addr + 1, addr64[1], val >> 8); + writemembl_no_mmut(addr, addr64a[0], val); + writemembl_no_mmut(addr + 1, addr64a[1], val >> 8); return; } else if (writelookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) { + mmu_perm = writelookupp[addr >> 12]; *(uint16_t *)(writelookup2[addr >> 12] + addr) = val; return; } @@ -961,17 +1001,19 @@ writememwl(uint32_t addr, uint16_t val) if (page_lookup[addr >> 12] && page_lookup[addr >> 12]->write_w) { page_lookup[addr >> 12]->write_w(addr, val, page_lookup[addr >> 12]); + mmu_perm = page_lookupp[addr >> 12]; return; } if (cr0 >> 31) { - addr64[0] = mmutranslate_write(addr); - if (addr64[0] > 0xffffffffULL) - return; - } else - addr64[0] = (uint64_t) addr; + a = mmutranslate_write(addr); + addr64a[0] = (uint32_t) a; - addr = (uint32_t) (addr64[0] & rammask); + if (a > 0xffffffffULL) + return; + } + + addr = addr64a[0] & rammask; map = write_mapping[addr >> MEM_GRANULARITY_BITS]; @@ -990,7 +1032,7 @@ writememwl(uint32_t addr, uint16_t val) /* Read a word from memory without MMU translation - results of previous MMU translation passed as array. */ uint16_t -readmemwl_no_mmut(uint32_t addr, uint64_t *addr64) +readmemwl_no_mmut(uint32_t addr, uint32_t *a64) { mem_mapping_t *map; @@ -1001,21 +1043,23 @@ readmemwl_no_mmut(uint32_t addr, uint64_t *addr64) cycles -= timing_misaligned; if ((addr & 0xfff) > 0xffe) { if (cr0 >> 31) { - if ((addr64[0] > 0xffffffffULL) || (addr64[1] > 0xffffffffULL)) + if (cpu_state.abrt || high_page) return 0xffff; } - return readmembl_no_mmut(addr, addr64[0]) | - (((uint16_t) readmembl_no_mmut(addr + 1, addr64[1])) << 8); - } else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) + return readmembl_no_mmut(addr, a64[0]) | + (((uint16_t) readmembl_no_mmut(addr + 1, a64[1])) << 8); + } else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) { + mmu_perm = readlookupp[addr >> 12]; return *(uint16_t *)(readlookup2[addr >> 12] + addr); + } } if (cr0 >> 31) { - if (addr64[0] > 0xffffffffULL) + if (cpu_state.abrt || high_page) return 0xffff; - addr = (uint32_t) (addr64[0] & rammask); + addr = (uint32_t) (a64[0] & rammask); } else addr &= rammask; @@ -1035,7 +1079,7 @@ readmemwl_no_mmut(uint32_t addr, uint64_t *addr64) /* Write a word to memory without MMU translation - results of previous MMU translation passed as array. */ void -writememwl_no_mmut(uint32_t addr, uint64_t *addr64, uint16_t val) +writememwl_no_mmut(uint32_t addr, uint32_t *a64, uint16_t val) { mem_mapping_t *map; @@ -1046,30 +1090,31 @@ writememwl_no_mmut(uint32_t addr, uint64_t *addr64, uint16_t val) cycles -= timing_misaligned; if ((addr & 0xfff) > 0xffe) { if (cr0 >> 31) { - if ((addr64[0] > 0xffffffffULL) || (addr64[1] > 0xffffffffULL)) + if (cpu_state.abrt || high_page) return; } - writemembl_no_mmut(addr, addr64[0], val); - writemembl_no_mmut(addr + 1, addr64[1], val >> 8); + writemembl_no_mmut(addr, a64[0], val); + writemembl_no_mmut(addr + 1, a64[1], val >> 8); return; } else if (writelookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) { + mmu_perm = writelookupp[addr >> 12]; *(uint16_t *)(writelookup2[addr >> 12] + addr) = val; return; } - } else - addr &= rammask; + } if (page_lookup[addr >> 12] && page_lookup[addr >> 12]->write_w) { + mmu_perm = page_lookupp[addr >> 12]; page_lookup[addr >> 12]->write_w(addr, val, page_lookup[addr >> 12]); return; } if (cr0 >> 31) { - if (addr64[0] > 0xffffffffULL) + if (cpu_state.abrt || high_page) return; - addr = (uint32_t) (addr64[0] & rammask); + addr = (uint32_t) (a64[0] & rammask); } else addr &= rammask; @@ -1091,47 +1136,62 @@ writememwl_no_mmut(uint32_t addr, uint64_t *addr64, uint16_t val) uint32_t readmemll(uint32_t addr) { - uint64_t addr64[4]; mem_mapping_t *map; int i; + uint64_t a = 0x0000000000000000ULL; for (i = 0; i < 4; i++) - addr64[i] = (uint64_t) (addr + i); + addr64a[i] = (uint64_t) (addr + i); mem_logical_addr = addr; + high_page = 0; + if (addr & 3) { if (!cpu_cyrix_alignment || (addr & 7) > 4) cycles -= timing_misaligned; if ((addr & 0xfff) > 0xffc) { if (cr0 >> 31) { for (i = 0; i < 4; i++) { - if ((i == 0) || !((addr + i) & 0xfff)) - addr64[i] = mmutranslate_read(addr + i); - else - addr64[i] = (addr64[i - 1] & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff)); + if (i == 0) { + a = mmutranslate_read(addr + i); + addr64a[i] = (uint32_t) a; + } else if (!((addr + i) & 0xfff)) { + a = mmutranslate_read(addr + 3); + addr64a[i] = (uint32_t) a; + if (!cpu_state.abrt) { + a = (a & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff)); + addr64a[i] = (uint32_t) a; + } + } else { + a = (a & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff)); + addr64a[i] = (uint32_t) a; + } - if (addr64[i] > 0xffffffffULL) + if (a > 0xffffffffULL) return 0xffff; } } /* No need to waste precious CPU host cycles on mmutranslate's that were already done, just pass their result as a parameter to be used if needed. */ - return readmemwl_no_mmut(addr, addr64) | - (((uint32_t) readmemwl_no_mmut(addr + 2, &(addr64[2]))) << 16); - } else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) + return readmemwl_no_mmut(addr, addr64a) | + (((uint32_t) readmemwl_no_mmut(addr + 2, &(addr64a[2]))) << 16); + } else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) { + mmu_perm = readlookupp[addr >> 12]; return *(uint32_t *)(readlookup2[addr >> 12] + addr); + } } if (cr0 >> 31) { - addr64[0] = mmutranslate_read(addr); - if (addr64[0] > 0xffffffffULL) - return 0xffffffff; - } else - addr64[0] = (uint64_t) addr; + a = mmutranslate_read(addr); + addr64a[0] = (uint32_t) a; - addr = (uint32_t) (addr64[0] & rammask); + if (a > 0xffffffffULL) + return 0xffffffff; + } + + addr = addr64a[0] & rammask; map = read_mapping[addr >> MEM_GRANULARITY_BITS]; @@ -1155,15 +1215,17 @@ readmemll(uint32_t addr) void writememll(uint32_t addr, uint32_t val) { - uint64_t addr64[4]; mem_mapping_t *map; int i; + uint64_t a = 0x0000000000000000ULL; for (i = 0; i < 4; i++) - addr64[i] = (uint64_t) (addr + i); + addr64a[i] = (uint64_t) (addr + i); mem_logical_addr = addr; + high_page = 0; + if (addr & 3) { if (!cpu_cyrix_alignment || (addr & 7) > 4) cycles -= timing_misaligned; @@ -1173,12 +1235,22 @@ writememll(uint32_t addr, uint32_t val) /* Do not translate a page that has a valid lookup, as that is by definition valid and the whole purpose of the lookup is to avoid repeat identical translations. */ if (!page_lookup[(addr + i) >> 12] || !page_lookup[(addr + i) >> 12]->write_b) { - if ((i == 0) || !((addr + i) & 0xfff)) - addr64[i] = mmutranslate_write(addr + i); - else - addr64[i] = (addr64[i - 1] & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff)); + if (i == 0) { + a = mmutranslate_write(addr + i); + addr64a[i] = (uint32_t) a; + } else if (!((addr + i) & 0xfff)) { + a = mmutranslate_write(addr + 3); + addr64a[i] = (uint32_t) a; + if (!cpu_state.abrt) { + a = (a & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff)); + addr64a[i] = (uint32_t) a; + } + } else { + a = (a & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff)); + addr64a[i] = (uint32_t) a; + } - if (addr64[i] > 0xffffffffULL) + if (a > 0xffffffffULL) return; } } @@ -1186,28 +1258,31 @@ writememll(uint32_t addr, uint32_t val) /* No need to waste precious CPU host cycles on mmutranslate's that were already done, just pass their result as a parameter to be used if needed. */ - writememwl_no_mmut(addr, &(addr64[0]), val); - writememwl_no_mmut(addr + 2, &(addr64[2]), val >> 16); + writememwl_no_mmut(addr, &(addr64a[0]), val); + writememwl_no_mmut(addr + 2, &(addr64a[2]), val >> 16); return; } else if (writelookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) { + mmu_perm = writelookupp[addr >> 12]; *(uint32_t *)(writelookup2[addr >> 12] + addr) = val; return; } } if (page_lookup[addr >> 12] && page_lookup[addr >> 12]->write_l) { + mmu_perm = page_lookupp[addr >> 12]; page_lookup[addr >> 12]->write_l(addr, val, page_lookup[addr >> 12]); return; } if (cr0 >> 31) { - addr64[0] = mmutranslate_write(addr); - if (addr64[0] > 0xffffffffULL) - return; - } else - addr64[0] = (uint64_t) addr; + a = mmutranslate_write(addr); + addr64a[0] = (uint32_t) a; - addr = (uint32_t) (addr64[0] & rammask); + if (a > 0xffffffffULL) + return; + } + + addr = addr64a[0] & rammask; map = write_mapping[addr >> MEM_GRANULARITY_BITS]; @@ -1232,8 +1307,9 @@ writememll(uint32_t addr, uint32_t val) /* Read a long from memory without MMU translation - results of previous MMU translation passed as array. */ uint32_t -readmemll_no_mmut(uint32_t addr, uint64_t *addr64) +readmemll_no_mmut(uint32_t addr, uint32_t *a64) { +#ifndef NO_MMUT mem_mapping_t *map; mem_logical_addr = addr; @@ -1243,21 +1319,23 @@ readmemll_no_mmut(uint32_t addr, uint64_t *addr64) cycles -= timing_misaligned; if ((addr & 0xfff) > 0xffc) { if (cr0 >> 31) { - if ((addr64[0] > 0xffffffffULL) || (addr64[3] > 0xffffffffULL)) + if (cpu_state.abrt || high_page) return 0xffffffff; } - return readmemwl_no_mmut(addr, addr64) | - (((uint32_t) readmemwl_no_mmut(addr + 2, &(addr64[2]))) << 16); - } else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) + return readmemwl_no_mmut(addr, a64) | + ((uint32_t) (readmemwl_no_mmut(addr + 2, &(a64[2]))) << 16); + } else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) { + mmu_perm = readlookupp[addr >> 12]; return *(uint32_t *)(readlookup2[addr >> 12] + addr); + } } if (cr0 >> 31) { - if (addr64[0] > 0xffffffffULL) + if (cpu_state.abrt || high_page) return 0xffffffff; - addr = (uint32_t) (addr64[0] & rammask); + addr = (uint32_t) (a64[0] & rammask); } else addr &= rammask; @@ -1277,13 +1355,17 @@ readmemll_no_mmut(uint32_t addr, uint64_t *addr64) ((uint32_t) (map->read_b(addr + 3, map->p)) << 24); return 0xffffffff; +#else + return readmemll(addr); +#endif } /* Write a long to memory without MMU translation - results of previous MMU translation passed as array. */ void -writememll_no_mmut(uint32_t addr, uint64_t *addr64, uint32_t val) +writememll_no_mmut(uint32_t addr, uint32_t *a64, uint32_t val) { +#ifndef NO_MMUT mem_mapping_t *map; mem_logical_addr = addr; @@ -1293,29 +1375,31 @@ writememll_no_mmut(uint32_t addr, uint64_t *addr64, uint32_t val) cycles -= timing_misaligned; if ((addr & 0xfff) > 0xffc) { if (cr0 >> 31) { - if ((addr64[0] > 0xffffffffULL) || (addr64[3] > 0xffffffffULL)) + if (cpu_state.abrt || high_page) return; } - writememwl_no_mmut(addr, &(addr64[0]), val); - writememwl_no_mmut(addr + 2, &(addr64[2]), val >> 16); + writememwl_no_mmut(addr, &(a64[0]), val); + writememwl_no_mmut(addr + 2, &(a64[2]), val >> 16); return; } else if (writelookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) { + mmu_perm = writelookupp[addr >> 12]; *(uint32_t *)(writelookup2[addr >> 12] + addr) = val; return; } } if (page_lookup[addr >> 12] && page_lookup[addr >> 12]->write_l) { + mmu_perm = page_lookupp[addr >> 12]; page_lookup[addr >> 12]->write_l(addr, val, page_lookup[addr >> 12]); return; } if (cr0 >> 31) { - if (addr64[0] > 0xffffffffULL) + if (cpu_state.abrt || high_page) return; - addr = (uint32_t) (addr64[0] & rammask); + addr = (uint32_t) (a64[0] & rammask); } else addr &= rammask; @@ -1337,52 +1421,70 @@ writememll_no_mmut(uint32_t addr, uint64_t *addr64, uint32_t val) map->write_b(addr + 3, val >> 24, map->p); return; } +#else + writememll(addr, val); +#endif } uint64_t readmemql(uint32_t addr) { - uint64_t addr64[8]; mem_mapping_t *map; - int i, wrap_i = 1; + int i; + uint64_t a = 0x0000000000000000ULL; for (i = 0; i < 8; i++) - addr64[i] = (uint64_t) (addr + i); + addr64a[i] = (uint64_t) (addr + i); mem_logical_addr = addr; + high_page = 0; + if (addr & 7) { cycles -= timing_misaligned; if ((addr & 0xfff) > 0xff8) { if (cr0 >> 31) { for (i = 0; i < 8; i++) { - if ((i == 0) || !((addr + i) & 0xfff)) - addr64[i] = mmutranslate_read(addr + i); - else - addr64[i] = (addr64[wrap_i] & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff)); + if (i == 0) { + a = mmutranslate_read(addr + i); + addr64a[i] = (uint32_t) a; + } else if (!((addr + i) & 0xfff)) { + a = mmutranslate_read(addr + 7); + addr64a[i] = (uint32_t) a; + if (!cpu_state.abrt) { + a = (a & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff)); + addr64a[i] = (uint32_t) a; + } + } else { + a = (a & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff)); + addr64a[i] = (uint32_t) a; + } - if (addr64[i] > 0xffffffffULL) + if (a > 0xffffffffULL) return 0xffff; } } /* No need to waste precious CPU host cycles on mmutranslate's that were already done, just pass their result as a parameter to be used if needed. */ - return readmemll_no_mmut(addr, addr64) | - (((uint64_t) readmemll_no_mmut(addr + 4, &(addr64[4]))) << 32); - } else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) + return readmemll_no_mmut(addr, addr64a) | + (((uint64_t) readmemll_no_mmut(addr + 4, &(addr64a[4]))) << 32); + } else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) { + mmu_perm = readlookupp[addr >> 12]; return *(uint64_t *)(readlookup2[addr >> 12] + addr); + } } if (cr0 >> 31) { - addr64[0] = mmutranslate_read(addr); - if (addr64[0] > 0xffffffffULL) - return 0xffffffffffffffffULL; - } else - addr64[0] = (uint64_t) addr; + a = mmutranslate_read(addr); + addr64a[0] = (uint32_t) a; - addr = (uint32_t) (addr64[0] & rammask); + if (a > 0xffffffffULL) + return 0xffffffffffffffffULL; + } + + addr = addr64a[0] & rammask; map = read_mapping[addr >> MEM_GRANULARITY_BITS]; if (map && map->read_l) @@ -1395,15 +1497,17 @@ readmemql(uint32_t addr) void writememql(uint32_t addr, uint64_t val) { - uint64_t addr64[8]; mem_mapping_t *map; int i; + uint64_t a = 0x0000000000000000ULL; for (i = 0; i < 8; i++) - addr64[i] = (uint64_t) (addr + i); + addr64a[i] = (uint64_t) (addr + i); mem_logical_addr = addr; + high_page = 0; + if (addr & 7) { cycles -= timing_misaligned; if ((addr & 0xfff) > 0xff8) { @@ -1412,12 +1516,22 @@ writememql(uint32_t addr, uint64_t val) /* Do not translate a page that has a valid lookup, as that is by definition valid and the whole purpose of the lookup is to avoid repeat identical translations. */ if (!page_lookup[(addr + i) >> 12] || !page_lookup[(addr + i) >> 12]->write_b) { - if ((i == 0) || !((addr + i) & 0xfff)) - addr64[i] = mmutranslate_write(addr + i); - else - addr64[i] = (addr64[i - 1] & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff)); + if (i == 0) { + a = mmutranslate_write(addr + i); + addr64a[i] = (uint32_t) a; + } else if (!((addr + i) & 0xfff)) { + a = mmutranslate_write(addr + 7); + addr64a[i] = (uint32_t) a; + if (!cpu_state.abrt) { + a = (a & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff)); + addr64a[i] = (uint32_t) a; + } + } else { + a = (a & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff)); + addr64a[i] = (uint32_t) a; + } - if (addr64[i] > 0xffffffffULL) + if (addr64a[i] > 0xffffffffULL) return; } } @@ -1425,29 +1539,30 @@ writememql(uint32_t addr, uint64_t val) /* No need to waste precious CPU host cycles on mmutranslate's that were already done, just pass their result as a parameter to be used if needed. */ - writememll_no_mmut(addr, &(addr64[0]), val); - writememll_no_mmut(addr + 4, &(addr64[4]), val >> 32); + writememll_no_mmut(addr, addr64a, val); + writememll_no_mmut(addr + 4, &(addr64a[4]), val >> 32); return; } else if (writelookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) { + mmu_perm = writelookupp[addr >> 12]; *(uint64_t *)(writelookup2[addr >> 12] + addr) = val; return; } } if (page_lookup[addr >> 12] && page_lookup[addr >> 12]->write_l) { + mmu_perm = page_lookupp[addr >> 12]; page_lookup[addr >> 12]->write_l(addr, val, page_lookup[addr >> 12]); page_lookup[addr >> 12]->write_l(addr + 4, val >> 32, page_lookup[addr >> 12]); return; } if (cr0 >> 31) { - addr64[0] = mmutranslate_write(addr); - if (addr64[0] > 0xffffffffULL) + addr64a[0] = mmutranslate_write(addr); + if (addr64a[0] > 0xffffffffULL) return; - } else - addr64[0] = (uint64_t) addr; + } - addr = (uint32_t) (addr64[0] & rammask); + addr = addr64a[0] & rammask; map = write_mapping[addr >> MEM_GRANULARITY_BITS]; @@ -1478,28 +1593,54 @@ writememql(uint32_t addr, uint64_t val) void -do_mmutranslate(uint32_t addr, uint64_t *addr64, int num, int write) +do_mmutranslate(uint32_t addr, uint32_t *a64, int num, int write) { int i, cond = 1; + uint32_t old_addr = addr; + uint64_t a = 0x0000000000000000ULL; + + for (i = 0; i < num; i++) + a64[i] = (uint64_t) addr; for (i = 0; i < num; i++) { - addr64[i] = (uint64_t) addr; - if (cr0 >> 31) { if (write && ((i == 0) || !(addr & 0xfff))) cond = (!page_lookup[addr >> 12] || !page_lookup[addr >> 12]->write_b); if (cond) { + /* If we have encountered at least one page fault, mark all subsequent addresses as + having page faulted, prevents false negatives in readmem*l_no_mmut. */ + if ((i > 0) && cpu_state.abrt && !high_page) + a64[i] = a64[i - 1]; /* If we are on the same page, there is no need to translate again, as we can just reuse the previous result. */ - if ((i == 0) || !(addr & 0xfff)) { - addr64[i] = mmutranslatereal(addr, write); + else if (i == 0) { + a = mmutranslatereal(addr, write); + a64[i] = (uint32_t) a; - if (addr64[i] > 0xffffffffULL) - return; - } else - addr64[i] = (addr64[i - 1] & ~0xfffLL) | ((uint64_t) (addr & 0xfff)); - } + high_page = high_page || (!cpu_state.abrt && (a > 0xffffffffULL)); + + if ((a <= 0xffffffffULL) && pages[addr >> 12].write_b) + write ? addwritelookup(addr, a64[i]) : addreadlookup(addr, a64[i]); + } else if (!(addr & 0xfff)) { + a = mmutranslatereal(old_addr + (num - 1), write); + a64[i] = (uint32_t) a; + + high_page = high_page || (!cpu_state.abrt && (a64[i] > 0xffffffffULL)); + + if (!cpu_state.abrt) { + a = (a & 0xfffffffffffff000ULL) | ((uint64_t) (addr & 0xfff)); + a64[i] = (uint32_t) a; + } + + if ((a <= 0xffffffffULL) && pages[addr >> 12].write_b) + write ? addwritelookup(addr, a64[i]) : addreadlookup(addr, a64[i]); + } else { + a = (a & 0xfffffffffffff000ULL) | ((uint64_t) (addr & 0xfff)); + a64[i] = (uint32_t) a; + } + } else + mmu_perm = page_lookupp[addr >> 12]; } addr++; @@ -2660,6 +2801,7 @@ mem_reset(void) } memset(page_lookup, 0x00, (1 << 20) * sizeof(page_t *)); + memset(page_lookupp, 0x04, (1 << 20) * sizeof(uint8_t)); memset(pages, 0x00, pages_sz*sizeof(page_t)); @@ -2798,8 +2940,11 @@ mem_init(void) /* Allocate the lookup tables. */ page_lookup = (page_t **)malloc((1<<20)*sizeof(page_t *)); + page_lookupp = (uint8_t *)malloc((1<<20)*sizeof(uint8_t)); readlookup2 = malloc((1<<20)*sizeof(uintptr_t)); + readlookupp = malloc((1<<20)*sizeof(uint8_t)); writelookup2 = malloc((1<<20)*sizeof(uintptr_t)); + writelookupp = malloc((1<<20)*sizeof(uint8_t)); } diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index 0a5a6db30..1c9245198 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -616,7 +616,7 @@ MAINOBJ := 86box.o config.o random.o timer.o io.o acpi.o apm.o dma.o ddma.o \ MEMOBJ := catalyst_flash.o i2c_eeprom.o intel_flash.o mem.o rom.o smram.o spd.o sst_flash.o -CPUOBJ := cpu.o cpu_table.o \ +CPUOBJ := cpu.o cpu_table.o fpu.o x86.o \ 808x.o 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o $(CGTOBJ) \ x86seg.o x87.o x87_timings.o \ $(DYNARECOBJ) @@ -876,9 +876,9 @@ all: $(PROG).exe $(PROG).exe: $(OBJ) 86Box.res @echo Linking $(PROG).exe .. @$(CC) $(LDFLAGS) -o $(PROG).exe $(OBJ) 86Box.res $(LIBS) -pipe -#ifneq ($(DEBUG), y) -# @$(STRIP) $(PROG).exe -#endif +ifneq ($(DEBUG), y) + @$(STRIP) $(PROG).exe +endif pcap_if.res: pcap_if.rc @echo Processing $<