aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Law <law@gcc.gnu.org>1993-01-14 14:50:18 -0700
committerJeff Law <law@gcc.gnu.org>1993-01-14 14:50:18 -0700
commitf014712100a9e119aa1c892a0a8227dda45816cc (patch)
tree254a469778e09156c5e25c2154e9ee5000aeff6f
parentba1811f11fe84a6d13d47e898f08fb38dedb91da (diff)
downloadgcc-f014712100a9e119aa1c892a0a8227dda45816cc.zip
gcc-f014712100a9e119aa1c892a0a8227dda45816cc.tar.gz
gcc-f014712100a9e119aa1c892a0a8227dda45816cc.tar.bz2
pa.h (LEGITIMIZE_ADDRESS): Rework to create REG or REG+D addresses instead of REG+REG addresses.
* pa.h (LEGITIMIZE_ADDRESS): Rework to create REG or REG+D addresses instead of REG+REG addresses. From-SVN: r3243
-rw-r--r--gcc/config/pa/pa.h55
1 files changed, 43 insertions, 12 deletions
diff --git a/gcc/config/pa/pa.h b/gcc/config/pa/pa.h
index 0e44427..1c26ff7 100644
--- a/gcc/config/pa/pa.h
+++ b/gcc/config/pa/pa.h
@@ -1232,23 +1232,54 @@ extern union tree_node *current_function_decl;
GO_IF_LEGITIMATE_ADDRESS.
It is always safe for this macro to do nothing. It exists to recognize
- opportunities to optimize the output. */
+ opportunities to optimize the output.
-/* On the HP-PA, change REG+N into REG+REG, and REG+(X*Y) into REG+REG. */
+ For the PA, transform:
+
+ memory(X + <large int>)
+
+ into:
+
+ Y = <large int> & ~mask;
+ Z = X + Y
+ memory (Z + (<large int> & mask));
+
+ This is for CSE to find several similar references, and only use one Z.
+
+ MODE_FLOAT references allow displacements which fit in 5 bits, so use
+ 0xf as the mask.
+
+ MODE_INT references allow displacements which fit in 11 bits, so use
+ 0x1fff as the mask.
+
+ This relies on the fact that most mode MODE_FLOAT references will use FP
+ registers and most mode MODE_INT references will use integer registers.
+ (In the rare case of an FP register used in an integer MODE, we depend
+ on secondary reloads and the final output pass to clean things up.) */
+
+ Also change REG+(X*Y) into REG. (With X*Y in an extra pseudo). */
#define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN) \
-{ if (GET_CODE (X) == PLUS && CONSTANT_ADDRESS_P (XEXP (X, 1))) \
- (X) = gen_rtx (PLUS, SImode, XEXP (X, 0), \
- copy_to_mode_reg (SImode, XEXP (X, 1))); \
- if (GET_CODE (X) == PLUS && CONSTANT_ADDRESS_P (XEXP (X, 0))) \
- (X) = gen_rtx (PLUS, SImode, XEXP (X, 1), \
- copy_to_mode_reg (SImode, XEXP (X, 0))); \
+{ if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 0)) == REG \
+ && GET_CODE (XEXP (X, 1)) == CONST_INT) \
+ { \
+ rtx int_reg, ptr_reg; \
+ int offset = INTVAL (XEXP (X, 1)); \
+ int mask = GET_MODE_CLASS (mode) == MODE_FLOAT ? 0xf \
+ : 0x1fff; \
+ int_reg = force_reg (SImode, GEN_INT (offset & ~ mask)); \
+ ptr_reg = force_reg (SImode, \
+ gen_rtx (PLUS, SImode, \
+ XEXP (X, 0), int_reg)); \
+ X = plus_constant (ptr_reg, offset & mask); \
+ goto WIN; \
+ } \
if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 0)) == MULT) \
- (X) = gen_rtx (PLUS, SImode, XEXP (X, 1), \
- force_operand (XEXP (X, 0), 0)); \
+ (X) = force_operand (gen_rtx (PLUS, SImode, XEXP (X, 1), \
+ force_operand (XEXP (X, 0), 0)), 0);\
if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 1)) == MULT) \
- (X) = gen_rtx (PLUS, SImode, XEXP (X, 0), \
- force_operand (XEXP (X, 1), 0)); \
+ (X) = force_operand (gen_rtx (PLUS, SImode, XEXP (X, 0), \
+ force_operand (XEXP (X, 1), 0)), 0);\
if (memory_address_p (MODE, X)) \
goto WIN; \
if (flag_pic) (X) = legitimize_pic_address (X, MODE, gen_reg_rtx (Pmode));\