From ec74ffb6a5a84572ba9d9db627a6bcfabf8377a2 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 15 Jul 2020 05:03:19 +0200 Subject: [PATCH] Old recompiler improvements: limited in-block IRQ checking to floppy IRQ's only, rewrote the GPF handlers in ASM, and changed the recompiled INC and DEC instructions to actually use INC and DEC on host. Also removed the keyboard_at.c timer hack. --- src/codegen/codegen_ops_arith.h | 12 ++++++++---- src/codegen/codegen_ops_x86-64.h | 23 +++++++++++++++++++++++ src/codegen/codegen_ops_x86.h | 19 +++++++++++++++++++ src/codegen/codegen_x86-64.c | 12 ++++++++++++ src/codegen/codegen_x86.c | 11 +++++++++++ src/codegen/codegen_x86.h | 4 ++++ src/device/keyboard_at.c | 6 ------ src/pic.c | 6 ++++-- 8 files changed, 81 insertions(+), 12 deletions(-) diff --git a/src/codegen/codegen_ops_arith.h b/src/codegen/codegen_ops_arith.h index ed2ce1ece..e2eb9baef 100644 --- a/src/codegen/codegen_ops_arith.h +++ b/src/codegen/codegen_ops_arith.h @@ -7,7 +7,8 @@ static uint32_t ropINC_rw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin host_reg = LOAD_REG_W(opcode & 7); STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg); - ADD_HOST_REG_IMM_W(host_reg, 1); + // ADD_HOST_REG_IMM_W(host_reg, 1); + INC_HOST_REG_W(host_reg); STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1); STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_INC16); STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg); @@ -26,7 +27,8 @@ static uint32_t ropINC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin host_reg = LOAD_REG_L(opcode & 7); STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg); - ADD_HOST_REG_IMM(host_reg, 1); + // ADD_HOST_REG_IMM(host_reg, 1); + INC_HOST_REG(host_reg); STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1); STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_INC32); STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); @@ -45,7 +47,8 @@ static uint32_t ropDEC_rw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin host_reg = LOAD_REG_W(opcode & 7); STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg); - SUB_HOST_REG_IMM_W(host_reg, 1); + // SUB_HOST_REG_IMM_W(host_reg, 1); + DEC_HOST_REG_W(host_reg); STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1); STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_DEC16); STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg); @@ -64,7 +67,8 @@ static uint32_t ropDEC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin host_reg = LOAD_REG_L(opcode & 7); STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg); - SUB_HOST_REG_IMM(host_reg, 1); + // SUB_HOST_REG_IMM(host_reg, 1); + DEC_HOST_REG(host_reg); STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1); STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_DEC32); STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); diff --git a/src/codegen/codegen_ops_x86-64.h b/src/codegen/codegen_ops_x86-64.h index 178f0f868..3dae840f5 100644 --- a/src/codegen/codegen_ops_x86-64.h +++ b/src/codegen/codegen_ops_x86-64.h @@ -2967,6 +2967,29 @@ static inline void SUB_HOST_REG_IMM(int host_reg, uint32_t imm) addlong(imm); } +static inline void INC_HOST_REG_W(int host_reg) +{ + addbyte(0x66); /*DECW host_reg*/ + addbyte(0xff); + addbyte(0xc0 | (host_reg & 7)); +} +static inline void INC_HOST_REG(int host_reg) +{ + addbyte(0xff); /*DECL host_reg*/ + addbyte(0xc0 | (host_reg & 7)); +} +static inline void DEC_HOST_REG_W(int host_reg) +{ + addbyte(0x66); /*DECW host_reg*/ + addbyte(0xff); + addbyte(0xc8 | (host_reg & 7)); +} +static inline void DEC_HOST_REG(int host_reg) +{ + addbyte(0xff); /*DECL host_reg*/ + addbyte(0xc8 | (host_reg & 7)); +} + static inline int CMP_HOST_REG_IMM_B(int host_reg, uint8_t imm) { if (host_reg & 8) diff --git a/src/codegen/codegen_ops_x86.h b/src/codegen/codegen_ops_x86.h index 5dcfdef87..737efe03a 100644 --- a/src/codegen/codegen_ops_x86.h +++ b/src/codegen/codegen_ops_x86.h @@ -483,6 +483,25 @@ static inline void SUB_HOST_REG_IMM(int host_reg, uint32_t imm) } } +static inline void INC_HOST_REG_W(int host_reg) +{ + addbyte(0x66); /*DECW host_reg*/ + addbyte(0x40 | host_reg); +} +static inline void INC_HOST_REG(int host_reg) +{ + addbyte(0x40 | host_reg); /*DECL host_reg*/ +} +static inline void DEC_HOST_REG_W(int host_reg) +{ + addbyte(0x66); /*DECW host_reg*/ + addbyte(0x48 | host_reg); +} +static inline void DEC_HOST_REG(int host_reg) +{ + addbyte(0x48 | host_reg); /*DECL host_reg*/ +} + static inline int CMP_HOST_REG_B(int dst_reg, int src_reg) { SUB_HOST_REG_B(dst_reg, src_reg); diff --git a/src/codegen/codegen_x86-64.c b/src/codegen/codegen_x86-64.c index c03d0767c..29de95b6b 100644 --- a/src/codegen/codegen_x86-64.c +++ b/src/codegen/codegen_x86-64.c @@ -294,6 +294,7 @@ void codegen_block_start_recompile(codeblock_t *block) block->status = cpu_cur_status; block_pos = BLOCK_GPF_OFFSET; +#ifdef OLD_GPF #if WIN64 addbyte(0x48); /*XOR RCX, RCX*/ addbyte(0x31); @@ -308,6 +309,17 @@ void codegen_block_start_recompile(codeblock_t *block) addbyte(0xf6); #endif call(block, (uintptr_t)x86gpf); +#else + addbyte(0xc6); /* mov byte ptr[&(cpu_state.abrt)],ABRT_GPF */ + addbyte(0x05); + addlong((uint32_t) (uintptr_t) &(cpu_state.abrt)); + addbyte(ABRT_GPF); + addbyte(0x31); /* xor eax,eax */ + addbyte(0xc0); + addbyte(0x67); /* mov [&(abrt_error)],eax */ + addbyte(0xa3); + addlong((uint32_t) (uintptr_t) &(abrt_error)); +#endif while (block_pos < BLOCK_EXIT_OFFSET) addbyte(0x90); /*NOP*/ block_pos = BLOCK_EXIT_OFFSET; /*Exit code*/ diff --git a/src/codegen/codegen_x86.c b/src/codegen/codegen_x86.c index 0c69e7d71..3415d642b 100644 --- a/src/codegen/codegen_x86.c +++ b/src/codegen/codegen_x86.c @@ -1440,6 +1440,7 @@ void codegen_block_start_recompile(codeblock_t *block) block->status = cpu_cur_status; block_pos = BLOCK_GPF_OFFSET; +#ifdef OLD_GPF addbyte(0xc7); /*MOV [ESP],0*/ addbyte(0x04); addbyte(0x24); @@ -1451,6 +1452,16 @@ void codegen_block_start_recompile(codeblock_t *block) addlong(0); addbyte(0xe8); /*CALL x86gpf*/ addlong((uint32_t)x86gpf - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); +#else + addbyte(0xc6); /* mov byte ptr[&(cpu_state.abrt)],ABRT_GPF */ + addbyte(0x05); + addlong((uint32_t) (uintptr_t) &(cpu_state.abrt)); + addbyte(ABRT_GPF); + addbyte(0x31); /* xor eax,eax */ + addbyte(0xc0); + addbyte(0xa3); /* mov [&(abrt_error)],eax */ + addlong((uint32_t) (uintptr_t) &(abrt_error)); +#endif block_pos = BLOCK_EXIT_OFFSET; /*Exit code*/ addbyte(0x83); /*ADDL $16,%esp*/ addbyte(0xC4); diff --git a/src/codegen/codegen_x86.h b/src/codegen/codegen_x86.h index 3a3662d32..369614329 100644 --- a/src/codegen/codegen_x86.h +++ b/src/codegen/codegen_x86.h @@ -8,7 +8,11 @@ #define HASH(l) ((l) & 0x1ffff) #define BLOCK_EXIT_OFFSET 0x7f0 +#ifdef OLD_GPF #define BLOCK_GPF_OFFSET (BLOCK_EXIT_OFFSET - 20) +#else +#define BLOCK_GPF_OFFSET (BLOCK_EXIT_OFFSET - 14) +#endif #define BLOCK_MAX 1720 diff --git a/src/device/keyboard_at.c b/src/device/keyboard_at.c index e58d9f664..dfcc1947b 100644 --- a/src/device/keyboard_at.c +++ b/src/device/keyboard_at.c @@ -2207,7 +2207,6 @@ kbd_read(uint16_t port, void *priv) { atkbd_t *dev = (atkbd_t *)priv; uint8_t ret = 0xff; - static int flip_flop = 0; if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) sub_cycles(ISA_CYCLES(8)); @@ -2245,11 +2244,6 @@ kbd_read(uint16_t port, void *priv) else ret &= ~0x04; } -#ifdef USE_DYNAREC - flip_flop = (flip_flop + 1) & 0xf; - if (cpu_use_dynarec && (flip_flop == 0xf)) - update_tsc(); -#endif break; case 0x64: diff --git a/src/pic.c b/src/pic.c index 24644ffe3..cd52c7f29 100644 --- a/src/pic.c +++ b/src/pic.c @@ -54,7 +54,7 @@ pic_log(const char *fmt, ...) if (pic_do_log) { va_start(ap, fmt); pclog_ex(fmt, ap); - va_end(ap); +ic_u va_end(ap); } } #else @@ -83,7 +83,9 @@ pic_updatepending() pic_intpending |= temp_pending; } } - pic_pending = !!((cpu_state.flags & I_FLAG) && pic_intpending); + /* This is a variable needed by the compiler to know when to force interpret a block, + only do this for FDC IRQ's. */ + pic_pending = !!((cpu_state.flags & I_FLAG) && (pic_intpending & (1 << 6))); pic_log("pic_intpending = %i %02X %02X %02X %02X\n", pic_intpending, pic.ins, pic.pend, pic.mask, pic.mask2); pic_log(" %02X %02X %02X %02X %i %i\n", pic2.ins, pic2.pend, pic2.mask, pic2.mask2, ((pic.mask | pic.mask2) & (1 << 2)), ((pic2.pend&~pic2.mask)&~pic2.mask2)); }