diff options
author | kazu <kazu@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-03-21 18:01:29 +0000 |
---|---|---|
committer | kazu <kazu@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-03-21 18:01:29 +0000 |
commit | db5c82c4c684a2c57aa5f04d732450fdf3e01b79 (patch) | |
tree | 4b7eb16eb0e044e4279433c45d2895a812452741 /gcc/config/v850 | |
parent | ff84d87f9010971b68351a57ce677422d8c21a47 (diff) | |
download | gcc-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.md | 439 | ||||
-rw-r--r-- | gcc/config/v850/v850-protos.h | 16 | ||||
-rw-r--r-- | gcc/config/v850/v850.c | 410 | ||||
-rw-r--r-- | gcc/config/v850/v850.h | 27 | ||||
-rw-r--r-- | gcc/config/v850/v850.md | 4 |
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 |