diff --git a/configure.ac b/configure.ac index 9899a3bdd..1cd439187 100644 --- a/configure.ac +++ b/configure.ac @@ -186,7 +186,7 @@ AC_CACHE_VAL([ac_cv_path__BASH], AC_CACHE_CHECK([for bash >= 3.1], [ac_cv_path__BASH], [AC_PATH_PROGS_FEATURE_CHECK([_BASH], [bash], [[_BASH_ver=$($ac_path__BASH --version 2>&1 \ - |$EGREP '^GNU bash, version (3\.[1-9]|4)') + |$EGREP '^GNU bash, version (3\.[1-9]|4|5)') test -n "$_BASH_ver" && ac_cv_path__BASH=$ac_path__BASH ac_path__BASH_found=:]], [AC_MSG_RESULT([no]) AC_MSG_ERROR([could not find bash >= 3.1])])]) diff --git a/local-patches/gcc/4.8.2/0001-WIP-xtensa-fix-lib-code-for-call0-ABI.patch b/local-patches/gcc/4.8.2/0001-WIP-xtensa-fix-lib-code-for-call0-ABI.patch index dbfb765f4..952375c6f 100644 --- a/local-patches/gcc/4.8.2/0001-WIP-xtensa-fix-lib-code-for-call0-ABI.patch +++ b/local-patches/gcc/4.8.2/0001-WIP-xtensa-fix-lib-code-for-call0-ABI.patch @@ -1,7 +1,7 @@ From 676b5a725bd71c9deb72b1957a5e6cf892d5d9fb Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Sun, 14 Sep 2014 21:15:14 -0700 -Subject: [PATCH 1/3] WIP: xtensa: fix lib code for call0 ABI +Subject: [PATCH 01/25] WIP: xtensa: fix lib code for call0 ABI Signed-off-by: Max Filippov --- diff --git a/local-patches/gcc/4.8.2/0002-WIP-xtensa-implement-call0-ABI.patch b/local-patches/gcc/4.8.2/0002-WIP-xtensa-implement-call0-ABI.patch index 3ac52cd7e..4581deda9 100644 --- a/local-patches/gcc/4.8.2/0002-WIP-xtensa-implement-call0-ABI.patch +++ b/local-patches/gcc/4.8.2/0002-WIP-xtensa-implement-call0-ABI.patch @@ -1,7 +1,7 @@ From 06d069d40208c4ce7456920e8b4f571ac9511821 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Sun, 14 Sep 2014 16:43:27 -0700 -Subject: [PATCH 2/3] WIP: xtensa: implement call0 ABI +Subject: [PATCH 02/25] WIP: xtensa: implement call0 ABI Signed-off-by: Max Filippov --- diff --git a/local-patches/gcc/4.8.2/0003-WIP-xtensa-implement-callee-saved-register-saving.patch b/local-patches/gcc/4.8.2/0003-WIP-xtensa-implement-callee-saved-register-saving.patch index a2a18fc0c..16a629faf 100644 --- a/local-patches/gcc/4.8.2/0003-WIP-xtensa-implement-callee-saved-register-saving.patch +++ b/local-patches/gcc/4.8.2/0003-WIP-xtensa-implement-callee-saved-register-saving.patch @@ -1,7 +1,7 @@ From d82c531991bb31e864e05f02032187f2e9dbc66f Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Sun, 28 Sep 2014 22:52:01 +0400 -Subject: [PATCH 3/3] WIP: xtensa: implement callee-saved register saving +Subject: [PATCH 03/25] WIP: xtensa: implement callee-saved register saving Also fix frame pointer, correctly move stack pointer, and avoid movsp. diff --git a/local-patches/gcc/4.8.2/0004-xtensa-always-emit-.literal_position-for-call0-ABI.patch b/local-patches/gcc/4.8.2/0004-xtensa-always-emit-.literal_position-for-call0-ABI.patch index 69556be45..0aba04a29 100644 --- a/local-patches/gcc/4.8.2/0004-xtensa-always-emit-.literal_position-for-call0-ABI.patch +++ b/local-patches/gcc/4.8.2/0004-xtensa-always-emit-.literal_position-for-call0-ABI.patch @@ -1,7 +1,7 @@ From 0b74cbfbbf3aa9b67f1c9f1971e98b0980b10661 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Sun, 5 Oct 2014 05:54:31 +0400 -Subject: [PATCH 4/5] xtensa: always emit .literal_position for call0 ABI +Subject: [PATCH 04/25] xtensa: always emit .literal_position for call0 ABI xtensa assembler implicitly starts literal pool before entry instructions. Emit .literal_position at the beginning of function for diff --git a/local-patches/gcc/4.8.2/0005-xtensa-use-subsi3-instead-of-addsi3-in-call0-prologu.patch b/local-patches/gcc/4.8.2/0005-xtensa-use-subsi3-instead-of-addsi3-in-call0-prologu.patch index 2200ca8b5..bde82da3c 100644 --- a/local-patches/gcc/4.8.2/0005-xtensa-use-subsi3-instead-of-addsi3-in-call0-prologu.patch +++ b/local-patches/gcc/4.8.2/0005-xtensa-use-subsi3-instead-of-addsi3-in-call0-prologu.patch @@ -1,7 +1,7 @@ From 1acaae7db15d0da960cbfd470533a51d8551f7b9 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Sun, 5 Oct 2014 06:26:18 +0400 -Subject: [PATCH 5/5] xtensa: use subsi3 instead of addsi3 in call0 prologue +Subject: [PATCH 05/25] xtensa: use subsi3 instead of addsi3 in call0 prologue This allows sharing single literal for stack adjustment between prologue and epilogue. diff --git a/local-patches/gcc/4.8.2/0006-xtensa-don-t-mess-with-argument-in-a7-in-CALL0-ABI.patch b/local-patches/gcc/4.8.2/0006-xtensa-don-t-mess-with-argument-in-a7-in-CALL0-ABI.patch new file mode 100644 index 000000000..f37e42a73 --- /dev/null +++ b/local-patches/gcc/4.8.2/0006-xtensa-don-t-mess-with-argument-in-a7-in-CALL0-ABI.patch @@ -0,0 +1,48 @@ +From 2d1af52aaa84f8e15a32eeb5ec58868f842a8acc Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Sun, 9 Nov 2014 03:48:56 +0300 +Subject: [PATCH 06/25] xtensa: don't mess with argument in a7 in CALL0 ABI + +Otherwise prologue ends with frame pointer in a7 instead of a15. CALL0 +ABI doesn't need this special care because a7 is an ordinary register in +that ABI. + +Signed-off-by: Max Filippov +--- + gcc/config/xtensa/xtensa.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/gcc/config/xtensa/xtensa.c b/gcc/config/xtensa/xtensa.c +index 7a17ea8..29dc603 100644 +--- a/gcc/config/xtensa/xtensa.c ++++ b/gcc/config/xtensa/xtensa.c +@@ -2118,7 +2118,7 @@ xtensa_function_arg_1 (cumulative_args_t cum_v, enum machine_mode mode, + regno = regbase + *arg_words; + + if (cum->incoming && regno <= A7_REG && regno + words > A7_REG) +- cfun->machine->need_a7_copy = true; ++ cfun->machine->need_a7_copy = TARGET_WINDOWED_ABI; + + return gen_rtx_REG (mode, regno); + } +@@ -2957,14 +2957,14 @@ xtensa_builtin_saveregs (void) + set_mem_alias_set (gp_regs, get_varargs_alias_set ()); + + /* Now store the incoming registers. */ +- cfun->machine->need_a7_copy = true; ++ cfun->machine->need_a7_copy = TARGET_WINDOWED_ABI; + cfun->machine->vararg_a7 = true; + move_block_from_reg (GP_ARG_FIRST + arg_words, + adjust_address (gp_regs, BLKmode, + arg_words * UNITS_PER_WORD), + gp_left); +- gcc_assert (cfun->machine->vararg_a7_copy != 0); +- emit_insn_before (cfun->machine->vararg_a7_copy, get_insns ()); ++ if (cfun->machine->vararg_a7_copy != 0) ++ emit_insn_before (cfun->machine->vararg_a7_copy, get_insns ()); + + return XEXP (gp_regs, 0); + } +-- +1.8.1.4 + diff --git a/local-patches/gcc/4.8.2/0007-xtensa-use-correct-guards-on-CRT_CALL_STATIC_FUNCTIO.patch b/local-patches/gcc/4.8.2/0007-xtensa-use-correct-guards-on-CRT_CALL_STATIC_FUNCTIO.patch new file mode 100644 index 000000000..22cdaf127 --- /dev/null +++ b/local-patches/gcc/4.8.2/0007-xtensa-use-correct-guards-on-CRT_CALL_STATIC_FUNCTIO.patch @@ -0,0 +1,37 @@ +From b1b4c61a540a146d5f1acb31fa065204b83eb6a4 Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Sun, 9 Nov 2014 04:52:36 +0300 +Subject: [PATCH 07/25] xtensa: use correct guards on CRT_CALL_STATIC_FUNCTION + definition + +CRT_CALL_STATIC_FUNCTION is used in libgcc, so it needs to be defined +depending on __XTENSA_*_ABI__, not TARGET_WINDOWED_ABI. + +Signed-off-by: Max Filippov +--- + gcc/config/xtensa/xtensa.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/gcc/config/xtensa/xtensa.h b/gcc/config/xtensa/xtensa.h +index 9f4a8a1..f7e22ce 100644 +--- a/gcc/config/xtensa/xtensa.h ++++ b/gcc/config/xtensa/xtensa.h +@@ -880,13 +880,13 @@ typedef struct xtensa_args + a MOVI and let the assembler relax it -- for the .init and .fini + sections, the assembler knows to put the literal in the right + place. */ +-#if TARGET_WINDOWED_ABI ++#if defined(__XTENSA_WINDOWED_ABI__) + #define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC) \ + asm (SECTION_OP "\n\ + movi\ta8, " USER_LABEL_PREFIX #FUNC "\n\ + callx8\ta8\n" \ + TEXT_SECTION_ASM_OP); +-#else ++#elif defined(__XTENSA_CALL0_ABI__) + #define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC) \ + asm (SECTION_OP "\n\ + movi\ta0, " USER_LABEL_PREFIX #FUNC "\n\ +-- +1.8.1.4 + diff --git a/local-patches/gcc/4.8.2/0008-xtensa-move-callee-saved-register-check-to-xtensa_ca.patch b/local-patches/gcc/4.8.2/0008-xtensa-move-callee-saved-register-check-to-xtensa_ca.patch new file mode 100644 index 000000000..41137c080 --- /dev/null +++ b/local-patches/gcc/4.8.2/0008-xtensa-move-callee-saved-register-check-to-xtensa_ca.patch @@ -0,0 +1,70 @@ +From 2f60e5db550a287c58e6e69d993946818d01159c Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Sun, 9 Nov 2014 06:24:08 +0300 +Subject: [PATCH 08/25] xtensa: move callee-saved register check to + xtensa_call_save_reg + +Don't reserve extra stack space with windowed ABI. Save A0 when +profiling is enabled. + +Signed-off-by: Max Filippov +--- + gcc/config/xtensa/xtensa.c | 21 +++++++++++++++------ + 1 file changed, 15 insertions(+), 6 deletions(-) + +diff --git a/gcc/config/xtensa/xtensa.c b/gcc/config/xtensa/xtensa.c +index 29dc603..e5dc8db 100644 +--- a/gcc/config/xtensa/xtensa.c ++++ b/gcc/config/xtensa/xtensa.c +@@ -2585,6 +2585,18 @@ xtensa_output_literal (FILE *file, rtx x, enum machine_mode mode, int labelno) + } + } + ++static bool ++xtensa_call_save_reg(int regno) ++{ ++ if (TARGET_WINDOWED_ABI) ++ return false; ++ ++ if (regno == A0_REG) ++ return crtl->profile || df_regs_ever_live_p (regno); ++ ++ return !fixed_regs[regno] && !call_used_regs[regno] && ++ df_regs_ever_live_p (regno); ++} + + /* Return the bytes needed to compute the frame pointer from the current + stack pointer. */ +@@ -2604,8 +2616,7 @@ compute_frame_size (int size) + xtensa_callee_save_size = 0; + for (regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno) + { +- if ((regno == A0_REG || (!fixed_regs[regno] && !call_used_regs[regno])) && +- df_regs_ever_live_p (regno)) ++ if (xtensa_call_save_reg(regno)) + xtensa_callee_save_size += UNITS_PER_WORD; + } + +@@ -2691,8 +2702,7 @@ xtensa_expand_prologue (void) + + for (regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno) + { +- if ((regno == A0_REG || (!fixed_regs[regno] && !call_used_regs[regno])) && +- df_regs_ever_live_p (regno)) ++ if (xtensa_call_save_reg(regno)) + { + rtx x = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (offset)); + +@@ -2779,8 +2789,7 @@ xtensa_expand_epilogue (void) + + for (regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno) + { +- if ((regno == A0_REG || (!fixed_regs[regno] && !call_used_regs[regno])) && +- df_regs_ever_live_p (regno)) ++ if (xtensa_call_save_reg(regno)) + { + rtx x = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (offset)); + +-- +1.8.1.4 + diff --git a/local-patches/gcc/4.8.2/0009-WIP-xtensa-fix-_mcount-call-for-CALL0-ABI.patch b/local-patches/gcc/4.8.2/0009-WIP-xtensa-fix-_mcount-call-for-CALL0-ABI.patch new file mode 100644 index 000000000..ab87b35c2 --- /dev/null +++ b/local-patches/gcc/4.8.2/0009-WIP-xtensa-fix-_mcount-call-for-CALL0-ABI.patch @@ -0,0 +1,56 @@ +From c73b720ae2759c70a4c657962e0bcb40c42fd9bc Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Sun, 9 Nov 2014 06:26:29 +0300 +Subject: [PATCH 09/25] WIP: xtensa: fix _mcount call for CALL0 ABI + +_mcount is not specified, let's call it with return address in a10, and +require it to preserve all registers. + +Signed-off-by: Max Filippov +--- + gcc/config/xtensa/xtensa.h | 21 +++------------------ + 1 file changed, 3 insertions(+), 18 deletions(-) + +diff --git a/gcc/config/xtensa/xtensa.h b/gcc/config/xtensa/xtensa.h +index f7e22ce..653631e 100644 +--- a/gcc/config/xtensa/xtensa.h ++++ b/gcc/config/xtensa/xtensa.h +@@ -601,32 +601,17 @@ typedef struct xtensa_args + + #define NO_PROFILE_COUNTERS 1 + +-#if TARGET_WINDOWED_ABI + #define FUNCTION_PROFILER(FILE, LABELNO) \ + do { \ + fprintf (FILE, "\t%s\ta10, a0\n", TARGET_DENSITY ? "mov.n" : "mov"); \ + if (flag_pic) \ + { \ +- fprintf (FILE, "\tmovi\ta8, _mcount@PLT\n"); \ +- fprintf (FILE, "\tcallx8\ta8\n"); \ +- } \ +- else \ +- fprintf (FILE, "\tcall8\t_mcount\n"); \ +- } while (0) +-#else +-#define FUNCTION_PROFILER(FILE, LABELNO) \ +- do { \ +- fprintf (FILE, "\t%s\ta2, a0\n", TARGET_DENSITY ? "mov.n" : "mov"); \ +- /* TODO save incoming args? */ \ +- if (flag_pic) \ +- { \ +- fprintf (FILE, "\tmovi\ta0, _mcount@PLT\n"); \ +- fprintf (FILE, "\tcallx0\ta0\n"); \ ++ fprintf (FILE, "\tmovi\ta%d, _mcount@PLT\n", WINDOW_SIZE); \ ++ fprintf (FILE, "\tcallx%d\ta%d\n", WINDOW_SIZE, WINDOW_SIZE); \ + } \ + else \ +- fprintf (FILE, "\tcall0\t_mcount\n"); \ ++ fprintf (FILE, "\tcall%d\t_mcount\n", WINDOW_SIZE); \ + } while (0) +-#endif + + /* Stack pointer value doesn't matter at exit. */ + #define EXIT_IGNORE_STACK 1 +-- +1.8.1.4 + diff --git a/local-patches/gcc/4.8.2/0010-xtensa-replace-if-ifdef-with-if-where-possible.patch b/local-patches/gcc/4.8.2/0010-xtensa-replace-if-ifdef-with-if-where-possible.patch new file mode 100644 index 000000000..3e4218c2e --- /dev/null +++ b/local-patches/gcc/4.8.2/0010-xtensa-replace-if-ifdef-with-if-where-possible.patch @@ -0,0 +1,376 @@ +From 8fc87fc4ac361effe8903b433a622c339c076a4f Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Sun, 9 Nov 2014 06:31:09 +0300 +Subject: [PATCH 10/25] xtensa: replace #if/#ifdef with if where possible + +Signed-off-by: Max Filippov +--- + gcc/config/xtensa/xtensa.c | 279 +++++++++++++++++++++++---------------------- + gcc/config/xtensa/xtensa.h | 13 +-- + 2 files changed, 143 insertions(+), 149 deletions(-) + +diff --git a/gcc/config/xtensa/xtensa.c b/gcc/config/xtensa/xtensa.c +index e5dc8db..f44d9ef 100644 +--- a/gcc/config/xtensa/xtensa.c ++++ b/gcc/config/xtensa/xtensa.c +@@ -1603,11 +1603,10 @@ xtensa_setup_frame_addresses (void) + /* Set flag to cause TARGET_FRAME_POINTER_REQUIRED to return true. */ + cfun->machine->accesses_prev_frame = 1; + +-#if TARGET_WINDOWED_ABI +- emit_library_call +- (gen_rtx_SYMBOL_REF (Pmode, "__xtensa_libgcc_window_spill"), +- LCT_NORMAL, VOIDmode, 0); +-#endif ++ if (TARGET_WINDOWED_ABI) ++ emit_library_call ++ (gen_rtx_SYMBOL_REF (Pmode, "__xtensa_libgcc_window_spill"), ++ LCT_NORMAL, VOIDmode, 0); + } + + +@@ -2659,64 +2658,66 @@ xtensa_expand_prologue (void) + + total_size = compute_frame_size (get_frame_size ()); + +-#if TARGET_WINDOWED_ABI +- +- if (total_size < (1 << (12+3))) +- insn = emit_insn (gen_entry (GEN_INT (total_size))); +- else +- { +- /* Use a8 as a temporary since a0-a7 may be live. */ +- rtx tmp_reg = gen_rtx_REG (Pmode, A8_REG); +- emit_insn (gen_entry (GEN_INT (MIN_FRAME_SIZE))); +- emit_move_insn (tmp_reg, GEN_INT (total_size - MIN_FRAME_SIZE)); +- emit_insn (gen_subsi3 (tmp_reg, stack_pointer_rtx, tmp_reg)); +- insn = emit_insn (gen_movsi (stack_pointer_rtx, tmp_reg)); +- } +-#else +- /* -128 is a limit of single addi instruction. */ +- if (total_size > 0 && total_size <= 128) ++ if (TARGET_WINDOWED_ABI) + { +- insn = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, +- GEN_INT (-total_size))); +- offset = total_size - UNITS_PER_WORD; ++ if (total_size < (1 << (12+3))) ++ insn = emit_insn (gen_entry (GEN_INT (total_size))); ++ else ++ { ++ /* Use a8 as a temporary since a0-a7 may be live. */ ++ rtx tmp_reg = gen_rtx_REG (Pmode, A8_REG); ++ emit_insn (gen_entry (GEN_INT (MIN_FRAME_SIZE))); ++ emit_move_insn (tmp_reg, GEN_INT (total_size - MIN_FRAME_SIZE)); ++ emit_insn (gen_subsi3 (tmp_reg, stack_pointer_rtx, tmp_reg)); ++ insn = emit_insn (gen_movsi (stack_pointer_rtx, tmp_reg)); ++ } + } +- else if (xtensa_callee_save_size) ++ else + { +- /* 1020 is maximal s32i offset, if the frame is bigger than that +- * we move sp to the end of callee-saved save area, save and then +- * move it to its final location. */ +- if (total_size > 1024) +- { ++ /* -128 is a limit of single addi instruction. */ ++ if (total_size > 0 && total_size <= 128) ++ { + insn = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, +- GEN_INT (-xtensa_callee_save_size))); +- offset = xtensa_callee_save_size - UNITS_PER_WORD; +- } +- else +- { +- rtx tmp_reg = gen_rtx_REG (Pmode, A9_REG); +- emit_move_insn (tmp_reg, GEN_INT (total_size)); +- insn = emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, tmp_reg)); ++ GEN_INT (-total_size))); + offset = total_size - UNITS_PER_WORD; + } +- } ++ else if (xtensa_callee_save_size) ++ { ++ /* 1020 is maximal s32i offset, if the frame is bigger than that ++ * we move sp to the end of callee-saved save area, save and then ++ * move it to its final location. */ ++ if (total_size > 1024) ++ { ++ insn = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, ++ GEN_INT (-xtensa_callee_save_size))); ++ offset = xtensa_callee_save_size - UNITS_PER_WORD; ++ } ++ else ++ { ++ rtx tmp_reg = gen_rtx_REG (Pmode, A9_REG); ++ emit_move_insn (tmp_reg, GEN_INT (total_size)); ++ insn = emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, tmp_reg)); ++ offset = total_size - UNITS_PER_WORD; ++ } ++ } + +- for (regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno) +- { +- if (xtensa_call_save_reg(regno)) +- { +- rtx x = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (offset)); ++ for (regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno) ++ { ++ if (xtensa_call_save_reg(regno)) ++ { ++ rtx x = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (offset)); + +- offset -= UNITS_PER_WORD; +- emit_move_insn (gen_frame_mem (SImode, x), gen_rtx_REG (SImode, regno)); ++ offset -= UNITS_PER_WORD; ++ emit_move_insn (gen_frame_mem (SImode, x), gen_rtx_REG (SImode, regno)); ++ } ++ } ++ if (total_size > 1024) ++ { ++ rtx tmp_reg = gen_rtx_REG (Pmode, A9_REG); ++ emit_move_insn (tmp_reg, GEN_INT (total_size - xtensa_callee_save_size)); ++ insn = emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, tmp_reg)); + } + } +- if (total_size > 1024) +- { +- rtx tmp_reg = gen_rtx_REG (Pmode, A9_REG); +- emit_move_insn (tmp_reg, GEN_INT (total_size - xtensa_callee_save_size)); +- insn = emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, tmp_reg)); +- } +-#endif + + if (frame_pointer_needed) + { +@@ -2766,73 +2767,74 @@ xtensa_expand_prologue (void) + void + xtensa_expand_epilogue (void) + { +-#if !TARGET_WINDOWED_ABI +- int regno; +- rtx insn; +- HOST_WIDE_INT offset; +- +- if (xtensa_current_frame_size > (frame_pointer_needed ? 127 : 1024)) ++ if (!TARGET_WINDOWED_ABI) + { +- rtx tmp_reg = gen_rtx_REG (Pmode, A9_REG); +- emit_move_insn (tmp_reg, GEN_INT (xtensa_current_frame_size - +- xtensa_callee_save_size)); +- insn = emit_insn (gen_addsi3 (stack_pointer_rtx, frame_pointer_needed ? +- hard_frame_pointer_rtx : stack_pointer_rtx, tmp_reg)); +- offset = xtensa_callee_save_size - UNITS_PER_WORD; +- } +- else +- { +- if (frame_pointer_needed) +- emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx); +- offset = xtensa_current_frame_size - UNITS_PER_WORD; +- } +- +- for (regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno) +- { +- if (xtensa_call_save_reg(regno)) +- { +- rtx x = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (offset)); ++ int regno; ++ rtx insn; ++ HOST_WIDE_INT offset; + +- offset -= UNITS_PER_WORD; +- emit_move_insn (gen_rtx_REG (SImode, regno), gen_frame_mem (SImode, x)); ++ if (xtensa_current_frame_size > (frame_pointer_needed ? 127 : 1024)) ++ { ++ rtx tmp_reg = gen_rtx_REG (Pmode, A9_REG); ++ emit_move_insn (tmp_reg, GEN_INT (xtensa_current_frame_size - ++ xtensa_callee_save_size)); ++ insn = emit_insn (gen_addsi3 (stack_pointer_rtx, frame_pointer_needed ? ++ hard_frame_pointer_rtx : stack_pointer_rtx, tmp_reg)); ++ offset = xtensa_callee_save_size - UNITS_PER_WORD; ++ } ++ else ++ { ++ if (frame_pointer_needed) ++ emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx); ++ offset = xtensa_current_frame_size - UNITS_PER_WORD; + } +- } +- +- if (xtensa_current_frame_size > 0) +- { +- rtx note_rtx; + +- if (frame_pointer_needed || /* always reachable with addi */ +- xtensa_current_frame_size > 1024 || +- xtensa_current_frame_size <= 127) ++ for (regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno) + { +- if (xtensa_current_frame_size <= 127) +- offset = xtensa_current_frame_size; +- else +- offset = xtensa_callee_save_size; ++ if (xtensa_call_save_reg(regno)) ++ { ++ rtx x = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (offset)); + +- insn = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, +- GEN_INT (offset))); ++ offset -= UNITS_PER_WORD; ++ emit_move_insn (gen_rtx_REG (SImode, regno), gen_frame_mem (SImode, x)); ++ } + } +- else ++ ++ if (xtensa_current_frame_size > 0) + { +- rtx tmp_reg = gen_rtx_REG (Pmode, A9_REG); +- emit_move_insn (tmp_reg, GEN_INT (xtensa_current_frame_size)); +- insn = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, tmp_reg)); +- } ++ rtx note_rtx; + +- /* Create a note to describe the CFA. Because this is only used to set +- DW_AT_frame_base for debug info, don't bother tracking changes through +- each instruction in the prologue. It just takes up space. */ +- note_rtx = gen_rtx_SET (VOIDmode, stack_pointer_rtx, +- plus_constant (Pmode, frame_pointer_needed +- ? hard_frame_pointer_rtx +- : stack_pointer_rtx, +- xtensa_current_frame_size)); +- RTX_FRAME_RELATED_P (insn) = 1; +- add_reg_note (insn, REG_FRAME_RELATED_EXPR, note_rtx); ++ if (frame_pointer_needed || /* always reachable with addi */ ++ xtensa_current_frame_size > 1024 || ++ xtensa_current_frame_size <= 127) ++ { ++ if (xtensa_current_frame_size <= 127) ++ offset = xtensa_current_frame_size; ++ else ++ offset = xtensa_callee_save_size; ++ ++ insn = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, ++ GEN_INT (offset))); ++ } ++ else ++ { ++ rtx tmp_reg = gen_rtx_REG (Pmode, A9_REG); ++ emit_move_insn (tmp_reg, GEN_INT (xtensa_current_frame_size)); ++ insn = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, tmp_reg)); ++ } ++ ++ /* Create a note to describe the CFA. Because this is only used to set ++ DW_AT_frame_base for debug info, don't bother tracking changes through ++ each instruction in the prologue. It just takes up space. */ ++ note_rtx = gen_rtx_SET (VOIDmode, stack_pointer_rtx, ++ plus_constant (Pmode, frame_pointer_needed ++ ? hard_frame_pointer_rtx ++ : stack_pointer_rtx, ++ xtensa_current_frame_size)); ++ RTX_FRAME_RELATED_P (insn) = 1; ++ add_reg_note (insn, REG_FRAME_RELATED_EXPR, note_rtx); ++ } + } +-#endif + xtensa_current_frame_size = 0; + xtensa_callee_save_size = 0; + emit_jump_insn (gen_return ()); +@@ -2853,35 +2855,34 @@ xtensa_return_addr (int count, rtx frame) + emit_move_insn (retaddr, gen_rtx_MEM (Pmode, addr)); + } + +-#if TARGET_WINDOWED_ABI +- { +- rtx result, curaddr, label; +- /* The 2 most-significant bits of the return address on Xtensa hold +- the register window size. To get the real return address, these +- bits must be replaced with the high bits from some address in the +- code. */ +- +- /* Get the 2 high bits of a local label in the code. */ +- curaddr = gen_reg_rtx (Pmode); +- label = gen_label_rtx (); +- emit_label (label); +- LABEL_PRESERVE_P (label) = 1; +- emit_move_insn (curaddr, gen_rtx_LABEL_REF (Pmode, label)); +- emit_insn (gen_lshrsi3 (curaddr, curaddr, GEN_INT (30))); +- emit_insn (gen_ashlsi3 (curaddr, curaddr, GEN_INT (30))); +- +- /* Clear the 2 high bits of the return address. */ +- result = gen_reg_rtx (Pmode); +- emit_insn (gen_ashlsi3 (result, retaddr, GEN_INT (2))); +- emit_insn (gen_lshrsi3 (result, result, GEN_INT (2))); +- +- /* Combine them to get the result. */ +- emit_insn (gen_iorsi3 (result, result, curaddr)); +- return result; +- } +-#else +- return retaddr; +-#endif ++ if (TARGET_WINDOWED_ABI) ++ { ++ rtx result, curaddr, label; ++ /* The 2 most-significant bits of the return address on Xtensa hold ++ the register window size. To get the real return address, these ++ bits must be replaced with the high bits from some address in the ++ code. */ ++ ++ /* Get the 2 high bits of a local label in the code. */ ++ curaddr = gen_reg_rtx (Pmode); ++ label = gen_label_rtx (); ++ emit_label (label); ++ LABEL_PRESERVE_P (label) = 1; ++ emit_move_insn (curaddr, gen_rtx_LABEL_REF (Pmode, label)); ++ emit_insn (gen_lshrsi3 (curaddr, curaddr, GEN_INT (30))); ++ emit_insn (gen_ashlsi3 (curaddr, curaddr, GEN_INT (30))); ++ ++ /* Clear the 2 high bits of the return address. */ ++ result = gen_reg_rtx (Pmode); ++ emit_insn (gen_ashlsi3 (result, retaddr, GEN_INT (2))); ++ emit_insn (gen_lshrsi3 (result, result, GEN_INT (2))); ++ ++ /* Combine them to get the result. */ ++ emit_insn (gen_iorsi3 (result, result, curaddr)); ++ return result; ++ } ++ else ++ return retaddr; + } + + /* Disable the use of word-sized or smaller complex modes for structures, +diff --git a/gcc/config/xtensa/xtensa.h b/gcc/config/xtensa/xtensa.h +index 653631e..23374bc 100644 +--- a/gcc/config/xtensa/xtensa.h ++++ b/gcc/config/xtensa/xtensa.h +@@ -358,11 +358,8 @@ extern char xtensa_hard_regno_mode_ok[][FIRST_PSEUDO_REGISTER]; + #define STACK_POINTER_REGNUM (GP_REG_FIRST + 1) + + /* Base register for access to local variables of the function. */ +-#if TARGET_WINDOWED_ABI +-#define HARD_FRAME_POINTER_REGNUM (GP_REG_FIRST + 7) +-#else +-#define HARD_FRAME_POINTER_REGNUM (GP_REG_FIRST + 15) +-#endif ++#define HARD_FRAME_POINTER_REGNUM (GP_REG_FIRST + \ ++ (TARGET_WINDOWED_ABI ? 7 : 15)) + + /* The register number of the frame pointer register, which is used to + access automatic variables in the stack frame. For Xtensa, this +@@ -538,11 +535,7 @@ extern const enum reg_class xtensa_regno_to_class[FIRST_PSEUDO_REGISTER]; + #define STACK_BOUNDARY 128 + + /* Use a fixed register window size of 8. */ +-#if TARGET_WINDOWED_ABI +-#define WINDOW_SIZE 8 +-#else +-#define WINDOW_SIZE 0 +-#endif ++#define WINDOW_SIZE (TARGET_WINDOWED_ABI ? 8 : 0) + + /* Symbolic macros for the registers used to return integer, floating + point, and values of coprocessor and user-defined modes. */ +-- +1.8.1.4 + diff --git a/local-patches/gcc/4.8.2/0011-xtensa-use-default-nonlocal_goto-in-CALL0-ABI.patch b/local-patches/gcc/4.8.2/0011-xtensa-use-default-nonlocal_goto-in-CALL0-ABI.patch new file mode 100644 index 000000000..3efc83a7e --- /dev/null +++ b/local-patches/gcc/4.8.2/0011-xtensa-use-default-nonlocal_goto-in-CALL0-ABI.patch @@ -0,0 +1,82 @@ +From ffda4ff4764984633e3e88374fa38d97a6bb33a4 Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Sun, 9 Nov 2014 23:17:49 +0300 +Subject: [PATCH 11/25] xtensa: use default nonlocal_goto in CALL0 ABI + +CALL0 doesn't need any additional stack modifications, so it can use the +default nonlocal_goto pattern and it doesn't need helper functions to +spill registers and unwind stack. + +Signed-off-by: Max Filippov +--- + gcc/config/xtensa/xtensa.md | 2 +- + libgcc/config/xtensa/lib2funcs.S | 12 ++++-------- + 2 files changed, 5 insertions(+), 9 deletions(-) + +diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md +index 7ddd326..7433b04 100644 +--- a/gcc/config/xtensa/xtensa.md ++++ b/gcc/config/xtensa/xtensa.md +@@ -1655,7 +1655,7 @@ + (match_operand:SI 1 "general_operand" "") + (match_operand:SI 2 "general_operand" "") + (match_operand:SI 3 "" "")] +- "" ++ "TARGET_WINDOWED_ABI" + { + xtensa_expand_nonlocal_goto (operands); + DONE; +diff --git a/libgcc/config/xtensa/lib2funcs.S b/libgcc/config/xtensa/lib2funcs.S +index f6f7a58..aea4449 100644 +--- a/libgcc/config/xtensa/lib2funcs.S ++++ b/libgcc/config/xtensa/lib2funcs.S +@@ -29,19 +29,17 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + current register window. This is used to set up the stack so that + arbitrary frames can be accessed. */ + ++#if XCHAL_HAVE_WINDOWED && !__XTENSA_CALL0_ABI__ + .align 4 + .global __xtensa_libgcc_window_spill + .type __xtensa_libgcc_window_spill,@function + __xtensa_libgcc_window_spill: +-#if XCHAL_HAVE_WINDOWED && !__XTENSA_CALL0_ABI__ + entry sp, 32 + movi a2, 0 + syscall + retw +-#else +- ret +-#endif + .size __xtensa_libgcc_window_spill, .-__xtensa_libgcc_window_spill ++#endif + + + /* __xtensa_nonlocal_goto: This code does all the hard work of a +@@ -55,11 +53,11 @@ __xtensa_libgcc_window_spill: + This function never returns to its caller but instead goes directly + to the address of the specified goto handler. */ + ++#if XCHAL_HAVE_WINDOWED && !__XTENSA_CALL0_ABI__ + .align 4 + .global __xtensa_nonlocal_goto + .type __xtensa_nonlocal_goto,@function + __xtensa_nonlocal_goto: +-#if XCHAL_HAVE_WINDOWED && !__XTENSA_CALL0_ABI__ + entry sp, 32 + + /* Flush registers. */ +@@ -132,10 +130,8 @@ __xtensa_nonlocal_goto: + src a0, a8, a3 /* combine them with a funnel shift */ + + retw +-#else +- ret +-#endif + .size __xtensa_nonlocal_goto, .-__xtensa_nonlocal_goto ++#endif + + + /* __xtensa_sync_caches: This function is called after writing a trampoline +-- +1.8.1.4 + diff --git a/local-patches/gcc/4.8.2/0012-xtensa-allow-direct-loading-of-sp-in-CALL0-ABI.patch b/local-patches/gcc/4.8.2/0012-xtensa-allow-direct-loading-of-sp-in-CALL0-ABI.patch new file mode 100644 index 000000000..a69cd4456 --- /dev/null +++ b/local-patches/gcc/4.8.2/0012-xtensa-allow-direct-loading-of-sp-in-CALL0-ABI.patch @@ -0,0 +1,52 @@ +From 73fee6043d8939bc32009771d0ea93eb0bf57643 Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Mon, 10 Nov 2014 02:38:42 +0300 +Subject: [PATCH 12/25] xtensa: allow direct loading of sp in CALL0 ABI + +Signed-off-by: Max Filippov +--- + gcc/config/xtensa/xtensa.md | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md +index 7433b04..9781080 100644 +--- a/gcc/config/xtensa/xtensa.md ++++ b/gcc/config/xtensa/xtensa.md +@@ -816,14 +816,15 @@ + }) + + (define_insn "movsi_internal" +- [(set (match_operand:SI 0 "nonimmed_operand" "=D,D,D,D,R,R,a,q,q,a,W,a,a,U,*a,*A") +- (match_operand:SI 1 "move_operand" "M,D,d,R,D,d,r,r,r,I,i,T,U,r,*A,*r"))] ++ [(set (match_operand:SI 0 "nonimmed_operand" "=D,D,D,D,d,R,R,a,q,q,a,W,a,a,q,U,*a,*A") ++ (match_operand:SI 1 "move_operand" "M,D,d,R,R,D,d,r,r,r,I,i,T,U,U,r,*A,*r"))] + "xtensa_valid_move (SImode, operands)" + "@ + movi.n\t%0, %x1 + mov.n\t%0, %1 + mov.n\t%0, %1 + %v1l32i.n\t%0, %1 ++ %v1l32i.n\t%0, %1 + %v0s32i.n\t%1, %0 + %v0s32i.n\t%1, %0 + mov\t%0, %1 +@@ -833,12 +834,14 @@ + const16\t%0, %t1\;const16\t%0, %b1 + %v1l32r\t%0, %1 + %v1l32i\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,move,load,load,store,rsr,wsr") ++ [(set_attr "type" "move,move,move,load,load,store,store,move,move,move,move,move,load,load,load,store,rsr,wsr") + (set_attr "mode" "SI") +- (set_attr "length" "2,2,2,2,2,2,3,3,3,3,6,3,3,3,3,3")]) ++ (set_attr "length" "2,2,2,2,2,2,2,3,3,3,3,6,3,3,3,3,3,3") ++ (set_attr "abi" "*,*,*,*,call0,*,*,*,call0,windowed,*,*,*,*,call0,*,*,*")]) + + ;; 16-bit Integer moves + +-- +1.8.1.4 + diff --git a/local-patches/gcc/4.8.2/0013-xtensa-fix-trampolines-generation-for-CALL0-ABI.patch b/local-patches/gcc/4.8.2/0013-xtensa-fix-trampolines-generation-for-CALL0-ABI.patch new file mode 100644 index 000000000..7c61dda3b --- /dev/null +++ b/local-patches/gcc/4.8.2/0013-xtensa-fix-trampolines-generation-for-CALL0-ABI.patch @@ -0,0 +1,232 @@ +From 7234dd9d4ee7af955e1edc20709c06e9d8112581 Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Mon, 10 Nov 2014 04:55:15 +0300 +Subject: [PATCH 13/25] xtensa: fix trampolines generation for CALL0 ABI + +Signed-off-by: Max Filippov +--- + gcc/config/xtensa/xtensa.c | 164 +++++++++++++++++++++++++++++++-------------- + gcc/config/xtensa/xtensa.h | 6 +- + 2 files changed, 117 insertions(+), 53 deletions(-) + +diff --git a/gcc/config/xtensa/xtensa.c b/gcc/config/xtensa/xtensa.c +index f44d9ef..1b82c75 100644 +--- a/gcc/config/xtensa/xtensa.c ++++ b/gcc/config/xtensa/xtensa.c +@@ -3730,9 +3730,14 @@ xtensa_function_value_regno_p (const unsigned int regno) + static rtx + xtensa_static_chain (const_tree ARG_UNUSED (fndecl), bool incoming_p) + { +- rtx base = incoming_p ? arg_pointer_rtx : stack_pointer_rtx; +- return gen_frame_mem (Pmode, plus_constant (Pmode, base, +- -5 * UNITS_PER_WORD)); ++ if (TARGET_WINDOWED_ABI) ++ { ++ rtx base = incoming_p ? arg_pointer_rtx : stack_pointer_rtx; ++ return gen_frame_mem (Pmode, plus_constant (Pmode, base, ++ -5 * UNITS_PER_WORD)); ++ } ++ else ++ return gen_rtx_REG (Pmode, A8_REG); + } + + +@@ -3750,65 +3755,109 @@ xtensa_asm_trampoline_template (FILE *stream) + bool use_call0 = (TARGET_CONST16 || TARGET_ABSOLUTE_LITERALS); + + fprintf (stream, "\t.begin no-transform\n"); +- fprintf (stream, "\tentry\tsp, %d\n", MIN_FRAME_SIZE); + +- if (use_call0) ++ if (TARGET_WINDOWED_ABI) + { +- /* Save the return address. */ +- fprintf (stream, "\tmov\ta10, a0\n"); ++ fprintf (stream, "\tentry\tsp, %d\n", MIN_FRAME_SIZE); + +- /* Use a CALL0 instruction to skip past the constants and in the +- process get the PC into A0. This allows PC-relative access to +- the constants without relying on L32R. */ +- fprintf (stream, "\tcall0\t.Lskipconsts\n"); +- } +- else +- fprintf (stream, "\tj\t.Lskipconsts\n"); ++ if (use_call0) ++ { ++ /* Save the return address. */ ++ fprintf (stream, "\tmov\ta10, a0\n"); ++ ++ /* Use a CALL0 instruction to skip past the constants and in the ++ process get the PC into A0. This allows PC-relative access to ++ the constants without relying on L32R. */ ++ fprintf (stream, "\tcall0\t.Lskipconsts\n"); ++ } ++ else ++ fprintf (stream, "\tj\t.Lskipconsts\n"); + +- fprintf (stream, "\t.align\t4\n"); +- fprintf (stream, ".Lchainval:%s0\n", integer_asm_op (4, TRUE)); +- fprintf (stream, ".Lfnaddr:%s0\n", integer_asm_op (4, TRUE)); +- fprintf (stream, ".Lskipconsts:\n"); ++ fprintf (stream, "\t.align\t4\n"); ++ fprintf (stream, ".Lchainval:%s0\n", integer_asm_op (4, TRUE)); ++ fprintf (stream, ".Lfnaddr:%s0\n", integer_asm_op (4, TRUE)); ++ fprintf (stream, ".Lskipconsts:\n"); + +- /* Load the static chain and function address from the trampoline. */ +- if (use_call0) +- { +- fprintf (stream, "\taddi\ta0, a0, 3\n"); +- fprintf (stream, "\tl32i\ta9, a0, 0\n"); +- fprintf (stream, "\tl32i\ta8, a0, 4\n"); ++ /* Load the static chain and function address from the trampoline. */ ++ if (use_call0) ++ { ++ fprintf (stream, "\taddi\ta0, a0, 3\n"); ++ fprintf (stream, "\tl32i\ta9, a0, 0\n"); ++ fprintf (stream, "\tl32i\ta8, a0, 4\n"); ++ } ++ else ++ { ++ fprintf (stream, "\tl32r\ta9, .Lchainval\n"); ++ fprintf (stream, "\tl32r\ta8, .Lfnaddr\n"); ++ } ++ ++ /* Store the static chain. */ ++ fprintf (stream, "\ts32i\ta9, sp, %d\n", MIN_FRAME_SIZE - 20); ++ ++ /* Set the proper stack pointer value. */ ++ fprintf (stream, "\tl32i\ta9, a8, 0\n"); ++ fprintf (stream, "\textui\ta9, a9, %d, 12\n", ++ TARGET_BIG_ENDIAN ? 8 : 12); ++ fprintf (stream, "\tslli\ta9, a9, 3\n"); ++ fprintf (stream, "\taddi\ta9, a9, %d\n", -MIN_FRAME_SIZE); ++ fprintf (stream, "\tsub\ta9, sp, a9\n"); ++ fprintf (stream, "\tmovsp\tsp, a9\n"); ++ ++ if (use_call0) ++ /* Restore the return address. */ ++ fprintf (stream, "\tmov\ta0, a10\n"); ++ ++ /* Jump to the instruction following the ENTRY. */ ++ fprintf (stream, "\taddi\ta8, a8, 3\n"); ++ fprintf (stream, "\tjx\ta8\n"); ++ ++ /* Pad size to a multiple of TRAMPOLINE_ALIGNMENT. */ ++ if (use_call0) ++ fprintf (stream, "\t.byte\t0\n"); ++ else ++ fprintf (stream, "\tnop\n"); + } + else + { +- fprintf (stream, "\tl32r\ta9, .Lchainval\n"); +- fprintf (stream, "\tl32r\ta8, .Lfnaddr\n"); +- } +- +- /* Store the static chain. */ +- fprintf (stream, "\ts32i\ta9, sp, %d\n", MIN_FRAME_SIZE - 20); +- +- /* Set the proper stack pointer value. */ +- fprintf (stream, "\tl32i\ta9, a8, 0\n"); +- fprintf (stream, "\textui\ta9, a9, %d, 12\n", +- TARGET_BIG_ENDIAN ? 8 : 12); +- fprintf (stream, "\tslli\ta9, a9, 3\n"); +- fprintf (stream, "\taddi\ta9, a9, %d\n", -MIN_FRAME_SIZE); +- fprintf (stream, "\tsub\ta9, sp, a9\n"); +- fprintf (stream, "\tmovsp\tsp, a9\n"); ++ if (use_call0) ++ { ++ /* Save the return address. */ ++ fprintf (stream, "\tmov\ta10, a0\n"); + +- if (use_call0) +- /* Restore the return address. */ +- fprintf (stream, "\tmov\ta0, a10\n"); ++ /* Use a CALL0 instruction to skip past the constants and in the ++ process get the PC into A0. This allows PC-relative access to ++ the constants without relying on L32R. */ ++ fprintf (stream, "\tcall0\t.Lskipconsts\n"); ++ } ++ else ++ fprintf (stream, "\tj\t.Lskipconsts\n"); + +- /* Jump to the instruction following the ENTRY. */ +- fprintf (stream, "\taddi\ta8, a8, 3\n"); +- fprintf (stream, "\tjx\ta8\n"); ++ fprintf (stream, "\t.align\t4\n"); ++ fprintf (stream, ".Lchainval:%s0\n", integer_asm_op (4, TRUE)); ++ fprintf (stream, ".Lfnaddr:%s0\n", integer_asm_op (4, TRUE)); ++ fprintf (stream, ".Lskipconsts:\n"); + +- /* Pad size to a multiple of TRAMPOLINE_ALIGNMENT. */ +- if (use_call0) +- fprintf (stream, "\t.byte\t0\n"); +- else +- fprintf (stream, "\tnop\n"); ++ /* Load the static chain and function address from the trampoline. */ ++ if (use_call0) ++ { ++ fprintf (stream, "\taddi\ta0, a0, 3\n"); ++ fprintf (stream, "\tl32i\ta8, a0, 0\n"); ++ fprintf (stream, "\tl32i\ta9, a0, 4\n"); ++ fprintf (stream, "\tmov\ta0, a10\n"); ++ } ++ else ++ { ++ fprintf (stream, "\tl32r\ta8, .Lchainval\n"); ++ fprintf (stream, "\tl32r\ta9, .Lfnaddr\n"); ++ } ++ fprintf (stream, "\tjx\ta9\n"); + ++ /* Pad size to a multiple of TRAMPOLINE_ALIGNMENT. */ ++ if (use_call0) ++ fprintf (stream, "\t.byte\t0\n"); ++ else ++ fprintf (stream, "\tnop\n"); ++ } + fprintf (stream, "\t.end no-transform\n"); + } + +@@ -3817,8 +3866,19 @@ xtensa_trampoline_init (rtx m_tramp, tree fndecl, rtx chain) + { + rtx func = XEXP (DECL_RTL (fndecl), 0); + bool use_call0 = (TARGET_CONST16 || TARGET_ABSOLUTE_LITERALS); +- int chain_off = use_call0 ? 12 : 8; +- int func_off = use_call0 ? 16 : 12; ++ int chain_off; ++ int func_off; ++ ++ if (TARGET_WINDOWED_ABI) ++ { ++ chain_off = use_call0 ? 12 : 8; ++ func_off = use_call0 ? 16 : 12; ++ } ++ else ++ { ++ chain_off = use_call0 ? 8 : 4; ++ func_off = use_call0 ? 12 : 8; ++ } + + emit_block_move (m_tramp, assemble_trampoline_template (), + GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL); +diff --git a/gcc/config/xtensa/xtensa.h b/gcc/config/xtensa/xtensa.h +index 23374bc..1670f8c 100644 +--- a/gcc/config/xtensa/xtensa.h ++++ b/gcc/config/xtensa/xtensa.h +@@ -611,7 +611,11 @@ typedef struct xtensa_args + + /* Size in bytes of the trampoline, as an integer. Make sure this is + a multiple of TRAMPOLINE_ALIGNMENT to avoid -Wpadded warnings. */ +-#define TRAMPOLINE_SIZE (TARGET_CONST16 || TARGET_ABSOLUTE_LITERALS ? 60 : 52) ++#define TRAMPOLINE_SIZE (TARGET_WINDOWED_ABI ? \ ++ (TARGET_CONST16 || TARGET_ABSOLUTE_LITERALS ? \ ++ 60 : 52) : \ ++ (TARGET_CONST16 || TARGET_ABSOLUTE_LITERALS ? \ ++ 32 : 24)) + + /* Alignment required for trampolines, in bits. */ + #define TRAMPOLINE_ALIGNMENT 32 +-- +1.8.1.4 + diff --git a/local-patches/gcc/4.8.2/0014-xtensa-drop-special-cases-for-SP-in-machine-definiti.patch b/local-patches/gcc/4.8.2/0014-xtensa-drop-special-cases-for-SP-in-machine-definiti.patch new file mode 100644 index 000000000..2a323f36e --- /dev/null +++ b/local-patches/gcc/4.8.2/0014-xtensa-drop-special-cases-for-SP-in-machine-definiti.patch @@ -0,0 +1,159 @@ +From 10543041c49922e358aea2ceebbb13526a7ddfed Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Mon, 10 Nov 2014 05:44:03 +0300 +Subject: [PATCH 14/25] xtensa: drop special cases for SP in machine definition + +Instead of adding explicit operations with 'q' constraint for CALL0 ABI +include SP into 'a' and 'D' constraints and make 'q' constraint empty. + +Drop no longer needed abi attribute. + +Signed-off-by: Max Filippov +--- + gcc/config/xtensa/constraints.md | 6 ++--- + gcc/config/xtensa/xtensa.md | 48 ++++++++++++---------------------------- + 2 files changed, 17 insertions(+), 37 deletions(-) + +diff --git a/gcc/config/xtensa/constraints.md b/gcc/config/xtensa/constraints.md +index 53b3ebfa..440c843 100644 +--- a/gcc/config/xtensa/constraints.md ++++ b/gcc/config/xtensa/constraints.md +@@ -19,7 +19,7 @@ + + ;; Register constraints. + +-(define_register_constraint "a" "GR_REGS" ++(define_register_constraint "a" "TARGET_WINDOWED_ABI ? GR_REGS : AR_REGS" + "General-purpose AR registers @code{a0}-@code{a15}, + except @code{a1} (@code{sp}).") + +@@ -36,7 +36,7 @@ + "Floating-point registers @code{f0}-@code{f15}; only available if the + Xtensa Floating-Pointer Coprocessor is configured.") + +-(define_register_constraint "q" "SP_REG" ++(define_register_constraint "q" "TARGET_WINDOWED_ABI ? SP_REG : NO_REGS" + "@internal + The stack pointer (register @code{a1}).") + +@@ -53,7 +53,7 @@ + General-purpose AR registers, but only if the Xtensa 16-Bit Integer + Multiply Option is configured.") + +-(define_register_constraint "D" "TARGET_DENSITY ? GR_REGS: NO_REGS" ++(define_register_constraint "D" "TARGET_DENSITY ? (TARGET_WINDOWED_ABI ? GR_REGS : AR_REGS) : NO_REGS" + "@internal + General-purpose AR registers, but only if the Xtensa Code Density + Option is configured.") +diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md +index 9781080..ba634b4 100644 +--- a/gcc/config/xtensa/xtensa.md ++++ b/gcc/config/xtensa/xtensa.md +@@ -92,15 +92,6 @@ + + (define_attr "length" "" (const_int 1)) + +-(define_attr "abi" "windowed,call0" (const_string "windowed")) +- +-(define_attr "enabled" "" +- (cond [(eq_attr "abi" "windowed") (const_int 1) +- (and (eq_attr "abi" "call0") +- (ne (symbol_ref "TARGET_WINDOWED_ABI") (const_int 1))) +- (const_int 1)] +- (const_int 0)) +- ) + ;; Describe a user's asm statement. + (define_asm_attributes + [(set_attr "type" "multi")]) +@@ -151,25 +142,19 @@ + ;; Addition. + + (define_insn "addsi3" +- [(set (match_operand:SI 0 "register_operand" "=D,D,r,r,r,q,q,q,q,q") +- (plus:SI (match_operand:SI 1 "register_operand" "%d,d,r,r,r,d,d,r,r,r") +- (match_operand:SI 2 "add_operand" "d,O,r,J,N,d,O,r,J,N")))] ++ [(set (match_operand:SI 0 "register_operand" "=D,D,r,r,r") ++ (plus:SI (match_operand:SI 1 "register_operand" "%d,d,r,r,r") ++ (match_operand:SI 2 "add_operand" "d,O,r,J,N")))] + "" + "@ + add.n\t%0, %1, %2 + addi.n\t%0, %1, %d2 + add\t%0, %1, %2 + addi\t%0, %1, %d2 +- addmi\t%0, %1, %x2 +- add.n\t%0, %1, %2 +- addi.n\t%0, %1, %d2 +- add\t%0, %1, %2 +- addi\t%0, %1, %d2 + addmi\t%0, %1, %x2" +- [(set_attr "type" "arith,arith,arith,arith,arith,arith,arith,arith,arith,arith") ++ [(set_attr "type" "arith,arith,arith,arith,arith") + (set_attr "mode" "SI") +- (set_attr "length" "2,2,3,3,3,2,2,3,3,3") +- (set_attr "abi" "*,*,*,*,*,call0,call0,call0,call0,call0")]) ++ (set_attr "length" "2,2,3,3,3")]) + + (define_insn "*addx" + [(set (match_operand:SI 0 "register_operand" "=a") +@@ -196,15 +181,14 @@ + ;; Subtraction. + + (define_insn "subsi3" +- [(set (match_operand:SI 0 "register_operand" "=a,q") +- (minus:SI (match_operand:SI 1 "register_operand" "r,r") +- (match_operand:SI 2 "register_operand" "r,r")))] ++ [(set (match_operand:SI 0 "register_operand" "=a") ++ (minus:SI (match_operand:SI 1 "register_operand" "r") ++ (match_operand:SI 2 "register_operand" "r")))] + "" + "sub\t%0, %1, %2" +- [(set_attr "type" "arith,arith") ++ [(set_attr "type" "arith") + (set_attr "mode" "SI") +- (set_attr "length" "3,3") +- (set_attr "abi" "*,call0")]) ++ (set_attr "length" "3")]) + + (define_insn "*subx" + [(set (match_operand:SI 0 "register_operand" "=a") +@@ -816,32 +800,28 @@ + }) + + (define_insn "movsi_internal" +- [(set (match_operand:SI 0 "nonimmed_operand" "=D,D,D,D,d,R,R,a,q,q,a,W,a,a,q,U,*a,*A") +- (match_operand:SI 1 "move_operand" "M,D,d,R,R,D,d,r,r,r,I,i,T,U,U,r,*A,*r"))] ++ [(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"))] + "xtensa_valid_move (SImode, operands)" + "@ + movi.n\t%0, %x1 + mov.n\t%0, %1 + mov.n\t%0, %1 + %v1l32i.n\t%0, %1 +- %v1l32i.n\t%0, %1 + %v0s32i.n\t%1, %0 + %v0s32i.n\t%1, %0 + mov\t%0, %1 +- mov\t%0, %1 + movsp\t%0, %1 + movi\t%0, %x1 + const16\t%0, %t1\;const16\t%0, %b1 + %v1l32r\t%0, %1 + %v1l32i\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,load,store,store,move,move,move,move,move,load,load,load,store,rsr,wsr") ++ [(set_attr "type" "move,move,move,load,store,store,move,move,move,move,load,load,store,rsr,wsr") + (set_attr "mode" "SI") +- (set_attr "length" "2,2,2,2,2,2,2,3,3,3,3,6,3,3,3,3,3,3") +- (set_attr "abi" "*,*,*,*,call0,*,*,*,call0,windowed,*,*,*,*,call0,*,*,*")]) ++ (set_attr "length" "2,2,2,2,2,2,3,3,3,6,3,3,3,3,3")]) + + ;; 16-bit Integer moves + +-- +1.8.1.4 + diff --git a/local-patches/gcc/4.8.2/0015-xtensa-fix-addsi3-pattern-for-windowed-ABI.patch b/local-patches/gcc/4.8.2/0015-xtensa-fix-addsi3-pattern-for-windowed-ABI.patch new file mode 100644 index 000000000..0a136d194 --- /dev/null +++ b/local-patches/gcc/4.8.2/0015-xtensa-fix-addsi3-pattern-for-windowed-ABI.patch @@ -0,0 +1,26 @@ +From b26a0f3c3701ad0e6ccc74218e0fdaabcbae414e Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Mon, 10 Nov 2014 06:08:22 +0300 +Subject: [PATCH 15/25] xtensa: fix addsi3 pattern for windowed ABI + +Signed-off-by: Max Filippov +--- + gcc/config/xtensa/xtensa.md | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md +index ba634b4..482fd62 100644 +--- a/gcc/config/xtensa/xtensa.md ++++ b/gcc/config/xtensa/xtensa.md +@@ -142,7 +142,7 @@ + ;; Addition. + + (define_insn "addsi3" +- [(set (match_operand:SI 0 "register_operand" "=D,D,r,r,r") ++ [(set (match_operand:SI 0 "register_operand" "=D,D,a,a,a") + (plus:SI (match_operand:SI 1 "register_operand" "%d,d,r,r,r") + (match_operand:SI 2 "add_operand" "d,O,r,J,N")))] + "" +-- +1.8.1.4 + diff --git a/local-patches/gcc/4.8.2/0016-xtensa-don-t-change-entry-pattern-in-machine-descrip.patch b/local-patches/gcc/4.8.2/0016-xtensa-don-t-change-entry-pattern-in-machine-descrip.patch new file mode 100644 index 000000000..ecb79ffe6 --- /dev/null +++ b/local-patches/gcc/4.8.2/0016-xtensa-don-t-change-entry-pattern-in-machine-descrip.patch @@ -0,0 +1,29 @@ +From 0325ee87614a58948774ece8d9d2718cd9bca367 Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Mon, 10 Nov 2014 06:15:26 +0300 +Subject: [PATCH 16/25] xtensa: don't change entry pattern in machine + descripton + +Signed-off-by: Max Filippov +--- + gcc/config/xtensa/xtensa.md | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md +index 482fd62..935821b 100644 +--- a/gcc/config/xtensa/xtensa.md ++++ b/gcc/config/xtensa/xtensa.md +@@ -1584,9 +1584,7 @@ + (unspec_volatile:SI [(match_operand:SI 0 "const_int_operand" "i")] + UNSPECV_ENTRY))] + "" +-{ +- return TARGET_WINDOWED_ABI ? "entry\tsp, %0" : "addi\tsp, sp, -%0"; +-} ++ "entry\tsp, %0" + [(set_attr "type" "entry") + (set_attr "mode" "SI") + (set_attr "length" "3")]) +-- +1.8.1.4 + diff --git a/local-patches/gcc/4.8.2/0017-xtensa-don-t-modify-call-patterns-use-is_leaf.patch b/local-patches/gcc/4.8.2/0017-xtensa-don-t-modify-call-patterns-use-is_leaf.patch new file mode 100644 index 000000000..f9e73778a --- /dev/null +++ b/local-patches/gcc/4.8.2/0017-xtensa-don-t-modify-call-patterns-use-is_leaf.patch @@ -0,0 +1,77 @@ +From b09e6a7ccc646f61944e4d99fd31dc91aeec0ab8 Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Sun, 28 Dec 2014 07:08:44 +0300 +Subject: [PATCH 17/25] xtensa: don't modify call* patterns, use is_leaf + +Signed-off-by: Max Filippov +--- + gcc/config/xtensa/xtensa.c | 2 +- + gcc/config/xtensa/xtensa.md | 18 +++++++----------- + 2 files changed, 8 insertions(+), 12 deletions(-) + +diff --git a/gcc/config/xtensa/xtensa.c b/gcc/config/xtensa/xtensa.c +index 1b82c75..ba936e7 100644 +--- a/gcc/config/xtensa/xtensa.c ++++ b/gcc/config/xtensa/xtensa.c +@@ -2591,7 +2591,7 @@ xtensa_call_save_reg(int regno) + return false; + + if (regno == A0_REG) +- return crtl->profile || df_regs_ever_live_p (regno); ++ return crtl->profile || !crtl->is_leaf || df_regs_ever_live_p (regno); + + return !fixed_regs[regno] && !call_used_regs[regno] && + df_regs_ever_live_p (regno); +diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md +index 935821b..e377df0 100644 +--- a/gcc/config/xtensa/xtensa.md ++++ b/gcc/config/xtensa/xtensa.md +@@ -1526,9 +1526,8 @@ + "") + + (define_expand "call" +- [(parallel [(call (match_operand 0 "memory_operand" "") +- (match_operand 1 "" "")) +- (clobber (reg:SI A0_REG))])] ++ [(call (match_operand 0 "memory_operand" "") ++ (match_operand 1 "" ""))] + "" + { + rtx addr = XEXP (operands[0], 0); +@@ -1541,8 +1540,7 @@ + + (define_insn "call_internal" + [(call (mem (match_operand:SI 0 "call_insn_operand" "nir")) +- (match_operand 1 "" "i")) +- (clobber (reg:SI A0_REG))] ++ (match_operand 1 "" "i"))] + "" + { + return xtensa_emit_call (0, operands); +@@ -1552,10 +1550,9 @@ + (set_attr "length" "3")]) + + (define_expand "call_value" +- [(parallel [(set (match_operand 0 "register_operand" "") +- (call (match_operand 1 "memory_operand" "") +- (match_operand 2 "" ""))) +- (clobber (reg:SI A0_REG))])] ++ [(set (match_operand 0 "register_operand" "") ++ (call (match_operand 1 "memory_operand" "") ++ (match_operand 2 "" "")))] + "" + { + rtx addr = XEXP (operands[1], 0); +@@ -1569,8 +1566,7 @@ + (define_insn "call_value_internal" + [(set (match_operand 0 "register_operand" "=a") + (call (mem (match_operand:SI 1 "call_insn_operand" "nir")) +- (match_operand 2 "" "i"))) +- (clobber (reg:SI A0_REG))] ++ (match_operand 2 "" "i")))] + "" + { + return xtensa_emit_call (1, operands); +-- +1.8.1.4 + diff --git a/local-patches/gcc/4.8.2/0018-xtensa-adjust-register-class-definitions-at-runtime.patch b/local-patches/gcc/4.8.2/0018-xtensa-adjust-register-class-definitions-at-runtime.patch new file mode 100644 index 000000000..69bea60f3 --- /dev/null +++ b/local-patches/gcc/4.8.2/0018-xtensa-adjust-register-class-definitions-at-runtime.patch @@ -0,0 +1,281 @@ +From 41db05e3a4a44bc6efdf464fe60b4484cfee93bb Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Sun, 28 Dec 2014 07:07:49 +0300 +Subject: [PATCH 18/25] xtensa: adjust register class definitions at runtime + +Signed-off-by: Max Filippov +--- + gcc/config/xtensa/xtensa-protos.h | 1 + + gcc/config/xtensa/xtensa.c | 82 ++++++++++++++++++++++++++++++--------- + gcc/config/xtensa/xtensa.h | 72 ++++++++++------------------------ + 3 files changed, 85 insertions(+), 70 deletions(-) + +diff --git a/gcc/config/xtensa/xtensa-protos.h b/gcc/config/xtensa/xtensa-protos.h +index 303c441..5cc97fe 100644 +--- a/gcc/config/xtensa/xtensa-protos.h ++++ b/gcc/config/xtensa/xtensa-protos.h +@@ -70,5 +70,6 @@ extern long compute_frame_size (int); + extern void xtensa_expand_prologue (void); + extern void xtensa_expand_epilogue (void); + extern void order_regs_for_local_alloc (void); ++extern enum reg_class xtensa_regno_to_class (int regno); + + #endif /* !__XTENSA_PROTOS_H__ */ +diff --git a/gcc/config/xtensa/xtensa.c b/gcc/config/xtensa/xtensa.c +index ba936e7..5ca4dbf 100644 +--- a/gcc/config/xtensa/xtensa.c ++++ b/gcc/config/xtensa/xtensa.c +@@ -103,21 +103,6 @@ const char xtensa_leaf_regs[FIRST_PSEUDO_REGISTER] = + 1 + }; + +-/* Map hard register number to register class */ +-const enum reg_class xtensa_regno_to_class[FIRST_PSEUDO_REGISTER] = +-{ +- RL_REGS, SP_REG, RL_REGS, RL_REGS, +- RL_REGS, RL_REGS, RL_REGS, TARGET_WINDOWED_ABI ? GR_REGS : RL_REGS, +- RL_REGS, RL_REGS, RL_REGS, RL_REGS, +- RL_REGS, RL_REGS, RL_REGS, TARGET_WINDOWED_ABI ? RL_REGS : GR_REGS, +- AR_REGS, AR_REGS, BR_REGS, +- FP_REGS, FP_REGS, FP_REGS, FP_REGS, +- FP_REGS, FP_REGS, FP_REGS, FP_REGS, +- FP_REGS, FP_REGS, FP_REGS, FP_REGS, +- FP_REGS, FP_REGS, FP_REGS, FP_REGS, +- ACC_REG, +-}; +- + static void xtensa_option_override (void); + static enum internal_test map_test_to_internal_test (enum rtx_code); + static rtx gen_int_relational (enum rtx_code, rtx, rtx, int *); +@@ -178,8 +163,8 @@ static bool xtensa_legitimate_constant_p (enum machine_mode, rtx); + static bool xtensa_member_type_forces_blk (const_tree, + enum machine_mode mode); + +-static const int reg_nonleaf_alloc_order[FIRST_PSEUDO_REGISTER] = +- REG_ALLOC_ORDER; ++static void xtensa_conditional_register_usage (void); ++ + + + /* These hooks specify assembly directives for creating certain kinds +@@ -292,6 +277,9 @@ static const int reg_nonleaf_alloc_order[FIRST_PSEUDO_REGISTER] = + #undef TARGET_LEGITIMATE_CONSTANT_P + #define TARGET_LEGITIMATE_CONSTANT_P xtensa_legitimate_constant_p + ++#undef TARGET_CONDITIONAL_REGISTER_USAGE ++#define TARGET_CONDITIONAL_REGISTER_USAGE xtensa_conditional_register_usage ++ + struct gcc_target targetm = TARGET_INITIALIZER; + + +@@ -3360,7 +3348,19 @@ order_regs_for_local_alloc (void) + { + if (!leaf_function_p ()) + { +- memcpy (reg_alloc_order, reg_nonleaf_alloc_order, ++ static const int reg_nonleaf_alloc_order[FIRST_PSEUDO_REGISTER] = ++ REG_ALLOC_ORDER; ++ static const int reg_nonleaf_alloc_order_call0[FIRST_PSEUDO_REGISTER] = ++ { ++ 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 12, 13, 14, 15, ++ 18, ++ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, ++ 0, 1, 16, 17, ++ 35, ++ }; ++ ++ memcpy (reg_alloc_order, TARGET_WINDOWED_ABI ? ++ reg_nonleaf_alloc_order : reg_nonleaf_alloc_order_call0, + FIRST_PSEUDO_REGISTER * sizeof (int)); + } + else +@@ -3897,4 +3897,50 @@ xtensa_legitimate_constant_p (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x) + return !xtensa_tls_referenced_p (x); + } + ++/* Update register usage after having seen the compiler flags. */ ++ ++static void ++xtensa_conditional_register_usage (void) ++{ ++ unsigned i, c_mask; ++ ++ c_mask = TARGET_WINDOWED_ABI ? (1 << 1) : (1 << 2); ++ ++ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) ++ { ++ /* Set/reset conditionally defined registers from ++ CALL_USED_REGISTERS initializer. */ ++ if (call_used_regs[i] > 1) ++ call_used_regs[i] = !!(call_used_regs[i] & c_mask); ++ } ++ ++ /* Remove hard FP register from the preferred reload registers set. */ ++ CLEAR_HARD_REG_BIT (reg_class_contents[(int)RL_REGS], ++ HARD_FRAME_POINTER_REGNUM); ++} ++ ++/* Map hard register number to register class */ ++ ++enum reg_class xtensa_regno_to_class (int regno) ++{ ++ static const enum reg_class regno_to_class[FIRST_PSEUDO_REGISTER] = ++ { ++ RL_REGS, SP_REG, RL_REGS, RL_REGS, ++ RL_REGS, RL_REGS, RL_REGS, RL_REGS, ++ RL_REGS, RL_REGS, RL_REGS, RL_REGS, ++ RL_REGS, RL_REGS, RL_REGS, RL_REGS, ++ AR_REGS, AR_REGS, BR_REGS, ++ FP_REGS, FP_REGS, FP_REGS, FP_REGS, ++ FP_REGS, FP_REGS, FP_REGS, FP_REGS, ++ FP_REGS, FP_REGS, FP_REGS, FP_REGS, ++ FP_REGS, FP_REGS, FP_REGS, FP_REGS, ++ ACC_REG, ++ }; ++ ++ if (regno == HARD_FRAME_POINTER_REGNUM) ++ return GR_REGS; ++ else ++ return regno_to_class[regno]; ++} ++ + #include "gt-xtensa.h" +diff --git a/gcc/config/xtensa/xtensa.h b/gcc/config/xtensa/xtensa.h +index 1670f8c..7c6eacc 100644 +--- a/gcc/config/xtensa/xtensa.h ++++ b/gcc/config/xtensa/xtensa.h +@@ -234,24 +234,22 @@ extern unsigned xtensa_current_frame_size; + registers that can be used without being saved. + The latter must include the registers where values are returned + and the register where structure-value addresses are passed. +- Aside from that, you can include as many other registers as you like. */ +-#if TARGET_WINDOWED_ABI +-#define CALL_USED_REGISTERS \ +-{ \ +- 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, \ +- 1, 1, 1, \ +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ +- 1, \ +-} +-#else ++ Aside from that, you can include as many other registers as you like. ++ ++ The value encoding is the following: ++ 1: register is used by all ABIs; ++ bit 1 is set: register is used by windowed ABI; ++ bit 2 is set: register is used by call0 ABI. ++ ++ Proper values are computed in TARGET_CONDITIONAL_REGISTER_USAGE. */ ++ + #define CALL_USED_REGISTERS \ + { \ +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, \ ++ 1, 1, 4, 4, 4, 4, 4, 4, 1, 1, 1, 1, 2, 2, 2, 2, \ + 1, 1, 1, \ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ + 1, \ + } +-#endif + + /* For non-leaf procedures on Xtensa processors, the allocation order + is as specified below by REG_ALLOC_ORDER. For leaf procedures, we +@@ -267,7 +265,6 @@ extern unsigned xtensa_current_frame_size; + argument registers are not used until after other register choices + have been exhausted. */ + +-#if TARGET_WINDOWED_ABI + #define REG_ALLOC_ORDER \ + { 8, 9, 10, 11, 12, 13, 14, 15, 7, 6, 5, 4, 3, 2, \ + 18, \ +@@ -275,15 +272,6 @@ extern unsigned xtensa_current_frame_size; + 0, 1, 16, 17, \ + 35, \ + } +-#else +-#define REG_ALLOC_ORDER \ +-{ 8, 9, 10, 11, 7, 6, 5, 4, 3, 2, 12, 13, 14, 15, \ +- 18, \ +- 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, \ +- 0, 1, 16, 17, \ +- 35, \ +-} +-#endif + + + #define ADJUST_REG_ALLOC_ORDER order_regs_for_local_alloc () +@@ -383,20 +371,17 @@ extern char xtensa_hard_regno_mode_ok[][FIRST_PSEUDO_REGISTER]; + take advantage of the possibility for variable-sized windows; instead, + we use a fixed window size of 8. */ + +-#if TARGET_WINDOWED_ABI + #define INCOMING_REGNO(OUT) \ +- ((GP_REG_P (OUT) && \ +- ((unsigned) ((OUT) - GP_REG_FIRST) >= WINDOW_SIZE)) ? \ +- (OUT) - WINDOW_SIZE : (OUT)) ++ (TARGET_WINDOWED_ABI ? \ ++ ((GP_REG_P (OUT) && \ ++ ((unsigned) ((OUT) - GP_REG_FIRST) >= WINDOW_SIZE)) ? \ ++ (OUT) - WINDOW_SIZE : (OUT)) : (OUT)) + + #define OUTGOING_REGNO(IN) \ +- ((GP_REG_P (IN) && \ +- ((unsigned) ((IN) - GP_REG_FIRST) < WINDOW_SIZE)) ? \ +- (IN) + WINDOW_SIZE : (IN)) +-#else +-#define INCOMING_REGNO(OUT) (OUT) +-#define OUTGOING_REGNO(IN) (IN) +-#endif ++ (TARGET_WINDOWED_ABI ? \ ++ ((GP_REG_P (IN) && \ ++ ((unsigned) ((IN) - GP_REG_FIRST) < WINDOW_SIZE)) ? \ ++ (IN) + WINDOW_SIZE : (IN)) : (IN)) + + + /* Define the classes of registers for register constraints in the +@@ -438,7 +423,6 @@ enum reg_class + /* Contents of the register classes. The Nth integer specifies the + contents of class N. The way the integer MASK is interpreted is + that register R is in the class if 'MASK & (1 << R)' is 1. */ +-#if TARGET_WINDOWED_ABI + #define REG_CLASS_CONTENTS \ + { \ + { 0x00000000, 0x00000000 }, /* no registers */ \ +@@ -446,33 +430,17 @@ enum reg_class + { 0xfff80000, 0x00000007 }, /* floating-point registers */ \ + { 0x00000000, 0x00000008 }, /* MAC16 accumulator */ \ + { 0x00000002, 0x00000000 }, /* stack pointer register */ \ +- { 0x0000ff7d, 0x00000000 }, /* preferred reload registers */ \ ++ { 0x0000fffd, 0x00000000 }, /* preferred reload registers */ \ + { 0x0000fffd, 0x00000000 }, /* general-purpose registers */ \ + { 0x0003ffff, 0x00000000 }, /* integer registers */ \ + { 0xffffffff, 0x0000000f } /* all registers */ \ + } +-#else +-#define REG_CLASS_CONTENTS \ +-{ \ +- { 0x00000000, 0x00000000 }, /* no registers */ \ +- { 0x00040000, 0x00000000 }, /* coprocessor boolean registers */ \ +- { 0xfff80000, 0x00000007 }, /* floating-point registers */ \ +- { 0x00000000, 0x00000008 }, /* MAC16 accumulator */ \ +- { 0x00000002, 0x00000000 }, /* stack pointer register */ \ +- { 0x00007ffd, 0x00000000 }, /* preferred reload registers */ \ +- { 0x0000fffd, 0x00000000 }, /* general-purpose registers */ \ +- { 0x0003ffff, 0x00000000 }, /* integer registers */ \ +- { 0xffffffff, 0x0000000f } /* all registers */ \ +-} +-#endif + + /* A C expression whose value is a register class containing hard + register REGNO. In general there is more that one such class; + choose a class which is "minimal", meaning that no smaller class + also contains the register. */ +-extern const enum reg_class xtensa_regno_to_class[FIRST_PSEUDO_REGISTER]; +- +-#define REGNO_REG_CLASS(REGNO) xtensa_regno_to_class[ (REGNO) ] ++#define REGNO_REG_CLASS(REGNO) xtensa_regno_to_class (REGNO) + + /* Use the Xtensa AR register file for base registers. + No index registers. */ +-- +1.8.1.4 + diff --git a/local-patches/gcc/4.8.2/0019-Turn-RETURN_ADDR_IN_PREVIOUS_FRAME-into-C-expression.patch b/local-patches/gcc/4.8.2/0019-Turn-RETURN_ADDR_IN_PREVIOUS_FRAME-into-C-expression.patch new file mode 100644 index 000000000..94b6e29f8 --- /dev/null +++ b/local-patches/gcc/4.8.2/0019-Turn-RETURN_ADDR_IN_PREVIOUS_FRAME-into-C-expression.patch @@ -0,0 +1,58 @@ +From d850f4988ccc44489f737cd9303b030590016060 Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Sun, 28 Dec 2014 20:52:44 +0300 +Subject: [PATCH 19/25] Turn RETURN_ADDR_IN_PREVIOUS_FRAME into C expression + +This allows a target to support both windowed and non-windowed ABI. + +Signed-off-by: Max Filippov +--- + gcc/builtins.c | 2 +- + gcc/config/sparc/sparc.h | 2 +- + gcc/config/xtensa/xtensa.h | 4 +--- + 3 files changed, 3 insertions(+), 5 deletions(-) + +diff --git a/gcc/builtins.c b/gcc/builtins.c +index e3c32a9..c9d2eca 100644 +--- a/gcc/builtins.c ++++ b/gcc/builtins.c +@@ -793,7 +793,7 @@ expand_builtin_return_addr (enum built_in_function fndecl_code, int count) + pointer, but it can be accessed off the previous frame pointer by + reading the value from the register window save area. */ + #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME +- if (fndecl_code == BUILT_IN_RETURN_ADDRESS) ++ if (RETURN_ADDR_IN_PREVIOUS_FRAME && fndecl_code == BUILT_IN_RETURN_ADDRESS) + count--; + #endif + +diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h +index c6122c1..a0d517a 100644 +--- a/gcc/config/sparc/sparc.h ++++ b/gcc/config/sparc/sparc.h +@@ -1283,7 +1283,7 @@ do { \ + access it from the current frame pointer. We can access it from the + previous frame pointer though by reading a value from the register window + save area. */ +-#define RETURN_ADDR_IN_PREVIOUS_FRAME ++#define RETURN_ADDR_IN_PREVIOUS_FRAME 1 + + /* This is the offset of the return address to the true next instruction to be + executed for the current function. */ +diff --git a/gcc/config/xtensa/xtensa.h b/gcc/config/xtensa/xtensa.h +index 7c6eacc..c36a6a6 100644 +--- a/gcc/config/xtensa/xtensa.h ++++ b/gcc/config/xtensa/xtensa.h +@@ -625,9 +625,7 @@ typedef struct xtensa_args + + /* Define this if the return address of a particular stack frame is + accessed from the frame pointer of the previous stack frame. */ +-#if TARGET_WINDOWED_ABI +-#define RETURN_ADDR_IN_PREVIOUS_FRAME +-#endif ++#define RETURN_ADDR_IN_PREVIOUS_FRAME TARGET_WINDOWED_ABI + + /* A C expression whose value is RTL representing the value of the + return address for the frame COUNT steps up from the current +-- +1.8.1.4 + diff --git a/local-patches/gcc/4.8.2/0020-xtensa-fix-__builtin_return_address-for-call0-ABI.patch b/local-patches/gcc/4.8.2/0020-xtensa-fix-__builtin_return_address-for-call0-ABI.patch new file mode 100644 index 000000000..c4475b18c --- /dev/null +++ b/local-patches/gcc/4.8.2/0020-xtensa-fix-__builtin_return_address-for-call0-ABI.patch @@ -0,0 +1,94 @@ +From d7d88454a381342e9c2cf9013ff01d02fc9c7df5 Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Tue, 6 Jan 2015 04:21:16 +0300 +Subject: [PATCH 20/25] xtensa: fix __builtin_return_address for call0 ABI + +Return 0 for frames other then the current, use get_hard_reg_initial_val +as a0 may be clobbered at the point of query. + +Signed-off-by: Max Filippov +--- + gcc/config/xtensa/xtensa.c | 60 ++++++++++++++++++++++++---------------------- + 1 file changed, 31 insertions(+), 29 deletions(-) + +diff --git a/gcc/config/xtensa/xtensa.c b/gcc/config/xtensa/xtensa.c +index 5ca4dbf..16c2697 100644 +--- a/gcc/config/xtensa/xtensa.c ++++ b/gcc/config/xtensa/xtensa.c +@@ -2831,7 +2831,15 @@ xtensa_expand_epilogue (void) + rtx + xtensa_return_addr (int count, rtx frame) + { +- rtx retaddr; ++ rtx result, retaddr, curaddr, label; ++ ++ if (!TARGET_WINDOWED_ABI) ++ { ++ if (count != 0) ++ return const0_rtx; ++ ++ return get_hard_reg_initial_val (Pmode, A0_REG); ++ } + + if (count == -1) + retaddr = gen_rtx_REG (Pmode, A0_REG); +@@ -2843,34 +2851,28 @@ xtensa_return_addr (int count, rtx frame) + emit_move_insn (retaddr, gen_rtx_MEM (Pmode, addr)); + } + +- if (TARGET_WINDOWED_ABI) +- { +- rtx result, curaddr, label; +- /* The 2 most-significant bits of the return address on Xtensa hold +- the register window size. To get the real return address, these +- bits must be replaced with the high bits from some address in the +- code. */ +- +- /* Get the 2 high bits of a local label in the code. */ +- curaddr = gen_reg_rtx (Pmode); +- label = gen_label_rtx (); +- emit_label (label); +- LABEL_PRESERVE_P (label) = 1; +- emit_move_insn (curaddr, gen_rtx_LABEL_REF (Pmode, label)); +- emit_insn (gen_lshrsi3 (curaddr, curaddr, GEN_INT (30))); +- emit_insn (gen_ashlsi3 (curaddr, curaddr, GEN_INT (30))); +- +- /* Clear the 2 high bits of the return address. */ +- result = gen_reg_rtx (Pmode); +- emit_insn (gen_ashlsi3 (result, retaddr, GEN_INT (2))); +- emit_insn (gen_lshrsi3 (result, result, GEN_INT (2))); +- +- /* Combine them to get the result. */ +- emit_insn (gen_iorsi3 (result, result, curaddr)); +- return result; +- } +- else +- return retaddr; ++ /* The 2 most-significant bits of the return address on Xtensa hold ++ the register window size. To get the real return address, these ++ bits must be replaced with the high bits from some address in the ++ code. */ ++ ++ /* Get the 2 high bits of a local label in the code. */ ++ curaddr = gen_reg_rtx (Pmode); ++ label = gen_label_rtx (); ++ emit_label (label); ++ LABEL_PRESERVE_P (label) = 1; ++ emit_move_insn (curaddr, gen_rtx_LABEL_REF (Pmode, label)); ++ emit_insn (gen_lshrsi3 (curaddr, curaddr, GEN_INT (30))); ++ emit_insn (gen_ashlsi3 (curaddr, curaddr, GEN_INT (30))); ++ ++ /* Clear the 2 high bits of the return address. */ ++ result = gen_reg_rtx (Pmode); ++ emit_insn (gen_ashlsi3 (result, retaddr, GEN_INT (2))); ++ emit_insn (gen_lshrsi3 (result, result, GEN_INT (2))); ++ ++ /* Combine them to get the result. */ ++ emit_insn (gen_iorsi3 (result, result, curaddr)); ++ return result; + } + + /* Disable the use of word-sized or smaller complex modes for structures, +-- +1.8.1.4 + diff --git a/local-patches/gcc/4.8.2/0021-xtensa-don-t-emit-CFA-notes-in-epilogue.patch b/local-patches/gcc/4.8.2/0021-xtensa-don-t-emit-CFA-notes-in-epilogue.patch new file mode 100644 index 000000000..0e5505031 --- /dev/null +++ b/local-patches/gcc/4.8.2/0021-xtensa-don-t-emit-CFA-notes-in-epilogue.patch @@ -0,0 +1,63 @@ +From 46ae7a2cc28b40fef95b860d042a86c3f198183a Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Tue, 6 Jan 2015 14:24:47 +0300 +Subject: [PATCH 21/25] xtensa: don't emit CFA notes in epilogue + +Signed-off-by: Max Filippov +--- + gcc/config/xtensa/xtensa.c | 18 +++--------------- + 1 file changed, 3 insertions(+), 15 deletions(-) + +diff --git a/gcc/config/xtensa/xtensa.c b/gcc/config/xtensa/xtensa.c +index 16c2697..52b24c3 100644 +--- a/gcc/config/xtensa/xtensa.c ++++ b/gcc/config/xtensa/xtensa.c +@@ -2758,7 +2758,6 @@ xtensa_expand_epilogue (void) + if (!TARGET_WINDOWED_ABI) + { + int regno; +- rtx insn; + HOST_WIDE_INT offset; + + if (xtensa_current_frame_size > (frame_pointer_needed ? 127 : 1024)) +@@ -2766,7 +2765,7 @@ xtensa_expand_epilogue (void) + rtx tmp_reg = gen_rtx_REG (Pmode, A9_REG); + emit_move_insn (tmp_reg, GEN_INT (xtensa_current_frame_size - + xtensa_callee_save_size)); +- insn = emit_insn (gen_addsi3 (stack_pointer_rtx, frame_pointer_needed ? ++ emit_insn (gen_addsi3 (stack_pointer_rtx, frame_pointer_needed ? + hard_frame_pointer_rtx : stack_pointer_rtx, tmp_reg)); + offset = xtensa_callee_save_size - UNITS_PER_WORD; + } +@@ -2801,26 +2800,15 @@ xtensa_expand_epilogue (void) + else + offset = xtensa_callee_save_size; + +- insn = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, ++ emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, + GEN_INT (offset))); + } + else + { + rtx tmp_reg = gen_rtx_REG (Pmode, A9_REG); + emit_move_insn (tmp_reg, GEN_INT (xtensa_current_frame_size)); +- insn = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, tmp_reg)); ++ emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, tmp_reg)); + } +- +- /* Create a note to describe the CFA. Because this is only used to set +- DW_AT_frame_base for debug info, don't bother tracking changes through +- each instruction in the prologue. It just takes up space. */ +- note_rtx = gen_rtx_SET (VOIDmode, stack_pointer_rtx, +- plus_constant (Pmode, frame_pointer_needed +- ? hard_frame_pointer_rtx +- : stack_pointer_rtx, +- xtensa_current_frame_size)); +- RTX_FRAME_RELATED_P (insn) = 1; +- add_reg_note (insn, REG_FRAME_RELATED_EXPR, note_rtx); + } + } + xtensa_current_frame_size = 0; +-- +1.8.1.4 + diff --git a/local-patches/gcc/4.8.2/0022-xtensa-add-notes-to-registers-saved-in-prologue.patch b/local-patches/gcc/4.8.2/0022-xtensa-add-notes-to-registers-saved-in-prologue.patch new file mode 100644 index 000000000..74e1c6b42 --- /dev/null +++ b/local-patches/gcc/4.8.2/0022-xtensa-add-notes-to-registers-saved-in-prologue.patch @@ -0,0 +1,105 @@ +From a1fa1f57102825b18926469d5bfa538b0c25bc11 Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Sat, 10 Jan 2015 15:51:22 +0300 +Subject: [PATCH 22/25] xtensa: add notes to registers saved in prologue + +Signed-off-by: Max Filippov +--- + gcc/config/xtensa/xtensa.c | 42 ++++++++++++++++++++++++++++++++++++++---- + 1 file changed, 38 insertions(+), 4 deletions(-) + +diff --git a/gcc/config/xtensa/xtensa.c b/gcc/config/xtensa/xtensa.c +index 52b24c3..a2d1eaf 100644 +--- a/gcc/config/xtensa/xtensa.c ++++ b/gcc/config/xtensa/xtensa.c +@@ -2667,6 +2667,11 @@ xtensa_expand_prologue (void) + { + insn = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, + GEN_INT (-total_size))); ++ RTX_FRAME_RELATED_P (insn) = 1; ++ note_rtx = gen_rtx_SET (VOIDmode, stack_pointer_rtx, ++ plus_constant (Pmode, stack_pointer_rtx, ++ -total_size)); ++ add_reg_note (insn, REG_FRAME_RELATED_EXPR, note_rtx); + offset = total_size - UNITS_PER_WORD; + } + else if (xtensa_callee_save_size) +@@ -2678,6 +2683,11 @@ xtensa_expand_prologue (void) + { + insn = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, + GEN_INT (-xtensa_callee_save_size))); ++ RTX_FRAME_RELATED_P (insn) = 1; ++ note_rtx = gen_rtx_SET (VOIDmode, stack_pointer_rtx, ++ plus_constant (Pmode, stack_pointer_rtx, ++ -xtensa_callee_save_size)); ++ add_reg_note (insn, REG_FRAME_RELATED_EXPR, note_rtx); + offset = xtensa_callee_save_size - UNITS_PER_WORD; + } + else +@@ -2685,6 +2695,11 @@ xtensa_expand_prologue (void) + rtx tmp_reg = gen_rtx_REG (Pmode, A9_REG); + emit_move_insn (tmp_reg, GEN_INT (total_size)); + insn = emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, tmp_reg)); ++ RTX_FRAME_RELATED_P (insn) = 1; ++ note_rtx = gen_rtx_SET (VOIDmode, stack_pointer_rtx, ++ plus_constant (Pmode, stack_pointer_rtx, ++ -total_size)); ++ add_reg_note (insn, REG_FRAME_RELATED_EXPR, note_rtx); + offset = total_size - UNITS_PER_WORD; + } + } +@@ -2694,9 +2709,14 @@ xtensa_expand_prologue (void) + if (xtensa_call_save_reg(regno)) + { + rtx x = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (offset)); ++ rtx mem = gen_frame_mem (SImode, x); ++ rtx reg = gen_rtx_REG (SImode, regno); + + offset -= UNITS_PER_WORD; +- emit_move_insn (gen_frame_mem (SImode, x), gen_rtx_REG (SImode, regno)); ++ insn = emit_move_insn (mem, reg); ++ RTX_FRAME_RELATED_P (insn) = 1; ++ add_reg_note (insn, REG_FRAME_RELATED_EXPR, ++ gen_rtx_SET (VOIDmode, mem, reg)); + } + } + if (total_size > 1024) +@@ -2704,6 +2724,11 @@ xtensa_expand_prologue (void) + rtx tmp_reg = gen_rtx_REG (Pmode, A9_REG); + emit_move_insn (tmp_reg, GEN_INT (total_size - xtensa_callee_save_size)); + insn = emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, tmp_reg)); ++ RTX_FRAME_RELATED_P (insn) = 1; ++ note_rtx = gen_rtx_SET (VOIDmode, stack_pointer_rtx, ++ plus_constant (Pmode, stack_pointer_rtx, ++ xtensa_callee_save_size - total_size)); ++ add_reg_note (insn, REG_FRAME_RELATED_EXPR, note_rtx); + } + } + +@@ -2733,11 +2758,20 @@ xtensa_expand_prologue (void) + } + } + else +- insn = emit_insn (gen_movsi (hard_frame_pointer_rtx, +- stack_pointer_rtx)); ++ { ++ insn = emit_insn (gen_movsi (hard_frame_pointer_rtx, ++ stack_pointer_rtx)); ++ if (!TARGET_WINDOWED_ABI) ++ { ++ note_rtx = gen_rtx_SET (VOIDmode, hard_frame_pointer_rtx, ++ stack_pointer_rtx); ++ RTX_FRAME_RELATED_P (insn) = 1; ++ add_reg_note (insn, REG_FRAME_RELATED_EXPR, note_rtx); ++ } ++ } + } + +- if (TARGET_WINDOWED_ABI || total_size > 0) ++ if (TARGET_WINDOWED_ABI) + { + /* Create a note to describe the CFA. Because this is only used to set + DW_AT_frame_base for debug info, don't bother tracking changes through +-- +1.8.1.4 + diff --git a/local-patches/gcc/4.8.2/0023-xtensa-implement-exception-return-for-call0-ABI.patch b/local-patches/gcc/4.8.2/0023-xtensa-implement-exception-return-for-call0-ABI.patch new file mode 100644 index 000000000..1e5fdee91 --- /dev/null +++ b/local-patches/gcc/4.8.2/0023-xtensa-implement-exception-return-for-call0-ABI.patch @@ -0,0 +1,174 @@ +From 601180aced8f4d0b4dd6ebfe0abc0bdd26a0cd72 Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Mon, 12 Jan 2015 15:21:31 +0300 +Subject: [PATCH 23/25] xtensa: implement exception return for call0 ABI + +Signed-off-by: Max Filippov +--- + gcc/config/xtensa/xtensa-protos.h | 1 + + gcc/config/xtensa/xtensa.c | 40 ++++++++++++++++++++++++++++++++++++++- + gcc/config/xtensa/xtensa.h | 2 ++ + gcc/config/xtensa/xtensa.md | 37 +++++++++++++++++++++++++++++++++++- + 4 files changed, 78 insertions(+), 2 deletions(-) + +diff --git a/gcc/config/xtensa/xtensa-protos.h b/gcc/config/xtensa/xtensa-protos.h +index 5cc97fe..056d333 100644 +--- a/gcc/config/xtensa/xtensa-protos.h ++++ b/gcc/config/xtensa/xtensa-protos.h +@@ -61,6 +61,7 @@ extern void init_cumulative_args (CUMULATIVE_ARGS *, int); + extern void print_operand (FILE *, rtx, int); + extern void print_operand_address (FILE *, rtx); + extern void xtensa_output_literal (FILE *, rtx, enum machine_mode, int); ++extern void xtensa_set_return_address (rtx, rtx); + extern rtx xtensa_return_addr (int, rtx); + #endif /* RTX_CODE */ + +diff --git a/gcc/config/xtensa/xtensa.c b/gcc/config/xtensa/xtensa.c +index a2d1eaf..8b15dad 100644 +--- a/gcc/config/xtensa/xtensa.c ++++ b/gcc/config/xtensa/xtensa.c +@@ -2579,7 +2579,11 @@ xtensa_call_save_reg(int regno) + return false; + + if (regno == A0_REG) +- return crtl->profile || !crtl->is_leaf || df_regs_ever_live_p (regno); ++ return crtl->profile || !crtl->is_leaf || crtl->calls_eh_return || ++ df_regs_ever_live_p (regno); ++ ++ if (crtl->calls_eh_return && regno >= 2 && regno < 4) ++ return true; + + return !fixed_regs[regno] && !call_used_regs[regno] && + df_regs_ever_live_p (regno); +@@ -2810,6 +2814,11 @@ xtensa_expand_epilogue (void) + offset = xtensa_current_frame_size - UNITS_PER_WORD; + } + ++ /* Prevent reordering of saved a0 update and loading it back from ++ the save area. */ ++ if (crtl->calls_eh_return) ++ emit_insn (gen_blockage ()); ++ + for (regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno) + { + if (xtensa_call_save_reg(regno)) +@@ -2844,12 +2853,41 @@ xtensa_expand_epilogue (void) + emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, tmp_reg)); + } + } ++ ++ if (crtl->calls_eh_return) ++ emit_insn (gen_add3_insn (stack_pointer_rtx, ++ stack_pointer_rtx, ++ EH_RETURN_STACKADJ_RTX)); + } + xtensa_current_frame_size = 0; + xtensa_callee_save_size = 0; + emit_jump_insn (gen_return ()); + } + ++void ++xtensa_set_return_address (rtx address, rtx scratch) ++{ ++ HOST_WIDE_INT total_size = compute_frame_size (get_frame_size ()); ++ rtx frame = frame_pointer_needed ? ++ hard_frame_pointer_rtx : stack_pointer_rtx; ++ rtx a0_addr = plus_constant (Pmode, frame, ++ total_size - UNITS_PER_WORD); ++ rtx note = gen_rtx_SET (VOIDmode, ++ gen_frame_mem (SImode, a0_addr), ++ gen_rtx_REG (SImode, A0_REG)); ++ rtx insn; ++ ++ if (total_size > 1024) { ++ emit_move_insn (scratch, GEN_INT (total_size - UNITS_PER_WORD)); ++ emit_insn (gen_addsi3 (scratch, frame, scratch)); ++ a0_addr = scratch; ++ } ++ ++ insn = emit_move_insn (gen_frame_mem (SImode, a0_addr), address); ++ RTX_FRAME_RELATED_P (insn) = 1; ++ add_reg_note (insn, REG_FRAME_RELATED_EXPR, note); ++} ++ + rtx + xtensa_return_addr (int count, rtx frame) + { +diff --git a/gcc/config/xtensa/xtensa.h b/gcc/config/xtensa/xtensa.h +index c36a6a6..73c2f1c 100644 +--- a/gcc/config/xtensa/xtensa.h ++++ b/gcc/config/xtensa/xtensa.h +@@ -815,6 +815,8 @@ typedef struct xtensa_args + | DW_EH_PE_pcrel | DW_EH_PE_sdata4) \ + : DW_EH_PE_absptr) + ++#define EH_RETURN_STACKADJ_RTX gen_rtx_REG (Pmode, GP_REG_FIRST + 10) ++ + /* Emit a PC-relative relocation. */ + #define ASM_OUTPUT_DWARF_PCREL(FILE, SIZE, LABEL) \ + do { \ +diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md +index e377df0..5303a59 100644 +--- a/gcc/config/xtensa/xtensa.md ++++ b/gcc/config/xtensa/xtensa.md +@@ -43,6 +43,7 @@ + (UNSPECV_S32C1I 5) + (UNSPECV_EH_RETURN 6) + (UNSPECV_SET_TP 7) ++ (UNSPECV_BLOCKAGE 8) + ]) + + ;; This code iterator allows signed and unsigned widening multiplications +@@ -1645,7 +1646,18 @@ + ;; already been applied to the handler, but the generic version doesn't + ;; allow us to frob it quite enough, so we just frob here. + +-(define_insn_and_split "eh_return" ++(define_expand "eh_return" ++ [(use (match_operand 0 "general_operand"))] ++ "" ++{ ++ if (TARGET_WINDOWED_ABI) ++ emit_insn (gen_eh_set_a0_windowed (operands[0])); ++ else ++ emit_insn (gen_eh_set_a0_call0 (operands[0])); ++ DONE; ++}) ++ ++(define_insn_and_split "eh_set_a0_windowed" + [(set (reg:SI A0_REG) + (unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] + UNSPECV_EH_RETURN)) +@@ -1658,6 +1670,29 @@ + (set (reg:SI A0_REG) (rotatert:SI (match_dup 1) (const_int 2)))] + "") + ++(define_insn_and_split "eh_set_a0_call0" ++ [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] ++ UNSPECV_EH_RETURN) ++ (clobber (match_scratch:SI 1 "=r"))] ++ "" ++ "#" ++ "reload_completed" ++ [(const_int 0)] ++{ ++ xtensa_set_return_address (operands[0], operands[1]); ++ DONE; ++}) ++ ++;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and ++;; all of memory. This blocks insns from being moved across this point. ++ ++(define_insn "blockage" ++ [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)] ++ "" ++ "" ++ [(set_attr "length" "0") ++ (set_attr "type" "nop")]) ++ + ;; Setting up a frame pointer is tricky for Xtensa because GCC doesn't + ;; know if a frame pointer is required until the reload pass, and + ;; because there may be an incoming argument value in the hard frame +-- +1.8.1.4 + diff --git a/local-patches/gcc/4.8.2/0024-xtensa-use-default-DWARF-unwinder-for-call0-ABI.patch b/local-patches/gcc/4.8.2/0024-xtensa-use-default-DWARF-unwinder-for-call0-ABI.patch new file mode 100644 index 000000000..6afcd9ae8 --- /dev/null +++ b/local-patches/gcc/4.8.2/0024-xtensa-use-default-DWARF-unwinder-for-call0-ABI.patch @@ -0,0 +1,115 @@ +From 5734054799af51281560490e3c4df42579e90dfb Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Wed, 7 Jan 2015 08:03:48 +0300 +Subject: [PATCH 24/25] xtensa: use default DWARF unwinder for call0 ABI + +Signed-off-by: Max Filippov +--- + libgcc/config/xtensa/linux-unwind.h | 3 +++ + libgcc/config/xtensa/t-windowed | 2 ++ + libgcc/config/xtensa/t-xtensa | 3 --- + libgcc/configure | 21 +++++++++++++++++++++ + libgcc/configure.ac | 16 ++++++++++++++++ + 5 files changed, 42 insertions(+), 3 deletions(-) + create mode 100644 libgcc/config/xtensa/t-windowed + +diff --git a/libgcc/config/xtensa/linux-unwind.h b/libgcc/config/xtensa/linux-unwind.h +index a942024..18cedbf 100644 +--- a/libgcc/config/xtensa/linux-unwind.h ++++ b/libgcc/config/xtensa/linux-unwind.h +@@ -52,6 +52,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + #define ENTRY_BYTE 0x36 + #endif + ++#ifdef __XTENSA_WINDOWED_ABI__ + #define MD_FALLBACK_FRAME_STATE_FOR xtensa_fallback_frame_state + + static _Unwind_Reason_Code +@@ -94,4 +95,6 @@ xtensa_fallback_frame_state (struct _Unwind_Context *context, + return _URC_NO_REASON; + } + ++#endif /* __XTENSA_WINDOWED_ABI__ */ ++ + #endif /* ifdef inhibit_libc */ +diff --git a/libgcc/config/xtensa/t-windowed b/libgcc/config/xtensa/t-windowed +new file mode 100644 +index 0000000..7d9e9db +--- /dev/null ++++ b/libgcc/config/xtensa/t-windowed +@@ -0,0 +1,2 @@ ++LIB2ADDEH = $(srcdir)/config/xtensa/unwind-dw2-xtensa.c \ ++ $(srcdir)/unwind-dw2-fde.c $(srcdir)/unwind-sjlj.c $(srcdir)/unwind-c.c +diff --git a/libgcc/config/xtensa/t-xtensa b/libgcc/config/xtensa/t-xtensa +index 27399e6..ed3eb84 100644 +--- a/libgcc/config/xtensa/t-xtensa ++++ b/libgcc/config/xtensa/t-xtensa +@@ -11,6 +11,3 @@ LIB1ASMFUNCS = _mulsi3 _divsi3 _modsi3 _udivsi3 _umodsi3 \ + _truncdfsf2 _extendsfdf2 + + LIB2ADD = $(srcdir)/config/xtensa/lib2funcs.S +- +-LIB2ADDEH = $(srcdir)/config/xtensa/unwind-dw2-xtensa.c \ +- $(srcdir)/unwind-dw2-fde.c $(srcdir)/unwind-sjlj.c $(srcdir)/unwind-c.c +diff --git a/libgcc/configure b/libgcc/configure +index 1425df6..03ea7ed 100644 +--- a/libgcc/configure ++++ b/libgcc/configure +@@ -4326,6 +4326,27 @@ EOF + ;; + esac + ++# Check if xtensa target is configured for windowed ABI and thus needs to use ++# custom unwind code. ++# This is after config.host so we can augment tmake_file. ++case ${host} in ++xtensa*-*) ++ cat > conftest.c <&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; }; then ++ tmake_file="${tmake_file} xtensa/t-windowed" ++ fi ++ ;; ++esac ++ + # Check for visibility support. This is after config.host so that + # we can check for asm_hidden_op. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __attribute__((visibility(\"hidden\")))" >&5 +diff --git a/libgcc/configure.ac b/libgcc/configure.ac +index 8b7aba5..8ce0482 100644 +--- a/libgcc/configure.ac ++++ b/libgcc/configure.ac +@@ -294,6 +294,22 @@ EOF + ;; + esac + ++# Check if xtensa target is configured for windowed ABI and thus needs to use ++# custom unwind code. ++# This is after config.host so we can augment tmake_file. ++case ${host} in ++xtensa*-*) ++ cat > conftest.c <&AS_MESSAGE_LOG_FD); then ++ tmake_file="${tmake_file} xtensa/t-windowed" ++ fi ++ ;; ++esac ++ + # Check for visibility support. This is after config.host so that + # we can check for asm_hidden_op. + AC_CACHE_CHECK([for __attribute__((visibility("hidden")))], +-- +1.8.1.4 + diff --git a/local-patches/gcc/4.8.2/0025-xtensa-align-data-naturally-when-optimizing-for-size.patch b/local-patches/gcc/4.8.2/0025-xtensa-align-data-naturally-when-optimizing-for-size.patch new file mode 100644 index 000000000..3435fada7 --- /dev/null +++ b/local-patches/gcc/4.8.2/0025-xtensa-align-data-naturally-when-optimizing-for-size.patch @@ -0,0 +1,36 @@ +From de95b6b65d806a648434e73a6db85f1e74d62ec8 Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Fri, 6 Feb 2015 23:52:18 +0300 +Subject: [PATCH 25/25] xtensa: align data naturally when optimizing for size + +Signed-off-by: Max Filippov +--- + gcc/config/xtensa/xtensa.h | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/gcc/config/xtensa/xtensa.h b/gcc/config/xtensa/xtensa.h +index 73c2f1c..f0d016b 100644 +--- a/gcc/config/xtensa/xtensa.h ++++ b/gcc/config/xtensa/xtensa.h +@@ -171,7 +171,8 @@ extern unsigned xtensa_current_frame_size; + constants to be word aligned so that 'strcpy' calls that copy + constants can be done inline. */ + #define CONSTANT_ALIGNMENT(EXP, ALIGN) \ +- ((TREE_CODE (EXP) == STRING_CST || TREE_CODE (EXP) == CONSTRUCTOR) \ ++ (!optimize_size && \ ++ (TREE_CODE (EXP) == STRING_CST || TREE_CODE (EXP) == CONSTRUCTOR) \ + && (ALIGN) < BITS_PER_WORD \ + ? BITS_PER_WORD \ + : (ALIGN)) +@@ -183,7 +184,7 @@ extern unsigned xtensa_current_frame_size; + that copy constants to character arrays can be done inline. */ + #undef DATA_ALIGNMENT + #define DATA_ALIGNMENT(TYPE, ALIGN) \ +- ((((ALIGN) < BITS_PER_WORD) \ ++ (!optimize_size && (((ALIGN) < BITS_PER_WORD) \ + && (TREE_CODE (TYPE) == ARRAY_TYPE \ + || TREE_CODE (TYPE) == UNION_TYPE \ + || TREE_CODE (TYPE) == RECORD_TYPE)) ? BITS_PER_WORD : (ALIGN)) +-- +1.8.1.4 + diff --git a/local-patches/gdb/7.5.1/0001-xtensa-fix-access-to-the-last-pseudo-register.patch b/local-patches/gdb/7.5.1/0001-xtensa-fix-access-to-the-last-pseudo-register.patch new file mode 100644 index 000000000..582484c3e --- /dev/null +++ b/local-patches/gdb/7.5.1/0001-xtensa-fix-access-to-the-last-pseudo-register.patch @@ -0,0 +1,57 @@ +From 36d3b813eb613d9f2d653554066d059a7e915d82 Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Mon, 18 May 2015 01:39:40 +0300 +Subject: [PATCH] xtensa: fix access to the last pseudo register + +Currently access to the last pseudo register is aliased to a1. This is +done by little snippets in the beginning of xtensa_pseudo_register_read +and xtensa_pseudo_register_write that used to do such aliasing for FP +register since bdb4c075a29dd086f0868b394b488b1c94666be6, but then +FP_ALIAS was expanded into gdbarch_num_regs (current_gdbarch) + +gdbarch_num_pseudo_regs (current_gdbarch) (one register past the last +pseudo register) in 304fe2552d6e0821e8fdb7575f8e7ba6607a076d, which +then was changed to the last pseudo register in +94a0e877111421d300d26b858bd3a0a27078d1e8. + +Drop these snippets. + +2015-05-18 Max Filippov +gdb/ + * xtensa-tdep.c (xtensa_pseudo_register_read) + (xtensa_pseudo_register_write): Don't alias last pseudo register + to a1. + +Signed-off-by: Max Filippov +--- + gdb/xtensa-tdep.c | 8 -------- + 1 file changed, 8 deletions(-) + +diff --git a/gdb/xtensa-tdep.c b/gdb/xtensa-tdep.c +index a66d00a..55e7d98 100644 +--- a/gdb/xtensa-tdep.c ++++ b/gdb/xtensa-tdep.c +@@ -553,10 +553,6 @@ xtensa_pseudo_register_read (struct gdbarch *gdbarch, + DEBUGTRACE ("xtensa_pseudo_register_read (... regnum = %d (%s) ...)\n", + regnum, xtensa_register_name (gdbarch, regnum)); + +- if (regnum == gdbarch_num_regs (gdbarch) +- + gdbarch_num_pseudo_regs (gdbarch) - 1) +- regnum = gdbarch_tdep (gdbarch)->a0_base + 1; +- + /* Read aliases a0..a15, if this is a Windowed ABI. */ + if (gdbarch_tdep (gdbarch)->isa_use_windowed_registers + && (regnum >= gdbarch_tdep (gdbarch)->a0_base) +@@ -653,10 +649,6 @@ xtensa_pseudo_register_write (struct gdbarch *gdbarch, + DEBUGTRACE ("xtensa_pseudo_register_write (... regnum = %d (%s) ...)\n", + regnum, xtensa_register_name (gdbarch, regnum)); + +- if (regnum == gdbarch_num_regs (gdbarch) +- + gdbarch_num_pseudo_regs (gdbarch) -1) +- regnum = gdbarch_tdep (gdbarch)->a0_base + 1; +- + /* Renumber register, if aliase a0..a15 on Windowed ABI. */ + if (gdbarch_tdep (gdbarch)->isa_use_windowed_registers + && (regnum >= gdbarch_tdep (gdbarch)->a0_base) +-- +1.8.1.4 + diff --git a/local-patches/gdb/7.5.1/0002-xtensa-initialize-call_abi-in-xtensa_tdep.patch b/local-patches/gdb/7.5.1/0002-xtensa-initialize-call_abi-in-xtensa_tdep.patch new file mode 100644 index 000000000..1182a455f --- /dev/null +++ b/local-patches/gdb/7.5.1/0002-xtensa-initialize-call_abi-in-xtensa_tdep.patch @@ -0,0 +1,39 @@ +From 7f8c0d8984bf5754807d3bb543cbc3ffc634e9e4 Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Sat, 30 May 2015 13:00:32 +0300 +Subject: [PATCH] xtensa: initialize call_abi in xtensa_tdep + +Use XSHAL_ABI value provided by xtensa-config.h to correctly initialize +xtensa_tdep.call_abi +This fixes calls to functions from GDB that otherwise fail with the +following assertion in call0 configuration: + + gdb/regcache.c:602: internal-error: regcache_raw_read: Assertion + `regnum >= 0 && regnum < regcache->descr->nr_raw_registers' failed. + +gdb/ + * xtensa-tdep.h (XTENSA_GDBARCH_TDEP_INSTANTIATE): Initialize + call_abi using XSHAL_ABI macro. + +Signed-off-by: Max Filippov +--- + gdb/xtensa-tdep.h | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/gdb/xtensa-tdep.h b/gdb/xtensa-tdep.h +index adacaf8..3b6ea66 100644 +--- a/gdb/xtensa-tdep.h ++++ b/gdb/xtensa-tdep.h +@@ -246,7 +246,8 @@ struct gdbarch_tdep + .spill_location = -1, \ + .spill_size = (spillsz), \ + .unused = 0, \ +- .call_abi = 0, \ ++ .call_abi = (XSHAL_ABI == XTHAL_ABI_CALL0) ? \ ++ CallAbiCall0Only : CallAbiDefault, \ + .debug_interrupt_level = XCHAL_DEBUGLEVEL, \ + .icache_line_bytes = XCHAL_ICACHE_LINESIZE, \ + .dcache_line_bytes = XCHAL_DCACHE_LINESIZE, \ +-- +1.8.1.4 + diff --git a/local-patches/gdb/7.5.1/0003-xtensa-make-sure-ar_base-is-initialized.patch b/local-patches/gdb/7.5.1/0003-xtensa-make-sure-ar_base-is-initialized.patch new file mode 100644 index 000000000..982bd7f7f --- /dev/null +++ b/local-patches/gdb/7.5.1/0003-xtensa-make-sure-ar_base-is-initialized.patch @@ -0,0 +1,35 @@ +From 208ea73d38c9c16cf983b6419f58050dbadcb6a9 Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Sun, 7 Jun 2015 22:43:49 +0300 +Subject: [PATCH 2/2] xtensa: make sure ar_base is initialized + +ar_base is uninitialized for cores w/o windowed registers as their +regmap doesn't have register 0x0100. +Check that ar_base is initialized and if not initialize it with a0_base. + +gdb/ + * xtensa-tdep.c (xtensa_derive_tdep): Make sure ar_base is + initialized. + +Signed-off-by: Max Filippov +--- + gdb/xtensa-tdep.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/gdb/xtensa-tdep.c b/gdb/xtensa-tdep.c +index 55e7d98..41f5ec1 100644 +--- a/gdb/xtensa-tdep.c ++++ b/gdb/xtensa-tdep.c +@@ -3175,6 +3175,9 @@ xtensa_derive_tdep (struct gdbarch_tdep *tdep) + tdep->num_regs = n; + } + ++ if (tdep->ar_base == -1) ++ tdep->ar_base = tdep->a0_base; ++ + /* Number of pseudo registers. */ + tdep->num_pseudo_regs = n - tdep->num_regs; + +-- +1.8.1.4 + diff --git a/local-patches/gdb/7.5.1/0004-WIP-end-of-prologue-detection-hack.patch b/local-patches/gdb/7.5.1/0004-WIP-end-of-prologue-detection-hack.patch new file mode 100644 index 000000000..506a57c3c --- /dev/null +++ b/local-patches/gdb/7.5.1/0004-WIP-end-of-prologue-detection-hack.patch @@ -0,0 +1,31 @@ +From 7f8eacbb468575fb67db7fd1155a3aedaa91911b Mon Sep 17 00:00:00 2001 +From: Max Filippov +Date: Sun, 7 Jun 2015 23:15:39 +0300 +Subject: [PATCH] WIP: *end of prologue* detection hack + +see + http://www.esp8266.com/viewtopic.php?p=18461#p18461 + http://www.esp8266.com/viewtopic.php?p=19026#p19026 + http://www.esp8266.com/viewtopic.php?p=19683#p19683 + +Signed-off-by: Max Filippov +--- + gdb/xtensa-tdep.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/gdb/xtensa-tdep.c b/gdb/xtensa-tdep.c +index 41f5ec1..6a7dba7 100644 +--- a/gdb/xtensa-tdep.c ++++ b/gdb/xtensa-tdep.c +@@ -2410,7 +2410,7 @@ call0_analyze_prologue (struct gdbarch *gdbarch, + /* Find out, if we have an information about the prologue from DWARF. */ + prologue_sal = find_pc_line (start, 0); + if (prologue_sal.line != 0) /* Found debug info. */ +- body_pc = prologue_sal.end; ++ body_pc = prologue_sal.end + 40; + + /* If we are going to analyze the prologue in general without knowing about + the current PC, make the best assumtion for the end of the prologue. */ +-- +1.8.1.4 + diff --git a/overlays/xtensa_lx106.tar b/overlays/xtensa_lx106.tar index 83b156e92..28ea93aea 100644 Binary files a/overlays/xtensa_lx106.tar and b/overlays/xtensa_lx106.tar differ diff --git a/samples/xtensa-lx106-elf/crosstool.config b/samples/xtensa-lx106-elf/crosstool.config index 820ce1c71..391c7892b 100644 --- a/samples/xtensa-lx106-elf/crosstool.config +++ b/samples/xtensa-lx106-elf/crosstool.config @@ -10,3 +10,6 @@ CT_TARGET_VENDOR="lx106" CT_LIBC_none=y CT_CC_V_4_8_2=y # CT_CC_STATIC_LIBSTDCXX is not set +CT_DEBUG_gdb=y +# CT_GDB_CROSS_PYTHON is not set +CT_GDB_V_7_5_1=y diff --git a/scripts/build/debug/300-gdb.sh b/scripts/build/debug/300-gdb.sh index 15bc98bd0..63d2866f2 100644 --- a/scripts/build/debug/300-gdb.sh +++ b/scripts/build/debug/300-gdb.sh @@ -94,7 +94,7 @@ do_debug_gdb_extract() { CT_Patch "expat" "${CT_DEBUG_GDB_EXPAT_VERSION}" fi - if [ -n "${CT_ARCH_XTENSA_CUSTOM_OVERLAY_FILE}" ]; then + if [ -n "${CT_ARCH_XTENSA_CUSTOM_NAME}" ]; then CT_ConfigureXtensa "gdb" "${CT_GDB_VERSION}" fi }