gas: xtensa: fix literal movement

Message ID 20180509175011.28815-1-jcmvbkbc@gmail.com
State New
Headers show
Series
  • gas: xtensa: fix literal movement
Related show

Commit Message

Max Filippov May 9, 2018, 5:50 p.m.
Not all literals need to be moved in the presence of
--text-section-literals or --auto-litpools, but only those created by
.literal pseudo op or generated as a result of relaxation. Attempts to
move other literals may result in abnormal termination of the assembler
due to the following assertion failure:

  Internal error in xg_find_litpool at gas/config/tc-xtensa.c:11209.

The same assertion may also be triggered by attempting to assign literal
pools to literals in .init and .fini sections; don't try to do that.

gas/
2018-05-09  Max Filippov  <jcmvbkbc@gmail.com>

	* config/tc-xtensa.c (xtensa_is_init_fini): New function.
       	(xtensa_move_literals): Only attempt to assign literal pool to
	literals with tc_frag_data.is_literal mark and not in .init or
	.fini sections.
	Join nested 'if' conditions to simplify function structure.
	(xtensa_switch_to_non_abs_literal_fragment): Use
	xtensa_is_init_fini to test for .init/.fini sections.
	* testsuite/gas/xtensa/all.exp (auto-litpools-3)
	(auto-litpools-4, text-section-literals-1): New tests.
	* testsuite/gas/xtensa/auto-litpools-3.d: New test results.
	* testsuite/gas/xtensa/auto-litpools-3.s: New test source.
	* testsuite/gas/xtensa/auto-litpools-4.d: New test results.
	* testsuite/gas/xtensa/auto-litpools-4.s: New test source.
	* testsuite/gas/xtensa/text-section-literals-1.d: New test results.
	* testsuite/gas/xtensa/text-section-literals-1.s: New test source.
---
 gas/config/tc-xtensa.c                             | 51 +++++++++++++---------
 gas/testsuite/gas/xtensa/all.exp                   |  3 ++
 gas/testsuite/gas/xtensa/auto-litpools-3.d         | 11 +++++
 gas/testsuite/gas/xtensa/auto-litpools-3.s         |  6 +++
 gas/testsuite/gas/xtensa/auto-litpools-4.d         | 18 ++++++++
 gas/testsuite/gas/xtensa/auto-litpools-4.s         |  6 +++
 gas/testsuite/gas/xtensa/text-section-literals-1.d | 18 ++++++++
 gas/testsuite/gas/xtensa/text-section-literals-1.s |  6 +++
 8 files changed, 98 insertions(+), 21 deletions(-)
 create mode 100644 gas/testsuite/gas/xtensa/auto-litpools-3.d
 create mode 100644 gas/testsuite/gas/xtensa/auto-litpools-3.s
 create mode 100644 gas/testsuite/gas/xtensa/auto-litpools-4.d
 create mode 100644 gas/testsuite/gas/xtensa/auto-litpools-4.s
 create mode 100644 gas/testsuite/gas/xtensa/text-section-literals-1.d
 create mode 100644 gas/testsuite/gas/xtensa/text-section-literals-1.s

-- 
2.11.0

Comments

augustine.sterling@gmail.com May 9, 2018, 6:56 p.m. | #1
On Wed, May 9, 2018 at 10:50 AM, Max Filippov <jcmvbkbc@gmail.com> wrote:
> gas/

> 2018-05-09  Max Filippov  <jcmvbkbc@gmail.com>

>

>         * config/tc-xtensa.c (xtensa_is_init_fini): New function.

>         (xtensa_move_literals): Only attempt to assign literal pool to

>         literals with tc_frag_data.is_literal mark and not in .init or

>         .fini sections.

>         Join nested 'if' conditions to simplify function structure.

>         (xtensa_switch_to_non_abs_literal_fragment): Use

>         xtensa_is_init_fini to test for .init/.fini sections.

>         * testsuite/gas/xtensa/all.exp (auto-litpools-3)

>         (auto-litpools-4, text-section-literals-1): New tests.

>         * testsuite/gas/xtensa/auto-litpools-3.d: New test results.

>         * testsuite/gas/xtensa/auto-litpools-3.s: New test source.

>         * testsuite/gas/xtensa/auto-litpools-4.d: New test results.

>         * testsuite/gas/xtensa/auto-litpools-4.s: New test source.

>         * testsuite/gas/xtensa/text-section-literals-1.d: New test results.

>         * testsuite/gas/xtensa/text-section-literals-1.s: New test source.


This is fine. Please apply.
Max Filippov May 9, 2018, 7:45 p.m. | #2
On Wed, May 9, 2018 at 11:56 AM, augustine.sterling@gmail.com
<augustine.sterling@gmail.com> wrote:
> On Wed, May 9, 2018 at 10:50 AM, Max Filippov <jcmvbkbc@gmail.com> wrote:

>> gas/

>> 2018-05-09  Max Filippov  <jcmvbkbc@gmail.com>

>>

>>         * config/tc-xtensa.c (xtensa_is_init_fini): New function.

>>         (xtensa_move_literals): Only attempt to assign literal pool to

>>         literals with tc_frag_data.is_literal mark and not in .init or

>>         .fini sections.

>>         Join nested 'if' conditions to simplify function structure.

>>         (xtensa_switch_to_non_abs_literal_fragment): Use

>>         xtensa_is_init_fini to test for .init/.fini sections.

>>         * testsuite/gas/xtensa/all.exp (auto-litpools-3)

>>         (auto-litpools-4, text-section-literals-1): New tests.

>>         * testsuite/gas/xtensa/auto-litpools-3.d: New test results.

>>         * testsuite/gas/xtensa/auto-litpools-3.s: New test source.

>>         * testsuite/gas/xtensa/auto-litpools-4.d: New test results.

>>         * testsuite/gas/xtensa/auto-litpools-4.s: New test source.

>>         * testsuite/gas/xtensa/text-section-literals-1.d: New test results.

>>         * testsuite/gas/xtensa/text-section-literals-1.s: New test source.

>

> This is fine. Please apply.


Thank you. Applied to master.

-- Max

Patch

diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c
index 4db7ef57e8f1..84211dd3e736 100644
--- a/gas/config/tc-xtensa.c
+++ b/gas/config/tc-xtensa.c
@@ -11260,6 +11260,14 @@  static struct litpool_frag *xg_find_litpool (struct litpool_seg *lps,
   return lp;
 }
 
+static bfd_boolean xtensa_is_init_fini (segT seg)
+{
+  if (!seg)
+    return 0;
+  return strcmp (segment_name (seg), INIT_SECTION_NAME) == 0
+    || strcmp (segment_name (seg), FINI_SECTION_NAME) == 0;
+}
+
 static void
 xtensa_move_literals (void)
 {
@@ -11291,6 +11299,9 @@  xtensa_move_literals (void)
       struct litpool_frag *lpf = lps->frag_list.next;
       addressT addr = 0;
 
+      if (xtensa_is_init_fini (lps->seg))
+	continue;
+
       for ( ; frchP; frchP = frchP->frch_next)
 	{
 	  fragS *fragP;
@@ -11311,22 +11322,23 @@  xtensa_move_literals (void)
 		  int slot;
 		  for (slot = 0; slot < MAX_SLOTS; slot++)
 		    {
-		      if (fragP->tc_frag_data.literal_frags[slot])
+		      fragS *litfrag = fragP->tc_frag_data.literal_frags[slot];
+
+		      if (litfrag
+			  && litfrag->tc_frag_data.is_literal
+			  && !litfrag->tc_frag_data.literal_frag)
 			{
-			  /* L32R; point its literal to the nearest litpool
-			     preferring non-"candidate" positions to avoid
-			     the jump-around.  */
-			  fragS *litfrag = fragP->tc_frag_data.literal_frags[slot];
-
-			  if (!litfrag->tc_frag_data.literal_frag)
-			    {
-			      struct litpool_frag *lp;
-
-			      lp = xg_find_litpool (lps, lpf, addr);
-			      /* Take earliest use of this literal to avoid
-				 forward refs.  */
-			      litfrag->tc_frag_data.literal_frag = lp->fragP;
-			    }
+			  /* L32R referring .literal or generated as a result
+			     of relaxation.  Point its literal to the nearest
+			     litpool preferring non-"candidate" positions to
+			     avoid the jump-around.  */
+
+			  struct litpool_frag *lp;
+
+			  lp = xg_find_litpool (lps, lpf, addr);
+			  /* Take earliest use of this literal to avoid
+			     forward refs.  */
+			  litfrag->tc_frag_data.literal_frag = lp->fragP;
 			}
 		    }
 		}
@@ -11594,14 +11606,11 @@  xtensa_switch_to_non_abs_literal_fragment (emit_state *result)
 {
   fragS *pool_location = get_literal_pool_location (now_seg);
   segT lit_seg;
-  bfd_boolean is_init =
-    (now_seg && !strcmp (segment_name (now_seg), INIT_SECTION_NAME));
-  bfd_boolean is_fini =
-    (now_seg && !strcmp (segment_name (now_seg), FINI_SECTION_NAME));
+  bfd_boolean is_init_fini = xtensa_is_init_fini (now_seg);
 
   if (pool_location == NULL
       && !use_literal_section
-      && !is_init && ! is_fini)
+      && !is_init_fini)
     {
       if (!auto_litpools)
 	{
@@ -11615,7 +11624,7 @@  xtensa_switch_to_non_abs_literal_fragment (emit_state *result)
   xtensa_switch_section_emit_state (result, lit_seg, 0);
 
   if (!use_literal_section
-      && !is_init && !is_fini
+      && !is_init_fini
       && get_literal_pool_location (now_seg) != pool_location)
     {
       /* Close whatever frag is there.  */
diff --git a/gas/testsuite/gas/xtensa/all.exp b/gas/testsuite/gas/xtensa/all.exp
index 650a93223d46..beb6f35aad5b 100644
--- a/gas/testsuite/gas/xtensa/all.exp
+++ b/gas/testsuite/gas/xtensa/all.exp
@@ -103,10 +103,13 @@  if [istarget xtensa*-*-*] then {
     run_dump_test "first_frag_align"
     run_dump_test "auto-litpools"
     run_dump_test "auto-litpools-2"
+    run_dump_test "auto-litpools-3"
+    run_dump_test "auto-litpools-4"
     run_dump_test "auto-litpools-first1"
     run_dump_test "auto-litpools-first2"
     run_dump_test "loc"
     run_dump_test "init-fini-literals"
+    run_dump_test "text-section-literals-1"
 }
 
 if [info exists errorInfo] then {
diff --git a/gas/testsuite/gas/xtensa/auto-litpools-3.d b/gas/testsuite/gas/xtensa/auto-litpools-3.d
new file mode 100644
index 000000000000..ee9e901535ef
--- /dev/null
+++ b/gas/testsuite/gas/xtensa/auto-litpools-3.d
@@ -0,0 +1,11 @@ 
+#as: --auto-litpools
+#objdump: -dr
+#name: auto-litpools-3 (don't move arbitrary data referenced by l32r)
+
+.*: +file format .*xtensa.*
+#...
+Disassembly of section .text:
+#...
+ *0:.*l32r.*
+.*0:.*\.data
+#...
diff --git a/gas/testsuite/gas/xtensa/auto-litpools-3.s b/gas/testsuite/gas/xtensa/auto-litpools-3.s
new file mode 100644
index 000000000000..cd0fb5deafa4
--- /dev/null
+++ b/gas/testsuite/gas/xtensa/auto-litpools-3.s
@@ -0,0 +1,6 @@ 
+	.data
+a:
+	.word	0x12345678
+
+	.text
+	l32r	a2, a
diff --git a/gas/testsuite/gas/xtensa/auto-litpools-4.d b/gas/testsuite/gas/xtensa/auto-litpools-4.d
new file mode 100644
index 000000000000..ba58c3e3e9df
--- /dev/null
+++ b/gas/testsuite/gas/xtensa/auto-litpools-4.d
@@ -0,0 +1,18 @@ 
+#as: --auto-litpools
+#objdump: -d
+#name: auto-litpools-4 (handle auto literal pools in .init and .fini)
+
+.*: +file format .*xtensa.*
+#...
+Disassembly of section .init.literal:
+#...
+Disassembly of section .fini.literal:
+#...
+Disassembly of section .init:
+#...
+ *0:.*l32r.*
+#...
+Disassembly of section .fini:
+#...
+ *0:.*l32r.*
+#...
diff --git a/gas/testsuite/gas/xtensa/auto-litpools-4.s b/gas/testsuite/gas/xtensa/auto-litpools-4.s
new file mode 100644
index 000000000000..d46c04d41d97
--- /dev/null
+++ b/gas/testsuite/gas/xtensa/auto-litpools-4.s
@@ -0,0 +1,6 @@ 
+	.section .init
+	.literal a, 0x12345678
+	movi	a2, 0x12345679
+	.section .fini
+	.literal b, 0x1234567a
+	movi	a2, 0x1234567b
diff --git a/gas/testsuite/gas/xtensa/text-section-literals-1.d b/gas/testsuite/gas/xtensa/text-section-literals-1.d
new file mode 100644
index 000000000000..2c481f8d0c5d
--- /dev/null
+++ b/gas/testsuite/gas/xtensa/text-section-literals-1.d
@@ -0,0 +1,18 @@ 
+#as: --text-section-literals
+#objdump: -d
+#name: text-section-literals (handle text section literal in .init and .fini without .literal_position)
+
+.*: +file format .*xtensa.*
+#...
+Disassembly of section .init.literal:
+#...
+Disassembly of section .fini.literal:
+#...
+Disassembly of section .init:
+#...
+ *0:.*l32r.*
+#...
+Disassembly of section .fini:
+#...
+ *0:.*l32r.*
+#...
diff --git a/gas/testsuite/gas/xtensa/text-section-literals-1.s b/gas/testsuite/gas/xtensa/text-section-literals-1.s
new file mode 100644
index 000000000000..d46c04d41d97
--- /dev/null
+++ b/gas/testsuite/gas/xtensa/text-section-literals-1.s
@@ -0,0 +1,6 @@ 
+	.section .init
+	.literal a, 0x12345678
+	movi	a2, 0x12345679
+	.section .fini
+	.literal b, 0x1234567a
+	movi	a2, 0x1234567b