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 6/8] gas: xtensa: reuse trampoline placement code


There's almost exact copy of the trampoline placement code in the
search_trampolines function that is used for jumps generated for relaxed
branch instructions. Get rid of the duplication and reuse
xg_find_best_trampoline function for that.

gas/
2017-11-20  Max Filippov  <jcmvbkbc@gmail.com>

	* config/tc-xtensa.c (search_trampolines, get_best_trampoline):
	Remove definitions.
	(xg_find_best_trampoline_for_tinsn): New function.
	(relax_frag_immed): Replace call to get_best_trampoline with a
	call to xg_find_best_trampoline_for_tinsn.
	* testsuite/gas/xtensa/trampoline.d: Adjust absolute addresses
	as the placement of trampolines for relaxed branches has been
	changed.
---
 gas/config/tc-xtensa.c                | 97 ++++-------------------------------
 gas/testsuite/gas/xtensa/trampoline.d |  6 +--
 2 files changed, 12 insertions(+), 91 deletions(-)

diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c
index 4bc28859176d..272ab774999f 100644
--- a/gas/config/tc-xtensa.c
+++ b/gas/config/tc-xtensa.c
@@ -9816,99 +9816,20 @@ bytes_to_stretch (fragS *this_frag,
 
 
 static fragS *
-search_trampolines (TInsn *tinsn, fragS *fragP, bfd_boolean unreachable_only)
+xg_find_best_trampoline_for_tinsn (TInsn *tinsn, fragS *fragP)
 {
+  symbolS *sym = tinsn->tok[0].X_add_symbol;
+  addressT source = fragP->fr_address;
+  addressT target = S_GET_VALUE (sym) + tinsn->tok[0].X_add_number;
   struct trampoline_seg *ts = find_trampoline_seg (now_seg);
-  fragS *tf = NULL;
   size_t i;
-  fragS *best_tf = NULL;
-  offsetT best_delta = 0;
-  offsetT best_addr = 0;
-  symbolS *sym = tinsn->tok[0].X_add_symbol;
-  offsetT target = S_GET_VALUE (sym) + tinsn->tok[0].X_add_number;
-  offsetT addr = fragP->fr_address;
-  offsetT lower = (addr < target) ? addr : target;
-  offsetT upper = (addr > target) ? addr : target;
-  offsetT delta = upper - lower;
-  offsetT midpoint = lower + delta / 2;
-  offsetT this_delta = -1;
-  offsetT this_addr = -1;
-
-  if (!ts)
-    return NULL;
-
-  if (delta > 2 * J_RANGE)
-    {
-      /* One trampoline won't do; we need multiple.
-	 Choose the farthest trampoline that's still in range of the original
-	 and let a later pass finish the job.  */
-      for (i = 0; i < ts->index.n_entries; ++i)
-	{
-	  tf = ts->index.entry[i];
-	  this_addr = tf->fr_address + tf->fr_fix;
-	  if (upper == addr)
-	    {
-	      /* Backward jump.  */
-	      if (addr - this_addr < J_RANGE)
-		break;
-	    }
-	  else if (i + 1 < ts->index.n_entries)
-	    {
-	      /* Forward jump.  */
-	      fragS *next = ts->index.entry[i + 1];
-	      offsetT next_addr = next->fr_address + next->fr_fix;
-
-	      if (next_addr - addr > J_RANGE)
-		break;
-	    }
-	  else
-	    {
-	      break;
-	    }
-	}
-      if (i < ts->index.n_entries &&
-	  labs (addr - this_addr) < J_RANGE)
-	return tf;
-
-      return NULL;
-    }
-
-  for (i = 0; i < ts->index.n_entries; ++i)
-    {
-      tf = ts->index.entry[i];
-      this_addr = tf->fr_address + tf->fr_fix;
-      this_delta = labs (this_addr - midpoint);
-      if (unreachable_only && tf->tc_frag_data.needs_jump_around)
-	continue;
-      if (!best_tf || this_delta < best_delta)
-        {
-	  best_tf = tf;
-	  best_delta = this_delta;
-	  best_addr = this_addr;
-        }
-    }
-
-  if (best_tf &&
-      best_delta < J_RANGE &&
-      labs(best_addr - lower) < J_RANGE &&
-      labs(best_addr - upper) < J_RANGE)
-    return best_tf;
-
-  return NULL; /* No suitable trampoline found.  */
-}
-
 
-static fragS *
-get_best_trampoline (TInsn *tinsn, fragS *fragP)
-{
-  fragS *tf = NULL;
-
-  tf = search_trampolines (tinsn, fragP, TRUE); /* Try unreachable first.  */
+  if (!ts || !ts->index.n_entries)
+    return NULL;
 
-  if (tf == NULL)
-    tf = search_trampolines (tinsn, fragP, FALSE); /* Try ones needing a jump-around, too.  */
+  i = xg_find_best_trampoline (&ts->index, source, target);
 
-  return tf;
+  return ts->index.entry[i];
 }
 
 
@@ -10164,7 +10085,7 @@ relax_frag_immed (segT segP,
 
       if (!xg_symbolic_immeds_fit (jinsn, segP, fragP, fragP->fr_offset, total_text_diff))
 	{
-	  fragS *tf = get_best_trampoline (jinsn, fragP);
+	  fragS *tf = xg_find_best_trampoline_for_tinsn (jinsn, fragP);
 
 	  if (tf)
 	    {
diff --git a/gas/testsuite/gas/xtensa/trampoline.d b/gas/testsuite/gas/xtensa/trampoline.d
index c0bac6d19e3d..f9aa5d97edb2 100644
--- a/gas/testsuite/gas/xtensa/trampoline.d
+++ b/gas/testsuite/gas/xtensa/trampoline.d
@@ -23,11 +23,11 @@
 #...
 .*49404:.*j.0x49404
 .*49407:.*beqz.n.a2,.0x4940c
-.*49409:.*j.0x693ce
+.*49409:.*j.0x61aa2
 #...
-.*693ce:.*j.0x7ddd1
+.*61aa2:.*j.0x7a13b
 #...
-.*7ddd1:.*j.0x927f5
+.*7a13b:.*j.0x927f5
 #...
 .*927f5:.*j.0x927f5
 #...
-- 
2.1.4


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