;; Predicate definitions for Renesas M32R.
|
;; Predicate definitions for Renesas M32R.
|
;; Copyright (C) 2005, 2007 Free Software Foundation, Inc.
|
;; Copyright (C) 2005, 2007 Free Software Foundation, Inc.
|
;;
|
;;
|
;; This file is part of GCC.
|
;; This file is part of GCC.
|
;;
|
;;
|
;; GCC is free software; you can redistribute it and/or modify
|
;; GCC is free software; you can redistribute it and/or modify
|
;; it under the terms of the GNU General Public License as published by
|
;; it under the terms of the GNU General Public License as published by
|
;; the Free Software Foundation; either version 3, or (at your option)
|
;; the Free Software Foundation; either version 3, or (at your option)
|
;; any later version.
|
;; any later version.
|
;;
|
;;
|
;; GCC is distributed in the hope that it will be useful,
|
;; GCC is distributed in the hope that it will be useful,
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
;; GNU General Public License for more details.
|
;; GNU General Public License for more details.
|
;;
|
;;
|
;; You should have received a copy of the GNU General Public License
|
;; You should have received a copy of the GNU General Public License
|
;; along with GCC; see the file COPYING3. If not see
|
;; along with GCC; see the file COPYING3. If not see
|
;; .
|
;; .
|
|
|
;; Return true if OP is a register or the constant 0.
|
;; Return true if OP is a register or the constant 0.
|
|
|
(define_predicate "reg_or_zero_operand"
|
(define_predicate "reg_or_zero_operand"
|
(match_code "reg,subreg,const_int")
|
(match_code "reg,subreg,const_int")
|
{
|
{
|
if (REG_P (op) || GET_CODE (op) == SUBREG)
|
if (REG_P (op) || GET_CODE (op) == SUBREG)
|
return register_operand (op, mode);
|
return register_operand (op, mode);
|
|
|
if (!CONST_INT_P (op))
|
if (!CONST_INT_P (op))
|
return 0;
|
return 0;
|
|
|
return INTVAL (op) == 0;
|
return INTVAL (op) == 0;
|
})
|
})
|
|
|
;; Return nonzero if the operand is suitable for use in a conditional
|
;; Return nonzero if the operand is suitable for use in a conditional
|
;; move sequence.
|
;; move sequence.
|
|
|
(define_predicate "conditional_move_operand"
|
(define_predicate "conditional_move_operand"
|
(match_code "reg,subreg,const_int")
|
(match_code "reg,subreg,const_int")
|
{
|
{
|
/* Only defined for simple integers so far... */
|
/* Only defined for simple integers so far... */
|
if (mode != SImode && mode != HImode && mode != QImode)
|
if (mode != SImode && mode != HImode && mode != QImode)
|
return FALSE;
|
return FALSE;
|
|
|
/* At the moment we can handle moving registers and loading constants. */
|
/* At the moment we can handle moving registers and loading constants. */
|
/* To be added: Addition/subtraction/bitops/multiplication of registers. */
|
/* To be added: Addition/subtraction/bitops/multiplication of registers. */
|
|
|
switch (GET_CODE (op))
|
switch (GET_CODE (op))
|
{
|
{
|
case REG:
|
case REG:
|
return 1;
|
return 1;
|
|
|
case CONST_INT:
|
case CONST_INT:
|
return satisfies_constraint_I (op);
|
return satisfies_constraint_I (op);
|
|
|
default:
|
default:
|
#if 0
|
#if 0
|
fprintf (stderr, "Test for cond move op of type: %s\n",
|
fprintf (stderr, "Test for cond move op of type: %s\n",
|
GET_RTX_NAME (GET_CODE (op)));
|
GET_RTX_NAME (GET_CODE (op)));
|
#endif
|
#endif
|
return 0;
|
return 0;
|
}
|
}
|
})
|
})
|
|
|
;; Return true if the code is a test of the carry bit.
|
;; Return true if the code is a test of the carry bit.
|
|
|
(define_predicate "carry_compare_operand"
|
(define_predicate "carry_compare_operand"
|
(match_code "eq,ne")
|
(match_code "eq,ne")
|
{
|
{
|
rtx x;
|
rtx x;
|
|
|
if (GET_MODE (op) != CCmode && GET_MODE (op) != VOIDmode)
|
if (GET_MODE (op) != CCmode && GET_MODE (op) != VOIDmode)
|
return FALSE;
|
return FALSE;
|
|
|
if (GET_CODE (op) != NE && GET_CODE (op) != EQ)
|
if (GET_CODE (op) != NE && GET_CODE (op) != EQ)
|
return FALSE;
|
return FALSE;
|
|
|
x = XEXP (op, 0);
|
x = XEXP (op, 0);
|
if (!REG_P (x) || REGNO (x) != CARRY_REGNUM)
|
if (!REG_P (x) || REGNO (x) != CARRY_REGNUM)
|
return FALSE;
|
return FALSE;
|
|
|
x = XEXP (op, 1);
|
x = XEXP (op, 1);
|
if (!CONST_INT_P (x) || INTVAL (x) != 0)
|
if (!CONST_INT_P (x) || INTVAL (x) != 0)
|
return FALSE;
|
return FALSE;
|
|
|
return TRUE;
|
return TRUE;
|
})
|
})
|
|
|
;; Return 1 if OP is an EQ or NE comparison operator.
|
;; Return 1 if OP is an EQ or NE comparison operator.
|
|
|
(define_predicate "eqne_comparison_operator"
|
(define_predicate "eqne_comparison_operator"
|
(match_code "eq,ne")
|
(match_code "eq,ne")
|
{
|
{
|
enum rtx_code code = GET_CODE (op);
|
enum rtx_code code = GET_CODE (op);
|
|
|
return (code == EQ || code == NE);
|
return (code == EQ || code == NE);
|
})
|
})
|
|
|
;; Return 1 if OP is a signed comparison operator.
|
;; Return 1 if OP is a signed comparison operator.
|
|
|
(define_predicate "signed_comparison_operator"
|
(define_predicate "signed_comparison_operator"
|
(match_code "eq,ne,lt,le,gt,ge")
|
(match_code "eq,ne,lt,le,gt,ge")
|
{
|
{
|
enum rtx_code code = GET_CODE (op);
|
enum rtx_code code = GET_CODE (op);
|
|
|
return (COMPARISON_P (op)
|
return (COMPARISON_P (op)
|
&& (code == EQ || code == NE
|
&& (code == EQ || code == NE
|
|| code == LT || code == LE || code == GT || code == GE));
|
|| code == LT || code == LE || code == GT || code == GE));
|
})
|
})
|
|
|
;; Return true if OP is an acceptable argument for a move destination.
|
;; Return true if OP is an acceptable argument for a move destination.
|
|
|
(define_predicate "move_dest_operand"
|
(define_predicate "move_dest_operand"
|
(match_code "reg,subreg,mem")
|
(match_code "reg,subreg,mem")
|
{
|
{
|
switch (GET_CODE (op))
|
switch (GET_CODE (op))
|
{
|
{
|
case REG :
|
case REG :
|
return register_operand (op, mode);
|
return register_operand (op, mode);
|
case SUBREG :
|
case SUBREG :
|
/* (subreg (mem ...) ...) can occur here if the inner part was once a
|
/* (subreg (mem ...) ...) can occur here if the inner part was once a
|
pseudo-reg and is now a stack slot. */
|
pseudo-reg and is now a stack slot. */
|
if (MEM_P (SUBREG_REG (op)))
|
if (MEM_P (SUBREG_REG (op)))
|
return address_operand (XEXP (SUBREG_REG (op), 0), mode);
|
return address_operand (XEXP (SUBREG_REG (op), 0), mode);
|
else
|
else
|
return register_operand (op, mode);
|
return register_operand (op, mode);
|
case MEM :
|
case MEM :
|
if (GET_CODE (XEXP (op, 0)) == POST_INC)
|
if (GET_CODE (XEXP (op, 0)) == POST_INC)
|
return 0; /* stores can't do post inc */
|
return 0; /* stores can't do post inc */
|
return address_operand (XEXP (op, 0), mode);
|
return address_operand (XEXP (op, 0), mode);
|
default :
|
default :
|
return 0;
|
return 0;
|
}
|
}
|
})
|
})
|
|
|
;; Return true if OP is an acceptable argument for a single word move
|
;; Return true if OP is an acceptable argument for a single word move
|
;; source.
|
;; source.
|
|
|
(define_predicate "move_src_operand"
|
(define_predicate "move_src_operand"
|
(match_code "reg,subreg,mem,const_int,const_double,label_ref,const,symbol_ref")
|
(match_code "reg,subreg,mem,const_int,const_double,label_ref,const,symbol_ref")
|
{
|
{
|
switch (GET_CODE (op))
|
switch (GET_CODE (op))
|
{
|
{
|
case LABEL_REF :
|
case LABEL_REF :
|
case SYMBOL_REF :
|
case SYMBOL_REF :
|
case CONST :
|
case CONST :
|
return addr24_operand (op, mode);
|
return addr24_operand (op, mode);
|
case CONST_INT :
|
case CONST_INT :
|
/* ??? We allow more cse opportunities if we only allow constants
|
/* ??? We allow more cse opportunities if we only allow constants
|
loadable with one insn, and split the rest into two. The instances
|
loadable with one insn, and split the rest into two. The instances
|
where this would help should be rare and the current way is
|
where this would help should be rare and the current way is
|
simpler. */
|
simpler. */
|
if (HOST_BITS_PER_WIDE_INT > 32)
|
if (HOST_BITS_PER_WIDE_INT > 32)
|
{
|
{
|
HOST_WIDE_INT rest = INTVAL (op) >> 31;
|
HOST_WIDE_INT rest = INTVAL (op) >> 31;
|
return (rest == 0 || rest == -1);
|
return (rest == 0 || rest == -1);
|
}
|
}
|
else
|
else
|
return 1;
|
return 1;
|
case CONST_DOUBLE :
|
case CONST_DOUBLE :
|
if (mode == SFmode)
|
if (mode == SFmode)
|
return 1;
|
return 1;
|
else if (mode == SImode)
|
else if (mode == SImode)
|
{
|
{
|
/* Large unsigned constants are represented as const_double's. */
|
/* Large unsigned constants are represented as const_double's. */
|
unsigned HOST_WIDE_INT low, high;
|
unsigned HOST_WIDE_INT low, high;
|
|
|
low = CONST_DOUBLE_LOW (op);
|
low = CONST_DOUBLE_LOW (op);
|
high = CONST_DOUBLE_HIGH (op);
|
high = CONST_DOUBLE_HIGH (op);
|
return high == 0 && low <= (unsigned) 0xffffffff;
|
return high == 0 && low <= (unsigned) 0xffffffff;
|
}
|
}
|
else
|
else
|
return 0;
|
return 0;
|
case REG :
|
case REG :
|
return register_operand (op, mode);
|
return register_operand (op, mode);
|
case SUBREG :
|
case SUBREG :
|
/* (subreg (mem ...) ...) can occur here if the inner part was once a
|
/* (subreg (mem ...) ...) can occur here if the inner part was once a
|
pseudo-reg and is now a stack slot. */
|
pseudo-reg and is now a stack slot. */
|
if (MEM_P (SUBREG_REG (op)))
|
if (MEM_P (SUBREG_REG (op)))
|
return address_operand (XEXP (SUBREG_REG (op), 0), mode);
|
return address_operand (XEXP (SUBREG_REG (op), 0), mode);
|
else
|
else
|
return register_operand (op, mode);
|
return register_operand (op, mode);
|
case MEM :
|
case MEM :
|
if (GET_CODE (XEXP (op, 0)) == PRE_INC
|
if (GET_CODE (XEXP (op, 0)) == PRE_INC
|
|| GET_CODE (XEXP (op, 0)) == PRE_DEC)
|
|| GET_CODE (XEXP (op, 0)) == PRE_DEC)
|
return 0; /* loads can't do pre-{inc,dec} */
|
return 0; /* loads can't do pre-{inc,dec} */
|
return address_operand (XEXP (op, 0), mode);
|
return address_operand (XEXP (op, 0), mode);
|
default :
|
default :
|
return 0;
|
return 0;
|
}
|
}
|
})
|
})
|
|
|
;; Return true if OP is an acceptable argument for a double word move
|
;; Return true if OP is an acceptable argument for a double word move
|
;; source.
|
;; source.
|
|
|
(define_predicate "move_double_src_operand"
|
(define_predicate "move_double_src_operand"
|
(match_code "reg,subreg,mem,const_int,const_double")
|
(match_code "reg,subreg,mem,const_int,const_double")
|
{
|
{
|
switch (GET_CODE (op))
|
switch (GET_CODE (op))
|
{
|
{
|
case CONST_INT :
|
case CONST_INT :
|
case CONST_DOUBLE :
|
case CONST_DOUBLE :
|
return 1;
|
return 1;
|
case REG :
|
case REG :
|
return register_operand (op, mode);
|
return register_operand (op, mode);
|
case SUBREG :
|
case SUBREG :
|
/* (subreg (mem ...) ...) can occur here if the inner part was once a
|
/* (subreg (mem ...) ...) can occur here if the inner part was once a
|
pseudo-reg and is now a stack slot. */
|
pseudo-reg and is now a stack slot. */
|
if (MEM_P (SUBREG_REG (op)))
|
if (MEM_P (SUBREG_REG (op)))
|
return move_double_src_operand (SUBREG_REG (op), mode);
|
return move_double_src_operand (SUBREG_REG (op), mode);
|
else
|
else
|
return register_operand (op, mode);
|
return register_operand (op, mode);
|
case MEM :
|
case MEM :
|
/* Disallow auto inc/dec for now. */
|
/* Disallow auto inc/dec for now. */
|
if (GET_CODE (XEXP (op, 0)) == PRE_DEC
|
if (GET_CODE (XEXP (op, 0)) == PRE_DEC
|
|| GET_CODE (XEXP (op, 0)) == PRE_INC)
|
|| GET_CODE (XEXP (op, 0)) == PRE_INC)
|
return 0;
|
return 0;
|
return address_operand (XEXP (op, 0), mode);
|
return address_operand (XEXP (op, 0), mode);
|
default :
|
default :
|
return 0;
|
return 0;
|
}
|
}
|
})
|
})
|
|
|
;; Return true if OP is a const_int requiring two instructions to
|
;; Return true if OP is a const_int requiring two instructions to
|
;; load.
|
;; load.
|
|
|
(define_predicate "two_insn_const_operand"
|
(define_predicate "two_insn_const_operand"
|
(match_code "const_int")
|
(match_code "const_int")
|
{
|
{
|
if (!CONST_INT_P (op))
|
if (!CONST_INT_P (op))
|
return 0;
|
return 0;
|
if (satisfies_constraint_J (op)
|
if (satisfies_constraint_J (op)
|
|| satisfies_constraint_M (op)
|
|| satisfies_constraint_M (op)
|
|| satisfies_constraint_L (op))
|
|| satisfies_constraint_L (op))
|
return 0;
|
return 0;
|
return 1;
|
return 1;
|
})
|
})
|
|
|
;; Returns 1 if OP is a symbol reference.
|
;; Returns 1 if OP is a symbol reference.
|
|
|
(define_predicate "symbolic_operand"
|
(define_predicate "symbolic_operand"
|
(match_code "symbol_ref,label_ref,const")
|
(match_code "symbol_ref,label_ref,const")
|
{
|
{
|
switch (GET_CODE (op))
|
switch (GET_CODE (op))
|
{
|
{
|
case SYMBOL_REF:
|
case SYMBOL_REF:
|
case LABEL_REF:
|
case LABEL_REF:
|
case CONST :
|
case CONST :
|
return 1;
|
return 1;
|
|
|
default:
|
default:
|
return 0;
|
return 0;
|
}
|
}
|
})
|
})
|
|
|
;; Return true if OP is a signed 8-bit immediate value.
|
;; Return true if OP is a signed 8-bit immediate value.
|
|
|
(define_predicate "int8_operand"
|
(define_predicate "int8_operand"
|
(match_code "const_int")
|
(match_code "const_int")
|
{
|
{
|
if (!CONST_INT_P (op))
|
if (!CONST_INT_P (op))
|
return 0;
|
return 0;
|
return satisfies_constraint_I (op);
|
return satisfies_constraint_I (op);
|
})
|
})
|
|
|
;; Return true if OP is an unsigned 16-bit immediate value.
|
;; Return true if OP is an unsigned 16-bit immediate value.
|
|
|
(define_predicate "uint16_operand"
|
(define_predicate "uint16_operand"
|
(match_code "const_int")
|
(match_code "const_int")
|
{
|
{
|
if (!CONST_INT_P (op))
|
if (!CONST_INT_P (op))
|
return 0;
|
return 0;
|
return satisfies_constraint_K (op);
|
return satisfies_constraint_K (op);
|
})
|
})
|
|
|
;; Return true if OP is a register or signed 16-bit value.
|
;; Return true if OP is a register or signed 16-bit value.
|
|
|
(define_predicate "reg_or_int16_operand"
|
(define_predicate "reg_or_int16_operand"
|
(match_code "reg,subreg,const_int")
|
(match_code "reg,subreg,const_int")
|
{
|
{
|
if (REG_P (op) || GET_CODE (op) == SUBREG)
|
if (REG_P (op) || GET_CODE (op) == SUBREG)
|
return register_operand (op, mode);
|
return register_operand (op, mode);
|
if (!CONST_INT_P (op))
|
if (!CONST_INT_P (op))
|
return 0;
|
return 0;
|
return satisfies_constraint_J (op);
|
return satisfies_constraint_J (op);
|
})
|
})
|
|
|
;; Return true if OP is a register or an unsigned 16-bit value.
|
;; Return true if OP is a register or an unsigned 16-bit value.
|
|
|
(define_predicate "reg_or_uint16_operand"
|
(define_predicate "reg_or_uint16_operand"
|
(match_code "reg,subreg,const_int")
|
(match_code "reg,subreg,const_int")
|
{
|
{
|
if (REG_P (op) || GET_CODE (op) == SUBREG)
|
if (REG_P (op) || GET_CODE (op) == SUBREG)
|
return register_operand (op, mode);
|
return register_operand (op, mode);
|
if (!CONST_INT_P (op))
|
if (!CONST_INT_P (op))
|
return 0;
|
return 0;
|
return satisfies_constraint_K (op);
|
return satisfies_constraint_K (op);
|
})
|
})
|
|
|
;; Return true if OP is a register or signed 16-bit value for
|
;; Return true if OP is a register or signed 16-bit value for
|
;; compares.
|
;; compares.
|
|
|
(define_predicate "reg_or_cmp_int16_operand"
|
(define_predicate "reg_or_cmp_int16_operand"
|
(match_code "reg,subreg,const_int")
|
(match_code "reg,subreg,const_int")
|
{
|
{
|
if (REG_P (op) || GET_CODE (op) == SUBREG)
|
if (REG_P (op) || GET_CODE (op) == SUBREG)
|
return register_operand (op, mode);
|
return register_operand (op, mode);
|
if (!CONST_INT_P (op))
|
if (!CONST_INT_P (op))
|
return 0;
|
return 0;
|
return satisfies_constraint_P (op);
|
return satisfies_constraint_P (op);
|
})
|
})
|
|
|
;; Return true if OP is a register or an integer value that can be
|
;; Return true if OP is a register or an integer value that can be
|
;; used is SEQ/SNE. We can use either XOR of the value or ADD of the
|
;; used is SEQ/SNE. We can use either XOR of the value or ADD of the
|
;; negative of the value for the constant. Don't allow 0, because
|
;; negative of the value for the constant. Don't allow 0, because
|
;; that is special cased.
|
;; that is special cased.
|
|
|
(define_predicate "reg_or_eq_int16_operand"
|
(define_predicate "reg_or_eq_int16_operand"
|
(match_code "reg,subreg,const_int")
|
(match_code "reg,subreg,const_int")
|
{
|
{
|
HOST_WIDE_INT value;
|
HOST_WIDE_INT value;
|
|
|
if (REG_P (op) || GET_CODE (op) == SUBREG)
|
if (REG_P (op) || GET_CODE (op) == SUBREG)
|
return register_operand (op, mode);
|
return register_operand (op, mode);
|
|
|
if (!CONST_INT_P (op))
|
if (!CONST_INT_P (op))
|
return 0;
|
return 0;
|
|
|
value = INTVAL (op);
|
value = INTVAL (op);
|
return (value != 0) && (UINT16_P (value) || CMP_INT16_P (-value));
|
return (value != 0) && (UINT16_P (value) || CMP_INT16_P (-value));
|
})
|
})
|
|
|
;; Return true if OP is a signed 16-bit immediate value useful in
|
;; Return true if OP is a signed 16-bit immediate value useful in
|
;; comparisons.
|
;; comparisons.
|
|
|
(define_predicate "cmp_int16_operand"
|
(define_predicate "cmp_int16_operand"
|
(match_code "const_int")
|
(match_code "const_int")
|
{
|
{
|
if (!CONST_INT_P (op))
|
if (!CONST_INT_P (op))
|
return 0;
|
return 0;
|
return satisfies_constraint_P (op);
|
return satisfies_constraint_P (op);
|
})
|
})
|
|
|
;; Acceptable arguments to the call insn.
|
;; Acceptable arguments to the call insn.
|
|
|
(define_predicate "call_address_operand"
|
(define_predicate "call_address_operand"
|
(match_code "symbol_ref,label_ref,const")
|
(match_code "symbol_ref,label_ref,const")
|
{
|
{
|
return symbolic_operand (op, mode);
|
return symbolic_operand (op, mode);
|
|
|
/* Constants and values in registers are not OK, because
|
/* Constants and values in registers are not OK, because
|
the m32r BL instruction can only support PC relative branching. */
|
the m32r BL instruction can only support PC relative branching. */
|
})
|
})
|
|
|
;; Return true if OP is an acceptable input argument for a zero/sign
|
;; Return true if OP is an acceptable input argument for a zero/sign
|
;; extend operation.
|
;; extend operation.
|
|
|
(define_predicate "extend_operand"
|
(define_predicate "extend_operand"
|
(match_code "reg,subreg,mem")
|
(match_code "reg,subreg,mem")
|
{
|
{
|
rtx addr;
|
rtx addr;
|
|
|
switch (GET_CODE (op))
|
switch (GET_CODE (op))
|
{
|
{
|
case REG :
|
case REG :
|
case SUBREG :
|
case SUBREG :
|
return register_operand (op, mode);
|
return register_operand (op, mode);
|
|
|
case MEM :
|
case MEM :
|
addr = XEXP (op, 0);
|
addr = XEXP (op, 0);
|
if (GET_CODE (addr) == PRE_INC || GET_CODE (addr) == PRE_DEC)
|
if (GET_CODE (addr) == PRE_INC || GET_CODE (addr) == PRE_DEC)
|
return 0; /* loads can't do pre inc/pre dec */
|
return 0; /* loads can't do pre inc/pre dec */
|
|
|
return address_operand (addr, mode);
|
return address_operand (addr, mode);
|
|
|
default :
|
default :
|
return 0;
|
return 0;
|
}
|
}
|
})
|
})
|
|
|
;; Return nonzero if the operand is an insn that is a small
|
;; Return nonzero if the operand is an insn that is a small
|
;; insn. Allow const_int 0 as well, which is a placeholder for NOP
|
;; insn. Allow const_int 0 as well, which is a placeholder for NOP
|
;; slots.
|
;; slots.
|
|
|
(define_predicate "small_insn_p"
|
(define_predicate "small_insn_p"
|
(match_code "insn,call_insn,jump_insn")
|
(match_code "insn,call_insn,jump_insn")
|
{
|
{
|
if (CONST_INT_P (op) && INTVAL (op) == 0)
|
if (CONST_INT_P (op) && INTVAL (op) == 0)
|
return 1;
|
return 1;
|
|
|
if (! INSN_P (op))
|
if (! INSN_P (op))
|
return 0;
|
return 0;
|
|
|
return get_attr_length (op) == 2;
|
return get_attr_length (op) == 2;
|
})
|
})
|
|
|
;; Return true if op is an integer constant, less than or equal to
|
;; Return true if op is an integer constant, less than or equal to
|
;; MAX_MOVE_BYTES.
|
;; MAX_MOVE_BYTES.
|
|
|
(define_predicate "m32r_block_immediate_operand"
|
(define_predicate "m32r_block_immediate_operand"
|
(match_code "const_int")
|
(match_code "const_int")
|
{
|
{
|
if (!CONST_INT_P (op)
|
if (!CONST_INT_P (op)
|
|| INTVAL (op) > MAX_MOVE_BYTES
|
|| INTVAL (op) > MAX_MOVE_BYTES
|
|| INTVAL (op) <= 0)
|
|| INTVAL (op) <= 0)
|
return 0;
|
return 0;
|
|
|
return 1;
|
return 1;
|
})
|
})
|
|
|
;; Return nonzero if the operand is an insn that is a large insn.
|
;; Return nonzero if the operand is an insn that is a large insn.
|
|
|
(define_predicate "large_insn_p"
|
(define_predicate "large_insn_p"
|
(match_code "insn,call_insn,jump_insn")
|
(match_code "insn,call_insn,jump_insn")
|
{
|
{
|
if (! INSN_P (op))
|
if (! INSN_P (op))
|
return 0;
|
return 0;
|
|
|
return get_attr_length (op) != 2;
|
return get_attr_length (op) != 2;
|
})
|
})
|
|
|
;; Returns 1 if OP is an acceptable operand for seth/add3.
|
;; Returns 1 if OP is an acceptable operand for seth/add3.
|
|
|
(define_predicate "seth_add3_operand"
|
(define_predicate "seth_add3_operand"
|
(match_code "symbol_ref,label_ref,const")
|
(match_code "symbol_ref,label_ref,const")
|
{
|
{
|
if (flag_pic)
|
if (flag_pic)
|
return 0;
|
return 0;
|
|
|
if (GET_CODE (op) == SYMBOL_REF
|
if (GET_CODE (op) == SYMBOL_REF
|
|| GET_CODE (op) == LABEL_REF)
|
|| GET_CODE (op) == LABEL_REF)
|
return 1;
|
return 1;
|
|
|
if (GET_CODE (op) == CONST
|
if (GET_CODE (op) == CONST
|
&& GET_CODE (XEXP (op, 0)) == PLUS
|
&& GET_CODE (XEXP (op, 0)) == PLUS
|
&& GET_CODE (XEXP (XEXP (op, 0), 0)) == SYMBOL_REF
|
&& GET_CODE (XEXP (XEXP (op, 0), 0)) == SYMBOL_REF
|
&& satisfies_constraint_J (XEXP (XEXP (op, 0), 1)))
|
&& satisfies_constraint_J (XEXP (XEXP (op, 0), 1)))
|
return 1;
|
return 1;
|
|
|
return 0;
|
return 0;
|
})
|
})
|
|
|