diff options
author | drath <drath@b42882b7-edfa-0310-969c-e2dbd0fdcd60> | 2007-05-29 11:23:42 +0000 |
---|---|---|
committer | drath <drath@b42882b7-edfa-0310-969c-e2dbd0fdcd60> | 2007-05-29 11:23:42 +0000 |
commit | 237e894805dd757cc24029af1b4b1e824c51712b (patch) | |
tree | abe2187fa53c3ba2e51201df0a60a6e10af6cc0f /src/target/arm_simulator.c | |
parent | e8af4de0a7d224e1aa28e72f0de1ddf0bec5beb8 (diff) |
- 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.c | 50 |
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 */ |