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] gas: xtensa: fix incorrect code generated with auto litpools


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

commit 947fa9141488c1d39303fcdaa056332d2d0b2599
Author: Max Filippov <jcmvbkbc@gmail.com>
Date:   Mon Apr 10 13:12:52 2017 +0100

    gas: xtensa: fix incorrect code generated with auto litpools
    
    	* config/tc-xtensa.c (xtensa_maybe_create_literal_pool_frag):
    	Initialize lps->frag_count with auto_litpool_limit.
    	(xg_promote_candidate_litpool): New function.
    	(xtensa_move_literals): Extract candidate litpool promotion code
    	into separate function. Call it for all possible found
    	candidates.
    	(xtensa_switch_to_literal_fragment): Drop 'recursive' flag and
    	call to xtensa_mark_literal_pool_location that it guards.
    	Replace it with call to xtensa_maybe_create_literal_pool_frag.
    	Initialize pool_location with created literal pool candidate.
    	* testsuite/gas/xtensa/all.exp: Add new tests.
    	* testsuite/gas/xtensa/auto-litpools-first1.d: New test results.
    	* testsuite/gas/xtensa/auto-litpools-first1.s: New test.
    	* testsuite/gas/xtensa/auto-litpools-first2.d: New test results.
    	* testsuite/gas/xtensa/auto-litpools-first2.s: New test.
    	* testsuite/gas/xtensa/auto-litpools.d: Fix offsets changed due
    	to additional jump instruction.

Diff:
---
 gas/ChangeLog                                   | 20 ++++++++
 gas/config/tc-xtensa.c                          | 66 ++++++++++++++-----------
 gas/testsuite/gas/xtensa/all.exp                |  2 +
 gas/testsuite/gas/xtensa/auto-litpools-first1.d | 12 +++++
 gas/testsuite/gas/xtensa/auto-litpools-first1.s |  3 ++
 gas/testsuite/gas/xtensa/auto-litpools-first2.d | 15 ++++++
 gas/testsuite/gas/xtensa/auto-litpools-first2.s |  3 ++
 gas/testsuite/gas/xtensa/auto-litpools.d        |  6 +--
 8 files changed, 95 insertions(+), 32 deletions(-)

diff --git a/gas/ChangeLog b/gas/ChangeLog
index ff9fca3..f7a8628 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,23 @@
+2017-04-10  Max Filippov  <jcmvbkbc@gmail.com>
+
+	* config/tc-xtensa.c (xtensa_maybe_create_literal_pool_frag):
+	Initialize lps->frag_count with auto_litpool_limit.
+	(xg_promote_candidate_litpool): New function.
+	(xtensa_move_literals): Extract candidate litpool promotion code
+	into separate function. Call it for all possible found
+	candidates.
+	(xtensa_switch_to_literal_fragment): Drop 'recursive' flag and
+	call to xtensa_mark_literal_pool_location that it guards.
+	Replace it with call to xtensa_maybe_create_literal_pool_frag.
+	Initialize pool_location with created literal pool candidate.
+	* testsuite/gas/xtensa/all.exp: Add new tests.
+	* testsuite/gas/xtensa/auto-litpools-first1.d: New test results.
+	* testsuite/gas/xtensa/auto-litpools-first1.s: New test.
+	* testsuite/gas/xtensa/auto-litpools-first2.d: New test results.
+	* testsuite/gas/xtensa/auto-litpools-first2.s: New test.
+	* testsuite/gas/xtensa/auto-litpools.d: Fix offsets changed due
+	to additional jump instruction.
+
 2017-04-07  Alan Modra  <amodra@gmail.com>
 
 	* testsuite/gas/ppc/altivec2.s: Delete E6500 vector insns.
diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c
index c45c70d..e1efaae 100644
--- a/gas/config/tc-xtensa.c
+++ b/gas/config/tc-xtensa.c
@@ -7547,6 +7547,10 @@ xtensa_maybe_create_literal_pool_frag (bfd_boolean create,
       lps->seg = now_seg;
       lps->frag_list.next = &lps->frag_list;
       lps->frag_list.prev = &lps->frag_list;
+      /* Put candidate literal pool at the beginning of every section,
+         so that even when section starts with literal load there's a
+	 literal pool available.  */
+      lps->frag_count = auto_litpool_limit;
     }
 
   lps->frag_count++;
@@ -11035,6 +11039,30 @@ xtensa_move_seg_list_to_beginning (seg_list *head)
 static void mark_literal_frags (seg_list *);
 
 static void
+xg_promote_candidate_litpool (struct litpool_seg *lps,
+			      struct litpool_frag *lp)
+{
+  fragS *poolbeg;
+  fragS *poolend;
+  symbolS *lsym;
+  char label[10 + 2 * sizeof (fragS *)];
+
+  poolbeg = lp->fragP;
+  lp->priority = 1;
+  poolbeg->fr_subtype = RELAX_LITERAL_POOL_BEGIN;
+  poolend = poolbeg->fr_next;
+  gas_assert (poolend->fr_type == rs_machine_dependent &&
+	      poolend->fr_subtype == RELAX_LITERAL_POOL_END);
+  /* Create a local symbol pointing to the
+     end of the pool.  */
+  sprintf (label, ".L0_LT_%p", poolbeg);
+  lsym = (symbolS *)local_symbol_make (label, lps->seg,
+				       0, poolend);
+  poolbeg->fr_symbol = lsym;
+  /* Rest is done in xtensa_relax_frag.  */
+}
+
+static void
 xtensa_move_literals (void)
 {
   seg_list *segment;
@@ -11121,27 +11149,17 @@ xtensa_move_literals (void)
 				      /* This is still a "candidate" but the next one
 				         will be too far away, so revert to the nearest
 					 one, convert it and add the jump around.  */
-				      fragS *poolbeg;
-				      fragS *poolend;
-				      symbolS *lsym;
-				      char label[10 + 2 * sizeof (fragS *)];
 				      lp = lpf->prev;
-				      poolbeg = lp->fragP;
-				      lp->priority = 1;
-				      poolbeg->fr_subtype = RELAX_LITERAL_POOL_BEGIN;
-				      poolend = poolbeg->fr_next;
-				      gas_assert (poolend->fr_type == rs_machine_dependent &&
-						  poolend->fr_subtype == RELAX_LITERAL_POOL_END);
-				      /* Create a local symbol pointing to the
-				         end of the pool.  */
-				      sprintf (label, ".L0_LT_%p", poolbeg);
-				      lsym = (symbolS *)local_symbol_make (label, lps->seg,
-									   0, poolend);
-				      poolbeg->fr_symbol = lsym;
-				      /* Rest is done in xtensa_relax_frag.  */
+				      break;
 				    }
 				}
 			    }
+
+			  /* Convert candidate and add the jump around.  */
+			  if (lp->fragP->fr_subtype ==
+			      RELAX_LITERAL_POOL_CANDIDATE_BEGIN)
+			    xg_promote_candidate_litpool (lps, lp);
+
 			  if (! litfrag->tc_frag_data.literal_frag)
 			    {
 			      /* Take earliest use of this literal to avoid
@@ -11413,7 +11431,6 @@ xtensa_switch_to_literal_fragment (emit_state *result)
 static void
 xtensa_switch_to_non_abs_literal_fragment (emit_state *result)
 {
-  static bfd_boolean recursive = FALSE;
   fragS *pool_location = get_literal_pool_location (now_seg);
   segT lit_seg;
   bfd_boolean is_init =
@@ -11423,23 +11440,14 @@ xtensa_switch_to_non_abs_literal_fragment (emit_state *result)
 
   if (pool_location == NULL
       && !use_literal_section
-      && !recursive
       && !is_init && ! is_fini)
     {
       if (!auto_litpools)
 	{
 	  as_bad (_("literal pool location required for text-section-literals; specify with .literal_position"));
 	}
-
-      /* When we mark a literal pool location, we want to put a frag in
-	 the literal pool that points to it.  But to do that, we want to
-	 switch_to_literal_fragment.  But literal sections don't have
-	 literal pools, so their location is always null, so we would
-	 recurse forever.  This is kind of hacky, but it works.  */
-
-      recursive = TRUE;
-      xtensa_mark_literal_pool_location ();
-      recursive = FALSE;
+      xtensa_maybe_create_literal_pool_frag (TRUE, TRUE);
+      pool_location = get_literal_pool_location (now_seg);
     }
 
   lit_seg = cache_literal_section (FALSE);
diff --git a/gas/testsuite/gas/xtensa/all.exp b/gas/testsuite/gas/xtensa/all.exp
index 98041b5..1ab3827 100644
--- a/gas/testsuite/gas/xtensa/all.exp
+++ b/gas/testsuite/gas/xtensa/all.exp
@@ -101,6 +101,8 @@ if [istarget xtensa*-*-*] then {
     run_dump_test "trampoline"
     run_dump_test "first_frag_align"
     run_dump_test "auto-litpools"
+    run_dump_test "auto-litpools-first1"
+    run_dump_test "auto-litpools-first2"
     run_dump_test "loc"
     run_dump_test "init-fini-literals"
 }
diff --git a/gas/testsuite/gas/xtensa/auto-litpools-first1.d b/gas/testsuite/gas/xtensa/auto-litpools-first1.d
new file mode 100644
index 0000000..322cdc5
--- /dev/null
+++ b/gas/testsuite/gas/xtensa/auto-litpools-first1.d
@@ -0,0 +1,12 @@
+#as: --auto-litpools
+#objdump: -ds
+#name: auto-litpools-first1 (check that literal pool is created when source starts with literal)
+
+.*: +file format .*xtensa.*
+#...
+Contents of section .text:
+ 0000 ........ 20170331 .*
+#...
+00000000 <f>:
+.*0:.*j.8 .*
+#...
diff --git a/gas/testsuite/gas/xtensa/auto-litpools-first1.s b/gas/testsuite/gas/xtensa/auto-litpools-first1.s
new file mode 100644
index 0000000..7ac0bf8
--- /dev/null
+++ b/gas/testsuite/gas/xtensa/auto-litpools-first1.s
@@ -0,0 +1,3 @@
+f:
+	.literal .L0, 0x20170331
+	l32r	a2, .L0
diff --git a/gas/testsuite/gas/xtensa/auto-litpools-first2.d b/gas/testsuite/gas/xtensa/auto-litpools-first2.d
new file mode 100644
index 0000000..a6b798e
--- /dev/null
+++ b/gas/testsuite/gas/xtensa/auto-litpools-first2.d
@@ -0,0 +1,15 @@
+#as: --auto-litpools
+#objdump: -ds
+#name: auto-litpools-first2 (check that literal pool with jump around is created for generated literal)
+
+.*: +file format .*xtensa.*
+#...
+Contents of section .text:
+ 0000 ........ ........ 20170331 .*
+#...
+00000000 <f>:
+   0:.*addi.*a1.*
+   3:.*j.*c.*
+#...
+   c:.*l32r.*a2, 8.*
+#...
diff --git a/gas/testsuite/gas/xtensa/auto-litpools-first2.s b/gas/testsuite/gas/xtensa/auto-litpools-first2.s
new file mode 100644
index 0000000..c097dac
--- /dev/null
+++ b/gas/testsuite/gas/xtensa/auto-litpools-first2.s
@@ -0,0 +1,3 @@
+f:
+	addi	a1, a1, -16
+	movi	a2, 0x20170331
diff --git a/gas/testsuite/gas/xtensa/auto-litpools.d b/gas/testsuite/gas/xtensa/auto-litpools.d
index 4d1a690..fc6f5cb 100644
--- a/gas/testsuite/gas/xtensa/auto-litpools.d
+++ b/gas/testsuite/gas/xtensa/auto-litpools.d
@@ -4,9 +4,9 @@
 
 .*: +file format .*xtensa.*
 #...
-.*4:.*l32r.a2, 0 .*
+.*8:.*l32r.a2, 4 .*
 #...
-.*3e437:.*j.3e440 .*
+.*3e43b:.*j.3e444 .*
 #...
-.*40750:.*l32r.a2, 3e43c .*
+.*40754:.*l32r.a2, 3e440 .*
 #...


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