Perform NULL segment checks upfront in opcode handlers, rather than on every memory access.

This removes the need to pass the segment to readmem*l()/writemem*l().
This commit is contained in:
SarahW 2018-07-18 22:10:18 +01:00
commit 0f0a1c3223
31 changed files with 976 additions and 325 deletions

View file

@ -9,7 +9,8 @@ static int opREP_INSB_ ## size(uint32_t fetchdat)
{ \
uint8_t temp; \
\
check_io_perm(DX); \
SEG_CHECK_WRITE(&_es); \
check_io_perm(DX); \
temp = inb(DX); \
writememb(es, DEST_REG, temp); if (cpu_state.abrt) return 1; \
\
@ -36,6 +37,7 @@ static int opREP_INSW_ ## size(uint32_t fetchdat)
{ \
uint16_t temp; \
\
SEG_CHECK_WRITE(&_es); \
check_io_perm(DX); \
check_io_perm(DX+1); \
temp = inw(DX); \
@ -64,6 +66,7 @@ static int opREP_INSL_ ## size(uint32_t fetchdat)
{ \
uint32_t temp; \
\
SEG_CHECK_WRITE(&_es); \
check_io_perm(DX); \
check_io_perm(DX+1); \
check_io_perm(DX+2); \
@ -93,7 +96,9 @@ static int opREP_OUTSB_ ## size(uint32_t fetchdat)
\
if (CNT_REG > 0) \
{ \
uint8_t temp = readmemb(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \
uint8_t temp; \
SEG_CHECK_READ(cpu_state.ea_seg); \
temp = readmemb(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \
check_io_perm(DX); \
outb(DX, temp); \
if (flags & D_FLAG) SRC_REG--; \
@ -117,7 +122,9 @@ static int opREP_OUTSW_ ## size(uint32_t fetchdat)
\
if (CNT_REG > 0) \
{ \
uint16_t temp = readmemw(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \
uint16_t temp; \
SEG_CHECK_READ(cpu_state.ea_seg); \
temp = readmemw(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \
check_io_perm(DX); \
check_io_perm(DX+1); \
outw(DX, temp); \
@ -142,7 +149,9 @@ static int opREP_OUTSL_ ## size(uint32_t fetchdat)
\
if (CNT_REG > 0) \
{ \
uint32_t temp = readmeml(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \
uint32_t temp; \
SEG_CHECK_READ(cpu_state.ea_seg); \
temp = readmeml(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \
check_io_perm(DX); \
check_io_perm(DX+1); \
check_io_perm(DX+2); \
@ -170,6 +179,11 @@ static int opREP_MOVSB_ ## size(uint32_t fetchdat)
int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \
if (trap) \
cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \
if (CNT_REG > 0) \
{ \
SEG_CHECK_READ(cpu_state.ea_seg); \
SEG_CHECK_WRITE(&_es); \
} \
while (CNT_REG > 0) \
{ \
uint8_t temp; \
@ -203,6 +217,11 @@ static int opREP_MOVSW_ ## size(uint32_t fetchdat)
int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \
if (trap) \
cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \
if (CNT_REG > 0) \
{ \
SEG_CHECK_READ(cpu_state.ea_seg); \
SEG_CHECK_WRITE(&_es); \
} \
while (CNT_REG > 0) \
{ \
uint16_t temp; \
@ -236,6 +255,11 @@ static int opREP_MOVSL_ ## size(uint32_t fetchdat)
int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \
if (trap) \
cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \
if (CNT_REG > 0) \
{ \
SEG_CHECK_READ(cpu_state.ea_seg); \
SEG_CHECK_WRITE(&_es); \
} \
while (CNT_REG > 0) \
{ \
uint32_t temp; \
@ -271,6 +295,8 @@ static int opREP_STOSB_ ## size(uint32_t fetchdat)
int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \
if (trap) \
cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \
if (CNT_REG > 0) \
SEG_CHECK_WRITE(&_es); \
while (CNT_REG > 0) \
{ \
CHECK_WRITE_REP(&_es, DEST_REG, DEST_REG); \
@ -299,6 +325,8 @@ static int opREP_STOSW_ ## size(uint32_t fetchdat)
int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \
if (trap) \
cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \
if (CNT_REG > 0) \
SEG_CHECK_WRITE(&_es); \
while (CNT_REG > 0) \
{ \
CHECK_WRITE_REP(&_es, DEST_REG, DEST_REG+1); \
@ -327,6 +355,8 @@ static int opREP_STOSL_ ## size(uint32_t fetchdat)
int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \
if (trap) \
cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \
if (CNT_REG > 0) \
SEG_CHECK_WRITE(&_es); \
while (CNT_REG > 0) \
{ \
CHECK_WRITE_REP(&_es, DEST_REG, DEST_REG+3); \
@ -356,6 +386,8 @@ static int opREP_LODSB_ ## size(uint32_t fetchdat)
int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \
if (trap) \
cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \
if (CNT_REG > 0) \
SEG_CHECK_READ(cpu_state.ea_seg); \
while (CNT_REG > 0) \
{ \
AL = readmemb(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \
@ -383,6 +415,8 @@ static int opREP_LODSW_ ## size(uint32_t fetchdat)
int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \
if (trap) \
cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \
if (CNT_REG > 0) \
SEG_CHECK_READ(cpu_state.ea_seg); \
while (CNT_REG > 0) \
{ \
AX = readmemw(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \
@ -410,6 +444,8 @@ static int opREP_LODSL_ ## size(uint32_t fetchdat)
int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \
if (trap) \
cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \
if (CNT_REG > 0) \
SEG_CHECK_READ(cpu_state.ea_seg); \
while (CNT_REG > 0) \
{ \
EAX = readmeml(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \
@ -441,8 +477,11 @@ static int opREP_CMPSB_ ## size(uint32_t fetchdat)
tempz = FV; \
if ((CNT_REG > 0) && (FV == tempz)) \
{ \
uint8_t temp = readmemb(cpu_state.ea_seg->base, SRC_REG); \
uint8_t temp2 = readmemb(es, DEST_REG); if (cpu_state.abrt) return 1; \
uint8_t temp, temp2; \
SEG_CHECK_READ(cpu_state.ea_seg); \
SEG_CHECK_READ(&_es); \
temp = readmemb(cpu_state.ea_seg->base, SRC_REG); \
temp2 = readmemb(es, DEST_REG); if (cpu_state.abrt) return 1; \
\
if (flags & D_FLAG) { DEST_REG--; SRC_REG--; } \
else { DEST_REG++; SRC_REG++; } \
@ -468,8 +507,11 @@ static int opREP_CMPSW_ ## size(uint32_t fetchdat)
tempz = FV; \
if ((CNT_REG > 0) && (FV == tempz)) \
{ \
uint16_t temp = readmemw(cpu_state.ea_seg->base, SRC_REG); \
uint16_t temp2 = readmemw(es, DEST_REG); if (cpu_state.abrt) return 1; \
uint16_t temp, temp2; \
SEG_CHECK_READ(cpu_state.ea_seg); \
SEG_CHECK_READ(&_es); \
temp = readmemw(cpu_state.ea_seg->base, SRC_REG); \
temp2 = readmemw(es, DEST_REG); if (cpu_state.abrt) return 1; \
\
if (flags & D_FLAG) { DEST_REG -= 2; SRC_REG -= 2; } \
else { DEST_REG += 2; SRC_REG += 2; } \
@ -495,8 +537,11 @@ static int opREP_CMPSL_ ## size(uint32_t fetchdat)
tempz = FV; \
if ((CNT_REG > 0) && (FV == tempz)) \
{ \
uint32_t temp = readmeml(cpu_state.ea_seg->base, SRC_REG); \
uint32_t temp2 = readmeml(es, DEST_REG); if (cpu_state.abrt) return 1; \
uint32_t temp, temp2; \
SEG_CHECK_READ(cpu_state.ea_seg); \
SEG_CHECK_READ(&_es); \
temp = readmeml(cpu_state.ea_seg->base, SRC_REG); \
temp2 = readmeml(es, DEST_REG); if (cpu_state.abrt) return 1; \
\
if (flags & D_FLAG) { DEST_REG -= 4; SRC_REG -= 4; } \
else { DEST_REG += 4; SRC_REG += 4; } \
@ -523,6 +568,8 @@ static int opREP_SCASB_ ## size(uint32_t fetchdat)
if (trap) \
cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \
tempz = FV; \
if ((CNT_REG > 0) && (FV == tempz)) \
SEG_CHECK_READ(&_es); \
while ((CNT_REG > 0) && (FV == tempz)) \
{ \
uint8_t temp = readmemb(es, DEST_REG); if (cpu_state.abrt) break;\
@ -554,6 +601,8 @@ static int opREP_SCASW_ ## size(uint32_t fetchdat)
if (trap) \
cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \
tempz = FV; \
if ((CNT_REG > 0) && (FV == tempz)) \
SEG_CHECK_READ(&_es); \
while ((CNT_REG > 0) && (FV == tempz)) \
{ \
uint16_t temp = readmemw(es, DEST_REG); if (cpu_state.abrt) break;\
@ -585,6 +634,8 @@ static int opREP_SCASL_ ## size(uint32_t fetchdat)
if (trap) \
cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \
tempz = FV; \
if ((CNT_REG > 0) && (FV == tempz)) \
SEG_CHECK_READ(&_es); \
while ((CNT_REG > 0) && (FV == tempz)) \
{ \
uint32_t temp = readmeml(es, DEST_REG); if (cpu_state.abrt) break;\