diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 12 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000-protos.h | 4 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 38 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.md | 26 |
4 files changed, 57 insertions, 23 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5215e63..687eb462 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +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> * tree-ssa-dom.c (propagate_rhs_into_lhs): Temporarily work diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h index c1f6a04..0cb5a50 100644 --- a/gcc/config/rs6000/rs6000-protos.h +++ b/gcc/config/rs6000/rs6000-protos.h @@ -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 bool legitimate_constant_pool_address_p (rtx); 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 find_addr_reg (rtx); @@ -102,7 +100,9 @@ extern rtx rs6000_legitimize_address (rtx, rtx, enum machine_mode); extern rtx rs6000_legitimize_reload_address (rtx, enum machine_mode, int, int, int, 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_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); diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 889f2b0..fbe4615 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -588,6 +588,7 @@ static unsigned toc_hash_function (const void *); static int toc_hash_eq (const void *, const void *); static int constant_pool_expr_1 (rtx, int *, int *); 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_lo_sum_address_p (enum machine_mode, rtx, int); static struct machine_function * rs6000_init_machine_status (void); @@ -2692,8 +2693,8 @@ legitimate_constant_pool_address_p (rtx x) && constant_pool_expr_p (XEXP (x, 1))); } -bool -rs6000_legitimate_small_data_p (enum machine_mode mode, rtx x) +static bool +legitimate_small_data_p (enum machine_mode mode, rtx x) { return (DEFAULT_ABI == ABI_V4 && !flag_pic && !TARGET_TOC @@ -3478,7 +3479,7 @@ rs6000_legitimate_address (enum machine_mode mode, rtx x, int reg_ok_strict) && TARGET_UPDATE && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict)) return 1; - if (rs6000_legitimate_small_data_p (mode, x)) + if (legitimate_small_data_p (mode, x)) return 1; if (legitimate_constant_pool_address_p (x)) return 1; @@ -3543,6 +3544,33 @@ rs6000_mode_dependent_address (rtx addr) 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 to hold something 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) : gen_adddi3 (breg, breg, delta_rtx)); src = replace_equiv_address (src, breg); } - else if (! offsettable_memref_p (src)) + else if (! rs6000_offsettable_memref_p (src)) { rtx basereg; basereg = gen_rtx_REG (Pmode, reg); @@ -12541,7 +12569,7 @@ rs6000_split_multireg_move (rtx dst, rtx src) dst = replace_equiv_address (dst, breg); } else - gcc_assert (offsettable_memref_p (dst)); + gcc_assert (rs6000_offsettable_memref_p (dst)); } for (i = 0; i < nregs; i++) diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index a844f2f..48e8df2 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -8155,14 +8155,11 @@ else return \"mr %0,%1\;mr %L0,%L1\"; case 1: - if (GET_CODE (operands[1]) == MEM - && (rs6000_legitimate_offset_address_p (DFmode, XEXP (operands[1], 0), - reload_completed || reload_in_progress) - || 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_DEC)) + if (rs6000_offsettable_memref_p (operands[1]) + || (GET_CODE (operands[1]) == MEM + && (GET_CODE (XEXP (operands[1], 0)) == LO_SUM + || GET_CODE (XEXP (operands[1], 0)) == PRE_INC + || GET_CODE (XEXP (operands[1], 0)) == PRE_DEC))) { /* If the low-address word is used in the address, we must load it last. Otherwise, load it first. Note that we cannot have @@ -8198,14 +8195,11 @@ } } case 2: - if (GET_CODE (operands[0]) == MEM - && (rs6000_legitimate_offset_address_p (DFmode, XEXP (operands[0], 0), - reload_completed || reload_in_progress) - || 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_DEC)) + if (rs6000_offsettable_memref_p (operands[0]) + || (GET_CODE (operands[0]) == MEM + && (GET_CODE (XEXP (operands[0], 0)) == LO_SUM + || GET_CODE (XEXP (operands[0], 0)) == PRE_INC + || GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))) return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\"; else { |