Tweak flat DS/SS dynarec optimisation, should reduce block churn when routines are called both with and without flat DS/SS.

Fixed incorrect STACK32 flag when entering V86 mode that was hidden by block churn.
Protected and V86 mode status now considered when selecting block.
This commit is contained in:
SarahW 2017-11-15 21:55:27 +00:00
commit 717d815604
10 changed files with 108 additions and 78 deletions

View file

@ -589,7 +589,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);
@ -601,7 +602,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;
}

View file

@ -869,7 +869,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))
@ -905,7 +905,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))
@ -933,7 +933,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))
@ -972,7 +972,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);
@ -1045,7 +1045,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);
@ -1131,7 +1131,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);
@ -1209,7 +1209,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);
@ -1330,7 +1330,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);
@ -1414,7 +1414,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);
@ -1505,7 +1505,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);
@ -1594,7 +1594,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);
@ -5283,7 +5283,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);
@ -5335,7 +5335,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);
@ -5367,7 +5367,7 @@ static inline void MEM_CHECK_WRITE(x86seg *seg)
addbyte(0);
// addbyte(0xc3); /*RET*/
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]*/
@ -5413,7 +5413,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);
@ -5461,7 +5461,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);
@ -5470,7 +5470,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];
@ -5526,7 +5526,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);
@ -5562,7 +5562,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);
@ -5610,7 +5610,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);
@ -5619,7 +5619,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];
@ -5675,7 +5675,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);
@ -5706,7 +5706,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);
@ -5778,7 +5778,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);
@ -5856,7 +5856,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);
@ -5956,7 +5956,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);
@ -6033,7 +6033,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);
@ -6117,7 +6117,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);

View file

@ -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);
@ -3922,7 +3922,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);
@ -3940,7 +3940,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);
@ -3958,7 +3958,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);

View file

@ -312,6 +312,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*/
@ -397,8 +399,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()

View file

@ -1424,6 +1424,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);
@ -1483,8 +1485,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()

View file

@ -175,11 +175,19 @@ struct
extern uint32_t cpu_cur_status;
/*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
#define COMPILE_TIME_ASSERT(expr) typedef char COMP_TIME_ASSERT[(expr) ? 1 : 0];

View file

@ -762,16 +762,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);
@ -822,16 +822,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;
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;
}
}

View file

@ -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;

View file

@ -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;

View file

@ -229,16 +229,16 @@ static 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;
}
}
@ -321,7 +321,7 @@ void loadseg(uint16_t seg, x86seg *s)
s->access = 0;
s->base=-1;
if (s == &_ds)
cpu_cur_status &= ~CPU_STATUS_FLATDS;
cpu_cur_status |= CPU_STATUS_NOTFLATDS;
// pclog("NULL selector %s%s%s%s %04X(%06X):%06X\n",(s==&_ds)?"DS":"",(s==&_es)?"ES":"",(s==&_fs)?"FS":"",(s==&_gs)?"GS":"",CS,cs,pc);
return;
}
@ -452,7 +452,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;
if (s == &_ds)
codegen_flat_ds = 0;
@ -463,16 +463,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;
}
}
@ -1980,6 +1980,7 @@ void pmodeint(int num, int soft)
#endif
eflags&=~VM_FLAG;
cpu_cur_status &= ~CPU_STATUS_V86;
if (!(type&0x100))
{
flags&=~I_FLAG;
@ -2141,11 +2142,12 @@ void pmodeiret(int is32)
segs[3]=POPL(); if (cpu_state.abrt) { ESP = oldsp; return; }
// pclog("Pop stack %04X:%04X\n",newss,newsp);
eflags=tempflags>>16;
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);
@ -2166,7 +2168,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;
@ -2562,6 +2564,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
{
loadcs(new_cs);
set_use32(0);
cpu_cur_status |= CPU_STATUS_V86;
}
else
{
@ -2631,6 +2634,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;