Skip to content

Commit

Permalink
local-patches: sync with xtensa gcc call0 ABI support
Browse files Browse the repository at this point in the history
Fixed:
- possible a7/a15 corruption in functions with 6+ argument words and
  frame pointer enabled;
- vararg functions;
- setjmp/longjmp;
- nested functions;
- profiling with -pg option (_mcount call);

A bit improved code generation for SP manipulations.

Known broken:
- __builtin_return_address;
- __builtin_frame_address for frames other than current.

Unknown:
- C++ exception handling.

Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
  • Loading branch information
jcmvbkbc committed Nov 10, 2014
1 parent 69ddd72 commit f767aec
Show file tree
Hide file tree
Showing 16 changed files with 1,172 additions and 5 deletions.
@@ -1,7 +1,7 @@
From 676b5a725bd71c9deb72b1957a5e6cf892d5d9fb Mon Sep 17 00:00:00 2001
From: Max Filippov <jcmvbkbc@gmail.com>
Date: Sun, 14 Sep 2014 21:15:14 -0700
Subject: [PATCH 1/3] WIP: xtensa: fix lib code for call0 ABI
Subject: [PATCH 01/16] WIP: xtensa: fix lib code for call0 ABI

Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
---
Expand Down
@@ -1,7 +1,7 @@
From 06d069d40208c4ce7456920e8b4f571ac9511821 Mon Sep 17 00:00:00 2001
From: Max Filippov <jcmvbkbc@gmail.com>
Date: Sun, 14 Sep 2014 16:43:27 -0700
Subject: [PATCH 2/3] WIP: xtensa: implement call0 ABI
Subject: [PATCH 02/16] WIP: xtensa: implement call0 ABI

Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
---
Expand Down
@@ -1,7 +1,7 @@
From d82c531991bb31e864e05f02032187f2e9dbc66f Mon Sep 17 00:00:00 2001
From: Max Filippov <jcmvbkbc@gmail.com>
Date: Sun, 28 Sep 2014 22:52:01 +0400
Subject: [PATCH 3/3] WIP: xtensa: implement callee-saved register saving
Subject: [PATCH 03/16] WIP: xtensa: implement callee-saved register saving

Also fix frame pointer, correctly move stack pointer, and avoid movsp.

Expand Down
@@ -1,7 +1,7 @@
From 0b74cbfbbf3aa9b67f1c9f1971e98b0980b10661 Mon Sep 17 00:00:00 2001
From: Max Filippov <jcmvbkbc@gmail.com>
Date: Sun, 5 Oct 2014 05:54:31 +0400
Subject: [PATCH 4/5] xtensa: always emit .literal_position for call0 ABI
Subject: [PATCH 04/16] 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
Expand Down
@@ -1,7 +1,7 @@
From 1acaae7db15d0da960cbfd470533a51d8551f7b9 Mon Sep 17 00:00:00 2001
From: Max Filippov <jcmvbkbc@gmail.com>
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/16] xtensa: use subsi3 instead of addsi3 in call0 prologue

This allows sharing single literal for stack adjustment between prologue
and epilogue.
Expand Down
@@ -0,0 +1,48 @@
From 2d1af52aaa84f8e15a32eeb5ec58868f842a8acc Mon Sep 17 00:00:00 2001
From: Max Filippov <jcmvbkbc@gmail.com>
Date: Sun, 9 Nov 2014 03:48:56 +0300
Subject: [PATCH 06/16] 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 <jcmvbkbc@gmail.com>
---
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

@@ -0,0 +1,37 @@
From b1b4c61a540a146d5f1acb31fa065204b83eb6a4 Mon Sep 17 00:00:00 2001
From: Max Filippov <jcmvbkbc@gmail.com>
Date: Sun, 9 Nov 2014 04:52:36 +0300
Subject: [PATCH 07/16] 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 <jcmvbkbc@gmail.com>
---
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

@@ -0,0 +1,70 @@
From 2f60e5db550a287c58e6e69d993946818d01159c Mon Sep 17 00:00:00 2001
From: Max Filippov <jcmvbkbc@gmail.com>
Date: Sun, 9 Nov 2014 06:24:08 +0300
Subject: [PATCH 08/16] 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 <jcmvbkbc@gmail.com>
---
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

@@ -0,0 +1,56 @@
From c73b720ae2759c70a4c657962e0bcb40c42fd9bc Mon Sep 17 00:00:00 2001
From: Max Filippov <jcmvbkbc@gmail.com>
Date: Sun, 9 Nov 2014 06:26:29 +0300
Subject: [PATCH 09/16] 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 <jcmvbkbc@gmail.com>
---
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

0 comments on commit f767aec

Please sign in to comment.