mirror of
https://github.com/joncampbell123/dosbox-x.git
synced 2025-10-14 02:17:36 +08:00
Merge pull request #2169 from koolkdev/dynamic-core-trap-flag
Handle trap flag after POPF in dynamic cores
This commit is contained in:
@@ -119,7 +119,8 @@ enum BlockReturn {
|
||||
#endif
|
||||
BR_Iret,
|
||||
BR_CallBack,
|
||||
BR_SMCBlock
|
||||
BR_SMCBlock,
|
||||
BR_Trap
|
||||
};
|
||||
|
||||
#define SMC_CURRENT_BLOCK 0xffff
|
||||
@@ -378,6 +379,17 @@ run_block:
|
||||
}
|
||||
}
|
||||
goto restart_core;
|
||||
case BR_Trap:
|
||||
// trapflag is set, switch to the trap-aware decoder
|
||||
#if C_DEBUG
|
||||
#if C_HEAVY_DEBUG
|
||||
if (DEBUG_HeavyIsBreakpoint()) {
|
||||
return debugCallback;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
cpudecoder=CPU_Core_Dyn_X86_Trap_Run;
|
||||
return CBRET_NONE;
|
||||
}
|
||||
return CBRET_NONE;
|
||||
}
|
||||
|
@@ -312,7 +312,7 @@ static INLINE void dyn_set_eip_last(void) {
|
||||
}
|
||||
|
||||
|
||||
enum save_info_type {db_exception, cycle_check, normal, fpu_restore};
|
||||
enum save_info_type {db_exception, cycle_check, normal, fpu_restore, trap};
|
||||
|
||||
|
||||
static struct {
|
||||
@@ -376,6 +376,18 @@ static void dyn_check_irqrequest(void) {
|
||||
used_save_info++;
|
||||
}
|
||||
|
||||
static void dyn_check_trapflag(void) {
|
||||
gen_dop_word_imm(DOP_TEST,true,DREG(FLAGS),FLAG_TF);
|
||||
save_info[used_save_info].branch_pos=gen_create_branch_long(BR_NZ);
|
||||
gen_releasereg(DREG(FLAGS));
|
||||
dyn_savestate(&save_info[used_save_info].state);
|
||||
save_info[used_save_info].cycles=decode.cycles;
|
||||
save_info[used_save_info].eip_change=decode.code-decode.code_start;
|
||||
if (!cpu.code.big) save_info[used_save_info].eip_change&=0xffff;
|
||||
save_info[used_save_info].type=trap;
|
||||
used_save_info++;
|
||||
}
|
||||
|
||||
static void dyn_check_bool_exception_ne(void) {
|
||||
save_info[used_save_info].branch_pos=gen_create_branch_long(BR_Z);
|
||||
dyn_savestate(&save_info[used_save_info].state);
|
||||
@@ -408,6 +420,14 @@ static void dyn_fill_blocks(void) {
|
||||
dyn_save_critical_regs();
|
||||
gen_return(BR_Cycles);
|
||||
break;
|
||||
case trap:
|
||||
dyn_loadstate(&save_info[sct].state);
|
||||
decode.cycles=save_info[sct].cycles;
|
||||
dyn_reduce_cycles();
|
||||
gen_dop_word_imm(DOP_ADD,decode.big_op,DREG(EIP),save_info[sct].eip_change);
|
||||
dyn_save_critical_regs();
|
||||
gen_return(BR_Trap);
|
||||
break;
|
||||
#ifdef X86_DYNFPU_DH_ENABLED
|
||||
case fpu_restore:
|
||||
dyn_loadstate(&save_info[sct].state);
|
||||
@@ -2456,6 +2476,7 @@ restart_prefix:
|
||||
dyn_flags_host_to_gen();
|
||||
gen_releasereg(DREG(TMPB));
|
||||
dyn_check_irqrequest();
|
||||
dyn_check_trapflag();
|
||||
break;
|
||||
/* MOV AL,direct addresses */
|
||||
case 0xa0:
|
||||
|
@@ -91,6 +91,8 @@
|
||||
|
||||
// access to a general register
|
||||
#define DRCD_REG_VAL(reg) (&cpu_regs.regs[reg].dword)
|
||||
// access to the flags register
|
||||
#define DRCD_REG_FLAGS (&cpu_regs.flags)
|
||||
// access to a segment register
|
||||
#define DRCD_SEG_VAL(seg) (&Segs.val[seg])
|
||||
// access to the physical value of a segment register/selector
|
||||
@@ -112,7 +114,8 @@ enum BlockReturn {
|
||||
#endif
|
||||
BR_Iret,
|
||||
BR_CallBack,
|
||||
BR_SMCBlock
|
||||
BR_SMCBlock,
|
||||
BR_Trap
|
||||
};
|
||||
|
||||
// identificator to signal self-modification of the currently executed block
|
||||
@@ -381,6 +384,18 @@ run_block:
|
||||
if (block) goto run_block;
|
||||
break;
|
||||
|
||||
case BR_Trap:
|
||||
// trapflag is set, switch to the trap-aware decoder
|
||||
#if C_DEBUG
|
||||
#if C_HEAVY_DEBUG
|
||||
if (DEBUG_HeavyIsBreakpoint()) {
|
||||
return debugCallback;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
cpudecoder=CPU_Core_Dynrec_Trap_Run;
|
||||
return CBRET_NONE;
|
||||
|
||||
default:
|
||||
E_Exit("Invalid return code %d", ret);
|
||||
}
|
||||
|
@@ -361,6 +361,7 @@ restart_prefix:
|
||||
case 0x9d: // popf
|
||||
gen_call_function_I(CPU_POPF,decode.big_op);
|
||||
dyn_check_exception(FC_RETOP);
|
||||
dyn_check_trapflag();
|
||||
InvalidateFlags();
|
||||
break;
|
||||
|
||||
|
@@ -426,6 +426,8 @@ static void INLINE dyn_get_modrm(void) {
|
||||
#define MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(host_reg, reg_index, high_byte) gen_mov_regbyte_to_reg_low_canuseword(host_reg,(DRC_PTR_SIZE_IM)(DRCD_REG_BYTE(reg_index,high_byte)) - (DRC_PTR_SIZE_IM)(&cpu_regs))
|
||||
#define MOV_REG_BYTE_FROM_HOST_REG_LOW(host_reg, reg_index, high_byte) gen_mov_regbyte_from_reg_low(host_reg,(DRC_PTR_SIZE_IM)(DRCD_REG_BYTE(reg_index,high_byte)) - (DRC_PTR_SIZE_IM)(&cpu_regs))
|
||||
|
||||
#define MOV_FLAGS_TO_HOST_REG(host_reg) gen_mov_regval32_to_reg(host_reg,(DRC_PTR_SIZE_IM)(DRCD_REG_FLAGS) - (DRC_PTR_SIZE_IM)(&cpu_regs))
|
||||
|
||||
#else
|
||||
|
||||
#define MOV_REG_VAL_TO_HOST_REG(host_reg, reg_index) gen_mov_word_to_reg(host_reg,DRCD_REG_VAL(reg_index),true)
|
||||
@@ -443,6 +445,8 @@ static void INLINE dyn_get_modrm(void) {
|
||||
#define MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(host_reg, reg_index, high_byte) gen_mov_byte_to_reg_low_canuseword(host_reg,DRCD_REG_BYTE(reg_index,high_byte))
|
||||
#define MOV_REG_BYTE_FROM_HOST_REG_LOW(host_reg, reg_index, high_byte) gen_mov_byte_from_reg_low(host_reg,DRCD_REG_BYTE(reg_index,high_byte))
|
||||
|
||||
#define MOV_FLAGS_TO_HOST_REG(host_reg) gen_mov_word_to_reg(host_reg,DRCD_REG_FLAGS,true)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -610,7 +614,7 @@ template <typename T> static DRC_PTR_SIZE_IM INLINE gen_call_function_mm(const T
|
||||
|
||||
|
||||
|
||||
enum save_info_type {db_exception, cycle_check, string_break};
|
||||
enum save_info_type {db_exception, cycle_check, string_break, trap};
|
||||
|
||||
|
||||
// function that is called on exceptions
|
||||
@@ -670,6 +674,13 @@ static void dyn_fill_blocks(void) {
|
||||
gen_add_direct_word(®_eip,save_info_dynrec[sct].eip_change,decode.big_op);
|
||||
dyn_return(BR_Cycles);
|
||||
break;
|
||||
case trap:
|
||||
// trapflag is set, switch to trap-aware decoder
|
||||
decode.cycles=save_info_dynrec[sct].cycles;
|
||||
dyn_reduce_cycles();
|
||||
gen_add_direct_word(®_eip,save_info_dynrec[sct].eip_change,decode.big_op);
|
||||
dyn_return(BR_Trap);
|
||||
break;
|
||||
}
|
||||
}
|
||||
used_save_info_dynrec=0;
|
||||
@@ -698,6 +709,19 @@ static void dyn_check_exception(HostReg reg) {
|
||||
}
|
||||
|
||||
|
||||
// check and branch if the trap flag is turned on
|
||||
static void dyn_check_trapflag(void) {
|
||||
MOV_FLAGS_TO_HOST_REG(FC_OP1);
|
||||
gen_and_imm(FC_OP1, FLAG_TF);
|
||||
save_info_dynrec[used_save_info_dynrec].branch_pos=gen_create_branch_long_nonzero(FC_OP1,true);
|
||||
save_info_dynrec[used_save_info_dynrec].cycles=decode.cycles;
|
||||
save_info_dynrec[used_save_info_dynrec].eip_change=decode.code-decode.code_start;
|
||||
if (!cpu.code.big) save_info_dynrec[used_save_info_dynrec].eip_change&=0xffff;
|
||||
save_info_dynrec[used_save_info_dynrec].type=trap;
|
||||
used_save_info_dynrec++;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool DRC_CALL_CONV mem_readb_checked_drc(PhysPt address) DRC_FC;
|
||||
bool DRC_CALL_CONV mem_readb_checked_drc(PhysPt address) {
|
||||
|
Reference in New Issue
Block a user