Buildroot Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [Buildroot] [PATCH 0/4] xtensa: toolchain fix for compiling huge functions
@ 2015-08-12 22:19 Max Filippov
  2015-08-12 22:20 ` [Buildroot] [PATCH 1/4] binutils: backport auto-litpools xtensa gas option Max Filippov
                   ` (5 more replies)
  0 siblings, 6 replies; 9+ messages in thread
From: Max Filippov @ 2015-08-12 22:19 UTC (permalink / raw)
  To: buildroot

Hi Thomas,

this series backports binutils and gcc patches that add auto-litpools option
and replaces text-section-literals ABI flag for xtensa with auto-litpools.
With that change compiling huge functions should no longer be an issue on
xtensa. Obviously that change will break builds with pre-built toolchain.

Max Filippov (4):
  binutils: backport auto-litpools xtensa gas option
  gcc: backport mauto-litpools xtensa option
  xtensa: switch from text-section-literals to auto-litpools
  Revert "opencv: mark as not available on Xtensa"

 package/Makefile.in                                |   4 +-
 .../2.24/913-xtensa-add-auto-litpools-option.patch | 698 ++++++++++++++++++++
 .../913-xtensa-add-auto-litpools-option.patch      | 699 +++++++++++++++++++++
 .../870-xtensa-add-mauto-litpools-option.patch     | 290 +++++++++
 .../870-xtensa-add-mauto-litpools-option.patch     | 290 +++++++++
 .../870-xtensa-add-mauto-litpools-option.patch     | 290 +++++++++
 package/gcc/gcc.mk                                 |   6 +-
 package/opencv/Config.in                           |   3 -
 8 files changed, 2272 insertions(+), 8 deletions(-)
 create mode 100644 package/binutils/2.24/913-xtensa-add-auto-litpools-option.patch
 create mode 100644 package/binutils/2.25.1/913-xtensa-add-auto-litpools-option.patch
 create mode 100644 package/gcc/4.8.5/870-xtensa-add-mauto-litpools-option.patch
 create mode 100644 package/gcc/4.9.3/870-xtensa-add-mauto-litpools-option.patch
 create mode 100644 package/gcc/5.2.0/870-xtensa-add-mauto-litpools-option.patch

-- 
1.8.1.4

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Buildroot] [PATCH 1/4] binutils: backport auto-litpools xtensa gas option
  2015-08-12 22:19 [Buildroot] [PATCH 0/4] xtensa: toolchain fix for compiling huge functions Max Filippov
@ 2015-08-12 22:20 ` Max Filippov
  2015-08-12 22:20 ` [Buildroot] [PATCH 2/4] gcc: backport mauto-litpools xtensa option Max Filippov
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 9+ messages in thread
From: Max Filippov @ 2015-08-12 22:20 UTC (permalink / raw)
  To: buildroot

Auto-litpools is the automated version of text-section-literals: literal
pool candidate frags are planted every N frags and during relaxation
they are turned into actual literal pools where literals are moved to
become reachable for their first reference by L32R instruction.

Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
---
 .../2.24/913-xtensa-add-auto-litpools-option.patch | 698 ++++++++++++++++++++
 .../913-xtensa-add-auto-litpools-option.patch      | 699 +++++++++++++++++++++
 2 files changed, 1397 insertions(+)
 create mode 100644 package/binutils/2.24/913-xtensa-add-auto-litpools-option.patch
 create mode 100644 package/binutils/2.25.1/913-xtensa-add-auto-litpools-option.patch

diff --git a/package/binutils/2.24/913-xtensa-add-auto-litpools-option.patch b/package/binutils/2.24/913-xtensa-add-auto-litpools-option.patch
new file mode 100644
index 0000000..f0199e1
--- /dev/null
+++ b/package/binutils/2.24/913-xtensa-add-auto-litpools-option.patch
@@ -0,0 +1,698 @@
+From 978adaaa4cd3921842e2be8a31c05f081fb17fcf Mon Sep 17 00:00:00 2001
+From: Max Filippov <jcmvbkbc@gmail.com>
+Date: Wed, 29 Jul 2015 17:42:54 +0300
+Subject: [PATCH] xtensa: add --auto-litpools option
+
+Auto-litpools is the automated version of text-section-literals: literal
+pool candidate frags are planted every N frags and during relaxation
+they are turned into actual literal pools where literals are moved to
+become reachable for their first reference by L32R instruction.
+
+2015-08-12  David Weatherford  <weath@cadence.com>
+gas/
+	* config/tc-xtensa.c (struct litpool_frag, struct litpool_seg):
+	New structures.
+	(xtensa_maybe_create_literal_pool_frag): New function.
+	(litpool_seg_list, auto_litpools, auto_litpool_limit)
+	(litpool_buf, litpool_slotbuf): New static variables.
+	(option_auto_litpools, option_no_auto_litpools)
+	(option_auto_litpool_limit): New enum identifiers.
+	(md_longopts): Add entries for auto-litpools, no-auto-litpools
+	and auto-litpool-limit.
+	(md_parse_option): Handle option_auto_litpools,
+	option_no_auto_litpools and option_auto_litpool_limit.
+	(md_show_usage): Add help for --[no-]auto-litpools and
+	--auto-litpool-limit.
+	(xtensa_mark_literal_pool_location): Record a place for literal
+	pool with a call to xtensa_maybe_create_literal_pool_frag.
+	(get_literal_pool_location): Find highest priority literal pool
+	or convert candidate to literal pool when auto-litpools are used.
+	(xg_assemble_vliw_tokens): Create literal pool after jump
+	instruction.
+	(xtensa_check_frag_count): Create candidate literal pool every
+	auto_litpool_limit frags.
+	(xtensa_relax_frag): Add jump around literals to non-empty
+	literal pool.
+	(xtensa_move_literals): Estimate literal pool addresses and move
+	unreachable literals closer to their users, converting candidate
+	to literal pool if needed.
+	(xtensa_switch_to_non_abs_literal_fragment): Only emit error
+	about missing .literal_position in case auto-litpools are not
+	used.
+	* config/tc-xtensa.h (xtensa_relax_statesE): New relaxation
+	state: RELAX_LITERAL_POOL_CANDIDATE_BEGIN.
+
+2015-08-12  Max Filippov  <jcmvbkbc@gmail.com>
+gas/testsuite/
+	* gas/xtensa/all.exp: Add auto-litpools to the list of xtensa
+	tests.
+	* gas/xtensa/auto-litpools.s: New file: auto-litpools test.
+	* gas/xtensa/auto-litpools.s: New file: auto-litpools test
+	result pattern.
+
+Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
+---
+Backported from: b46824bd49648c575372e6d9bc6a6defeabd6ed5
+Changes to ChangeLogs and documentation are dropped.
+
+ gas/config/tc-xtensa.c                   | 432 ++++++++++++++++++++++++++++++-
+ gas/config/tc-xtensa.h                   |   1 +
+ gas/testsuite/gas/xtensa/all.exp         |   1 +
+ gas/testsuite/gas/xtensa/auto-litpools.d |  12 +
+ gas/testsuite/gas/xtensa/auto-litpools.s |  13 +
+ 5 files changed, 454 insertions(+), 5 deletions(-)
+ create mode 100644 gas/testsuite/gas/xtensa/auto-litpools.d
+ create mode 100644 gas/testsuite/gas/xtensa/auto-litpools.s
+
+diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c
+index 7311a05..b8b1e7d 100644
+--- a/gas/config/tc-xtensa.c
++++ b/gas/config/tc-xtensa.c
+@@ -440,6 +440,29 @@ bfd_boolean directive_state[] =
+ #endif
+ };
+ 
++/* A circular list of all potential and actual literal pool locations
++   in a segment.  */
++struct litpool_frag
++{
++  struct litpool_frag *next;
++  struct litpool_frag *prev;
++  fragS *fragP;
++  addressT addr;
++  short priority; /* 1, 2, or 3 -- 1 is highest  */
++  short original_priority;
++};
++
++/* Map a segment to its litpool_frag list.  */
++struct litpool_seg
++{
++  struct litpool_seg *next;
++  asection *seg;
++  struct litpool_frag frag_list;
++  int frag_count; /* since last litpool location  */
++};
++
++static struct litpool_seg litpool_seg_list;
++
+ 
+ /* Directive functions.  */
+ 
+@@ -474,6 +497,9 @@ static void xtensa_create_trampoline_frag (bfd_boolean);
+ static void xtensa_maybe_create_trampoline_frag (void);
+ struct trampoline_frag;
+ static int init_trampoline_frag (struct trampoline_frag *);
++static void xtensa_maybe_create_literal_pool_frag (bfd_boolean, bfd_boolean);
++static bfd_boolean auto_litpools = FALSE;
++static int auto_litpool_limit = 10000;
+ 
+ /* Alignment Functions.  */
+ 
+@@ -698,6 +724,10 @@ enum
+ 
+   option_trampolines,
+   option_no_trampolines,
++
++  option_auto_litpools,
++  option_no_auto_litpools,
++  option_auto_litpool_limit,
+ };
+ 
+ const char *md_shortopts = "";
+@@ -773,6 +803,10 @@ struct option md_longopts[] =
+   { "trampolines", no_argument, NULL, option_trampolines },
+   { "no-trampolines", no_argument, NULL, option_no_trampolines },
+ 
++  { "auto-litpools", no_argument, NULL, option_auto_litpools },
++  { "no-auto-litpools", no_argument, NULL, option_no_auto_litpools },
++  { "auto-litpool-limit", required_argument, NULL, option_auto_litpool_limit },
++
+   { NULL, no_argument, NULL, 0 }
+ };
+ 
+@@ -961,6 +995,34 @@ md_parse_option (int c, char *arg)
+       use_trampolines = FALSE;
+       return 1;
+ 
++    case option_auto_litpools:
++      auto_litpools = TRUE;
++      use_literal_section = FALSE;
++      return 1;
++
++    case option_no_auto_litpools:
++      auto_litpools = FALSE;
++      auto_litpool_limit = -1;
++      return 1;
++
++    case option_auto_litpool_limit:
++      {
++	int value = 0;
++	if (auto_litpool_limit < 0)
++	  as_fatal (_("no-auto-litpools is incompatible with auto-litpool-limit"));
++	if (*arg == 0 || *arg == '-')
++	  as_fatal (_("invalid auto-litpool-limit argument"));
++	value = strtol (arg, &arg, 10);
++	if (*arg != 0)
++	  as_fatal (_("invalid auto-litpool-limit argument"));
++	if (value < 100 || value > 10000)
++	  as_fatal (_("invalid auto-litpool-limit argument (range is 100-10000)"));
++	auto_litpool_limit = value;
++	auto_litpools = TRUE;
++	use_literal_section = FALSE;
++	return 1;
++      }
++
+     default:
+       return 0;
+     }
+@@ -986,7 +1048,12 @@ Xtensa options:\n\
+                           flix bundles\n\
+   --rename-section old=new Rename section 'old' to 'new'\n\
+   --[no-]trampolines      [Do not] generate trampolines (jumps to jumps)\n\
+-                          when jumps do not reach their targets\n", stream);
++                          when jumps do not reach their targets\n\
++  --[no-]auto-litpools    [Do not] automatically create literal pools\n\
++  --auto-litpool-limit=<value>\n\
++                          (range 100-10000) Maximum number of blocks of\n\
++                          instructions to emit between literal pool\n\
++                          locations; implies --auto-litpools flag\n", stream);
+ }
+ 
+ \f
+@@ -4728,6 +4795,8 @@ xtensa_mark_literal_pool_location (void)
+   pool_location = frag_now;
+   frag_now->tc_frag_data.lit_frchain = frchain_now;
+   frag_now->tc_frag_data.literal_frag = frag_now;
++  /* Just record this frag.  */
++  xtensa_maybe_create_literal_pool_frag (FALSE, FALSE);
+   frag_variant (rs_machine_dependent, 0, 0,
+ 		RELAX_LITERAL_POOL_BEGIN, NULL, 0, NULL);
+   xtensa_set_frag_assembly_state (frag_now);
+@@ -4832,6 +4901,31 @@ get_expanded_loop_offset (xtensa_opcode opcode)
+ static fragS *
+ get_literal_pool_location (segT seg)
+ {
++  struct litpool_seg *lps = litpool_seg_list.next;
++  struct litpool_frag *lpf;
++  for ( ; lps && lps->seg->id != seg->id; lps = lps->next)
++    ;
++  if (lps)
++    {
++      for (lpf = lps->frag_list.prev; lpf->fragP; lpf = lpf->prev)
++	{ /* Skip "candidates" for now.  */
++	  if (lpf->fragP->fr_subtype == RELAX_LITERAL_POOL_BEGIN &&
++	      lpf->priority == 1)
++	    return lpf->fragP;
++	}
++      /* Must convert a lower-priority pool.  */
++      for (lpf = lps->frag_list.prev; lpf->fragP; lpf = lpf->prev)
++	{
++	  if (lpf->fragP->fr_subtype == RELAX_LITERAL_POOL_BEGIN)
++	    return lpf->fragP;
++	}
++      /* Still no match -- try for a low priority pool.  */
++      for (lpf = lps->frag_list.prev; lpf->fragP; lpf = lpf->prev)
++	{
++	  if (lpf->fragP->fr_subtype == RELAX_LITERAL_POOL_CANDIDATE_BEGIN)
++	    return lpf->fragP;
++	}
++    }
+   return seg_info (seg)->tc_segment_info_data.literal_pool_loc;
+ }
+ 
+@@ -7098,6 +7192,11 @@ xg_assemble_vliw_tokens (vliw_insn *vinsn)
+       frag_now->tc_frag_data.slot_symbols[slot] = tinsn->symbol;
+       frag_now->tc_frag_data.slot_offsets[slot] = tinsn->offset;
+       frag_now->tc_frag_data.literal_frags[slot] = tinsn->literal_frag;
++      if (tinsn->opcode == xtensa_l32r_opcode)
++	{
++	  frag_now->tc_frag_data.literal_frags[slot] =
++		  tinsn->tok[1].X_add_symbol->sy_frag;
++	}
+       if (tinsn->literal_space != 0)
+ 	xg_assemble_literal_space (tinsn->literal_space, slot);
+       frag_now->tc_frag_data.free_reg[slot] = tinsn->extra_arg;
+@@ -7170,6 +7269,8 @@ xg_assemble_vliw_tokens (vliw_insn *vinsn)
+ 		    frag_now->fr_symbol, frag_now->fr_offset, NULL);
+ 	  xtensa_set_frag_assembly_state (frag_now);
+ 	  xtensa_maybe_create_trampoline_frag ();
++	  /* Always create one here.  */
++	  xtensa_maybe_create_literal_pool_frag (TRUE, FALSE);
+ 	}
+       else if (is_branch && do_align_targets ())
+ 	{
+@@ -7314,11 +7415,18 @@ xtensa_check_frag_count (void)
+       clear_frag_count ();
+       unreachable_count = 0;
+     }
++
++  /* We create an area for a possible literal pool every N (default 5000)
++     frags or so.  */
++  xtensa_maybe_create_literal_pool_frag (TRUE, TRUE);
+ }
+ 
+ static xtensa_insnbuf trampoline_buf = NULL;
+ static xtensa_insnbuf trampoline_slotbuf = NULL;
+ 
++static xtensa_insnbuf litpool_buf = NULL;
++static xtensa_insnbuf litpool_slotbuf = NULL;
++
+ #define TRAMPOLINE_FRAG_SIZE 3000
+ 
+ static void
+@@ -7410,6 +7518,135 @@ dump_trampolines (void)
+     }
+ }
+ 
++static void dump_litpools (void) __attribute__ ((unused));
++
++static void
++dump_litpools (void)
++{
++  struct litpool_seg *lps = litpool_seg_list.next;
++  struct litpool_frag *lpf;
++
++  for ( ; lps ; lps = lps->next )
++    {
++      printf("litpool seg %s\n", lps->seg->name);
++      for ( lpf = lps->frag_list.next; lpf->fragP; lpf = lpf->next )
++	{
++	  fragS *litfrag = lpf->fragP->fr_next;
++	  int count = 0;
++	  while (litfrag && litfrag->fr_subtype != RELAX_LITERAL_POOL_END)
++	    {
++	      if (litfrag->fr_fix == 4)
++		count++;
++	      litfrag = litfrag->fr_next;
++	    }
++	  printf("   %ld <%d:%d> (%d) [%d]: ",
++		 lpf->addr, lpf->priority, lpf->original_priority,
++		 lpf->fragP->fr_line, count);
++	  //dump_frag(lpf->fragP);
++	}
++    }
++}
++
++static void
++xtensa_maybe_create_literal_pool_frag (bfd_boolean create,
++				       bfd_boolean only_if_needed)
++{
++  struct litpool_seg *lps = litpool_seg_list.next;
++  fragS *fragP;
++  struct litpool_frag *lpf;
++  bfd_boolean needed = FALSE;
++
++  if (use_literal_section || !auto_litpools)
++    return;
++
++  for ( ; lps ; lps = lps->next )
++    {
++      if (lps->seg == now_seg)
++	break;
++    }
++
++  if (lps == NULL)
++    {
++      lps = (struct litpool_seg *)xcalloc (sizeof (struct litpool_seg), 1);
++      lps->next = litpool_seg_list.next;
++      litpool_seg_list.next = lps;
++      lps->seg = now_seg;
++      lps->frag_list.next = &lps->frag_list;
++      lps->frag_list.prev = &lps->frag_list;
++    }
++
++  lps->frag_count++;
++
++  if (create)
++    {
++      if (only_if_needed)
++	{
++	  if (past_xtensa_end || !use_transform() ||
++	      frag_now->tc_frag_data.is_no_transform)
++	    {
++	      return;
++	    }
++	  if (auto_litpool_limit <= 0)
++	    {
++	      /* Don't create a litpool based only on frag count.  */
++	      return;
++	    }
++	  else if (lps->frag_count > auto_litpool_limit)
++	    {
++	      needed = TRUE;
++	    }
++	  else
++	    {
++	      return;
++	    }
++	}
++      else
++	{
++	  needed = TRUE;
++	}
++    }
++
++  if (needed)
++    {
++      int size = (only_if_needed) ? 3 : 0; /* Space for a "j" insn.  */
++      /* Create a potential site for a literal pool.  */
++      frag_wane (frag_now);
++      frag_new (0);
++      xtensa_set_frag_assembly_state (frag_now);
++      fragP = frag_now;
++      fragP->tc_frag_data.lit_frchain = frchain_now;
++      fragP->tc_frag_data.literal_frag = fragP;
++      frag_var (rs_machine_dependent, size, size,
++		    (only_if_needed) ?
++		        RELAX_LITERAL_POOL_CANDIDATE_BEGIN :
++		        RELAX_LITERAL_POOL_BEGIN,
++		    NULL, 0, NULL);
++      frag_now->tc_frag_data.lit_seg = now_seg;
++      frag_variant (rs_machine_dependent, 0, 0,
++		    RELAX_LITERAL_POOL_END, NULL, 0, NULL);
++      xtensa_set_frag_assembly_state (frag_now);
++    }
++  else
++    {
++      /* RELAX_LITERAL_POOL_BEGIN frag is being created;
++	 just record it here.  */
++      fragP = frag_now;
++    }
++
++  lpf = (struct litpool_frag *)xmalloc(sizeof (struct litpool_frag));
++  /* Insert at tail of circular list.  */
++  lpf->addr = 0;
++  lps->frag_list.prev->next = lpf;
++  lpf->next = &lps->frag_list;
++  lpf->prev = lps->frag_list.prev;
++  lps->frag_list.prev = lpf;
++  lpf->fragP = fragP;
++  lpf->priority = (needed) ? (only_if_needed) ? 3 : 2 : 1;
++  lpf->original_priority = lpf->priority;
++
++  lps->frag_count = 0;
++}
++
+ static void
+ xtensa_cleanup_align_frags (void)
+ {
+@@ -9029,7 +9266,41 @@ xtensa_relax_frag (fragS *fragP, long stretch, int *stretched_p)
+       break;
+ 
+     case RELAX_LITERAL_POOL_BEGIN:
++      if (fragP->fr_var != 0)
++	{
++	  /* We have a converted "candidate" literal pool;
++	     assemble a jump around it.  */
++	  TInsn insn;
++	  if (!litpool_slotbuf)
++	    {
++	      litpool_buf = xtensa_insnbuf_alloc (isa);
++	      litpool_slotbuf = xtensa_insnbuf_alloc (isa);
++	    }
++	  new_stretch += 3;
++	  fragP->tc_frag_data.relax_seen = FALSE; /* Need another pass.  */
++	  fragP->tc_frag_data.is_insn = TRUE;
++	  tinsn_init (&insn);
++	  insn.insn_type = ITYPE_INSN;
++	  insn.opcode = xtensa_j_opcode;
++	  insn.ntok = 1;
++	  set_expr_symbol_offset (&insn.tok[0], fragP->fr_symbol,
++				  fragP->fr_fix);
++	  fmt = xg_get_single_format (xtensa_j_opcode);
++	  tinsn_to_slotbuf (fmt, 0, &insn, litpool_slotbuf);
++	  xtensa_format_set_slot (isa, fmt, 0, litpool_buf, litpool_slotbuf);
++	  xtensa_insnbuf_to_chars (isa, litpool_buf,
++				   (unsigned char *)fragP->fr_literal +
++				   fragP->fr_fix, 3);
++	  fragP->fr_fix += 3;
++	  fragP->fr_var -= 3;
++	  /* Add a fix-up.  */
++	  fix_new (fragP, 0, 3, fragP->fr_symbol, 0, TRUE,
++		   BFD_RELOC_XTENSA_SLOT0_OP);
++	}
++      break;
++
+     case RELAX_LITERAL_POOL_END:
++    case RELAX_LITERAL_POOL_CANDIDATE_BEGIN:
+     case RELAX_MAYBE_UNREACHABLE:
+     case RELAX_MAYBE_DESIRE_ALIGN:
+       /* No relaxation required.  */
+@@ -10789,12 +11060,115 @@ xtensa_move_literals (void)
+   segT dest_seg;
+   fixS *fix, *next_fix, **fix_splice;
+   sym_list *lit;
++  struct litpool_seg *lps;
+ 
+   mark_literal_frags (literal_head->next);
+ 
+   if (use_literal_section)
+     return;
+ 
++  /* Assign addresses (rough estimates) to the potential literal pool locations
++     and create new ones if the gaps are too large.  */
++
++  for (lps = litpool_seg_list.next; lps; lps = lps->next)
++    {
++      frchainS *frchP = seg_info (lps->seg)->frchainP;
++      struct litpool_frag *lpf = lps->frag_list.next;
++      addressT addr = 0;
++
++      for ( ; frchP; frchP = frchP->frch_next)
++	{
++	  fragS *fragP;
++	  for (fragP = frchP->frch_root; fragP; fragP = fragP->fr_next)
++	    {
++	      if (lpf && fragP == lpf->fragP)
++		{
++		  gas_assert(fragP->fr_type == rs_machine_dependent &&
++			     (fragP->fr_subtype == RELAX_LITERAL_POOL_BEGIN ||
++			      fragP->fr_subtype == RELAX_LITERAL_POOL_CANDIDATE_BEGIN));
++		  /* Found a litpool location.  */
++		  lpf->addr = addr;
++		  lpf = lpf->next;
++		}
++	      if (fragP->fr_type == rs_machine_dependent &&
++		  fragP->fr_subtype == RELAX_SLOTS)
++		{
++		  int slot;
++		  for (slot = 0; slot < MAX_SLOTS; slot++)
++		    {
++		      if (fragP->tc_frag_data.literal_frags[slot])
++			{
++			  /* 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];
++			  struct litpool_frag *lp = lpf->prev;
++			  if (!lp->fragP)
++			    {
++			      break;
++			    }
++			  while (lp->fragP->fr_subtype ==
++				 RELAX_LITERAL_POOL_CANDIDATE_BEGIN)
++			    {
++			      lp = lp->prev;
++			      if (lp->fragP == NULL)
++				{
++				  /* End of list; have to bite the bullet.
++				     Take the nearest.  */
++				  lp = lpf->prev;
++				  break;
++				}
++			      /* Does it (conservatively) reach?  */
++			      if (addr - lp->addr <= 128 * 1024)
++				{
++				  if (lp->fragP->fr_subtype == RELAX_LITERAL_POOL_BEGIN)
++				    {
++				      /* Found a good one.  */
++				      break;
++				    }
++				  else if (lp->prev->fragP &&
++					   addr - lp->prev->addr > 128 * 1024)
++				    {
++				      /* 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.  */
++				    }
++				}
++			    }
++			  if (! litfrag->tc_frag_data.literal_frag)
++			    {
++			      /* Take earliest use of this literal to avoid
++				 forward refs.  */
++			      litfrag->tc_frag_data.literal_frag = lp->fragP;
++			    }
++			}
++		    }
++		}
++	      addr += fragP->fr_fix;
++	      if (fragP->fr_type == rs_fill)
++		addr += fragP->fr_offset;
++	    }
++	}
++    }
++
+   for (segment = literal_head->next; segment; segment = segment->next)
+     {
+       /* Keep the literals for .init and .fini in separate sections.  */
+@@ -10839,9 +11213,6 @@ xtensa_move_literals (void)
+       while (search_frag != frag_now)
+ 	{
+ 	  next_frag = search_frag->fr_next;
+-
+-	  /* First, move the frag out of the literal section and
+-	     to the appropriate place.  */
+ 	  if (search_frag->tc_frag_data.literal_frag)
+ 	    {
+ 	      literal_pool = search_frag->tc_frag_data.literal_frag;
+@@ -10849,8 +11220,56 @@ xtensa_move_literals (void)
+ 	      frchain_to = literal_pool->tc_frag_data.lit_frchain;
+ 	      gas_assert (frchain_to);
+ 	    }
++
++	  if (search_frag->fr_type == rs_fill && search_frag->fr_fix == 0)
++	    {
++	      /* Skip empty fill frags.  */
++	      *frag_splice = next_frag;
++	      search_frag = next_frag;
++	      continue;
++	    }
++
++	  if (search_frag->fr_type == rs_align)
++	    {
++	      /* Skip alignment frags, because the pool as a whole will be
++	         aligned if used, and we don't want to force alignment if the
++		 pool is unused.  */
++	      *frag_splice = next_frag;
++	      search_frag = next_frag;
++	      continue;
++	    }
++
++	  /* First, move the frag out of the literal section and
++	     to the appropriate place.  */
++
++	  /* Insert an aligmnent frag at start of pool.  */
++	  if (literal_pool->fr_next->fr_type == rs_machine_dependent &&
++	      literal_pool->fr_next->fr_subtype == RELAX_LITERAL_POOL_END)
++	    {
++	      segT pool_seg = literal_pool->fr_next->tc_frag_data.lit_seg;
++	      emit_state prev_state;
++	      fragS *prev_frag;
++	      fragS *align_frag;
++	      xtensa_switch_section_emit_state (&prev_state, pool_seg, 0);
++	      prev_frag = frag_now;
++	      frag_variant (rs_fill, 0, 0, 0, NULL, 0, NULL);
++	      align_frag = frag_now;
++	      frag_align (2, 0, 0);
++	      /* Splice it into the right place.  */
++	      prev_frag->fr_next = align_frag->fr_next;
++	      align_frag->fr_next = literal_pool->fr_next;
++	      literal_pool->fr_next = align_frag;
++	      /* Insert after this one.  */
++	      literal_pool->tc_frag_data.literal_frag = align_frag;
++	      xtensa_restore_emit_state (&prev_state);
++	    }
+ 	  insert_after = literal_pool->tc_frag_data.literal_frag;
+ 	  dest_seg = insert_after->fr_next->tc_frag_data.lit_seg;
++	  /* Skip align frag.  */
++	  if (insert_after->fr_next->fr_type == rs_align)
++	    {
++	      insert_after = insert_after->fr_next;
++	    }
+ 
+ 	  *frag_splice = next_frag;
+ 	  search_frag->fr_next = insert_after->fr_next;
+@@ -11014,7 +11433,10 @@ xtensa_switch_to_non_abs_literal_fragment (emit_state *result)
+       && !recursive
+       && !is_init && ! is_fini)
+     {
+-      as_bad (_("literal pool location required for text-section-literals; specify with .literal_position"));
++      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
+diff --git a/gas/config/tc-xtensa.h b/gas/config/tc-xtensa.h
+index b2e43fa..290d902 100644
+--- a/gas/config/tc-xtensa.h
++++ b/gas/config/tc-xtensa.h
+@@ -124,6 +124,7 @@ enum xtensa_relax_statesE
+ 
+   RELAX_LITERAL_POOL_BEGIN,
+   RELAX_LITERAL_POOL_END,
++  RELAX_LITERAL_POOL_CANDIDATE_BEGIN,
+   /* Technically these are not relaxations at all but mark a location
+      to store literals later.  Note that fr_var stores the frchain for
+      BEGIN frags and fr_var stores now_seg for END frags.  */
+diff --git a/gas/testsuite/gas/xtensa/all.exp b/gas/testsuite/gas/xtensa/all.exp
+index d197ec8..db39629 100644
+--- a/gas/testsuite/gas/xtensa/all.exp
++++ b/gas/testsuite/gas/xtensa/all.exp
+@@ -100,5 +100,6 @@ if [istarget xtensa*-*-*] then {
+     run_dump_test "jlong"
+     run_dump_test "trampoline"
++    run_dump_test "auto-litpools"
+ }
+ 
+ if [info exists errorInfo] then {
+diff --git a/gas/testsuite/gas/xtensa/auto-litpools.d b/gas/testsuite/gas/xtensa/auto-litpools.d
+new file mode 100644
+index 0000000..4d1a690
+--- /dev/null
++++ b/gas/testsuite/gas/xtensa/auto-litpools.d
+@@ -0,0 +1,12 @@
++#as: --auto-litpools
++#objdump: -d
++#name: auto literal pool placement
++
++.*: +file format .*xtensa.*
++#...
++.*4:.*l32r.a2, 0 .*
++#...
++.*3e437:.*j.3e440 .*
++#...
++.*40750:.*l32r.a2, 3e43c .*
++#...
+diff --git a/gas/testsuite/gas/xtensa/auto-litpools.s b/gas/testsuite/gas/xtensa/auto-litpools.s
+new file mode 100644
+index 0000000..9a5b26b
+--- /dev/null
++++ b/gas/testsuite/gas/xtensa/auto-litpools.s
+@@ -0,0 +1,13 @@
++	.text
++	.align	4
++	.literal	.L0, 0x12345
++	.literal	.L1, 0x12345
++
++f:
++	l32r	a2, .L0
++	.rep	44000
++	_nop
++	_nop
++	.endr
++	l32r	a2, .L1
++	ret
+-- 
+1.8.1.4
+
diff --git a/package/binutils/2.25.1/913-xtensa-add-auto-litpools-option.patch b/package/binutils/2.25.1/913-xtensa-add-auto-litpools-option.patch
new file mode 100644
index 0000000..3ed9af1
--- /dev/null
+++ b/package/binutils/2.25.1/913-xtensa-add-auto-litpools-option.patch
@@ -0,0 +1,699 @@
+From 978adaaa4cd3921842e2be8a31c05f081fb17fcf Mon Sep 17 00:00:00 2001
+From: Max Filippov <jcmvbkbc@gmail.com>
+Date: Wed, 29 Jul 2015 17:42:54 +0300
+Subject: [PATCH] xtensa: add --auto-litpools option
+
+Auto-litpools is the automated version of text-section-literals: literal
+pool candidate frags are planted every N frags and during relaxation
+they are turned into actual literal pools where literals are moved to
+become reachable for their first reference by L32R instruction.
+
+2015-08-12  David Weatherford  <weath@cadence.com>
+gas/
+	* config/tc-xtensa.c (struct litpool_frag, struct litpool_seg):
+	New structures.
+	(xtensa_maybe_create_literal_pool_frag): New function.
+	(litpool_seg_list, auto_litpools, auto_litpool_limit)
+	(litpool_buf, litpool_slotbuf): New static variables.
+	(option_auto_litpools, option_no_auto_litpools)
+	(option_auto_litpool_limit): New enum identifiers.
+	(md_longopts): Add entries for auto-litpools, no-auto-litpools
+	and auto-litpool-limit.
+	(md_parse_option): Handle option_auto_litpools,
+	option_no_auto_litpools and option_auto_litpool_limit.
+	(md_show_usage): Add help for --[no-]auto-litpools and
+	--auto-litpool-limit.
+	(xtensa_mark_literal_pool_location): Record a place for literal
+	pool with a call to xtensa_maybe_create_literal_pool_frag.
+	(get_literal_pool_location): Find highest priority literal pool
+	or convert candidate to literal pool when auto-litpools are used.
+	(xg_assemble_vliw_tokens): Create literal pool after jump
+	instruction.
+	(xtensa_check_frag_count): Create candidate literal pool every
+	auto_litpool_limit frags.
+	(xtensa_relax_frag): Add jump around literals to non-empty
+	literal pool.
+	(xtensa_move_literals): Estimate literal pool addresses and move
+	unreachable literals closer to their users, converting candidate
+	to literal pool if needed.
+	(xtensa_switch_to_non_abs_literal_fragment): Only emit error
+	about missing .literal_position in case auto-litpools are not
+	used.
+	* config/tc-xtensa.h (xtensa_relax_statesE): New relaxation
+	state: RELAX_LITERAL_POOL_CANDIDATE_BEGIN.
+
+2015-08-12  Max Filippov  <jcmvbkbc@gmail.com>
+gas/testsuite/
+	* gas/xtensa/all.exp: Add auto-litpools to the list of xtensa
+	tests.
+	* gas/xtensa/auto-litpools.s: New file: auto-litpools test.
+	* gas/xtensa/auto-litpools.s: New file: auto-litpools test
+	result pattern.
+
+Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
+---
+Backported from: b46824bd49648c575372e6d9bc6a6defeabd6ed5
+Changes to ChangeLogs and documentation are dropped.
+
+ gas/config/tc-xtensa.c                   | 432 ++++++++++++++++++++++++++++++-
+ gas/config/tc-xtensa.h                   |   1 +
+ gas/testsuite/gas/xtensa/all.exp         |   1 +
+ gas/testsuite/gas/xtensa/auto-litpools.d |  12 +
+ gas/testsuite/gas/xtensa/auto-litpools.s |  13 +
+ 5 files changed, 454 insertions(+), 5 deletions(-)
+ create mode 100644 gas/testsuite/gas/xtensa/auto-litpools.d
+ create mode 100644 gas/testsuite/gas/xtensa/auto-litpools.s
+
+diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c
+index 7311a05..b8b1e7d 100644
+--- a/gas/config/tc-xtensa.c
++++ b/gas/config/tc-xtensa.c
+@@ -440,6 +440,29 @@ bfd_boolean directive_state[] =
+ #endif
+ };
+ 
++/* A circular list of all potential and actual literal pool locations
++   in a segment.  */
++struct litpool_frag
++{
++  struct litpool_frag *next;
++  struct litpool_frag *prev;
++  fragS *fragP;
++  addressT addr;
++  short priority; /* 1, 2, or 3 -- 1 is highest  */
++  short original_priority;
++};
++
++/* Map a segment to its litpool_frag list.  */
++struct litpool_seg
++{
++  struct litpool_seg *next;
++  asection *seg;
++  struct litpool_frag frag_list;
++  int frag_count; /* since last litpool location  */
++};
++
++static struct litpool_seg litpool_seg_list;
++
+ 
+ /* Directive functions.  */
+ 
+@@ -474,6 +497,9 @@ static void xtensa_create_trampoline_frag (bfd_boolean);
+ static void xtensa_maybe_create_trampoline_frag (void);
+ struct trampoline_frag;
+ static int init_trampoline_frag (struct trampoline_frag *);
++static void xtensa_maybe_create_literal_pool_frag (bfd_boolean, bfd_boolean);
++static bfd_boolean auto_litpools = FALSE;
++static int auto_litpool_limit = 10000;
+ 
+ /* Alignment Functions.  */
+ 
+@@ -698,6 +724,10 @@ enum
+ 
+   option_trampolines,
+   option_no_trampolines,
++
++  option_auto_litpools,
++  option_no_auto_litpools,
++  option_auto_litpool_limit,
+ };
+ 
+ const char *md_shortopts = "";
+@@ -773,6 +803,10 @@ struct option md_longopts[] =
+   { "trampolines", no_argument, NULL, option_trampolines },
+   { "no-trampolines", no_argument, NULL, option_no_trampolines },
+ 
++  { "auto-litpools", no_argument, NULL, option_auto_litpools },
++  { "no-auto-litpools", no_argument, NULL, option_no_auto_litpools },
++  { "auto-litpool-limit", required_argument, NULL, option_auto_litpool_limit },
++
+   { NULL, no_argument, NULL, 0 }
+ };
+ 
+@@ -961,6 +995,34 @@ md_parse_option (int c, char *arg)
+       use_trampolines = FALSE;
+       return 1;
+ 
++    case option_auto_litpools:
++      auto_litpools = TRUE;
++      use_literal_section = FALSE;
++      return 1;
++
++    case option_no_auto_litpools:
++      auto_litpools = FALSE;
++      auto_litpool_limit = -1;
++      return 1;
++
++    case option_auto_litpool_limit:
++      {
++	int value = 0;
++	if (auto_litpool_limit < 0)
++	  as_fatal (_("no-auto-litpools is incompatible with auto-litpool-limit"));
++	if (*arg == 0 || *arg == '-')
++	  as_fatal (_("invalid auto-litpool-limit argument"));
++	value = strtol (arg, &arg, 10);
++	if (*arg != 0)
++	  as_fatal (_("invalid auto-litpool-limit argument"));
++	if (value < 100 || value > 10000)
++	  as_fatal (_("invalid auto-litpool-limit argument (range is 100-10000)"));
++	auto_litpool_limit = value;
++	auto_litpools = TRUE;
++	use_literal_section = FALSE;
++	return 1;
++      }
++
+     default:
+       return 0;
+     }
+@@ -986,7 +1048,12 @@ Xtensa options:\n\
+                           flix bundles\n\
+   --rename-section old=new Rename section 'old' to 'new'\n\
+   --[no-]trampolines      [Do not] generate trampolines (jumps to jumps)\n\
+-                          when jumps do not reach their targets\n", stream);
++                          when jumps do not reach their targets\n\
++  --[no-]auto-litpools    [Do not] automatically create literal pools\n\
++  --auto-litpool-limit=<value>\n\
++                          (range 100-10000) Maximum number of blocks of\n\
++                          instructions to emit between literal pool\n\
++                          locations; implies --auto-litpools flag\n", stream);
+ }
+ 
+ \f
+@@ -4728,6 +4795,8 @@ xtensa_mark_literal_pool_location (void)
+   pool_location = frag_now;
+   frag_now->tc_frag_data.lit_frchain = frchain_now;
+   frag_now->tc_frag_data.literal_frag = frag_now;
++  /* Just record this frag.  */
++  xtensa_maybe_create_literal_pool_frag (FALSE, FALSE);
+   frag_variant (rs_machine_dependent, 0, 0,
+ 		RELAX_LITERAL_POOL_BEGIN, NULL, 0, NULL);
+   xtensa_set_frag_assembly_state (frag_now);
+@@ -4832,6 +4901,31 @@ get_expanded_loop_offset (xtensa_opcode opcode)
+ static fragS *
+ get_literal_pool_location (segT seg)
+ {
++  struct litpool_seg *lps = litpool_seg_list.next;
++  struct litpool_frag *lpf;
++  for ( ; lps && lps->seg->id != seg->id; lps = lps->next)
++    ;
++  if (lps)
++    {
++      for (lpf = lps->frag_list.prev; lpf->fragP; lpf = lpf->prev)
++	{ /* Skip "candidates" for now.  */
++	  if (lpf->fragP->fr_subtype == RELAX_LITERAL_POOL_BEGIN &&
++	      lpf->priority == 1)
++	    return lpf->fragP;
++	}
++      /* Must convert a lower-priority pool.  */
++      for (lpf = lps->frag_list.prev; lpf->fragP; lpf = lpf->prev)
++	{
++	  if (lpf->fragP->fr_subtype == RELAX_LITERAL_POOL_BEGIN)
++	    return lpf->fragP;
++	}
++      /* Still no match -- try for a low priority pool.  */
++      for (lpf = lps->frag_list.prev; lpf->fragP; lpf = lpf->prev)
++	{
++	  if (lpf->fragP->fr_subtype == RELAX_LITERAL_POOL_CANDIDATE_BEGIN)
++	    return lpf->fragP;
++	}
++    }
+   return seg_info (seg)->tc_segment_info_data.literal_pool_loc;
+ }
+ 
+@@ -7098,6 +7192,11 @@ xg_assemble_vliw_tokens (vliw_insn *vinsn)
+       frag_now->tc_frag_data.slot_symbols[slot] = tinsn->symbol;
+       frag_now->tc_frag_data.slot_offsets[slot] = tinsn->offset;
+       frag_now->tc_frag_data.literal_frags[slot] = tinsn->literal_frag;
++      if (tinsn->opcode == xtensa_l32r_opcode)
++	{
++	  frag_now->tc_frag_data.literal_frags[slot] =
++		  tinsn->tok[1].X_add_symbol->sy_frag;
++	}
+       if (tinsn->literal_space != 0)
+ 	xg_assemble_literal_space (tinsn->literal_space, slot);
+       frag_now->tc_frag_data.free_reg[slot] = tinsn->extra_arg;
+@@ -7170,6 +7269,8 @@ xg_assemble_vliw_tokens (vliw_insn *vinsn)
+ 		    frag_now->fr_symbol, frag_now->fr_offset, NULL);
+ 	  xtensa_set_frag_assembly_state (frag_now);
+ 	  xtensa_maybe_create_trampoline_frag ();
++	  /* Always create one here.  */
++	  xtensa_maybe_create_literal_pool_frag (TRUE, FALSE);
+ 	}
+       else if (is_branch && do_align_targets ())
+ 	{
+@@ -7314,11 +7415,18 @@ xtensa_check_frag_count (void)
+       clear_frag_count ();
+       unreachable_count = 0;
+     }
++
++  /* We create an area for a possible literal pool every N (default 5000)
++     frags or so.  */
++  xtensa_maybe_create_literal_pool_frag (TRUE, TRUE);
+ }
+ 
+ static xtensa_insnbuf trampoline_buf = NULL;
+ static xtensa_insnbuf trampoline_slotbuf = NULL;
+ 
++static xtensa_insnbuf litpool_buf = NULL;
++static xtensa_insnbuf litpool_slotbuf = NULL;
++
+ #define TRAMPOLINE_FRAG_SIZE 3000
+ 
+ static void
+@@ -7410,6 +7518,135 @@ dump_trampolines (void)
+     }
+ }
+ 
++static void dump_litpools (void) __attribute__ ((unused));
++
++static void
++dump_litpools (void)
++{
++  struct litpool_seg *lps = litpool_seg_list.next;
++  struct litpool_frag *lpf;
++
++  for ( ; lps ; lps = lps->next )
++    {
++      printf("litpool seg %s\n", lps->seg->name);
++      for ( lpf = lps->frag_list.next; lpf->fragP; lpf = lpf->next )
++	{
++	  fragS *litfrag = lpf->fragP->fr_next;
++	  int count = 0;
++	  while (litfrag && litfrag->fr_subtype != RELAX_LITERAL_POOL_END)
++	    {
++	      if (litfrag->fr_fix == 4)
++		count++;
++	      litfrag = litfrag->fr_next;
++	    }
++	  printf("   %ld <%d:%d> (%d) [%d]: ",
++		 lpf->addr, lpf->priority, lpf->original_priority,
++		 lpf->fragP->fr_line, count);
++	  //dump_frag(lpf->fragP);
++	}
++    }
++}
++
++static void
++xtensa_maybe_create_literal_pool_frag (bfd_boolean create,
++				       bfd_boolean only_if_needed)
++{
++  struct litpool_seg *lps = litpool_seg_list.next;
++  fragS *fragP;
++  struct litpool_frag *lpf;
++  bfd_boolean needed = FALSE;
++
++  if (use_literal_section || !auto_litpools)
++    return;
++
++  for ( ; lps ; lps = lps->next )
++    {
++      if (lps->seg == now_seg)
++	break;
++    }
++
++  if (lps == NULL)
++    {
++      lps = (struct litpool_seg *)xcalloc (sizeof (struct litpool_seg), 1);
++      lps->next = litpool_seg_list.next;
++      litpool_seg_list.next = lps;
++      lps->seg = now_seg;
++      lps->frag_list.next = &lps->frag_list;
++      lps->frag_list.prev = &lps->frag_list;
++    }
++
++  lps->frag_count++;
++
++  if (create)
++    {
++      if (only_if_needed)
++	{
++	  if (past_xtensa_end || !use_transform() ||
++	      frag_now->tc_frag_data.is_no_transform)
++	    {
++	      return;
++	    }
++	  if (auto_litpool_limit <= 0)
++	    {
++	      /* Don't create a litpool based only on frag count.  */
++	      return;
++	    }
++	  else if (lps->frag_count > auto_litpool_limit)
++	    {
++	      needed = TRUE;
++	    }
++	  else
++	    {
++	      return;
++	    }
++	}
++      else
++	{
++	  needed = TRUE;
++	}
++    }
++
++  if (needed)
++    {
++      int size = (only_if_needed) ? 3 : 0; /* Space for a "j" insn.  */
++      /* Create a potential site for a literal pool.  */
++      frag_wane (frag_now);
++      frag_new (0);
++      xtensa_set_frag_assembly_state (frag_now);
++      fragP = frag_now;
++      fragP->tc_frag_data.lit_frchain = frchain_now;
++      fragP->tc_frag_data.literal_frag = fragP;
++      frag_var (rs_machine_dependent, size, size,
++		    (only_if_needed) ?
++		        RELAX_LITERAL_POOL_CANDIDATE_BEGIN :
++		        RELAX_LITERAL_POOL_BEGIN,
++		    NULL, 0, NULL);
++      frag_now->tc_frag_data.lit_seg = now_seg;
++      frag_variant (rs_machine_dependent, 0, 0,
++		    RELAX_LITERAL_POOL_END, NULL, 0, NULL);
++      xtensa_set_frag_assembly_state (frag_now);
++    }
++  else
++    {
++      /* RELAX_LITERAL_POOL_BEGIN frag is being created;
++	 just record it here.  */
++      fragP = frag_now;
++    }
++
++  lpf = (struct litpool_frag *)xmalloc(sizeof (struct litpool_frag));
++  /* Insert at tail of circular list.  */
++  lpf->addr = 0;
++  lps->frag_list.prev->next = lpf;
++  lpf->next = &lps->frag_list;
++  lpf->prev = lps->frag_list.prev;
++  lps->frag_list.prev = lpf;
++  lpf->fragP = fragP;
++  lpf->priority = (needed) ? (only_if_needed) ? 3 : 2 : 1;
++  lpf->original_priority = lpf->priority;
++
++  lps->frag_count = 0;
++}
++
+ static void
+ xtensa_cleanup_align_frags (void)
+ {
+@@ -9029,7 +9266,41 @@ xtensa_relax_frag (fragS *fragP, long stretch, int *stretched_p)
+       break;
+ 
+     case RELAX_LITERAL_POOL_BEGIN:
++      if (fragP->fr_var != 0)
++	{
++	  /* We have a converted "candidate" literal pool;
++	     assemble a jump around it.  */
++	  TInsn insn;
++	  if (!litpool_slotbuf)
++	    {
++	      litpool_buf = xtensa_insnbuf_alloc (isa);
++	      litpool_slotbuf = xtensa_insnbuf_alloc (isa);
++	    }
++	  new_stretch += 3;
++	  fragP->tc_frag_data.relax_seen = FALSE; /* Need another pass.  */
++	  fragP->tc_frag_data.is_insn = TRUE;
++	  tinsn_init (&insn);
++	  insn.insn_type = ITYPE_INSN;
++	  insn.opcode = xtensa_j_opcode;
++	  insn.ntok = 1;
++	  set_expr_symbol_offset (&insn.tok[0], fragP->fr_symbol,
++				  fragP->fr_fix);
++	  fmt = xg_get_single_format (xtensa_j_opcode);
++	  tinsn_to_slotbuf (fmt, 0, &insn, litpool_slotbuf);
++	  xtensa_format_set_slot (isa, fmt, 0, litpool_buf, litpool_slotbuf);
++	  xtensa_insnbuf_to_chars (isa, litpool_buf,
++				   (unsigned char *)fragP->fr_literal +
++				   fragP->fr_fix, 3);
++	  fragP->fr_fix += 3;
++	  fragP->fr_var -= 3;
++	  /* Add a fix-up.  */
++	  fix_new (fragP, 0, 3, fragP->fr_symbol, 0, TRUE,
++		   BFD_RELOC_XTENSA_SLOT0_OP);
++	}
++      break;
++
+     case RELAX_LITERAL_POOL_END:
++    case RELAX_LITERAL_POOL_CANDIDATE_BEGIN:
+     case RELAX_MAYBE_UNREACHABLE:
+     case RELAX_MAYBE_DESIRE_ALIGN:
+       /* No relaxation required.  */
+@@ -10789,12 +11060,115 @@ xtensa_move_literals (void)
+   segT dest_seg;
+   fixS *fix, *next_fix, **fix_splice;
+   sym_list *lit;
++  struct litpool_seg *lps;
+ 
+   mark_literal_frags (literal_head->next);
+ 
+   if (use_literal_section)
+     return;
+ 
++  /* Assign addresses (rough estimates) to the potential literal pool locations
++     and create new ones if the gaps are too large.  */
++
++  for (lps = litpool_seg_list.next; lps; lps = lps->next)
++    {
++      frchainS *frchP = seg_info (lps->seg)->frchainP;
++      struct litpool_frag *lpf = lps->frag_list.next;
++      addressT addr = 0;
++
++      for ( ; frchP; frchP = frchP->frch_next)
++	{
++	  fragS *fragP;
++	  for (fragP = frchP->frch_root; fragP; fragP = fragP->fr_next)
++	    {
++	      if (lpf && fragP == lpf->fragP)
++		{
++		  gas_assert(fragP->fr_type == rs_machine_dependent &&
++			     (fragP->fr_subtype == RELAX_LITERAL_POOL_BEGIN ||
++			      fragP->fr_subtype == RELAX_LITERAL_POOL_CANDIDATE_BEGIN));
++		  /* Found a litpool location.  */
++		  lpf->addr = addr;
++		  lpf = lpf->next;
++		}
++	      if (fragP->fr_type == rs_machine_dependent &&
++		  fragP->fr_subtype == RELAX_SLOTS)
++		{
++		  int slot;
++		  for (slot = 0; slot < MAX_SLOTS; slot++)
++		    {
++		      if (fragP->tc_frag_data.literal_frags[slot])
++			{
++			  /* 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];
++			  struct litpool_frag *lp = lpf->prev;
++			  if (!lp->fragP)
++			    {
++			      break;
++			    }
++			  while (lp->fragP->fr_subtype ==
++				 RELAX_LITERAL_POOL_CANDIDATE_BEGIN)
++			    {
++			      lp = lp->prev;
++			      if (lp->fragP == NULL)
++				{
++				  /* End of list; have to bite the bullet.
++				     Take the nearest.  */
++				  lp = lpf->prev;
++				  break;
++				}
++			      /* Does it (conservatively) reach?  */
++			      if (addr - lp->addr <= 128 * 1024)
++				{
++				  if (lp->fragP->fr_subtype == RELAX_LITERAL_POOL_BEGIN)
++				    {
++				      /* Found a good one.  */
++				      break;
++				    }
++				  else if (lp->prev->fragP &&
++					   addr - lp->prev->addr > 128 * 1024)
++				    {
++				      /* 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.  */
++				    }
++				}
++			    }
++			  if (! litfrag->tc_frag_data.literal_frag)
++			    {
++			      /* Take earliest use of this literal to avoid
++				 forward refs.  */
++			      litfrag->tc_frag_data.literal_frag = lp->fragP;
++			    }
++			}
++		    }
++		}
++	      addr += fragP->fr_fix;
++	      if (fragP->fr_type == rs_fill)
++		addr += fragP->fr_offset;
++	    }
++	}
++    }
++
+   for (segment = literal_head->next; segment; segment = segment->next)
+     {
+       /* Keep the literals for .init and .fini in separate sections.  */
+@@ -10839,9 +11213,6 @@ xtensa_move_literals (void)
+       while (search_frag != frag_now)
+ 	{
+ 	  next_frag = search_frag->fr_next;
+-
+-	  /* First, move the frag out of the literal section and
+-	     to the appropriate place.  */
+ 	  if (search_frag->tc_frag_data.literal_frag)
+ 	    {
+ 	      literal_pool = search_frag->tc_frag_data.literal_frag;
+@@ -10849,8 +11220,56 @@ xtensa_move_literals (void)
+ 	      frchain_to = literal_pool->tc_frag_data.lit_frchain;
+ 	      gas_assert (frchain_to);
+ 	    }
++
++	  if (search_frag->fr_type == rs_fill && search_frag->fr_fix == 0)
++	    {
++	      /* Skip empty fill frags.  */
++	      *frag_splice = next_frag;
++	      search_frag = next_frag;
++	      continue;
++	    }
++
++	  if (search_frag->fr_type == rs_align)
++	    {
++	      /* Skip alignment frags, because the pool as a whole will be
++	         aligned if used, and we don't want to force alignment if the
++		 pool is unused.  */
++	      *frag_splice = next_frag;
++	      search_frag = next_frag;
++	      continue;
++	    }
++
++	  /* First, move the frag out of the literal section and
++	     to the appropriate place.  */
++
++	  /* Insert an aligmnent frag at start of pool.  */
++	  if (literal_pool->fr_next->fr_type == rs_machine_dependent &&
++	      literal_pool->fr_next->fr_subtype == RELAX_LITERAL_POOL_END)
++	    {
++	      segT pool_seg = literal_pool->fr_next->tc_frag_data.lit_seg;
++	      emit_state prev_state;
++	      fragS *prev_frag;
++	      fragS *align_frag;
++	      xtensa_switch_section_emit_state (&prev_state, pool_seg, 0);
++	      prev_frag = frag_now;
++	      frag_variant (rs_fill, 0, 0, 0, NULL, 0, NULL);
++	      align_frag = frag_now;
++	      frag_align (2, 0, 0);
++	      /* Splice it into the right place.  */
++	      prev_frag->fr_next = align_frag->fr_next;
++	      align_frag->fr_next = literal_pool->fr_next;
++	      literal_pool->fr_next = align_frag;
++	      /* Insert after this one.  */
++	      literal_pool->tc_frag_data.literal_frag = align_frag;
++	      xtensa_restore_emit_state (&prev_state);
++	    }
+ 	  insert_after = literal_pool->tc_frag_data.literal_frag;
+ 	  dest_seg = insert_after->fr_next->tc_frag_data.lit_seg;
++	  /* Skip align frag.  */
++	  if (insert_after->fr_next->fr_type == rs_align)
++	    {
++	      insert_after = insert_after->fr_next;
++	    }
+ 
+ 	  *frag_splice = next_frag;
+ 	  search_frag->fr_next = insert_after->fr_next;
+@@ -11014,7 +11433,10 @@ xtensa_switch_to_non_abs_literal_fragment (emit_state *result)
+       && !recursive
+       && !is_init && ! is_fini)
+     {
+-      as_bad (_("literal pool location required for text-section-literals; specify with .literal_position"));
++      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
+diff --git a/gas/config/tc-xtensa.h b/gas/config/tc-xtensa.h
+index b2e43fa..290d902 100644
+--- a/gas/config/tc-xtensa.h
++++ b/gas/config/tc-xtensa.h
+@@ -124,6 +124,7 @@ enum xtensa_relax_statesE
+ 
+   RELAX_LITERAL_POOL_BEGIN,
+   RELAX_LITERAL_POOL_END,
++  RELAX_LITERAL_POOL_CANDIDATE_BEGIN,
+   /* Technically these are not relaxations at all but mark a location
+      to store literals later.  Note that fr_var stores the frchain for
+      BEGIN frags and fr_var stores now_seg for END frags.  */
+diff --git a/gas/testsuite/gas/xtensa/all.exp b/gas/testsuite/gas/xtensa/all.exp
+index d197ec8..db39629 100644
+--- a/gas/testsuite/gas/xtensa/all.exp
++++ b/gas/testsuite/gas/xtensa/all.exp
+@@ -100,6 +100,7 @@ if [istarget xtensa*-*-*] then {
+     run_dump_test "jlong"
+     run_dump_test "trampoline"
+     run_dump_test "first_frag_align"
++    run_dump_test "auto-litpools"
+ }
+ 
+ if [info exists errorInfo] then {
+diff --git a/gas/testsuite/gas/xtensa/auto-litpools.d b/gas/testsuite/gas/xtensa/auto-litpools.d
+new file mode 100644
+index 0000000..4d1a690
+--- /dev/null
++++ b/gas/testsuite/gas/xtensa/auto-litpools.d
+@@ -0,0 +1,12 @@
++#as: --auto-litpools
++#objdump: -d
++#name: auto literal pool placement
++
++.*: +file format .*xtensa.*
++#...
++.*4:.*l32r.a2, 0 .*
++#...
++.*3e437:.*j.3e440 .*
++#...
++.*40750:.*l32r.a2, 3e43c .*
++#...
+diff --git a/gas/testsuite/gas/xtensa/auto-litpools.s b/gas/testsuite/gas/xtensa/auto-litpools.s
+new file mode 100644
+index 0000000..9a5b26b
+--- /dev/null
++++ b/gas/testsuite/gas/xtensa/auto-litpools.s
+@@ -0,0 +1,13 @@
++	.text
++	.align	4
++	.literal	.L0, 0x12345
++	.literal	.L1, 0x12345
++
++f:
++	l32r	a2, .L0
++	.rep	44000
++	_nop
++	_nop
++	.endr
++	l32r	a2, .L1
++	ret
+-- 
+1.8.1.4
+
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [Buildroot] [PATCH 2/4] gcc: backport mauto-litpools xtensa option
  2015-08-12 22:19 [Buildroot] [PATCH 0/4] xtensa: toolchain fix for compiling huge functions Max Filippov
  2015-08-12 22:20 ` [Buildroot] [PATCH 1/4] binutils: backport auto-litpools xtensa gas option Max Filippov
@ 2015-08-12 22:20 ` Max Filippov
  2015-08-12 22:20 ` [Buildroot] [PATCH 3/4] xtensa: switch from text-section-literals to auto-litpools Max Filippov
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 9+ messages in thread
From: Max Filippov @ 2015-08-12 22:20 UTC (permalink / raw)
  To: buildroot

With support from assembler this option allows compiling huge functions,
where single literal pool at the beginning of a function may not be
reachable by L32R instructions at its end.

Currently assembler --auto-litpools option cannot deal with literals
used from multiple locations separated by more than 256 KBytes of code.
Don't turn constants into literals, instead use MOVI instruction to load
them into registers and let the assembler turn them into literals as
necessary.

Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
---
 .../870-xtensa-add-mauto-litpools-option.patch     | 290 +++++++++++++++++++++
 .../870-xtensa-add-mauto-litpools-option.patch     | 290 +++++++++++++++++++++
 .../870-xtensa-add-mauto-litpools-option.patch     | 290 +++++++++++++++++++++
 3 files changed, 870 insertions(+)
 create mode 100644 package/gcc/4.8.5/870-xtensa-add-mauto-litpools-option.patch
 create mode 100644 package/gcc/4.9.3/870-xtensa-add-mauto-litpools-option.patch
 create mode 100644 package/gcc/5.2.0/870-xtensa-add-mauto-litpools-option.patch

diff --git a/package/gcc/4.8.5/870-xtensa-add-mauto-litpools-option.patch b/package/gcc/4.8.5/870-xtensa-add-mauto-litpools-option.patch
new file mode 100644
index 0000000..aa1376c
--- /dev/null
+++ b/package/gcc/4.8.5/870-xtensa-add-mauto-litpools-option.patch
@@ -0,0 +1,290 @@
+From 6d852ffb43b111a39162135c95249e749c4e285b Mon Sep 17 00:00:00 2001
+From: Max Filippov <jcmvbkbc@gmail.com>
+Date: Thu, 6 Aug 2015 01:16:02 +0300
+Subject: [PATCH] xtensa: add -mauto-litpools option
+
+With support from assembler this option allows compiling huge functions,
+where single literal pool at the beginning of a function may not be
+reachable by L32R instructions at its end.
+
+Currently assembler --auto-litpools option cannot deal with literals
+used from multiple locations separated by more than 256 KBytes of code.
+Don't turn constants into literals, instead use MOVI instruction to load
+them into registers and let the assembler turn them into literals as
+necessary.
+
+2015-08-12  Max Filippov  <jcmvbkbc@gmail.com>
+gcc/
+	* config/xtensa/constraints.md (define_constraint "Y"): New
+	constraint.
+	* config/xtensa/elf.h (ASM_SPEC): Add m(no-)auto-litpools.
+	* config/xtensa/linux.h (ASM_SPEC): Likewise.
+	* config/xtensa/predicates.md (move_operand): Match constants
+	and symbols in the presence of TARGET_AUTO_LITPOOLS.
+	* config/xtensa/xtensa.c (xtensa_valid_move): Don't allow
+	immediate references to TLS data.
+	(xtensa_emit_move_sequence): Don't force constants to memory in
+	the presence of TARGET_AUTO_LITPOOLS.
+	(print_operand): Add 'y' format, same as default, but capable of
+	printing SF mode constants as well.
+	* config/xtensa/xtensa.md (movsi_internal, movhi_internal)
+	(movsf_internal): Add movi pattern that loads literal.
+	(movsf, movdf): Don't force constants to memory in the presence
+	of TARGET_AUTO_LITPOOLS.
+	(movdf_internal): Add 'Y' constraint.
+	* config/xtensa/xtensa.opt (mauto-litpools): New option.
+
+Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
+---
+Backported from: r226828
+Changes to ChangeLogs and documentation are dropped.
+
+ gcc/config/xtensa/constraints.md |  5 +++++
+ gcc/config/xtensa/elf.h          |  4 +++-
+ gcc/config/xtensa/linux.h        |  4 +++-
+ gcc/config/xtensa/predicates.md  |  3 ++-
+ gcc/config/xtensa/xtensa.c       | 19 ++++++++++++++++++-
+ gcc/config/xtensa/xtensa.md      | 35 +++++++++++++++++++----------------
+ gcc/config/xtensa/xtensa.opt     |  4 ++++
+ 7 files changed, 54 insertions(+), 20 deletions(-)
+
+diff --git a/gcc/config/xtensa/constraints.md b/gcc/config/xtensa/constraints.md
+index 30f4c1f..773d4f9 100644
+--- a/gcc/config/xtensa/constraints.md
++++ b/gcc/config/xtensa/constraints.md
+@@ -111,6 +111,11 @@
+  (and (match_code "const_int")
+       (match_test "xtensa_mask_immediate (ival)")))
+ 
++(define_constraint "Y"
++ "A constant that can be used in relaxed MOVI instructions."
++ (and (match_code "const_int,const_double,const,symbol_ref,label_ref")
++      (match_test "TARGET_AUTO_LITPOOLS")))
++
+ ;; Memory constraints.  Do not use define_memory_constraint here.  Doing so
+ ;; causes reload to force some constants into the constant pool, but since
+ ;; the Xtensa constant pool can only be accessed with L32R instructions, it
+diff --git a/gcc/config/xtensa/elf.h b/gcc/config/xtensa/elf.h
+index e59bede..12056f7 100644
+--- a/gcc/config/xtensa/elf.h
++++ b/gcc/config/xtensa/elf.h
+@@ -48,7 +48,9 @@ along with GCC; see the file COPYING3.  If not see
+   %{mtarget-align:--target-align} \
+   %{mno-target-align:--no-target-align} \
+   %{mlongcalls:--longcalls} \
+-  %{mno-longcalls:--no-longcalls}"
++  %{mno-longcalls:--no-longcalls} \
++  %{mauto-litpools:--auto-litpools} \
++  %{mno-auto-litpools:--no-auto-litpools}"
+ 
+ #undef LIB_SPEC
+ #define LIB_SPEC "-lc -lsim -lc -lhandlers-sim -lhal"
+diff --git a/gcc/config/xtensa/linux.h b/gcc/config/xtensa/linux.h
+index 675aacf..5b0243a 100644
+--- a/gcc/config/xtensa/linux.h
++++ b/gcc/config/xtensa/linux.h
+@@ -42,7 +42,9 @@ along with GCC; see the file COPYING3.  If not see
+   %{mtarget-align:--target-align} \
+   %{mno-target-align:--no-target-align} \
+   %{mlongcalls:--longcalls} \
+-  %{mno-longcalls:--no-longcalls}"
++  %{mno-longcalls:--no-longcalls} \
++  %{mauto-litpools:--auto-litpools} \
++  %{mno-auto-litpools:--no-auto-litpools}"
+ 
+ #define GLIBC_DYNAMIC_LINKER "/lib/ld.so.1"
+ 
+diff --git a/gcc/config/xtensa/predicates.md b/gcc/config/xtensa/predicates.md
+index e02209e..d7dfa11 100644
+--- a/gcc/config/xtensa/predicates.md
++++ b/gcc/config/xtensa/predicates.md
+@@ -142,7 +142,8 @@
+ 	       (match_test "GET_MODE_CLASS (mode) == MODE_INT
+ 			    && xtensa_simm12b (INTVAL (op))"))
+ 	  (and (match_code "const_int,const_double,const,symbol_ref,label_ref")
+-	       (match_test "TARGET_CONST16 && CONSTANT_P (op)
++	       (match_test "(TARGET_CONST16 || TARGET_AUTO_LITPOOLS)
++			    && CONSTANT_P (op)
+ 			    && GET_MODE_SIZE (mode) % UNITS_PER_WORD == 0")))))
+ 
+ ;; Accept the floating point constant 1 in the appropriate mode.
+diff --git a/gcc/config/xtensa/xtensa.c b/gcc/config/xtensa/xtensa.c
+index eb039ba..206ff80 100644
+--- a/gcc/config/xtensa/xtensa.c
++++ b/gcc/config/xtensa/xtensa.c
+@@ -501,6 +501,9 @@ xtensa_valid_move (machine_mode mode, rtx *operands)
+     {
+       int dst_regnum = xt_true_regnum (operands[0]);
+ 
++      if (xtensa_tls_referenced_p (operands[1]))
++	return FALSE;
++
+       /* The stack pointer can only be assigned with a MOVSP opcode.  */
+       if (dst_regnum == STACK_POINTER_REGNUM)
+ 	return !TARGET_WINDOWED_ABI
+@@ -1069,7 +1072,7 @@ xtensa_emit_move_sequence (rtx *operands, machine_mode mode)
+ 	  return 1;
+ 	}
+ 
+-      if (! TARGET_CONST16)
++      if (! TARGET_AUTO_LITPOOLS && ! TARGET_CONST16)
+ 	{
+ 	  src = force_const_mem (SImode, src);
+ 	  operands[1] = src;
+@@ -2449,6 +2452,20 @@ print_operand (FILE *file, rtx x, int letter)
+ 	}
+       break;
+ 
++    case 'y':
++      if (GET_CODE (x) == CONST_DOUBLE &&
++	  GET_MODE (x) == SFmode)
++	{
++	  REAL_VALUE_TYPE r;
++	  long l;
++	  REAL_VALUE_FROM_CONST_DOUBLE (r, x);
++	  REAL_VALUE_TO_TARGET_SINGLE (r, l);
++	  fprintf (file, "0x%08lx", l);
++	  break;
++	}
++
++      /* fall through */
++
+     default:
+       if (GET_CODE (x) == REG || GET_CODE (x) == SUBREG)
+ 	fprintf (file, "%s", reg_names[xt_true_regnum (x)]);
+diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md
+index 6d84384..0e673a3 100644
+--- a/gcc/config/xtensa/xtensa.md
++++ b/gcc/config/xtensa/xtensa.md
+@@ -761,8 +761,8 @@
+ })
+ 
+ (define_insn "movsi_internal"
+-  [(set (match_operand:SI 0 "nonimmed_operand" "=D,D,D,D,R,R,a,q,a,W,a,a,U,*a,*A")
+-	(match_operand:SI 1 "move_operand" "M,D,d,R,D,d,r,r,I,i,T,U,r,*A,*r"))]
++  [(set (match_operand:SI 0 "nonimmed_operand" "=D,D,D,D,R,R,a,q,a,a,W,a,a,U,*a,*A")
++	(match_operand:SI 1 "move_operand" "M,D,d,R,D,d,r,r,I,Y,i,T,U,r,*A,*r"))]
+   "xtensa_valid_move (SImode, operands)"
+   "@
+    movi.n\t%0, %x1
+@@ -774,15 +774,16 @@
+    mov\t%0, %1
+    movsp\t%0, %1
+    movi\t%0, %x1
++   movi\t%0, %1
+    const16\t%0, %t1\;const16\t%0, %b1
+    %v1l32r\t%0, %1
+    %v1l32i\t%0, %1
+    %v0s32i\t%1, %0
+    rsr\t%0, ACCLO
+    wsr\t%1, ACCLO"
+-  [(set_attr "type" "move,move,move,load,store,store,move,move,move,move,load,load,store,rsr,wsr")
++  [(set_attr "type" "move,move,move,load,store,store,move,move,move,move,move,load,load,store,rsr,wsr")
+    (set_attr "mode"	"SI")
+-   (set_attr "length"	"2,2,2,2,2,2,3,3,3,6,3,3,3,3,3")])
++   (set_attr "length"	"2,2,2,2,2,2,3,3,3,3,6,3,3,3,3,3")])
+ 
+ ;; 16-bit Integer moves
+ 
+@@ -796,21 +797,22 @@
+ })
+ 
+ (define_insn "movhi_internal"
+-  [(set (match_operand:HI 0 "nonimmed_operand" "=D,D,a,a,a,U,*a,*A")
+-	(match_operand:HI 1 "move_operand" "M,d,r,I,U,r,*A,*r"))]
++  [(set (match_operand:HI 0 "nonimmed_operand" "=D,D,a,a,a,a,U,*a,*A")
++	(match_operand:HI 1 "move_operand" "M,d,r,I,Y,U,r,*A,*r"))]
+   "xtensa_valid_move (HImode, operands)"
+   "@
+    movi.n\t%0, %x1
+    mov.n\t%0, %1
+    mov\t%0, %1
+    movi\t%0, %x1
++   movi\t%0, %1
+    %v1l16ui\t%0, %1
+    %v0s16i\t%1, %0
+    rsr\t%0, ACCLO
+    wsr\t%1, ACCLO"
+-  [(set_attr "type"	"move,move,move,move,load,store,rsr,wsr")
++  [(set_attr "type"	"move,move,move,move,move,load,store,rsr,wsr")
+    (set_attr "mode"	"HI")
+-   (set_attr "length"	"2,2,3,3,3,3,3,3")])
++   (set_attr "length"	"2,2,3,3,3,3,3,3,3")])
+ 
+ ;; 8-bit Integer moves
+ 
+@@ -881,7 +883,7 @@
+ 	(match_operand:SF 1 "general_operand" ""))]
+   ""
+ {
+-  if (!TARGET_CONST16 && CONSTANT_P (operands[1]))
++  if (!TARGET_CONST16 && !TARGET_AUTO_LITPOOLS && CONSTANT_P (operands[1]))
+     operands[1] = force_const_mem (SFmode, operands[1]);
+ 
+   if ((!register_operand (operands[0], SFmode)
+@@ -896,8 +898,8 @@
+ })
+ 
+ (define_insn "movsf_internal"
+-  [(set (match_operand:SF 0 "nonimmed_operand" "=f,f,U,D,D,R,a,f,a,W,a,a,U")
+-	(match_operand:SF 1 "move_operand" "f,U,f,d,R,d,r,r,f,iF,T,U,r"))]
++  [(set (match_operand:SF 0 "nonimmed_operand" "=f,f,U,D,D,R,a,f,a,a,W,a,a,U")
++	(match_operand:SF 1 "move_operand" "f,U,f,d,R,d,r,r,f,Y,iF,T,U,r"))]
+   "((register_operand (operands[0], SFmode)
+      || register_operand (operands[1], SFmode))
+     && !(FP_REG_P (xt_true_regnum (operands[0]))
+@@ -912,13 +914,14 @@
+    mov\t%0, %1
+    wfr\t%0, %1
+    rfr\t%0, %1
++   movi\t%0, %y1
+    const16\t%0, %t1\;const16\t%0, %b1
+    %v1l32r\t%0, %1
+    %v1l32i\t%0, %1
+    %v0s32i\t%1, %0"
+-  [(set_attr "type"	"farith,fload,fstore,move,load,store,move,farith,farith,move,load,load,store")
++  [(set_attr "type"	"farith,fload,fstore,move,load,store,move,farith,farith,move,move,load,load,store")
+    (set_attr "mode"	"SF")
+-   (set_attr "length"	"3,3,3,2,2,2,3,3,3,6,3,3,3")])
++   (set_attr "length"	"3,3,3,2,2,2,3,3,3,3,6,3,3,3")])
+ 
+ (define_insn "*lsiu"
+   [(set (match_operand:SF 0 "register_operand" "=f")
+@@ -991,7 +994,7 @@
+ 	(match_operand:DF 1 "general_operand" ""))]
+   ""
+ {
+-  if (CONSTANT_P (operands[1]) && !TARGET_CONST16)
++  if (CONSTANT_P (operands[1]) && !TARGET_CONST16 && !TARGET_AUTO_LITPOOLS)
+     operands[1] = force_const_mem (DFmode, operands[1]);
+ 
+   if (!register_operand (operands[0], DFmode)
+@@ -1002,8 +1005,8 @@
+ })
+ 
+ (define_insn_and_split "movdf_internal"
+-  [(set (match_operand:DF 0 "nonimmed_operand" "=a,W,a,a,U")
+-	(match_operand:DF 1 "move_operand" "r,iF,T,U,r"))]
++  [(set (match_operand:DF 0 "nonimmed_operand" "=a,a,W,a,a,U")
++	(match_operand:DF 1 "move_operand" "r,Y,iF,T,U,r"))]
+   "register_operand (operands[0], DFmode)
+    || register_operand (operands[1], DFmode)"
+   "#"
+diff --git a/gcc/config/xtensa/xtensa.opt b/gcc/config/xtensa/xtensa.opt
+index 2fd6cee..21c6e96 100644
+--- a/gcc/config/xtensa/xtensa.opt
++++ b/gcc/config/xtensa/xtensa.opt
+@@ -38,6 +38,10 @@ mtext-section-literals
+ Target
+ Intersperse literal pools with code in the text section
+ 
++mauto-litpools
++Target Report Mask(AUTO_LITPOOLS)
++Relax literals in assembler and place them automatically in the text section
++
+ mserialize-volatile
+ Target Report Mask(SERIALIZE_VOLATILE)
+ -mno-serialize-volatile	Do not serialize volatile memory references with MEMW instructions
+-- 
+1.8.1.4
+
diff --git a/package/gcc/4.9.3/870-xtensa-add-mauto-litpools-option.patch b/package/gcc/4.9.3/870-xtensa-add-mauto-litpools-option.patch
new file mode 100644
index 0000000..aa1376c
--- /dev/null
+++ b/package/gcc/4.9.3/870-xtensa-add-mauto-litpools-option.patch
@@ -0,0 +1,290 @@
+From 6d852ffb43b111a39162135c95249e749c4e285b Mon Sep 17 00:00:00 2001
+From: Max Filippov <jcmvbkbc@gmail.com>
+Date: Thu, 6 Aug 2015 01:16:02 +0300
+Subject: [PATCH] xtensa: add -mauto-litpools option
+
+With support from assembler this option allows compiling huge functions,
+where single literal pool at the beginning of a function may not be
+reachable by L32R instructions at its end.
+
+Currently assembler --auto-litpools option cannot deal with literals
+used from multiple locations separated by more than 256 KBytes of code.
+Don't turn constants into literals, instead use MOVI instruction to load
+them into registers and let the assembler turn them into literals as
+necessary.
+
+2015-08-12  Max Filippov  <jcmvbkbc@gmail.com>
+gcc/
+	* config/xtensa/constraints.md (define_constraint "Y"): New
+	constraint.
+	* config/xtensa/elf.h (ASM_SPEC): Add m(no-)auto-litpools.
+	* config/xtensa/linux.h (ASM_SPEC): Likewise.
+	* config/xtensa/predicates.md (move_operand): Match constants
+	and symbols in the presence of TARGET_AUTO_LITPOOLS.
+	* config/xtensa/xtensa.c (xtensa_valid_move): Don't allow
+	immediate references to TLS data.
+	(xtensa_emit_move_sequence): Don't force constants to memory in
+	the presence of TARGET_AUTO_LITPOOLS.
+	(print_operand): Add 'y' format, same as default, but capable of
+	printing SF mode constants as well.
+	* config/xtensa/xtensa.md (movsi_internal, movhi_internal)
+	(movsf_internal): Add movi pattern that loads literal.
+	(movsf, movdf): Don't force constants to memory in the presence
+	of TARGET_AUTO_LITPOOLS.
+	(movdf_internal): Add 'Y' constraint.
+	* config/xtensa/xtensa.opt (mauto-litpools): New option.
+
+Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
+---
+Backported from: r226828
+Changes to ChangeLogs and documentation are dropped.
+
+ gcc/config/xtensa/constraints.md |  5 +++++
+ gcc/config/xtensa/elf.h          |  4 +++-
+ gcc/config/xtensa/linux.h        |  4 +++-
+ gcc/config/xtensa/predicates.md  |  3 ++-
+ gcc/config/xtensa/xtensa.c       | 19 ++++++++++++++++++-
+ gcc/config/xtensa/xtensa.md      | 35 +++++++++++++++++++----------------
+ gcc/config/xtensa/xtensa.opt     |  4 ++++
+ 7 files changed, 54 insertions(+), 20 deletions(-)
+
+diff --git a/gcc/config/xtensa/constraints.md b/gcc/config/xtensa/constraints.md
+index 30f4c1f..773d4f9 100644
+--- a/gcc/config/xtensa/constraints.md
++++ b/gcc/config/xtensa/constraints.md
+@@ -111,6 +111,11 @@
+  (and (match_code "const_int")
+       (match_test "xtensa_mask_immediate (ival)")))
+ 
++(define_constraint "Y"
++ "A constant that can be used in relaxed MOVI instructions."
++ (and (match_code "const_int,const_double,const,symbol_ref,label_ref")
++      (match_test "TARGET_AUTO_LITPOOLS")))
++
+ ;; Memory constraints.  Do not use define_memory_constraint here.  Doing so
+ ;; causes reload to force some constants into the constant pool, but since
+ ;; the Xtensa constant pool can only be accessed with L32R instructions, it
+diff --git a/gcc/config/xtensa/elf.h b/gcc/config/xtensa/elf.h
+index e59bede..12056f7 100644
+--- a/gcc/config/xtensa/elf.h
++++ b/gcc/config/xtensa/elf.h
+@@ -48,7 +48,9 @@ along with GCC; see the file COPYING3.  If not see
+   %{mtarget-align:--target-align} \
+   %{mno-target-align:--no-target-align} \
+   %{mlongcalls:--longcalls} \
+-  %{mno-longcalls:--no-longcalls}"
++  %{mno-longcalls:--no-longcalls} \
++  %{mauto-litpools:--auto-litpools} \
++  %{mno-auto-litpools:--no-auto-litpools}"
+ 
+ #undef LIB_SPEC
+ #define LIB_SPEC "-lc -lsim -lc -lhandlers-sim -lhal"
+diff --git a/gcc/config/xtensa/linux.h b/gcc/config/xtensa/linux.h
+index 675aacf..5b0243a 100644
+--- a/gcc/config/xtensa/linux.h
++++ b/gcc/config/xtensa/linux.h
+@@ -42,7 +42,9 @@ along with GCC; see the file COPYING3.  If not see
+   %{mtarget-align:--target-align} \
+   %{mno-target-align:--no-target-align} \
+   %{mlongcalls:--longcalls} \
+-  %{mno-longcalls:--no-longcalls}"
++  %{mno-longcalls:--no-longcalls} \
++  %{mauto-litpools:--auto-litpools} \
++  %{mno-auto-litpools:--no-auto-litpools}"
+ 
+ #define GLIBC_DYNAMIC_LINKER "/lib/ld.so.1"
+ 
+diff --git a/gcc/config/xtensa/predicates.md b/gcc/config/xtensa/predicates.md
+index e02209e..d7dfa11 100644
+--- a/gcc/config/xtensa/predicates.md
++++ b/gcc/config/xtensa/predicates.md
+@@ -142,7 +142,8 @@
+ 	       (match_test "GET_MODE_CLASS (mode) == MODE_INT
+ 			    && xtensa_simm12b (INTVAL (op))"))
+ 	  (and (match_code "const_int,const_double,const,symbol_ref,label_ref")
+-	       (match_test "TARGET_CONST16 && CONSTANT_P (op)
++	       (match_test "(TARGET_CONST16 || TARGET_AUTO_LITPOOLS)
++			    && CONSTANT_P (op)
+ 			    && GET_MODE_SIZE (mode) % UNITS_PER_WORD == 0")))))
+ 
+ ;; Accept the floating point constant 1 in the appropriate mode.
+diff --git a/gcc/config/xtensa/xtensa.c b/gcc/config/xtensa/xtensa.c
+index eb039ba..206ff80 100644
+--- a/gcc/config/xtensa/xtensa.c
++++ b/gcc/config/xtensa/xtensa.c
+@@ -501,6 +501,9 @@ xtensa_valid_move (machine_mode mode, rtx *operands)
+     {
+       int dst_regnum = xt_true_regnum (operands[0]);
+ 
++      if (xtensa_tls_referenced_p (operands[1]))
++	return FALSE;
++
+       /* The stack pointer can only be assigned with a MOVSP opcode.  */
+       if (dst_regnum == STACK_POINTER_REGNUM)
+ 	return !TARGET_WINDOWED_ABI
+@@ -1069,7 +1072,7 @@ xtensa_emit_move_sequence (rtx *operands, machine_mode mode)
+ 	  return 1;
+ 	}
+ 
+-      if (! TARGET_CONST16)
++      if (! TARGET_AUTO_LITPOOLS && ! TARGET_CONST16)
+ 	{
+ 	  src = force_const_mem (SImode, src);
+ 	  operands[1] = src;
+@@ -2449,6 +2452,20 @@ print_operand (FILE *file, rtx x, int letter)
+ 	}
+       break;
+ 
++    case 'y':
++      if (GET_CODE (x) == CONST_DOUBLE &&
++	  GET_MODE (x) == SFmode)
++	{
++	  REAL_VALUE_TYPE r;
++	  long l;
++	  REAL_VALUE_FROM_CONST_DOUBLE (r, x);
++	  REAL_VALUE_TO_TARGET_SINGLE (r, l);
++	  fprintf (file, "0x%08lx", l);
++	  break;
++	}
++
++      /* fall through */
++
+     default:
+       if (GET_CODE (x) == REG || GET_CODE (x) == SUBREG)
+ 	fprintf (file, "%s", reg_names[xt_true_regnum (x)]);
+diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md
+index 6d84384..0e673a3 100644
+--- a/gcc/config/xtensa/xtensa.md
++++ b/gcc/config/xtensa/xtensa.md
+@@ -761,8 +761,8 @@
+ })
+ 
+ (define_insn "movsi_internal"
+-  [(set (match_operand:SI 0 "nonimmed_operand" "=D,D,D,D,R,R,a,q,a,W,a,a,U,*a,*A")
+-	(match_operand:SI 1 "move_operand" "M,D,d,R,D,d,r,r,I,i,T,U,r,*A,*r"))]
++  [(set (match_operand:SI 0 "nonimmed_operand" "=D,D,D,D,R,R,a,q,a,a,W,a,a,U,*a,*A")
++	(match_operand:SI 1 "move_operand" "M,D,d,R,D,d,r,r,I,Y,i,T,U,r,*A,*r"))]
+   "xtensa_valid_move (SImode, operands)"
+   "@
+    movi.n\t%0, %x1
+@@ -774,15 +774,16 @@
+    mov\t%0, %1
+    movsp\t%0, %1
+    movi\t%0, %x1
++   movi\t%0, %1
+    const16\t%0, %t1\;const16\t%0, %b1
+    %v1l32r\t%0, %1
+    %v1l32i\t%0, %1
+    %v0s32i\t%1, %0
+    rsr\t%0, ACCLO
+    wsr\t%1, ACCLO"
+-  [(set_attr "type" "move,move,move,load,store,store,move,move,move,move,load,load,store,rsr,wsr")
++  [(set_attr "type" "move,move,move,load,store,store,move,move,move,move,move,load,load,store,rsr,wsr")
+    (set_attr "mode"	"SI")
+-   (set_attr "length"	"2,2,2,2,2,2,3,3,3,6,3,3,3,3,3")])
++   (set_attr "length"	"2,2,2,2,2,2,3,3,3,3,6,3,3,3,3,3")])
+ 
+ ;; 16-bit Integer moves
+ 
+@@ -796,21 +797,22 @@
+ })
+ 
+ (define_insn "movhi_internal"
+-  [(set (match_operand:HI 0 "nonimmed_operand" "=D,D,a,a,a,U,*a,*A")
+-	(match_operand:HI 1 "move_operand" "M,d,r,I,U,r,*A,*r"))]
++  [(set (match_operand:HI 0 "nonimmed_operand" "=D,D,a,a,a,a,U,*a,*A")
++	(match_operand:HI 1 "move_operand" "M,d,r,I,Y,U,r,*A,*r"))]
+   "xtensa_valid_move (HImode, operands)"
+   "@
+    movi.n\t%0, %x1
+    mov.n\t%0, %1
+    mov\t%0, %1
+    movi\t%0, %x1
++   movi\t%0, %1
+    %v1l16ui\t%0, %1
+    %v0s16i\t%1, %0
+    rsr\t%0, ACCLO
+    wsr\t%1, ACCLO"
+-  [(set_attr "type"	"move,move,move,move,load,store,rsr,wsr")
++  [(set_attr "type"	"move,move,move,move,move,load,store,rsr,wsr")
+    (set_attr "mode"	"HI")
+-   (set_attr "length"	"2,2,3,3,3,3,3,3")])
++   (set_attr "length"	"2,2,3,3,3,3,3,3,3")])
+ 
+ ;; 8-bit Integer moves
+ 
+@@ -881,7 +883,7 @@
+ 	(match_operand:SF 1 "general_operand" ""))]
+   ""
+ {
+-  if (!TARGET_CONST16 && CONSTANT_P (operands[1]))
++  if (!TARGET_CONST16 && !TARGET_AUTO_LITPOOLS && CONSTANT_P (operands[1]))
+     operands[1] = force_const_mem (SFmode, operands[1]);
+ 
+   if ((!register_operand (operands[0], SFmode)
+@@ -896,8 +898,8 @@
+ })
+ 
+ (define_insn "movsf_internal"
+-  [(set (match_operand:SF 0 "nonimmed_operand" "=f,f,U,D,D,R,a,f,a,W,a,a,U")
+-	(match_operand:SF 1 "move_operand" "f,U,f,d,R,d,r,r,f,iF,T,U,r"))]
++  [(set (match_operand:SF 0 "nonimmed_operand" "=f,f,U,D,D,R,a,f,a,a,W,a,a,U")
++	(match_operand:SF 1 "move_operand" "f,U,f,d,R,d,r,r,f,Y,iF,T,U,r"))]
+   "((register_operand (operands[0], SFmode)
+      || register_operand (operands[1], SFmode))
+     && !(FP_REG_P (xt_true_regnum (operands[0]))
+@@ -912,13 +914,14 @@
+    mov\t%0, %1
+    wfr\t%0, %1
+    rfr\t%0, %1
++   movi\t%0, %y1
+    const16\t%0, %t1\;const16\t%0, %b1
+    %v1l32r\t%0, %1
+    %v1l32i\t%0, %1
+    %v0s32i\t%1, %0"
+-  [(set_attr "type"	"farith,fload,fstore,move,load,store,move,farith,farith,move,load,load,store")
++  [(set_attr "type"	"farith,fload,fstore,move,load,store,move,farith,farith,move,move,load,load,store")
+    (set_attr "mode"	"SF")
+-   (set_attr "length"	"3,3,3,2,2,2,3,3,3,6,3,3,3")])
++   (set_attr "length"	"3,3,3,2,2,2,3,3,3,3,6,3,3,3")])
+ 
+ (define_insn "*lsiu"
+   [(set (match_operand:SF 0 "register_operand" "=f")
+@@ -991,7 +994,7 @@
+ 	(match_operand:DF 1 "general_operand" ""))]
+   ""
+ {
+-  if (CONSTANT_P (operands[1]) && !TARGET_CONST16)
++  if (CONSTANT_P (operands[1]) && !TARGET_CONST16 && !TARGET_AUTO_LITPOOLS)
+     operands[1] = force_const_mem (DFmode, operands[1]);
+ 
+   if (!register_operand (operands[0], DFmode)
+@@ -1002,8 +1005,8 @@
+ })
+ 
+ (define_insn_and_split "movdf_internal"
+-  [(set (match_operand:DF 0 "nonimmed_operand" "=a,W,a,a,U")
+-	(match_operand:DF 1 "move_operand" "r,iF,T,U,r"))]
++  [(set (match_operand:DF 0 "nonimmed_operand" "=a,a,W,a,a,U")
++	(match_operand:DF 1 "move_operand" "r,Y,iF,T,U,r"))]
+   "register_operand (operands[0], DFmode)
+    || register_operand (operands[1], DFmode)"
+   "#"
+diff --git a/gcc/config/xtensa/xtensa.opt b/gcc/config/xtensa/xtensa.opt
+index 2fd6cee..21c6e96 100644
+--- a/gcc/config/xtensa/xtensa.opt
++++ b/gcc/config/xtensa/xtensa.opt
+@@ -38,6 +38,10 @@ mtext-section-literals
+ Target
+ Intersperse literal pools with code in the text section
+ 
++mauto-litpools
++Target Report Mask(AUTO_LITPOOLS)
++Relax literals in assembler and place them automatically in the text section
++
+ mserialize-volatile
+ Target Report Mask(SERIALIZE_VOLATILE)
+ -mno-serialize-volatile	Do not serialize volatile memory references with MEMW instructions
+-- 
+1.8.1.4
+
diff --git a/package/gcc/5.2.0/870-xtensa-add-mauto-litpools-option.patch b/package/gcc/5.2.0/870-xtensa-add-mauto-litpools-option.patch
new file mode 100644
index 0000000..aa1376c
--- /dev/null
+++ b/package/gcc/5.2.0/870-xtensa-add-mauto-litpools-option.patch
@@ -0,0 +1,290 @@
+From 6d852ffb43b111a39162135c95249e749c4e285b Mon Sep 17 00:00:00 2001
+From: Max Filippov <jcmvbkbc@gmail.com>
+Date: Thu, 6 Aug 2015 01:16:02 +0300
+Subject: [PATCH] xtensa: add -mauto-litpools option
+
+With support from assembler this option allows compiling huge functions,
+where single literal pool at the beginning of a function may not be
+reachable by L32R instructions at its end.
+
+Currently assembler --auto-litpools option cannot deal with literals
+used from multiple locations separated by more than 256 KBytes of code.
+Don't turn constants into literals, instead use MOVI instruction to load
+them into registers and let the assembler turn them into literals as
+necessary.
+
+2015-08-12  Max Filippov  <jcmvbkbc@gmail.com>
+gcc/
+	* config/xtensa/constraints.md (define_constraint "Y"): New
+	constraint.
+	* config/xtensa/elf.h (ASM_SPEC): Add m(no-)auto-litpools.
+	* config/xtensa/linux.h (ASM_SPEC): Likewise.
+	* config/xtensa/predicates.md (move_operand): Match constants
+	and symbols in the presence of TARGET_AUTO_LITPOOLS.
+	* config/xtensa/xtensa.c (xtensa_valid_move): Don't allow
+	immediate references to TLS data.
+	(xtensa_emit_move_sequence): Don't force constants to memory in
+	the presence of TARGET_AUTO_LITPOOLS.
+	(print_operand): Add 'y' format, same as default, but capable of
+	printing SF mode constants as well.
+	* config/xtensa/xtensa.md (movsi_internal, movhi_internal)
+	(movsf_internal): Add movi pattern that loads literal.
+	(movsf, movdf): Don't force constants to memory in the presence
+	of TARGET_AUTO_LITPOOLS.
+	(movdf_internal): Add 'Y' constraint.
+	* config/xtensa/xtensa.opt (mauto-litpools): New option.
+
+Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
+---
+Backported from: r226828
+Changes to ChangeLogs and documentation are dropped.
+
+ gcc/config/xtensa/constraints.md |  5 +++++
+ gcc/config/xtensa/elf.h          |  4 +++-
+ gcc/config/xtensa/linux.h        |  4 +++-
+ gcc/config/xtensa/predicates.md  |  3 ++-
+ gcc/config/xtensa/xtensa.c       | 19 ++++++++++++++++++-
+ gcc/config/xtensa/xtensa.md      | 35 +++++++++++++++++++----------------
+ gcc/config/xtensa/xtensa.opt     |  4 ++++
+ 7 files changed, 54 insertions(+), 20 deletions(-)
+
+diff --git a/gcc/config/xtensa/constraints.md b/gcc/config/xtensa/constraints.md
+index 30f4c1f..773d4f9 100644
+--- a/gcc/config/xtensa/constraints.md
++++ b/gcc/config/xtensa/constraints.md
+@@ -111,6 +111,11 @@
+  (and (match_code "const_int")
+       (match_test "xtensa_mask_immediate (ival)")))
+ 
++(define_constraint "Y"
++ "A constant that can be used in relaxed MOVI instructions."
++ (and (match_code "const_int,const_double,const,symbol_ref,label_ref")
++      (match_test "TARGET_AUTO_LITPOOLS")))
++
+ ;; Memory constraints.  Do not use define_memory_constraint here.  Doing so
+ ;; causes reload to force some constants into the constant pool, but since
+ ;; the Xtensa constant pool can only be accessed with L32R instructions, it
+diff --git a/gcc/config/xtensa/elf.h b/gcc/config/xtensa/elf.h
+index e59bede..12056f7 100644
+--- a/gcc/config/xtensa/elf.h
++++ b/gcc/config/xtensa/elf.h
+@@ -48,7 +48,9 @@ along with GCC; see the file COPYING3.  If not see
+   %{mtarget-align:--target-align} \
+   %{mno-target-align:--no-target-align} \
+   %{mlongcalls:--longcalls} \
+-  %{mno-longcalls:--no-longcalls}"
++  %{mno-longcalls:--no-longcalls} \
++  %{mauto-litpools:--auto-litpools} \
++  %{mno-auto-litpools:--no-auto-litpools}"
+ 
+ #undef LIB_SPEC
+ #define LIB_SPEC "-lc -lsim -lc -lhandlers-sim -lhal"
+diff --git a/gcc/config/xtensa/linux.h b/gcc/config/xtensa/linux.h
+index 675aacf..5b0243a 100644
+--- a/gcc/config/xtensa/linux.h
++++ b/gcc/config/xtensa/linux.h
+@@ -42,7 +42,9 @@ along with GCC; see the file COPYING3.  If not see
+   %{mtarget-align:--target-align} \
+   %{mno-target-align:--no-target-align} \
+   %{mlongcalls:--longcalls} \
+-  %{mno-longcalls:--no-longcalls}"
++  %{mno-longcalls:--no-longcalls} \
++  %{mauto-litpools:--auto-litpools} \
++  %{mno-auto-litpools:--no-auto-litpools}"
+ 
+ #define GLIBC_DYNAMIC_LINKER "/lib/ld.so.1"
+ 
+diff --git a/gcc/config/xtensa/predicates.md b/gcc/config/xtensa/predicates.md
+index e02209e..d7dfa11 100644
+--- a/gcc/config/xtensa/predicates.md
++++ b/gcc/config/xtensa/predicates.md
+@@ -142,7 +142,8 @@
+ 	       (match_test "GET_MODE_CLASS (mode) == MODE_INT
+ 			    && xtensa_simm12b (INTVAL (op))"))
+ 	  (and (match_code "const_int,const_double,const,symbol_ref,label_ref")
+-	       (match_test "TARGET_CONST16 && CONSTANT_P (op)
++	       (match_test "(TARGET_CONST16 || TARGET_AUTO_LITPOOLS)
++			    && CONSTANT_P (op)
+ 			    && GET_MODE_SIZE (mode) % UNITS_PER_WORD == 0")))))
+ 
+ ;; Accept the floating point constant 1 in the appropriate mode.
+diff --git a/gcc/config/xtensa/xtensa.c b/gcc/config/xtensa/xtensa.c
+index eb039ba..206ff80 100644
+--- a/gcc/config/xtensa/xtensa.c
++++ b/gcc/config/xtensa/xtensa.c
+@@ -501,6 +501,9 @@ xtensa_valid_move (machine_mode mode, rtx *operands)
+     {
+       int dst_regnum = xt_true_regnum (operands[0]);
+ 
++      if (xtensa_tls_referenced_p (operands[1]))
++	return FALSE;
++
+       /* The stack pointer can only be assigned with a MOVSP opcode.  */
+       if (dst_regnum == STACK_POINTER_REGNUM)
+ 	return !TARGET_WINDOWED_ABI
+@@ -1069,7 +1072,7 @@ xtensa_emit_move_sequence (rtx *operands, machine_mode mode)
+ 	  return 1;
+ 	}
+ 
+-      if (! TARGET_CONST16)
++      if (! TARGET_AUTO_LITPOOLS && ! TARGET_CONST16)
+ 	{
+ 	  src = force_const_mem (SImode, src);
+ 	  operands[1] = src;
+@@ -2449,6 +2452,20 @@ print_operand (FILE *file, rtx x, int letter)
+ 	}
+       break;
+ 
++    case 'y':
++      if (GET_CODE (x) == CONST_DOUBLE &&
++	  GET_MODE (x) == SFmode)
++	{
++	  REAL_VALUE_TYPE r;
++	  long l;
++	  REAL_VALUE_FROM_CONST_DOUBLE (r, x);
++	  REAL_VALUE_TO_TARGET_SINGLE (r, l);
++	  fprintf (file, "0x%08lx", l);
++	  break;
++	}
++
++      /* fall through */
++
+     default:
+       if (GET_CODE (x) == REG || GET_CODE (x) == SUBREG)
+ 	fprintf (file, "%s", reg_names[xt_true_regnum (x)]);
+diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md
+index 6d84384..0e673a3 100644
+--- a/gcc/config/xtensa/xtensa.md
++++ b/gcc/config/xtensa/xtensa.md
+@@ -761,8 +761,8 @@
+ })
+ 
+ (define_insn "movsi_internal"
+-  [(set (match_operand:SI 0 "nonimmed_operand" "=D,D,D,D,R,R,a,q,a,W,a,a,U,*a,*A")
+-	(match_operand:SI 1 "move_operand" "M,D,d,R,D,d,r,r,I,i,T,U,r,*A,*r"))]
++  [(set (match_operand:SI 0 "nonimmed_operand" "=D,D,D,D,R,R,a,q,a,a,W,a,a,U,*a,*A")
++	(match_operand:SI 1 "move_operand" "M,D,d,R,D,d,r,r,I,Y,i,T,U,r,*A,*r"))]
+   "xtensa_valid_move (SImode, operands)"
+   "@
+    movi.n\t%0, %x1
+@@ -774,15 +774,16 @@
+    mov\t%0, %1
+    movsp\t%0, %1
+    movi\t%0, %x1
++   movi\t%0, %1
+    const16\t%0, %t1\;const16\t%0, %b1
+    %v1l32r\t%0, %1
+    %v1l32i\t%0, %1
+    %v0s32i\t%1, %0
+    rsr\t%0, ACCLO
+    wsr\t%1, ACCLO"
+-  [(set_attr "type" "move,move,move,load,store,store,move,move,move,move,load,load,store,rsr,wsr")
++  [(set_attr "type" "move,move,move,load,store,store,move,move,move,move,move,load,load,store,rsr,wsr")
+    (set_attr "mode"	"SI")
+-   (set_attr "length"	"2,2,2,2,2,2,3,3,3,6,3,3,3,3,3")])
++   (set_attr "length"	"2,2,2,2,2,2,3,3,3,3,6,3,3,3,3,3")])
+ 
+ ;; 16-bit Integer moves
+ 
+@@ -796,21 +797,22 @@
+ })
+ 
+ (define_insn "movhi_internal"
+-  [(set (match_operand:HI 0 "nonimmed_operand" "=D,D,a,a,a,U,*a,*A")
+-	(match_operand:HI 1 "move_operand" "M,d,r,I,U,r,*A,*r"))]
++  [(set (match_operand:HI 0 "nonimmed_operand" "=D,D,a,a,a,a,U,*a,*A")
++	(match_operand:HI 1 "move_operand" "M,d,r,I,Y,U,r,*A,*r"))]
+   "xtensa_valid_move (HImode, operands)"
+   "@
+    movi.n\t%0, %x1
+    mov.n\t%0, %1
+    mov\t%0, %1
+    movi\t%0, %x1
++   movi\t%0, %1
+    %v1l16ui\t%0, %1
+    %v0s16i\t%1, %0
+    rsr\t%0, ACCLO
+    wsr\t%1, ACCLO"
+-  [(set_attr "type"	"move,move,move,move,load,store,rsr,wsr")
++  [(set_attr "type"	"move,move,move,move,move,load,store,rsr,wsr")
+    (set_attr "mode"	"HI")
+-   (set_attr "length"	"2,2,3,3,3,3,3,3")])
++   (set_attr "length"	"2,2,3,3,3,3,3,3,3")])
+ 
+ ;; 8-bit Integer moves
+ 
+@@ -881,7 +883,7 @@
+ 	(match_operand:SF 1 "general_operand" ""))]
+   ""
+ {
+-  if (!TARGET_CONST16 && CONSTANT_P (operands[1]))
++  if (!TARGET_CONST16 && !TARGET_AUTO_LITPOOLS && CONSTANT_P (operands[1]))
+     operands[1] = force_const_mem (SFmode, operands[1]);
+ 
+   if ((!register_operand (operands[0], SFmode)
+@@ -896,8 +898,8 @@
+ })
+ 
+ (define_insn "movsf_internal"
+-  [(set (match_operand:SF 0 "nonimmed_operand" "=f,f,U,D,D,R,a,f,a,W,a,a,U")
+-	(match_operand:SF 1 "move_operand" "f,U,f,d,R,d,r,r,f,iF,T,U,r"))]
++  [(set (match_operand:SF 0 "nonimmed_operand" "=f,f,U,D,D,R,a,f,a,a,W,a,a,U")
++	(match_operand:SF 1 "move_operand" "f,U,f,d,R,d,r,r,f,Y,iF,T,U,r"))]
+   "((register_operand (operands[0], SFmode)
+      || register_operand (operands[1], SFmode))
+     && !(FP_REG_P (xt_true_regnum (operands[0]))
+@@ -912,13 +914,14 @@
+    mov\t%0, %1
+    wfr\t%0, %1
+    rfr\t%0, %1
++   movi\t%0, %y1
+    const16\t%0, %t1\;const16\t%0, %b1
+    %v1l32r\t%0, %1
+    %v1l32i\t%0, %1
+    %v0s32i\t%1, %0"
+-  [(set_attr "type"	"farith,fload,fstore,move,load,store,move,farith,farith,move,load,load,store")
++  [(set_attr "type"	"farith,fload,fstore,move,load,store,move,farith,farith,move,move,load,load,store")
+    (set_attr "mode"	"SF")
+-   (set_attr "length"	"3,3,3,2,2,2,3,3,3,6,3,3,3")])
++   (set_attr "length"	"3,3,3,2,2,2,3,3,3,3,6,3,3,3")])
+ 
+ (define_insn "*lsiu"
+   [(set (match_operand:SF 0 "register_operand" "=f")
+@@ -991,7 +994,7 @@
+ 	(match_operand:DF 1 "general_operand" ""))]
+   ""
+ {
+-  if (CONSTANT_P (operands[1]) && !TARGET_CONST16)
++  if (CONSTANT_P (operands[1]) && !TARGET_CONST16 && !TARGET_AUTO_LITPOOLS)
+     operands[1] = force_const_mem (DFmode, operands[1]);
+ 
+   if (!register_operand (operands[0], DFmode)
+@@ -1002,8 +1005,8 @@
+ })
+ 
+ (define_insn_and_split "movdf_internal"
+-  [(set (match_operand:DF 0 "nonimmed_operand" "=a,W,a,a,U")
+-	(match_operand:DF 1 "move_operand" "r,iF,T,U,r"))]
++  [(set (match_operand:DF 0 "nonimmed_operand" "=a,a,W,a,a,U")
++	(match_operand:DF 1 "move_operand" "r,Y,iF,T,U,r"))]
+   "register_operand (operands[0], DFmode)
+    || register_operand (operands[1], DFmode)"
+   "#"
+diff --git a/gcc/config/xtensa/xtensa.opt b/gcc/config/xtensa/xtensa.opt
+index 2fd6cee..21c6e96 100644
+--- a/gcc/config/xtensa/xtensa.opt
++++ b/gcc/config/xtensa/xtensa.opt
+@@ -38,6 +38,10 @@ mtext-section-literals
+ Target
+ Intersperse literal pools with code in the text section
+ 
++mauto-litpools
++Target Report Mask(AUTO_LITPOOLS)
++Relax literals in assembler and place them automatically in the text section
++
+ mserialize-volatile
+ Target Report Mask(SERIALIZE_VOLATILE)
+ -mno-serialize-volatile	Do not serialize volatile memory references with MEMW instructions
+-- 
+1.8.1.4
+
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [Buildroot] [PATCH 3/4] xtensa: switch from text-section-literals to auto-litpools
  2015-08-12 22:19 [Buildroot] [PATCH 0/4] xtensa: toolchain fix for compiling huge functions Max Filippov
  2015-08-12 22:20 ` [Buildroot] [PATCH 1/4] binutils: backport auto-litpools xtensa gas option Max Filippov
  2015-08-12 22:20 ` [Buildroot] [PATCH 2/4] gcc: backport mauto-litpools xtensa option Max Filippov
@ 2015-08-12 22:20 ` Max Filippov
  2015-08-12 22:20 ` [Buildroot] [PATCH 4/4] Revert "opencv: mark as not available on Xtensa" Max Filippov
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 9+ messages in thread
From: Max Filippov @ 2015-08-12 22:20 UTC (permalink / raw)
  To: buildroot

Now that both binutils and gcc support auto-litpools use that option
instead of text-section-literals to be able to compile huge functions.

Fixes:
  http://autobuild.buildroot.net/results/dd384fe0ef02a4205bea66a4a16ca2062afe53b4/
  http://autobuild.buildroot.net/results/87dd357a4b883ea3cd75546b3d63c4c28245beee/
  http://autobuild.buildroot.net/results/b5bca00dec1ecb118c7fb9c10dee74c94809c831/
and many others.

Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
---
 package/Makefile.in | 4 ++--
 package/gcc/gcc.mk  | 6 +++---
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/package/Makefile.in b/package/Makefile.in
index 545694f..5038e50 100644
--- a/package/Makefile.in
+++ b/package/Makefile.in
@@ -91,7 +91,7 @@ endif
 # code size and performance, the linker can usually optimize away the
 # overhead when a call ends up within a certain range.
 #
-# Use text-section-literals for Xtensa globally.
+# Use auto-litpools for Xtensa globally.
 # Collecting literals into separate section can be advantageous if that
 # section is placed into DTCM at link time. This is applicable for code
 # running on bare metal, but makes no sense under linux, where userspace
@@ -100,7 +100,7 @@ endif
 # instruction can only access literals in 256 KBytes range.
 #
 ifeq ($(BR2_xtensa),y)
-TARGET_ABI += -mlongcalls -mtext-section-literals
+TARGET_ABI += -mlongcalls -mauto-litpools
 endif
 
 ifeq ($(BR2_arc)$(BR2_ARC_ATOMIC_EXT),yy)
diff --git a/package/gcc/gcc.mk b/package/gcc/gcc.mk
index 501fcea..6b9ef92 100644
--- a/package/gcc/gcc.mk
+++ b/package/gcc/gcc.mk
@@ -112,11 +112,11 @@ GCC_COMMON_TARGET_CXXFLAGS = $(filter-out -Os,$(GCC_COMMON_TARGET_CXXFLAGS))
 endif
 endif
 
-# Xtensa libgcc can't be built with -mtext-section-literals
+# Xtensa libgcc can't be built with -mauto-litpools
 # because of the trick used to generate .init/.fini sections.
 ifeq ($(BR2_xtensa),y)
-GCC_COMMON_TARGET_CFLAGS = $(filter-out -mtext-section-literals,$(TARGET_CFLAGS))
-GCC_COMMON_TARGET_CXXFLAGS = $(filter-out -mtext-section-literals,$(TARGET_CXXFLAGS))
+GCC_COMMON_TARGET_CFLAGS = $(filter-out -mauto-litpools,$(TARGET_CFLAGS))
+GCC_COMMON_TARGET_CXXFLAGS = $(filter-out -mauto-litpools,$(TARGET_CXXFLAGS))
 endif
 
 # Propagate options used for target software building to GCC target libs
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [Buildroot] [PATCH 4/4] Revert "opencv: mark as not available on Xtensa"
  2015-08-12 22:19 [Buildroot] [PATCH 0/4] xtensa: toolchain fix for compiling huge functions Max Filippov
                   ` (2 preceding siblings ...)
  2015-08-12 22:20 ` [Buildroot] [PATCH 3/4] xtensa: switch from text-section-literals to auto-litpools Max Filippov
@ 2015-08-12 22:20 ` Max Filippov
  2015-08-18 21:29 ` [Buildroot] [PATCH 0/4] xtensa: toolchain fix for compiling huge functions Yann E. MORIN
  2015-10-04 16:28 ` Thomas Petazzoni
  5 siblings, 0 replies; 9+ messages in thread
From: Max Filippov @ 2015-08-12 22:20 UTC (permalink / raw)
  To: buildroot

Now that xtensa toolchain is able to compile huge functions this
workaround is no longer needed.

This reverts commit d21932508e69d4ab849cba9958f953ae9342cb8c.
---
 package/opencv/Config.in | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/package/opencv/Config.in b/package/opencv/Config.in
index a52092d..0b5d1ac 100644
--- a/package/opencv/Config.in
+++ b/package/opencv/Config.in
@@ -5,8 +5,6 @@ menuconfig BR2_PACKAGE_OPENCV
 	depends on BR2_INSTALL_LIBSTDCPP
 	depends on BR2_USE_WCHAR
 	depends on !BR2_STATIC_LIBS # include dlfcn.h
-	# Causes some toolchain failures on Xtensa
-	depends on !BR2_xtensa
 	help
 	  OpenCV (Open Source Computer Vision) is a library of programming
 	  functions for real time computer vision.
@@ -336,7 +334,6 @@ config BR2_PACKAGE_OPENCV_INSTALL_DATA
 endif # BR2_PACKAGE_OPENCV
 
 comment "opencv needs a toolchain w/ C++, NPTL, wchar, dynamic library"
-	depends on !BR2_xtensa
 	depends on !BR2_INSTALL_LIBSTDCPP || \
 		!BR2_USE_WCHAR || \
 		!BR2_TOOLCHAIN_HAS_THREADS_NPTL || \
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [Buildroot] [PATCH 0/4] xtensa: toolchain fix for compiling huge functions
  2015-08-12 22:19 [Buildroot] [PATCH 0/4] xtensa: toolchain fix for compiling huge functions Max Filippov
                   ` (3 preceding siblings ...)
  2015-08-12 22:20 ` [Buildroot] [PATCH 4/4] Revert "opencv: mark as not available on Xtensa" Max Filippov
@ 2015-08-18 21:29 ` Yann E. MORIN
  2015-08-18 22:20   ` Max Filippov
  2015-10-04 16:28 ` Thomas Petazzoni
  5 siblings, 1 reply; 9+ messages in thread
From: Yann E. MORIN @ 2015-08-18 21:29 UTC (permalink / raw)
  To: buildroot

Max, All,

On 2015-08-13 01:19 +0300, Max Filippov spake thusly:
> this series backports binutils and gcc patches that add auto-litpools option
> and replaces text-section-literals ABI flag for xtensa with auto-litpools.
> With that change compiling huge functions should no longer be an issue on
> xtensa. Obviously that change will break builds with pre-built toolchain.

I'm not a huge fan of this series.

  - First, they are "feature patches" (even if backported) to critical
    components (gcc, binutils).

  - Then, patches 3 and 4 will break external toolchains.

  - Finally, it seems to me quite some efforst for "just" one package.

So, I'd say we wait for gcc + binutils to spew out releases with those
changes, then we can incorporate those versions in Buildroot, and make
OpenCV depend on _GCC_AT_LEAST_X_Y ...

Note: those comments are also valid for the unwind patch you sent
later...

Note-2: I know this might be a very difficult job you've made,
backporting those fixes. Still, I don;t think they are fit for having
in Buldroot.

Regards,
Yann E. MORIN.

> Max Filippov (4):
>   binutils: backport auto-litpools xtensa gas option
>   gcc: backport mauto-litpools xtensa option
>   xtensa: switch from text-section-literals to auto-litpools
>   Revert "opencv: mark as not available on Xtensa"
> 
>  package/Makefile.in                                |   4 +-
>  .../2.24/913-xtensa-add-auto-litpools-option.patch | 698 ++++++++++++++++++++
>  .../913-xtensa-add-auto-litpools-option.patch      | 699 +++++++++++++++++++++
>  .../870-xtensa-add-mauto-litpools-option.patch     | 290 +++++++++
>  .../870-xtensa-add-mauto-litpools-option.patch     | 290 +++++++++
>  .../870-xtensa-add-mauto-litpools-option.patch     | 290 +++++++++
>  package/gcc/gcc.mk                                 |   6 +-
>  package/opencv/Config.in                           |   3 -
>  8 files changed, 2272 insertions(+), 8 deletions(-)
>  create mode 100644 package/binutils/2.24/913-xtensa-add-auto-litpools-option.patch
>  create mode 100644 package/binutils/2.25.1/913-xtensa-add-auto-litpools-option.patch
>  create mode 100644 package/gcc/4.8.5/870-xtensa-add-mauto-litpools-option.patch
>  create mode 100644 package/gcc/4.9.3/870-xtensa-add-mauto-litpools-option.patch
>  create mode 100644 package/gcc/5.2.0/870-xtensa-add-mauto-litpools-option.patch
> 
> -- 
> 1.8.1.4
> 
> _______________________________________________
> buildroot mailing list
> buildroot at busybox.net
> http://lists.busybox.net/mailman/listinfo/buildroot

-- 
.-----------------.--------------------.------------------.--------------------.
|  Yann E. MORIN  | Real-Time Embedded | /"\ ASCII RIBBON | Erics' conspiracy: |
| +33 662 376 056 | Software  Designer | \ / CAMPAIGN     |  ___               |
| +33 223 225 172 `------------.-------:  X  AGAINST      |  \e/  There is no  |
| http://ymorin.is-a-geek.org/ | _/*\_ | / \ HTML MAIL    |   v   conspiracy.  |
'------------------------------^-------^------------------^--------------------'

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Buildroot] [PATCH 0/4] xtensa: toolchain fix for compiling huge functions
  2015-08-18 21:29 ` [Buildroot] [PATCH 0/4] xtensa: toolchain fix for compiling huge functions Yann E. MORIN
@ 2015-08-18 22:20   ` Max Filippov
  0 siblings, 0 replies; 9+ messages in thread
From: Max Filippov @ 2015-08-18 22:20 UTC (permalink / raw)
  To: buildroot

Hi Yann,

On Wed, Aug 19, 2015 at 12:29 AM, Yann E. MORIN <yann.morin.1998@free.fr> wrote:
> On 2015-08-13 01:19 +0300, Max Filippov spake thusly:
>> this series backports binutils and gcc patches that add auto-litpools option
>> and replaces text-section-literals ABI flag for xtensa with auto-litpools.
>> With that change compiling huge functions should no longer be an issue on
>> xtensa. Obviously that change will break builds with pre-built toolchain.
>
> I'm not a huge fan of this series.
>
>   - First, they are "feature patches" (even if backported) to critical
>     components (gcc, binutils).
>
>   - Then, patches 3 and 4 will break external toolchains.
>
>   - Finally, it seems to me quite some efforst for "just" one package.

Agree, except for the last point: it's actually not the first breakage
caused by huge functions, previously we had similar issues with
packages built with -O0.

> So, I'd say we wait for gcc + binutils to spew out releases with those
> changes, then we can incorporate those versions in Buildroot, and make
> OpenCV depend on _GCC_AT_LEAST_X_Y ...

Ok, though it's a bit more complex than that: we'd also need to set
TARGET_ABI depending on combination of gcc and binutils versions.

> Note: those comments are also valid for the unwind patch you sent
> later...

With that I don't agree: these are real libgcc bug fixes, they are tiny
(two of them are one-liners), they don't break builds with external
toolchain and they affect pretty much anything that uses pthread
cancellation.

-- 
Thanks.
-- Max

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Buildroot] [PATCH 0/4] xtensa: toolchain fix for compiling huge functions
  2015-08-12 22:19 [Buildroot] [PATCH 0/4] xtensa: toolchain fix for compiling huge functions Max Filippov
                   ` (4 preceding siblings ...)
  2015-08-18 21:29 ` [Buildroot] [PATCH 0/4] xtensa: toolchain fix for compiling huge functions Yann E. MORIN
@ 2015-10-04 16:28 ` Thomas Petazzoni
  2015-10-05 14:52   ` Max Filippov
  5 siblings, 1 reply; 9+ messages in thread
From: Thomas Petazzoni @ 2015-10-04 16:28 UTC (permalink / raw)
  To: buildroot

Hello Max,

On Thu, 13 Aug 2015 01:19:59 +0300, Max Filippov wrote:

> Max Filippov (4):
>   binutils: backport auto-litpools xtensa gas option
>   gcc: backport mauto-litpools xtensa option
>   xtensa: switch from text-section-literals to auto-litpools
>   Revert "opencv: mark as not available on Xtensa"

In the end, I decided to apply these patches. They will break the
current pre-built Xtensa external toolchain we use (which was built
with Buildroot), but I will rebuild it soon to cope with that.

It's not nice to have such large patches in binutils/gcc, but I guess
it's necessary for architectures that are a bit specific, and for which
the compiler support is not yet perfect. I hope you are pushing these
changes to upstream gcc and binutils, so that we can drop the patches
in future versions.

BTW, can you have a look at gcc 5.x for Xtensa? We currently allow
using gcc 5.2.x on Xtensa, but we don't have any patches for it. It
would be great if you could have a look at which gcc 4.9.x patches are
still needed for gcc 5.x.

Thanks!

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Buildroot] [PATCH 0/4] xtensa: toolchain fix for compiling huge functions
  2015-10-04 16:28 ` Thomas Petazzoni
@ 2015-10-05 14:52   ` Max Filippov
  0 siblings, 0 replies; 9+ messages in thread
From: Max Filippov @ 2015-10-05 14:52 UTC (permalink / raw)
  To: buildroot

Hi Thomas,

On Sun, Oct 4, 2015 at 7:28 PM, Thomas Petazzoni
<thomas.petazzoni@free-electrons.com> wrote:
> On Thu, 13 Aug 2015 01:19:59 +0300, Max Filippov wrote:
>
>> Max Filippov (4):
>>   binutils: backport auto-litpools xtensa gas option
>>   gcc: backport mauto-litpools xtensa option
>>   xtensa: switch from text-section-literals to auto-litpools
>>   Revert "opencv: mark as not available on Xtensa"
>
> In the end, I decided to apply these patches. They will break the
> current pre-built Xtensa external toolchain we use (which was built
> with Buildroot), but I will rebuild it soon to cope with that.
>
> It's not nice to have such large patches in binutils/gcc, but I guess
> it's necessary for architectures that are a bit specific, and for which
> the compiler support is not yet perfect. I hope you are pushing these
> changes to upstream gcc and binutils, so that we can drop the patches
> in future versions.

They will appear in next major releases of gcc (6.1) and binutils (2.26),
but not in any of the current branches as they are not regression fixes.
Having them backported to all xtensa toolchain versions makes set of
ABI flags smaller and future backports easier.

> BTW, can you have a look at gcc 5.x for Xtensa? We currently allow
> using gcc 5.2.x on Xtensa, but we don't have any patches for it. It
> would be great if you could have a look at which gcc 4.9.x patches are
> still needed for gcc 5.x.

https://patchwork.ozlabs.org/patch/508172/
No other xtensa-specific patches I know of.

-- 
Thanks.
-- Max

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2015-10-05 14:52 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-08-12 22:19 [Buildroot] [PATCH 0/4] xtensa: toolchain fix for compiling huge functions Max Filippov
2015-08-12 22:20 ` [Buildroot] [PATCH 1/4] binutils: backport auto-litpools xtensa gas option Max Filippov
2015-08-12 22:20 ` [Buildroot] [PATCH 2/4] gcc: backport mauto-litpools xtensa option Max Filippov
2015-08-12 22:20 ` [Buildroot] [PATCH 3/4] xtensa: switch from text-section-literals to auto-litpools Max Filippov
2015-08-12 22:20 ` [Buildroot] [PATCH 4/4] Revert "opencv: mark as not available on Xtensa" Max Filippov
2015-08-18 21:29 ` [Buildroot] [PATCH 0/4] xtensa: toolchain fix for compiling huge functions Yann E. MORIN
2015-08-18 22:20   ` Max Filippov
2015-10-04 16:28 ` Thomas Petazzoni
2015-10-05 14:52   ` Max Filippov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox