Reduced number of segment/selector checks in recompiler - minor speedup.
This commit is contained in:
parent
80555e9d2a
commit
51489d031c
4 changed files with 33 additions and 0 deletions
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue