diff options
author | Hartmut Penner <hpenner@de.ibm.com> | 2004-01-12 08:11:28 +0000 |
---|---|---|
committer | Hartmut Penner <hpenner@gcc.gnu.org> | 2004-01-12 08:11:28 +0000 |
commit | d2288d5d766ff3997591950e84713b0a1e72deb7 (patch) | |
tree | d47c67bc221d940f2cf8e958c637910354dd89ee /gcc | |
parent | ea1ea21af5153ef84ac00dee8a1eaa54662b0aa2 (diff) | |
download | gcc-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/ChangeLog | 14 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000-protos.h | 1 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 21 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.h | 9 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.md | 18 |
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" |