This is the mail archive of the binutils-cvs@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb] MIPS16/opcodes: Fix PC-relative operation delay-slot adjustment


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=860b03a8f357d1565bd9d79ae25121059b2d28ae

commit 860b03a8f357d1565bd9d79ae25121059b2d28ae
Author: Maciej W. Rozycki <macro@imgtec.com>
Date:   Thu Dec 8 23:29:01 2016 +0000

    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.

Diff:
---
 binutils/ChangeLog                                 |   6 +
 binutils/testsuite/binutils-all/mips/mips.exp      |   1 +
 .../testsuite/binutils-all/mips/mips16-pcrel.d     | 200 +++++++++++++++++++
 .../testsuite/binutils-all/mips/mips16-pcrel.s     | 219 +++++++++++++++++++++
 opcodes/ChangeLog                                  |   6 +
 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;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]