xref: /dflybsd-src/contrib/gcc-8.0/gcc/config/i386/predicates.md (revision 95059079af47f9a66a175f374f2da1a5020e3255)
138fd1498Szrj;; Predicate definitions for IA-32 and x86-64.
238fd1498Szrj;; Copyright (C) 2004-2018 Free Software Foundation, Inc.
338fd1498Szrj;;
438fd1498Szrj;; This file is part of GCC.
538fd1498Szrj;;
638fd1498Szrj;; GCC is free software; you can redistribute it and/or modify
738fd1498Szrj;; it under the terms of the GNU General Public License as published by
838fd1498Szrj;; the Free Software Foundation; either version 3, or (at your option)
938fd1498Szrj;; any later version.
1038fd1498Szrj;;
1138fd1498Szrj;; GCC is distributed in the hope that it will be useful,
1238fd1498Szrj;; but WITHOUT ANY WARRANTY; without even the implied warranty of
1338fd1498Szrj;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1438fd1498Szrj;; GNU General Public License for more details.
1538fd1498Szrj;;
1638fd1498Szrj;; You should have received a copy of the GNU General Public License
1738fd1498Szrj;; along with GCC; see the file COPYING3.  If not see
1838fd1498Szrj;; <http://www.gnu.org/licenses/>.
1938fd1498Szrj
2038fd1498Szrj;; Return true if OP is either a i387 or SSE fp register.
2138fd1498Szrj(define_predicate "any_fp_register_operand"
2238fd1498Szrj  (and (match_code "reg")
2338fd1498Szrj       (match_test "ANY_FP_REGNO_P (REGNO (op))")))
2438fd1498Szrj
2538fd1498Szrj;; Return true if OP is an i387 fp register.
2638fd1498Szrj(define_predicate "fp_register_operand"
2738fd1498Szrj  (and (match_code "reg")
2838fd1498Szrj       (match_test "STACK_REGNO_P (REGNO (op))")))
2938fd1498Szrj
3038fd1498Szrj;; True if the operand is a GENERAL class register.
3138fd1498Szrj(define_predicate "general_reg_operand"
3238fd1498Szrj  (and (match_code "reg")
3338fd1498Szrj       (match_test "GENERAL_REGNO_P (REGNO (op))")))
3438fd1498Szrj
3538fd1498Szrj;; True if the operand is a nonimmediate operand with GENERAL class register.
3638fd1498Szrj(define_predicate "nonimmediate_gr_operand"
3738fd1498Szrj  (if_then_else (match_code "reg")
3838fd1498Szrj    (match_test "GENERAL_REGNO_P (REGNO (op))")
3938fd1498Szrj    (match_operand 0 "nonimmediate_operand")))
4038fd1498Szrj
4138fd1498Szrj;; True if the operand is a general operand with GENERAL class register.
4238fd1498Szrj(define_predicate "general_gr_operand"
4338fd1498Szrj  (if_then_else (match_code "reg")
4438fd1498Szrj    (match_test "GENERAL_REGNO_P (REGNO (op))")
4538fd1498Szrj    (match_operand 0 "general_operand")))
4638fd1498Szrj
4738fd1498Szrj;; True if the operand is an MMX register.
4838fd1498Szrj(define_predicate "mmx_reg_operand"
4938fd1498Szrj  (and (match_code "reg")
5038fd1498Szrj       (match_test "MMX_REGNO_P (REGNO (op))")))
5138fd1498Szrj
5238fd1498Szrj;; True if the operand is an SSE register.
5338fd1498Szrj(define_predicate "sse_reg_operand"
5438fd1498Szrj  (and (match_code "reg")
5538fd1498Szrj       (match_test "SSE_REGNO_P (REGNO (op))")))
5638fd1498Szrj
5738fd1498Szrj;; True if the operand is an AVX-512 new register.
5838fd1498Szrj(define_predicate "ext_sse_reg_operand"
5938fd1498Szrj  (and (match_code "reg")
6038fd1498Szrj       (match_test "EXT_REX_SSE_REGNO_P (REGNO (op))")))
6138fd1498Szrj
6238fd1498Szrj;; Return true if op is a QImode register.
6338fd1498Szrj(define_predicate "any_QIreg_operand"
6438fd1498Szrj  (and (match_code "reg")
6538fd1498Szrj       (match_test "ANY_QI_REGNO_P (REGNO (op))")))
6638fd1498Szrj
6738fd1498Szrj;; Return true if op is one of QImode registers: %[abcd][hl].
6838fd1498Szrj(define_predicate "QIreg_operand"
6938fd1498Szrj  (and (match_code "reg")
7038fd1498Szrj       (match_test "QI_REGNO_P (REGNO (op))")))
7138fd1498Szrj
7238fd1498Szrj;; Return true if op is a QImode register operand other than %[abcd][hl].
7338fd1498Szrj(define_predicate "ext_QIreg_operand"
7438fd1498Szrj  (and (match_test "TARGET_64BIT")
7538fd1498Szrj       (match_code "reg")
7638fd1498Szrj       (not (match_test "QI_REGNO_P (REGNO (op))"))))
7738fd1498Szrj
7838fd1498Szrj;; Return true if op is the AX register.
7938fd1498Szrj(define_predicate "ax_reg_operand"
8038fd1498Szrj  (and (match_code "reg")
8138fd1498Szrj       (match_test "REGNO (op) == AX_REG")))
8238fd1498Szrj
8338fd1498Szrj;; Return true if op is the flags register.
8438fd1498Szrj(define_predicate "flags_reg_operand"
8538fd1498Szrj  (and (match_code "reg")
8638fd1498Szrj       (match_test "REGNO (op) == FLAGS_REG")))
8738fd1498Szrj
8838fd1498Szrj;; Match a DI, SI or HImode register for a zero_extract.
8938fd1498Szrj(define_special_predicate "ext_register_operand"
9038fd1498Szrj  (and (match_operand 0 "register_operand")
9138fd1498Szrj       (ior (and (match_test "TARGET_64BIT")
9238fd1498Szrj		 (match_test "GET_MODE (op) == DImode"))
9338fd1498Szrj	    (match_test "GET_MODE (op) == SImode")
9438fd1498Szrj	    (match_test "GET_MODE (op) == HImode"))))
9538fd1498Szrj
9638fd1498Szrj;; Match register operands, but include memory operands for TARGET_SSE_MATH.
9738fd1498Szrj(define_predicate "register_ssemem_operand"
9838fd1498Szrj  (if_then_else
9938fd1498Szrj    (match_test "SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH")
10038fd1498Szrj    (match_operand 0 "nonimmediate_operand")
10138fd1498Szrj    (match_operand 0 "register_operand")))
10238fd1498Szrj
10338fd1498Szrj;; Match nonimmediate operands, but exclude memory operands
10438fd1498Szrj;; for TARGET_SSE_MATH if TARGET_MIX_SSE_I387 is not enabled.
10538fd1498Szrj(define_predicate "nonimm_ssenomem_operand"
10638fd1498Szrj  (if_then_else
10738fd1498Szrj    (and (match_test "SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH")
10838fd1498Szrj	 (not (match_test "TARGET_MIX_SSE_I387")))
10938fd1498Szrj    (match_operand 0 "register_operand")
11038fd1498Szrj    (match_operand 0 "nonimmediate_operand")))
11138fd1498Szrj
11238fd1498Szrj;; The above predicate, suitable for x87 arithmetic operators.
11338fd1498Szrj(define_predicate "x87nonimm_ssenomem_operand"
11438fd1498Szrj  (if_then_else
11538fd1498Szrj    (and (match_test "SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH")
11638fd1498Szrj	 (not (match_test "TARGET_MIX_SSE_I387 && X87_ENABLE_ARITH (mode)")))
11738fd1498Szrj    (match_operand 0 "register_operand")
11838fd1498Szrj    (match_operand 0 "nonimmediate_operand")))
11938fd1498Szrj
12038fd1498Szrj;; Match register operands, include memory operand for TARGET_SSE4_1.
12138fd1498Szrj(define_predicate "register_sse4nonimm_operand"
12238fd1498Szrj  (if_then_else (match_test "TARGET_SSE4_1")
12338fd1498Szrj    (match_operand 0 "nonimmediate_operand")
12438fd1498Szrj    (match_operand 0 "register_operand")))
12538fd1498Szrj
12638fd1498Szrj;; Return true if VALUE is symbol reference
12738fd1498Szrj(define_predicate "symbol_operand"
12838fd1498Szrj  (match_code "symbol_ref"))
12938fd1498Szrj
13038fd1498Szrj;; Return true if VALUE can be stored in a sign extended immediate field.
13138fd1498Szrj(define_predicate "x86_64_immediate_operand"
13238fd1498Szrj  (match_code "const_int,symbol_ref,label_ref,const")
13338fd1498Szrj{
13438fd1498Szrj  if (!TARGET_64BIT)
13538fd1498Szrj    return immediate_operand (op, mode);
13638fd1498Szrj
13738fd1498Szrj  switch (GET_CODE (op))
13838fd1498Szrj    {
13938fd1498Szrj    case CONST_INT:
14038fd1498Szrj      {
14138fd1498Szrj        HOST_WIDE_INT val = INTVAL (op);
14238fd1498Szrj        return trunc_int_for_mode (val, SImode) == val;
14338fd1498Szrj      }
14438fd1498Szrj    case SYMBOL_REF:
14538fd1498Szrj      /* TLS symbols are not constant.  */
14638fd1498Szrj      if (SYMBOL_REF_TLS_MODEL (op))
14738fd1498Szrj	return false;
14838fd1498Szrj
14938fd1498Szrj      /* Load the external function address via the GOT slot.  */
15038fd1498Szrj      if (ix86_force_load_from_GOT_p (op))
15138fd1498Szrj	return false;
15238fd1498Szrj
15338fd1498Szrj      /* For certain code models, the symbolic references are known to fit.
15438fd1498Szrj	 in CM_SMALL_PIC model we know it fits if it is local to the shared
15538fd1498Szrj	 library.  Don't count TLS SYMBOL_REFs here, since they should fit
15638fd1498Szrj	 only if inside of UNSPEC handled below.  */
15738fd1498Szrj      return (ix86_cmodel == CM_SMALL || ix86_cmodel == CM_KERNEL
15838fd1498Szrj	      || (ix86_cmodel == CM_MEDIUM && !SYMBOL_REF_FAR_ADDR_P (op)));
15938fd1498Szrj
16038fd1498Szrj    case LABEL_REF:
16138fd1498Szrj      /* For certain code models, the code is near as well.  */
16238fd1498Szrj      return (ix86_cmodel == CM_SMALL || ix86_cmodel == CM_MEDIUM
16338fd1498Szrj	      || ix86_cmodel == CM_KERNEL);
16438fd1498Szrj
16538fd1498Szrj    case CONST:
16638fd1498Szrj      /* We also may accept the offsetted memory references in certain
16738fd1498Szrj	 special cases.  */
16838fd1498Szrj      if (GET_CODE (XEXP (op, 0)) == UNSPEC)
16938fd1498Szrj	switch (XINT (XEXP (op, 0), 1))
17038fd1498Szrj	  {
17138fd1498Szrj	  case UNSPEC_GOTPCREL:
17238fd1498Szrj	  case UNSPEC_DTPOFF:
17338fd1498Szrj	  case UNSPEC_GOTNTPOFF:
17438fd1498Szrj	  case UNSPEC_NTPOFF:
17538fd1498Szrj	    return true;
17638fd1498Szrj	  default:
17738fd1498Szrj	    break;
17838fd1498Szrj	  }
17938fd1498Szrj
18038fd1498Szrj      if (GET_CODE (XEXP (op, 0)) == PLUS)
18138fd1498Szrj	{
18238fd1498Szrj	  rtx op1 = XEXP (XEXP (op, 0), 0);
18338fd1498Szrj	  rtx op2 = XEXP (XEXP (op, 0), 1);
18438fd1498Szrj
185*58e805e6Szrj	  if (ix86_cmodel == CM_LARGE && GET_CODE (op1) != UNSPEC)
18638fd1498Szrj	    return false;
18738fd1498Szrj	  if (!CONST_INT_P (op2))
18838fd1498Szrj	    return false;
18938fd1498Szrj
19038fd1498Szrj	  HOST_WIDE_INT offset = INTVAL (op2);
19138fd1498Szrj	  if (trunc_int_for_mode (offset, SImode) != offset)
19238fd1498Szrj	    return false;
19338fd1498Szrj
19438fd1498Szrj	  switch (GET_CODE (op1))
19538fd1498Szrj	    {
19638fd1498Szrj	    case SYMBOL_REF:
19738fd1498Szrj	      /* TLS symbols are not constant.  */
19838fd1498Szrj	      if (SYMBOL_REF_TLS_MODEL (op1))
19938fd1498Szrj		return false;
20038fd1498Szrj
20138fd1498Szrj	      /* Load the external function address via the GOT slot.  */
20238fd1498Szrj	      if (ix86_force_load_from_GOT_p (op1))
20338fd1498Szrj	        return false;
20438fd1498Szrj
20538fd1498Szrj	      /* For CM_SMALL assume that latest object is 16MB before
20638fd1498Szrj		 end of 31bits boundary.  We may also accept pretty
20738fd1498Szrj		 large negative constants knowing that all objects are
20838fd1498Szrj		 in the positive half of address space.  */
20938fd1498Szrj	      if ((ix86_cmodel == CM_SMALL
21038fd1498Szrj		   || (ix86_cmodel == CM_MEDIUM
21138fd1498Szrj		       && !SYMBOL_REF_FAR_ADDR_P (op1)))
21238fd1498Szrj		  && offset < 16*1024*1024)
21338fd1498Szrj		return true;
21438fd1498Szrj	      /* For CM_KERNEL we know that all object resist in the
21538fd1498Szrj		 negative half of 32bits address space.  We may not
21638fd1498Szrj		 accept negative offsets, since they may be just off
21738fd1498Szrj		 and we may accept pretty large positive ones.  */
21838fd1498Szrj	      if (ix86_cmodel == CM_KERNEL
21938fd1498Szrj		  && offset > 0)
22038fd1498Szrj		return true;
22138fd1498Szrj	      break;
22238fd1498Szrj
22338fd1498Szrj	    case LABEL_REF:
22438fd1498Szrj	      /* These conditions are similar to SYMBOL_REF ones, just the
22538fd1498Szrj		 constraints for code models differ.  */
22638fd1498Szrj	      if ((ix86_cmodel == CM_SMALL || ix86_cmodel == CM_MEDIUM)
22738fd1498Szrj		  && offset < 16*1024*1024)
22838fd1498Szrj		return true;
22938fd1498Szrj	      if (ix86_cmodel == CM_KERNEL
23038fd1498Szrj		  && offset > 0)
23138fd1498Szrj		return true;
23238fd1498Szrj	      break;
23338fd1498Szrj
23438fd1498Szrj	    case UNSPEC:
23538fd1498Szrj	      switch (XINT (op1, 1))
23638fd1498Szrj		{
23738fd1498Szrj		case UNSPEC_DTPOFF:
23838fd1498Szrj		case UNSPEC_NTPOFF:
23938fd1498Szrj		  return true;
24038fd1498Szrj		}
24138fd1498Szrj	      break;
24238fd1498Szrj
24338fd1498Szrj	    default:
24438fd1498Szrj	      break;
24538fd1498Szrj	    }
24638fd1498Szrj	}
24738fd1498Szrj      break;
24838fd1498Szrj
24938fd1498Szrj      default:
25038fd1498Szrj	gcc_unreachable ();
25138fd1498Szrj    }
25238fd1498Szrj
25338fd1498Szrj  return false;
25438fd1498Szrj})
25538fd1498Szrj
25638fd1498Szrj;; Return true if VALUE can be stored in the zero extended immediate field.
25738fd1498Szrj(define_predicate "x86_64_zext_immediate_operand"
25838fd1498Szrj  (match_code "const_int,symbol_ref,label_ref,const")
25938fd1498Szrj{
26038fd1498Szrj  switch (GET_CODE (op))
26138fd1498Szrj    {
26238fd1498Szrj    case CONST_INT:
26338fd1498Szrj      return !(INTVAL (op) & ~(HOST_WIDE_INT) 0xffffffff);
26438fd1498Szrj
26538fd1498Szrj    case SYMBOL_REF:
26638fd1498Szrj      /* TLS symbols are not constant.  */
26738fd1498Szrj      if (SYMBOL_REF_TLS_MODEL (op))
26838fd1498Szrj	return false;
26938fd1498Szrj
27038fd1498Szrj      /* Load the external function address via the GOT slot.  */
27138fd1498Szrj      if (ix86_force_load_from_GOT_p (op))
27238fd1498Szrj	return false;
27338fd1498Szrj
27438fd1498Szrj     /* For certain code models, the symbolic references are known to fit.  */
27538fd1498Szrj      return (ix86_cmodel == CM_SMALL
27638fd1498Szrj	      || (ix86_cmodel == CM_MEDIUM
27738fd1498Szrj		  && !SYMBOL_REF_FAR_ADDR_P (op)));
27838fd1498Szrj
27938fd1498Szrj    case LABEL_REF:
28038fd1498Szrj      /* For certain code models, the code is near as well.  */
28138fd1498Szrj      return ix86_cmodel == CM_SMALL || ix86_cmodel == CM_MEDIUM;
28238fd1498Szrj
28338fd1498Szrj    case CONST:
28438fd1498Szrj      /* We also may accept the offsetted memory references in certain
28538fd1498Szrj	 special cases.  */
28638fd1498Szrj      if (GET_CODE (XEXP (op, 0)) == PLUS)
28738fd1498Szrj	{
28838fd1498Szrj	  rtx op1 = XEXP (XEXP (op, 0), 0);
28938fd1498Szrj	  rtx op2 = XEXP (XEXP (op, 0), 1);
29038fd1498Szrj
29138fd1498Szrj	  if (ix86_cmodel == CM_LARGE)
29238fd1498Szrj	    return false;
29338fd1498Szrj	  if (!CONST_INT_P (op2))
29438fd1498Szrj	    return false;
29538fd1498Szrj
29638fd1498Szrj	  HOST_WIDE_INT offset = INTVAL (op2);
29738fd1498Szrj	  if (trunc_int_for_mode (offset, SImode) != offset)
29838fd1498Szrj	    return false;
29938fd1498Szrj
30038fd1498Szrj	  switch (GET_CODE (op1))
30138fd1498Szrj	    {
30238fd1498Szrj	    case SYMBOL_REF:
30338fd1498Szrj	      /* TLS symbols are not constant.  */
30438fd1498Szrj	      if (SYMBOL_REF_TLS_MODEL (op1))
30538fd1498Szrj		return false;
30638fd1498Szrj
30738fd1498Szrj	      /* Load the external function address via the GOT slot.  */
30838fd1498Szrj	      if (ix86_force_load_from_GOT_p (op1))
30938fd1498Szrj	        return false;
31038fd1498Szrj
31138fd1498Szrj	      /* For small code model we may accept pretty large positive
31238fd1498Szrj		 offsets, since one bit is available for free.  Negative
31338fd1498Szrj		 offsets are limited by the size of NULL pointer area
31438fd1498Szrj		 specified by the ABI.  */
31538fd1498Szrj	      if ((ix86_cmodel == CM_SMALL
31638fd1498Szrj		   || (ix86_cmodel == CM_MEDIUM
31738fd1498Szrj		       && !SYMBOL_REF_FAR_ADDR_P (op1)))
31838fd1498Szrj		  && offset > -0x10000)
31938fd1498Szrj		return true;
32038fd1498Szrj	      /* ??? For the kernel, we may accept adjustment of
32138fd1498Szrj		 -0x10000000, since we know that it will just convert
32238fd1498Szrj		 negative address space to positive, but perhaps this
32338fd1498Szrj		 is not worthwhile.  */
32438fd1498Szrj	      break;
32538fd1498Szrj
32638fd1498Szrj	    case LABEL_REF:
32738fd1498Szrj	      /* These conditions are similar to SYMBOL_REF ones, just the
32838fd1498Szrj		 constraints for code models differ.  */
32938fd1498Szrj	      if ((ix86_cmodel == CM_SMALL || ix86_cmodel == CM_MEDIUM)
33038fd1498Szrj		  && offset > -0x10000)
33138fd1498Szrj		return true;
33238fd1498Szrj	      break;
33338fd1498Szrj
33438fd1498Szrj	    default:
33538fd1498Szrj	      return false;
33638fd1498Szrj	    }
33738fd1498Szrj	}
33838fd1498Szrj      break;
33938fd1498Szrj
34038fd1498Szrj    default:
34138fd1498Szrj      gcc_unreachable ();
34238fd1498Szrj    }
34338fd1498Szrj  return false;
34438fd1498Szrj})
34538fd1498Szrj
34638fd1498Szrj;; Return true if VALUE is a constant integer whose low and high words satisfy
34738fd1498Szrj;; x86_64_immediate_operand.
34838fd1498Szrj(define_predicate "x86_64_hilo_int_operand"
34938fd1498Szrj  (match_code "const_int,const_wide_int")
35038fd1498Szrj{
35138fd1498Szrj  switch (GET_CODE (op))
35238fd1498Szrj    {
35338fd1498Szrj    case CONST_INT:
35438fd1498Szrj      return x86_64_immediate_operand (op, mode);
35538fd1498Szrj
35638fd1498Szrj    case CONST_WIDE_INT:
35738fd1498Szrj      gcc_assert (CONST_WIDE_INT_NUNITS (op) == 2);
35838fd1498Szrj      return (x86_64_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (op, 0)),
35938fd1498Szrj					DImode)
36038fd1498Szrj	      && x86_64_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (op,
36138fd1498Szrj									1)),
36238fd1498Szrj					   DImode));
36338fd1498Szrj
36438fd1498Szrj    default:
36538fd1498Szrj      gcc_unreachable ();
36638fd1498Szrj    }
36738fd1498Szrj})
36838fd1498Szrj
36938fd1498Szrj;; Return true if VALUE is a constant integer whose value is
37038fd1498Szrj;; x86_64_immediate_operand value zero extended from word mode to mode.
37138fd1498Szrj(define_predicate "x86_64_dwzext_immediate_operand"
37238fd1498Szrj  (match_code "const_int,const_wide_int")
37338fd1498Szrj{
37438fd1498Szrj  switch (GET_CODE (op))
37538fd1498Szrj    {
37638fd1498Szrj    case CONST_INT:
37738fd1498Szrj      if (!TARGET_64BIT)
37838fd1498Szrj	return UINTVAL (op) <= HOST_WIDE_INT_UC (0xffffffff);
37938fd1498Szrj      return UINTVAL (op) <= HOST_WIDE_INT_UC (0x7fffffff);
38038fd1498Szrj
38138fd1498Szrj    case CONST_WIDE_INT:
38238fd1498Szrj      if (!TARGET_64BIT)
38338fd1498Szrj	return false;
38438fd1498Szrj      return (CONST_WIDE_INT_NUNITS (op) == 2
38538fd1498Szrj	      && CONST_WIDE_INT_ELT (op, 1) == 0
38638fd1498Szrj	      && (trunc_int_for_mode (CONST_WIDE_INT_ELT (op, 0), SImode)
38738fd1498Szrj		  == (HOST_WIDE_INT) CONST_WIDE_INT_ELT (op, 0)));
38838fd1498Szrj
38938fd1498Szrj    default:
39038fd1498Szrj      gcc_unreachable ();
39138fd1498Szrj    }
39238fd1498Szrj})
39338fd1498Szrj
39438fd1498Szrj;; Return true if size of VALUE can be stored in a sign
39538fd1498Szrj;; extended immediate field.
39638fd1498Szrj(define_predicate "x86_64_immediate_size_operand"
39738fd1498Szrj  (and (match_code "symbol_ref")
39838fd1498Szrj       (ior (not (match_test "TARGET_64BIT"))
39938fd1498Szrj	    (match_test "ix86_cmodel == CM_SMALL")
40038fd1498Szrj	    (match_test "ix86_cmodel == CM_KERNEL"))))
40138fd1498Szrj
40238fd1498Szrj;; Return true if OP is general operand representable on x86_64.
40338fd1498Szrj(define_predicate "x86_64_general_operand"
40438fd1498Szrj  (if_then_else (match_test "TARGET_64BIT")
40538fd1498Szrj    (ior (match_operand 0 "nonimmediate_operand")
40638fd1498Szrj	 (match_operand 0 "x86_64_immediate_operand"))
40738fd1498Szrj    (match_operand 0 "general_operand")))
40838fd1498Szrj
40938fd1498Szrj;; Return true if OP's both words are general operands representable
41038fd1498Szrj;; on x86_64.
41138fd1498Szrj(define_predicate "x86_64_hilo_general_operand"
41238fd1498Szrj  (if_then_else (match_test "TARGET_64BIT")
41338fd1498Szrj    (ior (match_operand 0 "nonimmediate_operand")
41438fd1498Szrj	 (match_operand 0 "x86_64_hilo_int_operand"))
41538fd1498Szrj    (match_operand 0 "general_operand")))
41638fd1498Szrj
41738fd1498Szrj;; Return true if OP is non-VOIDmode general operand representable
41838fd1498Szrj;; on x86_64.  This predicate is used in sign-extending conversion
41938fd1498Szrj;; operations that require non-VOIDmode immediate operands.
42038fd1498Szrj(define_predicate "x86_64_sext_operand"
42138fd1498Szrj  (and (match_test "GET_MODE (op) != VOIDmode")
42238fd1498Szrj       (match_operand 0 "x86_64_general_operand")))
42338fd1498Szrj
42438fd1498Szrj;; Return true if OP is non-VOIDmode general operand.  This predicate
42538fd1498Szrj;; is used in sign-extending conversion operations that require
42638fd1498Szrj;; non-VOIDmode immediate operands.
42738fd1498Szrj(define_predicate "sext_operand"
42838fd1498Szrj  (and (match_test "GET_MODE (op) != VOIDmode")
42938fd1498Szrj       (match_operand 0 "general_operand")))
43038fd1498Szrj
43138fd1498Szrj;; Return true if OP is representable on x86_64 as zero-extended operand.
43238fd1498Szrj;; This predicate is used in zero-extending conversion operations that
43338fd1498Szrj;; require non-VOIDmode immediate operands.
43438fd1498Szrj(define_predicate "x86_64_zext_operand"
43538fd1498Szrj  (if_then_else (match_test "TARGET_64BIT")
43638fd1498Szrj    (ior (match_operand 0 "nonimmediate_operand")
43738fd1498Szrj	 (and (match_operand 0 "x86_64_zext_immediate_operand")
43838fd1498Szrj	      (match_test "GET_MODE (op) != VOIDmode")))
43938fd1498Szrj    (match_operand 0 "nonimmediate_operand")))
44038fd1498Szrj
44138fd1498Szrj;; Return true if OP is general operand representable on x86_64
44238fd1498Szrj;; as either sign extended or zero extended constant.
44338fd1498Szrj(define_predicate "x86_64_szext_general_operand"
44438fd1498Szrj  (if_then_else (match_test "TARGET_64BIT")
44538fd1498Szrj    (ior (match_operand 0 "nonimmediate_operand")
44638fd1498Szrj	 (match_operand 0 "x86_64_immediate_operand")
44738fd1498Szrj	 (match_operand 0 "x86_64_zext_immediate_operand"))
44838fd1498Szrj    (match_operand 0 "general_operand")))
44938fd1498Szrj
45038fd1498Szrj;; Return true if OP is nonmemory operand representable on x86_64.
45138fd1498Szrj(define_predicate "x86_64_nonmemory_operand"
45238fd1498Szrj  (if_then_else (match_test "TARGET_64BIT")
45338fd1498Szrj    (ior (match_operand 0 "register_operand")
45438fd1498Szrj	 (match_operand 0 "x86_64_immediate_operand"))
45538fd1498Szrj    (match_operand 0 "nonmemory_operand")))
45638fd1498Szrj
45738fd1498Szrj;; Return true if OP is nonmemory operand representable on x86_64.
45838fd1498Szrj(define_predicate "x86_64_szext_nonmemory_operand"
45938fd1498Szrj  (if_then_else (match_test "TARGET_64BIT")
46038fd1498Szrj    (ior (match_operand 0 "register_operand")
46138fd1498Szrj	 (match_operand 0 "x86_64_immediate_operand")
46238fd1498Szrj	 (match_operand 0 "x86_64_zext_immediate_operand"))
46338fd1498Szrj    (match_operand 0 "nonmemory_operand")))
46438fd1498Szrj
46538fd1498Szrj;; Return true when operand is PIC expression that can be computed by lea
46638fd1498Szrj;; operation.
46738fd1498Szrj(define_predicate "pic_32bit_operand"
46838fd1498Szrj  (match_code "const,symbol_ref,label_ref")
46938fd1498Szrj{
47038fd1498Szrj  if (!flag_pic)
47138fd1498Szrj    return false;
47238fd1498Szrj
47338fd1498Szrj  /* Rule out relocations that translate into 64bit constants.  */
47438fd1498Szrj  if (TARGET_64BIT && GET_CODE (op) == CONST)
47538fd1498Szrj    {
47638fd1498Szrj      op = XEXP (op, 0);
47738fd1498Szrj      if (GET_CODE (op) == PLUS && CONST_INT_P (XEXP (op, 1)))
47838fd1498Szrj	op = XEXP (op, 0);
47938fd1498Szrj      if (GET_CODE (op) == UNSPEC
48038fd1498Szrj	  && (XINT (op, 1) == UNSPEC_GOTOFF
48138fd1498Szrj	      || XINT (op, 1) == UNSPEC_GOT))
48238fd1498Szrj	return false;
48338fd1498Szrj    }
48438fd1498Szrj
48538fd1498Szrj  return symbolic_operand (op, mode);
48638fd1498Szrj})
48738fd1498Szrj
48838fd1498Szrj;; Return true if OP is nonmemory operand acceptable by movabs patterns.
48938fd1498Szrj(define_predicate "x86_64_movabs_operand"
49038fd1498Szrj  (and (match_operand 0 "nonmemory_operand")
49138fd1498Szrj       (not (match_operand 0 "pic_32bit_operand"))))
49238fd1498Szrj
49338fd1498Szrj;; Return true if OP is either a symbol reference or a sum of a symbol
49438fd1498Szrj;; reference and a constant.
49538fd1498Szrj(define_predicate "symbolic_operand"
49638fd1498Szrj  (match_code "symbol_ref,label_ref,const")
49738fd1498Szrj{
49838fd1498Szrj  switch (GET_CODE (op))
49938fd1498Szrj    {
50038fd1498Szrj    case SYMBOL_REF:
50138fd1498Szrj    case LABEL_REF:
50238fd1498Szrj      return true;
50338fd1498Szrj
50438fd1498Szrj    case CONST:
50538fd1498Szrj      op = XEXP (op, 0);
50638fd1498Szrj      if (GET_CODE (op) == SYMBOL_REF
50738fd1498Szrj	  || GET_CODE (op) == LABEL_REF
50838fd1498Szrj	  || (GET_CODE (op) == UNSPEC
50938fd1498Szrj	      && (XINT (op, 1) == UNSPEC_GOT
51038fd1498Szrj		  || XINT (op, 1) == UNSPEC_GOTOFF
51138fd1498Szrj		  || XINT (op, 1) == UNSPEC_PCREL
51238fd1498Szrj		  || XINT (op, 1) == UNSPEC_GOTPCREL)))
51338fd1498Szrj	return true;
51438fd1498Szrj      if (GET_CODE (op) != PLUS
51538fd1498Szrj	  || !CONST_INT_P (XEXP (op, 1)))
51638fd1498Szrj	return false;
51738fd1498Szrj
51838fd1498Szrj      op = XEXP (op, 0);
51938fd1498Szrj      if (GET_CODE (op) == SYMBOL_REF
52038fd1498Szrj	  || GET_CODE (op) == LABEL_REF)
52138fd1498Szrj	return true;
52238fd1498Szrj      /* Only @GOTOFF gets offsets.  */
52338fd1498Szrj      if (GET_CODE (op) != UNSPEC
52438fd1498Szrj	  || XINT (op, 1) != UNSPEC_GOTOFF)
52538fd1498Szrj	return false;
52638fd1498Szrj
52738fd1498Szrj      op = XVECEXP (op, 0, 0);
52838fd1498Szrj      if (GET_CODE (op) == SYMBOL_REF
52938fd1498Szrj	  || GET_CODE (op) == LABEL_REF)
53038fd1498Szrj	return true;
53138fd1498Szrj      return false;
53238fd1498Szrj
53338fd1498Szrj    default:
53438fd1498Szrj      gcc_unreachable ();
53538fd1498Szrj    }
53638fd1498Szrj})
53738fd1498Szrj
53838fd1498Szrj;; Return true if OP is a symbolic operand that resolves locally.
53938fd1498Szrj(define_predicate "local_symbolic_operand"
54038fd1498Szrj  (match_code "const,label_ref,symbol_ref")
54138fd1498Szrj{
54238fd1498Szrj  if (GET_CODE (op) == CONST
54338fd1498Szrj      && GET_CODE (XEXP (op, 0)) == PLUS
54438fd1498Szrj      && CONST_INT_P (XEXP (XEXP (op, 0), 1)))
54538fd1498Szrj    op = XEXP (XEXP (op, 0), 0);
54638fd1498Szrj
54738fd1498Szrj  if (GET_CODE (op) == LABEL_REF)
54838fd1498Szrj    return true;
54938fd1498Szrj
55038fd1498Szrj  if (GET_CODE (op) != SYMBOL_REF)
55138fd1498Szrj    return false;
55238fd1498Szrj
55338fd1498Szrj  if (SYMBOL_REF_TLS_MODEL (op))
55438fd1498Szrj    return false;
55538fd1498Szrj
55638fd1498Szrj  /* Dll-imported symbols are always external.  */
55738fd1498Szrj  if (TARGET_DLLIMPORT_DECL_ATTRIBUTES && SYMBOL_REF_DLLIMPORT_P (op))
55838fd1498Szrj    return false;
55938fd1498Szrj  if (SYMBOL_REF_LOCAL_P (op))
56038fd1498Szrj    return true;
56138fd1498Szrj
56238fd1498Szrj  /* There is, however, a not insubstantial body of code in the rest of
56338fd1498Szrj     the compiler that assumes it can just stick the results of
56438fd1498Szrj     ASM_GENERATE_INTERNAL_LABEL in a symbol_ref and have done.  */
56538fd1498Szrj  /* ??? This is a hack.  Should update the body of the compiler to
56638fd1498Szrj     always create a DECL an invoke targetm.encode_section_info.  */
56738fd1498Szrj  if (strncmp (XSTR (op, 0), internal_label_prefix,
56838fd1498Szrj	       internal_label_prefix_len) == 0)
56938fd1498Szrj    return true;
57038fd1498Szrj
57138fd1498Szrj  return false;
57238fd1498Szrj})
57338fd1498Szrj
57438fd1498Szrj;; Test for a legitimate @GOTOFF operand.
57538fd1498Szrj;;
57638fd1498Szrj;; VxWorks does not impose a fixed gap between segments; the run-time
57738fd1498Szrj;; gap can be different from the object-file gap.  We therefore can't
57838fd1498Szrj;; use @GOTOFF unless we are absolutely sure that the symbol is in the
57938fd1498Szrj;; same segment as the GOT.  Unfortunately, the flexibility of linker
58038fd1498Szrj;; scripts means that we can't be sure of that in general, so assume
58138fd1498Szrj;; that @GOTOFF is never valid on VxWorks.
58238fd1498Szrj(define_predicate "gotoff_operand"
58338fd1498Szrj  (and (not (match_test "TARGET_VXWORKS_RTP"))
58438fd1498Szrj       (match_operand 0 "local_symbolic_operand")))
58538fd1498Szrj
58638fd1498Szrj;; Test for various thread-local symbols.
58738fd1498Szrj(define_special_predicate "tls_symbolic_operand"
58838fd1498Szrj  (and (match_code "symbol_ref")
58938fd1498Szrj       (match_test "SYMBOL_REF_TLS_MODEL (op)")))
59038fd1498Szrj
59138fd1498Szrj(define_special_predicate "tls_modbase_operand"
59238fd1498Szrj  (and (match_code "symbol_ref")
59338fd1498Szrj       (match_test "op == ix86_tls_module_base ()")))
59438fd1498Szrj
59538fd1498Szrj(define_predicate "tls_address_pattern"
59638fd1498Szrj  (and (match_code "set,parallel,unspec,unspec_volatile")
59738fd1498Szrj       (match_test "ix86_tls_address_pattern_p (op)")))
59838fd1498Szrj
59938fd1498Szrj;; Test for a pc-relative call operand
60038fd1498Szrj(define_predicate "constant_call_address_operand"
60138fd1498Szrj  (match_code "symbol_ref")
60238fd1498Szrj{
60338fd1498Szrj  if (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC
60438fd1498Szrj      || flag_force_indirect_call)
60538fd1498Szrj    return false;
60638fd1498Szrj  if (TARGET_DLLIMPORT_DECL_ATTRIBUTES && SYMBOL_REF_DLLIMPORT_P (op))
60738fd1498Szrj    return false;
60838fd1498Szrj  return true;
60938fd1498Szrj})
61038fd1498Szrj
61138fd1498Szrj;; P6 processors will jump to the address after the decrement when %esp
61238fd1498Szrj;; is used as a call operand, so they will execute return address as a code.
61338fd1498Szrj;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
61438fd1498Szrj
61538fd1498Szrj(define_predicate "call_register_no_elim_operand"
61638fd1498Szrj  (match_operand 0 "register_operand")
61738fd1498Szrj{
61838fd1498Szrj  if (SUBREG_P (op))
61938fd1498Szrj    op = SUBREG_REG (op);
62038fd1498Szrj
62138fd1498Szrj  if (!TARGET_64BIT && op == stack_pointer_rtx)
62238fd1498Szrj    return false;
62338fd1498Szrj
62438fd1498Szrj  return register_no_elim_operand (op, mode);
62538fd1498Szrj})
62638fd1498Szrj
62738fd1498Szrj;; True for any non-virtual or eliminable register.  Used in places where
62838fd1498Szrj;; instantiation of such a register may cause the pattern to not be recognized.
62938fd1498Szrj(define_predicate "register_no_elim_operand"
63038fd1498Szrj  (match_operand 0 "register_operand")
63138fd1498Szrj{
63238fd1498Szrj  if (SUBREG_P (op))
63338fd1498Szrj    op = SUBREG_REG (op);
63438fd1498Szrj  return !(op == arg_pointer_rtx
63538fd1498Szrj	   || op == frame_pointer_rtx
63638fd1498Szrj	   || IN_RANGE (REGNO (op),
63738fd1498Szrj			FIRST_PSEUDO_REGISTER, LAST_VIRTUAL_REGISTER));
63838fd1498Szrj})
63938fd1498Szrj
64038fd1498Szrj;; Similarly, but include the stack pointer.  This is used to prevent esp
64138fd1498Szrj;; from being used as an index reg.
64238fd1498Szrj(define_predicate "index_register_operand"
64338fd1498Szrj  (match_operand 0 "register_operand")
64438fd1498Szrj{
64538fd1498Szrj  if (SUBREG_P (op))
64638fd1498Szrj    op = SUBREG_REG (op);
64738fd1498Szrj  if (reload_completed)
64838fd1498Szrj    return REG_OK_FOR_INDEX_STRICT_P (op);
64938fd1498Szrj  else
65038fd1498Szrj    return REG_OK_FOR_INDEX_NONSTRICT_P (op);
65138fd1498Szrj})
65238fd1498Szrj
65338fd1498Szrj;; Return false if this is any eliminable register.  Otherwise general_operand.
65438fd1498Szrj(define_predicate "general_no_elim_operand"
65538fd1498Szrj  (if_then_else (match_code "reg,subreg")
65638fd1498Szrj    (match_operand 0 "register_no_elim_operand")
65738fd1498Szrj    (match_operand 0 "general_operand")))
65838fd1498Szrj
65938fd1498Szrj;; Return false if this is any eliminable register.  Otherwise
66038fd1498Szrj;; register_operand or a constant.
66138fd1498Szrj(define_predicate "nonmemory_no_elim_operand"
66238fd1498Szrj  (ior (match_operand 0 "register_no_elim_operand")
66338fd1498Szrj       (match_operand 0 "immediate_operand")))
66438fd1498Szrj
66538fd1498Szrj;; Test for a valid operand for indirect branch.
66638fd1498Szrj(define_predicate "indirect_branch_operand"
66738fd1498Szrj  (ior (match_operand 0 "register_operand")
66838fd1498Szrj       (and (not (match_test "TARGET_INDIRECT_BRANCH_REGISTER"))
66938fd1498Szrj	    (not (match_test "TARGET_X32"))
67038fd1498Szrj	    (match_operand 0 "memory_operand"))))
67138fd1498Szrj
67238fd1498Szrj;; Return true if OP is a memory operands that can be used in sibcalls.
67338fd1498Szrj;; Since sibcall never returns, we can only use call-clobbered register
67438fd1498Szrj;; as GOT base.  Allow GOT slot here only with pseudo register as GOT
67538fd1498Szrj;; base.  Properly handle sibcall over GOT slot with *sibcall_GOT_32
67638fd1498Szrj;; and *sibcall_value_GOT_32 patterns.
67738fd1498Szrj(define_predicate "sibcall_memory_operand"
67838fd1498Szrj  (match_operand 0 "memory_operand")
67938fd1498Szrj{
68038fd1498Szrj  op = XEXP (op, 0);
68138fd1498Szrj  if (CONSTANT_P (op))
68238fd1498Szrj    return true;
68338fd1498Szrj  if (GET_CODE (op) == PLUS && REG_P (XEXP (op, 0)))
68438fd1498Szrj    {
68538fd1498Szrj      int regno = REGNO (XEXP (op, 0));
68638fd1498Szrj      if (!HARD_REGISTER_NUM_P (regno) || call_used_regs[regno])
68738fd1498Szrj	{
68838fd1498Szrj	  op = XEXP (op, 1);
68938fd1498Szrj	  if (GOT32_symbol_operand (op, VOIDmode))
69038fd1498Szrj	    return true;
69138fd1498Szrj	}
69238fd1498Szrj    }
69338fd1498Szrj  return false;
69438fd1498Szrj})
69538fd1498Szrj
69638fd1498Szrj;; Return true if OP is a GOT memory operand.
69738fd1498Szrj(define_predicate "GOT_memory_operand"
69838fd1498Szrj  (match_operand 0 "memory_operand")
69938fd1498Szrj{
70038fd1498Szrj  op = XEXP (op, 0);
70138fd1498Szrj  return (GET_CODE (op) == CONST
70238fd1498Szrj	  && GET_CODE (XEXP (op, 0)) == UNSPEC
70338fd1498Szrj	  && XINT (XEXP (op, 0), 1) == UNSPEC_GOTPCREL);
70438fd1498Szrj})
70538fd1498Szrj
70638fd1498Szrj;; Test for a valid operand for a call instruction.
70738fd1498Szrj;; Allow constant call address operands in Pmode only.
70838fd1498Szrj(define_special_predicate "call_insn_operand"
70938fd1498Szrj  (ior (match_test "constant_call_address_operand
71038fd1498Szrj		     (op, mode == VOIDmode ? mode : Pmode)")
71138fd1498Szrj       (match_operand 0 "call_register_no_elim_operand")
71238fd1498Szrj       (and (not (match_test "TARGET_INDIRECT_BRANCH_REGISTER"))
71338fd1498Szrj	    (ior (and (not (match_test "TARGET_X32"))
71438fd1498Szrj		      (match_operand 0 "memory_operand"))
71538fd1498Szrj		 (and (match_test "TARGET_X32 && Pmode == DImode")
71638fd1498Szrj		      (match_operand 0 "GOT_memory_operand"))))))
71738fd1498Szrj
71838fd1498Szrj;; Similarly, but for tail calls, in which we cannot allow memory references.
71938fd1498Szrj(define_special_predicate "sibcall_insn_operand"
72038fd1498Szrj  (ior (match_test "constant_call_address_operand
72138fd1498Szrj		     (op, mode == VOIDmode ? mode : Pmode)")
72238fd1498Szrj       (match_operand 0 "register_no_elim_operand")
72338fd1498Szrj       (and (not (match_test "TARGET_INDIRECT_BRANCH_REGISTER"))
72438fd1498Szrj	    (ior (and (not (match_test "TARGET_X32"))
72538fd1498Szrj		      (match_operand 0 "sibcall_memory_operand"))
72638fd1498Szrj		 (and (match_test "TARGET_X32 && Pmode == DImode")
72738fd1498Szrj		      (match_operand 0 "GOT_memory_operand"))))))
72838fd1498Szrj
72938fd1498Szrj;; Return true if OP is a 32-bit GOT symbol operand.
73038fd1498Szrj(define_predicate "GOT32_symbol_operand"
73138fd1498Szrj  (match_test "GET_CODE (op) == CONST
73238fd1498Szrj               && GET_CODE (XEXP (op, 0)) == UNSPEC
73338fd1498Szrj               && XINT (XEXP (op, 0), 1) == UNSPEC_GOT"))
73438fd1498Szrj
73538fd1498Szrj;; Match exactly zero.
73638fd1498Szrj(define_predicate "const0_operand"
73738fd1498Szrj  (match_code "const_int,const_double,const_vector")
73838fd1498Szrj{
73938fd1498Szrj  if (mode == VOIDmode)
74038fd1498Szrj    mode = GET_MODE (op);
74138fd1498Szrj  return op == CONST0_RTX (mode);
74238fd1498Szrj})
74338fd1498Szrj
74438fd1498Szrj;; Match one or a vector with all elements equal to one.
74538fd1498Szrj(define_predicate "const1_operand"
74638fd1498Szrj  (match_code "const_int,const_double,const_vector")
74738fd1498Szrj{
74838fd1498Szrj  if (mode == VOIDmode)
74938fd1498Szrj    mode = GET_MODE (op);
75038fd1498Szrj  return op == CONST1_RTX (mode);
75138fd1498Szrj})
75238fd1498Szrj
75338fd1498Szrj;; Match exactly -1.
75438fd1498Szrj(define_predicate "constm1_operand"
75538fd1498Szrj  (and (match_code "const_int")
75638fd1498Szrj       (match_test "op == constm1_rtx")))
75738fd1498Szrj
75838fd1498Szrj;; Match exactly eight.
75938fd1498Szrj(define_predicate "const8_operand"
76038fd1498Szrj  (and (match_code "const_int")
76138fd1498Szrj       (match_test "INTVAL (op) == 8")))
76238fd1498Szrj
76338fd1498Szrj;; Match exactly 128.
76438fd1498Szrj(define_predicate "const128_operand"
76538fd1498Szrj  (and (match_code "const_int")
76638fd1498Szrj       (match_test "INTVAL (op) == 128")))
76738fd1498Szrj
76838fd1498Szrj;; Match exactly 0x0FFFFFFFF in anddi as a zero-extension operation
76938fd1498Szrj(define_predicate "const_32bit_mask"
77038fd1498Szrj  (and (match_code "const_int")
77138fd1498Szrj       (match_test "trunc_int_for_mode (INTVAL (op), DImode)
77238fd1498Szrj		    == (HOST_WIDE_INT) 0xffffffff")))
77338fd1498Szrj
77438fd1498Szrj;; Match 2, 4, or 8.  Used for leal multiplicands.
77538fd1498Szrj(define_predicate "const248_operand"
77638fd1498Szrj  (match_code "const_int")
77738fd1498Szrj{
77838fd1498Szrj  HOST_WIDE_INT i = INTVAL (op);
77938fd1498Szrj  return i == 2 || i == 4 || i == 8;
78038fd1498Szrj})
78138fd1498Szrj
78238fd1498Szrj;; Match 1, 2, or 3.  Used for lea shift amounts.
78338fd1498Szrj(define_predicate "const123_operand"
78438fd1498Szrj  (match_code "const_int")
78538fd1498Szrj{
78638fd1498Szrj  HOST_WIDE_INT i = INTVAL (op);
78738fd1498Szrj  return i == 1 || i == 2 || i == 3;
78838fd1498Szrj})
78938fd1498Szrj
79038fd1498Szrj;; Match 2, 3, 6, or 7
79138fd1498Szrj(define_predicate "const2367_operand"
79238fd1498Szrj  (match_code "const_int")
79338fd1498Szrj{
79438fd1498Szrj  HOST_WIDE_INT i = INTVAL (op);
79538fd1498Szrj  return i == 2 || i == 3 || i == 6 || i == 7;
79638fd1498Szrj})
79738fd1498Szrj
79838fd1498Szrj;; Match 1, 2, 4, or 8
79938fd1498Szrj(define_predicate "const1248_operand"
80038fd1498Szrj  (match_code "const_int")
80138fd1498Szrj{
80238fd1498Szrj  HOST_WIDE_INT i = INTVAL (op);
80338fd1498Szrj  return i == 1 || i == 2 || i == 4 || i == 8;
80438fd1498Szrj})
80538fd1498Szrj
80638fd1498Szrj;; Match 3, 5, or 9.  Used for leal multiplicands.
80738fd1498Szrj(define_predicate "const359_operand"
80838fd1498Szrj  (match_code "const_int")
80938fd1498Szrj{
81038fd1498Szrj  HOST_WIDE_INT i = INTVAL (op);
81138fd1498Szrj  return i == 3 || i == 5 || i == 9;
81238fd1498Szrj})
81338fd1498Szrj
81438fd1498Szrj;; Match 4 or 8 to 11.  Used for embeded rounding.
81538fd1498Szrj(define_predicate "const_4_or_8_to_11_operand"
81638fd1498Szrj  (match_code "const_int")
81738fd1498Szrj{
81838fd1498Szrj  HOST_WIDE_INT i = INTVAL (op);
81938fd1498Szrj  return i == 4 || (i >= 8 && i <= 11);
82038fd1498Szrj})
82138fd1498Szrj
82238fd1498Szrj;; Match 4 or 8. Used for SAE.
82338fd1498Szrj(define_predicate "const48_operand"
82438fd1498Szrj  (match_code "const_int")
82538fd1498Szrj{
82638fd1498Szrj  HOST_WIDE_INT i = INTVAL (op);
82738fd1498Szrj  return i == 4 || i == 8;
82838fd1498Szrj})
82938fd1498Szrj
83038fd1498Szrj;; Match 0 or 1.
83138fd1498Szrj(define_predicate "const_0_to_1_operand"
83238fd1498Szrj  (and (match_code "const_int")
83338fd1498Szrj       (ior (match_test "op == const0_rtx")
83438fd1498Szrj	    (match_test "op == const1_rtx"))))
83538fd1498Szrj
83638fd1498Szrj;; Match 0 to 3.
83738fd1498Szrj(define_predicate "const_0_to_3_operand"
83838fd1498Szrj  (and (match_code "const_int")
83938fd1498Szrj       (match_test "IN_RANGE (INTVAL (op), 0, 3)")))
84038fd1498Szrj
84138fd1498Szrj;; Match 0 to 4.
84238fd1498Szrj(define_predicate "const_0_to_4_operand"
84338fd1498Szrj  (and (match_code "const_int")
84438fd1498Szrj       (match_test "IN_RANGE (INTVAL (op), 0, 4)")))
84538fd1498Szrj
84638fd1498Szrj;; Match 0 to 5.
84738fd1498Szrj(define_predicate "const_0_to_5_operand"
84838fd1498Szrj  (and (match_code "const_int")
84938fd1498Szrj       (match_test "IN_RANGE (INTVAL (op), 0, 5)")))
85038fd1498Szrj
85138fd1498Szrj;; Match 0 to 7.
85238fd1498Szrj(define_predicate "const_0_to_7_operand"
85338fd1498Szrj  (and (match_code "const_int")
85438fd1498Szrj       (match_test "IN_RANGE (INTVAL (op), 0, 7)")))
85538fd1498Szrj
85638fd1498Szrj;; Match 0 to 15.
85738fd1498Szrj(define_predicate "const_0_to_15_operand"
85838fd1498Szrj  (and (match_code "const_int")
85938fd1498Szrj       (match_test "IN_RANGE (INTVAL (op), 0, 15)")))
86038fd1498Szrj
86138fd1498Szrj;; Match 0 to 31.
86238fd1498Szrj(define_predicate "const_0_to_31_operand"
86338fd1498Szrj  (and (match_code "const_int")
86438fd1498Szrj       (match_test "IN_RANGE (INTVAL (op), 0, 31)")))
86538fd1498Szrj
86638fd1498Szrj;; Match 0 to 63.
86738fd1498Szrj(define_predicate "const_0_to_63_operand"
86838fd1498Szrj  (and (match_code "const_int")
86938fd1498Szrj       (match_test "IN_RANGE (INTVAL (op), 0, 63)")))
87038fd1498Szrj
87138fd1498Szrj;; Match 0 to 255.
87238fd1498Szrj(define_predicate "const_0_to_255_operand"
87338fd1498Szrj  (and (match_code "const_int")
87438fd1498Szrj       (match_test "IN_RANGE (INTVAL (op), 0, 255)")))
87538fd1498Szrj
87638fd1498Szrj;; Match (0 to 255) * 8
87738fd1498Szrj(define_predicate "const_0_to_255_mul_8_operand"
87838fd1498Szrj  (match_code "const_int")
87938fd1498Szrj{
88038fd1498Szrj  unsigned HOST_WIDE_INT val = INTVAL (op);
88138fd1498Szrj  return val <= 255*8 && val % 8 == 0;
88238fd1498Szrj})
88338fd1498Szrj
88438fd1498Szrj;; Return true if OP is CONST_INT >= 1 and <= 31 (a valid operand
88538fd1498Szrj;; for shift & compare patterns, as shifting by 0 does not change flags).
88638fd1498Szrj(define_predicate "const_1_to_31_operand"
88738fd1498Szrj  (and (match_code "const_int")
88838fd1498Szrj       (match_test "IN_RANGE (INTVAL (op), 1, 31)")))
88938fd1498Szrj
89038fd1498Szrj;; Return true if OP is CONST_INT >= 1 and <= 63 (a valid operand
89138fd1498Szrj;; for 64bit shift & compare patterns, as shifting by 0 does not change flags).
89238fd1498Szrj(define_predicate "const_1_to_63_operand"
89338fd1498Szrj  (and (match_code "const_int")
89438fd1498Szrj       (match_test "IN_RANGE (INTVAL (op), 1, 63)")))
89538fd1498Szrj
89638fd1498Szrj;; Match 2 or 3.
89738fd1498Szrj(define_predicate "const_2_to_3_operand"
89838fd1498Szrj  (and (match_code "const_int")
89938fd1498Szrj       (match_test "IN_RANGE (INTVAL (op), 2, 3)")))
90038fd1498Szrj
90138fd1498Szrj;; Match 4 to 5.
90238fd1498Szrj(define_predicate "const_4_to_5_operand"
90338fd1498Szrj  (and (match_code "const_int")
90438fd1498Szrj       (match_test "IN_RANGE (INTVAL (op), 4, 5)")))
90538fd1498Szrj
90638fd1498Szrj;; Match 4 to 7.
90738fd1498Szrj(define_predicate "const_4_to_7_operand"
90838fd1498Szrj  (and (match_code "const_int")
90938fd1498Szrj       (match_test "IN_RANGE (INTVAL (op), 4, 7)")))
91038fd1498Szrj
91138fd1498Szrj;; Match 6 to 7.
91238fd1498Szrj(define_predicate "const_6_to_7_operand"
91338fd1498Szrj  (and (match_code "const_int")
91438fd1498Szrj       (match_test "IN_RANGE (INTVAL (op), 6, 7)")))
91538fd1498Szrj
91638fd1498Szrj;; Match 8 to 9.
91738fd1498Szrj(define_predicate "const_8_to_9_operand"
91838fd1498Szrj  (and (match_code "const_int")
91938fd1498Szrj       (match_test "IN_RANGE (INTVAL (op), 8, 9)")))
92038fd1498Szrj
92138fd1498Szrj;; Match 8 to 11.
92238fd1498Szrj(define_predicate "const_8_to_11_operand"
92338fd1498Szrj  (and (match_code "const_int")
92438fd1498Szrj       (match_test "IN_RANGE (INTVAL (op), 8, 11)")))
92538fd1498Szrj
92638fd1498Szrj;; Match 8 to 15.
92738fd1498Szrj(define_predicate "const_8_to_15_operand"
92838fd1498Szrj  (and (match_code "const_int")
92938fd1498Szrj       (match_test "IN_RANGE (INTVAL (op), 8, 15)")))
93038fd1498Szrj
93138fd1498Szrj;; Match 10 to 11.
93238fd1498Szrj(define_predicate "const_10_to_11_operand"
93338fd1498Szrj  (and (match_code "const_int")
93438fd1498Szrj       (match_test "IN_RANGE (INTVAL (op), 10, 11)")))
93538fd1498Szrj
93638fd1498Szrj;; Match 12 to 13.
93738fd1498Szrj(define_predicate "const_12_to_13_operand"
93838fd1498Szrj  (and (match_code "const_int")
93938fd1498Szrj       (match_test "IN_RANGE (INTVAL (op), 12, 13)")))
94038fd1498Szrj
94138fd1498Szrj;; Match 12 to 15.
94238fd1498Szrj(define_predicate "const_12_to_15_operand"
94338fd1498Szrj  (and (match_code "const_int")
94438fd1498Szrj       (match_test "IN_RANGE (INTVAL (op), 12, 15)")))
94538fd1498Szrj
94638fd1498Szrj;; Match 14 to 15.
94738fd1498Szrj(define_predicate "const_14_to_15_operand"
94838fd1498Szrj  (and (match_code "const_int")
94938fd1498Szrj       (match_test "IN_RANGE (INTVAL (op), 14, 15)")))
95038fd1498Szrj
95138fd1498Szrj;; Match 16 to 19.
95238fd1498Szrj(define_predicate "const_16_to_19_operand"
95338fd1498Szrj  (and (match_code "const_int")
95438fd1498Szrj       (match_test "IN_RANGE (INTVAL (op), 16, 19)")))
95538fd1498Szrj
95638fd1498Szrj;; Match 16 to 31.
95738fd1498Szrj(define_predicate "const_16_to_31_operand"
95838fd1498Szrj  (and (match_code "const_int")
95938fd1498Szrj       (match_test "IN_RANGE (INTVAL (op), 16, 31)")))
96038fd1498Szrj
96138fd1498Szrj;; Match 20 to 23.
96238fd1498Szrj(define_predicate "const_20_to_23_operand"
96338fd1498Szrj  (and (match_code "const_int")
96438fd1498Szrj       (match_test "IN_RANGE (INTVAL (op), 20, 23)")))
96538fd1498Szrj
96638fd1498Szrj;; Match 24 to 27.
96738fd1498Szrj(define_predicate "const_24_to_27_operand"
96838fd1498Szrj  (and (match_code "const_int")
96938fd1498Szrj       (match_test "IN_RANGE (INTVAL (op), 24, 27)")))
97038fd1498Szrj
97138fd1498Szrj;; Match 28 to 31.
97238fd1498Szrj(define_predicate "const_28_to_31_operand"
97338fd1498Szrj  (and (match_code "const_int")
97438fd1498Szrj       (match_test "IN_RANGE (INTVAL (op), 28, 31)")))
97538fd1498Szrj
97638fd1498Szrj;; True if this is a constant appropriate for an increment or decrement.
97738fd1498Szrj(define_predicate "incdec_operand"
97838fd1498Szrj  (match_code "const_int")
97938fd1498Szrj{
98038fd1498Szrj  /* On Pentium4, the inc and dec operations causes extra dependency on flag
98138fd1498Szrj     registers, since carry flag is not set.  */
98238fd1498Szrj  if (!TARGET_USE_INCDEC && !optimize_insn_for_size_p ())
98338fd1498Szrj    return false;
98438fd1498Szrj  return op == const1_rtx || op == constm1_rtx;
98538fd1498Szrj})
98638fd1498Szrj
98738fd1498Szrj;; True for registers, or 1 or -1.  Used to optimize double-word shifts.
98838fd1498Szrj(define_predicate "reg_or_pm1_operand"
98938fd1498Szrj  (ior (match_operand 0 "register_operand")
99038fd1498Szrj       (and (match_code "const_int")
99138fd1498Szrj	    (ior (match_test "op == const1_rtx")
99238fd1498Szrj		 (match_test "op == constm1_rtx")))))
99338fd1498Szrj
99438fd1498Szrj;; True if OP is acceptable as operand of DImode shift expander.
99538fd1498Szrj(define_predicate "shiftdi_operand"
99638fd1498Szrj  (if_then_else (match_test "TARGET_64BIT")
99738fd1498Szrj    (match_operand 0 "nonimmediate_operand")
99838fd1498Szrj    (match_operand 0 "register_operand")))
99938fd1498Szrj
100038fd1498Szrj(define_predicate "ashldi_input_operand"
100138fd1498Szrj  (if_then_else (match_test "TARGET_64BIT")
100238fd1498Szrj    (match_operand 0 "nonimmediate_operand")
100338fd1498Szrj    (match_operand 0 "reg_or_pm1_operand")))
100438fd1498Szrj
100538fd1498Szrj;; Return true if OP is a vector load from the constant pool with just
100638fd1498Szrj;; the first element nonzero.
100738fd1498Szrj(define_predicate "zero_extended_scalar_load_operand"
100838fd1498Szrj  (match_code "mem")
100938fd1498Szrj{
101038fd1498Szrj  unsigned n_elts;
101138fd1498Szrj  op = avoid_constant_pool_reference (op);
101238fd1498Szrj
101338fd1498Szrj  if (GET_CODE (op) != CONST_VECTOR)
101438fd1498Szrj    return false;
101538fd1498Szrj
101638fd1498Szrj  n_elts = CONST_VECTOR_NUNITS (op);
101738fd1498Szrj
101838fd1498Szrj  for (n_elts--; n_elts > 0; n_elts--)
101938fd1498Szrj    {
102038fd1498Szrj      rtx elt = CONST_VECTOR_ELT (op, n_elts);
102138fd1498Szrj      if (elt != CONST0_RTX (GET_MODE_INNER (GET_MODE (op))))
102238fd1498Szrj	return false;
102338fd1498Szrj    }
102438fd1498Szrj  return true;
102538fd1498Szrj})
102638fd1498Szrj
102738fd1498Szrj/* Return true if operand is a vector constant that is all ones. */
102838fd1498Szrj(define_predicate "vector_all_ones_operand"
102938fd1498Szrj  (and (match_code "const_vector")
103038fd1498Szrj       (match_test "INTEGRAL_MODE_P (GET_MODE (op))")
103138fd1498Szrj       (match_test "op == CONSTM1_RTX (GET_MODE (op))")))
103238fd1498Szrj
103338fd1498Szrj; Return true when OP is operand acceptable for vector memory operand.
103438fd1498Szrj; Only AVX can have misaligned memory operand.
103538fd1498Szrj(define_predicate "vector_memory_operand"
103638fd1498Szrj  (and (match_operand 0 "memory_operand")
103738fd1498Szrj       (ior (match_test "TARGET_AVX")
103838fd1498Szrj	    (match_test "MEM_ALIGN (op) >= GET_MODE_ALIGNMENT (mode)"))))
103938fd1498Szrj
104038fd1498Szrj; Return true when OP is register_operand or vector_memory_operand.
104138fd1498Szrj(define_predicate "vector_operand"
104238fd1498Szrj  (ior (match_operand 0 "register_operand")
104338fd1498Szrj       (match_operand 0 "vector_memory_operand")))
104438fd1498Szrj
104538fd1498Szrj; Return true when OP is operand acceptable for standard SSE move.
104638fd1498Szrj(define_predicate "vector_move_operand"
104738fd1498Szrj  (ior (match_operand 0 "nonimmediate_operand")
104838fd1498Szrj       (match_operand 0 "const0_operand")))
104938fd1498Szrj
105038fd1498Szrj;; Return true when OP is either nonimmediate operand, or any
105138fd1498Szrj;; CONST_VECTOR.
105238fd1498Szrj(define_predicate "nonimmediate_or_const_vector_operand"
105338fd1498Szrj  (ior (match_operand 0 "nonimmediate_operand")
105438fd1498Szrj       (match_code "const_vector")))
105538fd1498Szrj
105638fd1498Szrj;; Return true when OP is nonimmediate or standard SSE constant.
105738fd1498Szrj(define_predicate "nonimmediate_or_sse_const_operand"
105838fd1498Szrj  (ior (match_operand 0 "nonimmediate_operand")
105938fd1498Szrj       (match_test "standard_sse_constant_p (op, mode)")))
106038fd1498Szrj
106138fd1498Szrj;; Return true if OP is a register or a zero.
106238fd1498Szrj(define_predicate "reg_or_0_operand"
106338fd1498Szrj  (ior (match_operand 0 "register_operand")
106438fd1498Szrj       (match_operand 0 "const0_operand")))
106538fd1498Szrj
106638fd1498Szrj(define_predicate "norex_memory_operand"
106738fd1498Szrj  (and (match_operand 0 "memory_operand")
106838fd1498Szrj       (not (match_test "x86_extended_reg_mentioned_p (op)"))))
106938fd1498Szrj
107038fd1498Szrj;; Return true for RTX codes that force SImode address.
107138fd1498Szrj(define_predicate "SImode_address_operand"
107238fd1498Szrj  (match_code "subreg,zero_extend,and"))
107338fd1498Szrj
107438fd1498Szrj;; Return true if op is a valid address for LEA, and does not contain
107538fd1498Szrj;; a segment override.  Defined as a special predicate to allow
107638fd1498Szrj;; mode-less const_int operands pass to address_operand.
107738fd1498Szrj(define_special_predicate "address_no_seg_operand"
107838fd1498Szrj  (match_test "address_operand (op, VOIDmode)")
107938fd1498Szrj{
108038fd1498Szrj  struct ix86_address parts;
108138fd1498Szrj  int ok;
108238fd1498Szrj
108338fd1498Szrj  if (!CONST_INT_P (op)
108438fd1498Szrj      && mode != VOIDmode
108538fd1498Szrj      && GET_MODE (op) != mode)
108638fd1498Szrj    return false;
108738fd1498Szrj
108838fd1498Szrj  ok = ix86_decompose_address (op, &parts);
108938fd1498Szrj  gcc_assert (ok);
109038fd1498Szrj  return parts.seg == ADDR_SPACE_GENERIC;
109138fd1498Szrj})
109238fd1498Szrj
109338fd1498Szrj;; Return true if op if a valid base register, displacement or
109438fd1498Szrj;; sum of base register and displacement for VSIB addressing.
109538fd1498Szrj(define_predicate "vsib_address_operand"
109638fd1498Szrj  (match_test "address_operand (op, VOIDmode)")
109738fd1498Szrj{
109838fd1498Szrj  struct ix86_address parts;
109938fd1498Szrj  int ok;
110038fd1498Szrj  rtx disp;
110138fd1498Szrj
110238fd1498Szrj  ok = ix86_decompose_address (op, &parts);
110338fd1498Szrj  gcc_assert (ok);
110438fd1498Szrj  if (parts.index || parts.seg != ADDR_SPACE_GENERIC)
110538fd1498Szrj    return false;
110638fd1498Szrj
110738fd1498Szrj  /* VSIB addressing doesn't support (%rip).  */
110838fd1498Szrj  if (parts.disp)
110938fd1498Szrj    {
111038fd1498Szrj      disp = parts.disp;
111138fd1498Szrj      if (GET_CODE (disp) == CONST)
111238fd1498Szrj	{
111338fd1498Szrj	  disp = XEXP (disp, 0);
111438fd1498Szrj	  if (GET_CODE (disp) == PLUS)
111538fd1498Szrj	    disp = XEXP (disp, 0);
111638fd1498Szrj	  if (GET_CODE (disp) == UNSPEC)
111738fd1498Szrj	    switch (XINT (disp, 1))
111838fd1498Szrj	      {
111938fd1498Szrj	      case UNSPEC_GOTPCREL:
112038fd1498Szrj	      case UNSPEC_PCREL:
112138fd1498Szrj	      case UNSPEC_GOTNTPOFF:
112238fd1498Szrj		return false;
112338fd1498Szrj	      }
112438fd1498Szrj	}
112538fd1498Szrj      if (TARGET_64BIT
112638fd1498Szrj	  && flag_pic
112738fd1498Szrj	  && (GET_CODE (disp) == SYMBOL_REF
112838fd1498Szrj	      || GET_CODE (disp) == LABEL_REF))
112938fd1498Szrj	return false;
113038fd1498Szrj    }
113138fd1498Szrj
113238fd1498Szrj  return true;
113338fd1498Szrj})
113438fd1498Szrj
113538fd1498Szrj;; Return true if op is valid MPX address operand without base
113638fd1498Szrj(define_predicate "address_mpx_no_base_operand"
113738fd1498Szrj  (match_test "address_operand (op, VOIDmode)")
113838fd1498Szrj{
113938fd1498Szrj  struct ix86_address parts;
114038fd1498Szrj  int ok;
114138fd1498Szrj
114238fd1498Szrj  ok = ix86_decompose_address (op, &parts);
114338fd1498Szrj  gcc_assert (ok);
114438fd1498Szrj
114538fd1498Szrj  if (parts.index && parts.base)
114638fd1498Szrj    return false;
114738fd1498Szrj
114838fd1498Szrj  if (parts.seg != ADDR_SPACE_GENERIC)
114938fd1498Szrj    return false;
115038fd1498Szrj
115138fd1498Szrj  /* Do not support (%rip).  */
115238fd1498Szrj  if (parts.disp && flag_pic && TARGET_64BIT
115338fd1498Szrj      && SYMBOLIC_CONST (parts.disp))
115438fd1498Szrj    {
115538fd1498Szrj      if (GET_CODE (parts.disp) != CONST
115638fd1498Szrj	  || GET_CODE (XEXP (parts.disp, 0)) != PLUS
115738fd1498Szrj	  || GET_CODE (XEXP (XEXP (parts.disp, 0), 0)) != UNSPEC
115838fd1498Szrj	  || !CONST_INT_P (XEXP (XEXP (parts.disp, 0), 1))
115938fd1498Szrj	  || (XINT (XEXP (XEXP (parts.disp, 0), 0), 1) != UNSPEC_DTPOFF
116038fd1498Szrj	      && XINT (XEXP (XEXP (parts.disp, 0), 0), 1) != UNSPEC_NTPOFF))
116138fd1498Szrj	return false;
116238fd1498Szrj    }
116338fd1498Szrj
116438fd1498Szrj  return true;
116538fd1498Szrj})
116638fd1498Szrj
116738fd1498Szrj;; Return true if op is valid MPX address operand without index
116838fd1498Szrj(define_predicate "address_mpx_no_index_operand"
116938fd1498Szrj  (match_test "address_operand (op, VOIDmode)")
117038fd1498Szrj{
117138fd1498Szrj  struct ix86_address parts;
117238fd1498Szrj  int ok;
117338fd1498Szrj
117438fd1498Szrj  ok = ix86_decompose_address (op, &parts);
117538fd1498Szrj  gcc_assert (ok);
117638fd1498Szrj
117738fd1498Szrj  if (parts.index)
117838fd1498Szrj    return false;
117938fd1498Szrj
118038fd1498Szrj  if (parts.seg != ADDR_SPACE_GENERIC)
118138fd1498Szrj    return false;
118238fd1498Szrj
118338fd1498Szrj  /* Do not support (%rip).  */
118438fd1498Szrj  if (parts.disp && flag_pic && TARGET_64BIT
118538fd1498Szrj      && SYMBOLIC_CONST (parts.disp)
118638fd1498Szrj      && (GET_CODE (parts.disp) != CONST
118738fd1498Szrj	  || GET_CODE (XEXP (parts.disp, 0)) != PLUS
118838fd1498Szrj	  || GET_CODE (XEXP (XEXP (parts.disp, 0), 0)) != UNSPEC
118938fd1498Szrj	  || !CONST_INT_P (XEXP (XEXP (parts.disp, 0), 1))
119038fd1498Szrj	  || (XINT (XEXP (XEXP (parts.disp, 0), 0), 1) != UNSPEC_DTPOFF
119138fd1498Szrj	      && XINT (XEXP (XEXP (parts.disp, 0), 0), 1) != UNSPEC_NTPOFF)))
119238fd1498Szrj    return false;
119338fd1498Szrj
119438fd1498Szrj  return true;
119538fd1498Szrj})
119638fd1498Szrj
119738fd1498Szrj(define_predicate "vsib_mem_operator"
119838fd1498Szrj  (match_code "mem"))
119938fd1498Szrj
120038fd1498Szrj(define_predicate "bnd_mem_operator"
120138fd1498Szrj  (match_code "mem"))
120238fd1498Szrj
120338fd1498Szrj;; Return true if the rtx is known to be at least 32 bits aligned.
120438fd1498Szrj(define_predicate "aligned_operand"
120538fd1498Szrj  (match_operand 0 "general_operand")
120638fd1498Szrj{
120738fd1498Szrj  struct ix86_address parts;
120838fd1498Szrj  int ok;
120938fd1498Szrj
121038fd1498Szrj  /* Registers and immediate operands are always "aligned".  */
121138fd1498Szrj  if (!MEM_P (op))
121238fd1498Szrj    return true;
121338fd1498Szrj
121438fd1498Szrj  /* All patterns using aligned_operand on memory operands ends up
121538fd1498Szrj     in promoting memory operand to 64bit and thus causing memory mismatch.  */
121638fd1498Szrj  if (TARGET_MEMORY_MISMATCH_STALL && !optimize_insn_for_size_p ())
121738fd1498Szrj    return false;
121838fd1498Szrj
121938fd1498Szrj  /* Don't even try to do any aligned optimizations with volatiles.  */
122038fd1498Szrj  if (MEM_VOLATILE_P (op))
122138fd1498Szrj    return false;
122238fd1498Szrj
122338fd1498Szrj  if (MEM_ALIGN (op) >= 32)
122438fd1498Szrj    return true;
122538fd1498Szrj
122638fd1498Szrj  op = XEXP (op, 0);
122738fd1498Szrj
122838fd1498Szrj  /* Pushes and pops are only valid on the stack pointer.  */
122938fd1498Szrj  if (GET_CODE (op) == PRE_DEC
123038fd1498Szrj      || GET_CODE (op) == POST_INC)
123138fd1498Szrj    return true;
123238fd1498Szrj
123338fd1498Szrj  /* Decode the address.  */
123438fd1498Szrj  ok = ix86_decompose_address (op, &parts);
123538fd1498Szrj  gcc_assert (ok);
123638fd1498Szrj
123738fd1498Szrj  if (parts.base && SUBREG_P (parts.base))
123838fd1498Szrj    parts.base = SUBREG_REG (parts.base);
123938fd1498Szrj  if (parts.index && SUBREG_P (parts.index))
124038fd1498Szrj    parts.index = SUBREG_REG (parts.index);
124138fd1498Szrj
124238fd1498Szrj  /* Look for some component that isn't known to be aligned.  */
124338fd1498Szrj  if (parts.index)
124438fd1498Szrj    {
124538fd1498Szrj      if (REGNO_POINTER_ALIGN (REGNO (parts.index)) * parts.scale < 32)
124638fd1498Szrj	return false;
124738fd1498Szrj    }
124838fd1498Szrj  if (parts.base)
124938fd1498Szrj    {
125038fd1498Szrj      if (REGNO_POINTER_ALIGN (REGNO (parts.base)) < 32)
125138fd1498Szrj	return false;
125238fd1498Szrj    }
125338fd1498Szrj  if (parts.disp)
125438fd1498Szrj    {
125538fd1498Szrj      if (!CONST_INT_P (parts.disp)
125638fd1498Szrj	  || (INTVAL (parts.disp) & 3))
125738fd1498Szrj	return false;
125838fd1498Szrj    }
125938fd1498Szrj
126038fd1498Szrj  /* Didn't find one -- this must be an aligned address.  */
126138fd1498Szrj  return true;
126238fd1498Szrj})
126338fd1498Szrj
126438fd1498Szrj;; Return true if OP is memory operand with a displacement.
126538fd1498Szrj(define_predicate "memory_displacement_operand"
126638fd1498Szrj  (match_operand 0 "memory_operand")
126738fd1498Szrj{
126838fd1498Szrj  struct ix86_address parts;
126938fd1498Szrj  int ok;
127038fd1498Szrj
127138fd1498Szrj  ok = ix86_decompose_address (XEXP (op, 0), &parts);
127238fd1498Szrj  gcc_assert (ok);
127338fd1498Szrj  return parts.disp != NULL_RTX;
127438fd1498Szrj})
127538fd1498Szrj
127638fd1498Szrj;; Return true if OP is memory operand with a displacement only.
127738fd1498Szrj(define_predicate "memory_displacement_only_operand"
127838fd1498Szrj  (match_operand 0 "memory_operand")
127938fd1498Szrj{
128038fd1498Szrj  struct ix86_address parts;
128138fd1498Szrj  int ok;
128238fd1498Szrj
128338fd1498Szrj  if (TARGET_64BIT)
128438fd1498Szrj    return false;
128538fd1498Szrj
128638fd1498Szrj  ok = ix86_decompose_address (XEXP (op, 0), &parts);
128738fd1498Szrj  gcc_assert (ok);
128838fd1498Szrj
128938fd1498Szrj  if (parts.base || parts.index)
129038fd1498Szrj    return false;
129138fd1498Szrj
129238fd1498Szrj  return parts.disp != NULL_RTX;
129338fd1498Szrj})
129438fd1498Szrj
129538fd1498Szrj;; Return true if OP is memory operand that cannot be represented
129638fd1498Szrj;; by the modRM array.
129738fd1498Szrj(define_predicate "long_memory_operand"
129838fd1498Szrj  (and (match_operand 0 "memory_operand")
129938fd1498Szrj       (match_test "memory_address_length (op, false)")))
130038fd1498Szrj
130138fd1498Szrj;; Return true if OP is a comparison operator that can be issued by fcmov.
130238fd1498Szrj(define_predicate "fcmov_comparison_operator"
130338fd1498Szrj  (match_operand 0 "comparison_operator")
130438fd1498Szrj{
130538fd1498Szrj  machine_mode inmode = GET_MODE (XEXP (op, 0));
130638fd1498Szrj  enum rtx_code code = GET_CODE (op);
130738fd1498Szrj
130838fd1498Szrj  if (inmode == CCFPmode)
130938fd1498Szrj    {
131038fd1498Szrj      if (!ix86_trivial_fp_comparison_operator (op, mode))
131138fd1498Szrj	return false;
131238fd1498Szrj      code = ix86_fp_compare_code_to_integer (code);
131338fd1498Szrj    }
131438fd1498Szrj  /* i387 supports just limited amount of conditional codes.  */
131538fd1498Szrj  switch (code)
131638fd1498Szrj    {
131738fd1498Szrj    case LTU: case GTU: case LEU: case GEU:
131838fd1498Szrj      if (inmode == CCmode || inmode == CCFPmode || inmode == CCCmode)
131938fd1498Szrj	return true;
132038fd1498Szrj      return false;
132138fd1498Szrj    case ORDERED: case UNORDERED:
132238fd1498Szrj    case EQ: case NE:
132338fd1498Szrj      return true;
132438fd1498Szrj    default:
132538fd1498Szrj      return false;
132638fd1498Szrj    }
132738fd1498Szrj})
132838fd1498Szrj
132938fd1498Szrj;; Return true if OP is a comparison that can be used in the CMPSS/CMPPS insns.
133038fd1498Szrj;; The first set are supported directly; the second set can't be done with
133138fd1498Szrj;; full IEEE support, i.e. NaNs.
133238fd1498Szrj
133338fd1498Szrj(define_predicate "sse_comparison_operator"
133438fd1498Szrj  (ior (match_code "eq,ne,lt,le,unordered,unge,ungt,ordered")
133538fd1498Szrj       (and (match_test "TARGET_AVX")
133638fd1498Szrj	    (match_code "ge,gt,uneq,unle,unlt,ltgt"))))
133738fd1498Szrj
133838fd1498Szrj(define_predicate "ix86_comparison_int_operator"
133938fd1498Szrj  (match_code "ne,eq,ge,gt,le,lt"))
134038fd1498Szrj
134138fd1498Szrj(define_predicate "ix86_comparison_uns_operator"
134238fd1498Szrj  (match_code "ne,eq,geu,gtu,leu,ltu"))
134338fd1498Szrj
134438fd1498Szrj(define_predicate "bt_comparison_operator"
134538fd1498Szrj  (match_code "ne,eq"))
134638fd1498Szrj
134738fd1498Szrj;; Return true if OP is a valid comparison operator in valid mode.
134838fd1498Szrj(define_predicate "ix86_comparison_operator"
134938fd1498Szrj  (match_operand 0 "comparison_operator")
135038fd1498Szrj{
135138fd1498Szrj  machine_mode inmode = GET_MODE (XEXP (op, 0));
135238fd1498Szrj  enum rtx_code code = GET_CODE (op);
135338fd1498Szrj
135438fd1498Szrj  if (inmode == CCFPmode)
135538fd1498Szrj    return ix86_trivial_fp_comparison_operator (op, mode);
135638fd1498Szrj
135738fd1498Szrj  switch (code)
135838fd1498Szrj    {
135938fd1498Szrj    case EQ: case NE:
136038fd1498Szrj      if (inmode == CCGZmode)
136138fd1498Szrj	return false;
136238fd1498Szrj      return true;
136338fd1498Szrj    case GE: case LT:
136438fd1498Szrj      if (inmode == CCmode || inmode == CCGCmode
136538fd1498Szrj	  || inmode == CCGOCmode || inmode == CCNOmode || inmode == CCGZmode)
136638fd1498Szrj	return true;
136738fd1498Szrj      return false;
136838fd1498Szrj    case GEU: case LTU:
136938fd1498Szrj      if (inmode == CCGZmode)
137038fd1498Szrj	return true;
137138fd1498Szrj      /* FALLTHRU */
137238fd1498Szrj    case GTU: case LEU:
137338fd1498Szrj      if (inmode == CCmode || inmode == CCCmode || inmode == CCGZmode)
137438fd1498Szrj	return true;
137538fd1498Szrj      return false;
137638fd1498Szrj    case ORDERED: case UNORDERED:
137738fd1498Szrj      if (inmode == CCmode)
137838fd1498Szrj	return true;
137938fd1498Szrj      return false;
138038fd1498Szrj    case GT: case LE:
138138fd1498Szrj      if (inmode == CCmode || inmode == CCGCmode || inmode == CCNOmode)
138238fd1498Szrj	return true;
138338fd1498Szrj      return false;
138438fd1498Szrj    default:
138538fd1498Szrj      return false;
138638fd1498Szrj    }
138738fd1498Szrj})
138838fd1498Szrj
138938fd1498Szrj;; Return true if OP is a valid comparison operator
139038fd1498Szrj;; testing carry flag to be set.
139138fd1498Szrj(define_predicate "ix86_carry_flag_operator"
139238fd1498Szrj  (match_code "ltu,lt,unlt,gtu,gt,ungt,le,unle,ge,unge,ltgt,uneq")
139338fd1498Szrj{
139438fd1498Szrj  machine_mode inmode = GET_MODE (XEXP (op, 0));
139538fd1498Szrj  enum rtx_code code = GET_CODE (op);
139638fd1498Szrj
139738fd1498Szrj  if (inmode == CCFPmode)
139838fd1498Szrj    {
139938fd1498Szrj      if (!ix86_trivial_fp_comparison_operator (op, mode))
140038fd1498Szrj	return false;
140138fd1498Szrj      code = ix86_fp_compare_code_to_integer (code);
140238fd1498Szrj    }
140338fd1498Szrj  else if (inmode == CCCmode)
140438fd1498Szrj   return code == LTU || code == GTU;
140538fd1498Szrj  else if (inmode != CCmode)
140638fd1498Szrj    return false;
140738fd1498Szrj
140838fd1498Szrj  return code == LTU;
140938fd1498Szrj})
141038fd1498Szrj
141138fd1498Szrj;; Return true if this comparison only requires testing one flag bit.
141238fd1498Szrj(define_predicate "ix86_trivial_fp_comparison_operator"
141338fd1498Szrj  (match_code "gt,ge,unlt,unle,uneq,ltgt,ordered,unordered"))
141438fd1498Szrj
141538fd1498Szrj;; Return true if we know how to do this comparison.  Others require
141638fd1498Szrj;; testing more than one flag bit, and we let the generic middle-end
141738fd1498Szrj;; code do that.
141838fd1498Szrj(define_predicate "ix86_fp_comparison_operator"
141938fd1498Szrj  (if_then_else (match_test "ix86_fp_comparison_strategy (GET_CODE (op))
142038fd1498Szrj                             == IX86_FPCMP_ARITH")
142138fd1498Szrj               (match_operand 0 "comparison_operator")
142238fd1498Szrj               (match_operand 0 "ix86_trivial_fp_comparison_operator")))
142338fd1498Szrj
142438fd1498Szrj;; Nearly general operand, but accept any const_double, since we wish
142538fd1498Szrj;; to be able to drop them into memory rather than have them get pulled
142638fd1498Szrj;; into registers.
142738fd1498Szrj(define_predicate "cmp_fp_expander_operand"
142838fd1498Szrj  (ior (match_code "const_double")
142938fd1498Szrj       (match_operand 0 "general_operand")))
143038fd1498Szrj
143138fd1498Szrj;; Return true if this is a valid binary floating-point operation.
143238fd1498Szrj(define_predicate "binary_fp_operator"
143338fd1498Szrj  (match_code "plus,minus,mult,div"))
143438fd1498Szrj
143538fd1498Szrj;; Return true if this is a multiply operation.
143638fd1498Szrj(define_predicate "mult_operator"
143738fd1498Szrj  (match_code "mult"))
143838fd1498Szrj
143938fd1498Szrj;; Return true if this is a division operation.
144038fd1498Szrj(define_predicate "div_operator"
144138fd1498Szrj  (match_code "div"))
144238fd1498Szrj
144338fd1498Szrj;; Return true if this is a plus, minus, and, ior or xor operation.
144438fd1498Szrj(define_predicate "plusminuslogic_operator"
144538fd1498Szrj  (match_code "plus,minus,and,ior,xor"))
144638fd1498Szrj
144738fd1498Szrj;; Return true for ARITHMETIC_P.
144838fd1498Szrj(define_predicate "arith_or_logical_operator"
144938fd1498Szrj  (match_code "plus,mult,and,ior,xor,smin,smax,umin,umax,compare,minus,div,
145038fd1498Szrj	       mod,udiv,umod,ashift,rotate,ashiftrt,lshiftrt,rotatert"))
145138fd1498Szrj
145238fd1498Szrj;; Return true for COMMUTATIVE_P.
145338fd1498Szrj(define_predicate "commutative_operator"
145438fd1498Szrj  (match_code "plus,mult,and,ior,xor,smin,smax,umin,umax"))
145538fd1498Szrj
145638fd1498Szrj;; Return true if OP is a binary operator that can be promoted to wider mode.
145738fd1498Szrj(define_predicate "promotable_binary_operator"
145838fd1498Szrj  (ior (match_code "plus,minus,and,ior,xor,ashift")
145938fd1498Szrj       (and (match_code "mult")
146038fd1498Szrj	    (match_test "TARGET_TUNE_PROMOTE_HIMODE_IMUL"))))
146138fd1498Szrj
146238fd1498Szrj(define_predicate "compare_operator"
146338fd1498Szrj  (match_code "compare"))
146438fd1498Szrj
146538fd1498Szrj(define_predicate "absneg_operator"
146638fd1498Szrj  (match_code "abs,neg"))
146738fd1498Szrj
146838fd1498Szrj;; Return true if OP is a memory operand, aligned to
146938fd1498Szrj;; less than its natural alignment.
147038fd1498Szrj(define_predicate "misaligned_operand"
147138fd1498Szrj  (and (match_code "mem")
147238fd1498Szrj       (match_test "MEM_ALIGN (op) < GET_MODE_BITSIZE (mode)")))
147338fd1498Szrj
147438fd1498Szrj;; Return true if OP is a emms operation, known to be a PARALLEL.
147538fd1498Szrj(define_predicate "emms_operation"
147638fd1498Szrj  (match_code "parallel")
147738fd1498Szrj{
147838fd1498Szrj  unsigned i;
147938fd1498Szrj
148038fd1498Szrj  if (XVECLEN (op, 0) != 17)
148138fd1498Szrj    return false;
148238fd1498Szrj
148338fd1498Szrj  for (i = 0; i < 8; i++)
148438fd1498Szrj    {
148538fd1498Szrj      rtx elt = XVECEXP (op, 0, i+1);
148638fd1498Szrj
148738fd1498Szrj      if (GET_CODE (elt) != CLOBBER
148838fd1498Szrj	  || GET_CODE (SET_DEST (elt)) != REG
148938fd1498Szrj	  || GET_MODE (SET_DEST (elt)) != XFmode
149038fd1498Szrj	  || REGNO (SET_DEST (elt)) != FIRST_STACK_REG + i)
149138fd1498Szrj        return false;
149238fd1498Szrj
149338fd1498Szrj      elt = XVECEXP (op, 0, i+9);
149438fd1498Szrj
149538fd1498Szrj      if (GET_CODE (elt) != CLOBBER
149638fd1498Szrj	  || GET_CODE (SET_DEST (elt)) != REG
149738fd1498Szrj	  || GET_MODE (SET_DEST (elt)) != DImode
149838fd1498Szrj	  || REGNO (SET_DEST (elt)) != FIRST_MMX_REG + i)
149938fd1498Szrj	return false;
150038fd1498Szrj    }
150138fd1498Szrj  return true;
150238fd1498Szrj})
150338fd1498Szrj
150438fd1498Szrj;; Return true if OP is a vzeroall operation, known to be a PARALLEL.
150538fd1498Szrj(define_predicate "vzeroall_operation"
150638fd1498Szrj  (match_code "parallel")
150738fd1498Szrj{
150838fd1498Szrj  unsigned i, nregs = TARGET_64BIT ? 16 : 8;
150938fd1498Szrj
151038fd1498Szrj  if ((unsigned) XVECLEN (op, 0) != 1 + nregs)
151138fd1498Szrj    return false;
151238fd1498Szrj
151338fd1498Szrj  for (i = 0; i < nregs; i++)
151438fd1498Szrj    {
151538fd1498Szrj      rtx elt = XVECEXP (op, 0, i+1);
151638fd1498Szrj
151738fd1498Szrj      if (GET_CODE (elt) != SET
151838fd1498Szrj	  || GET_CODE (SET_DEST (elt)) != REG
151938fd1498Szrj	  || GET_MODE (SET_DEST (elt)) != V8SImode
1520*58e805e6Szrj	  || REGNO (SET_DEST (elt)) != GET_SSE_REGNO (i)
152138fd1498Szrj	  || SET_SRC (elt) != CONST0_RTX (V8SImode))
152238fd1498Szrj	return false;
152338fd1498Szrj    }
152438fd1498Szrj  return true;
152538fd1498Szrj})
152638fd1498Szrj
152738fd1498Szrj;; return true if OP is a vzeroupper operation.
152838fd1498Szrj(define_predicate "vzeroupper_operation"
152938fd1498Szrj  (and (match_code "unspec_volatile")
153038fd1498Szrj       (match_test "XINT (op, 1) == UNSPECV_VZEROUPPER")))
153138fd1498Szrj
153238fd1498Szrj;; Return true if OP is an addsub vec_merge operation
153338fd1498Szrj(define_predicate "addsub_vm_operator"
153438fd1498Szrj  (match_code "vec_merge")
153538fd1498Szrj{
153638fd1498Szrj  rtx op0, op1;
153738fd1498Szrj  int swapped;
153838fd1498Szrj  HOST_WIDE_INT mask;
153938fd1498Szrj  int nunits, elt;
154038fd1498Szrj
154138fd1498Szrj  op0 = XEXP (op, 0);
154238fd1498Szrj  op1 = XEXP (op, 1);
154338fd1498Szrj
154438fd1498Szrj  /* Sanity check.  */
154538fd1498Szrj  if (GET_CODE (op0) == MINUS && GET_CODE (op1) == PLUS)
154638fd1498Szrj    swapped = 0;
154738fd1498Szrj  else if (GET_CODE (op0) == PLUS && GET_CODE (op1) == MINUS)
154838fd1498Szrj    swapped = 1;
154938fd1498Szrj  else
155038fd1498Szrj    gcc_unreachable ();
155138fd1498Szrj
155238fd1498Szrj  mask = INTVAL (XEXP (op, 2));
155338fd1498Szrj  nunits = GET_MODE_NUNITS (mode);
155438fd1498Szrj
155538fd1498Szrj  for (elt = 0; elt < nunits; elt++)
155638fd1498Szrj    {
155738fd1498Szrj      /* bit clear: take from op0, set: take from op1  */
155838fd1498Szrj      int bit = !(mask & (HOST_WIDE_INT_1U << elt));
155938fd1498Szrj
156038fd1498Szrj      if (bit != ((elt & 1) ^ swapped))
156138fd1498Szrj	return false;
156238fd1498Szrj    }
156338fd1498Szrj
156438fd1498Szrj  return true;
156538fd1498Szrj})
156638fd1498Szrj
156738fd1498Szrj;; Return true if OP is an addsub vec_select/vec_concat operation
156838fd1498Szrj(define_predicate "addsub_vs_operator"
156938fd1498Szrj  (and (match_code "vec_select")
157038fd1498Szrj       (match_code "vec_concat" "0"))
157138fd1498Szrj{
157238fd1498Szrj  rtx op0, op1;
157338fd1498Szrj  bool swapped;
157438fd1498Szrj  int nunits, elt;
157538fd1498Szrj
157638fd1498Szrj  op0 = XEXP (XEXP (op, 0), 0);
157738fd1498Szrj  op1 = XEXP (XEXP (op, 0), 1);
157838fd1498Szrj
157938fd1498Szrj  /* Sanity check.  */
158038fd1498Szrj  if (GET_CODE (op0) == MINUS && GET_CODE (op1) == PLUS)
158138fd1498Szrj    swapped = false;
158238fd1498Szrj  else if (GET_CODE (op0) == PLUS && GET_CODE (op1) == MINUS)
158338fd1498Szrj    swapped = true;
158438fd1498Szrj  else
158538fd1498Szrj    gcc_unreachable ();
158638fd1498Szrj
158738fd1498Szrj  nunits = GET_MODE_NUNITS (mode);
158838fd1498Szrj  if (XVECLEN (XEXP (op, 1), 0) != nunits)
158938fd1498Szrj    return false;
159038fd1498Szrj
159138fd1498Szrj  /* We already checked that permutation is suitable for addsub,
159238fd1498Szrj     so only look at the first element of the parallel.  */
159338fd1498Szrj  elt = INTVAL (XVECEXP (XEXP (op, 1), 0, 0));
159438fd1498Szrj
159538fd1498Szrj  return elt == (swapped ? nunits : 0);
159638fd1498Szrj})
159738fd1498Szrj
159838fd1498Szrj;; Return true if OP is a parallel for an addsub vec_select.
159938fd1498Szrj(define_predicate "addsub_vs_parallel"
160038fd1498Szrj  (and (match_code "parallel")
160138fd1498Szrj       (match_code "const_int" "a"))
160238fd1498Szrj{
160338fd1498Szrj  int nelt = XVECLEN (op, 0);
160438fd1498Szrj  int elt, i;
160538fd1498Szrj
160638fd1498Szrj  if (nelt < 2)
160738fd1498Szrj    return false;
160838fd1498Szrj
160938fd1498Szrj  /* Check that the permutation is suitable for addsub.
161038fd1498Szrj     For example, { 0 9 2 11 4 13 6 15 } or { 8 1 10 3 12 5 14 7 }.  */
161138fd1498Szrj  elt = INTVAL (XVECEXP (op, 0, 0));
161238fd1498Szrj  if (elt == 0)
161338fd1498Szrj    {
161438fd1498Szrj      for (i = 1; i < nelt; ++i)
161538fd1498Szrj	if (INTVAL (XVECEXP (op, 0, i)) != (i + (i & 1) * nelt))
161638fd1498Szrj	  return false;
161738fd1498Szrj    }
161838fd1498Szrj  else if (elt == nelt)
161938fd1498Szrj    {
162038fd1498Szrj      for (i = 1; i < nelt; ++i)
162138fd1498Szrj	if (INTVAL (XVECEXP (op, 0, i)) != (elt + i - (i & 1) * nelt))
162238fd1498Szrj	  return false;
162338fd1498Szrj    }
162438fd1498Szrj  else
162538fd1498Szrj    return false;
162638fd1498Szrj
162738fd1498Szrj  return true;
162838fd1498Szrj})
162938fd1498Szrj
163038fd1498Szrj;; Return true if OP is a parallel for a vbroadcast permute.
163138fd1498Szrj(define_predicate "avx_vbroadcast_operand"
163238fd1498Szrj  (and (match_code "parallel")
163338fd1498Szrj       (match_code "const_int" "a"))
163438fd1498Szrj{
163538fd1498Szrj  rtx elt = XVECEXP (op, 0, 0);
163638fd1498Szrj  int i, nelt = XVECLEN (op, 0);
163738fd1498Szrj
163838fd1498Szrj  /* Don't bother checking there are the right number of operands,
163938fd1498Szrj     merely that they're all identical.  */
164038fd1498Szrj  for (i = 1; i < nelt; ++i)
164138fd1498Szrj    if (XVECEXP (op, 0, i) != elt)
164238fd1498Szrj      return false;
164338fd1498Szrj  return true;
164438fd1498Szrj})
164538fd1498Szrj
164638fd1498Szrj;; Return true if OP is a parallel for a palignr permute.
164738fd1498Szrj(define_predicate "palignr_operand"
164838fd1498Szrj  (and (match_code "parallel")
164938fd1498Szrj       (match_code "const_int" "a"))
165038fd1498Szrj{
165138fd1498Szrj  int elt = INTVAL (XVECEXP (op, 0, 0));
165238fd1498Szrj  int i, nelt = XVECLEN (op, 0);
165338fd1498Szrj
165438fd1498Szrj  /* Check that an order in the permutation is suitable for palignr.
165538fd1498Szrj     For example, {5 6 7 0 1 2 3 4} is "palignr 5, xmm, xmm".  */
165638fd1498Szrj  for (i = 1; i < nelt; ++i)
165738fd1498Szrj    if (INTVAL (XVECEXP (op, 0, i)) != ((elt + i) % nelt))
165838fd1498Szrj      return false;
165938fd1498Szrj  return true;
166038fd1498Szrj})
166138fd1498Szrj
166238fd1498Szrj;; Return true if OP is a proper third operand to vpblendw256.
166338fd1498Szrj(define_predicate "avx2_pblendw_operand"
166438fd1498Szrj  (match_code "const_int")
166538fd1498Szrj{
166638fd1498Szrj  HOST_WIDE_INT val = INTVAL (op);
166738fd1498Szrj  HOST_WIDE_INT low = val & 0xff;
166838fd1498Szrj  return val == ((low << 8) | low);
166938fd1498Szrj})
167038fd1498Szrj
167138fd1498Szrj;; Return true if OP is vector_operand or CONST_VECTOR.
167238fd1498Szrj(define_predicate "general_vector_operand"
167338fd1498Szrj  (ior (match_operand 0 "vector_operand")
167438fd1498Szrj       (match_code "const_vector")))
167538fd1498Szrj
167638fd1498Szrj;; Return true if OP is either -1 constant or stored in register.
167738fd1498Szrj(define_predicate "register_or_constm1_operand"
167838fd1498Szrj  (ior (match_operand 0 "register_operand")
167938fd1498Szrj       (and (match_code "const_int")
168038fd1498Szrj	    (match_test "op == constm1_rtx"))))
168138fd1498Szrj
168238fd1498Szrj;; Return true if the vector ends with between 12 and 18 register saves using
168338fd1498Szrj;; RAX as the base address.
168438fd1498Szrj(define_predicate "save_multiple"
168538fd1498Szrj  (match_code "parallel")
168638fd1498Szrj{
168738fd1498Szrj  const unsigned len = XVECLEN (op, 0);
168838fd1498Szrj  unsigned i;
168938fd1498Szrj
169038fd1498Szrj  /* Starting from end of vector, count register saves.  */
169138fd1498Szrj  for (i = 0; i < len; ++i)
169238fd1498Szrj    {
169338fd1498Szrj      rtx src, dest, addr;
169438fd1498Szrj      rtx e = XVECEXP (op, 0, len - 1 - i);
169538fd1498Szrj
169638fd1498Szrj      if (GET_CODE (e) != SET)
169738fd1498Szrj	break;
169838fd1498Szrj
169938fd1498Szrj      src  = SET_SRC (e);
170038fd1498Szrj      dest = SET_DEST (e);
170138fd1498Szrj
170238fd1498Szrj      if (!REG_P (src) || !MEM_P (dest))
170338fd1498Szrj	break;
170438fd1498Szrj
170538fd1498Szrj      addr = XEXP (dest, 0);
170638fd1498Szrj
170738fd1498Szrj      /* Good if dest address is in RAX.  */
170838fd1498Szrj      if (REG_P (addr) && REGNO (addr) == AX_REG)
170938fd1498Szrj	continue;
171038fd1498Szrj
171138fd1498Szrj      /* Good if dest address is offset of RAX.  */
171238fd1498Szrj      if (GET_CODE (addr) == PLUS
171338fd1498Szrj	  && REG_P (XEXP (addr, 0))
171438fd1498Szrj	  && REGNO (XEXP (addr, 0)) == AX_REG)
171538fd1498Szrj	continue;
171638fd1498Szrj
171738fd1498Szrj      break;
171838fd1498Szrj    }
171938fd1498Szrj  return (i >= 12 && i <= 18);
172038fd1498Szrj})
172138fd1498Szrj
172238fd1498Szrj
172338fd1498Szrj;; Return true if the vector ends with between 12 and 18 register loads using
172438fd1498Szrj;; RSI as the base address.
172538fd1498Szrj(define_predicate "restore_multiple"
172638fd1498Szrj  (match_code "parallel")
172738fd1498Szrj{
172838fd1498Szrj  const unsigned len = XVECLEN (op, 0);
172938fd1498Szrj  unsigned i;
173038fd1498Szrj
173138fd1498Szrj  /* Starting from end of vector, count register restores.  */
173238fd1498Szrj  for (i = 0; i < len; ++i)
173338fd1498Szrj    {
173438fd1498Szrj      rtx src, dest, addr;
173538fd1498Szrj      rtx e = XVECEXP (op, 0, len - 1 - i);
173638fd1498Szrj
173738fd1498Szrj      if (GET_CODE (e) != SET)
173838fd1498Szrj	break;
173938fd1498Szrj
174038fd1498Szrj      src  = SET_SRC (e);
174138fd1498Szrj      dest = SET_DEST (e);
174238fd1498Szrj
174338fd1498Szrj      if (!MEM_P (src) || !REG_P (dest))
174438fd1498Szrj	break;
174538fd1498Szrj
174638fd1498Szrj      addr = XEXP (src, 0);
174738fd1498Szrj
174838fd1498Szrj      /* Good if src address is in RSI.  */
174938fd1498Szrj      if (REG_P (addr) && REGNO (addr) == SI_REG)
175038fd1498Szrj	continue;
175138fd1498Szrj
175238fd1498Szrj      /* Good if src address is offset of RSI.  */
175338fd1498Szrj      if (GET_CODE (addr) == PLUS
175438fd1498Szrj	  && REG_P (XEXP (addr, 0))
175538fd1498Szrj	  && REGNO (XEXP (addr, 0)) == SI_REG)
175638fd1498Szrj	continue;
175738fd1498Szrj
175838fd1498Szrj      break;
175938fd1498Szrj    }
176038fd1498Szrj  return (i >= 12 && i <= 18);
176138fd1498Szrj})
1762