From 0cd0d83ceea95321a357b238cb8c8dbc6415fc81 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 13 Jul 2020 01:23:40 +0200 Subject: [PATCH] Both recompilers now check for interrupt after every instruction and exit the block if one has happened. --- src/codegen/codegen_x86-64.c | 16 ++++++++++++++++ src/codegen/codegen_x86.c | 18 ++++++++++++++++++ src/codegen_new/codegen.c | 5 +++++ src/cpu/386_dynarec.c | 17 +++++++++++++++++ src/cpu/cpu.c | 2 -- src/cpu/cpu.h | 2 ++ 6 files changed, 58 insertions(+), 2 deletions(-) diff --git a/src/codegen/codegen_x86-64.c b/src/codegen/codegen_x86-64.c index f674df1e4..960a76c88 100644 --- a/src/codegen/codegen_x86-64.c +++ b/src/codegen/codegen_x86-64.c @@ -1095,6 +1095,14 @@ generate_call: codegen_block_full_ins++; codegen_endpc = (cs + cpu_state.pc) + 8; + /* Check for interrupts. */ + call(block, (uintptr_t)int_check); + + addbyte(0x85); /*OR %eax, %eax*/ + addbyte(0xc0); + addbyte(0x0F); addbyte(0x85); /*JNZ 0*/ + addlong((uint32_t)(uintptr_t)&block->data[BLOCK_EXIT_OFFSET] - (uint32_t)(uintptr_t)(&block->data[block_pos + 4])); + return; } } @@ -1172,6 +1180,14 @@ generate_call: addbyte(0x0F); addbyte(0x85); /*JNZ 0*/ addlong((uint32_t)(uintptr_t)&block->data[BLOCK_EXIT_OFFSET] - (uint32_t)(uintptr_t)(&block->data[block_pos + 4])); + /* Check for interrupts. */ + call(block, (uintptr_t)int_check); + + addbyte(0x85); /*OR %eax, %eax*/ + addbyte(0xc0); + addbyte(0x0F); addbyte(0x85); /*JNZ 0*/ + addlong((uint32_t)(uintptr_t)&block->data[BLOCK_EXIT_OFFSET] - (uint32_t)(uintptr_t)(&block->data[block_pos + 4])); + codegen_endpc = (cs + cpu_state.pc) + 8; } diff --git a/src/codegen/codegen_x86.c b/src/codegen/codegen_x86.c index 44d66b42f..527d2dc06 100644 --- a/src/codegen/codegen_x86.c +++ b/src/codegen/codegen_x86.c @@ -2062,6 +2062,15 @@ generate_call: codegen_block_full_ins++; codegen_endpc = (cs + cpu_state.pc) + 8; + /* Check for interrupts. */ + addbyte(0xE8); /*CALL*/ + addlong(((uint8_t *)int_check - (uint8_t *)(&block->data[block_pos + 4]))); + + addbyte(0x09); /*OR %eax, %eax*/ + addbyte(0xc0); + addbyte(0x0F); addbyte(0x85); /*JNZ 0*/ + addlong((uint32_t)&block->data[BLOCK_EXIT_OFFSET] - (uint32_t)(&block->data[block_pos + 4])); + return; } } @@ -2150,6 +2159,15 @@ generate_call: addbyte(0x0F); addbyte(0x85); /*JNZ 0*/ addlong((uint32_t)&block->data[BLOCK_EXIT_OFFSET] - (uint32_t)(&block->data[block_pos + 4])); + /* Check for interrupts. */ + addbyte(0xE8); /*CALL*/ + addlong(((uint8_t *)int_check - (uint8_t *)(&block->data[block_pos + 4]))); + + addbyte(0x09); /*OR %eax, %eax*/ + addbyte(0xc0); + addbyte(0x0F); addbyte(0x85); /*JNZ 0*/ + addlong((uint32_t)&block->data[BLOCK_EXIT_OFFSET] - (uint32_t)(&block->data[block_pos + 4])); + codegen_endpc = (cs + cpu_state.pc) + 8; } diff --git a/src/codegen_new/codegen.c b/src/codegen_new/codegen.c index 441bb4aa2..50a94b9f8 100644 --- a/src/codegen_new/codegen.c +++ b/src/codegen_new/codegen.c @@ -696,6 +696,9 @@ generate_call: block->ins++; + /* Check for interrupts. */ + uop_CALL_INSTRUCTION_FUNC(ir, int_check); + if (block->ins >= MAX_INSTRUCTION_COUNT) CPU_BLOCK_END(); @@ -756,6 +759,8 @@ generate_call: uop_MOV_IMM(ir, IREG_ssegs, op_ssegs); uop_LOAD_FUNC_ARG_IMM(ir, 0, fetchdat); uop_CALL_INSTRUCTION_FUNC(ir, op); + /* Check for interrupts. */ + uop_CALL_INSTRUCTION_FUNC(ir, int_check); codegen_mark_code_present(block, cs+cpu_state.pc, 8); last_op_32 = op_32; diff --git a/src/cpu/386_dynarec.c b/src/cpu/386_dynarec.c index a07c1b83f..c88e2f124 100644 --- a/src/cpu/386_dynarec.c +++ b/src/cpu/386_dynarec.c @@ -303,6 +303,23 @@ void update_tsc(void) } } +int int_check(void) +{ + if (cpu_state.abrt) + return 1; + + if (trap) + return 1; + else if (smi_line) + return 1; + else if (nmi && nmi_enable && nmi_mask) + return 1; + else if ((cpu_state.flags & I_FLAG) && pic_intpending) + return 1; + + return 0; +} + void exec386_dynarec(int cycs) { int vector; diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index 4a64566ce..71c453878 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -61,8 +61,6 @@ #endif #include "x87_timings.h" -/*#define ENABLE_CPU_LOG 1*/ - static void cpu_write(uint16_t addr, uint8_t val, void *priv); static uint8_t cpu_read(uint16_t addr, void *priv); diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index ea7fc8270..ad500115e 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -601,4 +601,6 @@ extern const char *fpu_get_internal_name(int machine, int cpu_manufacturer, int extern const char *fpu_get_name_from_index(int machine, int cpu_manufacturer, int cpu, int c); extern int fpu_get_type_from_index(int machine, int cpu_manufacturer, int cpu, int c); +extern int int_check(); + #endif /*EMU_CPU_H*/