diff options
author | pbrook <pbrook@c046a42c-6fe2-441c-8c8c-71466251a162> | 2007-03-16 23:58:11 +0000 |
---|---|---|
committer | pbrook <pbrook@c046a42c-6fe2-441c-8c8c-71466251a162> | 2007-03-16 23:58:11 +0000 |
commit | 6658ffb81ee56a510d7d77025872a508a9adce3a (patch) | |
tree | 6cd595ce75c8cf82c7d38e997fdfd09de4fafefb /target-arm | |
parent | b35d7448b1d27a77bc6f59acc697710d5bd3823c (diff) |
Watchpoint support (previous commit got eaten by Savannah server crash).
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2479 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'target-arm')
-rw-r--r-- | target-arm/translate.c | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/target-arm/translate.c b/target-arm/translate.c index cf46e346ec..055ccfaa0f 100644 --- a/target-arm/translate.c +++ b/target-arm/translate.c @@ -45,6 +45,7 @@ typedef struct DisasContext { struct TranslationBlock *tb; int singlestep_enabled; int thumb; + int is_mem; #if !defined(CONFIG_USER_ONLY) int user; #endif @@ -290,6 +291,7 @@ static inline void gen_bx(DisasContext *s) #define gen_ldst(name, s) gen_op_##name##_raw() #else #define gen_ldst(name, s) do { \ + s->is_mem = 1; \ if (IS_USER(s)) \ gen_op_##name##_user(); \ else \ @@ -1612,6 +1614,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) gen_add_data_offset(s, insn); if (insn & (1 << 20)) { /* load */ + s->is_mem = 1; #if defined(CONFIG_USER_ONLY) if (insn & (1 << 22)) gen_op_ldub_raw(); @@ -2409,6 +2412,7 @@ static inline int gen_intermediate_code_internal(CPUState *env, dc->singlestep_enabled = env->singlestep_enabled; dc->condjmp = 0; dc->thumb = env->thumb; + dc->is_mem = 0; #if !defined(CONFIG_USER_ONLY) dc->user = (env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_USR; #endif @@ -2447,6 +2451,12 @@ static inline int gen_intermediate_code_internal(CPUState *env, gen_set_label(dc->condlabel); dc->condjmp = 0; } + /* Terminate the TB on memory ops if watchpoints are present. */ + /* FIXME: This should be replacd by the deterministic execution + * IRQ raising bits. */ + if (dc->is_mem && env->nb_watchpoints) + break; + /* Translation stops when a conditional branch is enoutered. * Otherwise the subsequent code could get translated several times. * Also stop translation when a page boundary is reached. This |