aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/alpha/alpha.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/alpha/alpha.c')
-rw-r--r--gcc/config/alpha/alpha.c88
1 files changed, 45 insertions, 43 deletions
diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c
index 46ad8f4be2d..86fd1ee5599 100644
--- a/gcc/config/alpha/alpha.c
+++ b/gcc/config/alpha/alpha.c
@@ -5541,34 +5541,23 @@ print_operand_address (FILE *file, rtx addr)
}
/* Emit RTL insns to initialize the variable parts of a trampoline at
- TRAMP. 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.
+ M_TRAMP. FNDECL is target function's decl. CHAIN_VALUE is an rtx
+ for the static chain value for the function. */
- The three offset parameters are for the individual template's
- layout. A JMPOFS < 0 indicates that the trampoline does not
- contain instructions at all.
-
- We assume here that a function will be called many more times than
- its address is taken (e.g., it might be passed to qsort), so we
- take the trouble to initialize the "hint" field in the JMP insn.
- Note that the hint field is PC (new) + 4 * bits 13:0. */
-
-void
-alpha_initialize_trampoline (rtx tramp, rtx fnaddr, rtx cxt,
- int fnofs, int cxtofs, int jmpofs)
+static void
+alpha_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
{
- rtx addr;
- /* VMS really uses DImode pointers in memory at this point. */
- enum machine_mode mode = TARGET_ABI_OPEN_VMS ? Pmode : ptr_mode;
+ rtx fnaddr, mem, word1, word2;
+
+ fnaddr = XEXP (DECL_RTL (fndecl), 0);
#ifdef POINTERS_EXTEND_UNSIGNED
- fnaddr = convert_memory_address (mode, fnaddr);
- cxt = convert_memory_address (mode, cxt);
+ fnaddr = convert_memory_address (Pmode, fnaddr);
+ chain_value = convert_memory_address (Pmode, chain_value);
#endif
if (TARGET_ABI_OPEN_VMS)
{
- rtx temp1, traddr;
const char *fnname;
char *trname;
@@ -5577,37 +5566,48 @@ alpha_initialize_trampoline (rtx tramp, rtx fnaddr, rtx cxt,
trname = (char *) alloca (strlen (fnname) + 5);
strcpy (trname, fnname);
strcat (trname, "..tr");
- traddr = gen_rtx_SYMBOL_REF
- (mode, ggc_alloc_string (trname, strlen (trname) + 1));
+ fnname = ggc_alloc_string (trname, strlen (trname) + 1);
+ word2 = gen_rtx_SYMBOL_REF (Pmode, fnname);
/* Trampoline (or "bounded") procedure descriptor is constructed from
the function's procedure descriptor with certain fields zeroed IAW
the VMS calling standard. This is stored in the first quadword. */
- temp1 = force_reg (DImode, gen_rtx_MEM (DImode, fnaddr));
- temp1 = expand_and (DImode, temp1,
- GEN_INT (0xffff0fff0000fff0), NULL_RTX);
- addr = memory_address (mode, plus_constant (tramp, 0));
- emit_move_insn (gen_rtx_MEM (DImode, addr), temp1);
-
- /* Trampoline transfer address is stored in the second quadword
- of the trampoline. */
- addr = memory_address (mode, plus_constant (tramp, 8));
- emit_move_insn (gen_rtx_MEM (mode, addr), traddr);
+ word1 = force_reg (DImode, gen_const_mem (DImode, fnaddr));
+ word1 = expand_and (DImode, word1, GEN_INT (0xffff0fff0000fff0), NULL);
}
+ else
+ {
+ /* These 4 instructions are:
+ ldq $1,24($27)
+ ldq $27,16($27)
+ jmp $31,($27),0
+ nop
+ We don't bother setting the HINT field of the jump; the nop
+ is merely there for padding. */
+ word1 = GEN_INT (0xa77b0010a43b0018);
+ word2 = GEN_INT (0x47ff041f6bfb0000);
+ }
+
+ /* Store the first two words, as computed above. */
+ mem = adjust_address (m_tramp, DImode, 0);
+ emit_move_insn (mem, word1);
+ mem = adjust_address (m_tramp, DImode, 8);
+ emit_move_insn (mem, word2);
+
+ /* Store function address and static chain value. */
+ mem = adjust_address (m_tramp, Pmode, 16);
+ emit_move_insn (mem, fnaddr);
+ mem = adjust_address (m_tramp, Pmode, 24);
+ emit_move_insn (mem, chain_value);
- /* Store function address and CXT. */
- addr = memory_address (mode, plus_constant (tramp, fnofs));
- emit_move_insn (gen_rtx_MEM (mode, addr), fnaddr);
- addr = memory_address (mode, plus_constant (tramp, cxtofs));
- emit_move_insn (gen_rtx_MEM (mode, addr), cxt);
-
+ if (!TARGET_ABI_OPEN_VMS)
+ {
+ emit_insn (gen_imb ());
#ifdef ENABLE_EXECUTE_STACK
- emit_library_call (init_one_libfunc ("__enable_execute_stack"),
- LCT_NORMAL, VOIDmode, 1, tramp, Pmode);
+ emit_library_call (init_one_libfunc ("__enable_execute_stack"),
+ LCT_NORMAL, VOIDmode, 1, XEXP (m_tramp, 0), Pmode);
#endif
-
- if (jmpofs >= 0)
- emit_insn (gen_imb ());
+ }
}
/* Determine where to put an argument to a function.
@@ -11114,6 +11114,8 @@ alpha_init_libfuncs (void)
#define TARGET_GIMPLIFY_VA_ARG_EXPR alpha_gimplify_va_arg
#undef TARGET_ARG_PARTIAL_BYTES
#define TARGET_ARG_PARTIAL_BYTES alpha_arg_partial_bytes
+#undef TARGET_TRAMPOLINE_INIT
+#define TARGET_TRAMPOLINE_INIT alpha_trampoline_init
#undef TARGET_SECONDARY_RELOAD
#define TARGET_SECONDARY_RELOAD alpha_secondary_reload