aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorHartmut Penner <hpenner@de.ibm.com>2004-01-12 08:11:28 +0000
committerHartmut Penner <hpenner@gcc.gnu.org>2004-01-12 08:11:28 +0000
commitd2288d5d766ff3997591950e84713b0a1e72deb7 (patch)
treed47c67bc221d940f2cf8e958c637910354dd89ee /gcc
parentea1ea21af5153ef84ac00dee8a1eaa54662b0aa2 (diff)
downloadgcc-d2288d5d766ff3997591950e84713b0a1e72deb7.zip
gcc-d2288d5d766ff3997591950e84713b0a1e72deb7.tar.gz
gcc-d2288d5d766ff3997591950e84713b0a1e72deb7.tar.bz2
rs6000.c (word_offset_memref_operand): New predicate to handle 'ld' conform addresses.
* gcc/config/rs6000/rs6000.c (word_offset_memref_operand): New predicate to handle 'ld' conform addresses. * gcc/config/rs6000/rs6000.h (EXTRA_CONSTRAINT): New 'Y' contraint. (EXTRA_MEMORY_CONSTRAINT): Tell reload which constraint are memory contraints. * gcc/config/rs6000/rs6000-protos.h (word_offset_memref_operand): New prototype. * gcc/config/rs6000/rs6000.md (*movdf_hardfloat64): Change 'o' to 'Y' constraint. (*movdf_softfloat64): Ditto. From-SVN: r75707
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog14
-rw-r--r--gcc/config/rs6000/rs6000-protos.h1
-rw-r--r--gcc/config/rs6000/rs6000.c21
-rw-r--r--gcc/config/rs6000/rs6000.h9
-rw-r--r--gcc/config/rs6000/rs6000.md18
5 files changed, 54 insertions, 9 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 0f76db1..dd94d58 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,17 @@
+2004-01-12 Hartmut Penner <hpenner@de.ibm.com>
+
+ * gcc/config/rs6000/rs6000.c (word_offset_memref_operand): New
+ predicate to handle 'ld' conform addresses.
+ * gcc/config/rs6000/rs6000.h (EXTRA_CONSTRAINT): New 'Y'
+ contraint.
+ (EXTRA_MEMORY_CONSTRAINT): Tell reload which constraint
+ are memory contraints.
+ * gcc/config/rs6000/rs6000-protos.h (word_offset_memref_operand):
+ New prototype.
+ * gcc/config/rs6000/rs6000.md (*movdf_hardfloat64):
+ Change 'o' to 'Y' constraint.
+ (*movdf_softfloat64): Ditto.
+
2004-01-12 Bernardo Innocenti <bernie@develer.com>
* gcc/config/m68k/m68k.md: Switch from the "*..." syntax to the
diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h
index b034193..982de3e 100644
--- a/gcc/config/rs6000/rs6000-protos.h
+++ b/gcc/config/rs6000/rs6000-protos.h
@@ -52,6 +52,7 @@ extern int reg_or_add_cint64_operand (rtx, enum machine_mode);
extern int reg_or_sub_cint64_operand (rtx, enum machine_mode);
extern int reg_or_logical_cint_operand (rtx, enum machine_mode);
extern int got_operand (rtx, enum machine_mode);
+extern int word_offset_memref_operand (rtx, enum machine_mode);
extern int got_no_const_operand (rtx, enum machine_mode);
extern int num_insns_constant (rtx, enum machine_mode);
extern int easy_fp_constant (rtx, enum machine_mode);
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index d485a5e..3e5dda0 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -2361,6 +2361,27 @@ small_data_operand (rtx op ATTRIBUTE_UNUSED,
#endif
}
+/* Return true, if operand is a memory operand and has a
+ displacement divisible by 4. */
+
+int
+word_offset_memref_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
+{
+ rtx addr;
+ int off = 0;
+
+ if (!memory_operand (op, mode))
+ return 0;
+
+ addr = XEXP (op, 0);
+ if (GET_CODE (addr) == PLUS
+ && GET_CODE (XEXP (addr, 0)) == REG
+ && GET_CODE (XEXP (addr, 1)) == CONST_INT)
+ off = INTVAL (XEXP (addr, 1));
+
+ return (off % 4) == 0;
+}
+
/* Return true if either operand is a general purpose register. */
bool
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index f09c694..d31863b 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -1419,6 +1419,7 @@ enum reg_class
'T' is a constant that can be placed into a 32-bit mask operand
'U' is for V.4 small data references.
'W' is a vector constant that can be easily generated (no mem refs).
+ 'Y' is a indexed or word-aligned displacement memory operand.
't' is for AND masks that can be performed by two rldic{l,r} insns. */
#define EXTRA_CONSTRAINT(OP, C) \
@@ -1433,8 +1434,16 @@ enum reg_class
|| !logical_operand (OP, DImode)) \
&& !mask64_operand (OP, DImode)) \
: (C) == 'W' ? (easy_vector_constant (OP, GET_MODE (OP))) \
+ : (C) == 'Y' ? (word_offset_memref_operand (OP, GET_MODE (OP))) \
: 0)
+/* Defining, which contraints are memory contraints. Tells reload,
+ that any memory address can be reloaded by copying the
+ memory address into a base register if required. */
+
+#define EXTRA_MEMORY_CONSTRAINT(C, STR) \
+ ((C) == 'Q' || (C) == 'Y')
+
/* Given an rtx X being reloaded into a reg required to be
in class CLASS, return the class of reg to actually use.
In general this is just CLASS; but on some machines
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 449a4f1..9a1874e 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -8160,11 +8160,11 @@
[(set_attr "type" "*,load,store,*,*,*")
(set_attr "length" "8,8,8,8,12,16")])
-; ld/std require word-aligned displacements, so use offsettable constraint.
-; List o->r and r->o before r->r for reload.
+; ld/std require word-aligned displacements -> 'Y' constraint.
+; List Y->r and r->Y before r->r for reload.
(define_insn "*movdf_hardfloat64"
- [(set (match_operand:DF 0 "nonimmediate_operand" "=o,??r,!r,f,f,m,!cl,!r,!r,!r,!r")
- (match_operand:DF 1 "input_operand" "r,o,r,f,m,f,r,h,G,H,F"))]
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,??r,!r,f,f,m,!cl,!r,!r,!r,!r")
+ (match_operand:DF 1 "input_operand" "r,Y,r,f,m,f,r,h,G,H,F"))]
"TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS
&& (gpc_reg_operand (operands[0], DFmode)
|| gpc_reg_operand (operands[1], DFmode))"
@@ -8184,22 +8184,22 @@
(set_attr "length" "4,4,4,4,4,4,4,4,8,12,16")])
(define_insn "*movdf_softfloat64"
- [(set (match_operand:DF 0 "nonimmediate_operand" "=r,cl,r,r,m,r,r,r,*h")
- (match_operand:DF 1 "input_operand" "r,r,h,m,r,G,H,F,0"))]
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=r,Y,r,cl,r,r,r,r,*h")
+ (match_operand:DF 1 "input_operand" "Y,r,r,r,h,G,H,F,0"))]
"TARGET_POWERPC64 && (TARGET_SOFT_FLOAT || !TARGET_FPRS)
&& (gpc_reg_operand (operands[0], DFmode)
|| gpc_reg_operand (operands[1], DFmode))"
"@
+ ld%U1%X1 %0,%1
+ std%U0%X0 %1,%0
mr %0,%1
mt%0 %1
mf%1 %0
- ld%U1%X1 %0,%1
- std%U0%X0 %1,%0
#
#
#
nop"
- [(set_attr "type" "*,*,*,load,store,*,*,*,*")
+ [(set_attr "type" "load,store,*,*,*,*,*,*,*")
(set_attr "length" "4,4,4,4,4,8,12,16,4")])
(define_expand "movtf"