;; Predicate definitions for SPARC.
-;; Copyright (C) 2005 Free Software Foundation, Inc.
+;; Copyright (C) 2005, 2007, 2008, 2010, 2012 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)
+;; the Free Software Foundation; either version 3, or (at your option)
;; any later version.
;;
;; GCC is distributed in the hope that it will be useful,
;; 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.
+;; along with GCC; see the file COPYING3. If not see
+;; <http://www.gnu.org/licenses/>.
;; Predicates for numerical constants.
(and (match_code "const_int,const_double,const_vector")
(match_test "op == CONST0_RTX (mode)")))
-;; Return true if OP is the one constant for MODE.
-(define_predicate "const_one_operand"
- (and (match_code "const_int,const_double,const_vector")
- (match_test "op == CONST1_RTX (mode)")))
+;; Return true if the integer representation of OP is
+;; all-ones.
+(define_predicate "const_all_ones_operand"
+ (match_code "const_int,const_double,const_vector")
+{
+ if (GET_CODE (op) == CONST_INT && INTVAL (op) == -1)
+ return true;
+#if HOST_BITS_PER_WIDE_INT == 32
+ if (GET_CODE (op) == CONST_DOUBLE
+ && GET_MODE (op) == VOIDmode
+ && CONST_DOUBLE_HIGH (op) == ~(HOST_WIDE_INT)0
+ && CONST_DOUBLE_LOW (op) == ~(HOST_WIDE_INT)0)
+ return true;
+#endif
+ if (GET_CODE (op) == CONST_VECTOR)
+ {
+ int i, num_elem = CONST_VECTOR_NUNITS (op);
+
+ for (i = 0; i < num_elem; i++)
+ {
+ rtx n = CONST_VECTOR_ELT (op, i);
+ if (! const_all_ones_operand (n, mode))
+ return false;
+ }
+ return true;
+ }
+ return false;
+})
;; Return true if OP is the integer constant 4096.
(define_predicate "const_4096_operand"
;; The first test avoids emitting sethi to load zero for example.
(define_predicate "const_high_operand"
(and (match_code "const_int")
- (and (match_test "INTVAL (op) & ~(HOST_WIDE_INT)0x3ff")
+ (and (not (match_operand 0 "small_int_operand"))
(match_test "SPARC_SETHI_P (INTVAL (op) & GET_MODE_MASK (mode))"))))
+;; Return true if OP is a constant whose 1's complement can be loaded by the
+;; sethi instruction.
+(define_predicate "const_compl_high_operand"
+ (and (match_code "const_int")
+ (and (not (match_operand 0 "small_int_operand"))
+ (match_test "SPARC_SETHI_P (~INTVAL (op) & GET_MODE_MASK (mode))"))))
+
+;; Return true if OP is a FP constant that needs to be loaded by the sethi/losum
+;; pair of instructions.
+(define_predicate "fp_const_high_losum_operand"
+ (match_operand 0 "const_double_operand")
+{
+ gcc_assert (mode == SFmode);
+ return fp_high_losum_p (op);
+})
+
+;; Return true if OP is a const_double or const_vector.
+(define_predicate "const_double_or_vector_operand"
+ (match_code "const_double,const_vector"))
+
+;; Return true if OP is Zero, or if the target is V7.
+(define_predicate "zero_or_v7_operand"
+ (and (match_code "const_int")
+ (ior (match_test "INTVAL (op) == 0")
+ (match_test "!TARGET_V8 && !TARGET_V9"))))
;; Predicates for symbolic constants.
;; Return true if OP is a symbolic operand for the TLS Global Dynamic model.
(define_predicate "tgd_symbolic_operand"
(and (match_code "symbol_ref")
- (match_test "tls_symbolic_operand (op) == TLS_MODEL_GLOBAL_DYNAMIC")))
+ (match_test "SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_GLOBAL_DYNAMIC")))
;; Return true if OP is a symbolic operand for the TLS Local Dynamic model.
(define_predicate "tld_symbolic_operand"
(and (match_code "symbol_ref")
- (match_test "tls_symbolic_operand (op) == TLS_MODEL_LOCAL_DYNAMIC")))
+ (match_test "SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_LOCAL_DYNAMIC")))
;; Return true if OP is a symbolic operand for the TLS Initial Exec model.
(define_predicate "tie_symbolic_operand"
(and (match_code "symbol_ref")
- (match_test "tls_symbolic_operand (op) == TLS_MODEL_INITIAL_EXEC")))
+ (match_test "SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_INITIAL_EXEC")))
;; Return true if OP is a symbolic operand for the TLS Local Exec model.
(define_predicate "tle_symbolic_operand"
(and (match_code "symbol_ref")
- (match_test "tls_symbolic_operand (op) == TLS_MODEL_LOCAL_EXEC")))
+ (match_test "SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_LOCAL_EXEC")))
;; Return true if the operand is an argument used in generating PIC references
;; in either the medium/low or embedded medium/anywhere code models on V9.
(ior (match_operand 0 "register_operand")
(match_operand 0 "const_zero_operand")))
+(define_predicate "register_or_v9_zero_operand"
+ (ior (match_operand 0 "register_operand")
+ (and (match_test "TARGET_V9")
+ (match_operand 0 "const_zero_operand"))))
+
+;; Return true if OP is either the zero constant, the all-ones
+;; constant, or a register.
+(define_predicate "register_or_zero_or_all_ones_operand"
+ (ior (match_operand 0 "register_or_zero_operand")
+ (match_operand 0 "const_all_ones_operand")))
+
;; Return true if OP is a register operand in a floating point register.
(define_predicate "fp_register_operand"
(match_operand 0 "register_operand")
#else
if (GET_CODE (op) != CONST_INT)
return false;
- m1 = INTVAL (op) & 0xffffffff;
- m2 = INTVAL (op) >> 32;
+ m1 = trunc_int_for_mode (INTVAL (op), SImode);
+ m2 = trunc_int_for_mode (INTVAL (op) >> 32, SImode);
#endif
return SPARC_SIMM13_P (m1) && SPARC_SIMM13_P (m2);
(match_operand 0 "uns_small_int_operand")))
-;; Predicates for miscellanous instructions.
+;; Predicates for miscellaneous instructions.
;; Return true if OP is valid for the lhs of a comparison insn.
(define_predicate "compare_operand"
- (match_code "reg, subreg, zero_extract")
+ (match_code "reg,subreg,zero_extract")
{
if (GET_CODE (op) == ZERO_EXTRACT)
return (register_operand (XEXP (op, 0), mode)
if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
return false;
+ mclass = GET_MODE_CLASS (mode);
+
/* Allow any 1-instruction integer constant. */
- if (GET_MODE_CLASS (mode) == MODE_INT
+ if (mclass == MODE_INT
&& (small_int_operand (op, mode) || const_high_operand (op, mode)))
return true;
&& (GET_CODE (op) == CONST_DOUBLE || GET_CODE (op) == CONST_INT))
return true;
- if (register_operand (op, mode))
+ if (mclass == MODE_FLOAT && GET_CODE (op) == CONST_DOUBLE)
return true;
- mclass = GET_MODE_CLASS (mode);
- if ((mclass == MODE_FLOAT && GET_CODE (op) == CONST_DOUBLE)
- || (mclass == MODE_VECTOR_INT && GET_CODE (op) == CONST_VECTOR))
+ if (mclass == MODE_VECTOR_INT && GET_CODE (op) == CONST_VECTOR
+ && (const_zero_operand (op, mode)
+ || const_all_ones_operand (op, mode)))
return true;
- /* If this is a SUBREG, look inside so that we handle
- paradoxical ones. */
+ if (register_operand (op, mode))
+ return true;
+
+ /* If this is a SUBREG, look inside so that we handle paradoxical ones. */
if (GET_CODE (op) == SUBREG)
op = SUBREG_REG (op);
(match_test "call_address_operand (XEXP (op, 0), mode)")))
+(define_predicate "mem_noofs_operand"
+ (and (match_code "mem")
+ (match_code "reg" "0")))
+
;; Predicates for operators.
;; Return true if OP is a comparison operator. This allows the use of