Commit 5546ac90 by Kazu Hirata

sh.c (general_movsrc_operand, [...]): Move to ...

	* config/sh/sh.c (general_movsrc_operand,
	general_movdst_operand, arith_reg_operand, arith_reg_dest,
	logical_reg_operand, int_gpr_dest, fp_arith_reg_operand,
	fp_arith_reg_dest, arith_operand, arith_reg_or_0_operand,
	xor_operand, cmp_operand, logical_operand, and_operand,
	fpscr_operand, fpul_operand, symbol_ref_operand,
	commutative_float_operator, noncommutative_float_operator,
	unary_float_operator, binary_float_operator,
	binary_logical_operator, equality_comparison_operator,
	greater_comparison_operator, less_comparison_operator,
	shift_operator, logical_operator, target_reg_operand,
	target_operand, mextr_bit_offset, extend_reg_operand,
	trunc_hi_operand, extend_reg_or_0_operand, minuend_operand,
	general_extend_operand, ua_address_operand,
	cache_address_operand, inqhi_operand, sh_rep_vec, sh_1el_vec,
	sh_const_vec, ua_offset, sh_register_operand, cmpsi_operand,
	shift_count_reg_operand, shift_count_operand,
	unaligned_load_operand): Move to ...
	* config/sh/predicates.md: ... here.
	* config/sh/sh.h (PREDICATE_CODES, SPECIAL_MODE_PREDICATES):
	Remove.

From-SVN: r100523
parent e0d161cf
2005-06-03 Andrew Pinski <pinskia@physics.uc.edu> 2005-06-02 Kazu Hirata <kazu@codesourcery.com>
* config/sh/sh.c (general_movsrc_operand,
general_movdst_operand, arith_reg_operand, arith_reg_dest,
logical_reg_operand, int_gpr_dest, fp_arith_reg_operand,
fp_arith_reg_dest, arith_operand, arith_reg_or_0_operand,
xor_operand, cmp_operand, logical_operand, and_operand,
fpscr_operand, fpul_operand, symbol_ref_operand,
commutative_float_operator, noncommutative_float_operator,
unary_float_operator, binary_float_operator,
binary_logical_operator, equality_comparison_operator,
greater_comparison_operator, less_comparison_operator,
shift_operator, logical_operator, target_reg_operand,
target_operand, mextr_bit_offset, extend_reg_operand,
trunc_hi_operand, extend_reg_or_0_operand, minuend_operand,
general_extend_operand, ua_address_operand,
cache_address_operand, inqhi_operand, sh_rep_vec, sh_1el_vec,
sh_const_vec, ua_offset, sh_register_operand, cmpsi_operand,
shift_count_reg_operand, shift_count_operand,
unaligned_load_operand): Move to ...
* config/sh/predicates.md: ... here.
* config/sh/sh.h (PREDICATE_CODES, SPECIAL_MODE_PREDICATES):
Remove.
2005-06-02 Andrew Pinski <pinskia@physics.uc.edu>
* tree.c (build_common_builtin_nodes): Fix the return type on * tree.c (build_common_builtin_nodes): Fix the return type on
__builtin_memcmp. __builtin_memcmp.
2005-06-03 Richard Guenther <rguenth@gcc.gnu.org> 2005-06-02 Richard Guenther <rguenth@gcc.gnu.org>
* tree-ssa-loop-ivopts.c (build_addr_strip_iref): Remove. * tree-ssa-loop-ivopts.c (build_addr_strip_iref): Remove.
(find_interesting_uses_address): Use build_fold_addr_expr instead. (find_interesting_uses_address): Use build_fold_addr_expr instead.
......
;; Predicate definitions for Renesas / SuperH SH.
;; 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.
;; TODO: Add a comment here.
(define_predicate "trapping_target_operand" (define_predicate "trapping_target_operand"
(match_code "if_then_else") (match_code "if_then_else")
{ {
...@@ -36,3 +58,861 @@ ...@@ -36,3 +58,861 @@
&& INTVAL (XEXP (and, 1)) == 3 && INTVAL (XEXP (and, 1)) == 3
&& INTVAL (XEXP (cond, 1)) == 3); && INTVAL (XEXP (cond, 1)) == 3);
}) })
;; TODO: Add a comment here.
(define_predicate "and_operand"
(match_code "subreg,reg,const_int")
{
if (logical_operand (op, mode))
return 1;
/* Check mshflo.l / mshflhi.l opportunities. */
if (TARGET_SHMEDIA
&& mode == DImode
&& GET_CODE (op) == CONST_INT
&& CONST_OK_FOR_J16 (INTVAL (op)))
return 1;
return 0;
})
;; Like arith_reg_dest, but this predicate belongs to
;; SPECIAL_MODE_PREDICATES.
(define_special_predicate "any_arith_reg_dest"
(match_code "subreg,reg")
{
return arith_reg_dest (op, mode);
})
;; Like register_operand, but this predicate belongs to
;; SPECIAL_MODE_PREDICATES.
(define_special_predicate "any_register_operand"
(match_code "subreg,reg")
{
return register_operand (op, mode);
})
;; Returns 1 if OP is a valid source operand for an arithmetic insn.
(define_predicate "arith_operand"
(match_code "subreg,reg,const_int,truncate")
{
if (arith_reg_operand (op, mode))
return 1;
if (TARGET_SHMEDIA)
{
/* FIXME: We should be checking whether the CONST_INT fits in a
CONST_OK_FOR_I16 here, but this causes reload_cse to crash when
attempting to transform a sequence of two 64-bit sets of the
same register from literal constants into a set and an add,
when the difference is too wide for an add. */
if (GET_CODE (op) == CONST_INT
|| EXTRA_CONSTRAINT_C16 (op))
return 1;
else if (GET_CODE (op) == TRUNCATE
&& ! system_reg_operand (XEXP (op, 0), VOIDmode)
&& (mode == VOIDmode || mode == GET_MODE (op))
&& (GET_MODE_SIZE (GET_MODE (op))
< GET_MODE_SIZE (GET_MODE (XEXP (op, 0))))
&& (! FP_REGISTER_P (REGNO (XEXP (op, 0)))
|| GET_MODE_SIZE (GET_MODE (op)) == 4))
return register_operand (XEXP (op, 0), VOIDmode);
else
return 0;
}
else if (GET_CODE (op) == CONST_INT && CONST_OK_FOR_I08 (INTVAL (op)))
return 1;
return 0;
})
;; Like above, but for DImode destinations: forbid paradoxical DImode
;; subregs, because this would lead to missing sign extensions when
;; truncating from DImode to SImode.
(define_predicate "arith_reg_dest"
(match_code "subreg,reg")
{
if (mode == DImode && GET_CODE (op) == SUBREG
&& GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) < 8
&& TARGET_SHMEDIA)
return 0;
return arith_reg_operand (op, mode);
})
;; Returns 1 if OP is a normal arithmetic register.
(define_predicate "arith_reg_operand"
(match_code "subreg,reg,sign_extend")
{
if (register_operand (op, mode))
{
int regno;
if (GET_CODE (op) == REG)
regno = REGNO (op);
else if (GET_CODE (op) == SUBREG && GET_CODE (SUBREG_REG (op)) == REG)
regno = REGNO (SUBREG_REG (op));
else
return 1;
return (regno != T_REG && regno != PR_REG
&& ! TARGET_REGISTER_P (regno)
&& (regno != FPUL_REG || TARGET_SH4)
&& regno != MACH_REG && regno != MACL_REG);
}
/* Allow a no-op sign extension - compare LOAD_EXTEND_OP.
We allow SImode here, as not using an FP register is just a matter of
proper register allocation. */
if (TARGET_SHMEDIA
&& GET_MODE (op) == DImode && GET_CODE (op) == SIGN_EXTEND
&& GET_MODE (XEXP (op, 0)) == SImode
&& GET_CODE (XEXP (op, 0)) != SUBREG)
return register_operand (XEXP (op, 0), VOIDmode);
#if 0 /* Can't do this because of PROMOTE_MODE for unsigned vars. */
if (GET_MODE (op) == SImode && GET_CODE (op) == SIGN_EXTEND
&& GET_MODE (XEXP (op, 0)) == HImode
&& GET_CODE (XEXP (op, 0)) == REG
&& REGNO (XEXP (op, 0)) <= LAST_GENERAL_REG)
return register_operand (XEXP (op, 0), VOIDmode);
#endif
if (GET_MODE_CLASS (GET_MODE (op)) == MODE_VECTOR_INT
&& GET_CODE (op) == SUBREG
&& GET_MODE (SUBREG_REG (op)) == DImode
&& GET_CODE (SUBREG_REG (op)) == SIGN_EXTEND
&& GET_MODE (XEXP (SUBREG_REG (op), 0)) == SImode
&& GET_CODE (XEXP (SUBREG_REG (op), 0)) != SUBREG)
return register_operand (XEXP (SUBREG_REG (op), 0), VOIDmode);
return 0;
})
;; Returns 1 if OP is a valid source operand for a compare insn.
(define_predicate "arith_reg_or_0_operand"
(match_code "subreg,reg,const_int,const_vector")
{
if (arith_reg_operand (op, mode))
return 1;
if (EXTRA_CONSTRAINT_Z (op))
return 1;
return 0;
})
;; TODO: Add a comment here.
(define_predicate "binary_float_operator"
(match_code "plus,minus,mult,div")
{
if (GET_MODE (op) != mode)
return 0;
switch (GET_CODE (op))
{
case PLUS:
case MINUS:
case MULT:
case DIV:
return 1;
default:
break;
}
return 0;
})
;; TODO: Add a comment here.
(define_predicate "binary_logical_operator"
(match_code "and,ior,xor")
{
if (GET_MODE (op) != mode)
return 0;
switch (GET_CODE (op))
{
case IOR:
case AND:
case XOR:
return 1;
default:
break;
}
return 0;
})
;; TODO: Add a comment here.
(define_predicate "cache_address_operand"
(match_code "plus,reg")
{
if (GET_CODE (op) == PLUS)
{
if (GET_CODE (XEXP (op, 0)) != REG)
return 0;
if (GET_CODE (XEXP (op, 1)) != CONST_INT
|| (INTVAL (XEXP (op, 1)) & 31))
return 0;
}
else if (GET_CODE (op) != REG)
return 0;
return address_operand (op, mode);
})
;; Return 1 if OP is a valid source operand for shmedia cmpgt / cmpgtu.
(define_predicate "cmp_operand"
(match_code "subreg,reg,const_int")
{
if (GET_CODE (op) == CONST_INT && CONST_OK_FOR_N (INTVAL (op)))
return 1;
if (TARGET_SHMEDIA
&& mode != DImode && GET_CODE (op) == SUBREG
&& GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) > 4)
return 0;
return arith_reg_operand (op, mode);
})
;; TODO: Add a comment here.
(define_predicate "cmpsi_operand"
(match_code "subreg,reg,const_int")
{
if (GET_CODE (op) == REG && REGNO (op) == T_REG
&& GET_MODE (op) == SImode
&& TARGET_SH1)
return 1;
return arith_operand (op, mode);
})
;; TODO: Add a comment here.
(define_predicate "commutative_float_operator"
(match_code "plus,mult")
{
if (GET_MODE (op) != mode)
return 0;
switch (GET_CODE (op))
{
case PLUS:
case MULT:
return 1;
default:
break;
}
return 0;
})
;; TODO: Add a comment here.
(define_predicate "equality_comparison_operator"
(match_code "eq,ne")
{
return ((mode == VOIDmode || GET_MODE (op) == mode)
&& (GET_CODE (op) == EQ || GET_CODE (op) == NE));
})
;; TODO: Add a comment here.
(define_predicate "extend_reg_operand"
(match_code "subreg,reg,truncate")
{
return (GET_CODE (op) == TRUNCATE
? arith_operand
: arith_reg_operand) (op, mode);
})
;; TODO: Add a comment here.
(define_predicate "extend_reg_or_0_operand"
(match_code "subreg,reg,truncate,const_int")
{
return (GET_CODE (op) == TRUNCATE
? arith_operand
: arith_reg_or_0_operand) (op, mode);
})
;; Like arith_reg_operand, but this predicate does not accept SIGN_EXTEND.
(define_predicate "ext_dest_operand"
(match_code "subreg,reg")
{
return arith_reg_operand (op, mode);
})
;; TODO: Add a comment here.
(define_predicate "fp_arith_reg_dest"
(match_code "subreg,reg")
{
if (mode == DImode && GET_CODE (op) == SUBREG
&& GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) < 8)
return 0;
return fp_arith_reg_operand (op, mode);
})
;; TODO: Add a comment here.
(define_predicate "fp_arith_reg_operand"
(match_code "subreg,reg")
{
if (register_operand (op, mode))
{
int regno;
if (GET_CODE (op) == REG)
regno = REGNO (op);
else if (GET_CODE (op) == SUBREG && GET_CODE (SUBREG_REG (op)) == REG)
regno = REGNO (SUBREG_REG (op));
else
return 1;
return (regno >= FIRST_PSEUDO_REGISTER
|| FP_REGISTER_P (regno));
}
return 0;
})
;; TODO: Add a comment here.
(define_predicate "fpscr_operand"
(match_code "reg")
{
return (GET_CODE (op) == REG
&& (REGNO (op) == FPSCR_REG
|| (REGNO (op) >= FIRST_PSEUDO_REGISTER
&& !(reload_in_progress || reload_completed)))
&& GET_MODE (op) == PSImode);
})
;; TODO: Add a comment here.
(define_predicate "fpul_operand"
(match_code "reg")
{
if (TARGET_SHMEDIA)
return fp_arith_reg_operand (op, mode);
return (GET_CODE (op) == REG
&& (REGNO (op) == FPUL_REG || REGNO (op) >= FIRST_PSEUDO_REGISTER)
&& GET_MODE (op) == mode);
})
;; TODO: Add a comment here.
(define_predicate "general_extend_operand"
(match_code "subreg,reg,mem,truncate")
{
return (GET_CODE (op) == TRUNCATE
? arith_operand
: nonimmediate_operand) (op, mode);
})
;; Returns 1 if OP can be source of a simple move operation. Same as
;; general_operand, but a LABEL_REF is valid, PRE_DEC is invalid as
;; are subregs of system registers.
(define_predicate "general_movsrc_operand"
(match_code "subreg,reg,const_int,const_double,mem,symbol_ref,label_ref,const,const_vector")
{
if (GET_CODE (op) == MEM)
{
rtx inside = XEXP (op, 0);
if (GET_CODE (inside) == CONST)
inside = XEXP (inside, 0);
if (GET_CODE (inside) == LABEL_REF)
return 1;
if (GET_CODE (inside) == PLUS
&& GET_CODE (XEXP (inside, 0)) == LABEL_REF
&& GET_CODE (XEXP (inside, 1)) == CONST_INT)
return 1;
/* Only post inc allowed. */
if (GET_CODE (inside) == PRE_DEC)
return 0;
}
if ((mode == QImode || mode == HImode)
&& (GET_CODE (op) == SUBREG
&& GET_CODE (XEXP (op, 0)) == REG
&& system_reg_operand (XEXP (op, 0), mode)))
return 0;
if (TARGET_SHMEDIA
&& (GET_CODE (op) == PARALLEL || GET_CODE (op) == CONST_VECTOR)
&& sh_rep_vec (op, mode))
return 1;
if (TARGET_SHMEDIA && 1
&& GET_CODE (op) == SUBREG && GET_MODE (op) == mode
&& SUBREG_REG (op) == const0_rtx && subreg_lowpart_p (op))
/* FIXME */ abort (); /* return 1; */
return general_operand (op, mode);
})
;; Returns 1 if OP can be a destination of a move. Same as
;; general_operand, but no preinc allowed.
(define_predicate "general_movdst_operand"
(match_code "subreg,reg,mem")
{
/* Only pre dec allowed. */
if (GET_CODE (op) == MEM && GET_CODE (XEXP (op, 0)) == POST_INC)
return 0;
if (mode == DImode && TARGET_SHMEDIA && GET_CODE (op) == SUBREG
&& GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) < 8
&& ! (high_life_started || reload_completed))
return 0;
return general_operand (op, mode);
})
;; Returns 1 if OP is a MEM that can be source of a simple move operation.
(define_predicate "unaligned_load_operand"
(match_code "mem")
{
rtx inside;
if (GET_CODE (op) != MEM || GET_MODE (op) != mode)
return 0;
inside = XEXP (op, 0);
if (GET_CODE (inside) == POST_INC)
inside = XEXP (inside, 0);
if (GET_CODE (inside) == REG)
return 1;
return 0;
})
;; TODO: Add a comment here.
(define_predicate "greater_comparison_operator"
(match_code "gt,ge,gtu,geu")
{
if (mode != VOIDmode && GET_MODE (op) != mode)
return 0;
switch (GET_CODE (op))
{
case GT:
case GE:
case GTU:
case GEU:
return 1;
default:
return 0;
}
})
;; TODO: Add a comment here.
(define_predicate "inqhi_operand"
(match_code "truncate")
{
if (GET_CODE (op) != TRUNCATE || mode != GET_MODE (op))
return 0;
op = XEXP (op, 0);
/* Can't use true_regnum here because copy_cost wants to know about
SECONDARY_INPUT_RELOAD_CLASS. */
return GET_CODE (op) == REG && FP_REGISTER_P (REGNO (op));
})
;; TODO: Add a comment here.
(define_special_predicate "int_gpr_dest"
(match_code "subreg,reg")
{
enum machine_mode op_mode = GET_MODE (op);
if (GET_MODE_CLASS (op_mode) != MODE_INT
|| GET_MODE_SIZE (op_mode) >= UNITS_PER_WORD)
return 0;
if (! reload_completed)
return 0;
return true_regnum (op) <= LAST_GENERAL_REG;
})
;; TODO: Add a comment here.
(define_predicate "less_comparison_operator"
(match_code "lt,le,ltu,leu")
{
if (mode != VOIDmode && GET_MODE (op) != mode)
return 0;
switch (GET_CODE (op))
{
case LT:
case LE:
case LTU:
case LEU:
return 1;
default:
return 0;
}
})
;; Returns 1 if OP is a valid source operand for a logical operation.
(define_predicate "logical_operand"
(match_code "subreg,reg,const_int")
{
if (TARGET_SHMEDIA
&& mode != DImode && GET_CODE (op) == SUBREG
&& GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) > 4)
return 0;
if (arith_reg_operand (op, mode))
return 1;
if (TARGET_SHMEDIA)
{
if (GET_CODE (op) == CONST_INT && CONST_OK_FOR_I10 (INTVAL (op)))
return 1;
else
return 0;
}
else if (GET_CODE (op) == CONST_INT && CONST_OK_FOR_K08 (INTVAL (op)))
return 1;
return 0;
})
;; TODO: Add a comment here.
(define_predicate "logical_operator"
(match_code "and,ior,xor")
{
if (mode != VOIDmode && GET_MODE (op) != mode)
return 0;
switch (GET_CODE (op))
{
case AND:
case IOR:
case XOR:
return 1;
default:
return 0;
}
})
;; Like arith_reg_operand, but for register source operands of narrow
;; logical SHMEDIA operations: forbid subregs of DImode / TImode regs.
(define_predicate "logical_reg_operand"
(match_code "subreg,reg")
{
if (TARGET_SHMEDIA
&& GET_CODE (op) == SUBREG
&& GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) > 4
&& mode != DImode)
return 0;
return arith_reg_operand (op, mode);
})
;; TODO: Add a comment here.
(define_predicate "mextr_bit_offset"
(match_code "const_int")
{
HOST_WIDE_INT i;
if (GET_CODE (op) != CONST_INT)
return 0;
i = INTVAL (op);
return i >= 1 * 8 && i <= 7 * 8 && (i & 7) == 0;
})
;; TODO: Add a comment here.
(define_predicate "minuend_operand"
(match_code "subreg,reg,truncate,const_int")
{
return op == constm1_rtx || extend_reg_or_0_operand (op, mode);
})
;; TODO: Add a comment here.
(define_predicate "noncommutative_float_operator"
(match_code "minus,div")
{
if (GET_MODE (op) != mode)
return 0;
switch (GET_CODE (op))
{
case MINUS:
case DIV:
return 1;
default:
break;
}
return 0;
})
;; TODO: Add a comment here.
(define_predicate "sh_const_vec"
(match_code "const_vector")
{
int i;
if (GET_CODE (op) != CONST_VECTOR
|| (GET_MODE (op) != mode && mode != VOIDmode))
return 0;
i = XVECLEN (op, 0) - 1;
for (; i >= 0; i--)
if (GET_CODE (XVECEXP (op, 0, i)) != CONST_INT)
return 0;
return 1;
})
;; Determine if OP is a constant vector matching MODE with only one
;; element that is not a sign extension. Two byte-sized elements
;; count as one.
(define_predicate "sh_1el_vec"
(match_code "const_vector")
{
int unit_size;
int i, last, least, sign_ix;
rtx sign;
if (GET_CODE (op) != CONST_VECTOR
|| (GET_MODE (op) != mode && mode != VOIDmode))
return 0;
/* Determine numbers of last and of least significant elements. */
last = XVECLEN (op, 0) - 1;
least = TARGET_LITTLE_ENDIAN ? 0 : last;
if (GET_CODE (XVECEXP (op, 0, least)) != CONST_INT)
return 0;
sign_ix = least;
if (GET_MODE_UNIT_SIZE (mode) == 1)
sign_ix = TARGET_LITTLE_ENDIAN ? 1 : last - 1;
if (GET_CODE (XVECEXP (op, 0, sign_ix)) != CONST_INT)
return 0;
unit_size = GET_MODE_UNIT_SIZE (GET_MODE (op));
sign = (INTVAL (XVECEXP (op, 0, sign_ix)) >> (unit_size * BITS_PER_UNIT - 1)
? constm1_rtx : const0_rtx);
i = XVECLEN (op, 0) - 1;
do
if (i != least && i != sign_ix && XVECEXP (op, 0, i) != sign)
return 0;
while (--i);
return 1;
})
;; Like register_operand, but take into account that SHMEDIA can use
;; the constant zero like a general register.
(define_predicate "sh_register_operand"
(match_code "reg,subreg,const_int")
{
if (op == CONST0_RTX (mode) && TARGET_SHMEDIA)
return 1;
return register_operand (op, mode);
})
;; TODO: Add a comment here.
(define_predicate "sh_rep_vec"
(match_code "const_vector")
{
int i;
rtx x, y;
if ((GET_CODE (op) != CONST_VECTOR && GET_CODE (op) != PARALLEL)
|| (GET_MODE (op) != mode && mode != VOIDmode))
return 0;
i = XVECLEN (op, 0) - 2;
x = XVECEXP (op, 0, i + 1);
if (GET_MODE_UNIT_SIZE (mode) == 1)
{
y = XVECEXP (op, 0, i);
for (i -= 2; i >= 0; i -= 2)
if (! rtx_equal_p (XVECEXP (op, 0, i + 1), x)
|| ! rtx_equal_p (XVECEXP (op, 0, i), y))
return 0;
}
else
for (; i >= 0; i--)
if (XVECEXP (op, 0, i) != x)
return 0;
return 1;
})
;; TODO: Add a comment here.
(define_predicate "shift_count_operand"
(match_code "const_int,const_double,const,symbol_ref,label_ref,subreg,reg,zero_extend,sign_extend")
{
return (CONSTANT_P (op)
? (GET_CODE (op) == CONST_INT
? (unsigned) INTVAL (op) < GET_MODE_BITSIZE (mode)
: nonmemory_operand (op, mode))
: shift_count_reg_operand (op, mode));
})
;; TODO: Add a comment here.
(define_predicate "shift_count_reg_operand"
(match_code "subreg,reg,zero_extend,sign_extend")
{
if ((GET_CODE (op) == ZERO_EXTEND || GET_CODE (op) == SIGN_EXTEND
|| (GET_CODE (op) == SUBREG && SUBREG_BYTE (op) == 0))
&& (mode == VOIDmode || mode == GET_MODE (op))
&& GET_MODE_BITSIZE (GET_MODE (XEXP (op, 0))) >= 6
&& GET_MODE_CLASS (GET_MODE (XEXP (op, 0))) == MODE_INT)
{
mode = VOIDmode;
do
op = XEXP (op, 0);
while ((GET_CODE (op) == ZERO_EXTEND || GET_CODE (op) == SIGN_EXTEND
|| GET_CODE (op) == TRUNCATE)
&& GET_MODE_BITSIZE (GET_MODE (XEXP (op, 0))) >= 6
&& GET_MODE_CLASS (GET_MODE (XEXP (op, 0))) == MODE_INT);
}
return arith_reg_operand (op, mode);
})
;; TODO: Add a comment here.
(define_predicate "shift_operator"
(match_code "ashift,ashiftrt,lshiftrt")
{
if (mode != VOIDmode && GET_MODE (op) != mode)
return 0;
switch (GET_CODE (op))
{
case ASHIFT:
case ASHIFTRT:
case LSHIFTRT:
return 1;
default:
return 0;
}
})
;; TODO: Add a comment here.
(define_predicate "symbol_ref_operand"
(match_code "symbol_ref")
{
return (GET_CODE (op) == SYMBOL_REF);
})
;; Same as target_reg_operand, except that label_refs and symbol_refs
;; are accepted before reload.
(define_special_predicate "target_operand"
(match_code "subreg,reg,label_ref,symbol_ref,const,unspec")
{
if (mode != VOIDmode && mode != Pmode)
return 0;
if ((GET_MODE (op) == Pmode || GET_MODE (op) == VOIDmode)
&& EXTRA_CONSTRAINT_Csy (op))
return ! reload_completed;
return target_reg_operand (op, mode);
})
;; Accept pseudos and branch target registers.
(define_special_predicate "target_reg_operand"
(match_code "subreg,reg")
{
if (mode == VOIDmode
? GET_MODE (op) != Pmode && GET_MODE (op) != PDImode
: mode != GET_MODE (op))
return 0;
if (GET_CODE (op) == SUBREG)
op = XEXP (op, 0);
if (GET_CODE (op) != REG)
return 0;
/* We must protect ourselves from matching pseudos that are virtual
register, because they will eventually be replaced with hardware
registers that aren't branch-target registers. */
if (REGNO (op) > LAST_VIRTUAL_REGISTER
|| TARGET_REGISTER_P (REGNO (op)))
return 1;
return 0;
})
;; TODO: Add a comment here.
(define_special_predicate "trunc_hi_operand"
(match_code "subreg,reg,truncate")
{
enum machine_mode op_mode = GET_MODE (op);
if (op_mode != SImode && op_mode != DImode
&& op_mode != V4HImode && op_mode != V2SImode)
return 0;
return extend_reg_operand (op, mode);
})
;; TODO: Add a comment here.
(define_predicate "ua_address_operand"
(match_code "subreg,reg,plus")
{
if (GET_CODE (op) == PLUS
&& (GET_CODE (XEXP (op, 1)) != CONST_INT
|| ! CONST_OK_FOR_I06 (INTVAL (XEXP (op, 1)))))
return 0;
return address_operand (op, QImode);
})
;; TODO: Add a comment here.
(define_predicate "ua_offset"
(match_code "const_int")
{
return GET_CODE (op) == CONST_INT && CONST_OK_FOR_I06 (INTVAL (op));
})
;; TODO: Add a comment here.
(define_predicate "unary_float_operator"
(match_code "abs,neg,sqrt")
{
if (GET_MODE (op) != mode)
return 0;
switch (GET_CODE (op))
{
case ABS:
case NEG:
case SQRT:
return 1;
default:
break;
}
return 0;
})
;; Return 1 if OP is a valid source operand for xor.
(define_predicate "xor_operand"
(match_code "subreg,reg,const_int")
{
if (GET_CODE (op) == CONST_INT)
return (TARGET_SHMEDIA
? (CONST_OK_FOR_I06 (INTVAL (op))
|| (no_new_pseudos && INTVAL (op) == 0xff))
: CONST_OK_FOR_K08 (INTVAL (op)));
if (TARGET_SHMEDIA
&& mode != DImode && GET_CODE (op) == SUBREG
&& GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) > 4)
return 0;
return arith_reg_operand (op, mode);
})
...@@ -7550,301 +7550,6 @@ system_reg_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED) ...@@ -7550,301 +7550,6 @@ system_reg_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
return 0; return 0;
} }
/* Returns 1 if OP can be source of a simple move operation.
Same as general_operand, but a LABEL_REF is valid, PRE_DEC is
invalid as are subregs of system registers. */
int
general_movsrc_operand (rtx op, enum machine_mode mode)
{
if (GET_CODE (op) == MEM)
{
rtx inside = XEXP (op, 0);
if (GET_CODE (inside) == CONST)
inside = XEXP (inside, 0);
if (GET_CODE (inside) == LABEL_REF)
return 1;
if (GET_CODE (inside) == PLUS
&& GET_CODE (XEXP (inside, 0)) == LABEL_REF
&& GET_CODE (XEXP (inside, 1)) == CONST_INT)
return 1;
/* Only post inc allowed. */
if (GET_CODE (inside) == PRE_DEC)
return 0;
}
if ((mode == QImode || mode == HImode)
&& (GET_CODE (op) == SUBREG
&& GET_CODE (XEXP (op, 0)) == REG
&& system_reg_operand (XEXP (op, 0), mode)))
return 0;
if (TARGET_SHMEDIA
&& (GET_CODE (op) == PARALLEL || GET_CODE (op) == CONST_VECTOR)
&& sh_rep_vec (op, mode))
return 1;
if (TARGET_SHMEDIA && 1
&& GET_CODE (op) == SUBREG && GET_MODE (op) == mode
&& SUBREG_REG (op) == const0_rtx && subreg_lowpart_p (op))
/* FIXME */ abort (); /* return 1; */
return general_operand (op, mode);
}
/* Returns 1 if OP can be a destination of a move.
Same as general_operand, but no preinc allowed. */
int
general_movdst_operand (rtx op, enum machine_mode mode)
{
/* Only pre dec allowed. */
if (GET_CODE (op) == MEM && GET_CODE (XEXP (op, 0)) == POST_INC)
return 0;
if (mode == DImode && TARGET_SHMEDIA && GET_CODE (op) == SUBREG
&& GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) < 8
&& ! (high_life_started || reload_completed))
return 0;
return general_operand (op, mode);
}
/* Returns 1 if OP is a normal arithmetic register. */
int
arith_reg_operand (rtx op, enum machine_mode mode)
{
if (register_operand (op, mode))
{
int regno;
if (GET_CODE (op) == REG)
regno = REGNO (op);
else if (GET_CODE (op) == SUBREG && GET_CODE (SUBREG_REG (op)) == REG)
regno = REGNO (SUBREG_REG (op));
else
return 1;
return (regno != T_REG && regno != PR_REG
&& ! TARGET_REGISTER_P (regno)
&& (regno != FPUL_REG || TARGET_SH4)
&& regno != MACH_REG && regno != MACL_REG);
}
/* Allow a no-op sign extension - compare LOAD_EXTEND_OP.
We allow SImode here, as not using an FP register is just a matter of
proper register allocation. */
if (TARGET_SHMEDIA
&& GET_MODE (op) == DImode && GET_CODE (op) == SIGN_EXTEND
&& GET_MODE (XEXP (op, 0)) == SImode
&& GET_CODE (XEXP (op, 0)) != SUBREG)
return register_operand (XEXP (op, 0), VOIDmode);
#if 0 /* Can't do this because of PROMOTE_MODE for unsigned vars. */
if (GET_MODE (op) == SImode && GET_CODE (op) == SIGN_EXTEND
&& GET_MODE (XEXP (op, 0)) == HImode
&& GET_CODE (XEXP (op, 0)) == REG
&& REGNO (XEXP (op, 0)) <= LAST_GENERAL_REG)
return register_operand (XEXP (op, 0), VOIDmode);
#endif
if (GET_MODE_CLASS (GET_MODE (op)) == MODE_VECTOR_INT
&& GET_CODE (op) == SUBREG
&& GET_MODE (SUBREG_REG (op)) == DImode
&& GET_CODE (SUBREG_REG (op)) == SIGN_EXTEND
&& GET_MODE (XEXP (SUBREG_REG (op), 0)) == SImode
&& GET_CODE (XEXP (SUBREG_REG (op), 0)) != SUBREG)
return register_operand (XEXP (SUBREG_REG (op), 0), VOIDmode);
return 0;
}
/* Like above, but for DImode destinations: forbid paradoxical DImode subregs,
because this would lead to missing sign extensions when truncating from
DImode to SImode. */
int
arith_reg_dest (rtx op, enum machine_mode mode)
{
if (mode == DImode && GET_CODE (op) == SUBREG
&& GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) < 8
&& TARGET_SHMEDIA)
return 0;
return arith_reg_operand (op, mode);
}
/* Like arith_reg_operand, but for register source operands of narrow
logical SHMEDIA operations: forbid subregs of DImode / TImode regs. */
int
logical_reg_operand (rtx op, enum machine_mode mode)
{
if (TARGET_SHMEDIA
&& GET_CODE (op) == SUBREG
&& GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) > 4
&& mode != DImode)
return 0;
return arith_reg_operand (op, mode);
}
int
int_gpr_dest (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
enum machine_mode op_mode = GET_MODE (op);
if (GET_MODE_CLASS (op_mode) != MODE_INT
|| GET_MODE_SIZE (op_mode) >= UNITS_PER_WORD)
return 0;
if (! reload_completed)
return 0;
return true_regnum (op) <= LAST_GENERAL_REG;
}
int
fp_arith_reg_operand (rtx op, enum machine_mode mode)
{
if (register_operand (op, mode))
{
int regno;
if (GET_CODE (op) == REG)
regno = REGNO (op);
else if (GET_CODE (op) == SUBREG && GET_CODE (SUBREG_REG (op)) == REG)
regno = REGNO (SUBREG_REG (op));
else
return 1;
return (regno >= FIRST_PSEUDO_REGISTER
|| FP_REGISTER_P (regno));
}
return 0;
}
int
fp_arith_reg_dest (rtx op, enum machine_mode mode)
{
if (mode == DImode && GET_CODE (op) == SUBREG
&& GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) < 8)
return 0;
return fp_arith_reg_operand (op, mode);
}
/* Returns 1 if OP is a valid source operand for an arithmetic insn. */
int
arith_operand (rtx op, enum machine_mode mode)
{
if (arith_reg_operand (op, mode))
return 1;
if (TARGET_SHMEDIA)
{
/* FIXME: We should be checking whether the CONST_INT fits in a
CONST_OK_FOR_I16 here, but this causes reload_cse to crash when
attempting to transform a sequence of two 64-bit sets of the
same register from literal constants into a set and an add,
when the difference is too wide for an add. */
if (GET_CODE (op) == CONST_INT
|| EXTRA_CONSTRAINT_C16 (op))
return 1;
else if (GET_CODE (op) == TRUNCATE
&& ! system_reg_operand (XEXP (op, 0), VOIDmode)
&& (mode == VOIDmode || mode == GET_MODE (op))
&& (GET_MODE_SIZE (GET_MODE (op))
< GET_MODE_SIZE (GET_MODE (XEXP (op, 0))))
&& (! FP_REGISTER_P (REGNO (XEXP (op, 0)))
|| GET_MODE_SIZE (GET_MODE (op)) == 4))
return register_operand (XEXP (op, 0), VOIDmode);
else
return 0;
}
else if (GET_CODE (op) == CONST_INT && CONST_OK_FOR_I08 (INTVAL (op)))
return 1;
return 0;
}
/* Returns 1 if OP is a valid source operand for a compare insn. */
int
arith_reg_or_0_operand (rtx op, enum machine_mode mode)
{
if (arith_reg_operand (op, mode))
return 1;
if (EXTRA_CONSTRAINT_Z (op))
return 1;
return 0;
}
/* Return 1 if OP is a valid source operand for xor. */
int
xor_operand (rtx op, enum machine_mode mode)
{
if (GET_CODE (op) == CONST_INT)
return (TARGET_SHMEDIA
? (CONST_OK_FOR_I06 (INTVAL (op))
|| (no_new_pseudos && INTVAL (op) == 0xff))
: CONST_OK_FOR_K08 (INTVAL (op)));
if (TARGET_SHMEDIA
&& mode != DImode && GET_CODE (op) == SUBREG
&& GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) > 4)
return 0;
return arith_reg_operand (op, mode);
}
/* Return 1 if OP is a valid source operand for shmedia cmpgt / cmpgtu. */
int
cmp_operand (rtx op, enum machine_mode mode)
{
if (GET_CODE (op) == CONST_INT && CONST_OK_FOR_N (INTVAL (op)))
return 1;
if (TARGET_SHMEDIA
&& mode != DImode && GET_CODE (op) == SUBREG
&& GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) > 4)
return 0;
return arith_reg_operand (op, mode);
}
/* Returns 1 if OP is a valid source operand for a logical operation. */
int
logical_operand (rtx op, enum machine_mode mode)
{
if (TARGET_SHMEDIA
&& mode != DImode && GET_CODE (op) == SUBREG
&& GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) > 4)
return 0;
if (arith_reg_operand (op, mode))
return 1;
if (TARGET_SHMEDIA)
{
if (GET_CODE (op) == CONST_INT && CONST_OK_FOR_I10 (INTVAL (op)))
return 1;
else
return 0;
}
else if (GET_CODE (op) == CONST_INT && CONST_OK_FOR_K08 (INTVAL (op)))
return 1;
return 0;
}
int
and_operand (rtx op, enum machine_mode mode)
{
if (logical_operand (op, mode))
return 1;
/* Check mshflo.l / mshflhi.l opportunities. */
if (TARGET_SHMEDIA
&& mode == DImode
&& GET_CODE (op) == CONST_INT
&& CONST_OK_FOR_J16 (INTVAL (op)))
return 1;
return 0;
}
/* Nonzero if OP is a floating point value with value 0.0. */ /* Nonzero if OP is a floating point value with value 0.0. */
int int
...@@ -7893,33 +7598,6 @@ tertiary_reload_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED) ...@@ -7893,33 +7598,6 @@ tertiary_reload_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
return code == MEM || (TARGET_SH4 && code == CONST_DOUBLE); return code == MEM || (TARGET_SH4 && code == CONST_DOUBLE);
} }
int
fpscr_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return (GET_CODE (op) == REG
&& (REGNO (op) == FPSCR_REG
|| (REGNO (op) >= FIRST_PSEUDO_REGISTER
&& !(reload_in_progress || reload_completed)))
&& GET_MODE (op) == PSImode);
}
int
fpul_operand (rtx op, enum machine_mode mode)
{
if (TARGET_SHMEDIA)
return fp_arith_reg_operand (op, mode);
return (GET_CODE (op) == REG
&& (REGNO (op) == FPUL_REG || REGNO (op) >= FIRST_PSEUDO_REGISTER)
&& GET_MODE (op) == mode);
}
int
symbol_ref_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return (GET_CODE (op) == SYMBOL_REF);
}
/* Return the TLS type for TLS symbols, 0 for otherwise. */ /* Return the TLS type for TLS symbols, 0 for otherwise. */
int int
tls_symbolic_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED) tls_symbolic_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
...@@ -7928,366 +7606,6 @@ tls_symbolic_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED) ...@@ -7928,366 +7606,6 @@ tls_symbolic_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
return 0; return 0;
return SYMBOL_REF_TLS_MODEL (op); return SYMBOL_REF_TLS_MODEL (op);
} }
int
commutative_float_operator (rtx op, enum machine_mode mode)
{
if (GET_MODE (op) != mode)
return 0;
switch (GET_CODE (op))
{
case PLUS:
case MULT:
return 1;
default:
break;
}
return 0;
}
int
noncommutative_float_operator (rtx op, enum machine_mode mode)
{
if (GET_MODE (op) != mode)
return 0;
switch (GET_CODE (op))
{
case MINUS:
case DIV:
return 1;
default:
break;
}
return 0;
}
int
unary_float_operator (rtx op, enum machine_mode mode)
{
if (GET_MODE (op) != mode)
return 0;
switch (GET_CODE (op))
{
case ABS:
case NEG:
case SQRT:
return 1;
default:
break;
}
return 0;
}
int
binary_float_operator (rtx op, enum machine_mode mode)
{
if (GET_MODE (op) != mode)
return 0;
switch (GET_CODE (op))
{
case PLUS:
case MINUS:
case MULT:
case DIV:
return 1;
default:
break;
}
return 0;
}
int
binary_logical_operator (rtx op, enum machine_mode mode)
{
if (GET_MODE (op) != mode)
return 0;
switch (GET_CODE (op))
{
case IOR:
case AND:
case XOR:
return 1;
default:
break;
}
return 0;
}
int
equality_comparison_operator (rtx op, enum machine_mode mode)
{
return ((mode == VOIDmode || GET_MODE (op) == mode)
&& (GET_CODE (op) == EQ || GET_CODE (op) == NE));
}
int
greater_comparison_operator (rtx op, enum machine_mode mode)
{
if (mode != VOIDmode && GET_MODE (op) != mode)
return 0;
switch (GET_CODE (op))
{
case GT:
case GE:
case GTU:
case GEU:
return 1;
default:
return 0;
}
}
int
less_comparison_operator (rtx op, enum machine_mode mode)
{
if (mode != VOIDmode && GET_MODE (op) != mode)
return 0;
switch (GET_CODE (op))
{
case LT:
case LE:
case LTU:
case LEU:
return 1;
default:
return 0;
}
}
int
shift_operator (rtx op, enum machine_mode mode)
{
if (mode != VOIDmode && GET_MODE (op) != mode)
return 0;
switch (GET_CODE (op))
{
case ASHIFT:
case ASHIFTRT:
case LSHIFTRT:
return 1;
default:
return 0;
}
}
int
logical_operator (rtx op, enum machine_mode mode)
{
if (mode != VOIDmode && GET_MODE (op) != mode)
return 0;
switch (GET_CODE (op))
{
case AND:
case IOR:
case XOR:
return 1;
default:
return 0;
}
}
/* Accept pseudos and branch target registers. */
int
target_reg_operand (rtx op, enum machine_mode mode)
{
if (mode == VOIDmode
? GET_MODE (op) != Pmode && GET_MODE (op) != PDImode
: mode != GET_MODE (op))
return 0;
if (GET_CODE (op) == SUBREG)
op = XEXP (op, 0);
if (GET_CODE (op) != REG)
return 0;
/* We must protect ourselves from matching pseudos that are virtual
register, because they will eventually be replaced with hardware
registers that aren't branch-target registers. */
if (REGNO (op) > LAST_VIRTUAL_REGISTER
|| TARGET_REGISTER_P (REGNO (op)))
return 1;
return 0;
}
/* Same as target_reg_operand, except that label_refs and symbol_refs
are accepted before reload. */
int
target_operand (rtx op, enum machine_mode mode)
{
if (mode != VOIDmode && mode != Pmode)
return 0;
if ((GET_MODE (op) == Pmode || GET_MODE (op) == VOIDmode)
&& EXTRA_CONSTRAINT_Csy (op))
return ! reload_completed;
return target_reg_operand (op, mode);
}
int
mextr_bit_offset (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
HOST_WIDE_INT i;
if (GET_CODE (op) != CONST_INT)
return 0;
i = INTVAL (op);
return i >= 1 * 8 && i <= 7 * 8 && (i & 7) == 0;
}
int
extend_reg_operand (rtx op, enum machine_mode mode)
{
return (GET_CODE (op) == TRUNCATE
? arith_operand
: arith_reg_operand) (op, mode);
}
int
trunc_hi_operand (rtx op, enum machine_mode mode)
{
enum machine_mode op_mode = GET_MODE (op);
if (op_mode != SImode && op_mode != DImode
&& op_mode != V4HImode && op_mode != V2SImode)
return 0;
return extend_reg_operand (op, mode);
}
int
extend_reg_or_0_operand (rtx op, enum machine_mode mode)
{
return (GET_CODE (op) == TRUNCATE
? arith_operand
: arith_reg_or_0_operand) (op, mode);
}
int
minuend_operand (rtx op, enum machine_mode mode)
{
return op == constm1_rtx || extend_reg_or_0_operand (op, mode);
}
int
general_extend_operand (rtx op, enum machine_mode mode)
{
return (GET_CODE (op) == TRUNCATE
? arith_operand
: nonimmediate_operand) (op, mode);
}
int
ua_address_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
if (GET_CODE (op) == PLUS
&& (GET_CODE (XEXP (op, 1)) != CONST_INT
|| ! CONST_OK_FOR_I06 (INTVAL (XEXP (op, 1)))))
return 0;
return address_operand (op, QImode);
}
int
cache_address_operand (rtx op, enum machine_mode mode)
{
if (GET_CODE (op) == PLUS)
{
if (GET_CODE (XEXP (op, 0)) != REG)
return 0;
if (GET_CODE (XEXP (op, 1)) != CONST_INT
|| (INTVAL (XEXP (op, 1)) & 31))
return 0;
}
else if (GET_CODE (op) != REG)
return 0;
return address_operand (op, mode);
}
int
inqhi_operand (rtx op, enum machine_mode mode)
{
if (GET_CODE (op) != TRUNCATE || mode != GET_MODE (op))
return 0;
op = XEXP (op, 0);
/* Can't use true_regnum here because copy_cost wants to know about
SECONDARY_INPUT_RELOAD_CLASS. */
return GET_CODE (op) == REG && FP_REGISTER_P (REGNO (op));
}
int
sh_rep_vec (rtx v, enum machine_mode mode)
{
int i;
rtx x, y;
if ((GET_CODE (v) != CONST_VECTOR && GET_CODE (v) != PARALLEL)
|| (GET_MODE (v) != mode && mode != VOIDmode))
return 0;
i = XVECLEN (v, 0) - 2;
x = XVECEXP (v, 0, i + 1);
if (GET_MODE_UNIT_SIZE (mode) == 1)
{
y = XVECEXP (v, 0, i);
for (i -= 2; i >= 0; i -= 2)
if (! rtx_equal_p (XVECEXP (v, 0, i + 1), x)
|| ! rtx_equal_p (XVECEXP (v, 0, i), y))
return 0;
}
else
for (; i >= 0; i--)
if (XVECEXP (v, 0, i) != x)
return 0;
return 1;
}
/* Determine if V is a constant vector matching MODE with only one element
that is not a sign extension. Two byte-sized elements count as one. */
int
sh_1el_vec (rtx v, enum machine_mode mode)
{
int unit_size;
int i, last, least, sign_ix;
rtx sign;
if (GET_CODE (v) != CONST_VECTOR
|| (GET_MODE (v) != mode && mode != VOIDmode))
return 0;
/* Determine numbers of last and of least significant elements. */
last = XVECLEN (v, 0) - 1;
least = TARGET_LITTLE_ENDIAN ? 0 : last;
if (GET_CODE (XVECEXP (v, 0, least)) != CONST_INT)
return 0;
sign_ix = least;
if (GET_MODE_UNIT_SIZE (mode) == 1)
sign_ix = TARGET_LITTLE_ENDIAN ? 1 : last - 1;
if (GET_CODE (XVECEXP (v, 0, sign_ix)) != CONST_INT)
return 0;
unit_size = GET_MODE_UNIT_SIZE (GET_MODE (v));
sign = (INTVAL (XVECEXP (v, 0, sign_ix)) >> (unit_size * BITS_PER_UNIT - 1)
? constm1_rtx : const0_rtx);
i = XVECLEN (v, 0) - 1;
do
if (i != least && i != sign_ix && XVECEXP (v, 0, i) != sign)
return 0;
while (--i);
return 1;
}
int
sh_const_vec (rtx v, enum machine_mode mode)
{
int i;
if (GET_CODE (v) != CONST_VECTOR
|| (GET_MODE (v) != mode && mode != VOIDmode))
return 0;
i = XVECLEN (v, 0) - 1;
for (; i >= 0; i--)
if (GET_CODE (XVECEXP (v, 0, i)) != CONST_INT)
return 0;
return 1;
}
/* Return the destination address of a branch. */ /* Return the destination address of a branch. */
...@@ -8799,12 +8117,6 @@ mark_constant_pool_use (rtx x) ...@@ -8799,12 +8117,6 @@ mark_constant_pool_use (rtx x)
return lab; return lab;
} }
int
ua_offset (rtx c, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return GET_CODE (c) == CONST_INT && CONST_OK_FOR_I06 (INTVAL (c));
}
/* Return true if it's possible to redirect BRANCH1 to the destination /* Return true if it's possible to redirect BRANCH1 to the destination
of an unconditional jump BRANCH2. We only want to do this if the of an unconditional jump BRANCH2. We only want to do this if the
...@@ -10088,57 +9400,6 @@ sh_register_move_cost (enum machine_mode mode, ...@@ -10088,57 +9400,6 @@ sh_register_move_cost (enum machine_mode mode,
return 2 * ((GET_MODE_SIZE (mode) + 3) / 4U); return 2 * ((GET_MODE_SIZE (mode) + 3) / 4U);
} }
/* Like register_operand, but take into account that SHMEDIA can use
the constant zero like a general register. */
int
sh_register_operand (rtx op, enum machine_mode mode)
{
if (op == CONST0_RTX (mode) && TARGET_SHMEDIA)
return 1;
return register_operand (op, mode);
}
int
cmpsi_operand (rtx op, enum machine_mode mode)
{
if (GET_CODE (op) == REG && REGNO (op) == T_REG
&& GET_MODE (op) == SImode
&& TARGET_SH1)
return 1;
return arith_operand (op, mode);
}
int
shift_count_reg_operand (rtx op, enum machine_mode mode)
{
if ((GET_CODE (op) == ZERO_EXTEND || GET_CODE (op) == SIGN_EXTEND
|| (GET_CODE (op) == SUBREG && SUBREG_BYTE (op) == 0))
&& (mode == VOIDmode || mode == GET_MODE (op))
&& GET_MODE_BITSIZE (GET_MODE (XEXP (op, 0))) >= 6
&& GET_MODE_CLASS (GET_MODE (XEXP (op, 0))) == MODE_INT)
{
mode = VOIDmode;
do
op = XEXP (op, 0);
while ((GET_CODE (op) == ZERO_EXTEND || GET_CODE (op) == SIGN_EXTEND
|| GET_CODE (op) == TRUNCATE)
&& GET_MODE_BITSIZE (GET_MODE (XEXP (op, 0))) >= 6
&& GET_MODE_CLASS (GET_MODE (XEXP (op, 0))) == MODE_INT);
}
return arith_reg_operand (op, mode);
}
int
shift_count_operand (rtx op, enum machine_mode mode)
{
return (CONSTANT_P (op)
? (GET_CODE (op) == CONST_INT
? (unsigned) INTVAL (op) < GET_MODE_BITSIZE (mode)
: nonmemory_operand (op, mode))
: shift_count_reg_operand (op, mode));
}
static rtx emit_load_ptr (rtx, rtx); static rtx emit_load_ptr (rtx, rtx);
static rtx static rtx
...@@ -10541,27 +9802,6 @@ check_use_sfunc_addr (rtx insn, rtx reg) ...@@ -10541,27 +9802,6 @@ check_use_sfunc_addr (rtx insn, rtx reg)
gcc_unreachable (); gcc_unreachable ();
} }
/* Returns 1 if OP is a MEM that can be source of a simple move operation. */
int
unaligned_load_operand (rtx op, enum machine_mode mode)
{
rtx inside;
if (GET_CODE (op) != MEM || GET_MODE (op) != mode)
return 0;
inside = XEXP (op, 0);
if (GET_CODE (inside) == POST_INC)
inside = XEXP (inside, 0);
if (GET_CODE (inside) == REG)
return 1;
return 0;
}
/* This function returns a constant rtx that represents pi / 2**15 in /* This function returns a constant rtx that represents pi / 2**15 in
SFmode. it's used to scale SFmode angles, in radians, to a SFmode. it's used to scale SFmode angles, in radians, to a
fixed-point signed 16.16-bit fraction of a full circle, i.e., 2*pi fixed-point signed 16.16-bit fraction of a full circle, i.e., 2*pi
......
...@@ -3246,73 +3246,6 @@ extern struct rtx_def *sp_switch; ...@@ -3246,73 +3246,6 @@ extern struct rtx_def *sp_switch;
#define ADJUST_INSN_LENGTH(X, LENGTH) \ #define ADJUST_INSN_LENGTH(X, LENGTH) \
(LENGTH) += sh_insn_length_adjustment (X); (LENGTH) += sh_insn_length_adjustment (X);
/* Define the codes that are matched by predicates in sh.c. */
#define PREDICATE_CODES \
{"and_operand", {SUBREG, REG, CONST_INT}}, \
{"any_arith_reg_dest", {SUBREG, REG}}, \
{"any_register_operand", {SUBREG, REG}}, \
{"arith_operand", {SUBREG, REG, CONST_INT}}, \
{"arith_reg_dest", {SUBREG, REG}}, \
{"arith_reg_operand", {SUBREG, REG, SIGN_EXTEND}}, \
{"arith_reg_or_0_operand", {SUBREG, REG, CONST_INT, CONST_VECTOR}}, \
{"binary_float_operator", {PLUS, MINUS, MULT, DIV}}, \
{"binary_logical_operator", {AND, IOR, XOR}}, \
{"cache_address_operand", {PLUS, REG}}, \
{"cmp_operand", {SUBREG, REG, CONST_INT}}, \
{"cmpsi_operand", {SUBREG, REG, CONST_INT}}, \
{"commutative_float_operator", {PLUS, MULT}}, \
{"equality_comparison_operator", {EQ,NE}}, \
{"extend_reg_operand", {SUBREG, REG, TRUNCATE}}, \
{"extend_reg_or_0_operand", {SUBREG, REG, TRUNCATE, CONST_INT}}, \
{"ext_dest_operand", {SUBREG, REG}}, \
{"fp_arith_reg_dest", {SUBREG, REG}}, \
{"fp_arith_reg_operand", {SUBREG, REG}}, \
{"fpscr_operand", {REG}}, \
{"fpul_operand", {REG}}, \
{"general_extend_operand", {SUBREG, REG, MEM, TRUNCATE}}, \
{"general_movsrc_operand", {SUBREG, REG, CONST_INT, CONST_DOUBLE, MEM, CONST }}, \
{"general_movdst_operand", {SUBREG, REG, MEM}}, \
{"unaligned_load_operand", {MEM}}, \
{"greater_comparison_operator", {GT,GE,GTU,GEU}}, \
{"inqhi_operand", {TRUNCATE}}, \
{"int_gpr_dest", {SUBREG, REG}}, \
{"less_comparison_operator", {LT,LE,LTU,LEU}}, \
{"logical_operand", {SUBREG, REG, CONST_INT}}, \
{"logical_operator", {AND,IOR,XOR}}, \
{"logical_reg_operand", {SUBREG, REG}}, \
{"mextr_bit_offset", {CONST_INT}}, \
{"minuend_operand", {SUBREG, REG, TRUNCATE, CONST_INT}}, \
{"noncommutative_float_operator", {MINUS, DIV}}, \
{"sh_const_vec", {CONST_VECTOR}}, \
{"sh_1el_vec", {CONST_VECTOR}}, \
{"sh_register_operand", {REG, SUBREG, CONST_INT}}, \
{"sh_rep_vec", {CONST_VECTOR}}, \
{"shift_count_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF, \
LABEL_REF, SUBREG, REG, ZERO_EXTEND, SIGN_EXTEND}},\
{"shift_count_reg_operand", {SUBREG, REG, ZERO_EXTEND, SIGN_EXTEND}}, \
{"shift_operator", {ASHIFT, ASHIFTRT, LSHIFTRT}}, \
{"symbol_ref_operand", {SYMBOL_REF}}, \
{"target_operand", {SUBREG, REG, LABEL_REF, SYMBOL_REF, CONST, UNSPEC}},\
{"target_reg_operand", {SUBREG, REG}}, \
{"trunc_hi_operand", {SUBREG, REG, TRUNCATE}}, \
{"ua_address_operand", {SUBREG, REG, PLUS}}, \
{"ua_offset", {CONST_INT}}, \
{"unary_float_operator", {ABS, NEG, SQRT}}, \
{"xor_operand", {SUBREG, REG, CONST_INT}}, \
#define SPECIAL_MODE_PREDICATES \
"any_arith_reg_dest", \
"any_register_operand", \
"int_gpr_dest", \
"target_operand", \
"target_reg_operand", \
"trunc_hi_operand", \
/* This line intentionally left blank. */
#define any_register_operand register_operand
#define any_arith_reg_dest arith_reg_dest
#define ext_dest_operand arith_reg_operand
/* Define this macro if it is advisable to hold scalars in registers /* Define this macro if it is advisable to hold scalars in registers
in a wider mode than that declared by the program. In such cases, in a wider mode than that declared by the program. In such cases,
the value is constrained to be within the bounds of the declared the value is constrained to be within the bounds of the declared
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment