summaryrefslogtreecommitdiff
path: root/src/target/arm_simulator.c
diff options
context:
space:
mode:
authordrath <drath@b42882b7-edfa-0310-969c-e2dbd0fdcd60>2007-05-29 11:23:42 +0000
committerdrath <drath@b42882b7-edfa-0310-969c-e2dbd0fdcd60>2007-05-29 11:23:42 +0000
commit237e894805dd757cc24029af1b4b1e824c51712b (patch)
treeabe2187fa53c3ba2e51201df0a60a6e10af6cc0f /src/target/arm_simulator.c
parente8af4de0a7d224e1aa28e72f0de1ddf0bec5beb8 (diff)
downloadopenocd+libswd-237e894805dd757cc24029af1b4b1e824c51712b.tar.gz
openocd+libswd-237e894805dd757cc24029af1b4b1e824c51712b.tar.bz2
openocd+libswd-237e894805dd757cc24029af1b4b1e824c51712b.tar.xz
openocd+libswd-237e894805dd757cc24029af1b4b1e824c51712b.zip
- split fileio handling into fileio part and image handling
- reworked etm/etb into a generic etm part with trace capture drivers (currently only etb supported) - added XScale debug handler binary to repository - added Thumb disassembling (thanks to Vincent Palatin for this patch) - added support for non-CFI compatible flashes to cfi driver (currently only SST39VFxxx devices supported) This checkin is experimental, not suitable for general use git-svn-id: svn://svn.berlios.de/openocd/trunk@155 b42882b7-edfa-0310-969c-e2dbd0fdcd60
Diffstat (limited to 'src/target/arm_simulator.c')
-rw-r--r--src/target/arm_simulator.c50
1 files changed, 36 insertions, 14 deletions
diff --git a/src/target/arm_simulator.c b/src/target/arm_simulator.c
index fd0b309c..561b14f8 100644
--- a/src/target/arm_simulator.c
+++ b/src/target/arm_simulator.c
@@ -257,6 +257,11 @@ int pass_condition(u32 cpsr, u32 opcode)
return 0;
}
+int thumb_pass_branch_condition(u32 cpsr, u16 opcode)
+{
+ return pass_condition(cpsr, (opcode & 0x0f00) << 20);
+}
+
/* simulate a single step (if possible)
* if the dry_run_pc argument is provided, no state is changed,
* but the new pc is stored in the variable pointed at by the argument
@@ -275,26 +280,43 @@ int arm_simulate_step(target_t *target, u32 *dry_run_pc)
target_read_u32(target, current_pc, &opcode);
arm_evaluate_opcode(opcode, current_pc, &instruction);
instruction_size = 4;
+
+ /* check condition code (for all instructions) */
+ if (!pass_condition(buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32), opcode))
+ {
+ if (dry_run_pc)
+ {
+ *dry_run_pc = current_pc + instruction_size;
+ }
+ else
+ {
+ buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, current_pc + instruction_size);
+ }
+
+ return ERROR_OK;
+ }
}
else
{
- /* TODO: add support for Thumb instruction set */
+ target_read_u32(target, current_pc, &opcode);
+ arm_evaluate_opcode(opcode, current_pc, &instruction);
instruction_size = 2;
- }
-
- /* check condition code */
- if (!pass_condition(buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32), opcode))
- {
- if (dry_run_pc)
- {
- *dry_run_pc = current_pc + instruction_size;
- }
- else
+
+ /* check condition code (only for branch instructions) */
+ if ((!thumb_pass_branch_condition(buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32), opcode)) &&
+ (instruction.type == ARM_B))
{
- buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, current_pc + instruction_size);
+ if (dry_run_pc)
+ {
+ *dry_run_pc = current_pc + instruction_size;
+ }
+ else
+ {
+ buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, current_pc + instruction_size);
+ }
+
+ return ERROR_OK;
}
-
- return ERROR_OK;
}
/* examine instruction type */