aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2011-01-12 09:45:42 -0800
committerRichard Henderson <rth@gcc.gnu.org>2011-01-12 09:45:42 -0800
commitd6a3e26499ed7c6ff937cdb7319c1f04029cb61c (patch)
treefdb2749be3712139374d777829a437d945232d45 /gcc
parent0f8ab43451a04f7e1d492a72f30e6d87eed23f70 (diff)
downloadgcc-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/ChangeLog7
-rw-r--r--gcc/config/mn10300/mn10300.c50
-rw-r--r--gcc/config/mn10300/mn10300.h5
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.