summaryrefslogtreecommitdiff
path: root/gcc/config/v850
diff options
context:
space:
mode:
authorkazu <kazu@138bc75d-0d04-0410-961f-82ee72b054a4>2005-03-21 18:01:29 +0000
committerkazu <kazu@138bc75d-0d04-0410-961f-82ee72b054a4>2005-03-21 18:01:29 +0000
commitdb5c82c4c684a2c57aa5f04d732450fdf3e01b79 (patch)
tree4b7eb16eb0e044e4279433c45d2895a812452741 /gcc/config/v850
parentff84d87f9010971b68351a57ce677422d8c21a47 (diff)
downloadgcc-db5c82c4c684a2c57aa5f04d732450fdf3e01b79.tar.gz
* config/v850/v850-protos.h: Remove the prototypes for
reg_or_int9_operand, reg_or_const_operand, pattern_is_ok_for_prepare, pattern_is_ok_for_dispose, reg_or_0_operand, reg_or_int5_operand, call_address_operand, movsi_source_operand, power_of_two_operand, not_power_of_two_operand, special_symbolref_operand, pattern_is_ok_for_prologue, pattern_is_ok_for_epilogue, and register_is_ok_for_epilogue. * config/v850/v850.c (reg_or_0_operand, reg_or_int5_operand, reg_or_int9_operand, reg_or_const_operand, call_address_operand, special_symbolref_operand, movsi_source_operand, power_of_two_operand, not_power_of_two_operand, register_is_ok_for_epilogue, pattern_is_ok_for_epilogue, pattern_is_ok_for_prologue, pattern_is_ok_for_dispose, pattern_is_ok_for_prepare): Move to predicates.md. * config/v850/v850.h (PREDICATE_CODES): Remove. * config/v850/v850.md: Include predicates.md. * config/v850/predicates.md: New. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@96822 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/v850')
-rw-r--r--gcc/config/v850/predicates.md439
-rw-r--r--gcc/config/v850/v850-protos.h16
-rw-r--r--gcc/config/v850/v850.c410
-rw-r--r--gcc/config/v850/v850.h27
-rw-r--r--gcc/config/v850/v850.md4
5 files changed, 445 insertions, 451 deletions
diff --git a/gcc/config/v850/predicates.md b/gcc/config/v850/predicates.md
new file mode 100644
index 00000000000..a878fdc01fd
--- /dev/null
+++ b/gcc/config/v850/predicates.md
@@ -0,0 +1,439 @@
+;; Predicate definitions for NEC V850.
+;; Copyright (C) 2005 Free Software Foundation, Inc.
+;;
+;; This file is part of GCC.
+;;
+;; GCC is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+;;
+;; GCC is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GCC; see the file COPYING. If not, write to
+;; the Free Software Foundation, 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;; Return true if OP is either a register or 0.
+
+(define_predicate "reg_or_0_operand"
+ (match_code "reg,subreg,const_int,const_double")
+{
+ if (GET_CODE (op) == CONST_INT)
+ return INTVAL (op) == 0;
+
+ else if (GET_CODE (op) == CONST_DOUBLE)
+ return CONST_DOUBLE_OK_FOR_G (op);
+
+ else
+ return register_operand (op, mode);
+})
+
+;; Return true if OP is either a register or a signed five bit
+;; integer.
+
+(define_predicate "reg_or_int5_operand"
+ (match_code "reg,subreg,const_int")
+{
+ if (GET_CODE (op) == CONST_INT)
+ return CONST_OK_FOR_J (INTVAL (op));
+
+ else
+ return register_operand (op, mode);
+})
+
+;; Return true if OP is either a register or a signed nine bit
+;; integer.
+
+(define_predicate "reg_or_int9_operand"
+ (match_code "reg,subreg,const_int")
+{
+ if (GET_CODE (op) == CONST_INT)
+ return CONST_OK_FOR_O (INTVAL (op));
+
+ return register_operand (op, mode);
+})
+
+;; Return true if OP is either a register or a const integer.
+
+(define_predicate "reg_or_const_operand"
+ (match_code "reg,const_int")
+{
+ if (GET_CODE (op) == CONST_INT)
+ return TRUE;
+
+ return register_operand (op, mode);
+})
+
+;; Return true if OP is a valid call operand.
+
+(define_predicate "call_address_operand"
+ (match_code "reg,symbol_ref")
+{
+ /* Only registers are valid call operands if TARGET_LONG_CALLS. */
+ if (TARGET_LONG_CALLS)
+ return GET_CODE (op) == REG;
+ return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == REG);
+})
+
+;; TODO: Add a comment here.
+
+(define_predicate "movsi_source_operand"
+ (match_code "label_ref,symbol_ref,const_int,const_double,const,high,mem,reg,subreg")
+{
+ /* Some constants, as well as symbolic operands
+ must be done with HIGH & LO_SUM patterns. */
+ if (CONSTANT_P (op)
+ && GET_CODE (op) != HIGH
+ && !(GET_CODE (op) == CONST_INT
+ && (CONST_OK_FOR_J (INTVAL (op))
+ || CONST_OK_FOR_K (INTVAL (op))
+ || CONST_OK_FOR_L (INTVAL (op)))))
+ return special_symbolref_operand (op, mode);
+ else
+ return general_operand (op, mode);
+})
+
+;; TODO: Add a comment here.
+
+(define_predicate "special_symbolref_operand"
+ (match_code "symbol_ref")
+{
+ if (GET_CODE (op) == CONST
+ && GET_CODE (XEXP (op, 0)) == PLUS
+ && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT
+ && CONST_OK_FOR_K (INTVAL (XEXP (XEXP (op, 0), 1))))
+ op = XEXP (XEXP (op, 0), 0);
+
+ if (GET_CODE (op) == SYMBOL_REF)
+ return (SYMBOL_REF_FLAGS (op)
+ & (SYMBOL_FLAG_ZDA | SYMBOL_FLAG_TDA | SYMBOL_FLAG_SDA)) != 0;
+
+ return FALSE;
+})
+
+;; TODO: Add a comment here.
+
+(define_predicate "power_of_two_operand"
+ (match_code "const_int")
+{
+ if (GET_CODE (op) != CONST_INT)
+ return 0;
+
+ if (exact_log2 (INTVAL (op)) == -1)
+ return 0;
+ return 1;
+})
+
+;; Return nonzero if the given RTX is suitable for collapsing into a
+;; jump to a function prologue.
+
+(define_predicate "pattern_is_ok_for_prologue"
+ (match_code "parallel")
+{
+ int count = XVECLEN (op, 0);
+ int i;
+ rtx vector_element;
+
+ /* If there are no registers to save then the function prologue
+ is not suitable. */
+ if (count <= 2)
+ return 0;
+
+ /* The pattern matching has already established that we are adjusting the
+ stack and pushing at least one register. We must now check that the
+ remaining entries in the vector to make sure that they are also register
+ pushes, except for the last entry which should be a CLOBBER of r10.
+
+ The test below performs the C equivalent of this machine description
+ pattern match:
+
+ (set (mem:SI (plus:SI (reg:SI 3)
+ (match_operand:SI 2 "immediate_operand" "i")))
+ (match_operand:SI 3 "register_is_ok_for_epilogue" "r"))
+
+ */
+
+ for (i = 2; i < count - (TARGET_LONG_CALLS ? 2: 1); i++)
+ {
+ rtx dest;
+ rtx src;
+ rtx plus;
+
+ vector_element = XVECEXP (op, 0, i);
+
+ if (GET_CODE (vector_element) != SET)
+ return 0;
+
+ dest = SET_DEST (vector_element);
+ src = SET_SRC (vector_element);
+
+ if (GET_CODE (dest) != MEM
+ || GET_MODE (dest) != SImode
+ || GET_CODE (src) != REG
+ || GET_MODE (src) != SImode
+ || ! register_is_ok_for_epilogue (src, SImode))
+ return 0;
+
+ plus = XEXP (dest, 0);
+
+ if ( GET_CODE (plus) != PLUS
+ || GET_CODE (XEXP (plus, 0)) != REG
+ || GET_MODE (XEXP (plus, 0)) != SImode
+ || REGNO (XEXP (plus, 0)) != STACK_POINTER_REGNUM
+ || GET_CODE (XEXP (plus, 1)) != CONST_INT)
+ return 0;
+
+ /* If the register is being pushed somewhere other than the stack
+ space just acquired by the first operand then abandon this quest.
+ Note: the test is <= because both values are negative. */
+ if (INTVAL (XEXP (plus, 1))
+ <= INTVAL (XEXP (SET_SRC (XVECEXP (op, 0, 0)), 1)))
+ {
+ return 0;
+ }
+ }
+
+ /* Make sure that the last entries in the vector are clobbers. */
+ for (; i < count; i++)
+ {
+ vector_element = XVECEXP (op, 0, i);
+
+ if (GET_CODE (vector_element) != CLOBBER
+ || GET_CODE (XEXP (vector_element, 0)) != REG
+ || !(REGNO (XEXP (vector_element, 0)) == 10
+ || (TARGET_LONG_CALLS ? (REGNO (XEXP (vector_element, 0)) == 11) : 0 )))
+ return 0;
+ }
+
+ return 1;
+})
+
+;; Return nonzero if the given RTX is suitable for collapsing into
+;; jump to a function epilogue.
+
+(define_predicate "pattern_is_ok_for_epilogue"
+ (match_code "parallel")
+{
+ int count = XVECLEN (op, 0);
+ int i;
+
+ /* If there are no registers to restore then the function epilogue
+ is not suitable. */
+ if (count <= 2)
+ return 0;
+
+ /* The pattern matching has already established that we are performing a
+ function epilogue and that we are popping at least one register. We must
+ now check the remaining entries in the vector to make sure that they are
+ also register pops. There is no good reason why there should ever be
+ anything else in this vector, but being paranoid always helps...
+
+ The test below performs the C equivalent of this machine description
+ pattern match:
+
+ (set (match_operand:SI n "register_is_ok_for_epilogue" "r")
+ (mem:SI (plus:SI (reg:SI 3) (match_operand:SI n "immediate_operand" "i"))))
+ */
+
+ for (i = 3; i < count; i++)
+ {
+ rtx vector_element = XVECEXP (op, 0, i);
+ rtx dest;
+ rtx src;
+ rtx plus;
+
+ if (GET_CODE (vector_element) != SET)
+ return 0;
+
+ dest = SET_DEST (vector_element);
+ src = SET_SRC (vector_element);
+
+ if (GET_CODE (dest) != REG
+ || GET_MODE (dest) != SImode
+ || ! register_is_ok_for_epilogue (dest, SImode)
+ || GET_CODE (src) != MEM
+ || GET_MODE (src) != SImode)
+ return 0;
+
+ plus = XEXP (src, 0);
+
+ if (GET_CODE (plus) != PLUS
+ || GET_CODE (XEXP (plus, 0)) != REG
+ || GET_MODE (XEXP (plus, 0)) != SImode
+ || REGNO (XEXP (plus, 0)) != STACK_POINTER_REGNUM
+ || GET_CODE (XEXP (plus, 1)) != CONST_INT)
+ return 0;
+ }
+
+ return 1;
+})
+
+;; Return true if the given RTX is a register which can be restored by
+;; a function epilogue.
+
+(define_predicate "register_is_ok_for_epilogue"
+ (match_code "reg")
+{
+ /* The save/restore routines can only cope with registers 20 - 31. */
+ return ((GET_CODE (op) == REG)
+ && (((REGNO (op) >= 20) && REGNO (op) <= 31)));
+})
+
+;; Return nonzero if the given RTX is suitable for collapsing into a
+;; DISPOSE instruction.
+
+(define_predicate "pattern_is_ok_for_dispose"
+ (match_code "parallel")
+{
+ int count = XVECLEN (op, 0);
+ int i;
+
+ /* If there are no registers to restore then
+ the dispose instruction is not suitable. */
+ if (count <= 2)
+ return 0;
+
+ /* The pattern matching has already established that we are performing a
+ function epilogue and that we are popping at least one register. We must
+ now check the remaining entries in the vector to make sure that they are
+ also register pops. There is no good reason why there should ever be
+ anything else in this vector, but being paranoid always helps...
+
+ The test below performs the C equivalent of this machine description
+ pattern match:
+
+ (set (match_operand:SI n "register_is_ok_for_epilogue" "r")
+ (mem:SI (plus:SI (reg:SI 3)
+ (match_operand:SI n "immediate_operand" "i"))))
+ */
+
+ for (i = 3; i < count; i++)
+ {
+ rtx vector_element = XVECEXP (op, 0, i);
+ rtx dest;
+ rtx src;
+ rtx plus;
+
+ if (GET_CODE (vector_element) != SET)
+ return 0;
+
+ dest = SET_DEST (vector_element);
+ src = SET_SRC (vector_element);
+
+ if ( GET_CODE (dest) != REG
+ || GET_MODE (dest) != SImode
+ || ! register_is_ok_for_epilogue (dest, SImode)
+ || GET_CODE (src) != MEM
+ || GET_MODE (src) != SImode)
+ return 0;
+
+ plus = XEXP (src, 0);
+
+ if ( GET_CODE (plus) != PLUS
+ || GET_CODE (XEXP (plus, 0)) != REG
+ || GET_MODE (XEXP (plus, 0)) != SImode
+ || REGNO (XEXP (plus, 0)) != STACK_POINTER_REGNUM
+ || GET_CODE (XEXP (plus, 1)) != CONST_INT)
+ return 0;
+ }
+
+ return 1;
+})
+
+;; Return nonzero if the given RTX is suitable for collapsing into a
+;; PREPARE instruction.
+
+(define_predicate "pattern_is_ok_for_prepare"
+ (match_code "parallel")
+{
+ int count = XVECLEN (op, 0);
+ int i;
+
+ /* If there are no registers to restore then the prepare instruction
+ is not suitable. */
+ if (count <= 1)
+ return 0;
+
+ /* The pattern matching has already established that we are adjusting the
+ stack and pushing at least one register. We must now check that the
+ remaining entries in the vector to make sure that they are also register
+ pushes.
+
+ The test below performs the C equivalent of this machine description
+ pattern match:
+
+ (set (mem:SI (plus:SI (reg:SI 3)
+ (match_operand:SI 2 "immediate_operand" "i")))
+ (match_operand:SI 3 "register_is_ok_for_epilogue" "r"))
+
+ */
+
+ for (i = 2; i < count; i++)
+ {
+ rtx vector_element = XVECEXP (op, 0, i);
+ rtx dest;
+ rtx src;
+ rtx plus;
+
+ if (GET_CODE (vector_element) != SET)
+ return 0;
+
+ dest = SET_DEST (vector_element);
+ src = SET_SRC (vector_element);
+
+ if ( GET_CODE (dest) != MEM
+ || GET_MODE (dest) != SImode
+ || GET_CODE (src) != REG
+ || GET_MODE (src) != SImode
+ || ! register_is_ok_for_epilogue (src, SImode)
+ )
+ return 0;
+
+ plus = XEXP (dest, 0);
+
+ if ( GET_CODE (plus) != PLUS
+ || GET_CODE (XEXP (plus, 0)) != REG
+ || GET_MODE (XEXP (plus, 0)) != SImode
+ || REGNO (XEXP (plus, 0)) != STACK_POINTER_REGNUM
+ || GET_CODE (XEXP (plus, 1)) != CONST_INT)
+ return 0;
+
+ /* If the register is being pushed somewhere other than the stack
+ space just acquired by the first operand then abandon this quest.
+ Note: the test is <= because both values are negative. */
+ if (INTVAL (XEXP (plus, 1))
+ <= INTVAL (XEXP (SET_SRC (XVECEXP (op, 0, 0)), 1)))
+ return 0;
+ }
+
+ return 1;
+})
+
+;; TODO: Add a comment here.
+
+(define_predicate "not_power_of_two_operand"
+ (match_code "const_int")
+{
+ unsigned int mask;
+
+ if (mode == QImode)
+ mask = 0xff;
+ else if (mode == HImode)
+ mask = 0xffff;
+ else if (mode == SImode)
+ mask = 0xffffffff;
+ else
+ return 0;
+
+ if (GET_CODE (op) != CONST_INT)
+ return 0;
+
+ if (exact_log2 (~INTVAL (op) & mask) == -1)
+ return 0;
+ return 1;
+})
diff --git a/gcc/config/v850/v850-protos.h b/gcc/config/v850/v850-protos.h
index cb36601996b..5512c7e42a7 100644
--- a/gcc/config/v850/v850-protos.h
+++ b/gcc/config/v850/v850-protos.h
@@ -1,5 +1,5 @@
/* Prototypes for v850.c functions used in the md file & elsewhere.
- Copyright (C) 1999, 2000, 2002, 2004 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2002, 2004, 2005 Free Software Foundation, Inc.
This file is part of GCC.
@@ -51,23 +51,9 @@ extern void notice_update_cc (rtx, rtx);
extern char * construct_save_jarl (rtx);
extern char * construct_restore_jr (rtx);
#ifdef HAVE_MACHINE_MODES
-extern int reg_or_int9_operand (rtx, Mmode);
-extern int reg_or_const_operand (rtx, Mmode);
extern char * construct_dispose_instruction (rtx);
extern char * construct_prepare_instruction (rtx);
-extern int pattern_is_ok_for_prepare (rtx, Mmode);
-extern int pattern_is_ok_for_dispose (rtx, Mmode);
extern int ep_memory_operand (rtx, Mmode, int);
-extern int reg_or_0_operand (rtx, Mmode);
-extern int reg_or_int5_operand (rtx, Mmode);
-extern int call_address_operand (rtx, Mmode);
-extern int movsi_source_operand (rtx, Mmode);
-extern int power_of_two_operand (rtx, Mmode);
-extern int not_power_of_two_operand (rtx, Mmode);
-extern int special_symbolref_operand (rtx, Mmode);
-extern int pattern_is_ok_for_prologue (rtx, Mmode);
-extern int pattern_is_ok_for_epilogue (rtx, Mmode);
-extern int register_is_ok_for_epilogue (rtx, Mmode);
#ifdef TREE_CODE
extern rtx function_arg (CUMULATIVE_ARGS *, Mmode, tree, int);
#endif
diff --git a/gcc/config/v850/v850.c b/gcc/config/v850/v850.c
index f3a165d28f4..9026fa850a2 100644
--- a/gcc/config/v850/v850.c
+++ b/gcc/config/v850/v850.c
@@ -1,5 +1,5 @@
/* Subroutines for insn-output.c for NEC V850 series
- Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
+ Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
Free Software Foundation, Inc.
Contributed by Jeff Law (law@cygnus.com).
@@ -1078,132 +1078,6 @@ ep_memory_operand (rtx op, enum machine_mode mode, int unsigned_load)
return FALSE;
}
-
-/* Return true if OP is either a register or 0 */
-
-int
-reg_or_0_operand (rtx op, enum machine_mode mode)
-{
- if (GET_CODE (op) == CONST_INT)
- return INTVAL (op) == 0;
-
- else if (GET_CODE (op) == CONST_DOUBLE)
- return CONST_DOUBLE_OK_FOR_G (op);
-
- else
- return register_operand (op, mode);
-}
-
-/* Return true if OP is either a register or a signed five bit integer */
-
-int
-reg_or_int5_operand (rtx op, enum machine_mode mode)
-{
- if (GET_CODE (op) == CONST_INT)
- return CONST_OK_FOR_J (INTVAL (op));
-
- else
- return register_operand (op, mode);
-}
-
-/* Return true if OP is either a register or a signed nine bit integer. */
-
-int
-reg_or_int9_operand (rtx op, enum machine_mode mode)
-{
- if (GET_CODE (op) == CONST_INT)
- return CONST_OK_FOR_O (INTVAL (op));
-
- return register_operand (op, mode);
-}
-
-/* Return true if OP is either a register or a const integer. */
-
-int
-reg_or_const_operand (rtx op, enum machine_mode mode)
-{
- if (GET_CODE (op) == CONST_INT)
- return TRUE;
-
- return register_operand (op, mode);
-}
-
-/* Return true if OP is a valid call operand. */
-
-int
-call_address_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
- /* Only registers are valid call operands if TARGET_LONG_CALLS. */
- if (TARGET_LONG_CALLS)
- return GET_CODE (op) == REG;
- return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == REG);
-}
-
-int
-special_symbolref_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
- if (GET_CODE (op) == CONST
- && GET_CODE (XEXP (op, 0)) == PLUS
- && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT
- && CONST_OK_FOR_K (INTVAL (XEXP (XEXP (op, 0), 1))))
- op = XEXP (XEXP (op, 0), 0);
-
- if (GET_CODE (op) == SYMBOL_REF)
- return (SYMBOL_REF_FLAGS (op)
- & (SYMBOL_FLAG_ZDA | SYMBOL_FLAG_TDA | SYMBOL_FLAG_SDA)) != 0;
-
- return FALSE;
-}
-
-int
-movsi_source_operand (rtx op, enum machine_mode mode)
-{
- /* Some constants, as well as symbolic operands
- must be done with HIGH & LO_SUM patterns. */
- if (CONSTANT_P (op)
- && GET_CODE (op) != HIGH
- && !(GET_CODE (op) == CONST_INT
- && (CONST_OK_FOR_J (INTVAL (op))
- || CONST_OK_FOR_K (INTVAL (op))
- || CONST_OK_FOR_L (INTVAL (op)))))
- return special_symbolref_operand (op, mode);
- else
- return general_operand (op, mode);
-}
-
-int
-power_of_two_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
- if (GET_CODE (op) != CONST_INT)
- return 0;
-
- if (exact_log2 (INTVAL (op)) == -1)
- return 0;
- return 1;
-}
-
-int
-not_power_of_two_operand (rtx op, enum machine_mode mode)
-{
- unsigned int mask;
-
- if (mode == QImode)
- mask = 0xff;
- else if (mode == HImode)
- mask = 0xffff;
- else if (mode == SImode)
- mask = 0xffffffff;
- else
- return 0;
-
- if (GET_CODE (op) != CONST_INT)
- return 0;
-
- if (exact_log2 (~INTVAL (op) & mask) == -1)
- return 0;
- return 1;
-}
-
/* Substitute memory references involving a pointer, to use the ep pointer,
taking care to save and preserve the ep. */
@@ -2366,75 +2240,6 @@ v850_encode_section_info (tree decl, rtx rtl, int first)
v850_encode_data_area (decl, XEXP (rtl, 0));
}
-/* Return true if the given RTX is a register which can be restored
- by a function epilogue. */
-int
-register_is_ok_for_epilogue (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
- /* The save/restore routines can only cope with registers 20 - 31. */
- return ((GET_CODE (op) == REG)
- && (((REGNO (op) >= 20) && REGNO (op) <= 31)));
-}
-
-/* Return nonzero if the given RTX is suitable for collapsing into
- jump to a function epilogue. */
-int
-pattern_is_ok_for_epilogue (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
- int count = XVECLEN (op, 0);
- int i;
-
- /* If there are no registers to restore then the function epilogue
- is not suitable. */
- if (count <= 2)
- return 0;
-
- /* The pattern matching has already established that we are performing a
- function epilogue and that we are popping at least one register. We must
- now check the remaining entries in the vector to make sure that they are
- also register pops. There is no good reason why there should ever be
- anything else in this vector, but being paranoid always helps...
-
- The test below performs the C equivalent of this machine description
- pattern match:
-
- (set (match_operand:SI n "register_is_ok_for_epilogue" "r")
- (mem:SI (plus:SI (reg:SI 3) (match_operand:SI n "immediate_operand" "i"))))
- */
-
- for (i = 3; i < count; i++)
- {
- rtx vector_element = XVECEXP (op, 0, i);
- rtx dest;
- rtx src;
- rtx plus;
-
- if (GET_CODE (vector_element) != SET)
- return 0;
-
- dest = SET_DEST (vector_element);
- src = SET_SRC (vector_element);
-
- if (GET_CODE (dest) != REG
- || GET_MODE (dest) != SImode
- || ! register_is_ok_for_epilogue (dest, SImode)
- || GET_CODE (src) != MEM
- || GET_MODE (src) != SImode)
- return 0;
-
- plus = XEXP (src, 0);
-
- if (GET_CODE (plus) != PLUS
- || GET_CODE (XEXP (plus, 0)) != REG
- || GET_MODE (XEXP (plus, 0)) != SImode
- || REGNO (XEXP (plus, 0)) != STACK_POINTER_REGNUM
- || GET_CODE (XEXP (plus, 1)) != CONST_INT)
- return 0;
- }
-
- return 1;
-}
-
/* Construct a JR instruction to a routine that will perform the equivalent of
the RTL passed in as an argument. This RTL is a function epilogue that
pops registers off the stack and possibly releases some extra stack space
@@ -2552,89 +2357,6 @@ construct_restore_jr (rtx op)
}
-/* Return nonzero if the given RTX is suitable for collapsing into
- a jump to a function prologue. */
-int
-pattern_is_ok_for_prologue (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
- int count = XVECLEN (op, 0);
- int i;
- rtx vector_element;
-
- /* If there are no registers to save then the function prologue
- is not suitable. */
- if (count <= 2)
- return 0;
-
- /* The pattern matching has already established that we are adjusting the
- stack and pushing at least one register. We must now check that the
- remaining entries in the vector to make sure that they are also register
- pushes, except for the last entry which should be a CLOBBER of r10.
-
- The test below performs the C equivalent of this machine description
- pattern match:
-
- (set (mem:SI (plus:SI (reg:SI 3)
- (match_operand:SI 2 "immediate_operand" "i")))
- (match_operand:SI 3 "register_is_ok_for_epilogue" "r"))
-
- */
-
- for (i = 2; i < count - (TARGET_LONG_CALLS ? 2: 1); i++)
- {
- rtx dest;
- rtx src;
- rtx plus;
-
- vector_element = XVECEXP (op, 0, i);
-
- if (GET_CODE (vector_element) != SET)
- return 0;
-
- dest = SET_DEST (vector_element);
- src = SET_SRC (vector_element);
-
- if (GET_CODE (dest) != MEM
- || GET_MODE (dest) != SImode
- || GET_CODE (src) != REG
- || GET_MODE (src) != SImode
- || ! register_is_ok_for_epilogue (src, SImode))
- return 0;
-
- plus = XEXP (dest, 0);
-
- if ( GET_CODE (plus) != PLUS
- || GET_CODE (XEXP (plus, 0)) != REG
- || GET_MODE (XEXP (plus, 0)) != SImode
- || REGNO (XEXP (plus, 0)) != STACK_POINTER_REGNUM
- || GET_CODE (XEXP (plus, 1)) != CONST_INT)
- return 0;
-
- /* If the register is being pushed somewhere other than the stack
- space just acquired by the first operand then abandon this quest.
- Note: the test is <= because both values are negative. */
- if (INTVAL (XEXP (plus, 1))
- <= INTVAL (XEXP (SET_SRC (XVECEXP (op, 0, 0)), 1)))
- {
- return 0;
- }
- }
-
- /* Make sure that the last entries in the vector are clobbers. */
- for (; i < count; i++)
- {
- vector_element = XVECEXP (op, 0, i);
-
- if (GET_CODE (vector_element) != CLOBBER
- || GET_CODE (XEXP (vector_element, 0)) != REG
- || !(REGNO (XEXP (vector_element, 0)) == 10
- || (TARGET_LONG_CALLS ? (REGNO (XEXP (vector_element, 0)) == 11) : 0 )))
- return 0;
- }
-
- return 1;
-}
-
/* Construct a JARL instruction to a routine that will perform the equivalent
of the RTL passed as a parameter. This RTL is a function prologue that
saves some of the registers r20 - r31 onto the stack, and possibly acquires
@@ -2946,67 +2668,6 @@ v850_insert_attributes (tree decl, tree * attr_ptr ATTRIBUTE_UNUSED )
}
}
-/* Return nonzero if the given RTX is suitable
- for collapsing into a DISPOSE instruction. */
-
-int
-pattern_is_ok_for_dispose (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
- int count = XVECLEN (op, 0);
- int i;
-
- /* If there are no registers to restore then
- the dispose instruction is not suitable. */
- if (count <= 2)
- return 0;
-
- /* The pattern matching has already established that we are performing a
- function epilogue and that we are popping at least one register. We must
- now check the remaining entries in the vector to make sure that they are
- also register pops. There is no good reason why there should ever be
- anything else in this vector, but being paranoid always helps...
-
- The test below performs the C equivalent of this machine description
- pattern match:
-
- (set (match_operand:SI n "register_is_ok_for_epilogue" "r")
- (mem:SI (plus:SI (reg:SI 3)
- (match_operand:SI n "immediate_operand" "i"))))
- */
-
- for (i = 3; i < count; i++)
- {
- rtx vector_element = XVECEXP (op, 0, i);
- rtx dest;
- rtx src;
- rtx plus;
-
- if (GET_CODE (vector_element) != SET)
- return 0;
-
- dest = SET_DEST (vector_element);
- src = SET_SRC (vector_element);
-
- if ( GET_CODE (dest) != REG
- || GET_MODE (dest) != SImode
- || ! register_is_ok_for_epilogue (dest, SImode)
- || GET_CODE (src) != MEM
- || GET_MODE (src) != SImode)
- return 0;
-
- plus = XEXP (src, 0);
-
- if ( GET_CODE (plus) != PLUS
- || GET_CODE (XEXP (plus, 0)) != REG
- || GET_MODE (XEXP (plus, 0)) != SImode
- || REGNO (XEXP (plus, 0)) != STACK_POINTER_REGNUM
- || GET_CODE (XEXP (plus, 1)) != CONST_INT)
- return 0;
- }
-
- return 1;
-}
-
/* Construct a DISPOSE instruction that is the equivalent of
the given RTX. We have already verified that this should
be possible. */
@@ -3133,75 +2794,6 @@ construct_dispose_instruction (rtx op)
return buff;
}
-/* Return nonzero if the given RTX is suitable
- for collapsing into a PREPARE instruction. */
-
-int
-pattern_is_ok_for_prepare (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
- int count = XVECLEN (op, 0);
- int i;
-
- /* If there are no registers to restore then the prepare instruction
- is not suitable. */
- if (count <= 1)
- return 0;
-
- /* The pattern matching has already established that we are adjusting the
- stack and pushing at least one register. We must now check that the
- remaining entries in the vector to make sure that they are also register
- pushes.
-
- The test below performs the C equivalent of this machine description
- pattern match:
-
- (set (mem:SI (plus:SI (reg:SI 3)
- (match_operand:SI 2 "immediate_operand" "i")))
- (match_operand:SI 3 "register_is_ok_for_epilogue" "r"))
-
- */
-
- for (i = 2; i < count; i++)
- {
- rtx vector_element = XVECEXP (op, 0, i);
- rtx dest;
- rtx src;
- rtx plus;
-
- if (GET_CODE (vector_element) != SET)
- return 0;
-
- dest = SET_DEST (vector_element);
- src = SET_SRC (vector_element);
-
- if ( GET_CODE (dest) != MEM
- || GET_MODE (dest) != SImode
- || GET_CODE (src) != REG
- || GET_MODE (src) != SImode
- || ! register_is_ok_for_epilogue (src, SImode)
- )
- return 0;
-
- plus = XEXP (dest, 0);
-
- if ( GET_CODE (plus) != PLUS
- || GET_CODE (XEXP (plus, 0)) != REG
- || GET_MODE (XEXP (plus, 0)) != SImode
- || REGNO (XEXP (plus, 0)) != STACK_POINTER_REGNUM
- || GET_CODE (XEXP (plus, 1)) != CONST_INT)
- return 0;
-
- /* If the register is being pushed somewhere other than the stack
- space just acquired by the first operand then abandon this quest.
- Note: the test is <= because both values are negative. */
- if (INTVAL (XEXP (plus, 1))
- <= INTVAL (XEXP (SET_SRC (XVECEXP (op, 0, 0)), 1)))
- return 0;
- }
-
- return 1;
-}
-
/* Construct a PREPARE instruction that is the equivalent of
the given RTL. We have already verified that this should
be possible. */
diff --git a/gcc/config/v850/v850.h b/gcc/config/v850/v850.h
index d878f39b8b8..1d2b91c10f9 100644
--- a/gcc/config/v850/v850.h
+++ b/gcc/config/v850/v850.h
@@ -1,5 +1,5 @@
/* Definitions of target machine for GNU compiler. NEC V850 series
- Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
+ Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
Free Software Foundation, Inc.
Contributed by Jeff Law (law@cygnus.com).
@@ -1368,29 +1368,4 @@ extern union tree_node * GHS_current_section_names [(int) COUNT_OF_GHS_SECTION_K
#define SYMBOL_REF_TDA_P(X) ((SYMBOL_REF_FLAGS (X) & SYMBOL_FLAG_TDA) != 0)
#define SYMBOL_REF_SDA_P(X) ((SYMBOL_REF_FLAGS (X) & SYMBOL_FLAG_SDA) != 0)
-/* Define this if you have defined special-purpose predicates in the
- file `MACHINE.c'. This macro is called within an initializer of an
- array of structures. The first field in the structure is the name
- of a predicate and the second field is an array of rtl codes. For
- each predicate, list all rtl codes that can be in expressions
- matched by the predicate. The list should have a trailing comma. */
-
-#define PREDICATE_CODES \
-{ "reg_or_0_operand", { REG, SUBREG, CONST_INT, CONST_DOUBLE }}, \
-{ "reg_or_int5_operand", { REG, SUBREG, CONST_INT }}, \
-{ "reg_or_int9_operand", { REG, SUBREG, CONST_INT }}, \
-{ "reg_or_const_operand", { REG, CONST_INT }}, \
-{ "call_address_operand", { REG, SYMBOL_REF }}, \
-{ "movsi_source_operand", { LABEL_REF, SYMBOL_REF, CONST_INT, \
- CONST_DOUBLE, CONST, HIGH, MEM, \
- REG, SUBREG }}, \
-{ "special_symbolref_operand", { SYMBOL_REF }}, \
-{ "power_of_two_operand", { CONST_INT }}, \
-{ "pattern_is_ok_for_prologue", { PARALLEL }}, \
-{ "pattern_is_ok_for_epilogue", { PARALLEL }}, \
-{ "register_is_ok_for_epilogue",{ REG }}, \
-{ "pattern_is_ok_for_dispose", { PARALLEL }}, \
-{ "pattern_is_ok_for_prepare", { PARALLEL }}, \
-{ "not_power_of_two_operand", { CONST_INT }},
-
#endif /* ! GCC_V850_H */
diff --git a/gcc/config/v850/v850.md b/gcc/config/v850/v850.md
index cc82079629b..b4dd0285c8d 100644
--- a/gcc/config/v850/v850.md
+++ b/gcc/config/v850/v850.md
@@ -1,5 +1,5 @@
;; GCC machine description for NEC V850
-;; Copyright (C) 1996, 1997, 1998, 1999, 2002, 2004
+;; Copyright (C) 1996, 1997, 1998, 1999, 2002, 2004, 2005
;; Free Software Foundation, Inc.
;; Contributed by Jeff Law (law@cygnus.com).
@@ -71,6 +71,8 @@
(define_insn_reservation "v850_memory" 2
(eq_attr "type" "load")
"nothing")
+
+(include "predicates.md")
;; ----------------------------------------------------------------------
;; MOVE INSTRUCTIONS