diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6fb680a45003eb246e19def9fe3dee62cd2a660a..e35464099ef6be1737bd028e068407214d09c33d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2007-01-19 Nathan Sidwell <nathan@codesourcery.com> + Richard Sandiford <richard@codesourcery.com> + + * config/m68k/m68k.h (M68K_STATIC_CHAIN_REG_NAME): New macro. + (INITIALIZE_TRAMPOLINE): Use STATIC_CHAIN_REGNUM. + (__transfer_from_trampoline): Use M68K_STATIC_CHAIN_REG_NAME. + * config/m68k/m68kelf.h (STATIC_CHAIN_REGNUM): Override. + (M68K_STATIC_CHAIN_REG_NAME): Likewise. + * config/m68k/netbsd-elf.h (M68K_STATIC_CHAIN_REG_NAME): Likewise. + 2007-01-19 Richard Sandiford <richard@codesourcery.com> * config/m68k/m68k.md (adddi_dilshr32): Rename to... diff --git a/gcc/config/m68k/m68k.h b/gcc/config/m68k/m68k.h index 5ab146162240995008ba1d53fef8293bf031c51f..c0a3f9e3b04f6fb48d15a2898281a9860be1cb53 100644 --- a/gcc/config/m68k/m68k.h +++ b/gcc/config/m68k/m68k.h @@ -432,6 +432,7 @@ Boston, MA 02110-1301, USA. */ #define ARG_POINTER_REGNUM 24 #define STATIC_CHAIN_REGNUM 8 +#define M68K_STATIC_CHAIN_REG_NAME REGISTER_PREFIX "a0" /* Register in which address to store a structure value is passed to a function. */ @@ -684,7 +685,8 @@ extern enum reg_class regno_reg_class[]; jmp FNADDR */ #define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \ { \ - emit_move_insn (gen_rtx_MEM (HImode, TRAMP), GEN_INT(0x207C)); \ + emit_move_insn (gen_rtx_MEM (HImode, TRAMP), \ + GEN_INT(0x207C + ((STATIC_CHAIN_REGNUM-8) << 9))); \ emit_move_insn (gen_rtx_MEM (SImode, plus_constant (TRAMP, 2)), CXT); \ emit_move_insn (gen_rtx_MEM (HImode, plus_constant (TRAMP, 6)), \ GEN_INT(0x4EF9)); \ @@ -707,7 +709,7 @@ extern enum reg_class regno_reg_class[]; void \ __transfer_from_trampoline () \ { \ - register char *a0 asm ("%a0"); \ + register char *a0 asm (M68K_STATIC_CHAIN_REG_NAME); \ asm (GLOBAL_ASM_OP "___trampoline"); \ asm ("___trampoline:"); \ asm volatile ("move%.l %0,%@" : : "m" (a0[22])); \ diff --git a/gcc/config/m68k/m68kelf.h b/gcc/config/m68k/m68kelf.h index ecdbd508ed01934addab53c9cfd39773b7e0438f..6c26650677d5514085e60e6eada6d1114040f342 100644 --- a/gcc/config/m68k/m68kelf.h +++ b/gcc/config/m68k/m68kelf.h @@ -83,6 +83,14 @@ do { \ #undef M68K_STRUCT_VALUE_REGNUM #define M68K_STRUCT_VALUE_REGNUM 8 +/* The static chain regnum defaults to a0, but we use that for + structure return, so have to use a1 for the static chain. */ + +#undef STATIC_CHAIN_REGNUM +#define STATIC_CHAIN_REGNUM 9 +#undef M68K_STATIC_CHAIN_REG_NAME +#define M68K_STATIC_CHAIN_REG_NAME REGISTER_PREFIX "a1" + #define ASM_COMMENT_START "|" /* Define how the m68k registers should be numbered for Dwarf output. diff --git a/gcc/config/m68k/netbsd-elf.h b/gcc/config/m68k/netbsd-elf.h index c67f6f8fc4a2dad83ed6f8b104e90fac2cc017c4..13aca931013a4883fcc99b2bdcb9c6bded4330b6 100644 --- a/gcc/config/m68k/netbsd-elf.h +++ b/gcc/config/m68k/netbsd-elf.h @@ -233,6 +233,8 @@ while (0) #undef STATIC_CHAIN_REGNUM #define STATIC_CHAIN_REGNUM 9 +#undef M68K_STATIC_CHAIN_REG_NAME +#define M68K_STATIC_CHAIN_REG_NAME REGISTER_PREFIX "a1" /* Now to renumber registers for dbx and gdb. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index bd0b434b8e1b21cee67a092722f20f4015cc5446..f10e21081e3a1a0a17c4b6fc8fdaf355fdbc067b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2007-01-19 Nathan Sidwell <nathan@codesourcery.com> + + * gcc.c-torture/execute/nestfunc-7.c: New. + 2007-01-18 Hui-May Chang <hm.chang@apple.com> * gcc.c-torture/compile/pr27528.c: Add -fno-pic option. diff --git a/gcc/testsuite/gcc.c-torture/execute/nestfunc-7.c b/gcc/testsuite/gcc.c-torture/execute/nestfunc-7.c new file mode 100644 index 0000000000000000000000000000000000000000..5b3d34b8dce90204a82950ff992649e23ae158a1 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/nestfunc-7.c @@ -0,0 +1,44 @@ +struct A +{ + int one; + int two; + int three; + int four; + int five; + int six; +}; + +static int test (void) +{ + int base; + + struct A Foo (void) + { + struct A a; + + a.one = base + 1; + a.two = base + 2; + a.three = base + 3; + a.four = base + 4; + a.five = base + 5; + a.six = base + 6; + + return a; + } + + base = 10; + struct A a = Foo (); + + return (a.one == 11 + && a.two == 12 + && a.three == 13 + && a.four == 14 + && a.five == 15 + && a.six == 16); +} + +int main (void) +{ + return !test (); +} +