Commit 4d588c14 by Richard Henderson

rs6000.c (constant_pool_expr_p): Make static and return bool.

        * config/rs6000/rs6000.c (constant_pool_expr_p): Make static and
	return bool.
        (toc_relative_expr_p): Likewise.
        (SPE_CONST_OFFSET_OK): Move from rs6000.h.
        (legitimate_constant_pool_address_p): Move from rs6000.h, change
        into a function, downcase all users.
        (legitimate_small_data_p): Likewise.
        (legitimate_offset_address_p): Likewise.
        (legitimate_indexed_address_p): Likewise.
        (legitimate_indirect_address_p): Likewise.
        (legitimate_lo_sum_address_p): Likewise.
        (rs6000_mode_dependent_address): Likewise.
        * rs6000.h (CONSTANT_POOL_EXPR_P, TOC_RELATIVE_EXPR_P): Remove.
        (SPE_CONST_OFFSET_OK, LEGITIMATE_CONSTANT_POOL_ADDRESS_P,
        LEGITIMATE_SMALL_DATA_P, LEGITIMATE_OFFSET_ADDRESS_P,
        LEGITIMATE_INDEXED_ADDRESS_P, LEGITIMATE_INDIRECT_ADDRESS_P,
        LEGITIMATE_LO_SUM_ADDRESS_P): Move into rs6000.c.
        (LEGITIMATE_ADDRESS_INTEGER_P): Remove.
        (GO_IF_MODE_DEPENDENT_ADDRESS): Use rs6000_mode_dependent_address.
        * config/rs6000/rs6000-protos.h: Update.

From-SVN: r66445
parent c3a5317c
2003-05-03 Richard Henderson <rth@redhat.com>
* config/rs6000/rs6000.c (constant_pool_expr_p): Make static and
return bool.
(toc_relative_expr_p): Likewise.
(SPE_CONST_OFFSET_OK): Move from rs6000.h.
(legitimate_constant_pool_address_p): Move from rs6000.h, change
into a function, downcase all users.
(legitimate_small_data_p): Likewise.
(legitimate_offset_address_p): Likewise.
(legitimate_indexed_address_p): Likewise.
(legitimate_indirect_address_p): Likewise.
(legitimate_lo_sum_address_p): Likewise.
(rs6000_mode_dependent_address): Likewise.
* rs6000.h (CONSTANT_POOL_EXPR_P, TOC_RELATIVE_EXPR_P): Remove.
(SPE_CONST_OFFSET_OK, LEGITIMATE_CONSTANT_POOL_ADDRESS_P,
LEGITIMATE_SMALL_DATA_P, LEGITIMATE_OFFSET_ADDRESS_P,
LEGITIMATE_INDEXED_ADDRESS_P, LEGITIMATE_INDIRECT_ADDRESS_P,
LEGITIMATE_LO_SUM_ADDRESS_P): Move into rs6000.c.
(LEGITIMATE_ADDRESS_INTEGER_P): Remove.
(GO_IF_MODE_DEPENDENT_ADDRESS): Use rs6000_mode_dependent_address.
* config/rs6000/rs6000-protos.h: Update.
2003-05-03 Geoffrey Keating <geoffk@apple.com> 2003-05-03 Geoffrey Keating <geoffk@apple.com>
* config/rs6000/rs6000.h (REVERSIBLE_CC_MODE): Define. * config/rs6000/rs6000.h (REVERSIBLE_CC_MODE): Define.
......
...@@ -82,8 +82,7 @@ extern int current_file_function_operand PARAMS ((rtx, enum machine_mode)); ...@@ -82,8 +82,7 @@ extern int current_file_function_operand PARAMS ((rtx, enum machine_mode));
extern int input_operand PARAMS ((rtx, enum machine_mode)); extern int input_operand PARAMS ((rtx, enum machine_mode));
extern int small_data_operand PARAMS ((rtx, enum machine_mode)); extern int small_data_operand PARAMS ((rtx, enum machine_mode));
extern int s8bit_cint_operand PARAMS ((rtx, enum machine_mode)); extern int s8bit_cint_operand PARAMS ((rtx, enum machine_mode));
extern int constant_pool_expr_p PARAMS ((rtx)); extern bool legitimate_constant_pool_address_p PARAMS ((rtx));
extern int toc_relative_expr_p PARAMS ((rtx));
extern int expand_block_move PARAMS ((rtx[])); extern int expand_block_move PARAMS ((rtx[]));
extern int load_multiple_operation PARAMS ((rtx, enum machine_mode)); extern int load_multiple_operation PARAMS ((rtx, enum machine_mode));
extern const char * rs6000_output_load_multiple PARAMS ((rtx[])); extern const char * rs6000_output_load_multiple PARAMS ((rtx[]));
...@@ -131,6 +130,7 @@ extern rtx rs6000_legitimize_address PARAMS ((rtx, rtx, enum machine_mode)); ...@@ -131,6 +130,7 @@ extern rtx rs6000_legitimize_address PARAMS ((rtx, rtx, enum machine_mode));
extern rtx rs6000_legitimize_reload_address PARAMS ((rtx, enum machine_mode, extern rtx rs6000_legitimize_reload_address PARAMS ((rtx, enum machine_mode,
int, int, int, int *)); int, int, int, int *));
extern int rs6000_legitimate_address PARAMS ((enum machine_mode, rtx, int)); extern int rs6000_legitimate_address PARAMS ((enum machine_mode, rtx, int));
extern bool rs6000_mode_dependent_address PARAMS ((rtx));
extern rtx rs6000_return_addr PARAMS ((int, rtx)); extern rtx rs6000_return_addr PARAMS ((int, rtx));
extern void rs6000_output_symbol_ref PARAMS ((FILE*, rtx)); extern void rs6000_output_symbol_ref PARAMS ((FILE*, rtx));
......
...@@ -204,6 +204,13 @@ static unsigned rs6000_hash_constant PARAMS ((rtx)); ...@@ -204,6 +204,13 @@ static unsigned rs6000_hash_constant PARAMS ((rtx));
static unsigned toc_hash_function PARAMS ((const void *)); static unsigned toc_hash_function PARAMS ((const void *));
static int toc_hash_eq PARAMS ((const void *, const void *)); static int toc_hash_eq PARAMS ((const void *, const void *));
static int constant_pool_expr_1 PARAMS ((rtx, int *, int *)); static int constant_pool_expr_1 PARAMS ((rtx, int *, int *));
static bool constant_pool_expr_p PARAMS ((rtx));
static bool toc_relative_expr_p PARAMS ((rtx));
static bool legitimate_small_data_p PARAMS ((enum machine_mode, rtx));
static bool legitimate_offset_address_p PARAMS ((enum machine_mode, rtx, int));
static bool legitimate_indexed_address_p PARAMS ((rtx, int));
static bool legitimate_indirect_address_p PARAMS ((rtx, int));
static bool legitimate_lo_sum_address_p PARAMS ((enum machine_mode, rtx, int));
static struct machine_function * rs6000_init_machine_status PARAMS ((void)); static struct machine_function * rs6000_init_machine_status PARAMS ((void));
static bool rs6000_assemble_integer PARAMS ((rtx, unsigned int, int)); static bool rs6000_assemble_integer PARAMS ((rtx, unsigned int, int));
#ifdef HAVE_GAS_HIDDEN #ifdef HAVE_GAS_HIDDEN
...@@ -2154,11 +2161,11 @@ input_operand (op, mode) ...@@ -2154,11 +2161,11 @@ input_operand (op, mode)
return 1; return 1;
/* A SYMBOL_REF referring to the TOC is valid. */ /* A SYMBOL_REF referring to the TOC is valid. */
if (LEGITIMATE_CONSTANT_POOL_ADDRESS_P (op)) if (legitimate_constant_pool_address_p (op))
return 1; return 1;
/* A constant pool expression (relative to the TOC) is valid */ /* A constant pool expression (relative to the TOC) is valid */
if (TOC_RELATIVE_EXPR_P (op)) if (toc_relative_expr_p (op))
return 1; return 1;
/* V.4 allows SYMBOL_REFs and CONSTs that are in the small data region /* V.4 allows SYMBOL_REFs and CONSTs that are in the small data region
...@@ -2216,6 +2223,8 @@ small_data_operand (op, mode) ...@@ -2216,6 +2223,8 @@ small_data_operand (op, mode)
#endif #endif
} }
/* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address. */
static int static int
constant_pool_expr_1 (op, have_sym, have_toc) constant_pool_expr_1 (op, have_sym, have_toc)
rtx op; rtx op;
...@@ -2255,7 +2264,7 @@ constant_pool_expr_1 (op, have_sym, have_toc) ...@@ -2255,7 +2264,7 @@ constant_pool_expr_1 (op, have_sym, have_toc)
} }
} }
int static bool
constant_pool_expr_p (op) constant_pool_expr_p (op)
rtx op; rtx op;
{ {
...@@ -2264,7 +2273,7 @@ constant_pool_expr_p (op) ...@@ -2264,7 +2273,7 @@ constant_pool_expr_p (op)
return constant_pool_expr_1 (op, &have_sym, &have_toc) && have_sym; return constant_pool_expr_1 (op, &have_sym, &have_toc) && have_sym;
} }
int static bool
toc_relative_expr_p (op) toc_relative_expr_p (op)
rtx op; rtx op;
{ {
...@@ -2273,6 +2282,155 @@ toc_relative_expr_p (op) ...@@ -2273,6 +2282,155 @@ toc_relative_expr_p (op)
return constant_pool_expr_1 (op, &have_sym, &have_toc) && have_toc; return constant_pool_expr_1 (op, &have_sym, &have_toc) && have_toc;
} }
/* SPE offset addressing is limited to 5-bits worth of double words. */
#define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
bool
legitimate_constant_pool_address_p (x)
rtx x;
{
return (TARGET_TOC
&& GET_CODE (x) == PLUS
&& GET_CODE (XEXP (x, 0)) == REG
&& (TARGET_MINIMAL_TOC || REGNO (XEXP (x, 0)) == TOC_REGISTER)
&& constant_pool_expr_p (XEXP (x, 1)));
}
static bool
legitimate_small_data_p (mode, x)
enum machine_mode mode;
rtx x;
{
return (DEFAULT_ABI == ABI_V4
&& !flag_pic && !TARGET_TOC
&& (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST)
&& small_data_operand (x, mode));
}
static bool
legitimate_offset_address_p (mode, x, strict)
enum machine_mode mode;
rtx x;
int strict;
{
unsigned HOST_WIDE_INT offset, extra;
if (GET_CODE (x) != PLUS)
return false;
if (GET_CODE (XEXP (x, 0)) != REG)
return false;
if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
return false;
if (GET_CODE (XEXP (x, 1)) != CONST_INT)
return false;
offset = INTVAL (XEXP (x, 1));
extra = 0;
switch (mode)
{
case V16QImode:
case V8HImode:
case V4SFmode:
case V4SImode:
/* AltiVec vector modes. Only reg+reg addressing is valid here,
which leaves the only valid constant offset of zero, which by
canonicalization rules is also invalid. */
return false;
case V4HImode:
case V2SImode:
case V1DImode:
case V2SFmode:
/* SPE vector modes. */
return SPE_CONST_OFFSET_OK (offset);
case DFmode:
case DImode:
if (TARGET_32BIT)
extra = 4;
else if (offset & 3)
return false;
break;
case TFmode:
case TImode:
if (TARGET_32BIT)
extra = 12;
else if (offset & 3)
return false;
else
extra = 8;
break;
default:
break;
}
return (offset + extra >= offset) && (offset + extra + 0x8000 < 0x10000);
}
static bool
legitimate_indexed_address_p (x, strict)
rtx x;
int strict;
{
rtx op0, op1;
if (GET_CODE (x) != PLUS)
return false;
op0 = XEXP (x, 0);
op1 = XEXP (x, 1);
if (!REG_P (op0) || !REG_P (op1))
return false;
return ((INT_REG_OK_FOR_BASE_P (op0, strict)
&& INT_REG_OK_FOR_INDEX_P (op1, strict))
|| (INT_REG_OK_FOR_BASE_P (op1, strict)
&& INT_REG_OK_FOR_INDEX_P (op0, strict)));
}
static inline bool
legitimate_indirect_address_p (x, strict)
rtx x;
int strict;
{
return GET_CODE (x) == REG && INT_REG_OK_FOR_BASE_P (x, strict);
}
static bool
legitimate_lo_sum_address_p (mode, x, strict)
enum machine_mode mode;
rtx x;
int strict;
{
if (GET_CODE (x) != LO_SUM)
return false;
if (GET_CODE (XEXP (x, 0)) != REG)
return false;
if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
return false;
x = XEXP (x, 1);
if (TARGET_ELF)
{
if (DEFAULT_ABI != ABI_AIX && flag_pic)
return false;
if (TARGET_TOC)
return false;
if (GET_MODE_NUNITS (mode) != 1)
return false;
if (GET_MODE_BITSIZE (mode) > 32
&& !(TARGET_HARD_FLOAT && TARGET_FPRS && mode == DFmode))
return false;
return CONSTANT_P (x);
}
return false;
}
/* Try machine-dependent ways of modifying an illegitimate address /* Try machine-dependent ways of modifying an illegitimate address
to be legitimate. If we find one, return the new, valid address. to be legitimate. If we find one, return the new, valid address.
This is used from only one place: `memory_address' in explow.c. This is used from only one place: `memory_address' in explow.c.
...@@ -2295,6 +2453,7 @@ toc_relative_expr_p (op) ...@@ -2295,6 +2453,7 @@ toc_relative_expr_p (op)
Then check for the sum of a register and something not constant, try to Then check for the sum of a register and something not constant, try to
load the other things into a register and return the sum. */ load the other things into a register and return the sum. */
rtx rtx
rs6000_legitimize_address (x, oldx, mode) rs6000_legitimize_address (x, oldx, mode)
rtx x; rtx x;
...@@ -2392,7 +2551,7 @@ rs6000_legitimize_address (x, oldx, mode) ...@@ -2392,7 +2551,7 @@ rs6000_legitimize_address (x, oldx, mode)
return gen_rtx_LO_SUM (Pmode, reg, (x)); return gen_rtx_LO_SUM (Pmode, reg, (x));
} }
else if (TARGET_TOC else if (TARGET_TOC
&& CONSTANT_POOL_EXPR_P (x) && constant_pool_expr_p (x)
&& ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode)) && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
{ {
return create_TOC_reference (x); return create_TOC_reference (x);
...@@ -2535,7 +2694,7 @@ rs6000_legitimize_reload_address (x, mode, opnum, type, ind_levels, win) ...@@ -2535,7 +2694,7 @@ rs6000_legitimize_reload_address (x, mode, opnum, type, ind_levels, win)
} }
#endif #endif
if (TARGET_TOC if (TARGET_TOC
&& CONSTANT_POOL_EXPR_P (x) && constant_pool_expr_p (x)
&& ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode)) && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
{ {
(x) = create_TOC_reference (x); (x) = create_TOC_reference (x);
...@@ -2569,17 +2728,17 @@ rs6000_legitimate_address (mode, x, reg_ok_strict) ...@@ -2569,17 +2728,17 @@ rs6000_legitimate_address (mode, x, reg_ok_strict)
rtx x; rtx x;
int reg_ok_strict; int reg_ok_strict;
{ {
if (LEGITIMATE_INDIRECT_ADDRESS_P (x, reg_ok_strict)) if (legitimate_indirect_address_p (x, reg_ok_strict))
return 1; return 1;
if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC) if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
&& !ALTIVEC_VECTOR_MODE (mode) && !ALTIVEC_VECTOR_MODE (mode)
&& !SPE_VECTOR_MODE (mode) && !SPE_VECTOR_MODE (mode)
&& TARGET_UPDATE && TARGET_UPDATE
&& LEGITIMATE_INDIRECT_ADDRESS_P (XEXP (x, 0), reg_ok_strict)) && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
return 1; return 1;
if (LEGITIMATE_SMALL_DATA_P (mode, x)) if (legitimate_small_data_p (mode, x))
return 1; return 1;
if (LEGITIMATE_CONSTANT_POOL_ADDRESS_P (x)) if (legitimate_constant_pool_address_p (x))
return 1; return 1;
/* If not REG_OK_STRICT (before reload) let pass any stack offset. */ /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
if (! reg_ok_strict if (! reg_ok_strict
...@@ -2588,20 +2747,59 @@ rs6000_legitimate_address (mode, x, reg_ok_strict) ...@@ -2588,20 +2747,59 @@ rs6000_legitimate_address (mode, x, reg_ok_strict)
&& XEXP (x, 0) == virtual_stack_vars_rtx && XEXP (x, 0) == virtual_stack_vars_rtx
&& GET_CODE (XEXP (x, 1)) == CONST_INT) && GET_CODE (XEXP (x, 1)) == CONST_INT)
return 1; return 1;
if (LEGITIMATE_OFFSET_ADDRESS_P (mode, x, reg_ok_strict)) if (legitimate_offset_address_p (mode, x, reg_ok_strict))
return 1; return 1;
if (mode != TImode if (mode != TImode
&& ((TARGET_HARD_FLOAT && TARGET_FPRS) && ((TARGET_HARD_FLOAT && TARGET_FPRS)
|| TARGET_POWERPC64 || TARGET_POWERPC64
|| (mode != DFmode && mode != TFmode)) || (mode != DFmode && mode != TFmode))
&& (TARGET_POWERPC64 || mode != DImode) && (TARGET_POWERPC64 || mode != DImode)
&& LEGITIMATE_INDEXED_ADDRESS_P (x, reg_ok_strict)) && legitimate_indexed_address_p (x, reg_ok_strict))
return 1; return 1;
if (LEGITIMATE_LO_SUM_ADDRESS_P (mode, x, reg_ok_strict)) if (legitimate_lo_sum_address_p (mode, x, reg_ok_strict))
return 1; return 1;
return 0; return 0;
} }
/* Go to LABEL if ADDR (a legitimate address expression)
has an effect that depends on the machine mode it is used for.
On the RS/6000 this is true of all integral offsets (since AltiVec
modes don't allow them) or is a pre-increment or decrement.
??? Except that due to conceptual problems in offsettable_address_p
we can't really report the problems of integral offsets. So leave
this assuming that the adjustable offset must be valid for the
sub-words of a TFmode operand, which is what we had before. */
bool
rs6000_mode_dependent_address (addr)
rtx addr;
{
switch (GET_CODE (addr))
{
case PLUS:
if (GET_CODE (XEXP (addr, 1)) == CONST_INT)
{
unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1));
return val + 12 + 0x8000 >= 0x10000;
}
break;
case LO_SUM:
return true;
case PRE_INC:
case PRE_DEC:
return TARGET_UPDATE;
default:
break;
}
return false;
}
/* Try to output insns to set TARGET equal to the constant C if it can /* Try to output insns to set TARGET equal to the constant C if it can
be done in less than N insns. Do all computations in MODE. be done in less than N insns. Do all computations in MODE.
Returns the place where the output has been placed if it can be Returns the place where the output has been placed if it can be
...@@ -2974,7 +3172,7 @@ rs6000_emit_move (dest, source, mode) ...@@ -2974,7 +3172,7 @@ rs6000_emit_move (dest, source, mode)
reference to it. */ reference to it. */
if (TARGET_TOC if (TARGET_TOC
&& GET_CODE (operands[1]) == SYMBOL_REF && GET_CODE (operands[1]) == SYMBOL_REF
&& CONSTANT_POOL_EXPR_P (operands[1]) && constant_pool_expr_p (operands[1])
&& ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]), && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
get_pool_mode (operands[1]))) get_pool_mode (operands[1])))
{ {
...@@ -2989,8 +3187,8 @@ rs6000_emit_move (dest, source, mode) ...@@ -2989,8 +3187,8 @@ rs6000_emit_move (dest, source, mode)
|| (GET_CODE (operands[0]) == REG || (GET_CODE (operands[0]) == REG
&& FP_REGNO_P (REGNO (operands[0])))) && FP_REGNO_P (REGNO (operands[0]))))
&& GET_CODE (operands[1]) != HIGH && GET_CODE (operands[1]) != HIGH
&& ! LEGITIMATE_CONSTANT_POOL_ADDRESS_P (operands[1]) && ! legitimate_constant_pool_address_p (operands[1])
&& ! TOC_RELATIVE_EXPR_P (operands[1])) && ! toc_relative_expr_p (operands[1]))
{ {
/* Emit a USE operation so that the constant isn't deleted if /* Emit a USE operation so that the constant isn't deleted if
expensive optimizations are turned on because nobody expensive optimizations are turned on because nobody
...@@ -3041,7 +3239,7 @@ rs6000_emit_move (dest, source, mode) ...@@ -3041,7 +3239,7 @@ rs6000_emit_move (dest, source, mode)
operands[1] = force_const_mem (mode, operands[1]); operands[1] = force_const_mem (mode, operands[1]);
if (TARGET_TOC if (TARGET_TOC
&& CONSTANT_POOL_EXPR_P (XEXP (operands[1], 0)) && constant_pool_expr_p (XEXP (operands[1], 0))
&& ASM_OUTPUT_SPECIAL_POOL_ENTRY_P ( && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
get_pool_constant (XEXP (operands[1], 0)), get_pool_constant (XEXP (operands[1], 0)),
get_pool_mode (XEXP (operands[1], 0)))) get_pool_mode (XEXP (operands[1], 0))))
...@@ -6832,14 +7030,14 @@ lmw_operation (op, mode) ...@@ -6832,14 +7030,14 @@ lmw_operation (op, mode)
|| count != 32 - (int) dest_regno) || count != 32 - (int) dest_regno)
return 0; return 0;
if (LEGITIMATE_INDIRECT_ADDRESS_P (src_addr, 0)) if (legitimate_indirect_address_p (src_addr, 0))
{ {
offset = 0; offset = 0;
base_regno = REGNO (src_addr); base_regno = REGNO (src_addr);
if (base_regno == 0) if (base_regno == 0)
return 0; return 0;
} }
else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, src_addr, 0)) else if (legitimate_offset_address_p (SImode, src_addr, 0))
{ {
offset = INTVAL (XEXP (src_addr, 1)); offset = INTVAL (XEXP (src_addr, 1));
base_regno = REGNO (XEXP (src_addr, 0)); base_regno = REGNO (XEXP (src_addr, 0));
...@@ -6862,12 +7060,12 @@ lmw_operation (op, mode) ...@@ -6862,12 +7060,12 @@ lmw_operation (op, mode)
|| GET_MODE (SET_SRC (elt)) != SImode) || GET_MODE (SET_SRC (elt)) != SImode)
return 0; return 0;
newaddr = XEXP (SET_SRC (elt), 0); newaddr = XEXP (SET_SRC (elt), 0);
if (LEGITIMATE_INDIRECT_ADDRESS_P (newaddr, 0)) if (legitimate_indirect_address_p (newaddr, 0))
{ {
newoffset = 0; newoffset = 0;
addr_reg = newaddr; addr_reg = newaddr;
} }
else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, newaddr, 0)) else if (legitimate_offset_address_p (SImode, newaddr, 0))
{ {
addr_reg = XEXP (newaddr, 0); addr_reg = XEXP (newaddr, 0);
newoffset = INTVAL (XEXP (newaddr, 1)); newoffset = INTVAL (XEXP (newaddr, 1));
...@@ -6910,14 +7108,14 @@ stmw_operation (op, mode) ...@@ -6910,14 +7108,14 @@ stmw_operation (op, mode)
|| count != 32 - (int) src_regno) || count != 32 - (int) src_regno)
return 0; return 0;
if (LEGITIMATE_INDIRECT_ADDRESS_P (dest_addr, 0)) if (legitimate_indirect_address_p (dest_addr, 0))
{ {
offset = 0; offset = 0;
base_regno = REGNO (dest_addr); base_regno = REGNO (dest_addr);
if (base_regno == 0) if (base_regno == 0)
return 0; return 0;
} }
else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, dest_addr, 0)) else if (legitimate_offset_address_p (SImode, dest_addr, 0))
{ {
offset = INTVAL (XEXP (dest_addr, 1)); offset = INTVAL (XEXP (dest_addr, 1));
base_regno = REGNO (XEXP (dest_addr, 0)); base_regno = REGNO (XEXP (dest_addr, 0));
...@@ -6940,12 +7138,12 @@ stmw_operation (op, mode) ...@@ -6940,12 +7138,12 @@ stmw_operation (op, mode)
|| GET_MODE (SET_DEST (elt)) != SImode) || GET_MODE (SET_DEST (elt)) != SImode)
return 0; return 0;
newaddr = XEXP (SET_DEST (elt), 0); newaddr = XEXP (SET_DEST (elt), 0);
if (LEGITIMATE_INDIRECT_ADDRESS_P (newaddr, 0)) if (legitimate_indirect_address_p (newaddr, 0))
{ {
newoffset = 0; newoffset = 0;
addr_reg = newaddr; addr_reg = newaddr;
} }
else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, newaddr, 0)) else if (legitimate_offset_address_p (SImode, newaddr, 0))
{ {
addr_reg = XEXP (newaddr, 0); addr_reg = XEXP (newaddr, 0);
newoffset = INTVAL (XEXP (newaddr, 1)); newoffset = INTVAL (XEXP (newaddr, 1));
...@@ -8099,7 +8297,7 @@ print_operand (file, x, code) ...@@ -8099,7 +8297,7 @@ print_operand (file, x, code)
case 'X': case 'X':
if (GET_CODE (x) == MEM if (GET_CODE (x) == MEM
&& LEGITIMATE_INDEXED_ADDRESS_P (XEXP (x, 0), 0)) && legitimate_indexed_address_p (XEXP (x, 0), 0))
putc ('x', file); putc ('x', file);
return; return;
...@@ -8294,7 +8492,7 @@ print_operand_address (file, x) ...@@ -8294,7 +8492,7 @@ print_operand_address (file, x)
fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]); fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
} }
#endif #endif
else if (LEGITIMATE_CONSTANT_POOL_ADDRESS_P (x)) else if (legitimate_constant_pool_address_p (x))
{ {
if (TARGET_AIX && (!TARGET_ELF || !TARGET_MINIMAL_TOC)) if (TARGET_AIX && (!TARGET_ELF || !TARGET_MINIMAL_TOC))
{ {
......
...@@ -1308,7 +1308,7 @@ enum reg_class ...@@ -1308,7 +1308,7 @@ enum reg_class
#define EXTRA_CONSTRAINT(OP, C) \ #define EXTRA_CONSTRAINT(OP, C) \
((C) == 'Q' ? GET_CODE (OP) == MEM && GET_CODE (XEXP (OP, 0)) == REG \ ((C) == 'Q' ? GET_CODE (OP) == MEM && GET_CODE (XEXP (OP, 0)) == REG \
: (C) == 'R' ? LEGITIMATE_CONSTANT_POOL_ADDRESS_P (OP) \ : (C) == 'R' ? legitimate_constant_pool_address_p (OP) \
: (C) == 'S' ? mask64_operand (OP, DImode) \ : (C) == 'S' ? mask64_operand (OP, DImode) \
: (C) == 'T' ? mask_operand (OP, SImode) \ : (C) == 'T' ? mask_operand (OP, SImode) \
: (C) == 'U' ? (DEFAULT_ABI == ABI_V4 \ : (C) == 'U' ? (DEFAULT_ABI == ABI_V4 \
...@@ -2068,74 +2068,6 @@ typedef struct rs6000_args ...@@ -2068,74 +2068,6 @@ typedef struct rs6000_args
adjacent memory cells are accessed by adding word-sized offsets adjacent memory cells are accessed by adding word-sized offsets
during assembly output. */ during assembly output. */
#define CONSTANT_POOL_EXPR_P(X) (constant_pool_expr_p (X))
#define TOC_RELATIVE_EXPR_P(X) (toc_relative_expr_p (X))
/* SPE offset addressing is limited to 5-bits worth of double words. */
#define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
#define LEGITIMATE_CONSTANT_POOL_ADDRESS_P(X) \
(TARGET_TOC \
&& GET_CODE (X) == PLUS \
&& GET_CODE (XEXP (X, 0)) == REG \
&& (TARGET_MINIMAL_TOC || REGNO (XEXP (X, 0)) == TOC_REGISTER) \
&& CONSTANT_POOL_EXPR_P (XEXP (X, 1)))
#define LEGITIMATE_SMALL_DATA_P(MODE, X) \
(DEFAULT_ABI == ABI_V4 \
&& !flag_pic && !TARGET_TOC \
&& (GET_CODE (X) == SYMBOL_REF || GET_CODE (X) == CONST) \
&& small_data_operand (X, MODE))
#define LEGITIMATE_ADDRESS_INTEGER_P(X, OFFSET) \
(GET_CODE (X) == CONST_INT \
&& (unsigned HOST_WIDE_INT) (INTVAL (X) + (OFFSET) + 0x8000) < 0x10000)
#define LEGITIMATE_OFFSET_ADDRESS_P(MODE, X, STRICT) \
(GET_CODE (X) == PLUS \
&& GET_CODE (XEXP (X, 0)) == REG \
&& INT_REG_OK_FOR_BASE_P (XEXP (X, 0), (STRICT)) \
&& LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 0) \
&& (! ALTIVEC_VECTOR_MODE (MODE) \
|| (GET_CODE (XEXP (X,1)) == CONST_INT && INTVAL (XEXP (X,1)) == 0)) \
&& (! SPE_VECTOR_MODE (MODE) \
|| (GET_CODE (XEXP (X, 1)) == CONST_INT \
&& SPE_CONST_OFFSET_OK (INTVAL (XEXP (X, 1))))) \
&& (((MODE) != DFmode && (MODE) != DImode) \
|| (TARGET_32BIT \
? LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 4) \
: ! (INTVAL (XEXP (X, 1)) & 3))) \
&& (((MODE) != TFmode && (MODE) != TImode) \
|| (TARGET_32BIT \
? LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 12) \
: (LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 8) \
&& ! (INTVAL (XEXP (X, 1)) & 3)))))
#define LEGITIMATE_INDEXED_ADDRESS_P(X, STRICT) \
(GET_CODE (X) == PLUS \
&& GET_CODE (XEXP (X, 0)) == REG \
&& GET_CODE (XEXP (X, 1)) == REG \
&& ((INT_REG_OK_FOR_BASE_P (XEXP (X, 0), (STRICT)) \
&& INT_REG_OK_FOR_INDEX_P (XEXP (X, 1), (STRICT))) \
|| (INT_REG_OK_FOR_BASE_P (XEXP (X, 1), (STRICT)) \
&& INT_REG_OK_FOR_INDEX_P (XEXP (X, 0), (STRICT)))))
#define LEGITIMATE_INDIRECT_ADDRESS_P(X, STRICT) \
(GET_CODE (X) == REG && INT_REG_OK_FOR_BASE_P (X, (STRICT)))
#define LEGITIMATE_LO_SUM_ADDRESS_P(MODE, X, STRICT) \
(TARGET_ELF \
&& (DEFAULT_ABI == ABI_AIX || ! flag_pic) \
&& ! TARGET_TOC \
&& GET_MODE_NUNITS (MODE) == 1 \
&& (GET_MODE_BITSIZE (MODE) <= 32 \
|| (TARGET_HARD_FLOAT && TARGET_FPRS && (MODE) == DFmode)) \
&& GET_CODE (X) == LO_SUM \
&& GET_CODE (XEXP (X, 0)) == REG \
&& INT_REG_OK_FOR_BASE_P (XEXP (X, 0), (STRICT)) \
&& CONSTANT_P (XEXP (X, 1)))
#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \ #define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
{ if (rs6000_legitimate_address (MODE, X, REG_OK_STRICT_FLAG)) \ { if (rs6000_legitimate_address (MODE, X, REG_OK_STRICT_FLAG)) \
goto ADDR; \ goto ADDR; \
...@@ -2190,27 +2122,13 @@ do { \ ...@@ -2190,27 +2122,13 @@ do { \
} while (0) } while (0)
/* Go to LABEL if ADDR (a legitimate address expression) /* Go to LABEL if ADDR (a legitimate address expression)
has an effect that depends on the machine mode it is used for. has an effect that depends on the machine mode it is used for. */
On the RS/6000 this is true if the address is valid with a zero offset
but not with an offset of four (this means it cannot be used as an
address for DImode or DFmode) or is a pre-increment or decrement. Since
we know it is valid, we just check for an address that is not valid with
an offset of four. */
#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL) \ #define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL) \
{ if (GET_CODE (ADDR) == PLUS \ do { \
&& LEGITIMATE_ADDRESS_INTEGER_P (XEXP (ADDR, 1), 0) \ if (rs6000_mode_dependent_address (ADDR)) \
&& ! LEGITIMATE_ADDRESS_INTEGER_P (XEXP (ADDR, 1), \
(TARGET_32BIT ? 4 : 8))) \
goto LABEL; \
if (TARGET_UPDATE && GET_CODE (ADDR) == PRE_INC) \
goto LABEL; \
if (TARGET_UPDATE && GET_CODE (ADDR) == PRE_DEC) \
goto LABEL; \
if (GET_CODE (ADDR) == LO_SUM) \
goto LABEL; \ goto LABEL; \
} } while (0)
/* The register number of the register used to address a table of /* The register number of the register used to address a table of
static data addresses in memory. In some cases this register is static data addresses in memory. In some cases this register is
......
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