]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/csky/predicates.md
Update copyright years.
[thirdparty/gcc.git] / gcc / config / csky / predicates.md
1 ;; Predicates for C-SKY.
2 ;; Copyright (C) 2018-2020 Free Software Foundation, Inc.
3 ;; Contributed by C-SKY Microsystems and Mentor Graphics.
4 ;;
5 ;; This file is part of GCC.
6 ;;
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)
10 ;; any later version.
11 ;;
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.
16 ;;
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/>. */
20
21 ;; Return 1 if OP is a load multiple operation.
22
23 (define_predicate "csky_load_multiple_operation"
24 (match_code "parallel")
25 {
26 int count = XVECLEN (op, 0);
27 int dest_regno;
28 rtx src_addr;
29 int i;
30
31 /* Perform a quick check so we don't blow up below. */
32 if (count <= 1
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)
38 return 0;
39
40 dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0)));
41 src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0);
42
43 for (i = 1; i < count; i++)
44 {
45 rtx elt = XVECEXP (op, 0, i);
46
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)
57 return 0;
58 }
59 return 1;
60 })
61
62 ;; Similar, for store multiple.
63
64 (define_predicate "csky_store_multiple_operation"
65 (match_code "parallel")
66 {
67 int count = XVECLEN (op, 0);
68 int src_regno;
69 rtx dest_addr;
70 int i;
71
72 /* Perform a quick check so we don't blow up below. */
73 if (count <= 1
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)
79 return 0;
80
81 src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0)));
82 dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0);
83
84 for (i = 1; i < count; i++)
85 {
86 rtx elt = XVECEXP (op, 0, i);
87
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)
98 return 0;
99 }
100 return 1;
101 })
102
103
104 (define_predicate "csky_arith_K_operand"
105 (match_code "reg,subreg,const_int")
106 {
107 if (register_operand (op, mode))
108 return 1;
109 if (CONST_INT_P (op) && CSKY_CONST_OK_FOR_K (INTVAL (op)))
110 return 1;
111 return 0;
112 })
113
114 (define_predicate "csky_literal_K_operand"
115 (match_code "const_int")
116 {
117 if (CONST_INT_P (op) && CSKY_CONST_OK_FOR_K (INTVAL (op)))
118 return 1;
119 return 0;
120 })
121
122 (define_predicate "csky_literal_I_operand"
123 (match_code "const_int")
124 {
125 if (CONST_INT_P (op) && CSKY_CONST_OK_FOR_I (INTVAL (op)))
126 return 1;
127 return 0;
128 })
129
130 (define_predicate "csky_literal_J_operand"
131 (match_code "const_int")
132 {
133 if (CONST_INT_P (op) && CSKY_CONST_OK_FOR_J (INTVAL (op)))
134 return 1;
135 return 0;
136 })
137
138 (define_predicate "csky_literal_Uk_operand"
139 (match_code "const_int")
140 {
141 if (CONST_INT_P (op) && CSKY_CONST_OK_FOR_Uk (INTVAL (op)))
142 return 1;
143 return 0;
144 })
145
146 ;; Nonzero if OP is a register or constant value of 1
147
148 (define_predicate "csky_arith_int1_operand"
149 (match_code "reg,subreg,const_int")
150 {
151 if (register_operand (op, mode))
152 return 1;
153 if (op == const1_rtx)
154 return 1;
155 return 0;
156 })
157
158
159 ;; Nonzero if OP is legal address for function call
160
161 (define_predicate "csky_call_address_operand"
162 (match_code "reg,subreg,symbol_ref")
163 {
164 if (!flag_pic && (GET_CODE (op) == SYMBOL_REF))
165 return 1;
166 if (register_operand (op, mode))
167 return 1;
168 return 0;
169 })
170
171 ;; Nonzero if OP is a valid source operand for a compare operation.
172
173 (define_predicate "csky_compare_operand"
174 (match_code "const_int,reg,subreg")
175 {
176 if (register_operand (op, mode))
177 return 1;
178 if (GET_CODE (op) == CONST_INT && INTVAL (op) == 0)
179 return 1;
180 return 0;
181 })
182
183 (define_predicate "csky_literal_K_Uh_operand"
184 (match_code "const_int")
185 {
186 if (CONST_INT_P (op)
187 && (CSKY_CONST_OK_FOR_K (INTVAL (op))
188 || CSKY_CONST_OK_FOR_Uh (INTVAL (op))))
189 return 1;
190 return 0;
191 })
192
193 ;; True if OP is a mem with an reg + optional displacement address.
194
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))")))
198
199 (define_predicate "csky_arith_any_imm_operand"
200 (match_code "const_int,reg,subreg")
201 {
202 if (register_operand (op, mode))
203 return 1;
204 if (CONST_INT_P (op))
205 return 1;
206 return 0;
207 })
208
209 (define_predicate "csky_arith_O_operand"
210 (match_code "reg,subreg,const_int")
211 {
212 if (register_operand (op, mode))
213 return 1;
214 if (CONST_INT_P (op) && CSKY_CONST_OK_FOR_O (INTVAL (op)))
215 return 1;
216 return 0;
217 })
218
219 (define_predicate "csky_unspec_operand"
220 (match_code "unspec")
221 {
222 if (op == NULL || GET_CODE(op) != UNSPEC)
223 return 0;
224 return 1;
225 }
226 )
227
228 (define_predicate "csky_const_float1_operand"
229 (and (match_code "const_double")
230 (match_test "(op == CONST1_RTX (mode))")))
231
232 (define_predicate "csky_arith_float1_operand"
233 (ior (match_operand 0 "register_operand")
234 (match_operand 0 "csky_const_float1_operand")))
235
236 (define_predicate "csky_const_float0_operand"
237 (and (match_code "const_double")
238 (match_test "(op == CONST0_RTX (mode))")))
239
240 (define_predicate "csky_compare_operand_float"
241 (ior (match_operand 0 "register_operand")
242 (match_operand 0 "csky_const_float0_operand")))
243
244 (define_special_predicate "registers_push"
245 (match_code "parallel")
246 {
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))
250 return false;
251 return true;
252 })
253
254 (define_special_predicate "registers_pop"
255 (match_code "parallel")
256 {
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))
260 return false;
261 return true;
262 })
263
264 (define_predicate "push_memory_operand"
265 (match_code "mem")
266 {
267 rtx x = XEXP (op, 0);
268 if (GET_CODE (x) != PRE_MODIFY)
269 return false;
270 if (XEXP (x, 0) != stack_pointer_rtx)
271 return false;
272 x = XEXP (x, 1);
273 if (GET_CODE (x) != PLUS)
274 return false;
275 if (XEXP (x, 0) != stack_pointer_rtx)
276 return false;
277 return CONST_INT_P (XEXP (x, 1));
278 })
279
280 (define_predicate "pop_memory_operand"
281 (match_code "mem")
282 {
283 rtx x = XEXP (op, 0);
284 if (GET_CODE (x) != POST_MODIFY)
285 return false;
286 if (XEXP (x, 0) != stack_pointer_rtx)
287 return false;
288 x = XEXP (x, 1);
289 if (GET_CODE (x) != PLUS)
290 return false;
291 if (XEXP (x, 0) != stack_pointer_rtx)
292 return false;
293 return CONST_INT_P (XEXP (x, 1));
294 })
295
296 (define_special_predicate "csky_float_comparison_operator"
297 (match_code "eq,ne,le,lt,ge,gt,geu,gtu,leu,ltu,
298 unordered,ordered"))