summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWaldemar Brodkorb <wbx@openadk.org>2019-10-10 14:11:10 +0200
committerWaldemar Brodkorb <wbx@openadk.org>2019-10-10 14:11:20 +0200
commit4dac543bb6ecc085acf6ed087910ef952ebea15f (patch)
treed4d8e683895f37e9643616a420baa186db4c60f8
parentd7c7da149c0038d0abcc8a18e9a4d520b2796112 (diff)
xtensa: fix bootup, add buildroot patches
-rw-r--r--target/xtensa/kernel/qemu-xtensa1
-rw-r--r--toolchain/binutils/patches/2.32/0003-bfd-xtensa-fix-shrink_dynamic_reloc_sections-for-exp.patch41
-rw-r--r--toolchain/binutils/patches/2.32/0004-gas-use-literals-const16-for-xtensa-loop-relaxation.patch294
-rw-r--r--toolchain/binutils/patches/2.32/0005-xtensa-gas-put-.literal_position-at-section-start.patch96
-rw-r--r--toolchain/gcc/patches/8.3.0/0001-xtensa-backport-fix-for-PR-target-90922.patch43
-rw-r--r--toolchain/gcc/patches/8.3.0/0002-xtensa-fix-PR-target-91880.patch49
6 files changed, 524 insertions, 0 deletions
diff --git a/target/xtensa/kernel/qemu-xtensa b/target/xtensa/kernel/qemu-xtensa
index 5db1a1077..d04e49c50 100644
--- a/target/xtensa/kernel/qemu-xtensa
+++ b/target/xtensa/kernel/qemu-xtensa
@@ -1,3 +1,4 @@
CONFIG_XTENSA=y
CONFIG_XTENSA_PLATFORM_XTFPGA=y
CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttyS0,38400 memmap=0x04000000@0"
diff --git a/toolchain/binutils/patches/2.32/0003-bfd-xtensa-fix-shrink_dynamic_reloc_sections-for-exp.patch b/toolchain/binutils/patches/2.32/0003-bfd-xtensa-fix-shrink_dynamic_reloc_sections-for-exp.patch
new file mode 100644
index 000000000..b80e1fa7c
--- /dev/null
+++ b/toolchain/binutils/patches/2.32/0003-bfd-xtensa-fix-shrink_dynamic_reloc_sections-for-exp.patch
@@ -0,0 +1,41 @@
+From 278989f23735aa501be1052e085540c75c126dbb Mon Sep 17 00:00:00 2001
+From: Max Filippov <jcmvbkbc@gmail.com>
+Date: Thu, 28 Mar 2019 17:03:57 -0700
+Subject: [PATCH] bfd: xtensa: fix shrink_dynamic_reloc_sections for
+ export-dynamic
+
+shrink_dynamic_reloc_sections must remove PLT entry that was created for
+an undefined weak symbol in the presence of --export-dynamic option when
+relaxation coalesces literals pointing to that symbol. This fixes the
+following assertion:
+
+ ld: BFD (GNU Binutils) 2.31.1 internal error, aborting at
+ elf32-xtensa.c:3292 in elf_xtensa_finish_dynamic_sections
+
+2019-03-28 Max Filippov <jcmvbkbc@gmail.com>
+bfd/
+ * elf32-xtensa.c (shrink_dynamic_reloc_sections): Add
+ info->export_dynamic to the conditional.
+
+Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
+---
+ bfd/elf32-xtensa.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c
+index c3df3d6db756..37ea200eea74 100644
+--- a/bfd/elf32-xtensa.c
++++ b/bfd/elf32-xtensa.c
+@@ -10083,7 +10083,8 @@ shrink_dynamic_reloc_sections (struct bfd_link_info *info,
+ && (input_section->flags & SEC_ALLOC) != 0
+ && (dynamic_symbol || bfd_link_pic (info))
+ && (!h || h->root.type != bfd_link_hash_undefweak
+- || (dynamic_symbol && bfd_link_dll (info))))
++ || (dynamic_symbol
++ && (bfd_link_dll (info) || info->export_dynamic))))
+ {
+ asection *srel;
+ bfd_boolean is_plt = FALSE;
+--
+2.11.0
+
diff --git a/toolchain/binutils/patches/2.32/0004-gas-use-literals-const16-for-xtensa-loop-relaxation.patch b/toolchain/binutils/patches/2.32/0004-gas-use-literals-const16-for-xtensa-loop-relaxation.patch
new file mode 100644
index 000000000..ed617bcaf
--- /dev/null
+++ b/toolchain/binutils/patches/2.32/0004-gas-use-literals-const16-for-xtensa-loop-relaxation.patch
@@ -0,0 +1,294 @@
+From 0dbdfb7918d0b0cfcb8883b24c1291574bf5bb7c Mon Sep 17 00:00:00 2001
+From: Max Filippov <jcmvbkbc@gmail.com>
+Date: Tue, 2 Apr 2019 14:32:42 -0700
+Subject: [PATCH] gas: use literals/const16 for xtensa loop relaxation
+
+Loop opcode relaxation that uses addi/addmi doesn't work well with other
+relaxations that may cause code movement. Instead of encoding fixed loop
+end offset in the relaxed sequence use l32r or a pair of const16 to load
+loop end address. This way the address of the loop end gets a relocation
+record and it gets updated appropriately.
+
+gas/
+2019-04-02 Max Filippov <jcmvbkbc@gmail.com>
+
+ * config/tc-xtensa.c (convert_frag_immed): Drop
+ convert_frag_immed_finish_loop invocation.
+ (convert_frag_immed_finish_loop): Drop declaration and
+ definition.
+ * config/xtensa-relax.c (widen_spec_list): Replace loop
+ widening that uses addi/addmi with widening that uses l32r
+ and const16.
+
+Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
+---
+ gas/config/tc-xtensa.c | 120 ----------------------------------------------
+ gas/config/xtensa-relax.c | 77 ++++++++++++++++++++---------
+ 2 files changed, 55 insertions(+), 142 deletions(-)
+
+diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c
+index 3bdbbc931cfc..0cc06361cf6f 100644
+--- a/gas/config/tc-xtensa.c
++++ b/gas/config/tc-xtensa.c
+@@ -10668,7 +10668,6 @@ convert_frag_fill_nop (fragS *fragP)
+ static fixS *fix_new_exp_in_seg
+ (segT, subsegT, fragS *, int, int, expressionS *, int,
+ bfd_reloc_code_real_type);
+-static void convert_frag_immed_finish_loop (segT, fragS *, TInsn *);
+
+ static void
+ convert_frag_immed (segT segP,
+@@ -10910,9 +10909,6 @@ convert_frag_immed (segT segP,
+ }
+ }
+
+- if (expanded && xtensa_opcode_is_loop (isa, orig_tinsn.opcode) == 1)
+- convert_frag_immed_finish_loop (segP, fragP, &orig_tinsn);
+-
+ if (expanded && is_direct_call_opcode (orig_tinsn.opcode))
+ {
+ /* Add an expansion note on the expanded instruction. */
+@@ -10949,122 +10945,6 @@ fix_new_exp_in_seg (segT new_seg,
+ }
+
+
+-/* Relax a loop instruction so that it can span loop >256 bytes.
+-
+- loop as, .L1
+- .L0:
+- rsr as, LEND
+- wsr as, LBEG
+- addi as, as, lo8 (label-.L1)
+- addmi as, as, mid8 (label-.L1)
+- wsr as, LEND
+- isync
+- rsr as, LCOUNT
+- addi as, as, 1
+- .L1:
+- <<body>>
+- label:
+-*/
+-
+-static void
+-convert_frag_immed_finish_loop (segT segP, fragS *fragP, TInsn *tinsn)
+-{
+- TInsn loop_insn;
+- TInsn addi_insn;
+- TInsn addmi_insn;
+- unsigned long target;
+- static xtensa_insnbuf insnbuf = NULL;
+- unsigned int loop_length, loop_length_hi, loop_length_lo;
+- xtensa_isa isa = xtensa_default_isa;
+- addressT loop_offset;
+- addressT addi_offset = 9;
+- addressT addmi_offset = 12;
+- fragS *next_fragP;
+- int target_count;
+-
+- if (!insnbuf)
+- insnbuf = xtensa_insnbuf_alloc (isa);
+-
+- /* Get the loop offset. */
+- loop_offset = get_expanded_loop_offset (tinsn->opcode);
+-
+- /* Validate that there really is a LOOP at the loop_offset. Because
+- loops are not bundleable, we can assume that the instruction will be
+- in slot 0. */
+- tinsn_from_chars (&loop_insn, fragP->fr_opcode + loop_offset, 0);
+- tinsn_immed_from_frag (&loop_insn, fragP, 0);
+-
+- gas_assert (xtensa_opcode_is_loop (isa, loop_insn.opcode) == 1);
+- addi_offset += loop_offset;
+- addmi_offset += loop_offset;
+-
+- gas_assert (tinsn->ntok == 2);
+- if (tinsn->tok[1].X_op == O_constant)
+- target = tinsn->tok[1].X_add_number;
+- else if (tinsn->tok[1].X_op == O_symbol)
+- {
+- /* Find the fragment. */
+- symbolS *sym = tinsn->tok[1].X_add_symbol;
+- gas_assert (S_GET_SEGMENT (sym) == segP
+- || S_GET_SEGMENT (sym) == absolute_section);
+- target = (S_GET_VALUE (sym) + tinsn->tok[1].X_add_number);
+- }
+- else
+- {
+- as_bad (_("invalid expression evaluation type %d"), tinsn->tok[1].X_op);
+- target = 0;
+- }
+-
+- loop_length = target - (fragP->fr_address + fragP->fr_fix);
+- loop_length_hi = loop_length & ~0x0ff;
+- loop_length_lo = loop_length & 0x0ff;
+- if (loop_length_lo >= 128)
+- {
+- loop_length_lo -= 256;
+- loop_length_hi += 256;
+- }
+-
+- /* Because addmi sign-extends the immediate, 'loop_length_hi' can be at most
+- 32512. If the loop is larger than that, then we just fail. */
+- if (loop_length_hi > 32512)
+- as_bad_where (fragP->fr_file, fragP->fr_line,
+- _("loop too long for LOOP instruction"));
+-
+- tinsn_from_chars (&addi_insn, fragP->fr_opcode + addi_offset, 0);
+- gas_assert (addi_insn.opcode == xtensa_addi_opcode);
+-
+- tinsn_from_chars (&addmi_insn, fragP->fr_opcode + addmi_offset, 0);
+- gas_assert (addmi_insn.opcode == xtensa_addmi_opcode);
+-
+- set_expr_const (&addi_insn.tok[2], loop_length_lo);
+- tinsn_to_insnbuf (&addi_insn, insnbuf);
+-
+- fragP->tc_frag_data.is_insn = TRUE;
+- xtensa_insnbuf_to_chars
+- (isa, insnbuf, (unsigned char *) fragP->fr_opcode + addi_offset, 0);
+-
+- set_expr_const (&addmi_insn.tok[2], loop_length_hi);
+- tinsn_to_insnbuf (&addmi_insn, insnbuf);
+- xtensa_insnbuf_to_chars
+- (isa, insnbuf, (unsigned char *) fragP->fr_opcode + addmi_offset, 0);
+-
+- /* Walk through all of the frags from here to the loop end
+- and mark them as no_transform to keep them from being modified
+- by the linker. If we ever have a relocation for the
+- addi/addmi of the difference of two symbols we can remove this. */
+-
+- target_count = 0;
+- for (next_fragP = fragP; next_fragP != NULL;
+- next_fragP = next_fragP->fr_next)
+- {
+- next_fragP->tc_frag_data.is_no_transform = TRUE;
+- if (next_fragP->tc_frag_data.is_loop_target)
+- target_count++;
+- if (target_count == 2)
+- break;
+- }
+-}
+-
+
+ /* A map that keeps information on a per-subsegment basis. This is
+ maintained during initial assembly, but is invalid once the
+diff --git a/gas/config/xtensa-relax.c b/gas/config/xtensa-relax.c
+index cb296ed85ed2..daf15d52c259 100644
+--- a/gas/config/xtensa-relax.c
++++ b/gas/config/xtensa-relax.c
+@@ -87,13 +87,7 @@
+ when the first and second operands are not the same as specified
+ by the "| %at!=%as" precondition clause.
+ {"l32i %at,%as,%imm | %at!=%as",
+- "LITERAL %imm; l32r %at,%LITERAL; add %at,%at,%as; l32i %at,%at,0"}
+-
+- There is special case for loop instructions here, but because we do
+- not currently have the ability to represent the difference of two
+- symbols, the conversion requires special code in the assembler to
+- write the operands of the addi/addmi pair representing the
+- difference of the old and new loop end label. */
++ "LITERAL %imm; l32r %at,%LITERAL; add %at,%at,%as; l32i %at,%at,0"} */
+
+ #include "as.h"
+ #include "xtensa-isa.h"
+@@ -306,44 +300,83 @@ static string_pattern_pair widen_spec_list[] =
+ {"l32i %at,%as,%imm | %at!=%as ? IsaUseConst16",
+ "const16 %at,HI16U(%imm); const16 %at,LOW16U(%imm); add %at,%at,%as; l32i %at,%at,0"},
+
+- /* This is only PART of the loop instruction. In addition,
+- hardcoded into its use is a modification of the final operand in
+- the instruction in bytes 9 and 12. */
+- {"loop %as,%label | %as!=1 ? IsaUseLoops",
++ /* Widening loops with literals. */
++ {"loop %as,%label | %as!=1 ? IsaUseLoops ? IsaUseL32R",
++ "loop %as,%LABEL;"
++ "rsr.lend %as;" /* LEND */
++ "wsr.lbeg %as;" /* LBEG */
++ "LITERAL %label;"
++ "l32r %as, %LITERAL;"
++ "nop;"
++ "wsr.lend %as;"
++ "isync;"
++ "rsr.lcount %as;" /* LCOUNT */
++ "addi %as, %as, 1;"
++ "LABEL"},
++ {"loopgtz %as,%label | %as!=1 ? IsaUseLoops ? IsaUseL32R",
++ "beqz %as,%label;"
++ "bltz %as,%label;"
++ "loopgtz %as,%LABEL;"
++ "rsr.lend %as;" /* LEND */
++ "wsr.lbeg %as;" /* LBEG */
++ "LITERAL %label;"
++ "l32r %as, %LITERAL;"
++ "nop;"
++ "wsr.lend %as;"
++ "isync;"
++ "rsr.lcount %as;" /* LCOUNT */
++ "addi %as, %as, 1;"
++ "LABEL"},
++ {"loopnez %as,%label | %as!=1 ? IsaUseLoops ? IsaUseL32R",
++ "beqz %as,%label;"
++ "loopnez %as,%LABEL;"
++ "rsr.lend %as;" /* LEND */
++ "wsr.lbeg %as;" /* LBEG */
++ "LITERAL %label;"
++ "l32r %as, %LITERAL;"
++ "nop;"
++ "wsr.lend %as;"
++ "isync;"
++ "rsr.lcount %as;" /* LCOUNT */
++ "addi %as, %as, 1;"
++ "LABEL"},
++
++ /* Widening loops with const16. */
++ {"loop %as,%label | %as!=1 ? IsaUseLoops ? IsaUseConst16",
+ "loop %as,%LABEL;"
+ "rsr.lend %as;" /* LEND */
+ "wsr.lbeg %as;" /* LBEG */
+- "addi %as, %as, 0;" /* lo8(%label-%LABEL1) */
+- "addmi %as, %as, 0;" /* mid8(%label-%LABEL1) */
++ "const16 %as,HI16U(%label);"
++ "const16 %as,LOW16U(%label);"
+ "wsr.lend %as;"
+ "isync;"
+ "rsr.lcount %as;" /* LCOUNT */
+- "addi %as, %as, 1;" /* density -> addi.n %as, %as, 1 */
++ "addi %as, %as, 1;"
+ "LABEL"},
+- {"loopgtz %as,%label | %as!=1 ? IsaUseLoops",
++ {"loopgtz %as,%label | %as!=1 ? IsaUseLoops ? IsaUseConst16",
+ "beqz %as,%label;"
+ "bltz %as,%label;"
+ "loopgtz %as,%LABEL;"
+ "rsr.lend %as;" /* LEND */
+ "wsr.lbeg %as;" /* LBEG */
+- "addi %as, %as, 0;" /* lo8(%label-%LABEL1) */
+- "addmi %as, %as, 0;" /* mid8(%label-%LABEL1) */
++ "const16 %as,HI16U(%label);"
++ "const16 %as,LOW16U(%label);"
+ "wsr.lend %as;"
+ "isync;"
+ "rsr.lcount %as;" /* LCOUNT */
+- "addi %as, %as, 1;" /* density -> addi.n %as, %as, 1 */
++ "addi %as, %as, 1;"
+ "LABEL"},
+- {"loopnez %as,%label | %as!=1 ? IsaUseLoops",
++ {"loopnez %as,%label | %as!=1 ? IsaUseLoops ? IsaUseConst16",
+ "beqz %as,%label;"
+ "loopnez %as,%LABEL;"
+ "rsr.lend %as;" /* LEND */
+ "wsr.lbeg %as;" /* LBEG */
+- "addi %as, %as, 0;" /* lo8(%label-%LABEL1) */
+- "addmi %as, %as, 0;" /* mid8(%label-%LABEL1) */
++ "const16 %as,HI16U(%label);"
++ "const16 %as,LOW16U(%label);"
+ "wsr.lend %as;"
+ "isync;"
+ "rsr.lcount %as;" /* LCOUNT */
+- "addi %as, %as, 1;" /* density -> addi.n %as, %as, 1 */
++ "addi %as, %as, 1;"
+ "LABEL"},
+
+ /* Relaxing to wide branches. Order is important here. With wide
+--
+2.11.0
+
diff --git a/toolchain/binutils/patches/2.32/0005-xtensa-gas-put-.literal_position-at-section-start.patch b/toolchain/binutils/patches/2.32/0005-xtensa-gas-put-.literal_position-at-section-start.patch
new file mode 100644
index 000000000..b4bbc27b3
--- /dev/null
+++ b/toolchain/binutils/patches/2.32/0005-xtensa-gas-put-.literal_position-at-section-start.patch
@@ -0,0 +1,96 @@
+From 471702ac4a57878a06e8167f063274cf413e548d Mon Sep 17 00:00:00 2001
+From: Max Filippov <jcmvbkbc@gmail.com>
+Date: Mon, 8 Apr 2019 13:47:18 -0700
+Subject: [PATCH] xtensa: gas: put .literal_position at section start
+
+Provide literal position at the beginning of each section for literal
+space reserved by relaxations when text-section-literals or
+auto-litpools options are used. Remove code that adds fill frag to the
+literal section for every .literal_position directive to avoid creation
+of empty literal sections.
+
+Fix auto-litpools tests that got literal pool address changes.
+
+gas/
+2019-04-11 Max Filippov <jcmvbkbc@gmail.com>
+
+ * config/tc-xtensa.c (xtensa_is_init_fini): Add declaration.
+ (xtensa_mark_literal_pool_location): Don't add fill frag to literal
+ section that records literal pool location.
+ (md_begin): Call xtensa_mark_literal_pool_location when text
+ section literals or auto litpools are used.
+ (xtensa_elf_section_change_hook): Call
+ xtensa_mark_literal_pool_location when text section literals or
+ auto litpools are used, there's no literal pool location defined
+ for the current section and it's not .init or .fini.
+
+Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
+---
+ gas/config/tc-xtensa.c | 22 +++++++++-------------
+ 1 file changed, 9 insertions(+), 13 deletions(-)
+
+diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c
+index 0cc06361cf6f..6a80e76fed8c 100644
+--- a/gas/config/tc-xtensa.c
++++ b/gas/config/tc-xtensa.c
+@@ -497,6 +497,7 @@ static fixS *xg_append_jump (fragS *fragP, symbolS *sym, offsetT offset);
+ static void xtensa_maybe_create_literal_pool_frag (bfd_boolean, bfd_boolean);
+ static bfd_boolean auto_litpools = FALSE;
+ static int auto_litpool_limit = 0;
++static bfd_boolean xtensa_is_init_fini (segT seg);
+
+ /* Alignment Functions. */
+
+@@ -4797,7 +4798,6 @@ xtensa_mark_literal_pool_location (void)
+ {
+ /* Any labels pointing to the current location need
+ to be adjusted to after the literal pool. */
+- emit_state s;
+ fragS *pool_location;
+
+ if (use_literal_section)
+@@ -4818,19 +4818,7 @@ xtensa_mark_literal_pool_location (void)
+ RELAX_LITERAL_POOL_END, NULL, 0, NULL);
+ xtensa_set_frag_assembly_state (frag_now);
+
+- /* Now put a frag into the literal pool that points to this location. */
+ set_literal_pool_location (now_seg, pool_location);
+- xtensa_switch_to_non_abs_literal_fragment (&s);
+- frag_align (2, 0, 0);
+- record_alignment (now_seg, 2);
+-
+- /* Close whatever frag is there. */
+- frag_variant (rs_fill, 0, 0, 0, NULL, 0, NULL);
+- xtensa_set_frag_assembly_state (frag_now);
+- frag_now->tc_frag_data.literal_frag = pool_location;
+- frag_variant (rs_fill, 0, 0, 0, NULL, 0, NULL);
+- xtensa_restore_emit_state (&s);
+- xtensa_set_frag_assembly_state (frag_now);
+ }
+
+
+@@ -5334,6 +5322,9 @@ md_begin (void)
+ /* Set up the assembly state. */
+ if (!frag_now->tc_frag_data.is_assembly_state_set)
+ xtensa_set_frag_assembly_state (frag_now);
++
++ if (!use_literal_section)
++ xtensa_mark_literal_pool_location ();
+ }
+
+
+@@ -5933,6 +5924,11 @@ xtensa_elf_section_change_hook (void)
+ /* Set up the assembly state. */
+ if (!frag_now->tc_frag_data.is_assembly_state_set)
+ xtensa_set_frag_assembly_state (frag_now);
++
++ if (!use_literal_section
++ && seg_info (now_seg)->tc_segment_info_data.literal_pool_loc == NULL
++ && !xtensa_is_init_fini (now_seg))
++ xtensa_mark_literal_pool_location ();
+ }
+
+
+--
+2.11.0
+
diff --git a/toolchain/gcc/patches/8.3.0/0001-xtensa-backport-fix-for-PR-target-90922.patch b/toolchain/gcc/patches/8.3.0/0001-xtensa-backport-fix-for-PR-target-90922.patch
new file mode 100644
index 000000000..c961ce5d2
--- /dev/null
+++ b/toolchain/gcc/patches/8.3.0/0001-xtensa-backport-fix-for-PR-target-90922.patch
@@ -0,0 +1,43 @@
+From a592242578e573778241cae6d3928c064dcdfda4 Mon Sep 17 00:00:00 2001
+From: jcmvbkbc <jcmvbkbc@138bc75d-0d04-0410-961f-82ee72b054a4>
+Date: Tue, 18 Jun 2019 22:19:12 +0000
+Subject: [PATCH] xtensa: fix for PR target/90922
+
+Stack pointer adjustment code in prologue missed a case of no
+callee-saved registers and a stack frame size bigger than 128 bytes.
+Handle that case.
+
+This fixes the following gcc tests with call0 ABI:
+ gcc.c-torture/execute/stdarg-2.c
+ gcc.dg/torture/pr55882.c
+ gcc.dg/torture/pr57569.c
+
+gcc/
+2019-06-18 Max Filippov <jcmvbkbc@gmail.com>
+
+ * config/xtensa/xtensa.c (xtensa_expand_prologue): Add stack
+ pointer adjustment for the case of no callee-saved registers and
+ stack frame bigger than 128 bytes.
+
+Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
+---
+ gcc/config/xtensa/xtensa.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/gcc/config/xtensa/xtensa.c b/gcc/config/xtensa/xtensa.c
+index 19bd616d67f6..ee5612441e25 100644
+--- a/gcc/config/xtensa/xtensa.c
++++ b/gcc/config/xtensa/xtensa.c
+@@ -2862,7 +2862,8 @@ xtensa_expand_prologue (void)
+ gen_rtx_SET (mem, reg));
+ }
+ }
+- if (total_size > 1024)
++ if (total_size > 1024
++ || (!callee_save_size && total_size > 128))
+ {
+ rtx tmp_reg = gen_rtx_REG (Pmode, A9_REG);
+ emit_move_insn (tmp_reg, GEN_INT (total_size -
+--
+2.11.0
+
diff --git a/toolchain/gcc/patches/8.3.0/0002-xtensa-fix-PR-target-91880.patch b/toolchain/gcc/patches/8.3.0/0002-xtensa-fix-PR-target-91880.patch
new file mode 100644
index 000000000..e65352501
--- /dev/null
+++ b/toolchain/gcc/patches/8.3.0/0002-xtensa-fix-PR-target-91880.patch
@@ -0,0 +1,49 @@
+From 7c11710230921246156aecc20eb4b6ccaeaaa473 Mon Sep 17 00:00:00 2001
+From: Max Filippov <jcmvbkbc@gmail.com>
+Date: Tue, 24 Sep 2019 04:15:17 -0700
+Subject: [PATCH] xtensa: fix PR target/91880
+
+Xtensa hwloop_optimize segfaults when zero overhead loop is about to be
+inserted as the first instruction of the function.
+Insert zero overhead loop instruction into new basic block before the
+loop when basic block that precedes the loop is empty.
+
+2019-09-26 Max Filippov <jcmvbkbc@gmail.com>
+gcc/
+ * config/xtensa/xtensa.c (hwloop_optimize): Insert zero overhead
+ loop instruction into new basic block before the loop when basic
+ block that precedes the loop is empty.
+
+Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
+---
+Backported from: r276166
+
+ gcc/config/xtensa/xtensa.c | 5 ++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/gcc/config/xtensa/xtensa.c b/gcc/config/xtensa/xtensa.c
+index ee5612441e25..2527468d57db 100644
+--- a/gcc/config/xtensa/xtensa.c
++++ b/gcc/config/xtensa/xtensa.c
+@@ -4232,7 +4232,9 @@ hwloop_optimize (hwloop_info loop)
+
+ seq = get_insns ();
+
+- if (!single_succ_p (entry_bb) || vec_safe_length (loop->incoming) > 1)
++ entry_after = BB_END (entry_bb);
++ if (!single_succ_p (entry_bb) || vec_safe_length (loop->incoming) > 1
++ || !entry_after)
+ {
+ basic_block new_bb;
+ edge e;
+@@ -4253,7 +4255,6 @@ hwloop_optimize (hwloop_info loop)
+ }
+ else
+ {
+- entry_after = BB_END (entry_bb);
+ while (DEBUG_INSN_P (entry_after)
+ || (NOTE_P (entry_after)
+ && NOTE_KIND (entry_after) != NOTE_INSN_BASIC_BLOCK))
+--
+2.11.0
+