aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorHans-Peter Nilsson <hp@axis.com>2005-11-12 21:09:11 +0000
committerHans-Peter Nilsson <hp@gcc.gnu.org>2005-11-12 21:09:11 +0000
commit15883505db0cb4d65a8ecda425569bd8919d5c3d (patch)
treee7ee182f6820106fbb98676bccaca43c17cc1e30 /gcc
parent73bebd55f00bd2b0c8e210c2fdd224b3987be7cd (diff)
downloadgcc-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/ChangeLog8
-rw-r--r--gcc/config/cris/cris-protos.h1
-rw-r--r--gcc/config/cris/cris.c78
-rw-r--r--gcc/config/cris/cris.h9
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) \