aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/mn10300/mn10300.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/mn10300/mn10300.c')
-rw-r--r--gcc/config/mn10300/mn10300.c42
1 files changed, 41 insertions, 1 deletions
diff --git a/gcc/config/mn10300/mn10300.c b/gcc/config/mn10300/mn10300.c
index 608f8a0fa35..1a0eb37bbde 100644
--- a/gcc/config/mn10300/mn10300.c
+++ b/gcc/config/mn10300/mn10300.c
@@ -83,6 +83,9 @@ static bool mn10300_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
static int mn10300_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
tree, bool);
static unsigned int mn10300_case_values_threshold (void);
+static void mn10300_encode_section_info (tree, rtx, int);
+static void mn10300_asm_trampoline_template (FILE *);
+static void mn10300_trampoline_init (rtx, tree, rtx);
/* Initialize the GCC target structure. */
#undef TARGET_ASM_ALIGNED_HI_OP
@@ -131,7 +134,11 @@ static unsigned int mn10300_case_values_threshold (void);
#undef TARGET_LEGITIMATE_ADDRESS_P
#define TARGET_LEGITIMATE_ADDRESS_P mn10300_legitimate_address_p
-static void mn10300_encode_section_info (tree, rtx, int);
+#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
+
struct gcc_target targetm = TARGET_INITIALIZER;
/* Implement TARGET_HANDLE_OPTION. */
@@ -2165,3 +2172,36 @@ unsigned int 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;
+
+ emit_block_move (m_tramp, assemble_trampoline_template (),
+ GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
+
+ mem = adjust_address (m_tramp, SImode, 0x14);
+ emit_move_insn (mem, chain_value);
+ mem = adjust_address (m_tramp, SImode, 0x18);
+ emit_move_insn (mem, fnaddr);
+}