continue handlers-chaining optimization: update time once per trace and not for every instruction
This commit is contained in:
parent
e000b61cfd
commit
96cedbc756
@ -77,6 +77,7 @@ void BX_CPU_C::cpu_loop(Bit32u max_instr_count)
|
|||||||
if (setjmp(BX_CPU_THIS_PTR jmp_buf_env)) {
|
if (setjmp(BX_CPU_THIS_PTR jmp_buf_env)) {
|
||||||
// can get here only from exception function or VMEXIT
|
// can get here only from exception function or VMEXIT
|
||||||
BX_TICK1_IF_SINGLE_PROCESSOR();
|
BX_TICK1_IF_SINGLE_PROCESSOR();
|
||||||
|
BX_SYNC_TIME();
|
||||||
#if BX_DEBUGGER || BX_GDBSTUB
|
#if BX_DEBUGGER || BX_GDBSTUB
|
||||||
if (dbg_instruction_epilog()) return;
|
if (dbg_instruction_epilog()) return;
|
||||||
#endif
|
#endif
|
||||||
@ -124,6 +125,8 @@ void BX_CPU_C::cpu_loop(Bit32u max_instr_count)
|
|||||||
// when handlers chaining is enabled this single call will execute entire trace
|
// when handlers chaining is enabled this single call will execute entire trace
|
||||||
BX_CPU_CALL_METHOD(i->execute, (i)); // might iterate repeat instruction
|
BX_CPU_CALL_METHOD(i->execute, (i)); // might iterate repeat instruction
|
||||||
|
|
||||||
|
BX_SYNC_TIME();
|
||||||
|
|
||||||
if (BX_CPU_THIS_PTR async_event) {
|
if (BX_CPU_THIS_PTR async_event) {
|
||||||
// clear stop trace magic indication that probably was set by repeat or branch32/64
|
// clear stop trace magic indication that probably was set by repeat or branch32/64
|
||||||
BX_CPU_THIS_PTR async_event &= ~BX_ASYNC_EVENT_STOP_TRACE;
|
BX_CPU_THIS_PTR async_event &= ~BX_ASYNC_EVENT_STOP_TRACE;
|
||||||
@ -226,6 +229,7 @@ void BX_CPP_AttrRegparmN(2) BX_CPU_C::repeat(bxInstruction_c *i, BxRepIterationP
|
|||||||
break; // exit always if debugger enabled
|
break; // exit always if debugger enabled
|
||||||
|
|
||||||
BX_TICK1_IF_SINGLE_PROCESSOR();
|
BX_TICK1_IF_SINGLE_PROCESSOR();
|
||||||
|
BX_SYNC_TIME();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -245,6 +249,7 @@ void BX_CPP_AttrRegparmN(2) BX_CPU_C::repeat(bxInstruction_c *i, BxRepIterationP
|
|||||||
break; // exit always if debugger enabled
|
break; // exit always if debugger enabled
|
||||||
|
|
||||||
BX_TICK1_IF_SINGLE_PROCESSOR();
|
BX_TICK1_IF_SINGLE_PROCESSOR();
|
||||||
|
BX_SYNC_TIME();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else // 16bit addrsize
|
else // 16bit addrsize
|
||||||
@ -263,6 +268,7 @@ void BX_CPP_AttrRegparmN(2) BX_CPU_C::repeat(bxInstruction_c *i, BxRepIterationP
|
|||||||
break; // exit always if debugger enabled
|
break; // exit always if debugger enabled
|
||||||
|
|
||||||
BX_TICK1_IF_SINGLE_PROCESSOR();
|
BX_TICK1_IF_SINGLE_PROCESSOR();
|
||||||
|
BX_SYNC_TIME();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -307,6 +313,7 @@ void BX_CPP_AttrRegparmN(2) BX_CPU_C::repeat_ZF(bxInstruction_c *i, BxRepIterati
|
|||||||
break; // exit always if debugger enabled
|
break; // exit always if debugger enabled
|
||||||
|
|
||||||
BX_TICK1_IF_SINGLE_PROCESSOR();
|
BX_TICK1_IF_SINGLE_PROCESSOR();
|
||||||
|
BX_SYNC_TIME();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -326,6 +333,7 @@ void BX_CPP_AttrRegparmN(2) BX_CPU_C::repeat_ZF(bxInstruction_c *i, BxRepIterati
|
|||||||
break; // exit always if debugger enabled
|
break; // exit always if debugger enabled
|
||||||
|
|
||||||
BX_TICK1_IF_SINGLE_PROCESSOR();
|
BX_TICK1_IF_SINGLE_PROCESSOR();
|
||||||
|
BX_SYNC_TIME();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else // 16bit addrsize
|
else // 16bit addrsize
|
||||||
@ -344,6 +352,7 @@ void BX_CPP_AttrRegparmN(2) BX_CPU_C::repeat_ZF(bxInstruction_c *i, BxRepIterati
|
|||||||
break; // exit always if debugger enabled
|
break; // exit always if debugger enabled
|
||||||
|
|
||||||
BX_TICK1_IF_SINGLE_PROCESSOR();
|
BX_TICK1_IF_SINGLE_PROCESSOR();
|
||||||
|
BX_SYNC_TIME();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -364,6 +373,7 @@ void BX_CPP_AttrRegparmN(2) BX_CPU_C::repeat_ZF(bxInstruction_c *i, BxRepIterati
|
|||||||
break; // exit always if debugger enabled
|
break; // exit always if debugger enabled
|
||||||
|
|
||||||
BX_TICK1_IF_SINGLE_PROCESSOR();
|
BX_TICK1_IF_SINGLE_PROCESSOR();
|
||||||
|
BX_SYNC_TIME();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -383,6 +393,7 @@ void BX_CPP_AttrRegparmN(2) BX_CPU_C::repeat_ZF(bxInstruction_c *i, BxRepIterati
|
|||||||
break; // exit always if debugger enabled
|
break; // exit always if debugger enabled
|
||||||
|
|
||||||
BX_TICK1_IF_SINGLE_PROCESSOR();
|
BX_TICK1_IF_SINGLE_PROCESSOR();
|
||||||
|
BX_SYNC_TIME();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else // 16bit addrsize
|
else // 16bit addrsize
|
||||||
@ -401,6 +412,7 @@ void BX_CPP_AttrRegparmN(2) BX_CPU_C::repeat_ZF(bxInstruction_c *i, BxRepIterati
|
|||||||
break; // exit always if debugger enabled
|
break; // exit always if debugger enabled
|
||||||
|
|
||||||
BX_TICK1_IF_SINGLE_PROCESSOR();
|
BX_TICK1_IF_SINGLE_PROCESSOR();
|
||||||
|
BX_SYNC_TIME();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -858,9 +858,12 @@ public: // for now...
|
|||||||
bx_address prev_rsp;
|
bx_address prev_rsp;
|
||||||
bx_bool speculative_rsp;
|
bx_bool speculative_rsp;
|
||||||
|
|
||||||
#if BX_DEBUGGER
|
#if BX_DEBUGGER || BX_SUPPORT_HANDLERS_CHAINING_SPEEDUPS
|
||||||
Bit64u icount;
|
Bit64u icount;
|
||||||
#endif
|
#endif
|
||||||
|
#if BX_SUPPORT_HANDLERS_CHAINING_SPEEDUPS
|
||||||
|
Bit64u icount_last_sync;
|
||||||
|
#endif
|
||||||
|
|
||||||
#define BX_INHIBIT_INTERRUPTS 0x01
|
#define BX_INHIBIT_INTERRUPTS 0x01
|
||||||
#define BX_INHIBIT_DEBUG 0x02
|
#define BX_INHIBIT_DEBUG 0x02
|
||||||
@ -3667,7 +3670,7 @@ public: // for now...
|
|||||||
BX_SMF BX_CPP_INLINE int bx_cpuid_support_rdtscp(void);
|
BX_SMF BX_CPP_INLINE int bx_cpuid_support_rdtscp(void);
|
||||||
|
|
||||||
BX_SMF BX_CPP_INLINE unsigned which_cpu(void) { return BX_CPU_THIS_PTR bx_cpuid; }
|
BX_SMF BX_CPP_INLINE unsigned which_cpu(void) { return BX_CPU_THIS_PTR bx_cpuid; }
|
||||||
#if BX_DEBUGGER
|
#if BX_DEBUGGER || BX_SUPPORT_HANDLERS_CHAINING_SPEEDUPS
|
||||||
BX_SMF BX_CPP_INLINE Bit64u get_icount(void) { return BX_CPU_THIS_PTR icount; }
|
BX_SMF BX_CPP_INLINE Bit64u get_icount(void) { return BX_CPU_THIS_PTR icount; }
|
||||||
#endif
|
#endif
|
||||||
BX_SMF BX_CPP_INLINE const bx_gen_reg_t *get_gen_regfile() { return BX_CPU_THIS_PTR gen_reg; }
|
BX_SMF BX_CPP_INLINE const bx_gen_reg_t *get_gen_regfile() { return BX_CPU_THIS_PTR gen_reg; }
|
||||||
|
@ -358,7 +358,7 @@ void BX_CPU_C::register_state(void)
|
|||||||
BXRS_HEX_PARAM_SIMPLE(cpu, activity_state);
|
BXRS_HEX_PARAM_SIMPLE(cpu, activity_state);
|
||||||
BXRS_HEX_PARAM_SIMPLE(cpu, inhibit_mask);
|
BXRS_HEX_PARAM_SIMPLE(cpu, inhibit_mask);
|
||||||
BXRS_HEX_PARAM_SIMPLE(cpu, debug_trap);
|
BXRS_HEX_PARAM_SIMPLE(cpu, debug_trap);
|
||||||
#if BX_DEBUGGER
|
#if BX_DEBUGGER || BX_SUPPORT_HANDLERS_CHAINING_SPEEDUPS
|
||||||
BXRS_DEC_PARAM_SIMPLE(cpu, icount);
|
BXRS_DEC_PARAM_SIMPLE(cpu, icount);
|
||||||
#endif
|
#endif
|
||||||
#if BX_SUPPORT_X86_64
|
#if BX_SUPPORT_X86_64
|
||||||
@ -773,8 +773,12 @@ void BX_CPU_C::reset(unsigned source)
|
|||||||
// status and control flags register set
|
// status and control flags register set
|
||||||
setEFlags(0x2); // Bit1 is always set
|
setEFlags(0x2); // Bit1 is always set
|
||||||
|
|
||||||
#if BX_DEBUGGER
|
#if BX_DEBUGGER || BX_SUPPORT_HANDLERS_CHAINING_SPEEDUPS
|
||||||
BX_CPU_THIS_PTR icount = 0;
|
if (source == BX_RESET_HARDWARE)
|
||||||
|
BX_CPU_THIS_PTR icount = 0;
|
||||||
|
#endif
|
||||||
|
#if BX_SUPPORT_HANDLERS_CHAINING_SPEEDUPS
|
||||||
|
BX_CPU_THIS_PTR icount_last_sync = BX_CPU_THIS_PTR icount;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
BX_CPU_THIS_PTR inhibit_mask = 0;
|
BX_CPU_THIS_PTR inhibit_mask = 0;
|
||||||
|
@ -28,11 +28,19 @@ class bxInstruction_c;
|
|||||||
|
|
||||||
typedef void BX_INSF_TYPE;
|
typedef void BX_INSF_TYPE;
|
||||||
|
|
||||||
#define BX_TICK1_IF_SINGLE_PROCESSOR() \
|
|
||||||
if (BX_SMP_PROCESSORS == 1) BX_TICK1()
|
|
||||||
|
|
||||||
#if BX_SUPPORT_HANDLERS_CHAINING_SPEEDUPS
|
#if BX_SUPPORT_HANDLERS_CHAINING_SPEEDUPS
|
||||||
|
|
||||||
|
#define BX_TICK1_IF_SINGLE_PROCESSOR() \
|
||||||
|
BX_CPU_THIS_PTR icount++;
|
||||||
|
|
||||||
|
#define BX_SYNC_TIME() { \
|
||||||
|
Bit32s delta = BX_CPU_THIS_PTR icount - BX_CPU_THIS_PTR icount_last_sync; \
|
||||||
|
if (delta > 0) { \
|
||||||
|
BX_CPU_THIS_PTR icount_last_sync = BX_CPU_THIS_PTR icount; \
|
||||||
|
BX_TICKN(delta); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
#define BX_COMMIT_INSTRUCTION(i) { \
|
#define BX_COMMIT_INSTRUCTION(i) { \
|
||||||
BX_CPU_THIS_PTR prev_rip = RIP; /* commit new RIP */ \
|
BX_CPU_THIS_PTR prev_rip = RIP; /* commit new RIP */ \
|
||||||
BX_INSTR_AFTER_EXECUTION(BX_CPU_ID, (i)); \
|
BX_INSTR_AFTER_EXECUTION(BX_CPU_ID, (i)); \
|
||||||
@ -62,6 +70,11 @@ typedef void BX_INSF_TYPE;
|
|||||||
#define BX_NEXT_TRACE(i) { return; }
|
#define BX_NEXT_TRACE(i) { return; }
|
||||||
#define BX_NEXT_INSTR(i) { return; }
|
#define BX_NEXT_INSTR(i) { return; }
|
||||||
|
|
||||||
|
#define BX_TICK1_IF_SINGLE_PROCESSOR() \
|
||||||
|
if (BX_SMP_PROCESSORS == 1) BX_TICK1()
|
||||||
|
|
||||||
|
#define BX_SYNC_TIME() /* do nothing */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// <TAG-TYPE-EXECUTEPTR-START>
|
// <TAG-TYPE-EXECUTEPTR-START>
|
||||||
|
@ -480,6 +480,8 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::RDTSC(bxInstruction_c *i)
|
|||||||
RAX = GET32L(ticks);
|
RAX = GET32L(ticks);
|
||||||
RDX = GET32H(ticks);
|
RDX = GET32H(ticks);
|
||||||
|
|
||||||
|
BX_DEBUG(("RDTSC: ticks 0x%08x:%08x", EDX, EAX));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
BX_ERROR(("RDTSC: not allowed to use instruction !"));
|
BX_ERROR(("RDTSC: not allowed to use instruction !"));
|
||||||
exception(BX_GP_EXCEPTION, 0);
|
exception(BX_GP_EXCEPTION, 0);
|
||||||
|
Loading…
Reference in New Issue
Block a user