diff options
author | Richard Henderson <rth@redhat.com> | 2009-09-22 08:14:48 -0700 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2009-09-22 08:14:48 -0700 |
commit | 859c146ca052061e4aba946a4bf5c292e3983c26 (patch) | |
tree | 160d1c04ddf1466d4ed051270616525ba3755879 /gcc | |
parent | 4601494d99331aa5c76fa0f7b892cebdf451621e (diff) | |
download | gcc-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/ChangeLog | 12 | ||||
-rw-r--r-- | gcc/config/pa/pa.c | 181 | ||||
-rw-r--r-- | gcc/config/pa/pa.h | 161 |
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. |