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 | |
parent | 731f7c4ea30cc409c45412eec15e3d66afe051f5 (diff) | |
download | fsf-binutils-gdb-860b03a8f357d1565bd9d79ae25121059b2d28ae.zip fsf-binutils-gdb-860b03a8f357d1565bd9d79ae25121059b2d28ae.tar.gz fsf-binutils-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.
-rw-r--r-- | binutils/ChangeLog | 6 | ||||
-rw-r--r-- | binutils/testsuite/binutils-all/mips/mips.exp | 1 | ||||
-rw-r--r-- | binutils/testsuite/binutils-all/mips/mips16-pcrel.d | 200 | ||||
-rw-r--r-- | binutils/testsuite/binutils-all/mips/mips16-pcrel.s | 219 | ||||
-rw-r--r-- | opcodes/ChangeLog | 6 | ||||
-rw-r--r-- | opcodes/mips-dis.c | 16 |
6 files changed, 442 insertions, 6 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog index ae19b53..f41e4ff 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,9 @@ +2016-12-08 Maciej W. Rozycki <macro@imgtec.com> + + * 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. + 2016-12-08 Étienne Buira <etienne.buira@gmail.com> * readelf.c (process_program_headers): Always use hex prefix when diff --git a/binutils/testsuite/binutils-all/mips/mips.exp b/binutils/testsuite/binutils-all/mips/mips.exp index 4dab9a6..5dc872d 100644 --- a/binutils/testsuite/binutils-all/mips/mips.exp +++ b/binutils/testsuite/binutils-all/mips/mips.exp @@ -24,4 +24,5 @@ if [is_elf_format] { run_dump_test "mixed-micromips" run_dump_test "mixed-mips16-micromips" run_dump_test "mips16-undecoded" + run_dump_test "mips16-pcrel" } diff --git a/binutils/testsuite/binutils-all/mips/mips16-pcrel.d b/binutils/testsuite/binutils-all/mips/mips16-pcrel.d new file mode 100644 index 0000000..6b8e96b --- /dev/null +++ b/binutils/testsuite/binutils-all/mips/mips16-pcrel.d @@ -0,0 +1,200 @@ +#PROG: objcopy +#objdump: -d --prefix-addresses --show-raw-insn +#name: MIPS16 PC-relative instruction disassembly +#as: -32 + +# Verify delay-slot adjustment for PC-relative operations. + +.*: +file format .*mips.* + +Disassembly of section \.text: +00000000 <[^>]*> 6500 nop +00000002 <[^>]*> 6500 nop +00000004 <[^>]*> 0aff la v0,00000400 <foo0\+0x400> +00000006 <[^>]*> 6500 nop +00000008 <[^>]*> 6500 nop +0000000a <[^>]*> 6500 nop +0000000c <[^>]*> b3ff lw v1,00000408 <foo0\+0x408> +0000000e <[^>]*> 6500 nop +00000010 <[^>]*> 6500 nop +00000012 <[^>]*> 6500 nop +00000014 <[^>]*> fe9f dla a0,00000090 <foo0\+0x90> +00000016 <[^>]*> 6500 nop +00000018 <[^>]*> 6500 nop +0000001a <[^>]*> 6500 nop +0000001c <[^>]*> 6500 nop +0000001e <[^>]*> 6500 nop +00000020 <[^>]*> fcbf ld a1,00000118 <foo0\+0x118> + \.\.\. +00001000 <[^>]*> 1800 0000 jal 00000000 <foo0> +00001004 <[^>]*> 0aff la v0,000013fc <foo1\+0x3fc> +00001006 <[^>]*> 6500 nop +00001008 <[^>]*> 1800 0000 jal 00000000 <foo0> +0000100c <[^>]*> b3ff lw v1,00001404 <foo1\+0x404> +0000100e <[^>]*> 6500 nop +00001010 <[^>]*> 1800 0000 jal 00000000 <foo0> +00001014 <[^>]*> fe9f dla a0,0000108c <foo1\+0x8c> +00001016 <[^>]*> 6500 nop +00001018 <[^>]*> 6500 nop +0000101a <[^>]*> 6500 nop +0000101c <[^>]*> 1800 0000 jal 00000000 <foo0> +00001020 <[^>]*> fcbf ld a1,00001110 <foo1\+0x110> + \.\.\. +00002000 <[^>]*> 1c00 0000 jalx 00000000 <foo0> +00002004 <[^>]*> 0aff la v0,000023fc <foo2\+0x3fc> +00002006 <[^>]*> 6500 nop +00002008 <[^>]*> 1c00 0000 jalx 00000000 <foo0> +0000200c <[^>]*> b3ff lw v1,00002404 <foo2\+0x404> +0000200e <[^>]*> 6500 nop +00002010 <[^>]*> 1c00 0000 jalx 00000000 <foo0> +00002014 <[^>]*> fe9f dla a0,0000208c <foo2\+0x8c> +00002016 <[^>]*> 6500 nop +00002018 <[^>]*> 6500 nop +0000201a <[^>]*> 6500 nop +0000201c <[^>]*> 1c00 0000 jalx 00000000 <foo0> +00002020 <[^>]*> fcbf ld a1,00002110 <foo2\+0x110> + \.\.\. +00003000 <[^>]*> 6500 nop +00003002 <[^>]*> e800 jr s0 +00003004 <[^>]*> 0aff la v0,000033fc <foo3\+0x3fc> +00003006 <[^>]*> 6500 nop +00003008 <[^>]*> 6500 nop +0000300a <[^>]*> e800 jr s0 +0000300c <[^>]*> b3ff lw v1,00003404 <foo3\+0x404> +0000300e <[^>]*> 6500 nop +00003010 <[^>]*> 6500 nop +00003012 <[^>]*> e800 jr s0 +00003014 <[^>]*> fe9f dla a0,0000308c <foo3\+0x8c> +00003016 <[^>]*> 6500 nop +00003018 <[^>]*> 6500 nop +0000301a <[^>]*> 6500 nop +0000301c <[^>]*> 6500 nop +0000301e <[^>]*> e800 jr s0 +00003020 <[^>]*> fcbf ld a1,00003110 <foo3\+0x110> + \.\.\. +00004000 <[^>]*> 6500 nop +00004002 <[^>]*> e820 jr ra +00004004 <[^>]*> 0aff la v0,000043fc <foo4\+0x3fc> +00004006 <[^>]*> 6500 nop +00004008 <[^>]*> 6500 nop +0000400a <[^>]*> e820 jr ra +0000400c <[^>]*> b3ff lw v1,00004404 <foo4\+0x404> +0000400e <[^>]*> 6500 nop +00004010 <[^>]*> 6500 nop +00004012 <[^>]*> e820 jr ra +00004014 <[^>]*> fe9f dla a0,0000408c <foo4\+0x8c> +00004016 <[^>]*> 6500 nop +00004018 <[^>]*> 6500 nop +0000401a <[^>]*> 6500 nop +0000401c <[^>]*> 6500 nop +0000401e <[^>]*> e820 jr ra +00004020 <[^>]*> fcbf ld a1,00004110 <foo4\+0x110> + \.\.\. +00005000 <[^>]*> 6500 nop +00005002 <[^>]*> e840 jalr s0 +00005004 <[^>]*> 0aff la v0,000053fc <foo5\+0x3fc> +00005006 <[^>]*> 6500 nop +00005008 <[^>]*> 6500 nop +0000500a <[^>]*> e840 jalr s0 +0000500c <[^>]*> b3ff lw v1,00005404 <foo5\+0x404> +0000500e <[^>]*> 6500 nop +00005010 <[^>]*> 6500 nop +00005012 <[^>]*> e840 jalr s0 +00005014 <[^>]*> fe9f dla a0,0000508c <foo5\+0x8c> +00005016 <[^>]*> 6500 nop +00005018 <[^>]*> 6500 nop +0000501a <[^>]*> 6500 nop +0000501c <[^>]*> 6500 nop +0000501e <[^>]*> e840 jalr s0 +00005020 <[^>]*> fcbf ld a1,00005110 <foo5\+0x110> + \.\.\. +00006000 <[^>]*> 6500 nop +00006002 <[^>]*> e860 0xe860 +00006004 <[^>]*> 0aff la v0,00006400 <foo6\+0x400> +00006006 <[^>]*> 6500 nop +00006008 <[^>]*> 6500 nop +0000600a <[^>]*> e860 0xe860 +0000600c <[^>]*> b3ff lw v1,00006408 <foo6\+0x408> +0000600e <[^>]*> 6500 nop +00006010 <[^>]*> 6500 nop +00006012 <[^>]*> e860 0xe860 +00006014 <[^>]*> fe9f dla a0,00006090 <foo6\+0x90> +00006016 <[^>]*> 6500 nop +00006018 <[^>]*> 6500 nop +0000601a <[^>]*> 6500 nop +0000601c <[^>]*> 6500 nop +0000601e <[^>]*> e860 0xe860 +00006020 <[^>]*> fcbf ld a1,00006118 <foo6\+0x118> + \.\.\. +00007000 <[^>]*> 6500 nop +00007002 <[^>]*> e880 jrc s0 +00007004 <[^>]*> 0aff la v0,00007400 <foo7\+0x400> +00007006 <[^>]*> 6500 nop +00007008 <[^>]*> 6500 nop +0000700a <[^>]*> e880 jrc s0 +0000700c <[^>]*> b3ff lw v1,00007408 <foo7\+0x408> +0000700e <[^>]*> 6500 nop +00007010 <[^>]*> 6500 nop +00007012 <[^>]*> e880 jrc s0 +00007014 <[^>]*> fe9f dla a0,00007090 <foo7\+0x90> +00007016 <[^>]*> 6500 nop +00007018 <[^>]*> 6500 nop +0000701a <[^>]*> 6500 nop +0000701c <[^>]*> 6500 nop +0000701e <[^>]*> e880 jrc s0 +00007020 <[^>]*> fcbf ld a1,00007118 <foo7\+0x118> + \.\.\. +00008000 <[^>]*> 6500 nop +00008002 <[^>]*> e8a0 jrc ra +00008004 <[^>]*> 0aff la v0,00008400 <foo8\+0x400> +00008006 <[^>]*> 6500 nop +00008008 <[^>]*> 6500 nop +0000800a <[^>]*> e8a0 jrc ra +0000800c <[^>]*> b3ff lw v1,00008408 <foo8\+0x408> +0000800e <[^>]*> 6500 nop +00008010 <[^>]*> 6500 nop +00008012 <[^>]*> e8a0 jrc ra +00008014 <[^>]*> fe9f dla a0,00008090 <foo8\+0x90> +00008016 <[^>]*> 6500 nop +00008018 <[^>]*> 6500 nop +0000801a <[^>]*> 6500 nop +0000801c <[^>]*> 6500 nop +0000801e <[^>]*> e8a0 jrc ra +00008020 <[^>]*> fcbf ld a1,00008118 <foo8\+0x118> + \.\.\. +00009000 <[^>]*> 6500 nop +00009002 <[^>]*> e8c0 jalrc s0 +00009004 <[^>]*> 0aff la v0,00009400 <foo9\+0x400> +00009006 <[^>]*> 6500 nop +00009008 <[^>]*> 6500 nop +0000900a <[^>]*> e8c0 jalrc s0 +0000900c <[^>]*> b3ff lw v1,00009408 <foo9\+0x408> +0000900e <[^>]*> 6500 nop +00009010 <[^>]*> 6500 nop +00009012 <[^>]*> e8c0 jalrc s0 +00009014 <[^>]*> fe9f dla a0,00009090 <foo9\+0x90> +00009016 <[^>]*> 6500 nop +00009018 <[^>]*> 6500 nop +0000901a <[^>]*> 6500 nop +0000901c <[^>]*> 6500 nop +0000901e <[^>]*> e8c0 jalrc s0 +00009020 <[^>]*> fcbf ld a1,00009118 <foo9\+0x118> + \.\.\. +0000a000 <[^>]*> 6500 nop +0000a002 <[^>]*> e960 0xe960 +0000a004 <[^>]*> 0aff la v0,0000a400 <fooa\+0x400> +0000a006 <[^>]*> 6500 nop +0000a008 <[^>]*> 6500 nop +0000a00a <[^>]*> e960 0xe960 +0000a00c <[^>]*> b3ff lw v1,0000a408 <fooa\+0x408> +0000a00e <[^>]*> 6500 nop +0000a010 <[^>]*> 6500 nop +0000a012 <[^>]*> e960 0xe960 +0000a014 <[^>]*> fe9f dla a0,0000a090 <fooa\+0x90> +0000a016 <[^>]*> 6500 nop +0000a018 <[^>]*> 6500 nop +0000a01a <[^>]*> 6500 nop +0000a01c <[^>]*> 6500 nop +0000a01e <[^>]*> e960 0xe960 +0000a020 <[^>]*> fcbf ld a1,0000a118 <fooa\+0x118> + \.\.\. diff --git a/binutils/testsuite/binutils-all/mips/mips16-pcrel.s b/binutils/testsuite/binutils-all/mips/mips16-pcrel.s new file mode 100644 index 0000000..f73aeae --- /dev/null +++ b/binutils/testsuite/binutils-all/mips/mips16-pcrel.s @@ -0,0 +1,219 @@ + .module mips64 + .set mips16 + .set noreorder + .set noautoextend + + .align 12, 0 +foo0: + nop + nop + addiu $2, $pc, 0x3fc + nop + nop + nop + lw $3, 0x3fc($pc) + nop + nop + nop + daddiu $4, $pc, 0x7c + nop + nop + nop + nop + nop + ld $5, 0xf8($pc) + + .align 12, 0 +foo1: + jal bar0 + addiu $2, $pc, 0x3fc + nop + jal bar0 + lw $3, 0x3fc($pc) + nop + jal bar0 + daddiu $4, $pc, 0x7c + nop + nop + nop + jal bar0 + ld $5, 0xf8($pc) + + .align 12, 0 +foo2: + jalx bar1 + addiu $2, $pc, 0x3fc + nop + jalx bar1 + lw $3, 0x3fc($pc) + nop + jalx bar1 + daddiu $4, $pc, 0x7c + nop + nop + nop + jalx bar1 + ld $5, 0xf8($pc) + + .align 12, 0 +foo3: + nop + jr $16 + addiu $2, $pc, 0x3fc + nop + nop + jr $16 + lw $3, 0x3fc($pc) + nop + nop + jr $16 + daddiu $4, $pc, 0x7c + nop + nop + nop + nop + jr $16 + ld $5, 0xf8($pc) + + .align 12, 0 +foo4: + nop + jr $31 + addiu $2, $pc, 0x3fc + nop + nop + jr $31 + lw $3, 0x3fc($pc) + nop + nop + jr $31 + daddiu $4, $pc, 0x7c + nop + nop + nop + nop + jr $31 + ld $5, 0xf8($pc) + + .align 12, 0 +foo5: + nop + jalr $16 + addiu $2, $pc, 0x3fc + nop + nop + jalr $16 + lw $3, 0x3fc($pc) + nop + nop + jalr $16 + daddiu $4, $pc, 0x7c + nop + nop + nop + nop + jalr $16 + ld $5, 0xf8($pc) + + .align 12, 0 +foo6: + nop + .half 0xe860 + addiu $2, $pc, 0x3fc + nop + nop + .half 0xe860 + lw $3, 0x3fc($pc) + nop + nop + .half 0xe860 + daddiu $4, $pc, 0x7c + nop + nop + nop + nop + .half 0xe860 + ld $5, 0xf8($pc) + + .align 12, 0 +foo7: + nop + jrc $16 + addiu $2, $pc, 0x3fc + nop + nop + jrc $16 + lw $3, 0x3fc($pc) + nop + nop + jrc $16 + daddiu $4, $pc, 0x7c + nop + nop + nop + nop + jrc $16 + ld $5, 0xf8($pc) + + .align 12, 0 +foo8: + nop + jrc $31 + addiu $2, $pc, 0x3fc + nop + nop + jrc $31 + lw $3, 0x3fc($pc) + nop + nop + jrc $31 + daddiu $4, $pc, 0x7c + nop + nop + nop + nop + jrc $31 + ld $5, 0xf8($pc) + + .align 12, 0 +foo9: + nop + jalrc $16 + addiu $2, $pc, 0x3fc + nop + nop + jalrc $16 + lw $3, 0x3fc($pc) + nop + nop + jalrc $16 + daddiu $4, $pc, 0x7c + nop + nop + nop + nop + jalrc $16 + ld $5, 0xf8($pc) + + .align 12, 0 +fooa: + nop + .half 0xe960 + addiu $2, $pc, 0x3fc + nop + nop + .half 0xe960 + lw $3, 0x3fc($pc) + nop + nop + .half 0xe960 + daddiu $4, $pc, 0x7c + nop + nop + nop + nop + .half 0xe960 + ld $5, 0xf8($pc) + +# Force some (non-delay-slot) zero bytes, to make 'objdump' print ... + .align 12, 0 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; |