v850-protos.h: Remove the prototypes for reg_or_int9_operand...

* 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.

From-SVN: r96822
This commit is contained in:
Kazu Hirata 2005-03-21 18:01:29 +00:00 committed by Kazu Hirata
parent f08dd1f8f3
commit 83310f5688
6 changed files with 467 additions and 451 deletions

View File

@ -1,3 +1,25 @@
2005-03-21 Kazu Hirata <kazu@cs.umass.edu>
* 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.
2005-03-21 Zack Weinberg <zack@codesourcery.com>
* Makefile.in (BASEVER, DEVPHASE, DATESTAMP)

View File

@ -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;
})

View File

@ -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

View File

@ -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. */

View File

@ -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 */

View File

@ -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