diff options
author | Richard Henderson <rth@redhat.com> | 2011-01-12 09:45:42 -0800 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2011-01-12 09:45:42 -0800 |
commit | d6a3e26499ed7c6ff937cdb7319c1f04029cb61c (patch) | |
tree | fdb2749be3712139374d777829a437d945232d45 /gcc | |
parent | 0f8ab43451a04f7e1d492a72f30e6d87eed23f70 (diff) | |
download | gcc-d6a3e26499ed7c6ff937cdb7319c1f04029cb61c.zip gcc-d6a3e26499ed7c6ff937cdb7319c1f04029cb61c.tar.gz gcc-d6a3e26499ed7c6ff937cdb7319c1f04029cb61c.tar.bz2 |
mn10300: Clean up trampoline handling
The old code was failing in the testsuite. I didn't try to
debug exactly why, since the existing code was needlessly
complex.
From-SVN: r168720
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/config/mn10300/mn10300.c | 50 | ||||
-rw-r--r-- | gcc/config/mn10300/mn10300.h | 5 |
3 files changed, 34 insertions, 28 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index fffa356..0317cbb 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2011-01-12 Richard Henderson <rth@redhat.com> + + * config/mn10300/mn10300.c (mn10300_asm_trampoline_template): Remove. + (mn10300_trampoline_init): Rewrite without a template, an immediate + load and a direct branch. + * config/mn10300/mn10300.h (TRAMPOLINE_SIZE): Reduce to 16. + 2011-01-12 Anatoly Sokolov <aesok@post.ru> * config/s390/s390.h (OUTPUT_ADDR_CONST_EXTRA): Remove. diff --git a/gcc/config/mn10300/mn10300.c b/gcc/config/mn10300/mn10300.c index d39b427..5f2d63b 100644 --- a/gcc/config/mn10300/mn10300.c +++ b/gcc/config/mn10300/mn10300.c @@ -2397,37 +2397,39 @@ mn10300_case_values_threshold (void) return 6; } -/* Worker function for TARGET_ASM_TRAMPOLINE_TEMPLATE. */ - -static void -mn10300_asm_trampoline_template (FILE *f) -{ - fprintf (f, "\tadd -4,sp\n"); - fprintf (f, "\t.long 0x0004fffa\n"); - fprintf (f, "\tmov (0,sp),a0\n"); - fprintf (f, "\tadd 4,sp\n"); - fprintf (f, "\tmov (13,a0),a1\n"); - fprintf (f, "\tmov (17,a0),a0\n"); - fprintf (f, "\tjmp (a0)\n"); - fprintf (f, "\t.long 0\n"); - fprintf (f, "\t.long 0\n"); -} - /* Worker function for TARGET_TRAMPOLINE_INIT. */ static void mn10300_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value) { - rtx fnaddr = XEXP (DECL_RTL (fndecl), 0); - rtx mem; + rtx mem, disp, fnaddr = XEXP (DECL_RTL (fndecl), 0); + + /* This is a strict alignment target, which means that we play + some games to make sure that the locations at which we need + to store <chain> and <disp> wind up at aligned addresses. + + 0x28 0x00 add 0,d0 + 0xfc 0xdd mov chain,a1 + <chain> + 0xf8 0xed 0x00 btst 0,d1 + 0xdc jmp fnaddr + <disp> + + Note that the two extra insns are effectively nops; they + clobber the flags but do not affect the contents of D0 or D1. */ - emit_block_move (m_tramp, assemble_trampoline_template (), - GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL); + disp = expand_binop (SImode, sub_optab, fnaddr, + plus_constant (XEXP (m_tramp, 0), 11), + NULL_RTX, 1, OPTAB_DIRECT); - mem = adjust_address (m_tramp, SImode, 0x14); + mem = adjust_address (m_tramp, SImode, 0); + emit_move_insn (mem, gen_int_mode (0xddfc0028, SImode)); + mem = adjust_address (m_tramp, SImode, 4); emit_move_insn (mem, chain_value); - mem = adjust_address (m_tramp, SImode, 0x18); - emit_move_insn (mem, fnaddr); + mem = adjust_address (m_tramp, SImode, 8); + emit_move_insn (mem, gen_int_mode (0xdc00edf8, SImode)); + mem = adjust_address (m_tramp, SImode, 12); + emit_move_insn (mem, disp); } /* Output the assembler code for a C++ thunk function. @@ -2720,8 +2722,6 @@ mn10300_conditional_register_usage (void) #undef TARGET_PREFERRED_OUTPUT_RELOAD_CLASS #define TARGET_PREFERRED_OUTPUT_RELOAD_CLASS mn10300_preferred_output_reload_class -#undef TARGET_ASM_TRAMPOLINE_TEMPLATE -#define TARGET_ASM_TRAMPOLINE_TEMPLATE mn10300_asm_trampoline_template #undef TARGET_TRAMPOLINE_INIT #define TARGET_TRAMPOLINE_INIT mn10300_trampoline_init diff --git a/gcc/config/mn10300/mn10300.h b/gcc/config/mn10300/mn10300.h index ef79245..3f63498 100644 --- a/gcc/config/mn10300/mn10300.h +++ b/gcc/config/mn10300/mn10300.h @@ -533,9 +533,8 @@ struct cum_arg /* Length in units of the trampoline for entering a nested function. */ -#define TRAMPOLINE_SIZE 0x1b - -#define TRAMPOLINE_ALIGNMENT 32 +#define TRAMPOLINE_SIZE 16 +#define TRAMPOLINE_ALIGNMENT 32 /* A C expression whose value is RTL representing the value of the return address for the frame COUNT steps up from the current frame. |