This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

SH: calling nested functions through trampolines was broken


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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]