aboutsummaryrefslogtreecommitdiff
path: root/target-arm
diff options
context:
space:
mode:
Diffstat (limited to 'target-arm')
-rw-r--r--target-arm/cpu.h7
-rw-r--r--target-arm/op.c6
-rw-r--r--target-arm/translate.c14
3 files changed, 26 insertions, 1 deletions
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 1346175134..ef7469d0c3 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -26,6 +26,8 @@
#include "softfloat.h"
+#define TARGET_HAS_ICE 1
+
#define EXCP_UDEF 1 /* undefined instruction */
#define EXCP_SWI 2 /* software interrupt */
#define EXCP_PREFETCH_ABORT 3
@@ -62,6 +64,11 @@ typedef struct CPUARMState {
int user_mode_only;
uint32_t address;
+ /* ICE debug support. */
+ target_ulong breakpoints[MAX_BREAKPOINTS];
+ int nb_breakpoints;
+ int singlestep_enabled;
+
/* in order to avoid passing too many arguments to the memory
write helpers, we store some rarely used information in the CPU
context) */
diff --git a/target-arm/op.c b/target-arm/op.c
index 42ee4f960a..f4cbb6e662 100644
--- a/target-arm/op.c
+++ b/target-arm/op.c
@@ -858,6 +858,12 @@ void OPPROTO op_undef_insn(void)
cpu_loop_exit();
}
+void OPPROTO op_debug(void)
+{
+ env->exception_index = EXCP_DEBUG;
+ cpu_loop_exit();
+}
+
/* VFP support. We follow the convention used for VFP instrunctions:
Single precition routines have a "s" suffix, double precision a
"d" suffix. */
diff --git a/target-arm/translate.c b/target-arm/translate.c
index 39c28e754d..280b68c4cb 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -2026,6 +2026,17 @@ static inline int gen_intermediate_code_internal(CPUState *env,
dc->pc = pc_start;
lj = -1;
do {
+ if (env->nb_breakpoints > 0) {
+ for(j = 0; j < env->nb_breakpoints; j++) {
+ if (env->breakpoints[j] == dc->pc) {
+ gen_op_movl_T0_im((long)dc->pc);
+ gen_op_movl_reg_TN[0][15]();
+ gen_op_debug();
+ dc->is_jmp = DISAS_JUMP;
+ break;
+ }
+ }
+ }
if (search_pc) {
j = gen_opc_ptr - gen_opc_buf;
if (lj < j) {
@@ -2040,7 +2051,8 @@ static inline int gen_intermediate_code_internal(CPUState *env,
disas_thumb_insn(dc);
else
disas_arm_insn(env, dc);
- } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
+ } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
+ !env->singlestep_enabled &&
(dc->pc - pc_start) < (TARGET_PAGE_SIZE - 32));
switch(dc->is_jmp) {
case DISAS_JUMP_NEXT: