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:
parent
f08dd1f8f3
commit
83310f5688
@ -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)
|
||||
|
439
gcc/config/v850/predicates.md
Normal file
439
gcc/config/v850/predicates.md
Normal 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;
|
||||
})
|
@ -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
|
||||
|
@ -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. */
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user