diff options
author | Maciej W. Rozycki <macro@codesourcery.com> | 2014-10-05 23:37:53 +0100 |
---|---|---|
committer | Maciej W. Rozycki <macro@codesourcery.com> | 2014-10-05 23:37:53 +0100 |
commit | 484933d11fca33ded4c5465eae3781bf79ee12e2 (patch) | |
tree | e6955c7c422abf93003183ea20f7f7db76884bad /gdb/mips-tdep.c | |
parent | ab50adb6a622fc599ce6e037ae0cdfaf952f4bb4 (diff) | |
download | gdb-484933d11fca33ded4c5465eae3781bf79ee12e2.zip gdb-484933d11fca33ded4c5465eae3781bf79ee12e2.tar.gz gdb-484933d11fca33ded4c5465eae3781bf79ee12e2.tar.bz2 |
MIPS: Rewrite `add_offset_16' to match its name
A helper function called `add_offset_16' is used by
`extended_mips16_next_pc' to calculate branch destinations. Weirdly
enough the helper does not do what the name suggests and rather than
doing its work for a 16-bit immediate branch offset it makes its
calculations on a 26-bit immediate target used by JAL and JALX
instructions. Furthermore the JAL/JALX calculation is only needed once
by `extended_mips16_next_pc' while a 16-bit branch offset calculation
is made inline several times across `extended_mips16_next_pc'.
This change therefore replaces the contents of `add_offset_16' with the
16-bit branch offset calculation and updates `extended_mips16_next_pc'
accordingly.
* mips-tdep.c (add_offset_16): Rewrite to implement what the
name implies.
(extended_mips16_next_pc): Update accordingly.
Diffstat (limited to 'gdb/mips-tdep.c')
-rw-r--r-- | gdb/mips-tdep.c | 16 |
1 files changed, 9 insertions, 7 deletions
diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c index dccbfa7..c072bf0 100644 --- a/gdb/mips-tdep.c +++ b/gdb/mips-tdep.c @@ -2126,10 +2126,13 @@ unpack_mips16 (struct gdbarch *gdbarch, CORE_ADDR pc, } +/* Calculate the destination of a branch whose 16-bit opcode word is at PC, + and having a signed 16-bit OFFSET. */ + static CORE_ADDR add_offset_16 (CORE_ADDR pc, int offset) { - return ((offset << 2) | ((pc + 2) & (~(CORE_ADDR) 0x0fffffff))); + return pc + (offset << 1) + 2; } static CORE_ADDR @@ -2144,7 +2147,7 @@ extended_mips16_next_pc (struct frame_info *frame, CORE_ADDR pc, { struct upk_mips16 upk; unpack_mips16 (gdbarch, pc, extension, insn, itype, &upk); - pc += (upk.offset << 1) + 2; + pc = add_offset_16 (pc, upk.offset); break; } case 3: /* JAL , JALX - Watch out, these are 32 bit @@ -2152,7 +2155,7 @@ extended_mips16_next_pc (struct frame_info *frame, CORE_ADDR pc, { struct upk_mips16 upk; unpack_mips16 (gdbarch, pc, extension, insn, jalxtype, &upk); - pc = add_offset_16 (pc, upk.offset); + pc = ((pc + 2) & (~(CORE_ADDR) 0x0fffffff)) | (upk.offset << 2); if ((insn >> 10) & 0x01) /* Exchange mode */ pc = pc & ~0x01; /* Clear low bit, indicate 32 bit mode. */ else @@ -2166,7 +2169,7 @@ extended_mips16_next_pc (struct frame_info *frame, CORE_ADDR pc, unpack_mips16 (gdbarch, pc, extension, insn, ritype, &upk); reg = get_frame_register_signed (frame, mips_reg3_to_reg[upk.regx]); if (reg == 0) - pc += (upk.offset << 1) + 2; + pc = add_offset_16 (pc, upk.offset); else pc += 2; break; @@ -2178,7 +2181,7 @@ extended_mips16_next_pc (struct frame_info *frame, CORE_ADDR pc, unpack_mips16 (gdbarch, pc, extension, insn, ritype, &upk); reg = get_frame_register_signed (frame, mips_reg3_to_reg[upk.regx]); if (reg != 0) - pc += (upk.offset << 1) + 2; + pc = add_offset_16 (pc, upk.offset); else pc += 2; break; @@ -2192,8 +2195,7 @@ extended_mips16_next_pc (struct frame_info *frame, CORE_ADDR pc, reg = get_frame_register_signed (frame, 24); /* Test register is 24 */ if (((upk.regx == 0) && (reg == 0)) /* BTEZ */ || ((upk.regx == 1) && (reg != 0))) /* BTNEZ */ - /* pc = add_offset_16(pc,upk.offset) ; */ - pc += (upk.offset << 1) + 2; + pc = add_offset_16 (pc, upk.offset); else pc += 2; break; |