This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
SH: calling nested functions through trampolines was broken
- To: gcc-patches at gcc dot gnu dot org
- Subject: SH: calling nested functions through trampolines was broken
- From: Alexandre Oliva <aoliva at redhat dot com>
- Date: 09 Jan 2001 08:26:28 -0200
- Organization: GCC Team, Red Hat
SH used to use r13 as STATIC_CHAIN_REGNUM. This means the trampoline
used to call nested functions would clobber a call-saved register.
After pondering about this issue for a while, I decided the best thing
to do was to change STATIC_CHAIN_REGNUM. Some alternatives have been
proposed to me, but this was the simplest and most effective.
I considered backward compatibility, and concluded it was not an
issue. At least in C, nested functions are only called from the same
translation unit, and pointers to them are constructed along with the
trampolines also in their own translation unit. Obviously, code that
uses nested functions that has already been compiled will remain
broken, but there's nothing I can do about that :-)
I'm checking this in. Tested on sh-elf.
Index: gcc/ChangeLog
from Alexandre Oliva <aoliva@redhat.com>
* config/sh/sh.h (STATIC_CHAIN_REGNUM): Change from r13 to r3.
(INITIALIZE_TRAMPOLINE): Adjust accordingly.
* config/sh/sh.c (sh_expand_prologue): Use r1 as temporary for
stack adjusts, instead of r3.
Index: gcc/config/sh/sh.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/sh/sh.h,v
retrieving revision 1.93
diff -u -p -r1.93 sh.h
--- gcc/config/sh/sh.h 2001/01/05 01:58:04 1.93
+++ gcc/config/sh/sh.h 2001/01/09 09:39:43
@@ -649,7 +649,7 @@ do { \
#define ARG_POINTER_REGNUM AP_REG
/* Register in which the static-chain is passed to a function. */
-#define STATIC_CHAIN_REGNUM 13
+#define STATIC_CHAIN_REGNUM 3
/* The register in which a struct value address is passed. */
@@ -1223,12 +1223,12 @@ extern int current_function_anonymous_ar
/*
On the SH, the trampoline looks like
- 2 0002 DD02 mov.l l2,r13
+ 2 0002 D202 mov.l l2,r2
1 0000 D301 mov.l l1,r3
- 3 0004 4D2B jmp @r13
+ 3 0004 422B jmp @r2
4 0006 0009 nop
- 5 0008 00000000 l1: .long function
- 6 000c 00000000 l2: .long area */
+ 5 0008 00000000 l1: .long area
+ 6 000c 00000000 l2: .long function */
/* Length in units of the trampoline for entering a nested function. */
#define TRAMPOLINE_SIZE 16
@@ -1244,9 +1244,9 @@ extern int current_function_anonymous_ar
#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) do \
{ \
emit_move_insn (gen_rtx_MEM (SImode, (TRAMP)), \
- GEN_INT (TARGET_LITTLE_ENDIAN ? 0xd301dd02 : 0xdd02d301));\
+ GEN_INT (TARGET_LITTLE_ENDIAN ? 0xd301d202 : 0xd202d301));\
emit_move_insn (gen_rtx_MEM (SImode, plus_constant ((TRAMP), 4)), \
- GEN_INT (TARGET_LITTLE_ENDIAN ? 0x00094d2b : 0x4d2b0009));\
+ GEN_INT (TARGET_LITTLE_ENDIAN ? 0x0009422b : 0x422b0009));\
emit_move_insn (gen_rtx_MEM (SImode, plus_constant ((TRAMP), 8)), \
(CXT)); \
emit_move_insn (gen_rtx_MEM (SImode, plus_constant ((TRAMP), 12)), \
Index: gcc/config/sh/sh.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/sh/sh.c,v
retrieving revision 1.82
diff -u -p -r1.82 sh.c
--- gcc/config/sh/sh.c 2001/01/03 21:13:29 1.82
+++ gcc/config/sh/sh.c 2001/01/09 09:39:41
@@ -3922,7 +3922,7 @@ sh_expand_prologue ()
/* We have pretend args if we had an object sent partially in registers
and partially on the stack, e.g. a large structure. */
output_stack_adjust (-current_function_pretend_args_size,
- stack_pointer_rtx, 3);
+ stack_pointer_rtx, 1);
extra_push = 0;
@@ -3970,7 +3970,7 @@ sh_expand_prologue ()
target_flags = save_flags;
output_stack_adjust (-rounded_frame_size (d),
- stack_pointer_rtx, 3);
+ stack_pointer_rtx, 1);
if (frame_pointer_needed)
emit_insn (gen_movsi (frame_pointer_rtx, stack_pointer_rtx));
--
Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/
Red Hat GCC Developer aoliva@{cygnus.com, redhat.com}
CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org}
Free Software Evangelist *Please* write to mailing lists, not to me