diff options
author | Maciej W. Rozycki <macro@imgtec.com> | 2016-12-08 23:29:01 +0000 |
---|---|---|
committer | Maciej W. Rozycki <macro@imgtec.com> | 2016-12-08 23:30:57 +0000 |
commit | 860b03a8f357d1565bd9d79ae25121059b2d28ae (patch) | |
tree | c76f74a44626b05d308861754e7561fe8f73bcb3 /opcodes | |
parent | 731f7c4ea30cc409c45412eec15e3d66afe051f5 (diff) | |
download | gdb-860b03a8f357d1565bd9d79ae25121059b2d28ae.zip gdb-860b03a8f357d1565bd9d79ae25121059b2d28ae.tar.gz gdb-860b03a8f357d1565bd9d79ae25121059b2d28ae.tar.bz2 |
MIPS16/opcodes: Fix PC-relative operation delay-slot adjustment
Complement commit dd8b7c222e0e ("MIPS: mips16e jalrc/jrc opcodes"),
<https://sourceware.org/ml/binutils/2005-07/msg00349.html>, and stop the
disassembler making a delay-slot adjustment for PC-relative operations
following either MIPS16e compact jumps, or undefined RR/J(AL)R(C)
encodings that have the `l' (link) and `ra' (source register is `ra')
bits set both at a time. Adjust code description for accuracy. Add a
suitable test case.
opcodes/
* mips-dis.c (print_mips16_insn_arg): Avoid delay-slot
adjustment for PC-relative operations following MIPS16e compact
jumps or undefined RR/J(AL)R(C) encodings.
binutils/
* testsuite/binutils-all/mips/mips16-pcrel.d: New test.
* testsuite/binutils-all/mips/mips16-pcrel.s: New test source.
* testsuite/binutils-all/mips/mips.exp: Run the new test.
Diffstat (limited to 'opcodes')
-rw-r--r-- | opcodes/ChangeLog | 6 | ||||
-rw-r--r-- | opcodes/mips-dis.c | 16 |
2 files changed, 16 insertions, 6 deletions
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index 110739a..70f9150 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,5 +1,11 @@ 2016-12-08 Maciej W. Rozycki <macro@imgtec.com> + * mips-dis.c (print_mips16_insn_arg): Avoid delay-slot + adjustment for PC-relative operations following MIPS16e compact + jumps or undefined RR/J(AL)R(C) encodings. + +2016-12-08 Maciej W. Rozycki <macro@imgtec.com> + * aarch64-asm.c (aarch64_ins_reglane): Rename `index' local variable to `reglane_index'. diff --git a/opcodes/mips-dis.c b/opcodes/mips-dis.c index 7192c84..19d0366 100644 --- a/opcodes/mips-dis.c +++ b/opcodes/mips-dis.c @@ -1917,12 +1917,12 @@ print_mips16_insn_arg (struct disassemble_info *info, { bfd_byte buffer[2]; - /* If this instruction is in the delay slot of a JR + /* If this instruction is in the delay slot of a JAL/JALX instruction, the base address is the address of the - JR instruction. If it is in the delay slot of a JALR - instruction, the base address is the address of the - JALR instruction. This test is unreliable: we have - no way of knowing whether the previous word is + JAL/JALX instruction. If it is in the delay slot of + a JR/JALR instruction, the base address is the address + of the JR/JALR instruction. This test is unreliable: + we have no way of knowing whether the previous word is instruction or data. */ if (info->read_memory_func (memaddr - 4, buffer, 2, info) == 0 && (((info->endian == BFD_ENDIAN_BIG @@ -1935,7 +1935,11 @@ print_mips16_insn_arg (struct disassemble_info *info, && (((info->endian == BFD_ENDIAN_BIG ? bfd_getb16 (buffer) : bfd_getl16 (buffer)) - & 0xf81f) == 0xe800)) + & 0xf89f) == 0xe800) + && (((info->endian == BFD_ENDIAN_BIG + ? bfd_getb16 (buffer) + : bfd_getl16 (buffer)) + & 0x0060) != 0x0060)) baseaddr = memaddr - 2; else baseaddr = memaddr; |