diff options
author | Hans-Peter Nilsson <hp@axis.com> | 2005-11-12 21:09:11 +0000 |
---|---|---|
committer | Hans-Peter Nilsson <hp@gcc.gnu.org> | 2005-11-12 21:09:11 +0000 |
commit | 15883505db0cb4d65a8ecda425569bd8919d5c3d (patch) | |
tree | e7ee182f6820106fbb98676bccaca43c17cc1e30 /gcc | |
parent | 73bebd55f00bd2b0c8e210c2fdd224b3987be7cd (diff) | |
download | gcc-15883505db0cb4d65a8ecda425569bd8919d5c3d.zip gcc-15883505db0cb4d65a8ecda425569bd8919d5c3d.tar.gz gcc-15883505db0cb4d65a8ecda425569bd8919d5c3d.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/config/cris/cris-protos.h | 1 | ||||
-rw-r--r-- | gcc/config/cris/cris.c | 78 | ||||
-rw-r--r-- | gcc/config/cris/cris.h | 9 |
4 files changed, 95 insertions, 1 deletions
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 <hp@axis.com> + + * 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 <rguenther@suse.de> * 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) \ |