aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2009-09-22 08:14:48 -0700
committerRichard Henderson <rth@gcc.gnu.org>2009-09-22 08:14:48 -0700
commit859c146ca052061e4aba946a4bf5c292e3983c26 (patch)
tree160d1c04ddf1466d4ed051270616525ba3755879 /gcc
parent4601494d99331aa5c76fa0f7b892cebdf451621e (diff)
downloadgcc-859c146ca052061e4aba946a4bf5c292e3983c26.zip
gcc-859c146ca052061e4aba946a4bf5c292e3983c26.tar.gz
gcc-859c146ca052061e4aba946a4bf5c292e3983c26.tar.bz2
pa.c (TARGET_ASM_TRAMPOLINE_TEMPLATE, [...]): New.
* gcc/config/pa/pa.c (TARGET_ASM_TRAMPOLINE_TEMPLATE, pa_asm_trampoline_template, TARGET_TRAMPOLINE_INIT, pa_trampoline_init, TARGET_TRAMPOLINE_ADJUST_ADDRESS, pa_trampoline_adjust_address): New. * config/pa/pa.h (TRAMPOLINE_TEMPLATE): Move code to pa_asm_trampoline_template. (TRAMPOLINE_ALIGNMENT): New. (TRAMPOLINE_CODE_SIZE): Move to pa.c. (INITIALIZE_TRAMPOLINE): Move code to pa_trampoline_init; adjust for hook parameters. (TRAMPOLINE_ADJUST_ADDRESS): Move code to pa_trampoline_adjust_address. From-SVN: r152005
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog12
-rw-r--r--gcc/config/pa/pa.c181
-rw-r--r--gcc/config/pa/pa.h161
3 files changed, 195 insertions, 159 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 229a560..cdb3ec9 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -192,6 +192,18 @@
(TRAMPOLINE_TEMPLATE): Move code to moxie_asm_trampoline_template.
(STATIC_CHAIN, STATIC_CHAIN_INCOMING): Remove.
+ * gcc/config/pa/pa.c (TARGET_ASM_TRAMPOLINE_TEMPLATE,
+ pa_asm_trampoline_template, TARGET_TRAMPOLINE_INIT,
+ pa_trampoline_init, TARGET_TRAMPOLINE_ADJUST_ADDRESS,
+ pa_trampoline_adjust_address): New.
+ * config/pa/pa.h (TRAMPOLINE_TEMPLATE): Move code to
+ pa_asm_trampoline_template.
+ (TRAMPOLINE_ALIGNMENT): New.
+ (TRAMPOLINE_CODE_SIZE): Move to pa.c.
+ (INITIALIZE_TRAMPOLINE): Move code to pa_trampoline_init;
+ adjust for hook parameters.
+ (TRAMPOLINE_ADJUST_ADDRESS): Move code to pa_trampoline_adjust_address.
+
2009-09-22 Jakub Jelinek <jakub@redhat.com>
* config/rs6000/rs6000.c (bdesc_2arg): Fix CODE_FOR_vector_gt* codes
diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c
index 65a07d9..09c830e 100644
--- a/gcc/config/pa/pa.c
+++ b/gcc/config/pa/pa.c
@@ -163,6 +163,10 @@ static enum machine_mode pa_promote_function_mode (const_tree,
enum machine_mode, int *,
const_tree, int);
+static void pa_asm_trampoline_template (FILE *);
+static void pa_trampoline_init (rtx, tree, rtx);
+static rtx pa_trampoline_adjust_address (rtx);
+
/* The following extra sections are only used for SOM. */
static GTY(()) section *som_readonly_data_section;
static GTY(()) section *som_one_only_readonly_data_section;
@@ -325,6 +329,13 @@ static size_t n_deferred_plabels = 0;
#undef TARGET_EXTRA_LIVE_ON_ENTRY
#define TARGET_EXTRA_LIVE_ON_ENTRY pa_extra_live_on_entry
+#undef TARGET_ASM_TRAMPOLINE_TEMPLATE
+#define TARGET_ASM_TRAMPOLINE_TEMPLATE pa_asm_trampoline_template
+#undef TARGET_TRAMPOLINE_INIT
+#define TARGET_TRAMPOLINE_INIT pa_trampoline_init
+#undef TARGET_TRAMPOLINE_ADJUST_ADDRESS
+#define TARGET_TRAMPOLINE_ADJUST_ADDRESS pa_trampoline_adjust_address
+
struct gcc_target targetm = TARGET_INITIALIZER;
/* Parse the -mfixed-range= option string. */
@@ -9808,4 +9819,174 @@ pa_modes_tieable_p (enum machine_mode mode1, enum machine_mode mode2)
return true;
}
+
+/* Length in units of the trampoline instruction code. */
+
+#define TRAMPOLINE_CODE_SIZE (TARGET_64BIT ? 24 : (TARGET_PA_20 ? 32 : 40))
+
+
+/* Output assembler code for a block containing the constant parts
+ of a trampoline, leaving space for the variable parts.\
+
+ The trampoline sets the static chain pointer to STATIC_CHAIN_REGNUM
+ and then branches to the specified routine.
+
+ This code template is copied from text segment to stack location
+ and then patched with pa_trampoline_init to contain valid values,
+ and then entered as a subroutine.
+
+ It is best to keep this as small as possible to avoid having to
+ flush multiple lines in the cache. */
+
+static void
+pa_asm_trampoline_template (FILE *f)
+{
+ if (!TARGET_64BIT)
+ {
+ fputs ("\tldw 36(%r22),%r21\n", f);
+ fputs ("\tbb,>=,n %r21,30,.+16\n", f);
+ if (ASSEMBLER_DIALECT == 0)
+ fputs ("\tdepi 0,31,2,%r21\n", f);
+ else
+ fputs ("\tdepwi 0,31,2,%r21\n", f);
+ fputs ("\tldw 4(%r21),%r19\n", f);
+ fputs ("\tldw 0(%r21),%r21\n", f);
+ if (TARGET_PA_20)
+ {
+ fputs ("\tbve (%r21)\n", f);
+ fputs ("\tldw 40(%r22),%r29\n", f);
+ fputs ("\t.word 0\n", f);
+ fputs ("\t.word 0\n", f);
+ }
+ else
+ {
+ fputs ("\tldsid (%r21),%r1\n", f);
+ fputs ("\tmtsp %r1,%sr0\n", f);
+ fputs ("\tbe 0(%sr0,%r21)\n", f);
+ fputs ("\tldw 40(%r22),%r29\n", f);
+ }
+ fputs ("\t.word 0\n", f);
+ fputs ("\t.word 0\n", f);
+ fputs ("\t.word 0\n", f);
+ fputs ("\t.word 0\n", f);
+ }
+ else
+ {
+ fputs ("\t.dword 0\n", f);
+ fputs ("\t.dword 0\n", f);
+ fputs ("\t.dword 0\n", f);
+ fputs ("\t.dword 0\n", f);
+ fputs ("\tmfia %r31\n", f);
+ fputs ("\tldd 24(%r31),%r1\n", f);
+ fputs ("\tldd 24(%r1),%r27\n", f);
+ fputs ("\tldd 16(%r1),%r1\n", f);
+ fputs ("\tbve (%r1)\n", f);
+ fputs ("\tldd 32(%r31),%r31\n", f);
+ fputs ("\t.dword 0 ; fptr\n", f);
+ fputs ("\t.dword 0 ; static link\n", f);
+ }
+}
+
+/* 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.
+
+ Move the function address to the trampoline template at offset 36.
+ Move the static chain value to trampoline template at offset 40.
+ Move the trampoline address to trampoline template at offset 44.
+ Move r19 to trampoline template at offset 48. The latter two
+ words create a plabel for the indirect call to the trampoline.
+
+ A similar sequence is used for the 64-bit port but the plabel is
+ at the beginning of the trampoline.
+
+ Finally, the cache entries for the trampoline code are flushed.
+ This is necessary to ensure that the trampoline instruction sequence
+ is written to memory prior to any attempts at prefetching the code
+ sequence. */
+
+static void
+pa_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
+{
+ rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
+ rtx start_addr = gen_reg_rtx (Pmode);
+ rtx end_addr = gen_reg_rtx (Pmode);
+ rtx line_length = gen_reg_rtx (Pmode);
+ rtx r_tramp, tmp;
+
+ emit_block_move (m_tramp, assemble_trampoline_template (),
+ GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
+ r_tramp = force_reg (Pmode, XEXP (m_tramp, 0));
+
+ if (!TARGET_64BIT)
+ {
+ tmp = adjust_address (m_tramp, Pmode, 36);
+ emit_move_insn (tmp, fnaddr);
+ tmp = adjust_address (m_tramp, Pmode, 40);
+ emit_move_insn (tmp, chain_value);
+
+ /* Create a fat pointer for the trampoline. */
+ tmp = adjust_address (m_tramp, Pmode, 44);
+ emit_move_insn (tmp, r_tramp);
+ tmp = adjust_address (m_tramp, Pmode, 48);
+ emit_move_insn (tmp, gen_rtx_REG (Pmode, 19));
+
+ /* fdc and fic only use registers for the address to flush,
+ they do not accept integer displacements. We align the
+ start and end addresses to the beginning of their respective
+ cache lines to minimize the number of lines flushed. */
+ emit_insn (gen_andsi3 (start_addr, r_tramp,
+ GEN_INT (-MIN_CACHELINE_SIZE)));
+ tmp = force_reg (Pmode, plus_constant (r_tramp, TRAMPOLINE_CODE_SIZE-1));
+ emit_insn (gen_andsi3 (end_addr, tmp,
+ GEN_INT (-MIN_CACHELINE_SIZE)));
+ emit_move_insn (line_length, GEN_INT (MIN_CACHELINE_SIZE));
+ emit_insn (gen_dcacheflushsi (start_addr, end_addr, line_length));
+ emit_insn (gen_icacheflushsi (start_addr, end_addr, line_length,
+ gen_reg_rtx (Pmode),
+ gen_reg_rtx (Pmode)));
+ }
+ else
+ {
+ tmp = adjust_address (m_tramp, Pmode, 56);
+ emit_move_insn (tmp, fnaddr);
+ tmp = adjust_address (m_tramp, Pmode, 64);
+ emit_move_insn (tmp, chain_value);
+
+ /* Create a fat pointer for the trampoline. */
+ tmp = adjust_address (m_tramp, Pmode, 16);
+ emit_move_insn (tmp, force_reg (Pmode, plus_constant (r_tramp, 32)));
+ tmp = adjust_address (m_tramp, Pmode, 24);
+ emit_move_insn (tmp, gen_rtx_REG (Pmode, 27));
+
+ /* fdc and fic only use registers for the address to flush,
+ they do not accept integer displacements. We align the
+ start and end addresses to the beginning of their respective
+ cache lines to minimize the number of lines flushed. */
+ tmp = force_reg (Pmode, plus_constant (r_tramp, 32));
+ emit_insn (gen_anddi3 (start_addr, tmp,
+ GEN_INT (-MIN_CACHELINE_SIZE)));
+ tmp = force_reg (Pmode, plus_constant (tmp, TRAMPOLINE_CODE_SIZE - 1));
+ emit_insn (gen_anddi3 (end_addr, tmp,
+ GEN_INT (-MIN_CACHELINE_SIZE)));
+ emit_move_insn (line_length, GEN_INT (MIN_CACHELINE_SIZE));
+ emit_insn (gen_dcacheflushdi (start_addr, end_addr, line_length));
+ emit_insn (gen_icacheflushdi (start_addr, end_addr, line_length,
+ gen_reg_rtx (Pmode),
+ gen_reg_rtx (Pmode)));
+ }
+}
+
+/* Perform any machine-specific adjustment in the address of the trampoline.
+ ADDR contains the address that was passed to pa_trampoline_init.
+ Adjust the trampoline address to point to the plabel at offset 44. */
+
+static rtx
+pa_trampoline_adjust_address (rtx addr)
+{
+ if (!TARGET_64BIT)
+ addr = memory_address (Pmode, plus_constant (addr, 46));
+ return addr;
+}
+
#include "gt-pa.h"
diff --git a/gcc/config/pa/pa.h b/gcc/config/pa/pa.h
index 3b0dded..7716e73 100644
--- a/gcc/config/pa/pa.h
+++ b/gcc/config/pa/pa.h
@@ -778,74 +778,13 @@ extern int may_call_alloca;
(get_frame_size () != 0 \
|| cfun->calls_alloca || crtl->outgoing_args_size)
-/* Output assembler code for a block containing the constant parts
- of a trampoline, leaving space for the variable parts.\
-
- The trampoline sets the static chain pointer to STATIC_CHAIN_REGNUM
- and then branches to the specified routine.
-
- This code template is copied from text segment to stack location
- and then patched with INITIALIZE_TRAMPOLINE to contain
- valid values, and then entered as a subroutine.
-
- It is best to keep this as small as possible to avoid having to
- flush multiple lines in the cache. */
-
-#define TRAMPOLINE_TEMPLATE(FILE) \
- { \
- if (!TARGET_64BIT) \
- { \
- fputs ("\tldw 36(%r22),%r21\n", FILE); \
- fputs ("\tbb,>=,n %r21,30,.+16\n", FILE); \
- if (ASSEMBLER_DIALECT == 0) \
- fputs ("\tdepi 0,31,2,%r21\n", FILE); \
- else \
- fputs ("\tdepwi 0,31,2,%r21\n", FILE); \
- fputs ("\tldw 4(%r21),%r19\n", FILE); \
- fputs ("\tldw 0(%r21),%r21\n", FILE); \
- if (TARGET_PA_20) \
- { \
- fputs ("\tbve (%r21)\n", FILE); \
- fputs ("\tldw 40(%r22),%r29\n", FILE); \
- fputs ("\t.word 0\n", FILE); \
- fputs ("\t.word 0\n", FILE); \
- } \
- else \
- { \
- fputs ("\tldsid (%r21),%r1\n", FILE); \
- fputs ("\tmtsp %r1,%sr0\n", FILE); \
- fputs ("\tbe 0(%sr0,%r21)\n", FILE); \
- fputs ("\tldw 40(%r22),%r29\n", FILE); \
- } \
- fputs ("\t.word 0\n", FILE); \
- fputs ("\t.word 0\n", FILE); \
- fputs ("\t.word 0\n", FILE); \
- fputs ("\t.word 0\n", FILE); \
- } \
- else \
- { \
- fputs ("\t.dword 0\n", FILE); \
- fputs ("\t.dword 0\n", FILE); \
- fputs ("\t.dword 0\n", FILE); \
- fputs ("\t.dword 0\n", FILE); \
- fputs ("\tmfia %r31\n", FILE); \
- fputs ("\tldd 24(%r31),%r1\n", FILE); \
- fputs ("\tldd 24(%r1),%r27\n", FILE); \
- fputs ("\tldd 16(%r1),%r1\n", FILE); \
- fputs ("\tbve (%r1)\n", FILE); \
- fputs ("\tldd 32(%r31),%r31\n", FILE); \
- fputs ("\t.dword 0 ; fptr\n", FILE); \
- fputs ("\t.dword 0 ; static link\n", FILE); \
- } \
- }
-
/* Length in units of the trampoline for entering a nested function. */
#define TRAMPOLINE_SIZE (TARGET_64BIT ? 72 : 52)
-/* Length in units of the trampoline instruction code. */
+/* Alignment required by the trampoline. */
-#define TRAMPOLINE_CODE_SIZE (TARGET_64BIT ? 24 : (TARGET_PA_20 ? 32 : 40))
+#define TRAMPOLINE_ALIGNMENT BITS_PER_WORD
/* Minimum length of a cache line. A length of 16 will work on all
PA-RISC processors. All PA 1.1 processors have a cache line of
@@ -855,102 +794,6 @@ extern int may_call_alloca;
#define MIN_CACHELINE_SIZE 32
-/* 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.
-
- Move the function address to the trampoline template at offset 36.
- Move the static chain value to trampoline template at offset 40.
- Move the trampoline address to trampoline template at offset 44.
- Move r19 to trampoline template at offset 48. The latter two
- words create a plabel for the indirect call to the trampoline.
-
- A similar sequence is used for the 64-bit port but the plabel is
- at the beginning of the trampoline.
-
- Finally, the cache entries for the trampoline code are flushed.
- This is necessary to ensure that the trampoline instruction sequence
- is written to memory prior to any attempts at prefetching the code
- sequence. */
-
-#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
-{ \
- rtx start_addr = gen_reg_rtx (Pmode); \
- rtx end_addr = gen_reg_rtx (Pmode); \
- rtx line_length = gen_reg_rtx (Pmode); \
- rtx tmp; \
- \
- if (!TARGET_64BIT) \
- { \
- tmp = memory_address (Pmode, plus_constant ((TRAMP), 36)); \
- emit_move_insn (gen_rtx_MEM (Pmode, tmp), (FNADDR)); \
- tmp = memory_address (Pmode, plus_constant ((TRAMP), 40)); \
- emit_move_insn (gen_rtx_MEM (Pmode, tmp), (CXT)); \
- \
- /* Create a fat pointer for the trampoline. */ \
- tmp = memory_address (Pmode, plus_constant ((TRAMP), 44)); \
- emit_move_insn (gen_rtx_MEM (Pmode, tmp), (TRAMP)); \
- tmp = memory_address (Pmode, plus_constant ((TRAMP), 48)); \
- emit_move_insn (gen_rtx_MEM (Pmode, tmp), \
- gen_rtx_REG (Pmode, 19)); \
- \
- /* fdc and fic only use registers for the address to flush, \
- they do not accept integer displacements. We align the \
- start and end addresses to the beginning of their respective \
- cache lines to minimize the number of lines flushed. */ \
- tmp = force_reg (Pmode, (TRAMP)); \
- emit_insn (gen_andsi3 (start_addr, tmp, \
- GEN_INT (-MIN_CACHELINE_SIZE))); \
- tmp = force_reg (Pmode, \
- plus_constant (tmp, TRAMPOLINE_CODE_SIZE - 1)); \
- emit_insn (gen_andsi3 (end_addr, tmp, \
- GEN_INT (-MIN_CACHELINE_SIZE))); \
- emit_move_insn (line_length, GEN_INT (MIN_CACHELINE_SIZE)); \
- emit_insn (gen_dcacheflushsi (start_addr, end_addr, line_length));\
- emit_insn (gen_icacheflushsi (start_addr, end_addr, line_length, \
- gen_reg_rtx (Pmode), \
- gen_reg_rtx (Pmode))); \
- } \
- else \
- { \
- tmp = memory_address (Pmode, plus_constant ((TRAMP), 56)); \
- emit_move_insn (gen_rtx_MEM (Pmode, tmp), (FNADDR)); \
- tmp = memory_address (Pmode, plus_constant ((TRAMP), 64)); \
- emit_move_insn (gen_rtx_MEM (Pmode, tmp), (CXT)); \
- \
- /* Create a fat pointer for the trampoline. */ \
- tmp = memory_address (Pmode, plus_constant ((TRAMP), 16)); \
- emit_move_insn (gen_rtx_MEM (Pmode, tmp), \
- force_reg (Pmode, plus_constant ((TRAMP), 32))); \
- tmp = memory_address (Pmode, plus_constant ((TRAMP), 24)); \
- emit_move_insn (gen_rtx_MEM (Pmode, tmp), \
- gen_rtx_REG (Pmode, 27)); \
- \
- /* fdc and fic only use registers for the address to flush, \
- they do not accept integer displacements. We align the \
- start and end addresses to the beginning of their respective \
- cache lines to minimize the number of lines flushed. */ \
- tmp = force_reg (Pmode, plus_constant ((TRAMP), 32)); \
- emit_insn (gen_anddi3 (start_addr, tmp, \
- GEN_INT (-MIN_CACHELINE_SIZE))); \
- tmp = force_reg (Pmode, \
- plus_constant (tmp, TRAMPOLINE_CODE_SIZE - 1)); \
- emit_insn (gen_anddi3 (end_addr, tmp, \
- GEN_INT (-MIN_CACHELINE_SIZE))); \
- emit_move_insn (line_length, GEN_INT (MIN_CACHELINE_SIZE)); \
- emit_insn (gen_dcacheflushdi (start_addr, end_addr, line_length));\
- emit_insn (gen_icacheflushdi (start_addr, end_addr, line_length, \
- gen_reg_rtx (Pmode), \
- gen_reg_rtx (Pmode))); \
- } \
-}
-
-/* Perform any machine-specific adjustment in the address of the trampoline.
- ADDR contains the address that was passed to INITIALIZE_TRAMPOLINE.
- Adjust the trampoline address to point to the plabel at offset 44. */
-
-#define TRAMPOLINE_ADJUST_ADDRESS(ADDR) \
- if (!TARGET_64BIT) (ADDR) = memory_address (Pmode, plus_constant ((ADDR), 46))
/* Addressing modes, and classification of registers for them.