From 21c60d5a3e5ff94b5fe0ab189d1306ad3fdcfac3 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 16 Nov 2017 12:53:50 +0100 Subject: [PATCH] Applied the PCem recompile fix commit. --- src/cpu/386_dynarec.c | 6 ++-- src/cpu/codegen_ops_x86-64.h | 56 ++++++++++++++++++------------------ src/cpu/codegen_ops_x86.h | 42 +++++++++++++-------------- src/cpu/codegen_x86-64.c | 6 ++-- src/cpu/codegen_x86.c | 6 ++-- src/cpu/cpu.h | 13 +++++++-- src/cpu/x86_ops_misc.h | 21 +++++++------- src/cpu/x86_ops_mov_ctrl.h | 8 ++++++ src/cpu/x86_ops_pmode.h | 4 +++ src/cpu/x86seg.c | 30 ++++++++++--------- 10 files changed, 111 insertions(+), 81 deletions(-) diff --git a/src/cpu/386_dynarec.c b/src/cpu/386_dynarec.c index b5f7821ed..fefe6868d 100644 --- a/src/cpu/386_dynarec.c +++ b/src/cpu/386_dynarec.c @@ -657,7 +657,8 @@ void exec386_dynarec(int cycs) and physical address. The physical address check will also catch any page faults at this stage*/ valid_block = (block->pc == cs + cpu_state.pc) && (block->_cs == cs) && - (block->phys == phys_addr) && (block->status == cpu_cur_status); + (block->phys == phys_addr) && !((block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) && + ((block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK)); if (!valid_block) { uint64_t mask = (uint64_t)1 << ((phys_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); @@ -669,7 +670,8 @@ void exec386_dynarec(int cycs) if (new_block) { valid_block = (new_block->pc == cs + cpu_state.pc) && (new_block->_cs == cs) && - (new_block->phys == phys_addr) && (new_block->status == cpu_cur_status); + (new_block->phys == phys_addr) && !((new_block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) && + ((new_block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK)); if (valid_block) block = new_block; } diff --git a/src/cpu/codegen_ops_x86-64.h b/src/cpu/codegen_ops_x86-64.h index 773829b1d..fb16d7c74 100644 --- a/src/cpu/codegen_ops_x86-64.h +++ b/src/cpu/codegen_ops_x86-64.h @@ -864,7 +864,7 @@ static inline void CHECK_SEG_READ(x86seg *seg) return; if (seg->checked) return; - if ((seg == &_ds) && codegen_flat_ds) + if (seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) return; if (IS_32_ADDR(&seg->base)) @@ -900,7 +900,7 @@ static inline void CHECK_SEG_WRITE(x86seg *seg) return; if (seg->checked) return; - if ((seg == &_ds) && codegen_flat_ds) + if (seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) return; if (IS_32_ADDR(&seg->base)) @@ -928,7 +928,7 @@ static inline void CHECK_SEG_WRITE(x86seg *seg) } static inline void CHECK_SEG_LIMITS(x86seg *seg, int end_offset) { - if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) return; if (IS_32_ADDR(&seg->base)) @@ -967,7 +967,7 @@ static inline void CHECK_SEG_LIMITS(x86seg *seg, int end_offset) static inline void MEM_LOAD_ADDR_EA_B(x86seg *seg) { - if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR ECX, ECX*/ addbyte(0xc9); @@ -1040,7 +1040,7 @@ static inline void MEM_LOAD_ADDR_EA_B(x86seg *seg) } static inline void MEM_LOAD_ADDR_EA_W(x86seg *seg) { - if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR ECX, ECX*/ addbyte(0xc9); @@ -1126,7 +1126,7 @@ static inline void MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset) } static inline void MEM_LOAD_ADDR_EA_L(x86seg *seg) { - if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR ECX, ECX*/ addbyte(0xc9); @@ -1204,7 +1204,7 @@ static inline void MEM_LOAD_ADDR_EA_L(x86seg *seg) } static inline void MEM_LOAD_ADDR_EA_Q(x86seg *seg) { - if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR ECX, ECX*/ addbyte(0xc9); @@ -1325,7 +1325,7 @@ static inline void MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg) addbyte(8); host_reg = 8; } - if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR ECX, ECX*/ addbyte(0xc9); @@ -1409,7 +1409,7 @@ static inline void MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg) } static inline void MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg) { - if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR ECX, ECX*/ addbyte(0xc9); @@ -1500,7 +1500,7 @@ static inline void MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg) } static inline void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg) { - if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR ECX, ECX*/ addbyte(0xc9); @@ -1589,7 +1589,7 @@ static inline void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg) } static inline void MEM_STORE_ADDR_EA_Q(x86seg *seg, int host_reg, int host_reg2) { - if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR ECX, ECX*/ addbyte(0xc9); @@ -5270,7 +5270,7 @@ static inline void MEM_CHECK_WRITE(x86seg *seg) CHECK_SEG_WRITE(seg); - if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR ESI, ESI*/ addbyte(0xf6); @@ -5321,7 +5321,7 @@ static inline void MEM_CHECK_WRITE(x86seg *seg) addbyte(0xc1); /*SHR EDI, 12*/ addbyte(0xef); addbyte(12); - if (!(seg == &_ds && codegen_flat_ds) && !(seg == &_ss && codegen_flat_ss)) + if (!(seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x83); /*CMP ESI, -1*/ addbyte(0xfe); @@ -5352,7 +5352,7 @@ static inline void MEM_CHECK_WRITE(x86seg *seg) jump2 = &codeblock[block_current].data[block_pos]; addbyte(0); - if (!(seg == &_ds && codegen_flat_ds) && !(seg == &_ss && codegen_flat_ss)) + if (!(seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) *jump3 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump3 - 1; /*slowpath:*/ addbyte(0x67); /*LEA EDI, [EAX+ESI]*/ @@ -5385,7 +5385,7 @@ static inline void MEM_CHECK_WRITE_W(x86seg *seg) CHECK_SEG_WRITE(seg); - if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR ESI, ESI*/ addbyte(0xf6); @@ -5433,7 +5433,7 @@ static inline void MEM_CHECK_WRITE_W(x86seg *seg) addbyte(0x79); /*JNS +*/ jump1 = &codeblock[block_current].data[block_pos]; addbyte(0); - if (!(seg == &_ds && codegen_flat_ds) && !(seg == &_ss && codegen_flat_ss)) + if (!(seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x83); /*CMP ESI, -1*/ addbyte(0xfe); @@ -5442,7 +5442,7 @@ static inline void MEM_CHECK_WRITE_W(x86seg *seg) addbyte(0x8d); /*LEA ESI, 1[EDI]*/ addbyte(0x77); addbyte(0x01); - if (!(seg == &_ds && codegen_flat_ds) && !(seg == &_ss && codegen_flat_ss)) + if (!(seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x74); /*JE slowpath*/ jump4 = &codeblock[block_current].data[block_pos]; @@ -5498,7 +5498,7 @@ static inline void MEM_CHECK_WRITE_W(x86seg *seg) /*slowpath:*/ *jump2 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump2 - 1; - if (!(seg == &_ds && codegen_flat_ds) && !(seg == &_ss && codegen_flat_ss)) + if (!(seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) *jump4 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump4 - 1; jump_pos = block_pos; load_param_1_reg_32(REG_EBX); @@ -5534,7 +5534,7 @@ static inline void MEM_CHECK_WRITE_L(x86seg *seg) CHECK_SEG_WRITE(seg); - if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR ESI, ESI*/ addbyte(0xf6); @@ -5582,7 +5582,7 @@ static inline void MEM_CHECK_WRITE_L(x86seg *seg) addbyte(0x79); /*JNS +*/ jump1 = &codeblock[block_current].data[block_pos]; addbyte(0); - if (!(seg == &_ds && codegen_flat_ds) && !(seg == &_ss && codegen_flat_ss)) + if (!(seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x83); /*CMP ESI, -1*/ addbyte(0xfe); @@ -5591,7 +5591,7 @@ static inline void MEM_CHECK_WRITE_L(x86seg *seg) addbyte(0x8d); /*LEA ESI, 3[EDI]*/ addbyte(0x77); addbyte(0x03); - if (!(seg == &_ds && codegen_flat_ds) && !(seg == &_ss && codegen_flat_ss)) + if (!(seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x74); /*JE slowpath*/ jump4 = &codeblock[block_current].data[block_pos]; @@ -5647,7 +5647,7 @@ static inline void MEM_CHECK_WRITE_L(x86seg *seg) /*slowpath:*/ *jump2 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump2 - 1; - if (!(seg == &_ds && codegen_flat_ds) && !(seg == &_ss && codegen_flat_ss)) + if (!(seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) *jump4 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump4 - 1; jump_pos = block_pos; load_param_1_reg_32(REG_EBX); @@ -5678,7 +5678,7 @@ static inline void MEM_CHECK_WRITE_L(x86seg *seg) static inline int MEM_LOAD_ADDR_EA_B_NO_ABRT(x86seg *seg) { - if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR ECX, ECX*/ addbyte(0xc9); @@ -5750,7 +5750,7 @@ static inline int MEM_LOAD_ADDR_EA_B_NO_ABRT(x86seg *seg) } static inline int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg) { - if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR ECX, ECX*/ addbyte(0xc9); @@ -5828,7 +5828,7 @@ static inline int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg) } static inline int MEM_LOAD_ADDR_EA_L_NO_ABRT(x86seg *seg) { - if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR ECX, ECX*/ addbyte(0xc9); @@ -5928,7 +5928,7 @@ static inline void MEM_STORE_ADDR_EA_B_NO_ABRT(x86seg *seg, int host_reg) addbyte(8); host_reg = 8; } - if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR EBX, EBX*/ addbyte(0xdb); @@ -6005,7 +6005,7 @@ static inline void MEM_STORE_ADDR_EA_B_NO_ABRT(x86seg *seg, int host_reg) } static inline void MEM_STORE_ADDR_EA_W_NO_ABRT(x86seg *seg, int host_reg) { - if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR EBX, EBX*/ addbyte(0xdb); @@ -6089,7 +6089,7 @@ static inline void MEM_STORE_ADDR_EA_W_NO_ABRT(x86seg *seg, int host_reg) } static inline void MEM_STORE_ADDR_EA_L_NO_ABRT(x86seg *seg, int host_reg) { - if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR EBX, EBX*/ addbyte(0xdb); diff --git a/src/cpu/codegen_ops_x86.h b/src/cpu/codegen_ops_x86.h index 9fe64268d..d81ba0dd9 100644 --- a/src/cpu/codegen_ops_x86.h +++ b/src/cpu/codegen_ops_x86.h @@ -618,7 +618,7 @@ static inline void CHECK_SEG_READ(x86seg *seg) return; if (seg->checked) return; - if (seg == &_ds && codegen_flat_ds) + if (seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) return; addbyte(0x83); /*CMP seg->base, -1*/ @@ -641,7 +641,7 @@ static inline void CHECK_SEG_WRITE(x86seg *seg) return; if (seg->checked) return; - if (seg == &_ds && codegen_flat_ds) + if (seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) return; addbyte(0x83); /*CMP seg->base, -1*/ @@ -656,7 +656,7 @@ static inline void CHECK_SEG_WRITE(x86seg *seg) } static inline void CHECK_SEG_LIMITS(x86seg *seg, int end_offset) { - if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) return; addbyte(0x3b); /*CMP EAX, seg->limit_low*/ @@ -684,7 +684,7 @@ static inline void CHECK_SEG_LIMITS(x86seg *seg, int end_offset) static inline void MEM_LOAD_ADDR_EA_B(x86seg *seg) { - if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR EDX, EDX*/ addbyte(0xd2); @@ -702,7 +702,7 @@ static inline void MEM_LOAD_ADDR_EA_B(x86seg *seg) } static inline int MEM_LOAD_ADDR_EA_B_NO_ABRT(x86seg *seg) { - if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR EDX, EDX*/ addbyte(0xd2); @@ -722,7 +722,7 @@ static inline int MEM_LOAD_ADDR_EA_B_NO_ABRT(x86seg *seg) } static inline void MEM_LOAD_ADDR_EA_W(x86seg *seg) { - if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR EDX, EDX*/ addbyte(0xd2); @@ -740,7 +740,7 @@ static inline void MEM_LOAD_ADDR_EA_W(x86seg *seg) } static inline void MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset) { - if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR EDX, EDX*/ addbyte(0xd2); @@ -761,7 +761,7 @@ static inline void MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset) } static inline int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg) { - if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR EDX, EDX*/ addbyte(0xd2); @@ -781,7 +781,7 @@ static inline int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg) } static inline void MEM_LOAD_ADDR_EA_L(x86seg *seg) { - if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR EDX, EDX*/ addbyte(0xd2); @@ -800,7 +800,7 @@ static inline void MEM_LOAD_ADDR_EA_L(x86seg *seg) } static inline int MEM_LOAD_ADDR_EA_L_NO_ABRT(x86seg *seg) { - if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR EDX, EDX*/ addbyte(0xd2); @@ -821,7 +821,7 @@ static inline int MEM_LOAD_ADDR_EA_L_NO_ABRT(x86seg *seg) static inline void MEM_LOAD_ADDR_EA_Q(x86seg *seg) { - if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR EDX, EDX*/ addbyte(0xd2); @@ -859,7 +859,7 @@ static inline void MEM_LOAD_ADDR_IMM_L(x86seg *seg, uint32_t addr) static inline void MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg) { - if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR ESI, ESI*/ addbyte(0xf6); @@ -880,7 +880,7 @@ static inline void MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg) } static inline void MEM_STORE_ADDR_EA_B_NO_ABRT(x86seg *seg, int host_reg) { - if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR ESI, ESI*/ addbyte(0xf6); @@ -901,7 +901,7 @@ static inline void MEM_STORE_ADDR_EA_B_NO_ABRT(x86seg *seg, int host_reg) } static inline void MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg) { - if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR ESI, ESI*/ addbyte(0xf6); @@ -922,7 +922,7 @@ static inline void MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg) } static inline void MEM_STORE_ADDR_EA_W_NO_ABRT(x86seg *seg, int host_reg) { - if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR ESI, ESI*/ addbyte(0xf6); @@ -943,7 +943,7 @@ static inline void MEM_STORE_ADDR_EA_W_NO_ABRT(x86seg *seg, int host_reg) } static inline void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg) { - if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR ESI, ESI*/ addbyte(0xf6); @@ -964,7 +964,7 @@ static inline void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg) } static inline void MEM_STORE_ADDR_EA_L_NO_ABRT(x86seg *seg, int host_reg) { - if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR ESI, ESI*/ addbyte(0xf6); @@ -995,7 +995,7 @@ static inline void MEM_STORE_ADDR_EA_Q(x86seg *seg, int host_reg, int host_reg2) addbyte(0x89); /*MOV ECX, host_reg2*/ addbyte(0xc0 | REG_ECX | (host_reg2 << 3)); } - if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR ESI, ESI*/ addbyte(0xf6); @@ -3919,7 +3919,7 @@ static inline void LOAD_EA() static inline void MEM_CHECK_WRITE(x86seg *seg) { CHECK_SEG_WRITE(seg); - if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR ESI, ESI*/ addbyte(0xf6); @@ -3937,7 +3937,7 @@ static inline void MEM_CHECK_WRITE(x86seg *seg) static inline void MEM_CHECK_WRITE_W(x86seg *seg) { CHECK_SEG_WRITE(seg); - if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR ESI, ESI*/ addbyte(0xf6); @@ -3955,7 +3955,7 @@ static inline void MEM_CHECK_WRITE_W(x86seg *seg) static inline void MEM_CHECK_WRITE_L(x86seg *seg) { CHECK_SEG_WRITE(seg); - if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR ESI, ESI*/ addbyte(0xf6); diff --git a/src/cpu/codegen_x86-64.c b/src/cpu/codegen_x86-64.c index 7d0c8c8f0..e3f5d6c7f 100644 --- a/src/cpu/codegen_x86-64.c +++ b/src/cpu/codegen_x86-64.c @@ -294,6 +294,8 @@ void codegen_block_start_recompile(codeblock_t *block) if (block->pc != cs + cpu_state.pc || block->was_recompiled) fatal("Recompile to used block!\n"); + block->status = cpu_cur_status; + block_pos = BLOCK_GPF_OFFSET; #if WIN64 addbyte(0x48); /*XOR RCX, RCX*/ @@ -377,8 +379,8 @@ void codegen_block_start_recompile(codeblock_t *block) block->was_recompiled = 1; - codegen_flat_ds = cpu_cur_status & CPU_STATUS_FLATDS; - codegen_flat_ss = cpu_cur_status & CPU_STATUS_FLATSS; + codegen_flat_ds = !(cpu_cur_status & CPU_STATUS_NOTFLATDS); + codegen_flat_ss = !(cpu_cur_status & CPU_STATUS_NOTFLATSS); } void codegen_block_remove() diff --git a/src/cpu/codegen_x86.c b/src/cpu/codegen_x86.c index 353fb8bd1..5fdf8b532 100644 --- a/src/cpu/codegen_x86.c +++ b/src/cpu/codegen_x86.c @@ -1415,6 +1415,8 @@ void codegen_block_start_recompile(codeblock_t *block) if (block->pc != cs + cpu_state.pc || block->was_recompiled) fatal("Recompile to used block!\n"); + block->status = cpu_cur_status; + block_pos = BLOCK_GPF_OFFSET; addbyte(0xc7); /*MOV [ESP],0*/ addbyte(0x04); @@ -1472,8 +1474,8 @@ void codegen_block_start_recompile(codeblock_t *block) block->TOP = cpu_state.TOP; block->was_recompiled = 1; - codegen_flat_ds = cpu_cur_status & CPU_STATUS_FLATDS; - codegen_flat_ss = cpu_cur_status & CPU_STATUS_FLATSS; + codegen_flat_ds = !(cpu_cur_status & CPU_STATUS_NOTFLATDS); + codegen_flat_ss = !(cpu_cur_status & CPU_STATUS_NOTFLATSS); } void codegen_block_remove() diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 3df22485e..7236a17ba 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -224,10 +224,19 @@ struct _cpustate_ { uint32_t last_ea; } cpu_state; +/*The flags below must match in both cpu_cur_status and block->status for a block + to be valid*/ #define CPU_STATUS_USE32 (1 << 0) #define CPU_STATUS_STACK32 (1 << 1) -#define CPU_STATUS_FLATDS (1 << 2) -#define CPU_STATUS_FLATSS (1 << 3) +#define CPU_STATUS_PMODE (1 << 2) +#define CPU_STATUS_V86 (1 << 3) +#define CPU_STATUS_FLAGS 0xffff + +/*If the flags below are set in cpu_cur_status, they must be set in block->status. + Otherwise they are ignored*/ +#define CPU_STATUS_NOTFLATDS (1 << 16) +#define CPU_STATUS_NOTFLATSS (1 << 17) +#define CPU_STATUS_MASK 0xffff0000 #ifdef __MSC__ # define COMPILE_TIME_ASSERT(expr) /*nada*/ diff --git a/src/cpu/x86_ops_misc.h b/src/cpu/x86_ops_misc.h index 215f18d19..7448007fb 100644 --- a/src/cpu/x86_ops_misc.h +++ b/src/cpu/x86_ops_misc.h @@ -774,16 +774,16 @@ static int opLOADALL(uint32_t fetchdat) _ss.access = readmemb(0, 0x845); _ss.limit = readmemw(0, 0x846); if (_ss.base == 0 && _ss.limit_low == 0 && _ss.limit_high == 0xffffffff) - cpu_cur_status |= CPU_STATUS_FLATSS; + cpu_cur_status &= ~CPU_STATUS_NOTFLATSS; else - cpu_cur_status &= ~CPU_STATUS_FLATSS; + cpu_cur_status |= CPU_STATUS_NOTFLATSS; ds = readmemw(0, 0x848) | (readmemb(0, 0x84A) << 16); _ds.access = readmemb(0, 0x84B); _ds.limit = readmemw(0, 0x84C); if (_ds.base == 0 && _ds.limit_low == 0 && _ds.limit_high == 0xffffffff) - cpu_cur_status |= CPU_STATUS_FLATDS; + cpu_cur_status &= ~CPU_STATUS_NOTFLATDS; else - cpu_cur_status &= ~CPU_STATUS_FLATDS; + cpu_cur_status |= CPU_STATUS_NOTFLATDS; gdt.base = readmemw(0, 0x84E) | (readmemb(0, 0x850) << 16); gdt.limit = readmemw(0, 0x852); ldt.base = readmemw(0, 0x854) | (readmemb(0, 0x856) << 16); @@ -834,17 +834,16 @@ static void loadall_load_segment(uint32_t addr, x86seg *s) if (s == &_ds) { if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) - - cpu_cur_status |= CPU_STATUS_FLATDS; - else - cpu_cur_status &= ~CPU_STATUS_FLATDS; + cpu_cur_status &= ~CPU_STATUS_NOTFLATDS; + else + cpu_cur_status |= CPU_STATUS_NOTFLATDS; } if (s == &_ss) { if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) - cpu_cur_status |= CPU_STATUS_FLATSS; - else - cpu_cur_status &= ~CPU_STATUS_FLATSS; + cpu_cur_status &= ~CPU_STATUS_NOTFLATSS; + else + cpu_cur_status |= CPU_STATUS_NOTFLATSS; } } diff --git a/src/cpu/x86_ops_mov_ctrl.h b/src/cpu/x86_ops_mov_ctrl.h index 6fa157da4..3a522a652 100644 --- a/src/cpu/x86_ops_mov_ctrl.h +++ b/src/cpu/x86_ops_mov_ctrl.h @@ -131,6 +131,10 @@ static int opMOV_CRx_r_a16(uint32_t fetchdat) cpu_cache_int_enabled = 0; if (is486 && ((cr0 ^ old_cr0) & (1 << 30))) cpu_update_waitstates(); + if (cr0 & 1) + cpu_cur_status |= CPU_STATUS_PMODE; + else + cpu_cur_status &= ~CPU_STATUS_PMODE; break; case 2: cr2 = cpu_state.regs[cpu_rm].l; @@ -183,6 +187,10 @@ static int opMOV_CRx_r_a32(uint32_t fetchdat) cpu_cache_int_enabled = 0; if (is486 && ((cr0 ^ old_cr0) & (1 << 30))) cpu_update_waitstates(); + if (cr0 & 1) + cpu_cur_status |= CPU_STATUS_PMODE; + else + cpu_cur_status &= ~CPU_STATUS_PMODE; break; case 2: cr2 = cpu_state.regs[cpu_rm].l; diff --git a/src/cpu/x86_ops_pmode.h b/src/cpu/x86_ops_pmode.h index 672c569d8..46e324322 100644 --- a/src/cpu/x86_ops_pmode.h +++ b/src/cpu/x86_ops_pmode.h @@ -375,6 +375,10 @@ static int op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32) } else tempw &= 0xF; msw = tempw; + if (msw & 1) + cpu_cur_status |= CPU_STATUS_PMODE; + else + cpu_cur_status &= ~CPU_STATUS_PMODE; PREFETCH_RUN(2, 2, rmdat, 0,0,(cpu_mod == 3) ? 0:1,0, ea32); break; diff --git a/src/cpu/x86seg.c b/src/cpu/x86seg.c index 8da3e8800..c7bb17b2f 100644 --- a/src/cpu/x86seg.c +++ b/src/cpu/x86seg.c @@ -222,16 +222,16 @@ void do_seg_load(x86seg *s, uint16_t *segdat) if (s == &_ds) { if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) - cpu_cur_status |= CPU_STATUS_FLATDS; + cpu_cur_status &= ~CPU_STATUS_NOTFLATDS; else - cpu_cur_status &= ~CPU_STATUS_FLATDS; + cpu_cur_status |= CPU_STATUS_NOTFLATDS; } if (s == &_ss) { if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) - cpu_cur_status |= CPU_STATUS_FLATSS; + cpu_cur_status &= ~CPU_STATUS_NOTFLATSS; else - cpu_cur_status &= ~CPU_STATUS_FLATSS; + cpu_cur_status |= CPU_STATUS_NOTFLATSS; } } @@ -306,7 +306,7 @@ void loadseg(uint16_t seg, x86seg *s) s->access = 0x80; s->base=-1; if (s == &_ds) - cpu_cur_status &= ~CPU_STATUS_FLATDS; + cpu_cur_status |= CPU_STATUS_NOTFLATDS; return; } addr=seg&~7; @@ -418,7 +418,7 @@ void loadseg(uint16_t seg, x86seg *s) s->base = seg << 4; s->seg = seg; if (s == &_ss) - stack32 = 0; + set_stack32(0); s->checked = 1; #ifdef USE_DYNAREC if (s == &_ds) @@ -431,16 +431,16 @@ void loadseg(uint16_t seg, x86seg *s) if (s == &_ds) { if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) - cpu_cur_status |= CPU_STATUS_FLATDS; + cpu_cur_status &= ~CPU_STATUS_NOTFLATDS; else - cpu_cur_status &= ~CPU_STATUS_FLATDS; + cpu_cur_status |= CPU_STATUS_NOTFLATDS; } if (s == &_ss) { if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) - cpu_cur_status |= CPU_STATUS_FLATSS; + cpu_cur_status &= ~CPU_STATUS_NOTFLATSS; else - cpu_cur_status &= ~CPU_STATUS_FLATSS; + cpu_cur_status |= CPU_STATUS_NOTFLATSS; } } @@ -1751,6 +1751,7 @@ void pmodeint(int num, int soft) #endif eflags&=~VM_FLAG; + cpu_cur_status &= ~CPU_STATUS_V86; if (!(type&0x100)) { flags&=~I_FLAG; @@ -1892,11 +1893,12 @@ void pmodeiret(int is32) segs[2]=POPL(); segs[3]=POPL(); if (cpu_state.abrt) { ESP = oldsp; return; } eflags=tempflags>>16; - loadseg(segs[0],&_es); + cpu_cur_status |= CPU_STATUS_V86; + loadseg(segs[0],&_es); do_seg_v86_init(&_es); loadseg(segs[1],&_ds); do_seg_v86_init(&_ds); - cpu_cur_status &= ~CPU_STATUS_FLATDS; + cpu_cur_status |= CPU_STATUS_NOTFLATDS; loadseg(segs[2],&_fs); do_seg_v86_init(&_fs); loadseg(segs[3],&_gs); @@ -1914,7 +1916,7 @@ void pmodeiret(int is32) ESP=newsp; loadseg(newss,&_ss); do_seg_v86_init(&_ss); - cpu_cur_status &= ~CPU_STATUS_FLATSS; + cpu_cur_status |= CPU_STATUS_NOTFLATSS; use32=0; cpu_cur_status &= ~CPU_STATUS_USE32; flags=(tempflags&0xFFD5)|2; @@ -2254,6 +2256,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) { loadcs(new_cs); set_use32(0); + cpu_cur_status |= CPU_STATUS_V86; } else { @@ -2315,6 +2318,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) do_seg_load(&_cs, segdat2); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); set_use32(segdat2[3] & 0x40); + cpu_cur_status &= ~CPU_STATUS_V86; } EAX=new_eax;