aboutsummaryrefslogtreecommitdiff
path: root/target-i386/bpt_helper.c
diff options
context:
space:
mode:
authorRichard Henderson <rth@twiddle.net>2015-09-15 11:45:13 -0700
committerEduardo Habkost <ehabkost@redhat.com>2015-10-23 12:59:27 -0200
commitd0052339236072bbf08c1d600c0906126b1ab258 (patch)
treeca1cc289d1122c1ded250868f7e5bbda747b25c2 /target-i386/bpt_helper.c
parent5223a9423c5fb9e32b0c3eaaa2c0bf8c5cfd6866 (diff)
target-i386: Check CR4[DE] for processing DR4/DR5
Introduce helper_get_dr so that we don't have to put CR4[DE] into the scarce HFLAGS resource. At the same time, rename helper_movl_drN_T0 to helper_set_dr and set the helper flags. Signed-off-by: Richard Henderson <rth@twiddle.net> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Diffstat (limited to 'target-i386/bpt_helper.c')
-rw-r--r--target-i386/bpt_helper.c46
1 files changed, 41 insertions, 5 deletions
diff --git a/target-i386/bpt_helper.c b/target-i386/bpt_helper.c
index 117cea2564..144cfd43fc 100644
--- a/target-i386/bpt_helper.c
+++ b/target-i386/bpt_helper.c
@@ -242,10 +242,11 @@ void helper_single_step(CPUX86State *env)
raise_exception(env, EXCP01_DB);
}
-void helper_movl_drN_T0(CPUX86State *env, int reg, target_ulong t0)
+void helper_set_dr(CPUX86State *env, int reg, target_ulong t0)
{
#ifndef CONFIG_USER_ONLY
- if (reg < 4) {
+ switch (reg) {
+ case 0: case 1: case 2: case 3:
if (hw_breakpoint_enabled(env->dr[7], reg)
&& hw_breakpoint_type(env->dr[7], reg) != DR7_TYPE_IO_RW) {
hw_breakpoint_remove(env, reg);
@@ -254,14 +255,49 @@ void helper_movl_drN_T0(CPUX86State *env, int reg, target_ulong t0)
} else {
env->dr[reg] = t0;
}
- } else if (reg == 7) {
+ return;
+ case 4:
+ if (env->cr[4] & CR4_DE_MASK) {
+ break;
+ }
+ /* fallthru */
+ case 6:
+ env->dr[6] = t0;
+ return;
+ case 5:
+ if (env->cr[4] & CR4_DE_MASK) {
+ break;
+ }
+ /* fallthru */
+ case 7:
cpu_x86_update_dr7(env, t0);
- } else {
- env->dr[reg] = t0;
+ return;
}
+ raise_exception_err_ra(env, EXCP06_ILLOP, 0, GETPC());
#endif
}
+target_ulong helper_get_dr(CPUX86State *env, int reg)
+{
+ switch (reg) {
+ case 0: case 1: case 2: case 3: case 6: case 7:
+ return env->dr[reg];
+ case 4:
+ if (env->cr[4] & CR4_DE_MASK) {
+ break;
+ } else {
+ return env->dr[6];
+ }
+ case 5:
+ if (env->cr[4] & CR4_DE_MASK) {
+ break;
+ } else {
+ return env->dr[7];
+ }
+ }
+ raise_exception_err_ra(env, EXCP06_ILLOP, 0, GETPC());
+}
+
/* Check if Port I/O is trapped by a breakpoint. */
void helper_bpt_io(CPUX86State *env, uint32_t port,
uint32_t size, target_ulong next_eip)