]>
Commit | Line | Data |
---|---|---|
deceffc1 | 1 | ;; Predicate definitions for Renesas M32R. |
f1717362 | 2 | ;; Copyright (C) 2005-2016 Free Software Foundation, Inc. |
deceffc1 | 3 | ;; |
4 | ;; This file is part of GCC. | |
5 | ;; | |
6 | ;; GCC is free software; you can redistribute it and/or modify | |
7 | ;; it under the terms of the GNU General Public License as published by | |
038d1e19 | 8 | ;; the Free Software Foundation; either version 3, or (at your option) |
deceffc1 | 9 | ;; any later version. |
10 | ;; | |
11 | ;; GCC is distributed in the hope that it will be useful, | |
12 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | ;; GNU General Public License for more details. | |
15 | ;; | |
16 | ;; You should have received a copy of the GNU General Public License | |
038d1e19 | 17 | ;; along with GCC; see the file COPYING3. If not see |
18 | ;; <http://www.gnu.org/licenses/>. | |
deceffc1 | 19 | |
20 | ;; Return true if OP is a register or the constant 0. | |
21 | ||
22 | (define_predicate "reg_or_zero_operand" | |
23 | (match_code "reg,subreg,const_int") | |
24 | { | |
452bfb8b | 25 | if (REG_P (op) || GET_CODE (op) == SUBREG) |
deceffc1 | 26 | return register_operand (op, mode); |
27 | ||
452bfb8b | 28 | if (!CONST_INT_P (op)) |
deceffc1 | 29 | return 0; |
30 | ||
31 | return INTVAL (op) == 0; | |
32 | }) | |
33 | ||
34 | ;; Return nonzero if the operand is suitable for use in a conditional | |
35 | ;; move sequence. | |
36 | ||
37 | (define_predicate "conditional_move_operand" | |
38 | (match_code "reg,subreg,const_int") | |
39 | { | |
40 | /* Only defined for simple integers so far... */ | |
41 | if (mode != SImode && mode != HImode && mode != QImode) | |
42 | return FALSE; | |
43 | ||
44 | /* At the moment we can handle moving registers and loading constants. */ | |
45 | /* To be added: Addition/subtraction/bitops/multiplication of registers. */ | |
46 | ||
47 | switch (GET_CODE (op)) | |
48 | { | |
49 | case REG: | |
50 | return 1; | |
51 | ||
52 | case CONST_INT: | |
bd9c4764 | 53 | return satisfies_constraint_I (op); |
deceffc1 | 54 | |
55 | default: | |
56 | #if 0 | |
57 | fprintf (stderr, "Test for cond move op of type: %s\n", | |
58 | GET_RTX_NAME (GET_CODE (op))); | |
59 | #endif | |
60 | return 0; | |
61 | } | |
62 | }) | |
63 | ||
64 | ;; Return true if the code is a test of the carry bit. | |
65 | ||
66 | (define_predicate "carry_compare_operand" | |
67 | (match_code "eq,ne") | |
68 | { | |
69 | rtx x; | |
70 | ||
71 | if (GET_MODE (op) != CCmode && GET_MODE (op) != VOIDmode) | |
72 | return FALSE; | |
73 | ||
74 | if (GET_CODE (op) != NE && GET_CODE (op) != EQ) | |
75 | return FALSE; | |
76 | ||
77 | x = XEXP (op, 0); | |
452bfb8b | 78 | if (!REG_P (x) || REGNO (x) != CARRY_REGNUM) |
deceffc1 | 79 | return FALSE; |
80 | ||
81 | x = XEXP (op, 1); | |
452bfb8b | 82 | if (!CONST_INT_P (x) || INTVAL (x) != 0) |
deceffc1 | 83 | return FALSE; |
84 | ||
85 | return TRUE; | |
86 | }) | |
87 | ||
88 | ;; Return 1 if OP is an EQ or NE comparison operator. | |
89 | ||
90 | (define_predicate "eqne_comparison_operator" | |
91 | (match_code "eq,ne") | |
92 | { | |
93 | enum rtx_code code = GET_CODE (op); | |
94 | ||
95 | return (code == EQ || code == NE); | |
96 | }) | |
97 | ||
98 | ;; Return 1 if OP is a signed comparison operator. | |
99 | ||
100 | (define_predicate "signed_comparison_operator" | |
101 | (match_code "eq,ne,lt,le,gt,ge") | |
102 | { | |
103 | enum rtx_code code = GET_CODE (op); | |
104 | ||
105 | return (COMPARISON_P (op) | |
106 | && (code == EQ || code == NE | |
107 | || code == LT || code == LE || code == GT || code == GE)); | |
108 | }) | |
109 | ||
110 | ;; Return true if OP is an acceptable argument for a move destination. | |
111 | ||
112 | (define_predicate "move_dest_operand" | |
113 | (match_code "reg,subreg,mem") | |
114 | { | |
115 | switch (GET_CODE (op)) | |
116 | { | |
117 | case REG : | |
118 | return register_operand (op, mode); | |
119 | case SUBREG : | |
120 | /* (subreg (mem ...) ...) can occur here if the inner part was once a | |
121 | pseudo-reg and is now a stack slot. */ | |
452bfb8b | 122 | if (MEM_P (SUBREG_REG (op))) |
deceffc1 | 123 | return address_operand (XEXP (SUBREG_REG (op), 0), mode); |
124 | else | |
125 | return register_operand (op, mode); | |
126 | case MEM : | |
127 | if (GET_CODE (XEXP (op, 0)) == POST_INC) | |
128 | return 0; /* stores can't do post inc */ | |
129 | return address_operand (XEXP (op, 0), mode); | |
130 | default : | |
131 | return 0; | |
132 | } | |
133 | }) | |
134 | ||
135 | ;; Return true if OP is an acceptable argument for a single word move | |
136 | ;; source. | |
137 | ||
138 | (define_predicate "move_src_operand" | |
139 | (match_code "reg,subreg,mem,const_int,const_double,label_ref,const,symbol_ref") | |
140 | { | |
141 | switch (GET_CODE (op)) | |
142 | { | |
143 | case LABEL_REF : | |
144 | case SYMBOL_REF : | |
145 | case CONST : | |
146 | return addr24_operand (op, mode); | |
147 | case CONST_INT : | |
148 | /* ??? We allow more cse opportunities if we only allow constants | |
149 | loadable with one insn, and split the rest into two. The instances | |
150 | where this would help should be rare and the current way is | |
151 | simpler. */ | |
152 | if (HOST_BITS_PER_WIDE_INT > 32) | |
153 | { | |
154 | HOST_WIDE_INT rest = INTVAL (op) >> 31; | |
155 | return (rest == 0 || rest == -1); | |
156 | } | |
157 | else | |
158 | return 1; | |
159 | case CONST_DOUBLE : | |
160 | if (mode == SFmode) | |
161 | return 1; | |
162 | else if (mode == SImode) | |
163 | { | |
164 | /* Large unsigned constants are represented as const_double's. */ | |
165 | unsigned HOST_WIDE_INT low, high; | |
166 | ||
167 | low = CONST_DOUBLE_LOW (op); | |
168 | high = CONST_DOUBLE_HIGH (op); | |
169 | return high == 0 && low <= (unsigned) 0xffffffff; | |
170 | } | |
171 | else | |
172 | return 0; | |
173 | case REG : | |
174 | return register_operand (op, mode); | |
175 | case SUBREG : | |
176 | /* (subreg (mem ...) ...) can occur here if the inner part was once a | |
177 | pseudo-reg and is now a stack slot. */ | |
452bfb8b | 178 | if (MEM_P (SUBREG_REG (op))) |
deceffc1 | 179 | return address_operand (XEXP (SUBREG_REG (op), 0), mode); |
180 | else | |
181 | return register_operand (op, mode); | |
182 | case MEM : | |
183 | if (GET_CODE (XEXP (op, 0)) == PRE_INC | |
184 | || GET_CODE (XEXP (op, 0)) == PRE_DEC) | |
185 | return 0; /* loads can't do pre-{inc,dec} */ | |
186 | return address_operand (XEXP (op, 0), mode); | |
187 | default : | |
188 | return 0; | |
189 | } | |
190 | }) | |
191 | ||
192 | ;; Return true if OP is an acceptable argument for a double word move | |
193 | ;; source. | |
194 | ||
195 | (define_predicate "move_double_src_operand" | |
196 | (match_code "reg,subreg,mem,const_int,const_double") | |
197 | { | |
198 | switch (GET_CODE (op)) | |
199 | { | |
200 | case CONST_INT : | |
201 | case CONST_DOUBLE : | |
202 | return 1; | |
203 | case REG : | |
204 | return register_operand (op, mode); | |
205 | case SUBREG : | |
206 | /* (subreg (mem ...) ...) can occur here if the inner part was once a | |
207 | pseudo-reg and is now a stack slot. */ | |
452bfb8b | 208 | if (MEM_P (SUBREG_REG (op))) |
deceffc1 | 209 | return move_double_src_operand (SUBREG_REG (op), mode); |
210 | else | |
211 | return register_operand (op, mode); | |
212 | case MEM : | |
213 | /* Disallow auto inc/dec for now. */ | |
214 | if (GET_CODE (XEXP (op, 0)) == PRE_DEC | |
215 | || GET_CODE (XEXP (op, 0)) == PRE_INC) | |
216 | return 0; | |
217 | return address_operand (XEXP (op, 0), mode); | |
218 | default : | |
219 | return 0; | |
220 | } | |
221 | }) | |
222 | ||
223 | ;; Return true if OP is a const_int requiring two instructions to | |
224 | ;; load. | |
225 | ||
226 | (define_predicate "two_insn_const_operand" | |
227 | (match_code "const_int") | |
228 | { | |
452bfb8b | 229 | if (!CONST_INT_P (op)) |
deceffc1 | 230 | return 0; |
bd9c4764 | 231 | if (satisfies_constraint_J (op) |
232 | || satisfies_constraint_M (op) | |
233 | || satisfies_constraint_L (op)) | |
deceffc1 | 234 | return 0; |
235 | return 1; | |
236 | }) | |
237 | ||
238 | ;; Returns 1 if OP is a symbol reference. | |
239 | ||
240 | (define_predicate "symbolic_operand" | |
241 | (match_code "symbol_ref,label_ref,const") | |
242 | { | |
243 | switch (GET_CODE (op)) | |
244 | { | |
245 | case SYMBOL_REF: | |
246 | case LABEL_REF: | |
247 | case CONST : | |
248 | return 1; | |
249 | ||
250 | default: | |
251 | return 0; | |
252 | } | |
253 | }) | |
254 | ||
c910419d | 255 | ;; Return true if OP is a signed 8-bit immediate value. |
deceffc1 | 256 | |
257 | (define_predicate "int8_operand" | |
258 | (match_code "const_int") | |
259 | { | |
452bfb8b | 260 | if (!CONST_INT_P (op)) |
deceffc1 | 261 | return 0; |
bd9c4764 | 262 | return satisfies_constraint_I (op); |
deceffc1 | 263 | }) |
264 | ||
c910419d | 265 | ;; Return true if OP is an unsigned 16-bit immediate value. |
deceffc1 | 266 | |
267 | (define_predicate "uint16_operand" | |
268 | (match_code "const_int") | |
269 | { | |
452bfb8b | 270 | if (!CONST_INT_P (op)) |
deceffc1 | 271 | return 0; |
bd9c4764 | 272 | return satisfies_constraint_K (op); |
deceffc1 | 273 | }) |
274 | ||
c910419d | 275 | ;; Return true if OP is a register or signed 16-bit value. |
deceffc1 | 276 | |
277 | (define_predicate "reg_or_int16_operand" | |
278 | (match_code "reg,subreg,const_int") | |
279 | { | |
452bfb8b | 280 | if (REG_P (op) || GET_CODE (op) == SUBREG) |
deceffc1 | 281 | return register_operand (op, mode); |
452bfb8b | 282 | if (!CONST_INT_P (op)) |
deceffc1 | 283 | return 0; |
bd9c4764 | 284 | return satisfies_constraint_J (op); |
deceffc1 | 285 | }) |
286 | ||
c910419d | 287 | ;; Return true if OP is a register or an unsigned 16-bit value. |
deceffc1 | 288 | |
289 | (define_predicate "reg_or_uint16_operand" | |
290 | (match_code "reg,subreg,const_int") | |
291 | { | |
452bfb8b | 292 | if (REG_P (op) || GET_CODE (op) == SUBREG) |
deceffc1 | 293 | return register_operand (op, mode); |
452bfb8b | 294 | if (!CONST_INT_P (op)) |
deceffc1 | 295 | return 0; |
bd9c4764 | 296 | return satisfies_constraint_K (op); |
deceffc1 | 297 | }) |
298 | ||
c910419d | 299 | ;; Return true if OP is a register or signed 16-bit value for |
deceffc1 | 300 | ;; compares. |
301 | ||
302 | (define_predicate "reg_or_cmp_int16_operand" | |
303 | (match_code "reg,subreg,const_int") | |
304 | { | |
452bfb8b | 305 | if (REG_P (op) || GET_CODE (op) == SUBREG) |
deceffc1 | 306 | return register_operand (op, mode); |
452bfb8b | 307 | if (!CONST_INT_P (op)) |
deceffc1 | 308 | return 0; |
bd9c4764 | 309 | return satisfies_constraint_P (op); |
deceffc1 | 310 | }) |
311 | ||
312 | ;; Return true if OP is a register or an integer value that can be | |
313 | ;; used is SEQ/SNE. We can use either XOR of the value or ADD of the | |
314 | ;; negative of the value for the constant. Don't allow 0, because | |
315 | ;; that is special cased. | |
316 | ||
317 | (define_predicate "reg_or_eq_int16_operand" | |
318 | (match_code "reg,subreg,const_int") | |
319 | { | |
320 | HOST_WIDE_INT value; | |
321 | ||
452bfb8b | 322 | if (REG_P (op) || GET_CODE (op) == SUBREG) |
deceffc1 | 323 | return register_operand (op, mode); |
324 | ||
452bfb8b | 325 | if (!CONST_INT_P (op)) |
deceffc1 | 326 | return 0; |
327 | ||
328 | value = INTVAL (op); | |
329 | return (value != 0) && (UINT16_P (value) || CMP_INT16_P (-value)); | |
330 | }) | |
331 | ||
c910419d | 332 | ;; Return true if OP is a signed 16-bit immediate value useful in |
deceffc1 | 333 | ;; comparisons. |
334 | ||
335 | (define_predicate "cmp_int16_operand" | |
336 | (match_code "const_int") | |
337 | { | |
452bfb8b | 338 | if (!CONST_INT_P (op)) |
deceffc1 | 339 | return 0; |
bd9c4764 | 340 | return satisfies_constraint_P (op); |
deceffc1 | 341 | }) |
342 | ||
343 | ;; Acceptable arguments to the call insn. | |
344 | ||
345 | (define_predicate "call_address_operand" | |
346 | (match_code "symbol_ref,label_ref,const") | |
347 | { | |
348 | return symbolic_operand (op, mode); | |
349 | ||
350 | /* Constants and values in registers are not OK, because | |
351 | the m32r BL instruction can only support PC relative branching. */ | |
352 | }) | |
353 | ||
354 | ;; Return true if OP is an acceptable input argument for a zero/sign | |
355 | ;; extend operation. | |
356 | ||
357 | (define_predicate "extend_operand" | |
358 | (match_code "reg,subreg,mem") | |
359 | { | |
360 | rtx addr; | |
361 | ||
362 | switch (GET_CODE (op)) | |
363 | { | |
364 | case REG : | |
365 | case SUBREG : | |
366 | return register_operand (op, mode); | |
367 | ||
368 | case MEM : | |
369 | addr = XEXP (op, 0); | |
370 | if (GET_CODE (addr) == PRE_INC || GET_CODE (addr) == PRE_DEC) | |
371 | return 0; /* loads can't do pre inc/pre dec */ | |
372 | ||
373 | return address_operand (addr, mode); | |
374 | ||
375 | default : | |
376 | return 0; | |
377 | } | |
378 | }) | |
379 | ||
380 | ;; Return nonzero if the operand is an insn that is a small | |
381 | ;; insn. Allow const_int 0 as well, which is a placeholder for NOP | |
382 | ;; slots. | |
383 | ||
384 | (define_predicate "small_insn_p" | |
385 | (match_code "insn,call_insn,jump_insn") | |
386 | { | |
452bfb8b | 387 | if (CONST_INT_P (op) && INTVAL (op) == 0) |
deceffc1 | 388 | return 1; |
389 | ||
390 | if (! INSN_P (op)) | |
391 | return 0; | |
392 | ||
d3ffa7b4 | 393 | return get_attr_length (as_a <rtx_insn *> (op)) == 2; |
deceffc1 | 394 | }) |
395 | ||
396 | ;; Return true if op is an integer constant, less than or equal to | |
397 | ;; MAX_MOVE_BYTES. | |
398 | ||
399 | (define_predicate "m32r_block_immediate_operand" | |
400 | (match_code "const_int") | |
401 | { | |
452bfb8b | 402 | if (!CONST_INT_P (op) |
deceffc1 | 403 | || INTVAL (op) > MAX_MOVE_BYTES |
404 | || INTVAL (op) <= 0) | |
405 | return 0; | |
406 | ||
407 | return 1; | |
408 | }) | |
409 | ||
410 | ;; Return nonzero if the operand is an insn that is a large insn. | |
411 | ||
412 | (define_predicate "large_insn_p" | |
413 | (match_code "insn,call_insn,jump_insn") | |
414 | { | |
415 | if (! INSN_P (op)) | |
416 | return 0; | |
417 | ||
d3ffa7b4 | 418 | return get_attr_length (as_a <rtx_insn *> (op)) != 2; |
deceffc1 | 419 | }) |
420 | ||
421 | ;; Returns 1 if OP is an acceptable operand for seth/add3. | |
422 | ||
423 | (define_predicate "seth_add3_operand" | |
424 | (match_code "symbol_ref,label_ref,const") | |
425 | { | |
426 | if (flag_pic) | |
427 | return 0; | |
428 | ||
429 | if (GET_CODE (op) == SYMBOL_REF | |
430 | || GET_CODE (op) == LABEL_REF) | |
431 | return 1; | |
432 | ||
433 | if (GET_CODE (op) == CONST | |
434 | && GET_CODE (XEXP (op, 0)) == PLUS | |
435 | && GET_CODE (XEXP (XEXP (op, 0), 0)) == SYMBOL_REF | |
bd9c4764 | 436 | && satisfies_constraint_J (XEXP (XEXP (op, 0), 1))) |
deceffc1 | 437 | return 1; |
438 | ||
439 | return 0; | |
440 | }) |