This is the mail archive of the binutils@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]

[PATCH RFC] MIPS/GAS: Relax branches to symbols resolved at link time


Where branch relaxation is enabled emit the long sequence for branches 
whose distance cannot be determined, i.e. to symbols that are undefined 
or in a different segment.  These symbols are only resolved at link time 
and therefore the longer sequence ensures the branch target is in range, 
which cannot be guaranteed with a direct branch.

This is the opposite to the current implementation, originally proposed 
here: <https://sourceware.org/ml/binutils/2002-09/msg00218.html>.  The 
proposal was then extensively discussed before the final version was 
posted here: <https://sourceware.org/ml/binutils/2002-10/msg00191.html> 
and eventually committed:

commit 4a6a3df43dbb37853a7b88b10ae97d9ec5daf987
Author: Alexandre Oliva <aoliva@redhat.com>
Date:   Sat Oct 12 05:23:33 2002 +0000

The case considered here was not commented in the review however and the
original version remains.  With branch relaxation enabled it makes more 
sense to do it consistently, so that all code impure with respect to 
branch distances can be linked.  Direct branches are still produced for
the cases concerned where branch relaxation is disabled, which is the 
default.

	gas/
	* config/tc-mips.c (relaxed_branch_length): Use the long 
	sequence where the distance cannot be determined.
	(relaxed_micromips_32bit_branch_length): Likewise.
	* testsuite/gas/mips/branch-extern-1.d: New test.
	* testsuite/gas/mips/branch-extern-2.d: New test.
	* testsuite/gas/mips/branch-extern-3.d: New test.
	* testsuite/gas/mips/branch-extern-4.d: New test.
	* testsuite/gas/mips/branch-extern.l: New stderr output.
	* testsuite/gas/mips/branch-extern.s: New test source.
	* testsuite/gas/mips/branch-section-1.d: New test.
	* testsuite/gas/mips/branch-section-2.d: New test.
	* testsuite/gas/mips/branch-section-3.d: New test.
	* testsuite/gas/mips/branch-section-4.d: New test.
	* testsuite/gas/mips/branch-section.l: New stderr output.
	* testsuite/gas/mips/branch-section.s: New test source.
	* testsuite/gas/mips/mips.exp: Run the new tests.
---

 This is a functional change, so please let me know if you have any 
objections (or any other questions or comments), or otherwise I'll apply 
this change shortly.

  Maciej

binutils-mips-gas-branch-relax-do.diff
Index: binutils/gas/config/tc-mips.c
===================================================================
--- binutils.orig/gas/config/tc-mips.c	2016-04-08 00:45:42.740538772 +0100
+++ binutils/gas/config/tc-mips.c	2016-04-08 20:45:32.316129627 +0100
@@ -16809,12 +16809,9 @@ relaxed_branch_length (fragS *fragp, ase
 
       toofar = val < - (0x8000 << 2) || val >= (0x8000 << 2);
     }
-  else if (fragp)
-    /* If the symbol is not defined or it's in a different segment,
-       assume the user knows what's going on and emit a short
-       branch.  */
-    toofar = FALSE;
   else
+    /* If the symbol is not defined or it's in a different segment,
+       we emit the long sequence.  */
     toofar = TRUE;
 
   if (fragp && update && toofar != RELAX_BRANCH_TOOFAR (fragp->fr_subtype))
@@ -16879,12 +16876,9 @@ relaxed_micromips_32bit_branch_length (f
 
       toofar = val < - (0x8000 << 1) || val >= (0x8000 << 1);
     }
-  else if (fragp)
-    /* If the symbol is not defined or it's in a different segment,
-       assume the user knows what's going on and emit a short
-       branch.  */
-    toofar = FALSE;
   else
+    /* If the symbol is not defined or it's in a different segment,
+       we emit the long sequence.  */
     toofar = TRUE;
 
   if (fragp && update
Index: binutils/gas/testsuite/gas/mips/branch-extern-1.d
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ binutils/gas/testsuite/gas/mips/branch-extern-1.d	2016-04-08 00:48:53.821062465 +0100
@@ -0,0 +1,12 @@
+#objdump: -dr --prefix-addresses --show-raw-insn
+#name: MIPS branch to an external symbol
+#as: -32 -KPIC
+#source: branch-extern.s
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+[0-9a-f]+ <[^>]*> 1000ffff 	b	00000000 <foo>
+[ 	]*[0-9a-f]+: R_MIPS_PC16	bar
+[0-9a-f]+ <[^>]*> 00000000 	nop
+	\.\.\.
Index: binutils/gas/testsuite/gas/mips/branch-extern-2.d
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ binutils/gas/testsuite/gas/mips/branch-extern-2.d	2016-04-08 00:48:53.911005633 +0100
@@ -0,0 +1,12 @@
+#objdump: -dr --prefix-addresses --show-raw-insn
+#name: microMIPS branch to an external symbol
+#as: -32 -KPIC -mmicromips
+#source: branch-extern.s
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+[0-9a-f]+ <[^>]*> 9400 fffe 	b	00000000 <foo>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC16_S1	bar
+[0-9a-f]+ <[^>]*> 0c00      	nop
+	\.\.\.
Index: binutils/gas/testsuite/gas/mips/branch-extern-3.d
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ binutils/gas/testsuite/gas/mips/branch-extern-3.d	2016-04-08 00:48:53.980061663 +0100
@@ -0,0 +1,17 @@
+#objdump: -dr --prefix-addresses --show-raw-insn
+#name: MIPS relaxed branch to an external symbol
+#as: -32 -KPIC -mips1 --relax-branch
+#source: branch-extern.s
+#stderr: branch-extern.l
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+[0-9a-f]+ <[^>]*> 8f810000 	lw	at,0\(gp\)
+[ 	]*[0-9a-f]+: R_MIPS_GOT16	bar
+[0-9a-f]+ <[^>]*> 00000000 	nop
+[0-9a-f]+ <[^>]*> 24210000 	addiu	at,at,0
+[ 	]*[0-9a-f]+: R_MIPS_LO16	bar
+[0-9a-f]+ <[^>]*> 00200008 	jr	at
+[0-9a-f]+ <[^>]*> 00000000 	nop
+	\.\.\.
Index: binutils/gas/testsuite/gas/mips/branch-extern-4.d
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ binutils/gas/testsuite/gas/mips/branch-extern-4.d	2016-04-08 00:48:54.056418939 +0100
@@ -0,0 +1,16 @@
+#objdump: -dr --prefix-addresses --show-raw-insn
+#name: microMIPS relaxed branch to an external symbol
+#as: -32 -KPIC -mmicromips --relax-branch
+#source: branch-extern.s
+#stderr: branch-extern.l
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+[0-9a-f]+ <[^>]*> fc3c 0000 	lw	at,0\(gp\)
+[ 	]*[0-9a-f]+: R_MICROMIPS_GOT16	bar
+[0-9a-f]+ <[^>]*> 3021 0000 	addiu	at,at,0
+[ 	]*[0-9a-f]+: R_MICROMIPS_LO16	bar
+[0-9a-f]+ <[^>]*> 4581      	jr	at
+[0-9a-f]+ <[^>]*> 0c00      	nop
+	\.\.\.
Index: binutils/gas/testsuite/gas/mips/branch-extern.l
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ binutils/gas/testsuite/gas/mips/branch-extern.l	2016-04-08 00:48:54.198595674 +0100
@@ -0,0 +1,2 @@
+.*: Assembler messages:
+.*:5: Warning: relaxed out-of-range branch into a jump
Index: binutils/gas/testsuite/gas/mips/branch-extern.s
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ binutils/gas/testsuite/gas/mips/branch-extern.s	2016-04-08 00:48:54.307410349 +0100
@@ -0,0 +1,10 @@
+	.text
+	.globl	foo
+	.ent	foo
+foo:
+	b	bar
+	.end	foo
+
+# Force some (non-delay-slot) zero bytes, to make 'objdump' print ...
+	.align  4, 0
+	.space  16
Index: binutils/gas/testsuite/gas/mips/branch-section-1.d
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ binutils/gas/testsuite/gas/mips/branch-section-1.d	2016-04-08 20:40:22.227180265 +0100
@@ -0,0 +1,17 @@
+#objdump: -dr --prefix-addresses --show-raw-insn
+#name: MIPS branch to a different section
+#as: -32
+#source: branch-section.s
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+[0-9a-f]+ <[^>]*> 1000ffff 	b	00000000 <foo>
+[ 	]*[0-9a-f]+: R_MIPS_PC16	bar
+[0-9a-f]+ <[^>]*> 00000000 	nop
+	\.\.\.
+
+Disassembly of section \.init:
+[0-9a-f]+ <[^>]*> 03e00008 	jr	ra
+[0-9a-f]+ <[^>]*> 00000000 	nop
+	\.\.\.
Index: binutils/gas/testsuite/gas/mips/branch-section-2.d
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ binutils/gas/testsuite/gas/mips/branch-section-2.d	2016-04-08 20:40:32.832656959 +0100
@@ -0,0 +1,17 @@
+#objdump: -dr --prefix-addresses --show-raw-insn
+#name: microMIPS branch to a different section
+#as: -32 -mmicromips
+#source: branch-section.s
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+[0-9a-f]+ <[^>]*> 9400 fffe 	b	00000000 <foo>
+[ 	]*[0-9a-f]+: R_MICROMIPS_PC16_S1	bar
+[0-9a-f]+ <[^>]*> 0c00      	nop
+	\.\.\.
+
+Disassembly of section \.init:
+[0-9a-f]+ <[^>]*> 459f      	jr	ra
+[0-9a-f]+ <[^>]*> 0c00      	nop
+	\.\.\.
Index: binutils/gas/testsuite/gas/mips/branch-section-3.d
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ binutils/gas/testsuite/gas/mips/branch-section-3.d	2016-04-08 21:36:32.767868329 +0100
@@ -0,0 +1,18 @@
+#objdump: -dr --prefix-addresses --show-raw-insn
+#name: MIPS relaxed branch to a different section
+#as: -32 --relax-branch
+#source: branch-section.s
+#stderr: branch-section.l
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+[0-9a-f]+ <[^>]*> 08000000 	j	00000000 <foo>
+[ 	]*[0-9a-f]+: R_MIPS_26	\.init
+[0-9a-f]+ <[^>]*> 00000000 	nop
+	\.\.\.
+
+Disassembly of section \.init:
+[0-9a-f]+ <[^>]*> 03e00008 	jr	ra
+[0-9a-f]+ <[^>]*> 00000000 	nop
+	\.\.\.
Index: binutils/gas/testsuite/gas/mips/branch-section-4.d
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ binutils/gas/testsuite/gas/mips/branch-section-4.d	2016-04-08 20:43:19.995104979 +0100
@@ -0,0 +1,18 @@
+#objdump: -dr --prefix-addresses --show-raw-insn
+#name: microMIPS relaxed branch to a different section
+#as: -32 -mmicromips --relax-branch
+#source: branch-section.s
+#stderr: branch-section.l
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+[0-9a-f]+ <[^>]*> d400 0000 	j	00000000 <foo>
+[ 	]*[0-9a-f]+: R_MICROMIPS_26_S1	bar
+[0-9a-f]+ <[^>]*> 0c00      	nop
+	\.\.\.
+
+Disassembly of section \.init:
+[0-9a-f]+ <[^>]*> 459f      	jr	ra
+[0-9a-f]+ <[^>]*> 0c00      	nop
+	\.\.\.
Index: binutils/gas/testsuite/gas/mips/branch-section.l
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ binutils/gas/testsuite/gas/mips/branch-section.l	2016-04-08 21:23:34.468197310 +0100
@@ -0,0 +1,2 @@
+.*: Assembler messages:
+.*:5: Warning: relaxed out-of-range branch into a jump
Index: binutils/gas/testsuite/gas/mips/branch-section.s
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ binutils/gas/testsuite/gas/mips/branch-section.s	2016-04-08 21:23:21.432468922 +0100
@@ -0,0 +1,20 @@
+	.text
+	.globl	foo
+	.ent	foo
+foo:
+	b	bar
+	.end	foo
+
+# Force some (non-delay-slot) zero bytes, to make 'objdump' print ...
+	.align  4, 0
+	.space  16
+
+	.section .init, "ax", @progbits
+	.ent	bar
+bar:
+	jr	$ra
+	.end	bar
+
+# Force some (non-delay-slot) zero bytes, to make 'objdump' print ...
+	.align  4, 0
+	.space  16
Index: binutils/gas/testsuite/gas/mips/mips.exp
===================================================================
--- binutils.orig/gas/testsuite/gas/mips/mips.exp	2016-04-08 00:45:43.809524559 +0100
+++ binutils/gas/testsuite/gas/mips/mips.exp	2016-04-08 20:46:10.480257638 +0100
@@ -570,6 +570,15 @@ if { [istarget mips*-*-vxworks*] } {
 	    "MIPS branch swapping ($count)"
     }
 
+    run_dump_test "branch-section-1"
+    run_dump_test "branch-section-2"
+    run_dump_test "branch-section-3"
+    run_dump_test "branch-section-4"
+    run_dump_test "branch-extern-1"
+    run_dump_test "branch-extern-2"
+    run_dump_test "branch-extern-3"
+    run_dump_test "branch-extern-4"
+
     run_dump_test "compact-eh-eb-1"
     run_dump_test "compact-eh-eb-2"
     run_dump_test "compact-eh-eb-3"


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