aboutsummaryrefslogtreecommitdiff
path: root/Debugger
diff options
context:
space:
mode:
authorTat-Chee Wan (USM)2011-07-12 08:30:18 +0800
committerTat-Chee Wan (USM)2011-07-12 08:30:18 +0800
commitd85fa5f7a8d9c18fb960d51195b4dfb67c6396bf (patch)
tree7a955a584bf31cd99a80b2a41d5a3a9c4a7b685d /Debugger
parent8149bcca21537f3522bf12afdad905ec5aeb28d8 (diff)
fix thumb mode bx pc target address calculation
BX PC is used to call ARM subroutines from Thumb mode. The address returned by BX PC should be 2 instructions after the current PC value (PC+4).
Diffstat (limited to 'Debugger')
-rw-r--r--Debugger/debug_opcodes.S10
1 files changed, 6 insertions, 4 deletions
diff --git a/Debugger/debug_opcodes.S b/Debugger/debug_opcodes.S
index d0b4226..12872dd 100644
--- a/Debugger/debug_opcodes.S
+++ b/Debugger/debug_opcodes.S
@@ -1317,14 +1317,16 @@ _exit_arm_coproc_swi_handler:
* R6: Default Following Instruction Address (PC+2)
* On exit:
* R0: following instruction address (B0 set to indicate Thumb mode)
- * R1: destroyed
+ * R1, R2: destroyed
*/
_thumb_bx_blx_handler:
stmfd sp!, {lr}
- and r0, r4, #THUMB_BLX_INSTR_REG_RNMASK /* Register Rn Enum in R0[6:3] (Hi-Reg indicated by B6) */
- mov r0, r0, lsr #3 /* Shift Rn Enum to R0[3:0] */
- _regenum2index r0, r1 /* Convert Enum into Index in R1 */
+ and r2, r4, #THUMB_BLX_INSTR_REG_RNMASK /* Register Rn Enum in R2[6:3] (Hi-Reg indicated by B6) */
+ mov r2, r2, lsr #3 /* Shift Rn Enum to R2[3:0] */
+ _regenum2index r2, r1 /* Convert Enum into Index in R1 */
_getdbgregisterfromindex r1, r0 /* Retrieve Register contents from Index (R1) into R0 */
+ teq r2, #REG_PC
+ addeq r0, r0, #4 /* Adjust PC relative register value (for BX PC) */
/* Here, the register value would have R0[0] set to indicate switch to Thumb mode */
ldmfd sp!, {pc}