110d565efSmrg;; Predicate definitions for code generation on the EPIPHANY cpu.
2*ec02198aSmrg;; Copyright (C) 1994-2020 Free Software Foundation, Inc.
310d565efSmrg;; Contributed by Embecosm on behalf of Adapteva, Inc.
410d565efSmrg;;
510d565efSmrg;; This file is part of GCC.
610d565efSmrg
710d565efSmrg;; GCC is free software; you can redistribute it and/or modify
810d565efSmrg;; it under the terms of the GNU General Public License as published by
910d565efSmrg;; the Free Software Foundation; either version 3, or (at your option)
1010d565efSmrg;; any later version.
1110d565efSmrg
1210d565efSmrg;; GCC is distributed in the hope that it will be useful,
1310d565efSmrg;; but WITHOUT ANY WARRANTY; without even the implied warranty of
1410d565efSmrg;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1510d565efSmrg;; GNU General Public License for more details.
1610d565efSmrg
1710d565efSmrg;; You should have received a copy of the GNU General Public License
1810d565efSmrg;; along with GCC; see the file COPYING3.  If not see
1910d565efSmrg;; <http://www.gnu.org/licenses/>.
2010d565efSmrg
2110d565efSmrg;; Returns true iff OP is a symbol reference that is a valid operand
2210d565efSmrg;; in a jump or call instruction.
2310d565efSmrg
2410d565efSmrg(define_predicate "symbolic_operand"
2510d565efSmrg  (match_code "symbol_ref,label_ref,const")
2610d565efSmrg{
2710d565efSmrg  if (GET_CODE (op) == SYMBOL_REF)
2810d565efSmrg    return (!epiphany_is_long_call_p (op)
2910d565efSmrg	    && (!flag_pic || SYMBOL_REF_LOCAL_P (op)));
3010d565efSmrg  if (GET_CODE (op) == LABEL_REF)
3110d565efSmrg    return true;
3210d565efSmrg  if (GET_CODE (op) == CONST)
3310d565efSmrg    {
3410d565efSmrg      op = XEXP (op, 0);
3510d565efSmrg      if (GET_CODE (op) != PLUS || !symbolic_operand (XEXP (op, 0), mode))
3610d565efSmrg	return false;
3710d565efSmrg      /* The idea here is that a 'small' constant offset should be OK.
3810d565efSmrg	 What exactly is considered 'small' is a bit arbitrary.  */
3910d565efSmrg      return satisfies_constraint_L (XEXP (op, 1));
4010d565efSmrg    }
4110d565efSmrg  gcc_unreachable ();
4210d565efSmrg})
4310d565efSmrg
4410d565efSmrg;; Acceptable arguments to the call insn.
4510d565efSmrg
4610d565efSmrg(define_predicate "call_address_operand"
4710d565efSmrg  (ior (match_code "reg")
4810d565efSmrg       (match_operand 0 "symbolic_operand")))
4910d565efSmrg
5010d565efSmrg(define_predicate "call_operand"
5110d565efSmrg  (match_code "mem")
5210d565efSmrg{
5310d565efSmrg  op = XEXP (op, 0);
5410d565efSmrg  return call_address_operand (op, mode);
5510d565efSmrg})
5610d565efSmrg
5710d565efSmrg;; general purpose register.
5810d565efSmrg(define_predicate "gpr_operand"
5910d565efSmrg  (match_code "reg,subreg")
6010d565efSmrg{
6110d565efSmrg  int regno;
6210d565efSmrg
6310d565efSmrg  if (!register_operand (op, mode))
6410d565efSmrg    return 0;
6510d565efSmrg  if (GET_CODE (op) == SUBREG)
6610d565efSmrg    op = XEXP (op, 0);
6710d565efSmrg  regno = REGNO (op);
6810d565efSmrg  return regno >= FIRST_PSEUDO_REGISTER || regno <= 63;
6910d565efSmrg})
7010d565efSmrg
7110d565efSmrg(define_special_predicate "any_gpr_operand"
7210d565efSmrg  (match_code "subreg,reg")
7310d565efSmrg{
7410d565efSmrg  return gpr_operand (op, mode);
7510d565efSmrg})
7610d565efSmrg
7710d565efSmrg;; register suitable for integer add / sub operations; besides general purpose
7810d565efSmrg;; registers we allow fake hard registers that are eliminated to a real
7910d565efSmrg;; hard register via an offset.
8010d565efSmrg(define_predicate "add_reg_operand"
8110d565efSmrg  (match_code "reg,subreg")
8210d565efSmrg{
8310d565efSmrg  int regno;
8410d565efSmrg
8510d565efSmrg  if (!register_operand (op, mode))
8610d565efSmrg    return 0;
8710d565efSmrg  if (GET_CODE (op) == SUBREG)
8810d565efSmrg    op = XEXP (op, 0);
8910d565efSmrg  regno = REGNO (op);
9010d565efSmrg  return (regno >= FIRST_PSEUDO_REGISTER || regno <= 63
9110d565efSmrg	  || regno == FRAME_POINTER_REGNUM
9210d565efSmrg	  || regno == ARG_POINTER_REGNUM);
9310d565efSmrg})
9410d565efSmrg
9510d565efSmrg;; Also allows suitable constants
9610d565efSmrg(define_predicate "add_operand"
9710d565efSmrg  (match_code "reg,subreg,const_int,symbol_ref,label_ref,const")
9810d565efSmrg{
9910d565efSmrg  if (GET_CODE (op) == REG || GET_CODE (op) == SUBREG)
10010d565efSmrg    return add_reg_operand (op, mode);
10110d565efSmrg  return satisfies_constraint_L (op) || satisfies_constraint_CnL (op);
10210d565efSmrg})
10310d565efSmrg
10410d565efSmrg;; Ordinary 3rd operand for arithmetic operations
10510d565efSmrg(define_predicate "arith_operand"
10610d565efSmrg  (match_code "reg,subreg,const_int,symbol_ref,label_ref,const")
10710d565efSmrg{
10810d565efSmrg  if (GET_CODE (op) == REG || GET_CODE (op) == SUBREG)
10910d565efSmrg    return register_operand (op, mode);
11010d565efSmrg  return satisfies_constraint_L (op);
11110d565efSmrg})
11210d565efSmrg
11310d565efSmrg;; Constant integer 3rd operand for arithmetic operations
11410d565efSmrg(define_predicate "arith_int_operand"
11510d565efSmrg  (match_code "const_int,symbol_ref,label_ref,const")
11610d565efSmrg{
11710d565efSmrg  return satisfies_constraint_L (op);
11810d565efSmrg})
11910d565efSmrg
12010d565efSmrg;; Return true if OP is an acceptable argument for a single word move source.
12110d565efSmrg
12210d565efSmrg(define_predicate "move_src_operand"
12310d565efSmrg  (match_code
12410d565efSmrg   "symbol_ref,label_ref,const,const_int,const_double,reg,subreg,mem,unspec")
12510d565efSmrg{
12610d565efSmrg  switch (GET_CODE (op))
12710d565efSmrg    {
12810d565efSmrg    case SYMBOL_REF :
12910d565efSmrg    case LABEL_REF :
13010d565efSmrg    case CONST :
13110d565efSmrg      return 1;
13210d565efSmrg    case CONST_INT :
13310d565efSmrg      return immediate_operand (op, mode);
13410d565efSmrg    case CONST_DOUBLE :
13510d565efSmrg      /* SImode constants should always fit into a CONST_INT.  Large
13610d565efSmrg	 unsigned 32-bit constants are represented as negative CONST_INTs.  */
13710d565efSmrg      gcc_assert (GET_MODE (op) != SImode);
13810d565efSmrg      /* We can handle 32-bit floating point constants.  */
13910d565efSmrg      if (mode == SFmode)
14010d565efSmrg	return GET_MODE (op) == SFmode;
14110d565efSmrg      return 0;
14210d565efSmrg    case REG :
14310d565efSmrg      return op != frame_pointer_rtx && register_operand (op, mode);
14410d565efSmrg    case SUBREG :
14510d565efSmrg      /* (subreg (mem ...) ...) can occur here if the inner part was once a
14610d565efSmrg	 pseudo-reg and is now a stack slot.  */
14710d565efSmrg      if (GET_CODE (SUBREG_REG (op)) == MEM)
14810d565efSmrg	return address_operand (XEXP (SUBREG_REG (op), 0), mode);
14910d565efSmrg      else
15010d565efSmrg	return register_operand (op, mode);
15110d565efSmrg    case MEM :
15210d565efSmrg      return address_operand (XEXP (op, 0), mode);
15310d565efSmrg    case UNSPEC:
15410d565efSmrg      return satisfies_constraint_Sra (op);
15510d565efSmrg    default :
15610d565efSmrg      return 0;
15710d565efSmrg    }
15810d565efSmrg})
15910d565efSmrg
16010d565efSmrg;; Return true if OP is an acceptable argument for a double word move source.
16110d565efSmrg
16210d565efSmrg(define_predicate "move_double_src_operand"
16310d565efSmrg  (match_code "reg,subreg,mem,const_int,const_double,const_vector")
16410d565efSmrg{
16510d565efSmrg  if (GET_CODE (op) == MEM && misaligned_operand (op, mode)
16610d565efSmrg      && !address_operand (plus_constant (Pmode, XEXP (op, 0), 4), SImode))
16710d565efSmrg    return 0;
16810d565efSmrg  return general_operand (op, mode);
16910d565efSmrg})
17010d565efSmrg
17110d565efSmrg;; Return true if OP is an acceptable argument for a move destination.
17210d565efSmrg
17310d565efSmrg(define_predicate "move_dest_operand"
17410d565efSmrg  (match_code "reg,subreg,mem")
17510d565efSmrg{
17610d565efSmrg  switch (GET_CODE (op))
17710d565efSmrg    {
17810d565efSmrg    case REG :
17910d565efSmrg      return register_operand (op, mode);
18010d565efSmrg    case SUBREG :
18110d565efSmrg      /* (subreg (mem ...) ...) can occur here if the inner part was once a
18210d565efSmrg	 pseudo-reg and is now a stack slot.  */
18310d565efSmrg      if (GET_CODE (SUBREG_REG (op)) == MEM)
18410d565efSmrg	{
18510d565efSmrg	  return address_operand (XEXP (SUBREG_REG (op), 0), mode);
18610d565efSmrg	}
18710d565efSmrg      else
18810d565efSmrg	{
18910d565efSmrg	  return register_operand (op, mode);
19010d565efSmrg	}
19110d565efSmrg    case MEM :
19210d565efSmrg      if (GET_MODE_SIZE (mode) == 8 && misaligned_operand (op, mode)
19310d565efSmrg	  && !address_operand (plus_constant (Pmode, XEXP (op, 0), 4), SImode))
19410d565efSmrg	return 0;
19510d565efSmrg      return address_operand (XEXP (op, 0), mode);
19610d565efSmrg    default :
19710d565efSmrg      return 0;
19810d565efSmrg    }
19910d565efSmrg})
20010d565efSmrg
20110d565efSmrg(define_special_predicate "stacktop_operand"
20210d565efSmrg  (match_code "mem")
20310d565efSmrg{
20410d565efSmrg  if (mode != VOIDmode && GET_MODE (op) != mode)
20510d565efSmrg    return false;
20610d565efSmrg  return rtx_equal_p (XEXP (op, 0), stack_pointer_rtx);
20710d565efSmrg})
20810d565efSmrg
20910d565efSmrg;; Return 1 if OP is a comparison operator valid for the mode of CC.
21010d565efSmrg;; This allows the use of MATCH_OPERATOR to recognize all the branch insns.
21110d565efSmrg;;
21210d565efSmrg;; Some insns only set a few bits in the condition code.  So only allow those
21310d565efSmrg;; comparisons that use the bits that are valid.
21410d565efSmrg
21510d565efSmrg(define_predicate "proper_comparison_operator"
21610d565efSmrg  (match_code "eq, ne, le, lt, ge, gt, leu, ltu, geu, gtu, unordered, ordered, uneq, unge, ungt, unle, unlt, ltgt")
21710d565efSmrg{
21810d565efSmrg  enum rtx_code code = GET_CODE (op);
21910d565efSmrg  rtx cc = XEXP (op, 0);
22010d565efSmrg
22110d565efSmrg  /* combine can try strange things.  */
22210d565efSmrg  if (!REG_P (cc))
22310d565efSmrg    return 0;
22410d565efSmrg  switch (GET_MODE (cc))
22510d565efSmrg    {
226c7a68eb7Smrg    case E_CC_Zmode:
227c7a68eb7Smrg    case E_CC_N_NEmode:
228c7a68eb7Smrg    case E_CC_FP_EQmode:
22910d565efSmrg      return REGNO (cc) == CC_REGNUM && (code == EQ || code == NE);
230c7a68eb7Smrg    case E_CC_C_LTUmode:
23110d565efSmrg      return REGNO (cc) == CC_REGNUM && (code == LTU || code == GEU);
232c7a68eb7Smrg    case E_CC_C_GTUmode:
23310d565efSmrg      return REGNO (cc) == CC_REGNUM && (code == GTU || code == LEU);
234c7a68eb7Smrg    case E_CC_FPmode:
23510d565efSmrg      return (REGNO (cc) == CCFP_REGNUM
23610d565efSmrg	      && (code == EQ || code == NE || code == LT || code == LE));
237c7a68eb7Smrg    case E_CC_FP_GTEmode:
23810d565efSmrg      return (REGNO (cc) == CC_REGNUM
23910d565efSmrg	      && (code == EQ || code == NE || code == GT || code == GE
24010d565efSmrg		  || code == UNLE || code == UNLT));
241c7a68eb7Smrg    case E_CC_FP_ORDmode:
24210d565efSmrg      return REGNO (cc) == CC_REGNUM && (code == ORDERED || code == UNORDERED);
243c7a68eb7Smrg    case E_CC_FP_UNEQmode:
24410d565efSmrg      return REGNO (cc) == CC_REGNUM && (code == UNEQ || code == LTGT);
245c7a68eb7Smrg    case E_CCmode:
24610d565efSmrg      return REGNO (cc) == CC_REGNUM;
24710d565efSmrg    /* From combiner.  */
248c7a68eb7Smrg    case E_QImode: case E_SImode: case E_SFmode: case E_HImode:
24910d565efSmrg    /* From cse.c:dead_libcall_p.  */
250c7a68eb7Smrg    case E_DFmode:
25110d565efSmrg      return 0;
25210d565efSmrg    default:
25310d565efSmrg      gcc_unreachable ();
25410d565efSmrg    }
25510d565efSmrg})
25610d565efSmrg
25710d565efSmrg(define_predicate "addsub_operator"
25810d565efSmrg  (match_code "plus, minus"))
25910d565efSmrg
26010d565efSmrg(define_predicate "cc_operand"
26110d565efSmrg  (and (match_code "reg")
26210d565efSmrg       (match_test "REGNO (op) == CC_REGNUM || REGNO (op) == CCFP_REGNUM")))
26310d565efSmrg
26410d565efSmrg(define_predicate "const0_operand"
26510d565efSmrg  (match_code "const_int, const_double")
26610d565efSmrg{
26710d565efSmrg  if (mode == VOIDmode)
26810d565efSmrg    mode = GET_MODE (op);
26910d565efSmrg  return op == CONST0_RTX (mode);
27010d565efSmrg})
27110d565efSmrg
27210d565efSmrg(define_predicate "const_float_1_operand"
27310d565efSmrg  (match_code "const_double")
27410d565efSmrg{
27510d565efSmrg  return op == CONST1_RTX (mode);
27610d565efSmrg})
27710d565efSmrg
27810d565efSmrg(define_predicate "cc_move_operand"
27910d565efSmrg  (and (match_code "reg")
28010d565efSmrg       (ior (match_test "REGNO (op) == CC_REGNUM")
28110d565efSmrg	    (match_test "gpr_operand (op, mode)"))))
28210d565efSmrg
28310d565efSmrg(define_predicate "float_operation"
28410d565efSmrg  (match_code "parallel")
28510d565efSmrg{
28610d565efSmrg  /* Most patterns start out with one SET and one CLOBBER, and gain a USE
28710d565efSmrg     or two of FP_NEAREST_REGNUM / FP_TRUNCATE_REGNUM / FP_ANYFP_REGNUM
28810d565efSmrg     after mode switching.  The longer patterns are
28910d565efSmrg     all beyond length 4, and before mode switching, end with a
29010d565efSmrg     CLOBBER of CCFP_REGNUM.  */
29110d565efSmrg  int count = XVECLEN (op, 0);
29210d565efSmrg  bool inserted = MACHINE_FUNCTION (cfun)->control_use_inserted;
29310d565efSmrg  int i;
29410d565efSmrg
29510d565efSmrg  if (count == 2
29610d565efSmrg      /* Vector ashift has an extra use for the constant factor required to
29710d565efSmrg	 implement the shift as multiply.  */
29810d565efSmrg      || (count == 3 && GET_CODE (XVECEXP (op, 0, 0)) == SET
29910d565efSmrg	  && GET_CODE (XEXP (XVECEXP (op, 0, 0), 1)) == ASHIFT))
30010d565efSmrg    return !inserted;
30110d565efSmrg
30210d565efSmrg  /* combine / recog will pass any old garbage here before checking the
30310d565efSmrg     rest of the insn.  */
30410d565efSmrg  if (count <= 3)
30510d565efSmrg    return false;
30610d565efSmrg
30710d565efSmrg  i = 1;
30810d565efSmrg  if (count > 4)
30910d565efSmrg    for (i = 2; i < count; i++)
31010d565efSmrg      {
31110d565efSmrg	rtx x = XVECEXP (op, 0, i);
31210d565efSmrg
31310d565efSmrg	if (GET_CODE (x) == CLOBBER)
31410d565efSmrg	  {
31510d565efSmrg	    if (!REG_P (XEXP (x, 0)))
31610d565efSmrg	      return false;
31710d565efSmrg	    if (REGNO (XEXP (x, 0)) == CCFP_REGNUM)
31810d565efSmrg	      {
31910d565efSmrg		if (count == i + 1)
32010d565efSmrg		  return !inserted;
32110d565efSmrg		break;
32210d565efSmrg	    }
32310d565efSmrg	  /* Just an ordinary clobber, keep looking.  */
32410d565efSmrg	}
32510d565efSmrg      else if (GET_CODE (x) == USE
32610d565efSmrg	       || (GET_CODE (x) == SET && i == 2))
32710d565efSmrg	continue;
32810d565efSmrg      else
32910d565efSmrg	return false;
33010d565efSmrg    }
33110d565efSmrg  if (count != i + 3 || !inserted)
33210d565efSmrg    return false;
33310d565efSmrg  for (i = i+1; i < count; i++)
33410d565efSmrg    {
33510d565efSmrg      rtx x = XVECEXP (op, 0, i);
33610d565efSmrg
33710d565efSmrg      if (GET_CODE (x) != USE && GET_CODE (x) != CLOBBER)
33810d565efSmrg	return false;
33910d565efSmrg      x = XEXP (x, 0);
34010d565efSmrg      if (!REG_P (x)
34110d565efSmrg	  || (REGNO (x) != FP_NEAREST_REGNUM
34210d565efSmrg	      && REGNO (x) != FP_TRUNCATE_REGNUM
34310d565efSmrg	      && REGNO (x) != FP_ANYFP_REGNUM))
34410d565efSmrg	return false;
34510d565efSmrg    }
34610d565efSmrg  return true;
34710d565efSmrg})
34810d565efSmrg
34910d565efSmrg(define_predicate "set_fp_mode_operand"
35010d565efSmrg  (ior (match_test "gpr_operand (op, mode)")
35110d565efSmrg       (and (match_code "const")
35210d565efSmrg	    (match_test "satisfies_constraint_Cfm (op)"))))
35310d565efSmrg
35410d565efSmrg(define_predicate "post_modify_address"
35510d565efSmrg  (match_code "post_modify,post_inc,post_dec"))
35610d565efSmrg
35710d565efSmrg(define_predicate "post_modify_operand"
35810d565efSmrg  (and (match_code "mem")
35910d565efSmrg       (match_test "post_modify_address (XEXP (op, 0), Pmode)")))
36010d565efSmrg
36110d565efSmrg; used in the memory clobber of stack_adjust_str, allows addresses with
36210d565efSmrg; large offsets.
36310d565efSmrg(define_predicate "memclob_operand"
36410d565efSmrg  (match_code "mem"))
36510d565efSmrg
36610d565efSmrg(define_predicate "nonsymbolic_immediate_operand"
36710d565efSmrg  (ior (match_test "immediate_operand (op, mode)")
36810d565efSmrg       (match_code "const_vector"))) /* Is this specific enough?  */
36910d565efSmrg
37010d565efSmrg;; Return true if OP is misaligned memory operand
37110d565efSmrg(define_predicate "misaligned_operand"
37210d565efSmrg  (and (match_code "mem")
37310d565efSmrg       (match_test "MEM_ALIGN (op) < GET_MODE_ALIGNMENT (mode)")))
374