]>
Commit | Line | Data |
---|---|---|
526b7aee | 1 | ;; Predicate definitions for Synopsys DesignWare ARC. |
23a5b65a | 2 | ;; Copyright (C) 2007-2014 Free Software Foundation, Inc. |
526b7aee SV |
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 | |
8 | ;; the Free Software Foundation; either version 3, or (at your option) | |
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 | |
17 | ;; along with GCC; see the file COPYING3. If not see | |
18 | ;; <http://www.gnu.org/licenses/>. | |
19 | ||
20 | (define_predicate "dest_reg_operand" | |
21 | (match_code "reg,subreg") | |
22 | { | |
23 | rtx op0 = op; | |
24 | ||
25 | if (GET_CODE (op0) == SUBREG) | |
26 | op0 = SUBREG_REG (op0); | |
27 | if (REG_P (op0) && REGNO (op0) < FIRST_PSEUDO_REGISTER | |
28 | && TEST_HARD_REG_BIT (reg_class_contents[ALL_CORE_REGS], | |
29 | REGNO (op0)) | |
30 | && !TEST_HARD_REG_BIT (reg_class_contents[WRITABLE_CORE_REGS], | |
31 | REGNO (op0))) | |
32 | return 0; | |
33 | return register_operand (op, mode); | |
34 | }) | |
35 | ||
36 | (define_predicate "mpy_dest_reg_operand" | |
37 | (match_code "reg,subreg") | |
38 | { | |
39 | rtx op0 = op; | |
40 | ||
41 | if (GET_CODE (op0) == SUBREG) | |
42 | op0 = SUBREG_REG (op0); | |
43 | if (REG_P (op0) && REGNO (op0) < FIRST_PSEUDO_REGISTER | |
44 | && TEST_HARD_REG_BIT (reg_class_contents[ALL_CORE_REGS], | |
45 | REGNO (op0)) | |
46 | /* Make sure the destination register is not LP_COUNT. */ | |
47 | && !TEST_HARD_REG_BIT (reg_class_contents[MPY_WRITABLE_CORE_REGS], | |
48 | REGNO (op0))) | |
49 | return 0; | |
50 | return register_operand (op, mode); | |
51 | }) | |
52 | ||
53 | ||
54 | ;; Returns 1 if OP is a symbol reference. | |
55 | (define_predicate "symbolic_operand" | |
56 | (match_code "symbol_ref, label_ref, const") | |
57 | ) | |
58 | ||
59 | ;; Acceptable arguments to the call insn. | |
60 | (define_predicate "call_address_operand" | |
61 | (ior (match_code "const_int, reg") | |
62 | (match_operand 0 "symbolic_operand") | |
63 | (match_test "CONSTANT_P (op) | |
64 | && arc_legitimate_constant_p (VOIDmode, op)")) | |
65 | ) | |
66 | ||
67 | (define_predicate "call_operand" | |
68 | (and (match_code "mem") | |
69 | (match_test "call_address_operand (XEXP (op, 0), mode)")) | |
70 | ) | |
71 | ||
72 | ;; Return true if OP is a unsigned 6-bit immediate (u6) value. | |
73 | (define_predicate "u6_immediate_operand" | |
74 | (and (match_code "const_int") | |
75 | (match_test "UNSIGNED_INT6 (INTVAL (op))")) | |
76 | ) | |
77 | ||
78 | ;; Return true if OP is a short immediate (shimm) value. | |
79 | (define_predicate "short_immediate_operand" | |
80 | (and (match_code "const_int") | |
81 | (match_test "SMALL_INT (INTVAL (op))")) | |
82 | ) | |
83 | ||
84 | (define_predicate "p2_immediate_operand" | |
85 | (and (match_code "const_int") | |
86 | (match_test "((INTVAL (op) - 1) & INTVAL (op)) == 0") | |
87 | (match_test "INTVAL (op)")) | |
88 | ) | |
89 | ||
90 | ;; Return true if OP will require a long immediate (limm) value. | |
91 | ;; This is currently only used when calculating length attributes. | |
92 | (define_predicate "long_immediate_operand" | |
93 | (match_code "symbol_ref, label_ref, const, const_double, const_int") | |
94 | { | |
95 | switch (GET_CODE (op)) | |
96 | { | |
97 | case SYMBOL_REF : | |
98 | case LABEL_REF : | |
99 | case CONST : | |
100 | return 1; | |
101 | case CONST_INT : | |
102 | return !SIGNED_INT12 (INTVAL (op)); | |
103 | case CONST_DOUBLE : | |
104 | /* These can happen because large unsigned 32 bit constants are | |
105 | represented this way (the multiplication patterns can cause these | |
106 | to be generated). They also occur for SFmode values. */ | |
107 | return 1; | |
108 | default: | |
109 | break; | |
110 | } | |
111 | return 0; | |
112 | } | |
113 | ) | |
114 | ||
115 | ;; Return true if OP is a MEM that when used as a load or store address will | |
116 | ;; require an 8 byte insn. | |
117 | ;; Load and store instructions don't allow the same possibilities but they're | |
118 | ;; similar enough that this one function will do. | |
119 | ;; This is currently only used when calculating length attributes. */ | |
120 | (define_predicate "long_immediate_loadstore_operand" | |
121 | (match_code "mem") | |
122 | { | |
123 | int size = GET_MODE_SIZE (GET_MODE (op)); | |
124 | ||
125 | op = XEXP (op, 0); | |
126 | switch (GET_CODE (op)) | |
127 | { | |
128 | case SYMBOL_REF : | |
129 | case LABEL_REF : | |
130 | case CONST : | |
131 | return 1; | |
132 | case CONST_INT : | |
133 | /* This must be handled as "st c,[limm]". Ditto for load. | |
134 | Technically, the assembler could translate some possibilities to | |
135 | "st c,[limm/2 + limm/2]" if limm/2 will fit in a shimm, but we don't | |
136 | assume that it does. */ | |
137 | return 1; | |
138 | case CONST_DOUBLE : | |
139 | /* These can happen because large unsigned 32 bit constants are | |
140 | represented this way (the multiplication patterns can cause these | |
141 | to be generated). They also occur for SFmode values. */ | |
142 | return 1; | |
143 | case REG : | |
144 | return 0; | |
145 | case PLUS : | |
146 | { | |
147 | rtx x = XEXP (op, 1); | |
148 | ||
149 | if (GET_CODE (x) == CONST) | |
150 | { | |
151 | x = XEXP (x, 0); | |
152 | if (GET_CODE (x) == PLUS) | |
153 | x = XEXP (x, 0); | |
154 | } | |
155 | if (CONST_INT_P (x)) | |
156 | return (!SMALL_INT (INTVAL (x)) | |
157 | && (size <= 1 || size > 4 | |
158 | || (INTVAL (x) & (size - 1)) != 0 | |
159 | || !SMALL_INT (INTVAL (x) / size))); | |
160 | else if (GET_CODE (x) == SYMBOL_REF) | |
161 | return TARGET_NO_SDATA_SET || !SYMBOL_REF_SMALL_P (x); | |
162 | return 0; | |
163 | } | |
164 | default: | |
165 | break; | |
166 | } | |
167 | return 0; | |
168 | } | |
169 | ) | |
170 | ||
171 | ;; Return true if OP is any of R0-R3,R12-R15 for ARCompact 16-bit | |
172 | ;; instructions | |
173 | (define_predicate "compact_register_operand" | |
174 | (match_code "reg, subreg") | |
175 | { | |
176 | if ((GET_MODE (op) != mode) && (mode != VOIDmode)) | |
177 | return 0; | |
178 | ||
179 | return (GET_CODE (op) == REG) | |
180 | && (REGNO (op) >= FIRST_PSEUDO_REGISTER | |
181 | || COMPACT_GP_REG_P (REGNO (op))) ; | |
182 | } | |
183 | ) | |
184 | ||
185 | ;; Return true if OP is an acceptable memory operand for ARCompact | |
186 | ;; 16-bit load instructions. | |
187 | (define_predicate "compact_load_memory_operand" | |
188 | (match_code "mem") | |
189 | { | |
190 | rtx addr, plus0, plus1; | |
191 | int size, off; | |
192 | ||
193 | /* Eliminate non-memory operations. */ | |
194 | if (GET_CODE (op) != MEM) | |
195 | return 0; | |
196 | ||
197 | /* .di instructions have no 16-bit form. */ | |
198 | if (MEM_VOLATILE_P (op) && !TARGET_VOLATILE_CACHE_SET) | |
199 | return 0; | |
200 | ||
201 | if (mode == VOIDmode) | |
202 | mode = GET_MODE (op); | |
203 | ||
204 | size = GET_MODE_SIZE (mode); | |
205 | ||
206 | /* dword operations really put out 2 instructions, so eliminate them. */ | |
207 | if (size > UNITS_PER_WORD) | |
208 | return 0; | |
209 | ||
210 | /* Decode the address now. */ | |
211 | addr = XEXP (op, 0); | |
212 | switch (GET_CODE (addr)) | |
213 | { | |
214 | case REG: | |
215 | return (REGNO (addr) >= FIRST_PSEUDO_REGISTER | |
216 | || COMPACT_GP_REG_P (REGNO (addr)) | |
217 | || (SP_REG_P (REGNO (addr)) && (size != 2))); | |
218 | /* Reverting for the moment since ldw_s does not have sp as a valid | |
219 | parameter. */ | |
220 | case PLUS: | |
221 | plus0 = XEXP (addr, 0); | |
222 | plus1 = XEXP (addr, 1); | |
223 | ||
224 | if ((GET_CODE (plus0) == REG) | |
225 | && ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER) | |
226 | || COMPACT_GP_REG_P (REGNO (plus0))) | |
227 | && ((GET_CODE (plus1) == REG) | |
228 | && ((REGNO (plus1) >= FIRST_PSEUDO_REGISTER) | |
229 | || COMPACT_GP_REG_P (REGNO (plus1))))) | |
230 | { | |
231 | return 1; | |
232 | } | |
233 | ||
234 | if ((GET_CODE (plus0) == REG) | |
235 | && ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER) | |
236 | || COMPACT_GP_REG_P (REGNO (plus0))) | |
237 | && (GET_CODE (plus1) == CONST_INT)) | |
238 | { | |
239 | off = INTVAL (plus1); | |
240 | ||
241 | /* Negative offset is not supported in 16-bit load/store insns. */ | |
242 | if (off < 0) | |
243 | return 0; | |
244 | ||
245 | switch (size) | |
246 | { | |
247 | case 1: | |
248 | return (off < 32); | |
249 | case 2: | |
250 | return ((off < 64) && (off % 2 == 0)); | |
251 | case 4: | |
252 | return ((off < 128) && (off % 4 == 0)); | |
253 | } | |
254 | } | |
255 | ||
256 | if ((GET_CODE (plus0) == REG) | |
257 | && ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER) | |
258 | || SP_REG_P (REGNO (plus0))) | |
259 | && (GET_CODE (plus1) == CONST_INT)) | |
260 | { | |
261 | off = INTVAL (plus1); | |
262 | return ((size != 2) && (off >= 0 && off < 128) && (off % 4 == 0)); | |
263 | } | |
264 | default: | |
265 | break ; | |
266 | /* TODO: 'gp' and 'pcl' are to supported as base address operand | |
267 | for 16-bit load instructions. */ | |
268 | } | |
269 | return 0; | |
270 | ||
271 | } | |
272 | ) | |
273 | ||
274 | ;; Return true if OP is an acceptable memory operand for ARCompact | |
275 | ;; 16-bit store instructions | |
276 | (define_predicate "compact_store_memory_operand" | |
277 | (match_code "mem") | |
278 | { | |
279 | rtx addr, plus0, plus1; | |
280 | int size, off; | |
281 | ||
282 | if (mode == VOIDmode) | |
283 | mode = GET_MODE (op); | |
284 | ||
285 | /* .di instructions have no 16-bit form. */ | |
286 | if (MEM_VOLATILE_P (op) && !TARGET_VOLATILE_CACHE_SET) | |
287 | return 0; | |
288 | ||
289 | size = GET_MODE_SIZE (mode); | |
290 | ||
291 | /* dword operations really put out 2 instructions, so eliminate them. */ | |
292 | if (size > UNITS_PER_WORD) | |
293 | return 0; | |
294 | ||
295 | /* Decode the address now. */ | |
296 | addr = XEXP (op, 0); | |
297 | switch (GET_CODE (addr)) | |
298 | { | |
299 | case REG: | |
300 | return (REGNO (addr) >= FIRST_PSEUDO_REGISTER | |
301 | || COMPACT_GP_REG_P (REGNO (addr)) | |
302 | || (SP_REG_P (REGNO (addr)) && (size != 2))); | |
303 | /* stw_s does not support SP as a parameter. */ | |
304 | case PLUS: | |
305 | plus0 = XEXP (addr, 0); | |
306 | plus1 = XEXP (addr, 1); | |
307 | ||
308 | if ((GET_CODE (plus0) == REG) | |
309 | && ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER) | |
310 | || COMPACT_GP_REG_P (REGNO (plus0))) | |
311 | && (GET_CODE (plus1) == CONST_INT)) | |
312 | { | |
313 | off = INTVAL (plus1); | |
314 | ||
315 | /* Negative offset is not supported in 16-bit load/store insns. */ | |
316 | if (off < 0) | |
317 | return 0; | |
318 | ||
319 | switch (size) | |
320 | { | |
321 | case 1: | |
322 | return (off < 32); | |
323 | case 2: | |
324 | return ((off < 64) && (off % 2 == 0)); | |
325 | case 4: | |
326 | return ((off < 128) && (off % 4 == 0)); | |
327 | } | |
328 | } | |
329 | ||
330 | if ((GET_CODE (plus0) == REG) | |
331 | && ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER) | |
332 | || SP_REG_P (REGNO (plus0))) | |
333 | && (GET_CODE (plus1) == CONST_INT)) | |
334 | { | |
335 | off = INTVAL (plus1); | |
336 | ||
337 | return ((size != 2) && (off >= 0 && off < 128) && (off % 4 == 0)); | |
338 | } | |
339 | default: | |
340 | break; | |
341 | } | |
342 | return 0; | |
343 | } | |
344 | ) | |
345 | ||
346 | ;; Return true if OP is an acceptable argument for a single word | |
347 | ;; move source. | |
348 | (define_predicate "move_src_operand" | |
349 | (match_code "symbol_ref, label_ref, const, const_int, const_double, reg, subreg, mem") | |
350 | { | |
351 | switch (GET_CODE (op)) | |
352 | { | |
353 | case SYMBOL_REF : | |
354 | case LABEL_REF : | |
355 | case CONST : | |
356 | return (!flag_pic || arc_legitimate_pic_operand_p(op)); | |
357 | case CONST_INT : | |
358 | return (LARGE_INT (INTVAL (op))); | |
359 | case CONST_DOUBLE : | |
360 | /* We can handle DImode integer constants in SImode if the value | |
361 | (signed or unsigned) will fit in 32 bits. This is needed because | |
362 | large unsigned 32 bit constants are represented as CONST_DOUBLEs. */ | |
363 | if (mode == SImode) | |
364 | return arc_double_limm_p (op); | |
365 | /* We can handle 32 bit floating point constants. */ | |
366 | if (mode == SFmode) | |
367 | return GET_MODE (op) == SFmode; | |
368 | return 0; | |
369 | case REG : | |
370 | return register_operand (op, mode); | |
371 | case SUBREG : | |
372 | /* (subreg (mem ...) ...) can occur here if the inner part was once a | |
373 | pseudo-reg and is now a stack slot. */ | |
374 | if (GET_CODE (SUBREG_REG (op)) == MEM) | |
375 | return address_operand (XEXP (SUBREG_REG (op), 0), mode); | |
376 | else | |
377 | return register_operand (op, mode); | |
378 | case MEM : | |
379 | return address_operand (XEXP (op, 0), mode); | |
380 | default : | |
381 | return 0; | |
382 | } | |
383 | } | |
384 | ) | |
385 | ||
386 | ;; Return true if OP is an acceptable argument for a double word | |
387 | ;; move source. | |
388 | (define_predicate "move_double_src_operand" | |
389 | (match_code "reg, subreg, mem, const_int, const_double") | |
390 | { | |
391 | switch (GET_CODE (op)) | |
392 | { | |
393 | case REG : | |
394 | return register_operand (op, mode); | |
395 | case SUBREG : | |
396 | /* (subreg (mem ...) ...) can occur here if the inner part was once a | |
397 | pseudo-reg and is now a stack slot. */ | |
398 | if (GET_CODE (SUBREG_REG (op)) == MEM) | |
399 | return move_double_src_operand (SUBREG_REG (op), mode); | |
400 | else | |
401 | return register_operand (op, mode); | |
402 | case MEM : | |
403 | return address_operand (XEXP (op, 0), mode); | |
404 | case CONST_INT : | |
405 | case CONST_DOUBLE : | |
406 | return 1; | |
407 | default : | |
408 | return 0; | |
409 | } | |
410 | } | |
411 | ) | |
412 | ||
413 | ;; Return true if OP is an acceptable argument for a move destination. | |
414 | (define_predicate "move_dest_operand" | |
415 | (match_code "reg, subreg, mem") | |
416 | { | |
417 | switch (GET_CODE (op)) | |
418 | { | |
419 | case REG : | |
420 | /* Program Counter register cannot be the target of a move. It is | |
421 | a readonly register. */ | |
422 | if (REGNO (op) == PROGRAM_COUNTER_REGNO) | |
423 | return 0; | |
424 | else if (TARGET_MULMAC_32BY16_SET | |
425 | && (REGNO (op) == 56 || REGNO(op) == 57)) | |
426 | return 0; | |
427 | else if (TARGET_MUL64_SET | |
428 | && (REGNO (op) == 57 || REGNO(op) == 58 || REGNO(op) == 59 )) | |
429 | return 0; | |
430 | else | |
431 | return dest_reg_operand (op, mode); | |
432 | case SUBREG : | |
433 | /* (subreg (mem ...) ...) can occur here if the inner part was once a | |
434 | pseudo-reg and is now a stack slot. */ | |
435 | if (GET_CODE (SUBREG_REG (op)) == MEM) | |
436 | return address_operand (XEXP (SUBREG_REG (op), 0), mode); | |
437 | else | |
438 | return dest_reg_operand (op, mode); | |
439 | case MEM : | |
440 | { | |
441 | rtx addr = XEXP (op, 0); | |
442 | ||
443 | if (GET_CODE (addr) == PLUS | |
444 | && (GET_CODE (XEXP (addr, 0)) == MULT | |
445 | || (!CONST_INT_P (XEXP (addr, 1)) | |
446 | && (TARGET_NO_SDATA_SET | |
447 | || GET_CODE (XEXP (addr, 1)) != SYMBOL_REF | |
448 | || !SYMBOL_REF_SMALL_P (XEXP (addr, 1)))))) | |
449 | return 0; | |
450 | if ((GET_CODE (addr) == PRE_MODIFY || GET_CODE (addr) == POST_MODIFY) | |
451 | && (GET_CODE (XEXP (addr, 1)) != PLUS | |
452 | || !CONST_INT_P (XEXP (XEXP (addr, 1), 1)))) | |
453 | return 0; | |
454 | return address_operand (addr, mode); | |
455 | } | |
456 | default : | |
457 | return 0; | |
458 | } | |
459 | ||
460 | } | |
461 | ) | |
462 | ||
463 | ;; Return true if OP is valid load with update operand. | |
464 | (define_predicate "load_update_operand" | |
465 | (match_code "mem") | |
466 | { | |
467 | if (GET_CODE (op) != MEM | |
468 | || GET_MODE (op) != mode) | |
469 | return 0; | |
470 | op = XEXP (op, 0); | |
471 | if (GET_CODE (op) != PLUS | |
472 | || GET_MODE (op) != Pmode | |
473 | || !register_operand (XEXP (op, 0), Pmode) | |
474 | || !nonmemory_operand (XEXP (op, 1), Pmode)) | |
475 | return 0; | |
476 | return 1; | |
477 | ||
478 | } | |
479 | ) | |
480 | ||
481 | ;; Return true if OP is valid store with update operand. | |
482 | (define_predicate "store_update_operand" | |
483 | (match_code "mem") | |
484 | { | |
485 | if (GET_CODE (op) != MEM | |
486 | || GET_MODE (op) != mode) | |
487 | return 0; | |
488 | op = XEXP (op, 0); | |
489 | if (GET_CODE (op) != PLUS | |
490 | || GET_MODE (op) != Pmode | |
491 | || !register_operand (XEXP (op, 0), Pmode) | |
492 | || !(GET_CODE (XEXP (op, 1)) == CONST_INT | |
493 | && SMALL_INT (INTVAL (XEXP (op, 1))))) | |
494 | return 0; | |
495 | return 1; | |
496 | } | |
497 | ) | |
498 | ||
499 | ;; Return true if OP is a non-volatile non-immediate operand. | |
500 | ;; Volatile memory refs require a special "cache-bypass" instruction | |
501 | ;; and only the standard movXX patterns are set up to handle them. | |
502 | (define_predicate "nonvol_nonimm_operand" | |
503 | (and (match_code "subreg, reg, mem") | |
504 | (match_test "(GET_CODE (op) != MEM || !MEM_VOLATILE_P (op)) && nonimmediate_operand (op, mode)")) | |
505 | ) | |
506 | ||
507 | ;; Return 1 if OP is a comparison operator valid for the mode of CC. | |
508 | ;; This allows the use of MATCH_OPERATOR to recognize all the branch insns. | |
509 | ||
510 | (define_predicate "proper_comparison_operator" | |
511 | (match_code "eq, ne, le, lt, ge, gt, leu, ltu, geu, gtu, unordered, ordered, uneq, unge, ungt, unle, unlt, ltgt") | |
512 | { | |
513 | enum rtx_code code = GET_CODE (op); | |
514 | ||
515 | if (!COMPARISON_P (op)) | |
516 | return 0; | |
517 | ||
518 | /* After generic flag-setting insns, we can use eq / ne / pl / mi / pnz . | |
519 | There are some creative uses for hi / ls after shifts, but these are | |
520 | hard to understand for the compiler and could be at best the target of | |
521 | a peephole. */ | |
522 | switch (GET_MODE (XEXP (op, 0))) | |
523 | { | |
524 | case CC_ZNmode: | |
525 | return (code == EQ || code == NE || code == GE || code == LT | |
526 | || code == GT); | |
527 | case CC_Zmode: | |
528 | return code == EQ || code == NE; | |
529 | case CC_Cmode: | |
530 | return code == LTU || code == GEU; | |
531 | case CC_FP_GTmode: | |
532 | return code == GT || code == UNLE; | |
533 | case CC_FP_GEmode: | |
534 | return code == GE || code == UNLT; | |
535 | case CC_FP_ORDmode: | |
536 | return code == ORDERED || code == UNORDERED; | |
537 | case CC_FP_UNEQmode: | |
538 | return code == UNEQ || code == LTGT; | |
539 | case CC_FPXmode: | |
540 | return (code == EQ || code == NE || code == UNEQ || code == LTGT | |
541 | || code == ORDERED || code == UNORDERED); | |
542 | ||
543 | case CCmode: | |
544 | case SImode: /* Used for BRcc. */ | |
545 | return 1; | |
546 | /* From combiner. */ | |
547 | case QImode: case HImode: case DImode: case SFmode: case DFmode: | |
548 | return 0; | |
549 | default: | |
550 | gcc_unreachable (); | |
551 | } | |
552 | }) | |
553 | ||
554 | (define_predicate "equality_comparison_operator" | |
555 | (match_code "eq, ne")) | |
556 | ||
557 | (define_predicate "brcc_nolimm_operator" | |
558 | (ior (match_test "REG_P (XEXP (op, 1))") | |
559 | (and (match_code "eq, ne, lt, ge, ltu, geu") | |
560 | (match_test "u6_immediate_operand (XEXP (op, 1), SImode)")) | |
561 | (and (match_code "le, gt, leu, gtu") | |
562 | (match_test "UNSIGNED_INT6 (INTVAL (XEXP (op, 1)) + 1)")))) | |
563 | ||
564 | ;; Return TRUE if this is the condition code register, if we aren't given | |
565 | ;; a mode, accept any CCmode register | |
566 | (define_special_predicate "cc_register" | |
567 | (match_code "reg") | |
568 | { | |
569 | if (mode == VOIDmode) | |
570 | { | |
571 | mode = GET_MODE (op); | |
572 | if (GET_MODE_CLASS (mode) != MODE_CC) | |
573 | return FALSE; | |
574 | } | |
575 | ||
576 | if (mode == GET_MODE (op) && GET_CODE (op) == REG && REGNO (op) == CC_REG) | |
577 | return TRUE; | |
578 | ||
579 | return FALSE; | |
580 | }) | |
581 | ||
582 | ;; Return TRUE if this is the condition code register; if we aren't given | |
583 | ;; a mode, accept any CCmode register. If we are given a mode, accept | |
584 | ;; modes that set a subset of flags. | |
585 | (define_special_predicate "cc_set_register" | |
586 | (match_code "reg") | |
587 | { | |
ef4bddc2 | 588 | machine_mode rmode = GET_MODE (op); |
526b7aee SV |
589 | |
590 | if (mode == VOIDmode) | |
591 | { | |
592 | mode = rmode; | |
593 | if (GET_MODE_CLASS (mode) != MODE_CC) | |
594 | return FALSE; | |
595 | } | |
596 | ||
597 | if (REGNO (op) != 61) | |
598 | return FALSE; | |
599 | if (mode == rmode | |
600 | || (mode == CC_ZNmode && rmode == CC_Zmode) | |
601 | || (mode == CCmode && rmode == CC_Zmode) | |
602 | || (mode == CCmode && rmode == CC_ZNmode) | |
603 | || (mode == CCmode && rmode == CC_Cmode)) | |
604 | return TRUE; | |
605 | ||
606 | return FALSE; | |
607 | }) | |
608 | ||
609 | ; Accept CC_REG in modes which provide the flags needed for MODE. */ | |
610 | (define_special_predicate "cc_use_register" | |
611 | (match_code "reg") | |
612 | { | |
613 | if (REGNO (op) != CC_REG) | |
614 | return 0; | |
615 | if (GET_MODE (op) == mode) | |
616 | return 1; | |
617 | switch (mode) | |
618 | { | |
619 | case CC_Zmode: | |
620 | if (GET_MODE (op) == CC_ZNmode) | |
621 | return 1; | |
622 | /* Fall through. */ | |
623 | case CC_ZNmode: case CC_Cmode: | |
624 | return GET_MODE (op) == CCmode; | |
625 | default: | |
626 | gcc_unreachable (); | |
627 | } | |
628 | }) | |
629 | ||
630 | (define_special_predicate "zn_compare_operator" | |
631 | (match_code "compare") | |
632 | { | |
633 | return GET_MODE (op) == CC_ZNmode || GET_MODE (op) == CC_Zmode; | |
634 | }) | |
635 | ||
636 | ;; Return true if OP is a shift operator. | |
637 | (define_predicate "shift_operator" | |
638 | (match_code "ashiftrt, lshiftrt, ashift") | |
639 | ) | |
640 | ||
641 | ;; Return true if OP is a left shift operator that can be implemented in | |
642 | ;; four insn words or less without a barrel shifter or multiplier. | |
643 | (define_predicate "shiftl4_operator" | |
644 | (and (match_code "ashift") | |
645 | (match_test "const_int_operand (XEXP (op, 1), VOIDmode) ") | |
646 | (match_test "UINTVAL (XEXP (op, 1)) <= 9U | |
647 | || INTVAL (XEXP (op, 1)) == 29 | |
648 | || INTVAL (XEXP (op, 1)) == 30 | |
649 | || INTVAL (XEXP (op, 1)) == 31"))) | |
650 | ||
651 | ;; Return true if OP is a right shift operator that can be implemented in | |
652 | ;; four insn words or less without a barrel shifter or multiplier. | |
653 | (define_predicate "shiftr4_operator" | |
654 | (and (match_code "ashiftrt, lshiftrt") | |
655 | (match_test "const_int_operand (XEXP (op, 1), VOIDmode) ") | |
656 | (match_test "UINTVAL (XEXP (op, 1)) <= 4U | |
657 | || INTVAL (XEXP (op, 1)) == 30 | |
658 | || INTVAL (XEXP (op, 1)) == 31"))) | |
659 | ||
660 | ;; Return true if OP is a shift operator that can be implemented in | |
661 | ;; four insn words or less without a barrel shifter or multiplier. | |
662 | (define_predicate "shift4_operator" | |
663 | (ior (match_operand 0 "shiftl4_operator") | |
664 | (match_operand 0 "shiftr4_operator"))) | |
665 | ||
666 | (define_predicate "mult_operator" | |
667 | (and (match_code "mult") (match_test "TARGET_ARC700 && !TARGET_NOMPY_SET")) | |
668 | ) | |
669 | ||
670 | (define_predicate "commutative_operator" | |
671 | (ior (match_code "plus,ior,xor,and") | |
672 | (match_operand 0 "mult_operator") | |
673 | (and (match_code "ss_plus") | |
674 | (match_test "TARGET_ARC700 || TARGET_EA_SET"))) | |
675 | ) | |
676 | ||
677 | (define_predicate "commutative_operator_sans_mult" | |
678 | (ior (match_code "plus,ior,xor,and") | |
679 | (and (match_code "ss_plus") | |
680 | (match_test "TARGET_ARC700 || TARGET_EA_SET"))) | |
681 | ) | |
682 | ||
683 | (define_predicate "noncommutative_operator" | |
684 | (ior (match_code "minus,ashift,ashiftrt,lshiftrt,rotatert") | |
685 | (and (match_code "ss_minus") | |
686 | (match_test "TARGET_ARC700 || TARGET_EA_SET"))) | |
687 | ) | |
688 | ||
689 | (define_predicate "unary_operator" | |
690 | (ior (match_code "abs,neg,not,sign_extend,zero_extend") | |
691 | (and (ior (match_code "ss_neg") | |
692 | (and (match_code "ss_truncate") | |
693 | (match_test "GET_MODE (XEXP (op, 0)) == HImode"))) | |
694 | (match_test "TARGET_ARC700 || TARGET_EA_SET"))) | |
695 | ) | |
696 | ||
697 | (define_predicate "_2_4_8_operand" | |
698 | (and (match_code "const_int") | |
699 | (match_test "INTVAL (op) == 2 || INTVAL (op) == 4 || INTVAL (op) == 8")) | |
700 | ) | |
701 | ||
702 | (define_predicate "arc_double_register_operand" | |
703 | (match_code "reg") | |
704 | { | |
705 | if ((GET_MODE (op) != mode) && (mode != VOIDmode)) | |
706 | return 0; | |
707 | ||
708 | return (GET_CODE (op) == REG | |
709 | && (REGNO (op) >= FIRST_PSEUDO_REGISTER | |
710 | || REGNO_REG_CLASS (REGNO (op)) == DOUBLE_REGS)); | |
711 | }) | |
712 | ||
713 | (define_predicate "shouldbe_register_operand" | |
714 | (match_code "reg,subreg,mem") | |
715 | { | |
716 | return ((reload_in_progress || reload_completed) | |
717 | ? general_operand : register_operand) (op, mode); | |
718 | }) | |
719 | ||
720 | (define_predicate "vector_register_operand" | |
721 | (match_code "reg") | |
722 | { | |
723 | if ((GET_MODE (op) != mode) && (mode != VOIDmode)) | |
724 | return 0; | |
725 | ||
726 | return (GET_CODE (op) == REG | |
727 | && (REGNO (op) >= FIRST_PSEUDO_REGISTER | |
728 | || REGNO_REG_CLASS (REGNO (op)) == SIMD_VR_REGS)); | |
729 | }) | |
730 | ||
731 | (define_predicate "vector_register_or_memory_operand" | |
732 | ( ior (match_code "reg") | |
733 | (match_code "mem")) | |
734 | { | |
735 | if ((GET_MODE (op) != mode) && (mode != VOIDmode)) | |
736 | return 0; | |
737 | ||
738 | if ((GET_CODE (op) == MEM) | |
739 | && (mode == V8HImode) | |
740 | && GET_CODE (XEXP (op,0)) == REG) | |
741 | return 1; | |
742 | ||
743 | return (GET_CODE (op) == REG | |
744 | && (REGNO (op) >= FIRST_PSEUDO_REGISTER | |
745 | || REGNO_REG_CLASS (REGNO (op)) == SIMD_VR_REGS)); | |
746 | }) | |
747 | ||
748 | (define_predicate "arc_dpfp_operator" | |
749 | (match_code "plus, mult,minus") | |
750 | ) | |
751 | ||
752 | (define_predicate "arc_simd_dma_register_operand" | |
753 | (match_code "reg") | |
754 | { | |
755 | if ((GET_MODE (op) != mode) && (mode != VOIDmode)) | |
756 | return 0; | |
757 | ||
758 | return (GET_CODE (op) == REG | |
759 | && (REGNO (op) >= FIRST_PSEUDO_REGISTER | |
760 | || REGNO_REG_CLASS (REGNO (op)) == SIMD_DMA_CONFIG_REGS)); | |
761 | }) | |
762 | ||
763 | (define_predicate "acc1_operand" | |
764 | (and (match_code "reg") | |
765 | (match_test "REGNO (op) == (TARGET_BIG_ENDIAN ? 56 : 57)"))) | |
766 | ||
767 | (define_predicate "acc2_operand" | |
768 | (and (match_code "reg") | |
769 | (match_test "REGNO (op) == (TARGET_BIG_ENDIAN ? 57 : 56)"))) | |
770 | ||
771 | (define_predicate "mlo_operand" | |
772 | (and (match_code "reg") | |
773 | (match_test "REGNO (op) == (TARGET_BIG_ENDIAN ? 59 : 58)"))) | |
774 | ||
775 | (define_predicate "mhi_operand" | |
776 | (and (match_code "reg") | |
777 | (match_test "REGNO (op) == (TARGET_BIG_ENDIAN ? 58 : 59)"))) | |
778 | ||
167ba5b9 JR |
779 | ; Unfortunately, we can not allow a const_int_operand before reload, because |
780 | ; reload needs a non-void mode to guide it how to reload the inside of a | |
781 | ; {sign_}extend. | |
526b7aee | 782 | (define_predicate "extend_operand" |
167ba5b9 JR |
783 | (ior (match_operand 0 "register_operand") |
784 | (and (match_operand 0 "immediate_operand") | |
785 | (ior (not (match_operand 0 "const_int_operand")) | |
786 | (match_test "reload_in_progress || reload_completed"))))) | |
526b7aee SV |
787 | |
788 | (define_predicate "millicode_store_operation" | |
789 | (match_code "parallel") | |
790 | { | |
791 | return arc_check_millicode (op, 0, 0); | |
792 | }) | |
793 | ||
794 | (define_predicate "millicode_load_operation" | |
795 | (match_code "parallel") | |
796 | { | |
797 | return arc_check_millicode (op, 2, 2); | |
798 | }) | |
799 | ||
800 | (define_predicate "millicode_load_clob_operation" | |
801 | (match_code "parallel") | |
802 | { | |
803 | return arc_check_millicode (op, 0, 1); | |
804 | }) | |
805 | ||
806 | (define_special_predicate "immediate_usidi_operand" | |
807 | (if_then_else | |
808 | (match_code "const_int") | |
809 | (match_test "INTVAL (op) >= 0") | |
810 | (and (match_test "const_double_operand (op, mode)") | |
811 | (match_test "CONST_DOUBLE_HIGH (op) == 0")))) |