mirror of https://github.com/xqemu/xqemu.git
target-i386: Re-introduce optimal breakpoint removal
Before the last patch, we had an efficient loop that disabled local breakpoints on task switch. Re-add that, but in a more general way that handles changes to the global enable bits too. Signed-off-by: Richard Henderson <rth@twiddle.net> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
This commit is contained in:
parent
93d00d0fbe
commit
36eb6e0967
|
@ -82,8 +82,29 @@ static void hw_breakpoint_remove(CPUX86State *env, int index)
|
||||||
|
|
||||||
void cpu_x86_update_dr7(CPUX86State *env, uint32_t new_dr7)
|
void cpu_x86_update_dr7(CPUX86State *env, uint32_t new_dr7)
|
||||||
{
|
{
|
||||||
|
target_ulong old_dr7 = env->dr[7];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
/* If nothing is changing except the global/local enable bits,
|
||||||
|
then we can make the change more efficient. */
|
||||||
|
if (((old_dr7 ^ new_dr7) & ~0xff) == 0) {
|
||||||
|
/* Fold the global and local enable bits together into the
|
||||||
|
global fields, then xor to show which registers have
|
||||||
|
changed collective enable state. */
|
||||||
|
int mod = ((old_dr7 | old_dr7 * 2) ^ (new_dr7 | new_dr7 * 2)) & 0xff;
|
||||||
|
|
||||||
|
for (i = 0; i < DR7_MAX_BP; i++) {
|
||||||
|
if ((mod & (2 << i * 2)) && !hw_breakpoint_enabled(new_dr7, i)) {
|
||||||
|
hw_breakpoint_remove(env, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
env->dr[7] = new_dr7;
|
||||||
|
for (i = 0; i < DR7_MAX_BP; i++) {
|
||||||
|
if (mod & (2 << i * 2) && hw_breakpoint_enabled(new_dr7, i)) {
|
||||||
|
hw_breakpoint_insert(env, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
for (i = 0; i < DR7_MAX_BP; i++) {
|
for (i = 0; i < DR7_MAX_BP; i++) {
|
||||||
hw_breakpoint_remove(env, i);
|
hw_breakpoint_remove(env, i);
|
||||||
}
|
}
|
||||||
|
@ -92,6 +113,7 @@ void cpu_x86_update_dr7(CPUX86State *env, uint32_t new_dr7)
|
||||||
hw_breakpoint_insert(env, i);
|
hw_breakpoint_insert(env, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static bool check_hw_breakpoints(CPUX86State *env, bool force_dr6_update)
|
static bool check_hw_breakpoints(CPUX86State *env, bool force_dr6_update)
|
||||||
|
|
Loading…
Reference in New Issue