move alpha legitimize macros
Richard Henderson
rth@redhat.com
Tue Sep 4 22:57:00 GMT 2001
Moving some largish bits out of line. No functionality change.
r~
* reload.c (push_reload): Export.
* reload.h (push_reload): Declare it.
* config/alpha/alpha.h (LEGITIMIZE_ADDRESS): Move out o' line.
(LEGITIMIZE_RELOAD_ADDRESS): Likewise.
* config/alpha/alpha.c (alpha_legitimize_address): New.
(alpha_legitimize_reload_address): Likewise.
* config/alpha/alpha-protos.h: Declare them.
Index: reload.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/reload.c,v
retrieving revision 1.159
diff -c -p -d -r1.159 reload.c
*** reload.c 2001/08/31 14:49:31 1.159
--- reload.c 2001/09/05 05:48:20
*************** static int push_secondary_reload PARAMS
*** 242,250 ****
#endif
static enum reg_class find_valid_class PARAMS ((enum machine_mode, int));
static int reload_inner_reg_of_subreg PARAMS ((rtx, enum machine_mode));
- static int push_reload PARAMS ((rtx, rtx, rtx *, rtx *, enum reg_class,
- enum machine_mode, enum machine_mode,
- int, int, int, enum reload_type));
static void push_replacement PARAMS ((rtx *, int, enum machine_mode));
static void combine_reloads PARAMS ((void));
static int find_reusable_reload PARAMS ((rtx *, rtx, enum reg_class,
--- 242,247 ----
*************** reload_inner_reg_of_subreg (x, mode)
*** 845,851 ****
the two reload-numbers are equal, but the caller should be careful to
distinguish them. */
! static int
push_reload (in, out, inloc, outloc, class,
inmode, outmode, strict_low, optional, opnum, type)
rtx in, out;
--- 842,848 ----
the two reload-numbers are equal, but the caller should be careful to
distinguish them. */
! int
push_reload (in, out, inloc, outloc, class,
inmode, outmode, strict_low, optional, opnum, type)
rtx in, out;
Index: reload.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/reload.h,v
retrieving revision 1.36
diff -c -p -d -r1.36 reload.h
*** reload.h 2001/08/22 14:35:33 1.36
--- reload.h 2001/09/05 05:48:20
*************** extern int regno_clobbered_p PARAMS ((un
*** 331,337 ****
int));
/* Return 1 if X is an operand of an insn that is being earlyclobbered. */
! int earlyclobber_operand_p PARAMS ((rtx));
/* Functions in reload1.c: */
--- 331,342 ----
int));
/* Return 1 if X is an operand of an insn that is being earlyclobbered. */
! extern int earlyclobber_operand_p PARAMS ((rtx));
!
! /* Record one reload that needs to be performed. */
! extern int push_reload PARAMS ((rtx, rtx, rtx *, rtx *, enum reg_class,
! enum machine_mode, enum machine_mode,
! int, int, int, enum reload_type));
/* Functions in reload1.c: */
Index: config/alpha/alpha-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/alpha/alpha-protos.h,v
retrieving revision 1.20
diff -c -p -d -r1.20 alpha-protos.h
*** alpha-protos.h 2001/08/18 20:25:50 1.20
--- alpha-protos.h 2001/09/05 05:48:20
*************** extern int addition_operation PARAMS ((r
*** 72,77 ****
--- 72,82 ----
extern rtx alpha_tablejump_addr_vec PARAMS ((rtx));
extern rtx alpha_tablejump_best_label PARAMS ((rtx));
+
+ extern rtx alpha_legitimize_address PARAMS ((rtx, rtx, enum machine_mode));
+ extern rtx alpha_legitimize_reload_address PARAMS ((rtx, enum machine_mode,
+ int, int, int));
+
extern void get_aligned_mem PARAMS ((rtx, rtx *, rtx *));
extern rtx get_unaligned_address PARAMS ((rtx, int));
extern enum reg_class secondary_reload_class PARAMS ((enum reg_class,
Index: config/alpha/alpha.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/alpha/alpha.c,v
retrieving revision 1.184
diff -c -p -d -r1.184 alpha.c
*** alpha.c 2001/08/18 20:25:50 1.184
--- alpha.c 2001/09/05 05:48:20
*************** Boston, MA 02111-1307, USA. */
*** 42,49 ****
#include "function.h"
#include "toplev.h"
#include "ggc.h"
- #include "tm_p.h"
#include "integrate.h"
#include "target.h"
#include "target-def.h"
--- 42,49 ----
#include "function.h"
#include "toplev.h"
#include "ggc.h"
#include "integrate.h"
+ #include "tm_p.h"
#include "target.h"
#include "target-def.h"
*************** alpha_tablejump_best_label (insn)
*** 1152,1157 ****
--- 1152,1280 ----
}
return best_label ? best_label : const0_rtx;
+ }
+
+ /* Try machine-dependent ways of modifying an illegitimate address
+ to be legitimate. If we find one, return the new, valid address. */
+
+ rtx
+ alpha_legitimize_address (x, oldx, mode)
+ rtx x;
+ rtx oldx ATTRIBUTE_UNUSED;
+ enum machine_mode mode ATTRIBUTE_UNUSED;
+ {
+ HOST_WIDE_INT addend;
+
+ /* If the address is (plus reg const_int) and the CONST_INT is not a
+ valid offset, compute the high part of the constant and add it to
+ the register. Then our address is (plus temp low-part-const). */
+ if (GET_CODE (x) == PLUS
+ && GET_CODE (XEXP (x, 0)) == REG
+ && GET_CODE (XEXP (x, 1)) == CONST_INT
+ && ! CONSTANT_ADDRESS_P (XEXP (x, 1)))
+ {
+ addend = INTVAL (XEXP (x, 1));
+ x = XEXP (x, 0);
+ goto split_addend;
+ }
+
+ /* If the address is (const (plus FOO const_int)), find the low-order
+ part of the CONST_INT. Then load FOO plus any high-order part of the
+ CONST_INT into a register. Our address is (plus reg low-part-const).
+ This is done to reduce the number of GOT entries. */
+ if (GET_CODE (x) == CONST
+ && GET_CODE (XEXP (x, 0)) == PLUS
+ && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)
+ {
+ addend = INTVAL (XEXP (XEXP (x, 0), 1));
+ x = force_reg (Pmode, XEXP (XEXP (x, 0), 0));
+ goto split_addend;
+ }
+
+ /* If we have a (plus reg const), emit the load as in (2), then add
+ the two registers, and finally generate (plus reg low-part-const) as
+ our address. */
+ if (GET_CODE (x) == PLUS
+ && GET_CODE (XEXP (x, 0)) == REG
+ && GET_CODE (XEXP (x, 1)) == CONST
+ && GET_CODE (XEXP (XEXP (x, 1), 0)) == PLUS
+ && GET_CODE (XEXP (XEXP (XEXP (x, 1), 0), 1)) == CONST_INT)
+ {
+ addend = INTVAL (XEXP (XEXP (XEXP (x, 1), 0), 1));
+ x = expand_simple_binop (Pmode, PLUS, XEXP (x, 0),
+ XEXP (XEXP (XEXP (x, 1), 0), 0),
+ NULL_RTX, 1, OPTAB_LIB_WIDEN);
+ goto split_addend;
+ }
+
+ return NULL;
+
+ split_addend:
+ {
+ HOST_WIDE_INT lowpart = (addend & 0xffff) - 2 * (addend & 0x8000);
+ HOST_WIDE_INT highpart = addend - lowpart;
+ x = expand_simple_binop (Pmode, PLUS, x, GEN_INT (highpart),
+ NULL_RTX, 1, OPTAB_LIB_WIDEN);
+ return plus_constant (x, lowpart);
+ }
+ }
+
+ /* Try a machine-dependent way of reloading an illegitimate address
+ operand. If we find one, push the reload and return the new rtx. */
+
+ rtx
+ alpha_legitimize_reload_address (x, mode, opnum, type, ind_levels)
+ rtx x;
+ enum machine_mode mode ATTRIBUTE_UNUSED;
+ int opnum;
+ int type;
+ int ind_levels ATTRIBUTE_UNUSED;
+ {
+ /* We must recognize output that we have already generated ourselves. */
+ if (GET_CODE (x) == PLUS
+ && GET_CODE (XEXP (x, 0)) == PLUS
+ && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
+ && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
+ && GET_CODE (XEXP (x, 1)) == CONST_INT)
+ {
+ push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
+ BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
+ opnum, type);
+ return x;
+ }
+
+ /* We wish to handle large displacements off a base register by
+ splitting the addend across an ldah and the mem insn. This
+ cuts number of extra insns needed from 3 to 1. */
+ if (GET_CODE (x) == PLUS
+ && GET_CODE (XEXP (x, 0)) == REG
+ && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
+ && REGNO_OK_FOR_BASE_P (REGNO (XEXP (x, 0)))
+ && GET_CODE (XEXP (x, 1)) == CONST_INT)
+ {
+ HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
+ HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
+ HOST_WIDE_INT high
+ = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
+
+ /* Check for 32-bit overflow. */
+ if (high + low != val)
+ return NULL_RTX;
+
+ /* Reload the high part into a base reg; leave the low part
+ in the mem directly. */
+ x = gen_rtx_PLUS (GET_MODE (x),
+ gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
+ GEN_INT (high)),
+ GEN_INT (low));
+
+ push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
+ BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
+ opnum, type);
+ return x;
+ }
+
+ return NULL_RTX;
}
/* REF is an alignable memory location. Place an aligned SImode
Index: config/alpha/alpha.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/alpha/alpha.h,v
retrieving revision 1.129
diff -c -p -d -r1.129 alpha.h
*** alpha.h 2001/08/21 12:17:28 1.129
--- alpha.h 2001/09/05 05:48:21
*************** do { \
*** 1460,1581 ****
GO_IF_LEGITIMATE_ADDRESS.
It is always safe for this macro to do nothing. It exists to recognize
! opportunities to optimize the output.
!
! For the Alpha, there are three cases we handle:
!
! (1) If the address is (plus reg const_int) and the CONST_INT is not a
! valid offset, compute the high part of the constant and add it to the
! register. Then our address is (plus temp low-part-const).
! (2) If the address is (const (plus FOO const_int)), find the low-order
! part of the CONST_INT. Then load FOO plus any high-order part of the
! CONST_INT into a register. Our address is (plus reg low-part-const).
! This is done to reduce the number of GOT entries.
! (3) If we have a (plus reg const), emit the load as in (2), then add
! the two registers, and finally generate (plus reg low-part-const) as
! our address. */
! #define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN) \
! { if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 0)) == REG \
! && GET_CODE (XEXP (X, 1)) == CONST_INT \
! && ! CONSTANT_ADDRESS_P (XEXP (X, 1))) \
! { \
! HOST_WIDE_INT val = INTVAL (XEXP (X, 1)); \
! HOST_WIDE_INT lowpart = (val & 0xffff) - 2 * (val & 0x8000); \
! HOST_WIDE_INT highpart = val - lowpart; \
! rtx high = GEN_INT (highpart); \
! rtx temp = expand_binop (Pmode, add_optab, XEXP (x, 0), \
! high, NULL_RTX, 1, OPTAB_LIB_WIDEN); \
! \
! (X) = plus_constant (temp, lowpart); \
! goto WIN; \
! } \
! else if (GET_CODE (X) == CONST \
! && GET_CODE (XEXP (X, 0)) == PLUS \
! && GET_CODE (XEXP (XEXP (X, 0), 1)) == CONST_INT) \
! { \
! HOST_WIDE_INT val = INTVAL (XEXP (XEXP (X, 0), 1)); \
! HOST_WIDE_INT lowpart = (val & 0xffff) - 2 * (val & 0x8000); \
! HOST_WIDE_INT highpart = val - lowpart; \
! rtx high = XEXP (XEXP (X, 0), 0); \
! \
! if (highpart) \
! high = plus_constant (high, highpart); \
! \
! (X) = plus_constant (force_reg (Pmode, high), lowpart); \
! goto WIN; \
! } \
! else if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 0)) == REG \
! && GET_CODE (XEXP (X, 1)) == CONST \
! && GET_CODE (XEXP (XEXP (X, 1), 0)) == PLUS \
! && GET_CODE (XEXP (XEXP (XEXP (X, 1), 0), 1)) == CONST_INT) \
! { \
! HOST_WIDE_INT val = INTVAL (XEXP (XEXP (XEXP (X, 1), 0), 1)); \
! HOST_WIDE_INT lowpart = (val & 0xffff) - 2 * (val & 0x8000); \
! HOST_WIDE_INT highpart = val - lowpart; \
! rtx high = XEXP (XEXP (XEXP (X, 1), 0), 0); \
! \
! if (highpart) \
! high = plus_constant (high, highpart); \
! \
! high = expand_binop (Pmode, add_optab, XEXP (X, 0), \
! force_reg (Pmode, high), \
! high, 1, OPTAB_LIB_WIDEN); \
! (X) = plus_constant (high, lowpart); \
! goto WIN; \
! } \
! }
/* Try a machine-dependent way of reloading an illegitimate address
operand. If we find one, push the reload and jump to WIN. This
! macro is used in only one place: `find_reloads_address' in reload.c.
!
! For the Alpha, we wish to handle large displacements off a base
! register by splitting the addend across an ldah and the mem insn.
! This cuts number of extra insns needed from 3 to 1. */
! #define LEGITIMIZE_RELOAD_ADDRESS(X,MODE,OPNUM,TYPE,IND_LEVELS,WIN) \
! do { \
! /* We must recognize output that we have already generated ourselves. */ \
! if (GET_CODE (X) == PLUS \
! && GET_CODE (XEXP (X, 0)) == PLUS \
! && GET_CODE (XEXP (XEXP (X, 0), 0)) == REG \
! && GET_CODE (XEXP (XEXP (X, 0), 1)) == CONST_INT \
! && GET_CODE (XEXP (X, 1)) == CONST_INT) \
! { \
! push_reload (XEXP (X, 0), NULL_RTX, &XEXP (X, 0), NULL, \
! BASE_REG_CLASS, GET_MODE (X), VOIDmode, 0, 0, \
! OPNUM, TYPE); \
! goto WIN; \
! } \
! if (GET_CODE (X) == PLUS \
! && GET_CODE (XEXP (X, 0)) == REG \
! && REGNO (XEXP (X, 0)) < FIRST_PSEUDO_REGISTER \
! && REG_MODE_OK_FOR_BASE_P (XEXP (X, 0), MODE) \
! && GET_CODE (XEXP (X, 1)) == CONST_INT) \
! { \
! HOST_WIDE_INT val = INTVAL (XEXP (X, 1)); \
! HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000; \
! HOST_WIDE_INT high \
! = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000; \
! \
! /* Check for 32-bit overflow. */ \
! if (high + low != val) \
! break; \
! \
! /* Reload the high part into a base reg; leave the low part \
! in the mem directly. */ \
! \
! X = gen_rtx_PLUS (GET_MODE (X), \
! gen_rtx_PLUS (GET_MODE (X), XEXP (X, 0), \
! GEN_INT (high)), \
! GEN_INT (low)); \
! \
! push_reload (XEXP (X, 0), NULL_RTX, &XEXP (X, 0), NULL, \
! BASE_REG_CLASS, GET_MODE (X), VOIDmode, 0, 0, \
! OPNUM, TYPE); \
! goto WIN; \
! } \
} while (0)
/* Go to LABEL if ADDR (a legitimate address expression)
--- 1460,1489 ----
GO_IF_LEGITIMATE_ADDRESS.
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) \
! do { \
! rtx new_x = alpha_legitimize_address (X, OLDX, MODE); \
! if (new_x) \
! { \
! X = new_x; \
! goto WIN; \
! } \
! } while (0)
/* Try a machine-dependent way of reloading an illegitimate address
operand. If we find one, push the reload and jump to WIN. This
! macro is used in only one place: `find_reloads_address' in reload.c. */
! #define LEGITIMIZE_RELOAD_ADDRESS(X,MODE,OPNUM,TYPE,IND_L,WIN) \
! do { \
! rtx new_x = alpha_legitimize_reload_address (X, MODE, OPNUM, TYPE, IND_L); \
! if (new_x) \
! { \
! X = new_x; \
! goto WIN; \
! } \
} while (0)
/* Go to LABEL if ADDR (a legitimate address expression)
More information about the Gcc-patches
mailing list