]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/m32r/predicates.md
Update copyright years.
[thirdparty/gcc.git] / gcc / config / m32r / predicates.md
CommitLineData
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})