Commit d04b6e6e by Eric Botcazou Committed by Eric Botcazou

rs6000-protos.h (rs6000_offsettable_memref_p): Declare.

	* config/rs6000/rs6000-protos.h (rs6000_offsettable_memref_p): Declare.
	(rs6000_legitimate_small_data_p): Delete.
	* config/rs6000/rs6000.c (rs6000_offsettable_memref_p): New predicate.
	(rs6000_legitimate_small_data_p): Rename to legitimate_small_data_p
	and make static.  Add forward declaration.  Update uses.
	(rs6000_split_multireg_move): Use rs6000_offsettable_memref_p instead
	of offsettable_memref_p.
	* config/rs6000/rs6000.md (movdf_hardfloat32): Revert 2005-08-23 fix.
	Use rs6000_offsettable_memref_p instead of a less accurate predicate.

From-SVN: r112349
parent 243cc836
2006-03-24 Eric Botcazou <ebotcazou@adacore.com>
* config/rs6000/rs6000-protos.h (rs6000_offsettable_memref_p): Declare.
(rs6000_legitimate_small_data_p): Delete.
* config/rs6000/rs6000.c (rs6000_offsettable_memref_p): New predicate.
(rs6000_legitimate_small_data_p): Rename to legitimate_small_data_p
and make static. Add forward declaration. Update uses.
(rs6000_split_multireg_move): Use rs6000_offsettable_memref_p instead
of offsettable_memref_p.
* config/rs6000/rs6000.md (movdf_hardfloat32): Revert 2005-08-23 fix.
Use rs6000_offsettable_memref_p instead of a less accurate predicate.
2006-03-24 Jeff Law <law@redhat.com> 2006-03-24 Jeff Law <law@redhat.com>
* tree-ssa-dom.c (propagate_rhs_into_lhs): Temporarily work * tree-ssa-dom.c (propagate_rhs_into_lhs): Temporarily work
......
...@@ -42,8 +42,6 @@ extern bool invalid_e500_subreg (rtx, enum machine_mode); ...@@ -42,8 +42,6 @@ extern bool invalid_e500_subreg (rtx, enum machine_mode);
extern void validate_condition_mode (enum rtx_code, enum machine_mode); extern void validate_condition_mode (enum rtx_code, enum machine_mode);
extern bool legitimate_constant_pool_address_p (rtx); extern bool legitimate_constant_pool_address_p (rtx);
extern bool legitimate_indirect_address_p (rtx, int); extern bool legitimate_indirect_address_p (rtx, int);
extern bool rs6000_legitimate_offset_address_p (enum machine_mode, rtx, int);
extern bool rs6000_legitimate_small_data_p (enum machine_mode, rtx);
extern rtx rs6000_got_register (rtx); extern rtx rs6000_got_register (rtx);
extern rtx find_addr_reg (rtx); extern rtx find_addr_reg (rtx);
...@@ -102,7 +100,9 @@ extern rtx rs6000_legitimize_address (rtx, rtx, enum machine_mode); ...@@ -102,7 +100,9 @@ extern rtx rs6000_legitimize_address (rtx, rtx, enum machine_mode);
extern rtx rs6000_legitimize_reload_address (rtx, enum machine_mode, extern rtx rs6000_legitimize_reload_address (rtx, enum machine_mode,
int, int, int, int *); int, int, int, int *);
extern int rs6000_legitimate_address (enum machine_mode, rtx, int); extern int rs6000_legitimate_address (enum machine_mode, rtx, int);
extern bool rs6000_legitimate_offset_address_p (enum machine_mode, rtx, int);
extern bool rs6000_mode_dependent_address (rtx); extern bool rs6000_mode_dependent_address (rtx);
extern bool rs6000_offsettable_memref_p (rtx);
extern rtx rs6000_return_addr (int, rtx); extern rtx rs6000_return_addr (int, rtx);
extern void rs6000_output_symbol_ref (FILE*, rtx); extern void rs6000_output_symbol_ref (FILE*, rtx);
extern HOST_WIDE_INT rs6000_initial_elimination_offset (int, int); extern HOST_WIDE_INT rs6000_initial_elimination_offset (int, int);
......
...@@ -588,6 +588,7 @@ static unsigned toc_hash_function (const void *); ...@@ -588,6 +588,7 @@ static unsigned toc_hash_function (const void *);
static int toc_hash_eq (const void *, const void *); static int toc_hash_eq (const void *, const void *);
static int constant_pool_expr_1 (rtx, int *, int *); static int constant_pool_expr_1 (rtx, int *, int *);
static bool constant_pool_expr_p (rtx); static bool constant_pool_expr_p (rtx);
static bool legitimate_small_data_p (enum machine_mode, rtx);
static bool legitimate_indexed_address_p (rtx, int); static bool legitimate_indexed_address_p (rtx, int);
static bool legitimate_lo_sum_address_p (enum machine_mode, rtx, int); static bool legitimate_lo_sum_address_p (enum machine_mode, rtx, int);
static struct machine_function * rs6000_init_machine_status (void); static struct machine_function * rs6000_init_machine_status (void);
...@@ -2692,8 +2693,8 @@ legitimate_constant_pool_address_p (rtx x) ...@@ -2692,8 +2693,8 @@ legitimate_constant_pool_address_p (rtx x)
&& constant_pool_expr_p (XEXP (x, 1))); && constant_pool_expr_p (XEXP (x, 1)));
} }
bool static bool
rs6000_legitimate_small_data_p (enum machine_mode mode, rtx x) legitimate_small_data_p (enum machine_mode mode, rtx x)
{ {
return (DEFAULT_ABI == ABI_V4 return (DEFAULT_ABI == ABI_V4
&& !flag_pic && !TARGET_TOC && !flag_pic && !TARGET_TOC
...@@ -3478,7 +3479,7 @@ rs6000_legitimate_address (enum machine_mode mode, rtx x, int reg_ok_strict) ...@@ -3478,7 +3479,7 @@ rs6000_legitimate_address (enum machine_mode mode, rtx x, int reg_ok_strict)
&& 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 (rs6000_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;
...@@ -3543,6 +3544,33 @@ rs6000_mode_dependent_address (rtx addr) ...@@ -3543,6 +3544,33 @@ rs6000_mode_dependent_address (rtx addr)
return false; return false;
} }
/* More elaborate version of recog's offsettable_memref_p predicate
that works around the ??? note of rs6000_mode_dependent_address.
In particular it accepts
(mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
in 32-bit mode, that the recog predicate rejects. */
bool
rs6000_offsettable_memref_p (rtx op)
{
if (!MEM_P (op))
return false;
/* First mimic offsettable_memref_p. */
if (offsettable_address_p (1, GET_MODE (op), XEXP (op, 0)))
return true;
/* offsettable_address_p invokes rs6000_mode_dependent_address, but
the latter predicate knows nothing about the mode of the memory
reference and, therefore, assumes that it is the largest supported
mode (TFmode). As a consequence, legitimate offsettable memory
references are rejected. rs6000_legitimate_offset_address_p contains
the correct logic for the PLUS case of rs6000_mode_dependent_address. */
return rs6000_legitimate_offset_address_p (GET_MODE (op), XEXP (op, 0), 1);
}
/* Return number of consecutive hard regs needed starting at reg REGNO /* Return number of consecutive hard regs needed starting at reg REGNO
to hold something of mode MODE. to hold something of mode MODE.
This is ordinarily the length in words of a value of mode MODE This is ordinarily the length in words of a value of mode MODE
...@@ -12488,7 +12516,7 @@ rs6000_split_multireg_move (rtx dst, rtx src) ...@@ -12488,7 +12516,7 @@ rs6000_split_multireg_move (rtx dst, rtx src)
: gen_adddi3 (breg, breg, delta_rtx)); : gen_adddi3 (breg, breg, delta_rtx));
src = replace_equiv_address (src, breg); src = replace_equiv_address (src, breg);
} }
else if (! offsettable_memref_p (src)) else if (! rs6000_offsettable_memref_p (src))
{ {
rtx basereg; rtx basereg;
basereg = gen_rtx_REG (Pmode, reg); basereg = gen_rtx_REG (Pmode, reg);
...@@ -12541,7 +12569,7 @@ rs6000_split_multireg_move (rtx dst, rtx src) ...@@ -12541,7 +12569,7 @@ rs6000_split_multireg_move (rtx dst, rtx src)
dst = replace_equiv_address (dst, breg); dst = replace_equiv_address (dst, breg);
} }
else else
gcc_assert (offsettable_memref_p (dst)); gcc_assert (rs6000_offsettable_memref_p (dst));
} }
for (i = 0; i < nregs; i++) for (i = 0; i < nregs; i++)
......
...@@ -8155,14 +8155,11 @@ ...@@ -8155,14 +8155,11 @@
else else
return \"mr %0,%1\;mr %L0,%L1\"; return \"mr %0,%1\;mr %L0,%L1\";
case 1: case 1:
if (GET_CODE (operands[1]) == MEM if (rs6000_offsettable_memref_p (operands[1])
&& (rs6000_legitimate_offset_address_p (DFmode, XEXP (operands[1], 0), || (GET_CODE (operands[1]) == MEM
reload_completed || reload_in_progress) && (GET_CODE (XEXP (operands[1], 0)) == LO_SUM
|| rs6000_legitimate_small_data_p (DFmode, XEXP (operands[1], 0))
|| GET_CODE (XEXP (operands[1], 0)) == REG
|| GET_CODE (XEXP (operands[1], 0)) == LO_SUM
|| GET_CODE (XEXP (operands[1], 0)) == PRE_INC || GET_CODE (XEXP (operands[1], 0)) == PRE_INC
|| GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)) || GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)))
{ {
/* If the low-address word is used in the address, we must load /* If the low-address word is used in the address, we must load
it last. Otherwise, load it first. Note that we cannot have it last. Otherwise, load it first. Note that we cannot have
...@@ -8198,14 +8195,11 @@ ...@@ -8198,14 +8195,11 @@
} }
} }
case 2: case 2:
if (GET_CODE (operands[0]) == MEM if (rs6000_offsettable_memref_p (operands[0])
&& (rs6000_legitimate_offset_address_p (DFmode, XEXP (operands[0], 0), || (GET_CODE (operands[0]) == MEM
reload_completed || reload_in_progress) && (GET_CODE (XEXP (operands[0], 0)) == LO_SUM
|| rs6000_legitimate_small_data_p (DFmode, XEXP (operands[0], 0))
|| GET_CODE (XEXP (operands[0], 0)) == REG
|| GET_CODE (XEXP (operands[0], 0)) == LO_SUM
|| GET_CODE (XEXP (operands[0], 0)) == PRE_INC || GET_CODE (XEXP (operands[0], 0)) == PRE_INC
|| GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)) || GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)))
return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\"; return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\";
else else
{ {
......
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