diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9a9a00517a4..4250e239849 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -322,6 +322,14 @@ to the end. Add static_chain_on_stack. (ix86_static_chain_on_stack): New. + * config/m68k/m68k.c (TARGET_TRAMPOLINE_INIT): New. + (m68k_output_mi_thunk): Don't use static_chain_rtx. + (m68k_trampoline_init): New. + * config/m68k/m68k.h (INITIALIZE_TRAMPOLINE): Move code to + m68k_trampoline_init and adjust for hook parameters. + * config/m68k/netbsd-elf.h (TRAMPOLINE_TEMPLATE): Remove. + (TRAMPOLINE_SIZE, INITIALIZE_TRAMPOLINE): Remove. + 2009-09-22 Jakub Jelinek * config/rs6000/rs6000.c (bdesc_2arg): Fix CODE_FOR_vector_gt* codes diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c index 033872c28a1..0862936b1b4 100644 --- a/gcc/config/m68k/m68k.c +++ b/gcc/config/m68k/m68k.c @@ -153,6 +153,7 @@ static bool m68k_rtx_costs (rtx, int, int, int *, bool); static bool m68k_return_in_memory (const_tree, const_tree); #endif static void m68k_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED; +static void m68k_trampoline_init (rtx, tree, rtx); /* Specify the identification number of the library being built */ @@ -267,6 +268,9 @@ const char *m68k_library_id_string = "_current_shared_library_a5_offset_"; #undef TARGET_CAN_ELIMINATE #define TARGET_CAN_ELIMINATE m68k_can_eliminate +#undef TARGET_TRAMPOLINE_INIT +#define TARGET_TRAMPOLINE_INIT m68k_trampoline_init + static const struct attribute_spec m68k_attribute_table[] = { /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */ @@ -4958,7 +4962,11 @@ m68k_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED, HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset, tree function) { - rtx this_slot, offset, addr, mem, insn; + rtx this_slot, offset, addr, mem, insn, tmp; + + /* Avoid clobbering the struct value reg by using the + static chain reg as a temporary. */ + tmp = gen_rtx_REG (Pmode, STATIC_CHAIN_REGNUM); /* Pretend to be a post-reload pass while generating rtl. */ reload_completed = 1; @@ -4985,15 +4993,15 @@ m68k_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED, if (vcall_offset != 0) { /* Set the static chain register to *THIS. */ - emit_move_insn (static_chain_rtx, this_slot); - emit_move_insn (static_chain_rtx, gen_rtx_MEM (Pmode, static_chain_rtx)); + emit_move_insn (tmp, this_slot); + emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp)); /* Set ADDR to a legitimate address for *THIS + VCALL_OFFSET. */ - addr = plus_constant (static_chain_rtx, vcall_offset); + addr = plus_constant (tmp, vcall_offset); if (!m68k_legitimate_address_p (Pmode, addr, true)) { - emit_insn (gen_rtx_SET (VOIDmode, static_chain_rtx, addr)); - addr = static_chain_rtx; + emit_insn (gen_rtx_SET (VOIDmode, tmp, addr)); + addr = tmp; } /* Load the offset into %d0 and add it to THIS. */ @@ -5019,8 +5027,8 @@ m68k_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED, SET_REGNO (pic_offset_table_rtx, STATIC_CHAIN_REGNUM); emit_insn (gen_load_got (pic_offset_table_rtx)); } - legitimize_pic_address (XEXP (mem, 0), Pmode, static_chain_rtx); - mem = replace_equiv_address (mem, static_chain_rtx); + legitimize_pic_address (XEXP (mem, 0), Pmode, tmp); + mem = replace_equiv_address (mem, tmp); } insn = emit_call_insn (gen_sibcall (mem, const0_rtx)); SIBLING_CALL_P (insn) = 1; @@ -6390,4 +6398,30 @@ m68k_sched_indexed_address_bypass_p (rtx pro, rtx con) } } +/* We generate a two-instructions program at M_TRAMP : + movea.l &CHAIN_VALUE,%a0 + jmp FNADDR + where %a0 can be modified by changing STATIC_CHAIN_REGNUM. */ + +static void +m68k_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value) +{ + rtx fnaddr = XEXP (DECL_RTL (fndecl), 0); + rtx mem; + + gcc_assert (ADDRESS_REGNO_P (STATIC_CHAIN_REGNUM)); + + mem = adjust_address (m_tramp, HImode, 0); + emit_move_insn (mem, GEN_INT(0x207C + ((STATIC_CHAIN_REGNUM-8) << 9))); + mem = adjust_address (m_tramp, SImode, 2); + emit_move_insn (mem, chain_value); + + mem = adjust_address (m_tramp, HImode, 6); + emit_move_insn (mem, GEN_INT(0x4EF9)); + mem = adjust_address (m_tramp, SImode, 8); + emit_move_insn (mem, fnaddr); + + FINALIZE_TRAMPOLINE (XEXP (m_tramp, 0)); +} + #include "gt-m68k.h" diff --git a/gcc/config/m68k/m68k.h b/gcc/config/m68k/m68k.h index b2cfb1d8fd1..5787e8aa1fd 100644 --- a/gcc/config/m68k/m68k.h +++ b/gcc/config/m68k/m68k.h @@ -617,20 +617,6 @@ extern enum reg_class regno_reg_class[]; #define FINALIZE_TRAMPOLINE(TRAMP) #endif -/* We generate a two-instructions program at address TRAMP : - movea.l &CXT,%a0 - jmp FNADDR */ -#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \ -{ \ - 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)); \ - emit_move_insn (gen_rtx_MEM (SImode, plus_constant (TRAMP, 8)), FNADDR); \ - FINALIZE_TRAMPOLINE(TRAMP); \ -} - /* This is the library routine that is used to transfer control from the trampoline to the actual nested function. It is defined for backward compatibility, for linking with object code that used the old trampoline diff --git a/gcc/config/m68k/netbsd-elf.h b/gcc/config/m68k/netbsd-elf.h index 258b9e1cc73..fd654188e05 100644 --- a/gcc/config/m68k/netbsd-elf.h +++ b/gcc/config/m68k/netbsd-elf.h @@ -312,39 +312,5 @@ while (0) #undef DEFAULT_PCC_STRUCT_RETURN #define DEFAULT_PCC_STRUCT_RETURN 1 -/* Output assembler code for a block containing the constant parts - of a trampoline, leaving space for the variable parts. */ - -/* On m68k svr4, the trampoline is different from the generic version - in that we use a1 as the static call chain. */ - -#undef TRAMPOLINE_TEMPLATE -#define TRAMPOLINE_TEMPLATE(FILE) \ -{ \ - assemble_aligned_integer (2, GEN_INT (0x227a)); \ - assemble_aligned_integer (2, GEN_INT (8)); \ - assemble_aligned_integer (2, GEN_INT (0x2f3a)); \ - assemble_aligned_integer (2, GEN_INT (8)); \ - assemble_aligned_integer (2, GEN_INT (0x4e75)); \ - assemble_aligned_integer (4, const0_rtx); \ - assemble_aligned_integer (4, const0_rtx); \ -} - -/* Redefine since we are using a different trampoline */ -#undef TRAMPOLINE_SIZE -#define TRAMPOLINE_SIZE 18 - -/* Emit RTL insns to initialize the variable parts of a trampoline. - FNADDR is an RTX for the address of the function's pure code. - CXT is an RTX for the static chain value for the function. */ - -#undef INITIALIZE_TRAMPOLINE -#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \ -{ \ - emit_move_insn (gen_rtx_MEM (SImode, plus_constant (TRAMP, 10)), CXT); \ - emit_move_insn (gen_rtx_MEM (SImode, plus_constant (TRAMP, 14)), FNADDR); \ -} - - /* XXX This is the end of the chunk lifted from m68kv4.h */