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