Commit d32d6b75 by Alan Modra Committed by Alan Modra

re PR target/53914 (poor code generated for offset addressing on ppc32)

	PR target/53914
	PR target/54009
	* config/rs6000/constraints.md (Y): Use mem_operand_gpr.
	* config/rs6000/predicates.md (word_offset_memref_operand): Delete.
	Adjust all rs6000_legitimate_offset_address_p calls.
	* config/rs6000/rs6000-protos.h (mem_operand_gpr): Declare.
	(rs6000_secondary_reload_gpr): Declare.
	(rs6000_legitimate_offset_address_p): Update prototype.
	(rs6000_offsettable_memref_p): Delete.
	(rs6000_secondary_reload_ppc64): Delete.
	* config/rs6000/rs6000.c (address_offset): New function.
	(mem_operand_gpr): Likewise.
	(rs6000_legitimate_offset_address_p): Add worst_case param.  When
	not worst_case assume class of regs with least restrictive offsets.
	Adjust all calls.
	(legitimate_lo_sum_address_p): Simplify register mode tests.
	(rs6000_legitimize_address): Likewise.  Assume best case offset
	addressing.  Combine ELF and MACHO lo_sum code.
	(rs6000_mode_dependent_address): Correct offset addressing limits.
	(rs6000_offsettable_memref_p): Make static, add reg_mode param.
	Use reg_mode to help rs6000_legitimate_offset_address_p.
	(rs6000_secondary_reload): Use address_offset.  Handle 32-bit multi
	gpr load/store when offset too large.
	(rs6000_secondary_reload_gpr): Renamed rs6000_secondary_reload_ppc64.
	(rs6000_split_multireg_move): Adjust rs6000_offsettable_memref_p calls.
	* config/rs6000/rs6000.md (movdf_hardfloat32): Use 'Y' constraint
	for gpr load/store.  Order alternatives as r->Y,Y->r,r->r and
	d->m,m->d,d->d.  Correct size of gpr load/store.
	(movdf_softfloat32): Use 'Y' constraint for gpr load/store.  Order
	alternatives.
	(movti_ppc64): Likewise.
	(movdi_internal32): Likewise.  Also disparage fprs.
	(movdi_mfpgpr, movdi_internal64): Likewise.
	(movtf_internal): Use 'm' for fpr load/store.  Order alternatives.
	(movtf_softfloat): Order alternatives.
	(extenddftf2_internal): Use 'm' and 'Y' for store.
	(movti_power, movti_string): Use 'Y' for gpr load/store.  Order.
	(stack_protect_setdi, stack_protect_testdi): Likewise.
	(movdf_hardfloat64_mfpgpr, movdf_hardfloat64): Order alternatives.
	(movdf_softfloat64): Likewise.
	(reload_<mode>_store): Adjust reload_di_store to provide
	reload_si_store as well.
	(reload_<mode>_load): Likewise.

From-SVN: r189801
parent 71922d52
2012-07-24 Alan Modra <amodra@gmail.com>
PR target/53914
PR target/54009
* config/rs6000/constraints.md (Y): Use mem_operand_gpr.
* config/rs6000/predicates.md (word_offset_memref_operand): Delete.
Adjust all rs6000_legitimate_offset_address_p calls.
* config/rs6000/rs6000-protos.h (mem_operand_gpr): Declare.
(rs6000_secondary_reload_gpr): Declare.
(rs6000_legitimate_offset_address_p): Update prototype.
(rs6000_offsettable_memref_p): Delete.
(rs6000_secondary_reload_ppc64): Delete.
* config/rs6000/rs6000.c (address_offset): New function.
(mem_operand_gpr): Likewise.
(rs6000_legitimate_offset_address_p): Add worst_case param. When
not worst_case assume class of regs with least restrictive offsets.
Adjust all calls.
(legitimate_lo_sum_address_p): Simplify register mode tests.
(rs6000_legitimize_address): Likewise. Assume best case offset
addressing. Combine ELF and MACHO lo_sum code.
(rs6000_mode_dependent_address): Correct offset addressing limits.
(rs6000_offsettable_memref_p): Make static, add reg_mode param.
Use reg_mode to help rs6000_legitimate_offset_address_p.
(rs6000_secondary_reload): Use address_offset. Handle 32-bit multi
gpr load/store when offset too large.
(rs6000_secondary_reload_gpr): Renamed rs6000_secondary_reload_ppc64.
(rs6000_split_multireg_move): Adjust rs6000_offsettable_memref_p calls.
* config/rs6000/rs6000.md (movdf_hardfloat32): Use 'Y' constraint
for gpr load/store. Order alternatives as r->Y,Y->r,r->r and
d->m,m->d,d->d. Correct size of gpr load/store.
(movdf_softfloat32): Use 'Y' constraint for gpr load/store. Order
alternatives.
(movti_ppc64): Likewise.
(movdi_internal32): Likewise. Also disparage fprs.
(movdi_mfpgpr, movdi_internal64): Likewise.
(movtf_internal): Use 'm' for fpr load/store. Order alternatives.
(movtf_softfloat): Order alternatives.
(extenddftf2_internal): Use 'm' and 'Y' for store.
(movti_power, movti_string): Use 'Y' for gpr load/store. Order.
(stack_protect_setdi, stack_protect_testdi): Likewise.
(movdf_hardfloat64_mfpgpr, movdf_hardfloat64): Order alternatives.
(movdf_softfloat64): Likewise.
(reload_<mode>_store): Adjust reload_di_store to provide
reload_si_store as well.
(reload_<mode>_load): Likewise.
2012-07-23 Oleg Endo <olegendo@gcc.gnu.org>
PR target/51244
......
......@@ -150,8 +150,9 @@ to use @samp{m} or @samp{es} in @code{asm} statements)"
(match_test "GET_CODE (XEXP (op, 0)) == REG")))
(define_memory_constraint "Y"
"Indexed or word-aligned displacement memory operand"
(match_operand 0 "word_offset_memref_operand"))
"memory operand for 8 byte and 16 byte gpr load/store"
(and (match_code "mem")
(match_operand 0 "mem_operand_gpr")))
(define_memory_constraint "Z"
"Memory operand that is an indexed or indirect from a register (it is
......
......@@ -432,29 +432,6 @@
(and (match_operand 0 "memory_operand")
(match_test "offsettable_nonstrict_memref_p (op)")))
;; Return 1 if the operand is a memory operand with an address divisible by 4
(define_predicate "word_offset_memref_operand"
(match_operand 0 "memory_operand")
{
/* Address inside MEM. */
op = XEXP (op, 0);
/* Extract address from auto-inc/dec. */
if (GET_CODE (op) == PRE_INC
|| GET_CODE (op) == PRE_DEC)
op = XEXP (op, 0);
else if (GET_CODE (op) == PRE_MODIFY)
op = XEXP (op, 1);
else if (GET_CODE (op) == LO_SUM
&& GET_CODE (XEXP (op, 0)) == REG
&& GET_CODE (XEXP (op, 1)) == CONST)
op = XEXP (XEXP (op, 1), 0);
return (GET_CODE (op) != PLUS
|| GET_CODE (XEXP (op, 1)) != CONST_INT
|| INTVAL (XEXP (op, 1)) % 4 == 0);
})
;; Return 1 if the operand is an indexed or indirect memory operand.
(define_predicate "indexed_or_indirect_operand"
(match_code "mem")
......@@ -892,7 +869,8 @@
return input_operand (op, mode);
})
;; Return true if OP is an invalid SUBREG operation on the e500.
;; Return true if OP is a non-immediate operand and not an invalid
;; SUBREG operation on the e500.
(define_predicate "rs6000_nonimmediate_operand"
(match_code "reg,subreg,mem")
{
......@@ -1325,7 +1303,7 @@
if (base_regno == 0)
return 0;
}
else if (rs6000_legitimate_offset_address_p (SImode, src_addr, 0))
else if (rs6000_legitimate_offset_address_p (SImode, src_addr, false, false))
{
offset = INTVAL (XEXP (src_addr, 1));
base_regno = REGNO (XEXP (src_addr, 0));
......@@ -1353,7 +1331,7 @@
newoffset = 0;
addr_reg = newaddr;
}
else if (rs6000_legitimate_offset_address_p (SImode, newaddr, 0))
else if (rs6000_legitimate_offset_address_p (SImode, newaddr, false, false))
{
addr_reg = XEXP (newaddr, 0);
newoffset = INTVAL (XEXP (newaddr, 1));
......@@ -1400,7 +1378,7 @@
if (base_regno == 0)
return 0;
}
else if (rs6000_legitimate_offset_address_p (SImode, dest_addr, 0))
else if (rs6000_legitimate_offset_address_p (SImode, dest_addr, false, false))
{
offset = INTVAL (XEXP (dest_addr, 1));
base_regno = REGNO (XEXP (dest_addr, 0));
......@@ -1428,7 +1406,7 @@
newoffset = 0;
addr_reg = newaddr;
}
else if (rs6000_legitimate_offset_address_p (SImode, newaddr, 0))
else if (rs6000_legitimate_offset_address_p (SImode, newaddr, false, false))
{
addr_reg = XEXP (newaddr, 0);
newoffset = INTVAL (XEXP (newaddr, 1));
......
......@@ -38,6 +38,7 @@ extern bool macho_lo_sum_memory_operand (rtx, enum machine_mode);
extern int num_insns_constant (rtx, enum machine_mode);
extern int num_insns_constant_wide (HOST_WIDE_INT);
extern int small_data_operand (rtx, enum machine_mode);
extern bool mem_operand_gpr (rtx, enum machine_mode);
extern bool toc_relative_expr_p (const_rtx, bool);
extern bool invalid_e500_subreg (rtx, enum machine_mode);
extern void validate_condition_mode (enum rtx_code, enum machine_mode);
......@@ -83,7 +84,7 @@ extern bool (*rs6000_cannot_change_mode_class_ptr) (enum machine_mode,
enum machine_mode,
enum reg_class);
extern void rs6000_secondary_reload_inner (rtx, rtx, rtx, bool);
extern void rs6000_secondary_reload_ppc64 (rtx, rtx, rtx, bool);
extern void rs6000_secondary_reload_gpr (rtx, rtx, rtx, bool);
extern int paired_emit_vector_cond_expr (rtx, rtx, rtx,
rtx, rtx, rtx);
extern void paired_expand_vector_move (rtx operands[]);
......@@ -121,9 +122,9 @@ extern void rs6000_emit_move (rtx, rtx, enum machine_mode);
extern rtx rs6000_secondary_memory_needed_rtx (enum machine_mode);
extern rtx (*rs6000_legitimize_reload_address_ptr) (rtx, enum machine_mode,
int, int, int, int *);
extern bool rs6000_legitimate_offset_address_p (enum machine_mode, rtx, int);
extern bool rs6000_legitimate_offset_address_p (enum machine_mode, rtx,
bool, bool);
extern rtx rs6000_find_base_term (rtx);
extern bool rs6000_offsettable_memref_p (rtx);
extern rtx rs6000_return_addr (int, rtx);
extern void rs6000_output_symbol_ref (FILE*, rtx);
extern HOST_WIDE_INT rs6000_initial_elimination_offset (int, int);
......
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