1 ;; Predicates for C-SKY.
2 ;; Copyright (C) 2018-2019 Free Software Foundation, Inc.
3 ;; Contributed by C-SKY Microsystems and Mentor Graphics.
5 ;; This file is part of GCC.
7 ;; GCC is free software; you can redistribute it and/or modify it
8 ;; under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 3, or (at your option)
12 ;; GCC is distributed in the hope that it will be useful, but
13 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 ;; General Public License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3. If not see
19 ;; <http://www.gnu.org/licenses/>. */
21 ;; Return 1 if OP is a load multiple operation.
23 (define_predicate "csky_load_multiple_operation"
24 (match_code "parallel")
26 int count = XVECLEN (op, 0);
31 /* Perform a quick check so we don't blow up below. */
33 || GET_CODE (XVECEXP (op, 0, 0)) != SET
34 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG
35 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != MEM
36 || GET_CODE (XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0)) != REG
37 || XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0) != stack_pointer_rtx)
40 dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0)));
41 src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0);
43 for (i = 1; i < count; i++)
45 rtx elt = XVECEXP (op, 0, i);
47 if (GET_CODE (elt) != SET
48 || GET_CODE (SET_DEST (elt)) != REG
49 || GET_MODE (SET_DEST (elt)) != SImode
50 || REGNO (SET_DEST (elt)) != (unsigned) (dest_regno + i)
51 || GET_CODE (SET_SRC (elt)) != MEM
52 || GET_MODE (SET_SRC (elt)) != SImode
53 || GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS
54 || ! rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr)
55 || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT
56 || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1)) != i * 4)
62 ;; Similar, for store multiple.
64 (define_predicate "csky_store_multiple_operation"
65 (match_code "parallel")
67 int count = XVECLEN (op, 0);
72 /* Perform a quick check so we don't blow up below. */
74 || GET_CODE (XVECEXP (op, 0, 0)) != SET
75 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != MEM
76 || GET_CODE (XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0)) != REG
77 || XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0) != stack_pointer_rtx
78 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != REG)
81 src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0)));
82 dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0);
84 for (i = 1; i < count; i++)
86 rtx elt = XVECEXP (op, 0, i);
88 if (GET_CODE (elt) != SET
89 || GET_CODE (SET_SRC (elt)) != REG
90 || GET_MODE (SET_SRC (elt)) != SImode
91 || REGNO (SET_SRC (elt)) != (unsigned) (src_regno + i)
92 || GET_CODE (SET_DEST (elt)) != MEM
93 || GET_MODE (SET_DEST (elt)) != SImode
94 || GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS
95 || ! rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr)
96 || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT
97 || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1)) != i * 4)
104 (define_predicate "csky_arith_K_operand"
105 (match_code "reg,subreg,const_int")
107 if (register_operand (op, mode))
109 if (CONST_INT_P (op) && CSKY_CONST_OK_FOR_K (INTVAL (op)))
114 (define_predicate "csky_literal_K_operand"
115 (match_code "const_int")
117 if (CONST_INT_P (op) && CSKY_CONST_OK_FOR_K (INTVAL (op)))
122 (define_predicate "csky_literal_I_operand"
123 (match_code "const_int")
125 if (CONST_INT_P (op) && CSKY_CONST_OK_FOR_I (INTVAL (op)))
130 (define_predicate "csky_literal_J_operand"
131 (match_code "const_int")
133 if (CONST_INT_P (op) && CSKY_CONST_OK_FOR_J (INTVAL (op)))
138 (define_predicate "csky_literal_Uk_operand"
139 (match_code "const_int")
141 if (CONST_INT_P (op) && CSKY_CONST_OK_FOR_Uk (INTVAL (op)))
146 ;; Nonzero if OP is a register or constant value of 1
148 (define_predicate "csky_arith_int1_operand"
149 (match_code "reg,subreg,const_int")
151 if (register_operand (op, mode))
153 if (op == const1_rtx)
159 ;; Nonzero if OP is legal address for function call
161 (define_predicate "csky_call_address_operand"
162 (match_code "reg,subreg,symbol_ref")
164 if (!flag_pic && (GET_CODE (op) == SYMBOL_REF))
166 if (register_operand (op, mode))
171 ;; Nonzero if OP is a valid source operand for a compare operation.
173 (define_predicate "csky_compare_operand"
174 (match_code "const_int,reg,subreg")
176 if (register_operand (op, mode))
178 if (GET_CODE (op) == CONST_INT && INTVAL (op) == 0)
183 (define_predicate "csky_literal_K_Uh_operand"
184 (match_code "const_int")
187 && (CSKY_CONST_OK_FOR_K (INTVAL (op))
188 || CSKY_CONST_OK_FOR_Uh (INTVAL (op))))
193 ;; True if OP is a mem with an reg + optional displacement address.
195 (define_predicate "csky_simple_mem_operand"
196 (and (match_operand 0 "memory_operand")
197 (match_test "csky_simple_addr_operand_p (XEXP (op, 0))")))
199 (define_predicate "csky_arith_any_imm_operand"
200 (match_code "const_int,reg,subreg")
202 if (register_operand (op, mode))
204 if (CONST_INT_P (op))
209 (define_predicate "csky_arith_O_operand"
210 (match_code "reg,subreg,const_int")
212 if (register_operand (op, mode))
214 if (CONST_INT_P (op) && CSKY_CONST_OK_FOR_O (INTVAL (op)))
219 (define_predicate "csky_unspec_operand"
220 (match_code "unspec")
222 if (op == NULL || GET_CODE(op) != UNSPEC)
228 (define_predicate "csky_const_float1_operand"
229 (and (match_code "const_double")
230 (match_test "(op == CONST1_RTX (mode))")))
232 (define_predicate "csky_arith_float1_operand"
233 (ior (match_operand 0 "register_operand")
234 (match_operand 0 "csky_const_float1_operand")))
236 (define_predicate "csky_const_float0_operand"
237 (and (match_code "const_double")
238 (match_test "(op == CONST0_RTX (mode))")))
240 (define_predicate "csky_compare_operand_float"
241 (ior (match_operand 0 "register_operand")
242 (match_operand 0 "csky_const_float0_operand")))
244 (define_special_predicate "registers_push"
245 (match_code "parallel")
247 if ((GET_CODE (XVECEXP (op, 0, 0)) != SET)
248 || (GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != UNSPEC)
249 || (XINT (SET_SRC (XVECEXP (op, 0, 0)), 1) != UNSPEC_PUSHPOP_MULT))
254 (define_special_predicate "registers_pop"
255 (match_code "parallel")
257 if ((GET_CODE (XVECEXP (op, 0, 1)) != SET)
258 || (GET_CODE (SET_SRC (XVECEXP (op, 0, 1))) != UNSPEC)
259 || (XINT (SET_SRC (XVECEXP (op, 0, 1)), 1) != UNSPEC_PUSHPOP_MULT))
264 (define_predicate "push_memory_operand"
267 rtx x = XEXP (op, 0);
268 if (GET_CODE (x) != PRE_MODIFY)
270 if (XEXP (x, 0) != stack_pointer_rtx)
273 if (GET_CODE (x) != PLUS)
275 if (XEXP (x, 0) != stack_pointer_rtx)
277 return CONST_INT_P (XEXP (x, 1));
280 (define_predicate "pop_memory_operand"
283 rtx x = XEXP (op, 0);
284 if (GET_CODE (x) != POST_MODIFY)
286 if (XEXP (x, 0) != stack_pointer_rtx)
289 if (GET_CODE (x) != PLUS)
291 if (XEXP (x, 0) != stack_pointer_rtx)
293 return CONST_INT_P (XEXP (x, 1));
296 (define_special_predicate "csky_float_comparison_operator"
297 (match_code "eq,ne,le,lt,ge,gt,geu,gtu,leu,ltu,