Mercurial > hg > CbC > CbC_gcc
annotate gcc/config/sh/predicates.md @ 55:77e2b8dfacca gcc-4.4.5
update it from 4.4.3 to 4.5.0
author | ryoma <e075725@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 12 Feb 2010 23:39:51 +0900 |
parents | a06113de4d67 |
children | b7f97abdc517 |
rev | line source |
---|---|
0 | 1 ;; Predicate definitions for Renesas / SuperH SH. |
2 ;; Copyright (C) 2005, 2006, 2007, 2008, 2009 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 ;; TODO: Add a comment here. | |
21 | |
22 (define_predicate "trapping_target_operand" | |
23 (match_code "if_then_else") | |
24 { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
25 rtx cond, mem, res, tar, and_expr; |
0 | 26 |
27 if (GET_MODE (op) != PDImode) | |
28 return 0; | |
29 cond = XEXP (op, 0); | |
30 mem = XEXP (op, 1); | |
31 res = XEXP (op, 2); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
32 if (!MEM_P (mem) |
0 | 33 || (GET_CODE (res) != SIGN_EXTEND && GET_CODE (res) != TRUNCATE)) |
34 return 0; | |
35 tar = XEXP (res, 0); | |
36 if (!rtx_equal_p (XEXP (mem, 0), tar) | |
37 || GET_MODE (tar) != Pmode) | |
38 return 0; | |
39 if (GET_CODE (cond) == CONST) | |
40 { | |
41 cond = XEXP (cond, 0); | |
42 if (!satisfies_constraint_Csy (tar)) | |
43 return 0; | |
44 if (GET_CODE (tar) == CONST) | |
45 tar = XEXP (tar, 0); | |
46 } | |
47 else if (!arith_reg_operand (tar, VOIDmode) | |
48 && ! satisfies_constraint_Csy (tar)) | |
49 return 0; | |
50 if (GET_CODE (cond) != EQ) | |
51 return 0; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
52 and_expr = XEXP (cond, 0); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
53 return (GET_CODE (and_expr) == AND |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
54 && rtx_equal_p (XEXP (and_expr, 0), tar) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
55 && CONST_INT_P (XEXP (and_expr, 1)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
56 && CONST_INT_P (XEXP (cond, 1)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
57 && INTVAL (XEXP (and_expr, 1)) == 3 |
0 | 58 && INTVAL (XEXP (cond, 1)) == 3); |
59 }) | |
60 | |
61 ;; TODO: Add a comment here. | |
62 | |
63 (define_predicate "and_operand" | |
64 (match_code "subreg,reg,const_int") | |
65 { | |
66 if (logical_operand (op, mode)) | |
67 return 1; | |
68 | |
69 /* Check mshflo.l / mshflhi.l opportunities. */ | |
70 if (TARGET_SHMEDIA | |
71 && mode == DImode | |
72 && satisfies_constraint_J16 (op)) | |
73 return 1; | |
74 | |
75 return 0; | |
76 }) | |
77 | |
78 ;; Like arith_reg_dest, but this predicate is defined with | |
79 ;; define_special_predicate, not define_predicate. | |
80 | |
81 (define_special_predicate "any_arith_reg_dest" | |
82 (match_code "subreg,reg") | |
83 { | |
84 return arith_reg_dest (op, mode); | |
85 }) | |
86 | |
87 ;; Like register_operand, but this predicate is defined with | |
88 ;; define_special_predicate, not define_predicate. | |
89 | |
90 (define_special_predicate "any_register_operand" | |
91 (match_code "subreg,reg") | |
92 { | |
93 return register_operand (op, mode); | |
94 }) | |
95 | |
96 ;; Returns 1 if OP is a valid source operand for an arithmetic insn. | |
97 | |
98 (define_predicate "arith_operand" | |
99 (match_code "subreg,reg,const_int,truncate") | |
100 { | |
101 if (arith_reg_operand (op, mode)) | |
102 return 1; | |
103 | |
104 if (TARGET_SHMEDIA) | |
105 { | |
106 /* FIXME: We should be checking whether the CONST_INT fits in a | |
107 signed 16-bit here, but this causes reload_cse to crash when | |
108 attempting to transform a sequence of two 64-bit sets of the | |
109 same register from literal constants into a set and an add, | |
110 when the difference is too wide for an add. */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
111 if (CONST_INT_P (op) |
0 | 112 || satisfies_constraint_Css (op)) |
113 return 1; | |
114 else if (GET_CODE (op) == TRUNCATE | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
115 && REG_P (XEXP (op, 0)) |
0 | 116 && ! system_reg_operand (XEXP (op, 0), VOIDmode) |
117 && (mode == VOIDmode || mode == GET_MODE (op)) | |
118 && (GET_MODE_SIZE (GET_MODE (op)) | |
119 < GET_MODE_SIZE (GET_MODE (XEXP (op, 0)))) | |
120 && (! FP_REGISTER_P (REGNO (XEXP (op, 0))) | |
121 || GET_MODE_SIZE (GET_MODE (op)) == 4)) | |
122 return register_operand (XEXP (op, 0), VOIDmode); | |
123 else | |
124 return 0; | |
125 } | |
126 else if (satisfies_constraint_I08 (op)) | |
127 return 1; | |
128 | |
129 return 0; | |
130 }) | |
131 | |
132 ;; Like above, but for DImode destinations: forbid paradoxical DImode | |
133 ;; subregs, because this would lead to missing sign extensions when | |
134 ;; truncating from DImode to SImode. | |
135 | |
136 (define_predicate "arith_reg_dest" | |
137 (match_code "subreg,reg") | |
138 { | |
139 if (mode == DImode && GET_CODE (op) == SUBREG | |
140 && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) < 8 | |
141 && TARGET_SHMEDIA) | |
142 return 0; | |
143 return arith_reg_operand (op, mode); | |
144 }) | |
145 | |
146 ;; Returns 1 if OP is a normal arithmetic register. | |
147 | |
148 (define_predicate "arith_reg_operand" | |
149 (match_code "subreg,reg,sign_extend") | |
150 { | |
151 if (register_operand (op, mode)) | |
152 { | |
153 int regno; | |
154 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
155 if (REG_P (op)) |
0 | 156 regno = REGNO (op); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
157 else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op))) |
0 | 158 regno = REGNO (SUBREG_REG (op)); |
159 else | |
160 return 1; | |
161 | |
162 return (regno != T_REG && regno != PR_REG | |
163 && ! TARGET_REGISTER_P (regno) | |
164 && (regno != FPUL_REG || TARGET_SH4) | |
165 && regno != MACH_REG && regno != MACL_REG); | |
166 } | |
167 /* Allow a no-op sign extension - compare LOAD_EXTEND_OP. | |
168 We allow SImode here, as not using an FP register is just a matter of | |
169 proper register allocation. */ | |
170 if (TARGET_SHMEDIA | |
171 && GET_MODE (op) == DImode && GET_CODE (op) == SIGN_EXTEND | |
172 && GET_MODE (XEXP (op, 0)) == SImode | |
173 && GET_CODE (XEXP (op, 0)) != SUBREG) | |
174 return register_operand (XEXP (op, 0), VOIDmode); | |
175 #if 0 /* Can't do this because of PROMOTE_MODE for unsigned vars. */ | |
176 if (GET_MODE (op) == SImode && GET_CODE (op) == SIGN_EXTEND | |
177 && GET_MODE (XEXP (op, 0)) == HImode | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
178 && REG_P (XEXP (op, 0)) |
0 | 179 && REGNO (XEXP (op, 0)) <= LAST_GENERAL_REG) |
180 return register_operand (XEXP (op, 0), VOIDmode); | |
181 #endif | |
182 if (GET_MODE_CLASS (GET_MODE (op)) == MODE_VECTOR_INT | |
183 && GET_CODE (op) == SUBREG | |
184 && GET_MODE (SUBREG_REG (op)) == DImode | |
185 && GET_CODE (SUBREG_REG (op)) == SIGN_EXTEND | |
186 && GET_MODE (XEXP (SUBREG_REG (op), 0)) == SImode | |
187 && GET_CODE (XEXP (SUBREG_REG (op), 0)) != SUBREG) | |
188 return register_operand (XEXP (SUBREG_REG (op), 0), VOIDmode); | |
189 return 0; | |
190 }) | |
191 | |
192 ;; Returns 1 if OP is a valid source operand for a compare insn. | |
193 | |
194 (define_predicate "arith_reg_or_0_operand" | |
195 (match_code "subreg,reg,const_int,const_vector") | |
196 { | |
197 if (arith_reg_operand (op, mode)) | |
198 return 1; | |
199 | |
200 if (satisfies_constraint_Z (op)) | |
201 return 1; | |
202 | |
203 return 0; | |
204 }) | |
205 | |
206 ;; TODO: Add a comment here. | |
207 | |
208 (define_predicate "binary_float_operator" | |
209 (and (match_code "plus,minus,mult,div") | |
210 (match_test "GET_MODE (op) == mode"))) | |
211 | |
212 ;; TODO: Add a comment here. | |
213 | |
214 (define_predicate "binary_logical_operator" | |
215 (and (match_code "and,ior,xor") | |
216 (match_test "GET_MODE (op) == mode"))) | |
217 | |
218 ;; Return 1 of OP is an address suitable for a cache manipulation operation. | |
219 ;; MODE has the meaning as in address_operand. | |
220 | |
221 (define_special_predicate "cache_address_operand" | |
222 (match_code "plus,reg") | |
223 { | |
224 if (GET_CODE (op) == PLUS) | |
225 { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
226 if (!REG_P (XEXP (op, 0))) |
0 | 227 return 0; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
228 if (!CONST_INT_P (XEXP (op, 1)) |
0 | 229 || (INTVAL (XEXP (op, 1)) & 31)) |
230 return 0; | |
231 } | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
232 else if (!REG_P (op)) |
0 | 233 return 0; |
234 return address_operand (op, mode); | |
235 }) | |
236 | |
237 ;; Return 1 if OP is a valid source operand for shmedia cmpgt / cmpgtu. | |
238 | |
239 (define_predicate "cmp_operand" | |
240 (match_code "subreg,reg,const_int") | |
241 { | |
242 if (satisfies_constraint_N (op)) | |
243 return 1; | |
244 if (TARGET_SHMEDIA | |
245 && mode != DImode && GET_CODE (op) == SUBREG | |
246 && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) > 4) | |
247 return 0; | |
248 return arith_reg_operand (op, mode); | |
249 }) | |
250 | |
251 ;; TODO: Add a comment here. | |
252 | |
253 (define_predicate "cmpsi_operand" | |
254 (match_code "subreg,reg,const_int") | |
255 { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
256 if (REG_P (op) && REGNO (op) == T_REG |
0 | 257 && GET_MODE (op) == SImode |
258 && TARGET_SH1) | |
259 return 1; | |
260 return arith_operand (op, mode); | |
261 }) | |
262 | |
263 ;; TODO: Add a comment here. | |
264 | |
265 (define_predicate "commutative_float_operator" | |
266 (and (match_code "plus,mult") | |
267 (match_test "GET_MODE (op) == mode"))) | |
268 | |
269 ;; TODO: Add a comment here. | |
270 | |
271 (define_predicate "equality_comparison_operator" | |
272 (match_code "eq,ne")) | |
273 | |
274 ;; TODO: Add a comment here. | |
275 | |
276 (define_predicate "extend_reg_operand" | |
277 (match_code "subreg,reg,truncate") | |
278 { | |
279 return (GET_CODE (op) == TRUNCATE | |
280 ? arith_operand | |
281 : arith_reg_operand) (op, mode); | |
282 }) | |
283 | |
284 ;; TODO: Add a comment here. | |
285 | |
286 (define_predicate "extend_reg_or_0_operand" | |
287 (match_code "subreg,reg,truncate,const_int") | |
288 { | |
289 return (GET_CODE (op) == TRUNCATE | |
290 ? arith_operand | |
291 : arith_reg_or_0_operand) (op, mode); | |
292 }) | |
293 | |
294 ;; Like arith_reg_operand, but this predicate does not accept SIGN_EXTEND. | |
295 | |
296 (define_predicate "ext_dest_operand" | |
297 (match_code "subreg,reg") | |
298 { | |
299 return arith_reg_operand (op, mode); | |
300 }) | |
301 | |
302 ;; TODO: Add a comment here. | |
303 | |
304 (define_predicate "fp_arith_reg_dest" | |
305 (match_code "subreg,reg") | |
306 { | |
307 if (mode == DImode && GET_CODE (op) == SUBREG | |
308 && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) < 8) | |
309 return 0; | |
310 return fp_arith_reg_operand (op, mode); | |
311 }) | |
312 | |
313 ;; TODO: Add a comment here. | |
314 | |
315 (define_predicate "fp_arith_reg_operand" | |
316 (match_code "subreg,reg") | |
317 { | |
318 if (register_operand (op, mode)) | |
319 { | |
320 int regno; | |
321 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
322 if (REG_P (op)) |
0 | 323 regno = REGNO (op); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
324 else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op))) |
0 | 325 regno = REGNO (SUBREG_REG (op)); |
326 else | |
327 return 1; | |
328 | |
329 return (regno >= FIRST_PSEUDO_REGISTER | |
330 || FP_REGISTER_P (regno)); | |
331 } | |
332 return 0; | |
333 }) | |
334 | |
335 ;; TODO: Add a comment here. | |
336 | |
337 (define_predicate "fpscr_operand" | |
338 (match_code "reg") | |
339 { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
340 return (REG_P (op) |
0 | 341 && (REGNO (op) == FPSCR_REG |
342 || (REGNO (op) >= FIRST_PSEUDO_REGISTER | |
343 && !(reload_in_progress || reload_completed))) | |
344 && GET_MODE (op) == PSImode); | |
345 }) | |
346 | |
347 ;; TODO: Add a comment here. | |
348 | |
349 (define_predicate "fpul_operand" | |
350 (match_code "reg") | |
351 { | |
352 if (TARGET_SHMEDIA) | |
353 return fp_arith_reg_operand (op, mode); | |
354 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
355 return (REG_P (op) |
0 | 356 && (REGNO (op) == FPUL_REG || REGNO (op) >= FIRST_PSEUDO_REGISTER) |
357 && GET_MODE (op) == mode); | |
358 }) | |
359 | |
360 ;; TODO: Add a comment here. | |
361 | |
362 (define_predicate "general_extend_operand" | |
363 (match_code "subreg,reg,mem,truncate") | |
364 { | |
365 return (GET_CODE (op) == TRUNCATE | |
366 ? arith_operand | |
367 : nonimmediate_operand) (op, mode); | |
368 }) | |
369 | |
370 ;; Returns 1 if OP can be source of a simple move operation. Same as | |
371 ;; general_operand, but a LABEL_REF is valid, PRE_DEC is invalid as | |
372 ;; are subregs of system registers. | |
373 | |
374 (define_predicate "general_movsrc_operand" | |
375 (match_code "subreg,reg,const_int,const_double,mem,symbol_ref,label_ref,const,const_vector") | |
376 { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
377 if (MEM_P (op)) |
0 | 378 { |
379 rtx inside = XEXP (op, 0); | |
380 if (GET_CODE (inside) == CONST) | |
381 inside = XEXP (inside, 0); | |
382 | |
383 if (GET_CODE (inside) == LABEL_REF) | |
384 return 1; | |
385 | |
386 if (GET_CODE (inside) == PLUS | |
387 && GET_CODE (XEXP (inside, 0)) == LABEL_REF | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
388 && CONST_INT_P (XEXP (inside, 1))) |
0 | 389 return 1; |
390 | |
391 /* Only post inc allowed. */ | |
392 if (GET_CODE (inside) == PRE_DEC) | |
393 return 0; | |
394 } | |
395 | |
396 if (TARGET_SHMEDIA | |
397 && (GET_CODE (op) == PARALLEL || GET_CODE (op) == CONST_VECTOR) | |
398 && sh_rep_vec (op, mode)) | |
399 return 1; | |
400 if (TARGET_SHMEDIA && 1 | |
401 && GET_CODE (op) == SUBREG && GET_MODE (op) == mode | |
402 && SUBREG_REG (op) == const0_rtx && subreg_lowpart_p (op)) | |
403 /* FIXME */ abort (); /* return 1; */ | |
404 return general_operand (op, mode); | |
405 }) | |
406 | |
407 ;; Returns 1 if OP can be a destination of a move. Same as | |
408 ;; general_operand, but no preinc allowed. | |
409 | |
410 (define_predicate "general_movdst_operand" | |
411 (match_code "subreg,reg,mem") | |
412 { | |
413 /* Only pre dec allowed. */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
414 if (MEM_P (op) && GET_CODE (XEXP (op, 0)) == POST_INC) |
0 | 415 return 0; |
416 if (mode == DImode && TARGET_SHMEDIA && GET_CODE (op) == SUBREG | |
417 && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) < 8 | |
418 && ! (high_life_started || reload_completed)) | |
419 return 0; | |
420 | |
421 return general_operand (op, mode); | |
422 }) | |
423 | |
424 ;; Returns 1 if OP is a MEM that can be source of a simple move operation. | |
425 | |
426 (define_predicate "unaligned_load_operand" | |
427 (match_code "mem") | |
428 { | |
429 rtx inside; | |
430 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
431 if (!MEM_P (op) || GET_MODE (op) != mode) |
0 | 432 return 0; |
433 | |
434 inside = XEXP (op, 0); | |
435 | |
436 if (GET_CODE (inside) == POST_INC) | |
437 inside = XEXP (inside, 0); | |
438 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
439 if (REG_P (inside)) |
0 | 440 return 1; |
441 | |
442 return 0; | |
443 }) | |
444 | |
445 ;; TODO: Add a comment here. | |
446 | |
447 (define_predicate "greater_comparison_operator" | |
448 (match_code "gt,ge,gtu,geu")) | |
449 | |
450 ;; TODO: Add a comment here. | |
451 | |
452 (define_predicate "inqhi_operand" | |
453 (match_code "truncate") | |
454 { | |
455 if (GET_CODE (op) != TRUNCATE || mode != GET_MODE (op)) | |
456 return 0; | |
457 op = XEXP (op, 0); | |
458 /* Can't use true_regnum here because copy_cost wants to know about | |
459 SECONDARY_INPUT_RELOAD_CLASS. */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
460 return REG_P (op) && FP_REGISTER_P (REGNO (op)); |
0 | 461 }) |
462 | |
463 ;; TODO: Add a comment here. | |
464 | |
465 (define_special_predicate "int_gpr_dest" | |
466 (match_code "subreg,reg") | |
467 { | |
468 enum machine_mode op_mode = GET_MODE (op); | |
469 | |
470 if (GET_MODE_CLASS (op_mode) != MODE_INT | |
471 || GET_MODE_SIZE (op_mode) >= UNITS_PER_WORD) | |
472 return 0; | |
473 if (! reload_completed) | |
474 return 0; | |
475 return true_regnum (op) <= LAST_GENERAL_REG; | |
476 }) | |
477 | |
478 ;; TODO: Add a comment here. | |
479 | |
480 (define_predicate "less_comparison_operator" | |
481 (match_code "lt,le,ltu,leu")) | |
482 | |
483 ;; Returns 1 if OP is a valid source operand for a logical operation. | |
484 | |
485 (define_predicate "logical_operand" | |
486 (match_code "subreg,reg,const_int") | |
487 { | |
488 if (TARGET_SHMEDIA | |
489 && mode != DImode && GET_CODE (op) == SUBREG | |
490 && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) > 4) | |
491 return 0; | |
492 | |
493 if (arith_reg_operand (op, mode)) | |
494 return 1; | |
495 | |
496 if (TARGET_SHMEDIA) | |
497 { | |
498 if (satisfies_constraint_I10 (op)) | |
499 return 1; | |
500 else | |
501 return 0; | |
502 } | |
503 else if (satisfies_constraint_K08 (op)) | |
504 return 1; | |
505 | |
506 return 0; | |
507 }) | |
508 | |
509 ;; TODO: Add a comment here. | |
510 | |
511 (define_predicate "logical_operator" | |
512 (match_code "and,ior,xor")) | |
513 | |
514 ;; Like arith_reg_operand, but for register source operands of narrow | |
515 ;; logical SHMEDIA operations: forbid subregs of DImode / TImode regs. | |
516 | |
517 (define_predicate "logical_reg_operand" | |
518 (match_code "subreg,reg") | |
519 { | |
520 if (TARGET_SHMEDIA | |
521 && GET_CODE (op) == SUBREG | |
522 && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) > 4 | |
523 && mode != DImode) | |
524 return 0; | |
525 return arith_reg_operand (op, mode); | |
526 }) | |
527 | |
528 ;; TODO: Add a comment here. | |
529 | |
530 (define_predicate "mextr_bit_offset" | |
531 (match_code "const_int") | |
532 { | |
533 HOST_WIDE_INT i; | |
534 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
535 if (!CONST_INT_P (op)) |
0 | 536 return 0; |
537 i = INTVAL (op); | |
538 return i >= 1 * 8 && i <= 7 * 8 && (i & 7) == 0; | |
539 }) | |
540 | |
541 ;; TODO: Add a comment here. | |
542 | |
543 (define_predicate "minuend_operand" | |
544 (match_code "subreg,reg,truncate,const_int") | |
545 { | |
546 return op == constm1_rtx || extend_reg_or_0_operand (op, mode); | |
547 }) | |
548 | |
549 ;; TODO: Add a comment here. | |
550 | |
551 (define_predicate "noncommutative_float_operator" | |
552 (and (match_code "minus,div") | |
553 (match_test "GET_MODE (op) == mode"))) | |
554 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
555 ;; UNORDERED is only supported on SHMEDIA. |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
556 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
557 (define_predicate "sh_float_comparison_operator" |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
558 (ior (match_operand 0 "ordered_comparison_operator") |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
559 (and (match_test "TARGET_SHMEDIA") |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
560 (match_code "unordered")))) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
561 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
562 (define_predicate "shmedia_cbranch_comparison_operator" |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
563 (ior (match_operand 0 "equality_comparison_operator") |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
564 (match_operand 0 "greater_comparison_operator"))) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
565 |
0 | 566 ;; TODO: Add a comment here. |
567 | |
568 (define_predicate "sh_const_vec" | |
569 (match_code "const_vector") | |
570 { | |
571 int i; | |
572 | |
573 if (GET_CODE (op) != CONST_VECTOR | |
574 || (GET_MODE (op) != mode && mode != VOIDmode)) | |
575 return 0; | |
576 i = XVECLEN (op, 0) - 1; | |
577 for (; i >= 0; i--) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
578 if (!CONST_INT_P (XVECEXP (op, 0, i))) |
0 | 579 return 0; |
580 return 1; | |
581 }) | |
582 | |
583 ;; Determine if OP is a constant vector matching MODE with only one | |
584 ;; element that is not a sign extension. Two byte-sized elements | |
585 ;; count as one. | |
586 | |
587 (define_predicate "sh_1el_vec" | |
588 (match_code "const_vector") | |
589 { | |
590 int unit_size; | |
591 int i, last, least, sign_ix; | |
592 rtx sign; | |
593 | |
594 if (GET_CODE (op) != CONST_VECTOR | |
595 || (GET_MODE (op) != mode && mode != VOIDmode)) | |
596 return 0; | |
597 /* Determine numbers of last and of least significant elements. */ | |
598 last = XVECLEN (op, 0) - 1; | |
599 least = TARGET_LITTLE_ENDIAN ? 0 : last; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
600 if (!CONST_INT_P (XVECEXP (op, 0, least))) |
0 | 601 return 0; |
602 sign_ix = least; | |
603 if (GET_MODE_UNIT_SIZE (mode) == 1) | |
604 sign_ix = TARGET_LITTLE_ENDIAN ? 1 : last - 1; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
605 if (!CONST_INT_P (XVECEXP (op, 0, sign_ix))) |
0 | 606 return 0; |
607 unit_size = GET_MODE_UNIT_SIZE (GET_MODE (op)); | |
608 sign = (INTVAL (XVECEXP (op, 0, sign_ix)) >> (unit_size * BITS_PER_UNIT - 1) | |
609 ? constm1_rtx : const0_rtx); | |
610 i = XVECLEN (op, 0) - 1; | |
611 do | |
612 if (i != least && i != sign_ix && XVECEXP (op, 0, i) != sign) | |
613 return 0; | |
614 while (--i); | |
615 return 1; | |
616 }) | |
617 | |
618 ;; Like register_operand, but take into account that SHMEDIA can use | |
619 ;; the constant zero like a general register. | |
620 | |
621 (define_predicate "sh_register_operand" | |
622 (match_code "reg,subreg,const_int,const_double") | |
623 { | |
624 if (op == CONST0_RTX (mode) && TARGET_SHMEDIA) | |
625 return 1; | |
626 return register_operand (op, mode); | |
627 }) | |
628 | |
629 ;; TODO: Add a comment here. | |
630 | |
631 (define_predicate "sh_rep_vec" | |
632 (match_code "const_vector,parallel") | |
633 { | |
634 int i; | |
635 rtx x, y; | |
636 | |
637 if ((GET_CODE (op) != CONST_VECTOR && GET_CODE (op) != PARALLEL) | |
638 || (GET_MODE (op) != mode && mode != VOIDmode)) | |
639 return 0; | |
640 i = XVECLEN (op, 0) - 2; | |
641 x = XVECEXP (op, 0, i + 1); | |
642 if (GET_MODE_UNIT_SIZE (mode) == 1) | |
643 { | |
644 y = XVECEXP (op, 0, i); | |
645 for (i -= 2; i >= 0; i -= 2) | |
646 if (! rtx_equal_p (XVECEXP (op, 0, i + 1), x) | |
647 || ! rtx_equal_p (XVECEXP (op, 0, i), y)) | |
648 return 0; | |
649 } | |
650 else | |
651 for (; i >= 0; i--) | |
652 if (XVECEXP (op, 0, i) != x) | |
653 return 0; | |
654 return 1; | |
655 }) | |
656 | |
657 ;; TODO: Add a comment here. | |
658 | |
659 (define_predicate "shift_count_operand" | |
660 (match_code "const_int,const_double,const,symbol_ref,label_ref,subreg,reg,zero_extend,sign_extend") | |
661 { | |
662 return (CONSTANT_P (op) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
663 ? (CONST_INT_P (op) |
0 | 664 ? (unsigned) INTVAL (op) < GET_MODE_BITSIZE (mode) |
665 : nonmemory_operand (op, mode)) | |
666 : shift_count_reg_operand (op, mode)); | |
667 }) | |
668 | |
669 ;; TODO: Add a comment here. | |
670 | |
671 (define_predicate "shift_count_reg_operand" | |
672 (match_code "subreg,reg,zero_extend,sign_extend") | |
673 { | |
674 if ((GET_CODE (op) == ZERO_EXTEND || GET_CODE (op) == SIGN_EXTEND | |
675 || (GET_CODE (op) == SUBREG && SUBREG_BYTE (op) == 0)) | |
676 && (mode == VOIDmode || mode == GET_MODE (op)) | |
677 && GET_MODE_BITSIZE (GET_MODE (XEXP (op, 0))) >= 6 | |
678 && GET_MODE_CLASS (GET_MODE (XEXP (op, 0))) == MODE_INT) | |
679 { | |
680 mode = VOIDmode; | |
681 do | |
682 op = XEXP (op, 0); | |
683 while ((GET_CODE (op) == ZERO_EXTEND || GET_CODE (op) == SIGN_EXTEND | |
684 || GET_CODE (op) == TRUNCATE) | |
685 && GET_MODE_BITSIZE (GET_MODE (XEXP (op, 0))) >= 6 | |
686 && GET_MODE_CLASS (GET_MODE (XEXP (op, 0))) == MODE_INT); | |
687 | |
688 } | |
689 return arith_reg_operand (op, mode); | |
690 }) | |
691 | |
692 ;; TODO: Add a comment here. | |
693 | |
694 (define_predicate "shift_operator" | |
695 (match_code "ashift,ashiftrt,lshiftrt")) | |
696 | |
697 ;; TODO: Add a comment here. | |
698 | |
699 (define_predicate "symbol_ref_operand" | |
700 (match_code "symbol_ref")) | |
701 | |
702 ;; Same as target_reg_operand, except that label_refs and symbol_refs | |
703 ;; are accepted before reload. | |
704 | |
705 (define_special_predicate "target_operand" | |
706 (match_code "subreg,reg,label_ref,symbol_ref,const,unspec") | |
707 { | |
708 if (mode != VOIDmode && mode != Pmode) | |
709 return 0; | |
710 | |
711 if ((GET_MODE (op) == Pmode || GET_MODE (op) == VOIDmode) | |
712 && satisfies_constraint_Csy (op)) | |
713 return ! reload_completed; | |
714 | |
715 return target_reg_operand (op, mode); | |
716 }) | |
717 | |
718 ;; Accept pseudos and branch target registers. | |
719 | |
720 (define_special_predicate "target_reg_operand" | |
721 (match_code "subreg,reg") | |
722 { | |
723 if (mode == VOIDmode | |
724 ? GET_MODE (op) != Pmode && GET_MODE (op) != PDImode | |
725 : mode != GET_MODE (op)) | |
726 return 0; | |
727 | |
728 if (GET_CODE (op) == SUBREG) | |
729 op = XEXP (op, 0); | |
730 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
731 if (!REG_P (op)) |
0 | 732 return 0; |
733 | |
734 /* We must protect ourselves from matching pseudos that are virtual | |
735 register, because they will eventually be replaced with hardware | |
736 registers that aren't branch-target registers. */ | |
737 if (REGNO (op) > LAST_VIRTUAL_REGISTER | |
738 || TARGET_REGISTER_P (REGNO (op))) | |
739 return 1; | |
740 | |
741 return 0; | |
742 }) | |
743 | |
744 ;; TODO: Add a comment here. | |
745 | |
746 (define_special_predicate "trunc_hi_operand" | |
747 (match_code "subreg,reg,truncate") | |
748 { | |
749 enum machine_mode op_mode = GET_MODE (op); | |
750 | |
751 if (op_mode != SImode && op_mode != DImode | |
752 && op_mode != V4HImode && op_mode != V2SImode) | |
753 return 0; | |
754 return extend_reg_operand (op, mode); | |
755 }) | |
756 | |
757 ;; Return 1 of OP is an address suitable for an unaligned access instruction. | |
758 | |
759 (define_special_predicate "ua_address_operand" | |
760 (match_code "subreg,reg,plus") | |
761 { | |
762 if (GET_CODE (op) == PLUS | |
763 && (! satisfies_constraint_I06 (XEXP (op, 1)))) | |
764 return 0; | |
765 return address_operand (op, QImode); | |
766 }) | |
767 | |
768 ;; TODO: Add a comment here. | |
769 | |
770 (define_predicate "ua_offset" | |
771 (match_code "const_int") | |
772 { | |
773 return satisfies_constraint_I06 (op); | |
774 }) | |
775 | |
776 ;; TODO: Add a comment here. | |
777 | |
778 (define_predicate "unary_float_operator" | |
779 (and (match_code "abs,neg,sqrt") | |
780 (match_test "GET_MODE (op) == mode"))) | |
781 | |
782 ;; Return 1 if OP is a valid source operand for xor. | |
783 | |
784 (define_predicate "xor_operand" | |
785 (match_code "subreg,reg,const_int") | |
786 { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
787 if (CONST_INT_P (op)) |
0 | 788 return (TARGET_SHMEDIA |
789 ? (satisfies_constraint_I06 (op) | |
790 || (!can_create_pseudo_p () && INTVAL (op) == 0xff)) | |
791 : satisfies_constraint_K08 (op)); | |
792 if (TARGET_SHMEDIA | |
793 && mode != DImode && GET_CODE (op) == SUBREG | |
794 && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) > 4) | |
795 return 0; | |
796 return arith_reg_operand (op, mode); | |
797 }) | |
798 | |
799 (define_predicate "bitwise_memory_operand" | |
800 (match_code "mem") | |
801 { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
802 if (MEM_P (op)) |
0 | 803 { |
804 if (REG_P (XEXP (op, 0))) | |
805 return 1; | |
806 | |
807 if (GET_CODE (XEXP (op, 0)) == PLUS | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
808 && REG_P (XEXP (XEXP (op, 0), 0)) |
0 | 809 && satisfies_constraint_K12 (XEXP (XEXP (op, 0), 1))) |
810 return 1; | |
811 } | |
812 return 0; | |
813 }) |