Mercurial > hg > CbC > CbC_gcc
comparison gcc/config/h8300/predicates.md @ 0:a06113de4d67
first commit
author | kent <kent@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 17 Jul 2009 14:47:48 +0900 |
parents | |
children | b7f97abdc517 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:a06113de4d67 |
---|---|
1 ;; Predicate definitions for Renesas H8/300. | |
2 ;; Copyright (C) 2005, 2007 Free Software Foundation, Inc. | |
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 ;; Return true if OP is a valid source operand for an integer move | |
21 ;; instruction. | |
22 | |
23 (define_predicate "general_operand_src" | |
24 (match_code "const_int,const_double,const,symbol_ref,label_ref,subreg,reg,mem") | |
25 { | |
26 if (GET_MODE (op) == mode | |
27 && GET_CODE (op) == MEM | |
28 && GET_CODE (XEXP (op, 0)) == POST_INC) | |
29 return 1; | |
30 return general_operand (op, mode); | |
31 }) | |
32 | |
33 ;; Return true if OP is a valid destination operand for an integer | |
34 ;; move instruction. | |
35 | |
36 (define_predicate "general_operand_dst" | |
37 (match_code "subreg,reg,mem") | |
38 { | |
39 if (GET_MODE (op) == mode | |
40 && GET_CODE (op) == MEM | |
41 && GET_CODE (XEXP (op, 0)) == PRE_DEC) | |
42 return 1; | |
43 return general_operand (op, mode); | |
44 }) | |
45 | |
46 ;; Likewise the second operand. | |
47 | |
48 (define_predicate "h8300_src_operand" | |
49 (match_code "const_int,const_double,const,symbol_ref,label_ref,subreg,reg,mem") | |
50 { | |
51 if (TARGET_H8300SX) | |
52 return general_operand (op, mode); | |
53 return nonmemory_operand (op, mode); | |
54 }) | |
55 | |
56 ;; Return true if OP is a suitable first operand for a general | |
57 ;; arithmetic insn such as "add". | |
58 | |
59 (define_predicate "h8300_dst_operand" | |
60 (match_code "subreg,reg,mem") | |
61 { | |
62 if (TARGET_H8300SX) | |
63 return nonimmediate_operand (op, mode); | |
64 return register_operand (op, mode); | |
65 }) | |
66 | |
67 ;; Check that an operand is either a register or an unsigned 4-bit | |
68 ;; constant. | |
69 | |
70 (define_predicate "nibble_operand" | |
71 (match_code "const_int") | |
72 { | |
73 return (GET_CODE (op) == CONST_INT && TARGET_H8300SX | |
74 && INTVAL (op) >= 0 && INTVAL (op) <= 15); | |
75 }) | |
76 | |
77 ;; Check that an operand is either a register or an unsigned 4-bit | |
78 ;; constant. | |
79 | |
80 (define_predicate "reg_or_nibble_operand" | |
81 (match_code "const_int,subreg,reg") | |
82 { | |
83 return (nibble_operand (op, mode) || register_operand (op, mode)); | |
84 }) | |
85 | |
86 ;; Return true if X is a shift operation of type H8SX_SHIFT_UNARY. | |
87 | |
88 (define_predicate "h8sx_unary_shift_operator" | |
89 (match_code "ashiftrt,lshiftrt,ashift,rotate") | |
90 { | |
91 return (BINARY_P (op) && NON_COMMUTATIVE_P (op) | |
92 && (h8sx_classify_shift (GET_MODE (op), GET_CODE (op), XEXP (op, 1)) | |
93 == H8SX_SHIFT_UNARY)); | |
94 }) | |
95 | |
96 ;; Likewise H8SX_SHIFT_BINARY. | |
97 | |
98 (define_predicate "h8sx_binary_shift_operator" | |
99 (match_code "ashiftrt,lshiftrt,ashift") | |
100 { | |
101 return (BINARY_P (op) && NON_COMMUTATIVE_P (op) | |
102 && (h8sx_classify_shift (GET_MODE (op), GET_CODE (op), XEXP (op, 1)) | |
103 == H8SX_SHIFT_BINARY)); | |
104 }) | |
105 | |
106 ;; Return true if OP is a binary operator in which it would be safe to | |
107 ;; replace register operands with memory operands. | |
108 | |
109 (define_predicate "h8sx_binary_memory_operator" | |
110 (match_code "plus,minus,and,ior,xor,ashift,ashiftrt,lshiftrt,rotate") | |
111 { | |
112 if (!TARGET_H8300SX) | |
113 return false; | |
114 | |
115 if (GET_MODE (op) != QImode | |
116 && GET_MODE (op) != HImode | |
117 && GET_MODE (op) != SImode) | |
118 return false; | |
119 | |
120 switch (GET_CODE (op)) | |
121 { | |
122 case PLUS: | |
123 case MINUS: | |
124 case AND: | |
125 case IOR: | |
126 case XOR: | |
127 return true; | |
128 | |
129 default: | |
130 return h8sx_unary_shift_operator (op, mode); | |
131 } | |
132 }) | |
133 | |
134 ;; Like h8sx_binary_memory_operator, but applies to unary operators. | |
135 | |
136 (define_predicate "h8sx_unary_memory_operator" | |
137 (match_code "neg,not") | |
138 { | |
139 if (!TARGET_H8300SX) | |
140 return false; | |
141 | |
142 if (GET_MODE (op) != QImode | |
143 && GET_MODE (op) != HImode | |
144 && GET_MODE (op) != SImode) | |
145 return false; | |
146 | |
147 switch (GET_CODE (op)) | |
148 { | |
149 case NEG: | |
150 case NOT: | |
151 return true; | |
152 | |
153 default: | |
154 return false; | |
155 } | |
156 }) | |
157 | |
158 ;; Return true if X is an ldm.l pattern. X is known to be parallel. | |
159 | |
160 (define_predicate "h8300_ldm_parallel" | |
161 (match_code "parallel") | |
162 { | |
163 return h8300_ldm_stm_parallel (XVEC (op, 0), 1, 0); | |
164 }) | |
165 | |
166 ;; Likewise stm.l. | |
167 | |
168 (define_predicate "h8300_stm_parallel" | |
169 (match_code "parallel") | |
170 { | |
171 return h8300_ldm_stm_parallel (XVEC (op, 0), 0, 0); | |
172 }) | |
173 | |
174 ;; Likewise rts/l and rte/l. Note that the .md pattern will check for | |
175 ;; the return so there's no need to do that here. | |
176 | |
177 (define_predicate "h8300_return_parallel" | |
178 (match_code "parallel") | |
179 { | |
180 return h8300_ldm_stm_parallel (XVEC (op, 0), 1, 1); | |
181 }) | |
182 | |
183 ;; Return true if OP is a constant that contains only one 1 in its | |
184 ;; binary representation. | |
185 | |
186 (define_predicate "single_one_operand" | |
187 (match_code "const_int") | |
188 { | |
189 if (GET_CODE (op) == CONST_INT) | |
190 { | |
191 /* We really need to do this masking because 0x80 in QImode is | |
192 represented as -128 for example. */ | |
193 if (exact_log2 (INTVAL (op) & GET_MODE_MASK (mode)) >= 0) | |
194 return 1; | |
195 } | |
196 | |
197 return 0; | |
198 }) | |
199 | |
200 ;; Return true if OP is a constant that contains only one 0 in its | |
201 ;; binary representation. | |
202 | |
203 (define_predicate "single_zero_operand" | |
204 (match_code "const_int") | |
205 { | |
206 if (GET_CODE (op) == CONST_INT) | |
207 { | |
208 /* We really need to do this masking because 0x80 in QImode is | |
209 represented as -128 for example. */ | |
210 if (exact_log2 (~INTVAL (op) & GET_MODE_MASK (mode)) >= 0) | |
211 return 1; | |
212 } | |
213 | |
214 return 0; | |
215 }) | |
216 | |
217 ;; Return true if OP is a valid call operand. | |
218 | |
219 (define_predicate "call_insn_operand" | |
220 (match_code "mem") | |
221 { | |
222 if (GET_CODE (op) == MEM) | |
223 { | |
224 rtx inside = XEXP (op, 0); | |
225 if (register_operand (inside, Pmode)) | |
226 return 1; | |
227 if (CONSTANT_ADDRESS_P (inside)) | |
228 return 1; | |
229 } | |
230 return 0; | |
231 }) | |
232 | |
233 ;; Return true if OP is a valid call operand, and OP represents an | |
234 ;; operand for a small call (4 bytes instead of 6 bytes). | |
235 | |
236 (define_predicate "small_call_insn_operand" | |
237 (match_code "mem") | |
238 { | |
239 if (GET_CODE (op) == MEM) | |
240 { | |
241 rtx inside = XEXP (op, 0); | |
242 | |
243 /* Register indirect is a small call. */ | |
244 if (register_operand (inside, Pmode)) | |
245 return 1; | |
246 | |
247 /* A call through the function vector is a small call too. */ | |
248 if (GET_CODE (inside) == SYMBOL_REF | |
249 && (SYMBOL_REF_FLAGS (inside) & SYMBOL_FLAG_FUNCVEC_FUNCTION)) | |
250 return 1; | |
251 } | |
252 /* Otherwise it's a large call. */ | |
253 return 0; | |
254 }) | |
255 | |
256 ;; Return true if OP is a valid jump operand. | |
257 | |
258 (define_predicate "jump_address_operand" | |
259 (match_code "reg,mem") | |
260 { | |
261 if (GET_CODE (op) == REG) | |
262 return mode == Pmode; | |
263 | |
264 if (GET_CODE (op) == MEM) | |
265 { | |
266 rtx inside = XEXP (op, 0); | |
267 if (register_operand (inside, Pmode)) | |
268 return 1; | |
269 if (CONSTANT_ADDRESS_P (inside)) | |
270 return 1; | |
271 } | |
272 return 0; | |
273 }) | |
274 | |
275 ;; Return 1 if an addition/subtraction of a constant integer can be | |
276 ;; transformed into two consecutive adds/subs that are faster than the | |
277 ;; straightforward way. Otherwise, return 0. | |
278 | |
279 (define_predicate "two_insn_adds_subs_operand" | |
280 (match_code "const_int") | |
281 { | |
282 if (TARGET_H8300SX) | |
283 return 0; | |
284 | |
285 if (GET_CODE (op) == CONST_INT) | |
286 { | |
287 HOST_WIDE_INT value = INTVAL (op); | |
288 | |
289 /* Force VALUE to be positive so that we do not have to consider | |
290 the negative case. */ | |
291 if (value < 0) | |
292 value = -value; | |
293 if (TARGET_H8300H || TARGET_H8300S) | |
294 { | |
295 /* A constant addition/subtraction takes 2 states in QImode, | |
296 4 states in HImode, and 6 states in SImode. Thus, the | |
297 only case we can win is when SImode is used, in which | |
298 case, two adds/subs are used, taking 4 states. */ | |
299 if (mode == SImode | |
300 && (value == 2 + 1 | |
301 || value == 4 + 1 | |
302 || value == 4 + 2 | |
303 || value == 4 + 4)) | |
304 return 1; | |
305 } | |
306 else | |
307 { | |
308 /* We do not profit directly by splitting addition or | |
309 subtraction of 3 and 4. However, since these are | |
310 implemented as a sequence of adds or subs, they do not | |
311 clobber (cc0) unlike a sequence of add.b and add.x. */ | |
312 if (mode == HImode | |
313 && (value == 2 + 1 | |
314 || value == 2 + 2)) | |
315 return 1; | |
316 } | |
317 } | |
318 | |
319 return 0; | |
320 }) | |
321 | |
322 ;; Recognize valid operands for bit-field instructions. | |
323 | |
324 (define_predicate "bit_operand" | |
325 (match_code "reg,subreg,mem") | |
326 { | |
327 /* We can accept any nonimmediate operand, except that MEM operands must | |
328 be limited to those that use addresses valid for the 'U' constraint. */ | |
329 if (!nonimmediate_operand (op, mode)) | |
330 return 0; | |
331 | |
332 /* H8SX accepts pretty much anything here. */ | |
333 if (TARGET_H8300SX) | |
334 return 1; | |
335 | |
336 /* Accept any mem during RTL generation. Otherwise, the code that does | |
337 insv and extzv will think that we cannot handle memory. However, | |
338 to avoid reload problems, we only accept 'U' MEM operands after RTL | |
339 generation. This means that any named pattern which uses this predicate | |
340 must force its operands to match 'U' before emitting RTL. */ | |
341 | |
342 if (GET_CODE (op) == REG) | |
343 return 1; | |
344 if (GET_CODE (op) == SUBREG) | |
345 return 1; | |
346 return (GET_CODE (op) == MEM | |
347 && OK_FOR_U (op)); | |
348 }) | |
349 | |
350 ;; Return nonzero if OP is a MEM suitable for bit manipulation insns. | |
351 | |
352 (define_predicate "bit_memory_operand" | |
353 (match_code "mem") | |
354 { | |
355 return (GET_CODE (op) == MEM | |
356 && OK_FOR_U (op)); | |
357 }) | |
358 | |
359 ;; Return nonzero if X is a stack pointer. | |
360 | |
361 (define_predicate "stack_pointer_operand" | |
362 (match_code "reg") | |
363 { | |
364 return op == stack_pointer_rtx; | |
365 }) | |
366 | |
367 ;; Return nonzero if X is a constant whose absolute value is greater | |
368 ;; than 2. | |
369 | |
370 (define_predicate "const_int_gt_2_operand" | |
371 (match_code "const_int") | |
372 { | |
373 return (GET_CODE (op) == CONST_INT | |
374 && abs (INTVAL (op)) > 2); | |
375 }) | |
376 | |
377 ;; Return nonzero if X is a constant whose absolute value is no | |
378 ;; smaller than 8. | |
379 | |
380 (define_predicate "const_int_ge_8_operand" | |
381 (match_code "const_int") | |
382 { | |
383 return (GET_CODE (op) == CONST_INT | |
384 && abs (INTVAL (op)) >= 8); | |
385 }) | |
386 | |
387 ;; Return nonzero if X is a constant expressible in QImode. | |
388 | |
389 (define_predicate "const_int_qi_operand" | |
390 (match_code "const_int") | |
391 { | |
392 return (GET_CODE (op) == CONST_INT | |
393 && (INTVAL (op) & 0xff) == INTVAL (op)); | |
394 }) | |
395 | |
396 ;; Return nonzero if X is a constant expressible in HImode. | |
397 | |
398 (define_predicate "const_int_hi_operand" | |
399 (match_code "const_int") | |
400 { | |
401 return (GET_CODE (op) == CONST_INT | |
402 && (INTVAL (op) & 0xffff) == INTVAL (op)); | |
403 }) | |
404 | |
405 ;; Return nonzero if X is a constant suitable for inc/dec. | |
406 | |
407 (define_predicate "incdec_operand" | |
408 (match_code "const_int") | |
409 { | |
410 return (GET_CODE (op) == CONST_INT | |
411 && (CONST_OK_FOR_M (INTVAL (op)) | |
412 || CONST_OK_FOR_O (INTVAL (op)))); | |
413 }) | |
414 | |
415 ;; Recognize valid operators for bit instructions. | |
416 | |
417 (define_predicate "bit_operator" | |
418 (match_code "xor,and,ior") | |
419 { | |
420 enum rtx_code code = GET_CODE (op); | |
421 | |
422 return (code == XOR | |
423 || code == AND | |
424 || code == IOR); | |
425 }) | |
426 | |
427 ;; Return nonzero if OP is a shift operator. | |
428 | |
429 (define_predicate "nshift_operator" | |
430 (match_code "ashiftrt,lshiftrt,ashift") | |
431 { | |
432 switch (GET_CODE (op)) | |
433 { | |
434 case ASHIFTRT: | |
435 case LSHIFTRT: | |
436 case ASHIFT: | |
437 return 1; | |
438 | |
439 default: | |
440 return 0; | |
441 } | |
442 }) | |
443 | |
444 ;; Return nonzero if X is either EQ or NE. | |
445 | |
446 (define_predicate "eqne_operator" | |
447 (match_code "eq,ne") | |
448 { | |
449 enum rtx_code code = GET_CODE (op); | |
450 | |
451 return (code == EQ || code == NE); | |
452 }) | |
453 | |
454 ;; Return nonzero if X is either GT or LE. | |
455 | |
456 (define_predicate "gtle_operator" | |
457 (match_code "gt,le,gtu,leu") | |
458 { | |
459 enum rtx_code code = GET_CODE (op); | |
460 | |
461 return (code == GT || code == LE); | |
462 }) | |
463 | |
464 ;; Return nonzero if X is either GTU or LEU. | |
465 | |
466 (define_predicate "gtuleu_operator" | |
467 (match_code "gtu,leu") | |
468 { | |
469 enum rtx_code code = GET_CODE (op); | |
470 | |
471 return (code == GTU || code == LEU); | |
472 }) | |
473 | |
474 ;; Return nonzero if X is either IOR or XOR. | |
475 | |
476 (define_predicate "iorxor_operator" | |
477 (match_code "ior,xor") | |
478 { | |
479 enum rtx_code code = GET_CODE (op); | |
480 | |
481 return (code == IOR || code == XOR); | |
482 }) |