summaryrefslogtreecommitdiff
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
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).
-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}