aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2006-03-24 10:09:01 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2006-03-24 10:09:01 +0000
commitd04b6e6e8a2d8bab65ef2d4a10e6993d7090c8ef (patch)
tree5ad3707267a5fefb5118ca74a64bf4c3267b16c4 /gcc
parent243cc8369be79c5ea217a53b2ab47563e2ea6e02 (diff)
downloadgcc-d04b6e6e8a2d8bab65ef2d4a10e6993d7090c8ef.zip
gcc-d04b6e6e8a2d8bab65ef2d4a10e6993d7090c8ef.tar.gz
gcc-d04b6e6e8a2d8bab65ef2d4a10e6993d7090c8ef.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog12
-rw-r--r--gcc/config/rs6000/rs6000-protos.h4
-rw-r--r--gcc/config/rs6000/rs6000.c38
-rw-r--r--gcc/config/rs6000/rs6000.md26
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
{