Commit e9ad4573 by Jeffrey A Law Committed by Jeff Law

mn10300.c (symbolic_operand, [...]): New functions.

        * mn10300.c (symbolic_operand, legitimize_address): New functions.
        * mn10300.h (LEGITIMIZE_ADDRESS): Call legitimize_address.
        (GO_IF_LEGITIMATE_ADDRESS): Don't allow base + symbolic.

From-SVN: r16158
parent 66724f0a
Fri Oct 24 13:19:40 1997 Jeffrey A Law (law@cygnus.com)
* mn10300.c (symbolic_operand, legitimize_address): New functions.
* mn10300.h (LEGITIMIZE_ADDRESS): Call legitimize_address.
(GO_IF_LEGITIMATE_ADDRESS): Don't allow base + symbolic.
Thu Oct 23 09:35:12 1997 Jeffrey A Law (law@cygnus.com)
* version.c: Bump for snapshot.
......
......@@ -989,3 +989,72 @@ impossible_plus_operand (op, mode)
return 0;
}
/* Return 1 if X contains a symbolic expression. We know these
expressions will have one of a few well defined forms, so
we need only check those forms. */
int
symbolic_operand (op, mode)
register rtx op;
enum machine_mode mode;
{
switch (GET_CODE (op))
{
case SYMBOL_REF:
case LABEL_REF:
return 1;
case CONST:
op = XEXP (op, 0);
return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
|| GET_CODE (XEXP (op, 0)) == LABEL_REF)
&& GET_CODE (XEXP (op, 1)) == CONST_INT);
default:
return 0;
}
}
/* Try machine dependent ways of modifying an illegitimate address
to be legitimate. If we find one, return the new valid address.
This macro is used in only one place: `memory_address' in explow.c.
OLDX is the address as it was before break_out_memory_refs was called.
In some cases it is useful to look at this to decide what needs to be done.
MODE and WIN are passed so that this macro can use
GO_IF_LEGITIMATE_ADDRESS.
Normally it is always safe for this macro to do nothing. It exists to
recognize opportunities to optimize the output.
But on a few ports with segmented architectures and indexed addressing
(mn10300, hppa) it is used to rewrite certain problematical addresses. */
rtx
legitimize_address (x, oldx, mode)
rtx x;
rtx oldx;
enum machine_mode mode;
{
/* Uh-oh. We might have an address for x[n-100000]. This needs
special handling to avoid creating an indexed memory address
with x-100000 as the base. */
if (GET_CODE (x) == PLUS
&& symbolic_operand (XEXP (x, 1), VOIDmode))
{
/* Ugly. We modify things here so that the address offset specified
by the index expression is computed first, then added to x to form
the entire address. */
rtx regx1, regx2, regy1, regy2, y;
/* Strip off any CONST. */
y = XEXP (x, 1);
if (GET_CODE (y) == CONST)
y = XEXP (y, 0);
regx1 = force_reg (Pmode, force_operand (XEXP (x, 0), 0));
regy1 = force_reg (Pmode, force_operand (XEXP (y, 0), 0));
regy2 = force_reg (Pmode, force_operand (XEXP (y, 1), 0));
regx1 = force_reg (Pmode, gen_rtx (GET_CODE (y), Pmode, regx1, regy2));
return force_reg (Pmode, gen_rtx (PLUS, Pmode, regx1, regy1));
}
}
......@@ -661,7 +661,7 @@ extern struct rtx_def *mn10300_builtin_saveregs ();
base = XEXP (X, 1), index = XEXP (X, 0); \
if (base != 0 && index != 0) \
{ \
if (CONSTANT_ADDRESS_P (index)) \
if (GET_CODE (index) == CONST_INT) \
goto ADDR; \
if (REG_P (index) \
&& REG_OK_FOR_INDEX_P (index) \
......@@ -685,7 +685,12 @@ extern struct rtx_def *mn10300_builtin_saveregs ();
It is always safe for this macro to do nothing. It exists to recognize
opportunities to optimize the output. */
#define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN) {}
extern struct rtx_def *legitimize_address ();
#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \
{ rtx orig_x = (X); \
(X) = legitimize_address (X, OLDX, MODE); \
if ((X) != orig_x && memory_address_p (MODE, X)) \
goto WIN; }
/* Go to LABEL if ADDR (a legitimate address expression)
has an effect that depends on the machine mode it is used for. */
......@@ -998,3 +1003,4 @@ extern int impossible_plus_operand ();
extern enum reg_class secondary_reload_class ();
extern int initial_offset ();
extern char *output_tst ();
int symbolic_operand ();
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment