Slight optimisation when DS/SS are 'flat' (base=0, limit=4G).

This commit is contained in:
SarahW 2017-05-24 21:50:37 +01:00
commit 083ca3d4a2
10 changed files with 564 additions and 139 deletions

View file

@ -869,6 +869,10 @@ static inline void CHECK_SEG_READ(x86seg *seg)
return;
if (seg->checked)
return;
if ((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS))
return;
if ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))
return;
if (IS_32_ADDR(&seg->base))
{
@ -903,6 +907,10 @@ static inline void CHECK_SEG_WRITE(x86seg *seg)
return;
if (seg->checked)
return;
if ((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS))
return;
if ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))
return;
if (IS_32_ADDR(&seg->base))
{
@ -929,6 +937,11 @@ static inline void CHECK_SEG_WRITE(x86seg *seg)
}
static inline void CHECK_SEG_LIMITS(x86seg *seg, int end_offset)
{
if ((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS))
return;
if ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))
return;
if (IS_32_ADDR(&seg->base))
{
addbyte(0xb8 | REG_ESI); /*MOV ESI, &addr*/
@ -965,7 +978,13 @@ static inline void CHECK_SEG_LIMITS(x86seg *seg, int end_offset)
static inline void MEM_LOAD_ADDR_EA_B(x86seg *seg)
{
if (IS_32_ADDR(&seg->base))
if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) ||
((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)))
{
addbyte(0x31); /*XOR ECX, ECX*/
addbyte(0xc9);
}
else if (IS_32_ADDR(&seg->base))
{
addbyte(0x8b); /*MOVL ECX, seg->base*/
addbyte(0x0c);
@ -1033,7 +1052,13 @@ static inline void MEM_LOAD_ADDR_EA_B(x86seg *seg)
}
static inline void MEM_LOAD_ADDR_EA_W(x86seg *seg)
{
if (IS_32_ADDR(&seg->base))
if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) ||
((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)))
{
addbyte(0x31); /*XOR ECX, ECX*/
addbyte(0xc9);
}
else if (IS_32_ADDR(&seg->base))
{
addbyte(0x8b); /*MOVL ECX, seg->base*/
addbyte(0x0c);
@ -1117,7 +1142,13 @@ static inline void MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset)
}
static inline void MEM_LOAD_ADDR_EA_L(x86seg *seg)
{
if (IS_32_ADDR(&seg->base))
if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) ||
((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)))
{
addbyte(0x31); /*XOR ECX, ECX*/
addbyte(0xc9);
}
else if (IS_32_ADDR(&seg->base))
{
addbyte(0x8b); /*MOVL ECX, seg->base*/
addbyte(0x0c);
@ -1193,7 +1224,13 @@ static inline void MEM_LOAD_ADDR_EA_L(x86seg *seg)
}
static inline void MEM_LOAD_ADDR_EA_Q(x86seg *seg)
{
if (IS_32_ADDR(&seg->base))
if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) ||
((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)))
{
addbyte(0x31); /*XOR ECX, ECX*/
addbyte(0xc9);
}
else if (IS_32_ADDR(&seg->base))
{
addbyte(0x8b); /*MOVL ECX, seg->base*/
addbyte(0x0c);
@ -1312,7 +1349,13 @@ static inline void MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg)
addbyte(8);
host_reg = 8;
}
if (IS_32_ADDR(&seg->base))
if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) ||
((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)))
{
addbyte(0x31); /*XOR ECX, ECX*/
addbyte(0xc9);
}
else if (IS_32_ADDR(&seg->base))
{
addbyte(0x8b); /*MOVL ECX, seg->base*/
addbyte(0x0c);
@ -1391,7 +1434,13 @@ 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 (IS_32_ADDR(&seg->base))
if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) ||
((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)))
{
addbyte(0x31); /*XOR ECX, ECX*/
addbyte(0xc9);
}
else if (IS_32_ADDR(&seg->base))
{
addbyte(0x8b); /*MOVL ECX, seg->base*/
addbyte(0x0c);
@ -1481,7 +1530,13 @@ 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 (IS_32_ADDR(&seg->base))
if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) ||
((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)))
{
addbyte(0x31); /*XOR ECX, ECX*/
addbyte(0xc9);
}
else if (IS_32_ADDR(&seg->base))
{
addbyte(0x8b); /*MOVL ECX, seg->base*/
addbyte(0x0c);
@ -1569,7 +1624,13 @@ 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 (IS_32_ADDR(&seg->base))
if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) ||
((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)))
{
addbyte(0x31); /*XOR ECX, ECX*/
addbyte(0xc9);
}
else if (IS_32_ADDR(&seg->base))
{
addbyte(0x8b); /*MOVL ECX, seg->base*/
addbyte(0x0c);
@ -5253,11 +5314,17 @@ static inline void LOAD_EA()
static inline void MEM_CHECK_WRITE(x86seg *seg)
{
uint8_t *jump1, *jump2, *jump3;
uint8_t *jump1, *jump2, *jump3 = NULL;
CHECK_SEG_WRITE(seg);
if (IS_32_ADDR(&seg->base))
if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) ||
((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)))
{
addbyte(0x31); /*XOR ESI, ESI*/
addbyte(0xf6);
}
else if (IS_32_ADDR(&seg->base))
{
addbyte(0x8b); /*MOV ESI, seg->base*/
addbyte(0x34);
@ -5304,12 +5371,16 @@ static inline void MEM_CHECK_WRITE(x86seg *seg)
addbyte(0xc1); /*SHR EDI, 12*/
addbyte(0xef);
addbyte(12);
addbyte(0x83); /*CMP ESI, -1*/
addbyte(0xfe);
addbyte(-1);
addbyte(0x74); /*JE slowpath*/
jump3 = &codeblock[block_current].data[block_pos];
addbyte(0);
if (!((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) &&
!((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)))
{
addbyte(0x83); /*CMP ESI, -1*/
addbyte(0xfe);
addbyte(-1);
addbyte(0x74); /*JE slowpath*/
jump3 = &codeblock[block_current].data[block_pos];
addbyte(0);
}
if (IS_32_ADDR(writelookup2))
{
addbyte(0x83); /*CMP writelookup2[RDI*8],-1*/
@ -5333,7 +5404,9 @@ static inline void MEM_CHECK_WRITE(x86seg *seg)
addbyte(0);
// addbyte(0xc3); /*RET*/
*jump3 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump3 - 1;
if (!((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) &&
!((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)))
*jump3 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump3 - 1;
/*slowpath:*/
addbyte(0x67); /*LEA EDI, [EAX+ESI]*/
addbyte(0x8d);
@ -5373,12 +5446,18 @@ static inline void MEM_CHECK_WRITE(x86seg *seg)
static inline void MEM_CHECK_WRITE_W(x86seg *seg)
{
uint8_t *jump1, *jump2, *jump3, *jump4;
uint8_t *jump1, *jump2, *jump3, *jump4 = NULL;
int jump_pos;
CHECK_SEG_WRITE(seg);
if (IS_32_ADDR(&seg->base))
if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) ||
((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)))
{
addbyte(0x31); /*XOR ESI, ESI*/
addbyte(0xf6);
}
else if (IS_32_ADDR(&seg->base))
{
addbyte(0x8b); /*MOV ESI, seg->base*/
addbyte(0x34);
@ -5421,15 +5500,23 @@ static inline void MEM_CHECK_WRITE_W(x86seg *seg)
addbyte(0x79); /*JNS +*/
jump1 = &codeblock[block_current].data[block_pos];
addbyte(0);
addbyte(0x83); /*CMP ESI, -1*/
addbyte(0xfe);
addbyte(-1);
if (!((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) &&
!((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)))
{
addbyte(0x83); /*CMP ESI, -1*/
addbyte(0xfe);
addbyte(-1);
}
addbyte(0x8d); /*LEA ESI, 1[EDI]*/
addbyte(0x77);
addbyte(0x01);
addbyte(0x74); /*JE slowpath*/
jump4 = &codeblock[block_current].data[block_pos];
addbyte(0);
if (!((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) &&
!((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)))
{
addbyte(0x74); /*JE slowpath*/
jump4 = &codeblock[block_current].data[block_pos];
addbyte(0);
}
addbyte(0x89); /*MOV EBX, EDI*/
addbyte(0xfb);
addbyte(0xc1); /*SHR EDI, 12*/
@ -5480,7 +5567,9 @@ static inline void MEM_CHECK_WRITE_W(x86seg *seg)
/*slowpath:*/
*jump2 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump2 - 1;
*jump4 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump4 - 1;
if (!((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) &&
!((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)))
*jump4 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump4 - 1;
jump_pos = block_pos;
load_param_1_reg_32(REG_EBX);
load_param_2_32(&codeblock[block_current], 1);
@ -5510,12 +5599,18 @@ static inline void MEM_CHECK_WRITE_W(x86seg *seg)
static inline void MEM_CHECK_WRITE_L(x86seg *seg)
{
uint8_t *jump1, *jump2, *jump3, *jump4;
uint8_t *jump1, *jump2, *jump3, *jump4 = NULL;
int jump_pos;
CHECK_SEG_WRITE(seg);
if (IS_32_ADDR(&seg->base))
if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) ||
((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)))
{
addbyte(0x31); /*XOR ESI, ESI*/
addbyte(0xf6);
}
else if (IS_32_ADDR(&seg->base))
{
addbyte(0x8b); /*MOV ESI, seg->base*/
addbyte(0x34);
@ -5558,15 +5653,23 @@ static inline void MEM_CHECK_WRITE_L(x86seg *seg)
addbyte(0x79); /*JNS +*/
jump1 = &codeblock[block_current].data[block_pos];
addbyte(0);
addbyte(0x83); /*CMP ESI, -1*/
addbyte(0xfe);
addbyte(-1);
if (!((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) &&
!((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)))
{
addbyte(0x83); /*CMP ESI, -1*/
addbyte(0xfe);
addbyte(-1);
}
addbyte(0x8d); /*LEA ESI, 3[EDI]*/
addbyte(0x77);
addbyte(0x03);
addbyte(0x74); /*JE slowpath*/
jump4 = &codeblock[block_current].data[block_pos];
addbyte(0);
if (!((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) &&
!((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)))
{
addbyte(0x74); /*JE slowpath*/
jump4 = &codeblock[block_current].data[block_pos];
addbyte(0);
}
addbyte(0x89); /*MOV EBX, EDI*/
addbyte(0xfb);
addbyte(0xc1); /*SHR EDI, 12*/
@ -5617,7 +5720,9 @@ static inline void MEM_CHECK_WRITE_L(x86seg *seg)
/*slowpath:*/
*jump2 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump2 - 1;
*jump4 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump4 - 1;
if (!((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) &&
!((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)))
*jump4 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump4 - 1;
jump_pos = block_pos;
load_param_1_reg_32(REG_EBX);
load_param_2_32(&codeblock[block_current], 1);
@ -5647,7 +5752,13 @@ static inline void MEM_CHECK_WRITE_L(x86seg *seg)
static inline int MEM_LOAD_ADDR_EA_B_NO_ABRT(x86seg *seg)
{
if (IS_32_ADDR(&seg->base))
if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) ||
((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)))
{
addbyte(0x31); /*XOR ECX, ECX*/
addbyte(0xc9);
}
else if (IS_32_ADDR(&seg->base))
{
addbyte(0x8b); /*MOVL ECX, seg->base*/
addbyte(0x0c);
@ -5714,7 +5825,13 @@ 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 (IS_32_ADDR(&seg->base))
if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) ||
((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)))
{
addbyte(0x31); /*XOR ECX, ECX*/
addbyte(0xc9);
}
else if (IS_32_ADDR(&seg->base))
{
addbyte(0x8b); /*MOVL ECX, seg->base*/
addbyte(0x0c);
@ -5790,7 +5907,13 @@ 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 (IS_32_ADDR(&seg->base))
if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) ||
((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)))
{
addbyte(0x31); /*XOR ECX, ECX*/
addbyte(0xc9);
}
else if (IS_32_ADDR(&seg->base))
{
addbyte(0x8b); /*MOVL ECX, seg->base*/
addbyte(0x0c);
@ -5888,7 +6011,13 @@ static inline void MEM_STORE_ADDR_EA_B_NO_ABRT(x86seg *seg, int host_reg)
addbyte(8);
host_reg = 8;
}
if (IS_32_ADDR(&seg->base))
if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) ||
((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)))
{
addbyte(0x31); /*XOR EBX, EBX*/
addbyte(0xdb);
}
else if (IS_32_ADDR(&seg->base))
{
addbyte(0x8b); /*MOVL EBX, seg->base*/
addbyte(0x1c);
@ -5960,7 +6089,13 @@ 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 (IS_32_ADDR(&seg->base))
if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) ||
((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)))
{
addbyte(0x31); /*XOR EBX, EBX*/
addbyte(0xdb);
}
else if (IS_32_ADDR(&seg->base))
{
addbyte(0x8b); /*MOVL EBX, seg->base*/
addbyte(0x1c);
@ -6043,7 +6178,13 @@ 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 (IS_32_ADDR(&seg->base))
if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) ||
((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)))
{
addbyte(0x31); /*XOR EBX, EBX*/
addbyte(0xdb);
}
else if (IS_32_ADDR(&seg->base))
{
addbyte(0x8b); /*MOVL EBX, seg->base*/
addbyte(0x1c);