;; Predicate definitions for IA-32 and x86-64.
-;; Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
+;; Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009
+;; 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, 51 Franklin Street, Fifth Floor,
-;; Boston, MA 02110-1301, USA.
+;; along with GCC; see the file COPYING3. If not see
+;; <http://www.gnu.org/licenses/>.
;; Return nonzero if OP is either a i387 or SSE fp register.
(define_predicate "any_fp_register_operand"
(and (match_code "reg")
(match_test "REGNO (op) == FLAGS_REG")))
+;; Return true if op is not xmm0 register.
+(define_predicate "reg_not_xmm0_operand"
+ (and (match_operand 0 "register_operand")
+ (match_test "GET_CODE (op) != REG
+ || REGNO (op) != FIRST_SSE_REG")))
+
+;; As above, but allow nonimmediate operands.
+(define_predicate "nonimm_not_xmm0_operand"
+ (and (match_operand 0 "nonimmediate_operand")
+ (match_test "GET_CODE (op) != REG
+ || REGNO (op) != FIRST_SSE_REG")))
+
;; Return 1 if VALUE can be stored in a sign extended immediate field.
(define_predicate "x86_64_immediate_operand"
(match_code "const_int,symbol_ref,label_ref,const")
|| !CONST_INT_P (XEXP (op, 1)))
return 0;
op = XEXP (op, 0);
- if (GET_CODE (op) == UNSPEC)
+ if (GET_CODE (op) == UNSPEC
+ && XINT (op, 1) != UNSPEC_MACHOPIC_OFFSET)
return 1;
}
return 0;
(and (match_code "const_int")
(match_test "IN_RANGE (INTVAL (op), 0, 15)")))
+;; Match 0 to 31.
+(define_predicate "const_0_to_31_operand"
+ (and (match_code "const_int")
+ (match_test "IN_RANGE (INTVAL (op), 0, 31)")))
+
;; Match 0 to 63.
(define_predicate "const_0_to_63_operand"
(and (match_code "const_int")
(and (match_code "const_int")
(match_test "IN_RANGE (INTVAL (op), 1, 31)")))
+;; Return nonzero if OP is CONST_INT >= 1 and <= 63 (a valid operand
+;; for 64bit shift & compare patterns, as shifting by 0 does not change flags).
+(define_predicate "const_1_to_63_operand"
+ (and (match_code "const_int")
+ (match_test "IN_RANGE (INTVAL (op), 1, 63)")))
+
;; Match 2 or 3.
(define_predicate "const_2_to_3_operand"
(and (match_code "const_int")
(match_test "IN_RANGE (INTVAL (op), 2, 3)")))
+;; Match 4 to 5.
+(define_predicate "const_4_to_5_operand"
+ (and (match_code "const_int")
+ (match_test "IN_RANGE (INTVAL (op), 4, 5)")))
+
;; Match 4 to 7.
(define_predicate "const_4_to_7_operand"
(and (match_code "const_int")
(match_test "IN_RANGE (INTVAL (op), 4, 7)")))
+;; Match 6 to 7.
+(define_predicate "const_6_to_7_operand"
+ (and (match_code "const_int")
+ (match_test "IN_RANGE (INTVAL (op), 6, 7)")))
+
+;; Match 8 to 11.
+(define_predicate "const_8_to_11_operand"
+ (and (match_code "const_int")
+ (match_test "IN_RANGE (INTVAL (op), 8, 11)")))
+
+;; Match 12 to 15.
+(define_predicate "const_12_to_15_operand"
+ (and (match_code "const_int")
+ (match_test "IN_RANGE (INTVAL (op), 12, 15)")))
+
+;; Match exactly one bit in 2-bit mask.
+(define_predicate "const_pow2_1_to_2_operand"
+ (and (match_code "const_int")
+ (match_test "INTVAL (op) == 1 || INTVAL (op) == 2")))
+
;; Match exactly one bit in 4-bit mask.
(define_predicate "const_pow2_1_to_8_operand"
(match_code "const_int")
return log <= 7;
})
+;; Match exactly one bit in 16-bit mask.
+(define_predicate "const_pow2_1_to_32768_operand"
+ (match_code "const_int")
+{
+ unsigned int log = exact_log2 (INTVAL (op));
+ return log <= 15;
+})
+
;; True if this is a constant appropriate for an increment or decrement.
(define_predicate "incdec_operand"
(match_code "const_int")
{
/* On Pentium4, the inc and dec operations causes extra dependency on flag
registers, since carry flag is not set. */
- if (!TARGET_USE_INCDEC && !optimize_size)
+ if (!TARGET_USE_INCDEC && !optimize_insn_for_size_p ())
return 0;
return op == const1_rtx || op == constm1_rtx;
})
/* All patterns using aligned_operand on memory operands ends up
in promoting memory operand to 64bit and thus causing memory mismatch. */
- if (TARGET_MEMORY_MISMATCH_STALL && !optimize_size)
+ if (TARGET_MEMORY_MISMATCH_STALL && !optimize_insn_for_size_p ())
return 0;
/* Don't even try to do any aligned optimizations with volatiles. */
return parts.disp != NULL_RTX;
})
+;; Returns 1 if OP is memory operand which will need zero or
+;; one register at most, not counting stack pointer or frame pointer.
+(define_predicate "cmpxchg8b_pic_memory_operand"
+ (match_operand 0 "memory_operand")
+{
+ struct ix86_address parts;
+ int ok;
+
+ ok = ix86_decompose_address (XEXP (op, 0), &parts);
+ gcc_assert (ok);
+ if (parts.base == NULL_RTX
+ || parts.base == arg_pointer_rtx
+ || parts.base == frame_pointer_rtx
+ || parts.base == hard_frame_pointer_rtx
+ || parts.base == stack_pointer_rtx)
+ return 1;
+
+ if (parts.index == NULL_RTX
+ || parts.index == arg_pointer_rtx
+ || parts.index == frame_pointer_rtx
+ || parts.index == hard_frame_pointer_rtx
+ || parts.index == stack_pointer_rtx)
+ return 1;
+
+ return 0;
+})
+
+
;; Returns 1 if OP is memory operand that cannot be represented
;; by the modRM array.
(define_predicate "long_memory_operand"
switch (code)
{
case LTU: case GTU: case LEU: case GEU:
- if (inmode == CCmode || inmode == CCFPmode || inmode == CCFPUmode)
+ if (inmode == CCmode || inmode == CCFPmode || inmode == CCFPUmode
+ || inmode == CCCmode)
return 1;
return 0;
case ORDERED: case UNORDERED:
(define_special_predicate "sse_comparison_operator"
(match_code "eq,lt,le,unordered,ne,unge,ungt,ordered"))
+;; Return 1 if OP is a comparison operator that can be issued by
+;; avx predicate generation instructions
+(define_predicate "avx_comparison_float_operator"
+ (match_code "ne,eq,ge,gt,le,lt,unordered,ordered,uneq,unge,ungt,unle,unlt,ltgt"))
+
+;; Return 1 if OP is a comparison operator that can be issued by sse predicate
+;; generation instructions
+(define_predicate "sse5_comparison_float_operator"
+ (and (match_test "TARGET_SSE5")
+ (match_code "ne,eq,ge,gt,le,lt,unordered,ordered,uneq,unge,ungt,unle,unlt,ltgt")))
+
+(define_predicate "ix86_comparison_int_operator"
+ (match_code "ne,eq,ge,gt,le,lt"))
+
+(define_predicate "ix86_comparison_uns_operator"
+ (match_code "ne,eq,geu,gtu,leu,ltu"))
+
+(define_predicate "bt_comparison_operator"
+ (match_code "ne,eq"))
+
;; Return 1 if OP is a valid comparison operator in valid mode.
(define_predicate "ix86_comparison_operator"
(match_operand 0 "comparison_operator")
|| inmode == CCGOCmode || inmode == CCNOmode)
return 1;
return 0;
- case LTU: case GTU: case LEU: case ORDERED: case UNORDERED: case GEU:
+ case LTU: case GTU: case LEU: case GEU:
+ if (inmode == CCmode || inmode == CCCmode)
+ return 1;
+ return 0;
+ case ORDERED: case UNORDERED:
if (inmode == CCmode)
return 1;
return 0;
;; Return 1 if OP is a valid comparison operator testing carry flag to be set.
(define_predicate "ix86_carry_flag_operator"
- (match_code "ltu,lt,unlt,gt,ungt,le,unle,ge,unge,ltgt,uneq")
+ (match_code "ltu,lt,unlt,gtu,gt,ungt,le,unle,ge,unge,ltgt,uneq")
{
enum machine_mode inmode = GET_MODE (XEXP (op, 0));
enum rtx_code code = GET_CODE (op);
return 0;
code = ix86_fp_compare_code_to_integer (code);
}
+ else if (inmode == CCCmode)
+ return code == LTU || code == GTU;
else if (inmode != CCmode)
return 0;
(match_code "plus,mult,and,ior,xor,smin,smax,umin,umax,compare,minus,div,
mod,udiv,umod,ashift,rotate,ashiftrt,lshiftrt,rotatert"))
+;; Return true for COMMUTATIVE_P.
+(define_predicate "commutative_operator"
+ (match_code "plus,mult,and,ior,xor,smin,smax,umin,umax"))
+
;; Return 1 if OP is a binary operator that can be promoted to wider mode.
(define_predicate "promotable_binary_operator"
(ior (match_code "plus,and,ior,xor,ashift")
(define_predicate "absneg_operator"
(match_code "abs,neg"))
+
+;; Return 1 if OP is misaligned memory operand
+(define_predicate "misaligned_operand"
+ (and (match_code "mem")
+ (match_test "MEM_ALIGN (op) < GET_MODE_ALIGNMENT (mode)")))
+
+;; Return 1 if OP is a vzeroall operation, known to be a PARALLEL.
+(define_predicate "vzeroall_operation"
+ (match_code "parallel")
+{
+ int nregs = TARGET_64BIT ? 16 : 8;
+
+ if (XVECLEN (op, 0) != nregs + 1)
+ return 0;
+
+ return 1;
+})