From 15883505db0cb4d65a8ecda425569bd8919d5c3d Mon Sep 17 00:00:00 2001 From: Hans-Peter Nilsson Date: Sat, 12 Nov 2005 21:09:11 +0000 Subject: cris.h (LEGITIMIZE_RELOAD_ADDRESS): Define. * config/cris/cris.h (LEGITIMIZE_RELOAD_ADDRESS): Define. * config/cris/cris.c: Include reload.h. (cris_initial_elimination_offset): New function. * config/cris/cris-protos.h: (cris_initial_elimination_offset): Prototype. From-SVN: r106835 --- gcc/ChangeLog | 8 +++++ gcc/config/cris/cris-protos.h | 1 + gcc/config/cris/cris.c | 78 ++++++++++++++++++++++++++++++++++++++++++- gcc/config/cris/cris.h | 9 +++++ 4 files changed, 95 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 760a639..b29bc2a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2005-11-12 Hans-Peter Nilsson + + * config/cris/cris.h (LEGITIMIZE_RELOAD_ADDRESS): Define. + * config/cris/cris.c: Include reload.h. + (cris_initial_elimination_offset): New function. + * config/cris/cris-protos.h: (cris_initial_elimination_offset): + Prototype. + 2005-11-12 Richard Guenther * gcse.c (find_rtx_in_ldst): Handle NULL pre_ldst_table. diff --git a/gcc/config/cris/cris-protos.h b/gcc/config/cris/cris-protos.h index f95a5d1..50673d9 100644 --- a/gcc/config/cris/cris-protos.h +++ b/gcc/config/cris/cris-protos.h @@ -31,6 +31,7 @@ extern bool cris_simple_epilogue (void); #ifdef RTX_CODE extern const char *cris_op_str (rtx); extern void cris_notice_update_cc (rtx, rtx); +extern bool cris_reload_address_legitimized (rtx, enum machine_mode, int, int, int); extern void cris_print_operand (FILE *, rtx, int); extern void cris_print_operand_address (FILE *, rtx); extern int cris_side_effect_mode_ok (enum rtx_code, rtx *, int, int, diff --git a/gcc/config/cris/cris.c b/gcc/config/cris/cris.c index 4ce3c8b..0c41539 100644 --- a/gcc/config/cris/cris.c +++ b/gcc/config/cris/cris.c @@ -38,6 +38,7 @@ Boston, MA 02110-1301, USA. */ #include "function.h" #include "toplev.h" #include "recog.h" +#include "reload.h" #include "tm_p.h" #include "debug.h" #include "output.h" @@ -1205,6 +1206,81 @@ cris_initial_elimination_offset (int fromreg, int toreg) gcc_unreachable (); } +/* Worker function for LEGITIMIZE_RELOAD_ADDRESS. */ + +bool +cris_reload_address_legitimized (rtx x, + enum machine_mode mode ATTRIBUTE_UNUSED, + int opnum ATTRIBUTE_UNUSED, + int itype, + int ind_levels ATTRIBUTE_UNUSED) +{ + enum reload_type type = itype; + rtx op0, op1; + rtx *op0p; + rtx *op1p; + + if (GET_CODE (x) != PLUS) + return false; + + op0 = XEXP (x, 0); + op0p = &XEXP (x, 0); + op1 = XEXP (x, 1); + op1p = &XEXP (x, 1); + + if (!REG_P (op1)) + return false; + + if (GET_CODE (op0) == SIGN_EXTEND + && GET_CODE (XEXP (op0, 0)) == MEM) + { + rtx op00 = XEXP (op0, 0); + rtx op000 = XEXP (op00, 0); + rtx *op000p = &XEXP (op00, 0); + + if ((GET_MODE (op00) == HImode || GET_MODE (op00) == QImode) + && (REG_P (op000) + || (GET_CODE (op000) == POST_INC && REG_P (XEXP (op000, 0))))) + { + bool something_reloaded = false; + + if (GET_CODE (op000) == POST_INC + && REG_P (XEXP (op000, 0)) + && REGNO (XEXP (op000, 0)) > CRIS_LAST_GENERAL_REGISTER) + /* No, this gets too complicated and is too rare to care + about trying to improve on the general code Here. + As the return-value is an all-or-nothing indicator, we + punt on the other register too. */ + return false; + + if ((REG_P (op000) + && REGNO (op000) > CRIS_LAST_GENERAL_REGISTER)) + { + /* The address of the inner mem is a pseudo or wrong + reg: reload that. */ + push_reload (op000, NULL_RTX, op000p, NULL, GENERAL_REGS, + GET_MODE (x), VOIDmode, 0, 0, opnum, type); + something_reloaded = true; + } + + if (REGNO (op1) > CRIS_LAST_GENERAL_REGISTER) + { + /* Base register is a pseudo or wrong reg: reload it. */ + push_reload (op1, NULL_RTX, op1p, NULL, GENERAL_REGS, + GET_MODE (x), VOIDmode, 0, 0, + opnum, type); + something_reloaded = true; + } + + gcc_assert (something_reloaded); + + return true; + } + } + + return false; +} + /* This function looks into the pattern to see how this insn affects condition codes. @@ -2160,7 +2236,7 @@ cris_asm_output_mi_thunk (FILE *stream, } } -/* Boilerplate emitted at start of file. +/* Boilerplate emitted at start of file. NO_APP *only at file start* means faster assembly. It also means comments are not allowed. In some cases comments will be output diff --git a/gcc/config/cris/cris.h b/gcc/config/cris/cris.h index 0ca52da..0d1d8af 100644 --- a/gcc/config/cris/cris.h +++ b/gcc/config/cris/cris.h @@ -1055,6 +1055,15 @@ struct cum_args {int regs;}; FIXME: Check and adjust for gcc-2.9x. */ #define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) {} +/* Fix reloads known to cause suboptimal spilling. */ +#define LEGITIMIZE_RELOAD_ADDRESS(X, MODE, OPNUM, TYPE, INDL, WIN) \ + do \ + { \ + if (cris_reload_address_legitimized (X, MODE, OPNUM, TYPE, INDL)) \ + goto WIN; \ + } \ + while (0) + /* In CRIS, only the postincrement address mode depends thus, since the increment depends on the size of the operand. */ #define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL) \ -- cgit v1.1