diff options
author | Richard Henderson <rth@redhat.com> | 2009-09-22 08:12:23 -0700 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2009-09-22 08:12:23 -0700 |
commit | 3e322b77d60784b418c7f03d5bf9911992ffcf40 (patch) | |
tree | c2bc9a19b43019ebebd71ad29fbb36881d7bee5e | |
parent | 92910d774d50640ec270c2386a96cfa78f1663ae (diff) | |
download | gcc-3e322b77d60784b418c7f03d5bf9911992ffcf40.zip gcc-3e322b77d60784b418c7f03d5bf9911992ffcf40.tar.gz gcc-3e322b77d60784b418c7f03d5bf9911992ffcf40.tar.bz2 |
cris.c (TARGET_ASM_TRAMPOLINE_TEMPLATE, [...]): New.
* config/cris/cris.c (TARGET_ASM_TRAMPOLINE_TEMPLATE,
TARGET_TRAMPOLINE_INIT, cris_asm_trampoline_template,
cris_trampoline_init): New.
* config/cris/cris.h (TRAMPOLINE_TEMPLATE): Move code to
cris_asm_trampoline_template.
(INITIALIZE_TRAMPOLINE): Move code to cris_trampoline_init;
adjust for target hook parameters.
From-SVN: r151989
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/config/cris/cris.c | 105 | ||||
-rw-r--r-- | gcc/config/cris/cris.h | 99 |
3 files changed, 114 insertions, 98 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c9c2cda..042d864 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -79,6 +79,14 @@ bfin_asm_trampoline_template. (INITIALIZE_TRAMPOLINE): Remove. + * config/cris/cris.c (TARGET_ASM_TRAMPOLINE_TEMPLATE, + TARGET_TRAMPOLINE_INIT, cris_asm_trampoline_template, + cris_trampoline_init): New. + * config/cris/cris.h (TRAMPOLINE_TEMPLATE): Move code to + cris_asm_trampoline_template. + (INITIALIZE_TRAMPOLINE): Move code to cris_trampoline_init; + adjust for target hook parameters. + 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/cris/cris.c b/gcc/config/cris/cris.c index 6b3fd0f..bf00a57 100644 --- a/gcc/config/cris/cris.c +++ b/gcc/config/cris/cris.c @@ -127,6 +127,9 @@ static bool cris_handle_option (size_t, const char *, int); static bool cris_frame_pointer_required (void); +static void cris_asm_trampoline_template (FILE *); +static void cris_trampoline_init (rtx, tree, rtx); + /* This is the parsed result of the "-max-stack-stackframe=" option. If it (still) is zero, then there was no such option given. */ int cris_max_stackframe = 0; @@ -189,6 +192,11 @@ int cris_cpu_version = CRIS_DEFAULT_CPU_VERSION; #undef TARGET_FRAME_POINTER_REQUIRED #define TARGET_FRAME_POINTER_REQUIRED cris_frame_pointer_required +#undef TARGET_ASM_TRAMPOLINE_TEMPLATE +#define TARGET_ASM_TRAMPOLINE_TEMPLATE cris_asm_trampoline_template +#undef TARGET_TRAMPOLINE_INIT +#define TARGET_TRAMPOLINE_INIT cris_trampoline_init + struct gcc_target targetm = TARGET_INITIALIZER; /* Helper for cris_load_multiple_op and cris_ret_movem_op. */ @@ -3853,6 +3861,103 @@ cris_frame_pointer_required (void) return !current_function_sp_is_unchanging; } +/* Implement TARGET_ASM_TRAMPOLINE_TEMPLATE. + + This looks too complicated, and it is. I assigned r7 to be the + static chain register, but it is call-saved, so we have to save it, + and come back to restore it after the call, so we have to save srp... + Anyway, trampolines are rare enough that we can cope with this + somewhat lack of elegance. + (Do not be tempted to "straighten up" whitespace in the asms; the + assembler #NO_APP state mandates strict spacing). */ +/* ??? See the i386 regparm=3 implementation that pushes the static + chain value to the stack in the trampoline, and uses a call-saved + register when called directly. */ + +static void +cris_asm_trampoline_template (FILE *f) +{ + if (TARGET_V32) + { + /* This normally-unused nop insn acts as an instruction to + the simulator to flush its instruction cache. None of + the other instructions in the trampoline template suits + as a trigger for V32. The pc-relative addressing mode + works nicely as a trigger for V10. + FIXME: Have specific V32 template (possibly avoiding the + use of a special instruction). */ + fprintf (f, "\tclearf x\n"); + /* We have to use a register as an intermediate, choosing + semi-randomly R1 (which has to not be the STATIC_CHAIN_REGNUM), + so we can use it for address indirection and jsr target. */ + fprintf (f, "\tmove $r1,$mof\n"); + /* +4 */ + fprintf (f, "\tmove.d 0,$r1\n"); + fprintf (f, "\tmove.d $%s,[$r1]\n", reg_names[STATIC_CHAIN_REGNUM]); + fprintf (f, "\taddq 6,$r1\n"); + fprintf (f, "\tmove $mof,[$r1]\n"); + fprintf (f, "\taddq 6,$r1\n"); + fprintf (f, "\tmove $srp,[$r1]\n"); + /* +20 */ + fprintf (f, "\tmove.d 0,$%s\n", reg_names[STATIC_CHAIN_REGNUM]); + /* +26 */ + fprintf (f, "\tmove.d 0,$r1\n"); + fprintf (f, "\tjsr $r1\n"); + fprintf (f, "\tsetf\n"); + /* +36 */ + fprintf (f, "\tmove.d 0,$%s\n", reg_names[STATIC_CHAIN_REGNUM]); + /* +42 */ + fprintf (f, "\tmove.d 0,$r1\n"); + /* +48 */ + fprintf (f, "\tmove.d 0,$r9\n"); + fprintf (f, "\tjump $r9\n"); + fprintf (f, "\tsetf\n"); + } + else + { + fprintf (f, "\tmove.d $%s,[$pc+20]\n", reg_names[STATIC_CHAIN_REGNUM]); + fprintf (f, "\tmove $srp,[$pc+22]\n"); + fprintf (f, "\tmove.d 0,$%s\n", reg_names[STATIC_CHAIN_REGNUM]); + fprintf (f, "\tjsr 0\n"); + fprintf (f, "\tmove.d 0,$%s\n", reg_names[STATIC_CHAIN_REGNUM]); + fprintf (f, "\tjump 0\n"); + } +} + +/* Implement TARGET_TRAMPOLINE_INIT. */ + +static void +cris_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value) +{ + rtx fnaddr = XEXP (DECL_RTL (fndecl), 0); + rtx tramp = XEXP (m_tramp, 0); + rtx mem; + + emit_block_move (m_tramp, assemble_trampoline_template (), + GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL); + + if (TARGET_V32) + { + mem = adjust_address (m_tramp, SImode, 6); + emit_move_insn (mem, plus_constant (tramp, 38)); + mem = adjust_address (m_tramp, SImode, 22); + emit_move_insn (mem, chain_value); + mem = adjust_address (m_tramp, SImode, 28); + emit_move_insn (mem, fnaddr); + } + else + { + mem = adjust_address (m_tramp, SImode, 10); + emit_move_insn (mem, chain_value); + mem = adjust_address (m_tramp, SImode, 16); + emit_move_insn (mem, fnaddr); + } + + /* Note that there is no need to do anything with the cache for + sake of a trampoline. */ +} + + #if 0 /* Various small functions to replace macros. Only called from a debugger. They might collide with gcc functions or system functions, diff --git a/gcc/config/cris/cris.h b/gcc/config/cris/cris.h index 3929107..586f7ff 100644 --- a/gcc/config/cris/cris.h +++ b/gcc/config/cris/cris.h @@ -935,108 +935,11 @@ struct cum_args {int regs;}; /* Node: Trampolines */ -/* This looks too complicated, and it is. I assigned r7 to be the - static chain register, but it is call-saved, so we have to save it, - and come back to restore it after the call, so we have to save srp... - Anyway, trampolines are rare enough that we can cope with this - somewhat lack of elegance. - (Do not be tempted to "straighten up" whitespace in the asms; the - assembler #NO_APP state mandates strict spacing). */ -#define TRAMPOLINE_TEMPLATE(FILE) \ - do \ - { \ - if (TARGET_V32) \ - { \ - /* This normally-unused nop insn acts as an instruction to \ - the simulator to flush its instruction cache. None of \ - the other instructions in the trampoline template suits \ - as a trigger for V32. The pc-relative addressing mode \ - works nicely as a trigger for V10. \ - FIXME: Have specific V32 template (possibly avoiding the \ - use of a special instruction). */ \ - fprintf (FILE, "\tclearf x\n"); \ - /* We have to use a register as an intermediate, choosing \ - semi-randomly R1 (which has to not be the \ - STATIC_CHAIN_REGNUM), so we can use it for address \ - indirection and jsr target. */ \ - fprintf (FILE, "\tmove $r1,$mof\n"); \ - /* +4 */ \ - fprintf (FILE, "\tmove.d 0,$r1\n"); \ - fprintf (FILE, "\tmove.d $%s,[$r1]\n", \ - reg_names[STATIC_CHAIN_REGNUM]); \ - fprintf (FILE, "\taddq 6,$r1\n"); \ - fprintf (FILE, "\tmove $mof,[$r1]\n"); \ - fprintf (FILE, "\taddq 6,$r1\n"); \ - fprintf (FILE, "\tmove $srp,[$r1]\n"); \ - /* +20 */ \ - fprintf (FILE, "\tmove.d 0,$%s\n", \ - reg_names[STATIC_CHAIN_REGNUM]); \ - /* +26 */ \ - fprintf (FILE, "\tmove.d 0,$r1\n"); \ - fprintf (FILE, "\tjsr $r1\n"); \ - fprintf (FILE, "\tsetf\n"); \ - /* +36 */ \ - fprintf (FILE, "\tmove.d 0,$%s\n", \ - reg_names[STATIC_CHAIN_REGNUM]); \ - /* +42 */ \ - fprintf (FILE, "\tmove.d 0,$r1\n"); \ - /* +48 */ \ - fprintf (FILE, "\tmove.d 0,$r9\n"); \ - fprintf (FILE, "\tjump $r9\n"); \ - fprintf (FILE, "\tsetf\n"); \ - } \ - else \ - { \ - fprintf (FILE, "\tmove.d $%s,[$pc+20]\n", \ - reg_names[STATIC_CHAIN_REGNUM]); \ - fprintf (FILE, "\tmove $srp,[$pc+22]\n"); \ - fprintf (FILE, "\tmove.d 0,$%s\n", \ - reg_names[STATIC_CHAIN_REGNUM]); \ - fprintf (FILE, "\tjsr 0\n"); \ - fprintf (FILE, "\tmove.d 0,$%s\n", \ - reg_names[STATIC_CHAIN_REGNUM]); \ - fprintf (FILE, "\tjump 0\n"); \ - } \ - } \ - while (0) - #define TRAMPOLINE_SIZE (TARGET_V32 ? 58 : 32) -/* CRIS wants instructions on word-boundary. - Note that due to a bug (reported) in 2.7.2 and earlier, this is - actually treated as alignment in _bytes_, not _bits_. (Obviously - this is not fatal, only a slight waste of stack space). */ +/* CRIS wants instructions on word-boundary. */ #define TRAMPOLINE_ALIGNMENT 16 -#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \ - do \ - if (TARGET_V32) \ - { \ - emit_move_insn (gen_rtx_MEM (SImode, \ - plus_constant (TRAMP, 6)), \ - plus_constant (TRAMP, 38)); \ - emit_move_insn (gen_rtx_MEM (SImode, \ - plus_constant (TRAMP, 22)), \ - CXT); \ - emit_move_insn (gen_rtx_MEM (SImode, \ - plus_constant (TRAMP, 28)), \ - FNADDR); \ - } \ - else \ - { \ - emit_move_insn (gen_rtx_MEM (SImode, \ - plus_constant (TRAMP, 10)), \ - CXT); \ - emit_move_insn (gen_rtx_MEM (SImode, \ - plus_constant (TRAMP, 16)), \ - FNADDR); \ - } \ - while (0) - -/* Note that there is no need to do anything with the cache for sake of - a trampoline. */ - - /* Node: Library Calls */ /* If you change this, you have to check whatever libraries and systems |