X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fconfig%2Fi386%2Fpredicates.md;h=785ff5d6033c75d27f5f8c8ad38034b30c3d3c3e;hb=75445c99f5623dcfddf231767426627e7bab4076;hp=86b6774d0623e0d1f593e21c006470221c85b181;hpb=4e9abdcc8c9f81e9978cae85f20ac3f15e88c5de;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md index 86b6774d062..785ff5d6033 100644 --- a/gcc/config/i386/predicates.md +++ b/gcc/config/i386/predicates.md @@ -1,11 +1,12 @@ ;; 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, @@ -14,9 +15,8 @@ ;; 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 +;; . ;; Return nonzero if OP is either a i387 or SSE fp register. (define_predicate "any_fp_register_operand" @@ -76,6 +76,18 @@ (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") @@ -417,7 +429,8 @@ || !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; @@ -484,9 +497,14 @@ ;; Test for a pc-relative call operand (define_predicate "constant_call_address_operand" - (and (ior (match_code "symbol_ref") - (match_operand 0 "local_symbolic_operand")) - (match_test "ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"))) + (match_code "symbol_ref") +{ + if (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC) + return false; + if (TARGET_DLLIMPORT_DECL_ATTRIBUTES && SYMBOL_REF_DLLIMPORT_P (op)) + return false; + return true; +}) ;; True for any non-virtual or eliminable register. Used in places where ;; instantiation of such a register may cause the pattern to not be recognized. @@ -584,6 +602,11 @@ (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") @@ -608,16 +631,47 @@ (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") @@ -634,13 +688,21 @@ 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; }) @@ -754,7 +816,7 @@ /* 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. */ @@ -825,6 +887,34 @@ 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" @@ -850,7 +940,8 @@ 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: @@ -873,6 +964,26 @@ (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") @@ -895,7 +1006,11 @@ || 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; @@ -910,7 +1025,7 @@ ;; 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); @@ -928,6 +1043,8 @@ 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; @@ -962,13 +1079,15 @@ (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. -;; Modern CPUs have same latency for HImode and SImode multiply, -;; but 386 and 486 do HImode multiply faster. */ (define_predicate "promotable_binary_operator" (ior (match_code "plus,and,ior,xor,ashift") (and (match_code "mult") - (match_test "ix86_tune > PROCESSOR_I486")))) + (match_test "TARGET_TUNE_PROMOTE_HIMODE_IMUL")))) ;; To avoid problems when jump re-emits comparisons like testqi_ext_ccno_0, ;; re-recognize the operand to avoid a copy_to_mode_reg that will fail. @@ -992,3 +1111,20 @@ (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; +})