Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(373)

Unified Diff: gcc/gcc/config/i386/predicates.md

Issue 3050029: [gcc] GCC 4.5.0=>4.5.1 (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/nacl-toolchain.git
Patch Set: Created 10 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « gcc/gcc/config/i386/ppro.md ('k') | gcc/gcc/config/i386/sol2-10.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: gcc/gcc/config/i386/predicates.md
diff --git a/gcc/gcc/config/i386/predicates.md b/gcc/gcc/config/i386/predicates.md
index fce6cf3a3fb96982fcffa3e85266a850bc8826b6..83f5e5dac314ff759ccb426ded4c2d39d8928592 100644
--- a/gcc/gcc/config/i386/predicates.md
+++ b/gcc/gcc/config/i386/predicates.md
@@ -76,16 +76,30 @@
(and (match_code "reg")
(match_test "REGNO (op) == FLAGS_REG")))
+;; Return true if op is a QImode register operand other than
+;; %[abcd][hl].
+(define_predicate "ext_QIreg_operand"
+ (and (match_code "reg")
+ (match_test "TARGET_64BIT
+ && GET_MODE (op) == QImode
+ && REGNO (op) > BX_REG")))
+
+;; Similarly, but don't check mode of the operand.
+(define_predicate "ext_QIreg_nomode_operand"
+ (and (match_code "reg")
+ (match_test "TARGET_64BIT
+ && REGNO (op) > BX_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
+ (match_test "!REG_P (op)
|| 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
+ (match_test "!REG_P (op)
|| REGNO (op) != FIRST_SSE_REG")))
;; Return 1 if VALUE can be stored in a sign extended immediate field.
@@ -313,8 +327,8 @@
(define_predicate "x86_64_szext_general_operand"
(if_then_else (match_test "TARGET_64BIT")
(ior (match_operand 0 "nonimmediate_operand")
- (ior (match_operand 0 "x86_64_immediate_operand")
- (match_operand 0 "x86_64_zext_immediate_operand")))
+ (match_operand 0 "x86_64_immediate_operand")
+ (match_operand 0 "x86_64_zext_immediate_operand"))
(match_operand 0 "general_operand")))
;; Return nonzero if OP is nonmemory operand representable on x86_64.
@@ -328,8 +342,8 @@
(define_predicate "x86_64_szext_nonmemory_operand"
(if_then_else (match_test "TARGET_64BIT")
(ior (match_operand 0 "register_operand")
- (ior (match_operand 0 "x86_64_immediate_operand")
- (match_operand 0 "x86_64_zext_immediate_operand")))
+ (match_operand 0 "x86_64_immediate_operand")
+ (match_operand 0 "x86_64_zext_immediate_operand"))
(match_operand 0 "nonmemory_operand")))
;; Return true when operand is PIC expression that can be computed by lea
@@ -563,8 +577,8 @@
;; Test for a valid operand for a call instruction.
(define_predicate "call_insn_operand"
(ior (match_operand 0 "constant_call_address_operand")
- (ior (match_operand 0 "call_register_no_elim_operand")
- (match_operand 0 "memory_operand"))))
+ (match_operand 0 "call_register_no_elim_operand")
+ (match_operand 0 "memory_operand")))
;; Similarly, but for tail calls, in which we cannot allow memory references.
(define_predicate "sibcall_insn_operand"
@@ -590,6 +604,11 @@
(and (match_code "const_int")
(match_test "INTVAL (op) == 8")))
+;; Match exactly 128.
+(define_predicate "const128_operand"
+ (and (match_code "const_int")
+ (match_test "INTVAL (op) == 128")))
+
;; Match 2, 4, or 8. Used for leal multiplicands.
(define_predicate "const248_operand"
(match_code "const_int")
@@ -718,7 +737,7 @@
{
/* 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;
})
@@ -747,13 +766,12 @@
{
unsigned n_elts;
op = maybe_get_pool_constant (op);
- if (!op)
- return 0;
- if (GET_CODE (op) != CONST_VECTOR)
+
+ if (!(op && GET_CODE (op) == CONST_VECTOR))
return 0;
- n_elts =
- (GET_MODE_SIZE (GET_MODE (op)) /
- GET_MODE_SIZE (GET_MODE_INNER (GET_MODE (op))));
+
+ n_elts = CONST_VECTOR_NUNITS (op);
+
for (n_elts--; n_elts > 0; n_elts--)
{
rtx elt = CONST_VECTOR_ELT (op, n_elts);
@@ -827,12 +845,12 @@
int ok;
/* Registers and immediate operands are always "aligned". */
- if (GET_CODE (op) != MEM)
+ if (!MEM_P (op))
return 1;
/* 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. */
@@ -894,6 +912,9 @@
struct ix86_address parts;
int ok;
+ if (TARGET_64BIT)
+ return 0;
+
ok = ix86_decompose_address (XEXP (op, 0), &parts);
gcc_assert (ok);
@@ -946,9 +967,7 @@
if (inmode == CCFPmode || inmode == CCFPUmode)
{
- enum rtx_code second_code, bypass_code;
- ix86_fp_comparison_codes (code, &bypass_code, &code, &second_code);
- if (bypass_code != UNKNOWN || second_code != UNKNOWN)
+ if (!ix86_trivial_fp_comparison_operator (op, mode))
return 0;
code = ix86_fp_compare_code_to_integer (code);
}
@@ -985,12 +1004,6 @@
(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"))
@@ -1008,11 +1021,8 @@
enum rtx_code code = GET_CODE (op);
if (inmode == CCFPmode || inmode == CCFPUmode)
- {
- enum rtx_code second_code, bypass_code;
- ix86_fp_comparison_codes (code, &bypass_code, &code, &second_code);
- return (bypass_code == UNKNOWN && second_code == UNKNOWN);
- }
+ return ix86_trivial_fp_comparison_operator (op, mode);
+
switch (code)
{
case EQ: case NE:
@@ -1046,16 +1056,9 @@
enum machine_mode inmode = GET_MODE (XEXP (op, 0));
enum rtx_code code = GET_CODE (op);
- if (!REG_P (XEXP (op, 0))
- || REGNO (XEXP (op, 0)) != FLAGS_REG
- || XEXP (op, 1) != const0_rtx)
- return 0;
-
if (inmode == CCFPmode || inmode == CCFPUmode)
{
- enum rtx_code second_code, bypass_code;
- ix86_fp_comparison_codes (code, &bypass_code, &code, &second_code);
- if (bypass_code != UNKNOWN || second_code != UNKNOWN)
+ if (!ix86_trivial_fp_comparison_operator (op, mode))
return 0;
code = ix86_fp_compare_code_to_integer (code);
}
@@ -1067,6 +1070,32 @@
return code == LTU;
})
+;; Return 1 if this comparison only requires testing one flag bit.
+(define_predicate "ix86_trivial_fp_comparison_operator"
+ (match_code "gt,ge,unlt,unle,uneq,ltgt,ordered,unordered"))
+
+;; Return 1 if we know how to do this comparison. Others require
+;; testing more than one flag bit, and we let the generic middle-end
+;; code do that.
+(define_predicate "ix86_fp_comparison_operator"
+ (if_then_else (match_test "ix86_fp_comparison_strategy (GET_CODE (op))
+ == IX86_FPCMP_ARITH")
+ (match_operand 0 "comparison_operator")
+ (match_operand 0 "ix86_trivial_fp_comparison_operator")))
+
+;; Same as above, but for swapped comparison used in fp_jcc_4_387.
+(define_predicate "ix86_swapped_fp_comparison_operator"
+ (match_operand 0 "comparison_operator")
+{
+ enum rtx_code code = GET_CODE (op);
+ int ret;
+
+ PUT_CODE (op, swap_condition (code));
+ ret = ix86_fp_comparison_operator (op, mode);
+ PUT_CODE (op, code);
+ return ret;
+})
+
;; Nearly general operand, but accept any const_double, since we wish
;; to be able to drop them into memory rather than have them get pulled
;; into registers.
@@ -1105,23 +1134,6 @@
(and (match_code "mult")
(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.
-;;
-;; ??? It seems likely that this will only work because cmpsi is an
-;; expander, and no actual insns use this.
-
-(define_predicate "cmpsi_operand"
- (ior (match_operand 0 "nonimmediate_operand")
- (and (match_code "and")
- (match_code "zero_extract" "0")
- (match_code "const_int" "1")
- (match_code "const_int" "01")
- (match_code "const_int" "02")
- (match_test "INTVAL (XEXP (XEXP (op, 0), 1)) == 8")
- (match_test "INTVAL (XEXP (XEXP (op, 0), 2)) == 8")
- )))
-
(define_predicate "compare_operator"
(match_code "compare"))
@@ -1133,14 +1145,129 @@
(and (match_code "mem")
(match_test "MEM_ALIGN (op) < GET_MODE_ALIGNMENT (mode)")))
+;; Return 1 if OP is a emms operation, known to be a PARALLEL.
+(define_predicate "emms_operation"
+ (match_code "parallel")
+{
+ unsigned i;
+
+ if (XVECLEN (op, 0) != 17)
+ return 0;
+
+ for (i = 0; i < 8; i++)
+ {
+ rtx elt = XVECEXP (op, 0, i+1);
+
+ if (GET_CODE (elt) != CLOBBER
+ || GET_CODE (SET_DEST (elt)) != REG
+ || GET_MODE (SET_DEST (elt)) != XFmode
+ || REGNO (SET_DEST (elt)) != FIRST_STACK_REG + i)
+ return 0;
+
+ elt = XVECEXP (op, 0, i+9);
+
+ if (GET_CODE (elt) != CLOBBER
+ || GET_CODE (SET_DEST (elt)) != REG
+ || GET_MODE (SET_DEST (elt)) != DImode
+ || REGNO (SET_DEST (elt)) != FIRST_MMX_REG + i)
+ return 0;
+ }
+ return 1;
+})
+
;; 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;
+ unsigned i, nregs = TARGET_64BIT ? 16 : 8;
+
+ if ((unsigned) XVECLEN (op, 0) != 1 + nregs)
+ return 0;
- if (XVECLEN (op, 0) != nregs + 1)
+ for (i = 0; i < nregs; i++)
+ {
+ rtx elt = XVECEXP (op, 0, i+1);
+
+ if (GET_CODE (elt) != SET
+ || GET_CODE (SET_DEST (elt)) != REG
+ || GET_MODE (SET_DEST (elt)) != V8SImode
+ || REGNO (SET_DEST (elt)) != SSE_REGNO (i)
+ || SET_SRC (elt) != CONST0_RTX (V8SImode))
+ return 0;
+ }
+ return 1;
+})
+
+;; Return 1 if OP is a vzeroupper operation, known to be a PARALLEL.
+(define_predicate "vzeroupper_operation"
+ (match_code "parallel")
+{
+ unsigned i, nregs = TARGET_64BIT ? 16 : 8;
+
+ if ((unsigned) XVECLEN (op, 0) != 1 + nregs)
return 0;
+ for (i = 0; i < nregs; i++)
+ {
+ rtx elt = XVECEXP (op, 0, i+1);
+
+ if (GET_CODE (elt) != CLOBBER
+ || GET_CODE (SET_DEST (elt)) != REG
+ || GET_MODE (SET_DEST (elt)) != V8SImode
+ || REGNO (SET_DEST (elt)) != SSE_REGNO (i))
+ return 0;
+ }
return 1;
})
+
+;; Return 1 if OP is a parallel for a vpermilp[ds] permute.
+;; ??? It would be much easier if the PARALLEL for a VEC_SELECT
+;; had a mode, but it doesn't. So we have 4 copies and install
+;; the mode by hand.
+
+(define_predicate "avx_vpermilp_v8sf_operand"
+ (and (match_code "parallel")
+ (match_test "avx_vpermilp_parallel (op, V8SFmode)")))
+
+(define_predicate "avx_vpermilp_v4df_operand"
+ (and (match_code "parallel")
+ (match_test "avx_vpermilp_parallel (op, V4DFmode)")))
+
+(define_predicate "avx_vpermilp_v4sf_operand"
+ (and (match_code "parallel")
+ (match_test "avx_vpermilp_parallel (op, V4SFmode)")))
+
+(define_predicate "avx_vpermilp_v2df_operand"
+ (and (match_code "parallel")
+ (match_test "avx_vpermilp_parallel (op, V2DFmode)")))
+
+;; Return 1 if OP is a parallel for a vperm2f128 permute.
+
+(define_predicate "avx_vperm2f128_v8sf_operand"
+ (and (match_code "parallel")
+ (match_test "avx_vperm2f128_parallel (op, V8SFmode)")))
+
+(define_predicate "avx_vperm2f128_v8si_operand"
+ (and (match_code "parallel")
+ (match_test "avx_vperm2f128_parallel (op, V8SImode)")))
+
+(define_predicate "avx_vperm2f128_v4df_operand"
+ (and (match_code "parallel")
+ (match_test "avx_vperm2f128_parallel (op, V4DFmode)")))
+
+;; Return 1 if OP is a parallel for a vbroadcast permute.
+
+(define_predicate "avx_vbroadcast_operand"
+ (and (match_code "parallel")
+ (match_code "const_int" "a"))
+{
+ rtx elt = XVECEXP (op, 0, 0);
+ int i, nelt = XVECLEN (op, 0);
+
+ /* Don't bother checking there are the right number of operands,
+ merely that they're all identical. */
+ for (i = 1; i < nelt; ++i)
+ if (XVECEXP (op, 0, i) != elt)
+ return false;
+ return true;
+})
« no previous file with comments | « gcc/gcc/config/i386/ppro.md ('k') | gcc/gcc/config/i386/sol2-10.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698