Reduced number of segment/selector checks in recompiler - minor speedup.

This commit is contained in:
TomW 2015-07-08 20:40:37 +01:00
commit 51489d031c
4 changed files with 33 additions and 0 deletions

View file

@ -462,6 +462,15 @@ static void SAR_L_IMM(int reg, int count)
static void CHECK_SEG_READ(x86seg *seg)
{
/*Segments always valid in real/V86 mode*/
if (!(cr0 & 1) || (eflags & VM_FLAG))
return;
/*CS and SS must always be valid*/
if (seg == &_cs || seg == &_ss)
return;
if (seg->checked)
return;
addbyte(0x83); /*CMP seg->base, -1*/
addbyte(0x05|0x38);
addlong((uint32_t)&seg->base);
@ -469,9 +478,20 @@ static void CHECK_SEG_READ(x86seg *seg)
addbyte(0x0f);
addbyte(0x84); /*JE end*/
addlong(BLOCK_EXIT_OFFSET - (block_pos + 4));
seg->checked = 1;
}
static void CHECK_SEG_WRITE(x86seg *seg)
{
/*Segments always valid in real/V86 mode*/
if (!(cr0 & 1) || (eflags & VM_FLAG))
return;
/*CS and SS must always be valid*/
if (seg == &_cs || seg == &_ss)
return;
if (seg->checked)
return;
addbyte(0x83); /*CMP seg->base, -1*/
addbyte(0x05|0x38);
addlong((uint32_t)&seg->base);
@ -479,6 +499,8 @@ static void CHECK_SEG_WRITE(x86seg *seg)
addbyte(0x0f);
addbyte(0x84); /*JE end*/
addlong(BLOCK_EXIT_OFFSET - (block_pos + 4));
seg->checked = 1;
}
static void CHECK_SEG_LIMITS(x86seg *seg, int end_offset)
{

View file

@ -261,6 +261,8 @@ void codegen_block_init(uint32_t phys_addr)
codegen_fpu_loaded_iq[0] = codegen_fpu_loaded_iq[1] = codegen_fpu_loaded_iq[2] = codegen_fpu_loaded_iq[3] =
codegen_fpu_loaded_iq[4] = codegen_fpu_loaded_iq[5] = codegen_fpu_loaded_iq[6] = codegen_fpu_loaded_iq[7] = 0;
_ds.checked = _es.checked = _fs.checked = _gs.checked = (cr0 & 1) ? 0 : 1;
}
void codegen_block_remove()

View file

@ -114,6 +114,9 @@ typedef struct
uint8_t access;
uint16_t seg;
uint32_t limit_low, limit_high;
#ifdef DYNAREC
int checked; /*Non-zero if selector is known to be valid*/
#endif
} x86seg;
x86seg gdt,ldt,idt,tr;

View file

@ -395,6 +395,9 @@ void loadseg(uint16_t seg, x86seg *s)
#endif
#ifndef CS_ACCESSED
}
#endif
#ifdef DYNAREC
s->checked = 0;
#endif
}
else
@ -404,6 +407,9 @@ void loadseg(uint16_t seg, x86seg *s)
s->seg = seg;
if (s == &_ss)
stack32 = 0;
#ifdef DYNAREC
s->checked = 1;
#endif
}
}