Mark some exceptions (mainly v86 related) as 'expected', meaning they
won't cause a code block deletion. This speeds up some v86 code due to a reduction in code block churning.
This commit is contained in:
parent
5a94c78cbb
commit
cccaf86fd3
7 changed files with 39 additions and 13 deletions
|
|
@ -196,7 +196,7 @@ void exec386(int cycs)
|
|||
flags_rebuild();
|
||||
// pclog("Abort\n");
|
||||
// if (CS == 0x228) pclog("Abort at %04X:%04X - %i %i %i\n",CS,pc,notpresent,nullseg,abrt);
|
||||
tempi = cpu_state.abrt;
|
||||
tempi = cpu_state.abrt & ABRT_MASK;
|
||||
cpu_state.abrt = 0;
|
||||
x86_doabrt(tempi);
|
||||
if (cpu_state.abrt)
|
||||
|
|
|
|||
|
|
@ -19,7 +19,10 @@ int checkio(int port);
|
|||
if (cpu_state.abrt) return 1; \
|
||||
if (tempi) \
|
||||
{ \
|
||||
x86gpf(NULL,0); \
|
||||
if (cpu_state.eflags & VM_FLAG) \
|
||||
x86gpf_expected(NULL,0); \
|
||||
else \
|
||||
x86gpf(NULL,0); \
|
||||
return 1; \
|
||||
} \
|
||||
}
|
||||
|
|
|
|||
|
|
@ -462,7 +462,8 @@ static inline void exec_recompiler(void)
|
|||
|
||||
if (cpu_state.abrt)
|
||||
{
|
||||
codegen_block_remove();
|
||||
if (!(cpu_state.abrt & ABRT_EXPECTED))
|
||||
codegen_block_remove();
|
||||
CPU_BLOCK_END();
|
||||
}
|
||||
|
||||
|
|
@ -471,7 +472,7 @@ static inline void exec_recompiler(void)
|
|||
}
|
||||
cpu_end_block_after_ins = 0;
|
||||
|
||||
if (!cpu_state.abrt && !x86_was_reset)
|
||||
if ((!cpu_state.abrt || (cpu_state.abrt & ABRT_EXPECTED)) && !x86_was_reset)
|
||||
codegen_block_end_recompile(block);
|
||||
|
||||
if (x86_was_reset)
|
||||
|
|
@ -540,7 +541,8 @@ static inline void exec_recompiler(void)
|
|||
|
||||
if (cpu_state.abrt)
|
||||
{
|
||||
codegen_block_remove();
|
||||
if (!(cpu_state.abrt & ABRT_EXPECTED))
|
||||
codegen_block_remove();
|
||||
CPU_BLOCK_END();
|
||||
}
|
||||
|
||||
|
|
@ -549,7 +551,8 @@ static inline void exec_recompiler(void)
|
|||
}
|
||||
cpu_end_block_after_ins = 0;
|
||||
|
||||
if (!cpu_state.abrt && !x86_was_reset)
|
||||
// if (!cpu_state.abrt && !x86_was_reset)
|
||||
if ((!cpu_state.abrt || (cpu_state.abrt & ABRT_EXPECTED)) && !x86_was_reset)
|
||||
codegen_block_end();
|
||||
|
||||
if (x86_was_reset)
|
||||
|
|
@ -592,7 +595,7 @@ void exec386_dynarec(int cycs)
|
|||
if (cpu_state.abrt)
|
||||
{
|
||||
flags_rebuild();
|
||||
tempi = cpu_state.abrt;
|
||||
tempi = cpu_state.abrt & ABRT_MASK;
|
||||
cpu_state.abrt = 0;
|
||||
x86_doabrt(tempi);
|
||||
if (cpu_state.abrt)
|
||||
|
|
|
|||
11
src/x86.h
11
src/x86.h
|
|
@ -261,6 +261,16 @@ enum
|
|||
ABRT_PF = 0xE
|
||||
};
|
||||
|
||||
#define ABRT_MASK 0x7f
|
||||
/*An 'expected' exception is one that would be expected to occur on every execution
|
||||
of this code path; eg a GPF due to being in v86 mode. An 'unexpected' exception is
|
||||
one that would be unlikely to occur on the next exception, eg a page fault may be
|
||||
fixed up by the exception handler and the next execution would not hit it.
|
||||
|
||||
This distinction is used by the dynarec; a block that hits an 'expected' exception
|
||||
would be compiled, a block that hits an 'unexpected' exception would be rejected so
|
||||
that we don't end up with an unnecessarily short block*/
|
||||
#define ABRT_EXPECTED 0x80
|
||||
extern uint32_t abrt_error;
|
||||
|
||||
void x86_doabrt(int x86_abrt);
|
||||
|
|
@ -275,6 +285,7 @@ void x86illegal();
|
|||
|
||||
void x86seg_reset();
|
||||
void x86gpf(char *s, uint16_t error);
|
||||
void x86gpf_expected(char *s, uint16_t error);
|
||||
|
||||
void resetx86();
|
||||
void softresetx86();
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ static int opINT(uint32_t fetchdat)
|
|||
}
|
||||
}
|
||||
}
|
||||
x86gpf(NULL,0);
|
||||
x86gpf_expected(NULL,0);
|
||||
return 1;
|
||||
}
|
||||
// /*if (temp == 0x10 && AH == 0xe) */pclog("INT %02X : %04X %04X %04X %04X %c %04X:%04X\n", temp, AX, BX, CX, DX, (AL < 32) ? ' ' : AL, CS, pc);
|
||||
|
|
|
|||
|
|
@ -166,7 +166,7 @@ static int opIRET(uint32_t fetchdat)
|
|||
}
|
||||
else
|
||||
{
|
||||
x86gpf(NULL,0);
|
||||
x86gpf_expected(NULL,0);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
|
@ -214,7 +214,7 @@ static int opIRETD(uint32_t fetchdat)
|
|||
|
||||
if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3))
|
||||
{
|
||||
x86gpf(NULL,0);
|
||||
x86gpf_expected(NULL,0);
|
||||
return 1;
|
||||
}
|
||||
if (msw & 1)
|
||||
|
|
|
|||
15
src/x86seg.c
15
src/x86seg.c
|
|
@ -161,10 +161,16 @@ void x86_doabrt(int x86_abrt)
|
|||
}
|
||||
void x86gpf(char *s, uint16_t error)
|
||||
{
|
||||
// pclog("GPF %04X\n", error);
|
||||
// pclog("GPF %04X %04x(%08x):%08x\n", error, CS,cs,cpu_state.pc);
|
||||
cpu_state.abrt = ABRT_GPF;
|
||||
abrt_error = error;
|
||||
}
|
||||
void x86gpf_expected(char *s, uint16_t error)
|
||||
{
|
||||
// pclog("GPF_v86 %04X %04x(%08x):%08x\n", error, CS,cs,cpu_state.pc);
|
||||
cpu_state.abrt = ABRT_GPF | ABRT_EXPECTED;
|
||||
abrt_error = error;
|
||||
}
|
||||
void x86ss(char *s, uint16_t error)
|
||||
{
|
||||
// pclog("SS %04X\n", error);
|
||||
|
|
@ -1715,8 +1721,11 @@ void pmodeint(int num, int soft)
|
|||
if (output) pclog("Addr %08X seg %04X %04X %04X %04X\n",addr,segdat[0],segdat[1],segdat[2],segdat[3]);
|
||||
if (!(segdat[2]&0x1F00))
|
||||
{
|
||||
//pclog("No seg\n");
|
||||
x86gpf(NULL,(num*8)+2);
|
||||
// pclog("No seg\n");
|
||||
if (cpu_state.eflags & VM_FLAG) /*This fires on all V86 interrupts in EMM386. Mark as expected to prevent code churn*/
|
||||
x86gpf_expected(NULL,(num*8)+2);
|
||||
else
|
||||
x86gpf(NULL,(num*8)+2);
|
||||
return;
|
||||
}
|
||||
if (DPL<CPL && soft)
|
||||
|
|
|
|||
Loading…
Reference in a new issue