Mercurial > hg > CbC > CbC_gcc
annotate gcc/config/rs6000/predicates.md @ 111:04ced10e8804
gcc 7
author | kono |
---|---|
date | Fri, 27 Oct 2017 22:46:09 +0900 |
parents | f6334be47118 |
children | 84e7813d76e9 |
rev | line source |
---|---|
0 | 1 ;; Predicate definitions for POWER and PowerPC. |
111 | 2 ;; Copyright (C) 2005-2017 Free Software Foundation, Inc. |
0 | 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 1 for anything except PARALLEL. | |
21 (define_predicate "any_operand" | |
111 | 22 (match_code "const_int,const_double,const_wide_int,const,symbol_ref,label_ref,subreg,reg,mem")) |
0 | 23 |
24 ;; Return 1 for any PARALLEL. | |
25 (define_predicate "any_parallel_operand" | |
26 (match_code "parallel")) | |
27 | |
28 ;; Return 1 if op is COUNT register. | |
29 (define_predicate "count_register_operand" | |
30 (and (match_code "reg") | |
31 (match_test "REGNO (op) == CTR_REGNO | |
32 || REGNO (op) > LAST_VIRTUAL_REGISTER"))) | |
111 | 33 |
34 ;; Return 1 if op is a SUBREG that is used to look at a SFmode value as | |
35 ;; and integer or vice versa. | |
36 ;; | |
37 ;; In the normal case where SFmode is in a floating point/vector register, it | |
38 ;; is stored as a DFmode and has a different format. If we don't transform the | |
39 ;; value, things that use logical operations on the values will get the wrong | |
40 ;; value. | |
41 ;; | |
42 ;; If we don't have 64-bit and direct move, this conversion will be done by | |
43 ;; store and load, instead of by fiddling with the bits within the register. | |
44 (define_predicate "sf_subreg_operand" | |
45 (match_code "subreg") | |
46 { | |
47 rtx inner_reg = SUBREG_REG (op); | |
48 machine_mode inner_mode = GET_MODE (inner_reg); | |
49 | |
50 if (TARGET_ALLOW_SF_SUBREG || !REG_P (inner_reg)) | |
51 return 0; | |
52 | |
53 if ((mode == SFmode && GET_MODE_CLASS (inner_mode) == MODE_INT) | |
54 || (GET_MODE_CLASS (mode) == MODE_INT && inner_mode == SFmode)) | |
55 { | |
56 if (INT_REGNO_P (REGNO (inner_reg))) | |
57 return 0; | |
58 | |
59 return 1; | |
60 } | |
61 return 0; | |
62 }) | |
63 | |
0 | 64 ;; Return 1 if op is an Altivec register. |
65 (define_predicate "altivec_register_operand" | |
111 | 66 (match_operand 0 "register_operand") |
67 { | |
68 if (GET_CODE (op) == SUBREG) | |
69 { | |
70 if (TARGET_NO_SF_SUBREG && sf_subreg_operand (op, mode)) | |
71 return 0; | |
72 | |
73 op = SUBREG_REG (op); | |
74 } | |
75 | |
76 if (!REG_P (op)) | |
77 return 0; | |
78 | |
79 if (REGNO (op) >= FIRST_PSEUDO_REGISTER) | |
80 return 1; | |
81 | |
82 return ALTIVEC_REGNO_P (REGNO (op)); | |
83 }) | |
0 | 84 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
85 ;; Return 1 if op is a VSX register. |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
86 (define_predicate "vsx_register_operand" |
111 | 87 (match_operand 0 "register_operand") |
88 { | |
89 if (GET_CODE (op) == SUBREG) | |
90 { | |
91 if (TARGET_NO_SF_SUBREG && sf_subreg_operand (op, mode)) | |
92 return 0; | |
93 | |
94 op = SUBREG_REG (op); | |
95 } | |
96 | |
97 if (!REG_P (op)) | |
98 return 0; | |
99 | |
100 if (REGNO (op) >= FIRST_PSEUDO_REGISTER) | |
101 return 1; | |
102 | |
103 return VSX_REGNO_P (REGNO (op)); | |
104 }) | |
105 | |
106 ;; Like vsx_register_operand, but allow SF SUBREGS | |
107 (define_predicate "vsx_reg_sfsubreg_ok" | |
108 (match_operand 0 "register_operand") | |
109 { | |
110 if (GET_CODE (op) == SUBREG) | |
111 op = SUBREG_REG (op); | |
112 | |
113 if (!REG_P (op)) | |
114 return 0; | |
115 | |
116 if (REGNO (op) >= FIRST_PSEUDO_REGISTER) | |
117 return 1; | |
118 | |
119 return VSX_REGNO_P (REGNO (op)); | |
120 }) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
121 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
122 ;; Return 1 if op is a vector register that operates on floating point vectors |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
123 ;; (either altivec or VSX). |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
124 (define_predicate "vfloat_operand" |
111 | 125 (match_operand 0 "register_operand") |
126 { | |
127 if (GET_CODE (op) == SUBREG) | |
128 { | |
129 if (TARGET_NO_SF_SUBREG && sf_subreg_operand (op, mode)) | |
130 return 0; | |
131 | |
132 op = SUBREG_REG (op); | |
133 } | |
134 | |
135 if (!REG_P (op)) | |
136 return 0; | |
137 | |
138 if (REGNO (op) >= FIRST_PSEUDO_REGISTER) | |
139 return 1; | |
140 | |
141 return VFLOAT_REGNO_P (REGNO (op)); | |
142 }) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
143 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
144 ;; Return 1 if op is a vector register that operates on integer vectors |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
145 ;; (only altivec, VSX doesn't support integer vectors) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
146 (define_predicate "vint_operand" |
111 | 147 (match_operand 0 "register_operand") |
148 { | |
149 if (GET_CODE (op) == SUBREG) | |
150 { | |
151 if (TARGET_NO_SF_SUBREG && sf_subreg_operand (op, mode)) | |
152 return 0; | |
153 | |
154 op = SUBREG_REG (op); | |
155 } | |
156 | |
157 if (!REG_P (op)) | |
158 return 0; | |
159 | |
160 if (REGNO (op) >= FIRST_PSEUDO_REGISTER) | |
161 return 1; | |
162 | |
163 return VINT_REGNO_P (REGNO (op)); | |
164 }) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
165 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
166 ;; Return 1 if op is a vector register to do logical operations on (and, or, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
167 ;; xor, etc.) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
168 (define_predicate "vlogical_operand" |
111 | 169 (match_operand 0 "register_operand") |
170 { | |
171 if (GET_CODE (op) == SUBREG) | |
172 { | |
173 if (TARGET_NO_SF_SUBREG && sf_subreg_operand (op, mode)) | |
174 return 0; | |
175 | |
176 op = SUBREG_REG (op); | |
177 } | |
178 | |
179 | |
180 if (!REG_P (op)) | |
181 return 0; | |
182 | |
183 if (REGNO (op) >= FIRST_PSEUDO_REGISTER) | |
184 return 1; | |
185 | |
186 return VLOGICAL_REGNO_P (REGNO (op)); | |
187 }) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
188 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
189 ;; Return 1 if op is the carry register. |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
190 (define_predicate "ca_operand" |
111 | 191 (match_operand 0 "register_operand") |
192 { | |
193 if (GET_CODE (op) == SUBREG) | |
194 op = SUBREG_REG (op); | |
195 | |
196 if (!REG_P (op)) | |
197 return 0; | |
198 | |
199 return CA_REGNO_P (REGNO (op)); | |
200 }) | |
201 | |
202 ;; Return 1 if operand is constant zero (scalars and vectors). | |
203 (define_predicate "zero_constant" | |
204 (and (match_code "const_int,const_double,const_wide_int,const_vector") | |
205 (match_test "op == CONST0_RTX (mode)"))) | |
206 | |
207 ;; Return 1 if operand is constant -1 (scalars and vectors). | |
208 (define_predicate "all_ones_constant" | |
209 (and (match_code "const_int,const_double,const_wide_int,const_vector") | |
210 (match_test "op == CONSTM1_RTX (mode) && !FLOAT_MODE_P (mode)"))) | |
0 | 211 |
212 ;; Return 1 if op is a signed 5-bit constant integer. | |
213 (define_predicate "s5bit_cint_operand" | |
214 (and (match_code "const_int") | |
215 (match_test "INTVAL (op) >= -16 && INTVAL (op) <= 15"))) | |
216 | |
111 | 217 ;; Return 1 if op is a unsigned 3-bit constant integer. |
218 (define_predicate "u3bit_cint_operand" | |
219 (and (match_code "const_int") | |
220 (match_test "INTVAL (op) >= 0 && INTVAL (op) <= 7"))) | |
221 | |
0 | 222 ;; Return 1 if op is a unsigned 5-bit constant integer. |
223 (define_predicate "u5bit_cint_operand" | |
224 (and (match_code "const_int") | |
225 (match_test "INTVAL (op) >= 0 && INTVAL (op) <= 31"))) | |
226 | |
111 | 227 ;; Return 1 if op is a unsigned 6-bit constant integer. |
228 (define_predicate "u6bit_cint_operand" | |
229 (and (match_code "const_int") | |
230 (match_test "INTVAL (op) >= 0 && INTVAL (op) <= 63"))) | |
231 | |
232 ;; Return 1 if op is an unsigned 7-bit constant integer. | |
233 (define_predicate "u7bit_cint_operand" | |
234 (and (match_code "const_int") | |
235 (match_test "IN_RANGE (INTVAL (op), 0, 127)"))) | |
236 | |
0 | 237 ;; Return 1 if op is a signed 8-bit constant integer. |
238 ;; Integer multiplication complete more quickly | |
239 (define_predicate "s8bit_cint_operand" | |
240 (and (match_code "const_int") | |
241 (match_test "INTVAL (op) >= -128 && INTVAL (op) <= 127"))) | |
242 | |
111 | 243 ;; Return 1 if op is a unsigned 10-bit constant integer. |
244 (define_predicate "u10bit_cint_operand" | |
245 (and (match_code "const_int") | |
246 (match_test "INTVAL (op) >= 0 && INTVAL (op) <= 1023"))) | |
247 | |
0 | 248 ;; Return 1 if op is a constant integer that can fit in a D field. |
249 (define_predicate "short_cint_operand" | |
250 (and (match_code "const_int") | |
251 (match_test "satisfies_constraint_I (op)"))) | |
252 | |
253 ;; Return 1 if op is a constant integer that can fit in an unsigned D field. | |
254 (define_predicate "u_short_cint_operand" | |
255 (and (match_code "const_int") | |
256 (match_test "satisfies_constraint_K (op)"))) | |
257 | |
111 | 258 ;; Return 1 if op is a constant integer that is a signed 16-bit constant |
259 ;; shifted left 16 bits | |
260 (define_predicate "upper16_cint_operand" | |
261 (and (match_code "const_int") | |
262 (match_test "satisfies_constraint_L (op)"))) | |
263 | |
0 | 264 ;; Return 1 if op is a constant integer that cannot fit in a signed D field. |
265 (define_predicate "non_short_cint_operand" | |
266 (and (match_code "const_int") | |
267 (match_test "(unsigned HOST_WIDE_INT) | |
268 (INTVAL (op) + 0x8000) >= 0x10000"))) | |
269 | |
270 ;; Return 1 if op is a positive constant integer that is an exact power of 2. | |
271 (define_predicate "exact_log2_cint_operand" | |
272 (and (match_code "const_int") | |
273 (match_test "INTVAL (op) > 0 && exact_log2 (INTVAL (op)) >= 0"))) | |
274 | |
111 | 275 ;; Match op = 0 or op = 1. |
276 (define_predicate "const_0_to_1_operand" | |
277 (and (match_code "const_int") | |
278 (match_test "IN_RANGE (INTVAL (op), 0, 1)"))) | |
279 | |
280 ;; Match op = 0..3. | |
281 (define_predicate "const_0_to_3_operand" | |
282 (and (match_code "const_int") | |
283 (match_test "IN_RANGE (INTVAL (op), 0, 3)"))) | |
284 | |
285 ;; Match op = 2 or op = 3. | |
286 (define_predicate "const_2_to_3_operand" | |
287 (and (match_code "const_int") | |
288 (match_test "IN_RANGE (INTVAL (op), 2, 3)"))) | |
289 | |
290 ;; Match op = 0..7. | |
291 (define_predicate "const_0_to_7_operand" | |
292 (and (match_code "const_int") | |
293 (match_test "IN_RANGE (INTVAL (op), 0, 7)"))) | |
294 | |
295 ;; Match op = 0..11 | |
296 (define_predicate "const_0_to_12_operand" | |
297 (and (match_code "const_int") | |
298 (match_test "IN_RANGE (INTVAL (op), 0, 12)"))) | |
299 | |
300 ;; Match op = 0..15 | |
301 (define_predicate "const_0_to_15_operand" | |
302 (and (match_code "const_int") | |
303 (match_test "IN_RANGE (INTVAL (op), 0, 15)"))) | |
304 | |
0 | 305 ;; Return 1 if op is a register that is not special. |
111 | 306 ;; Disallow (SUBREG:SF (REG:SI)) and (SUBREG:SI (REG:SF)) on VSX systems where |
307 ;; you need to be careful in moving a SFmode to SImode and vice versa due to | |
308 ;; the fact that SFmode is represented as DFmode in the VSX registers. | |
0 | 309 (define_predicate "gpc_reg_operand" |
111 | 310 (match_operand 0 "register_operand") |
311 { | |
312 if (GET_CODE (op) == SUBREG) | |
313 { | |
314 if (TARGET_NO_SF_SUBREG && sf_subreg_operand (op, mode)) | |
315 return 0; | |
316 | |
317 op = SUBREG_REG (op); | |
318 } | |
319 | |
320 if (!REG_P (op)) | |
321 return 0; | |
322 | |
323 if (REGNO (op) >= FIRST_PSEUDO_REGISTER) | |
324 return 1; | |
325 | |
326 if (TARGET_ALTIVEC && ALTIVEC_REGNO_P (REGNO (op))) | |
327 return 1; | |
328 | |
329 if (TARGET_VSX && VSX_REGNO_P (REGNO (op))) | |
330 return 1; | |
331 | |
332 return INT_REGNO_P (REGNO (op)) || FP_REGNO_P (REGNO (op)); | |
333 }) | |
334 | |
335 ;; Return 1 if op is a general purpose register. Unlike gpc_reg_operand, don't | |
336 ;; allow floating point or vector registers. Since vector registers are not | |
337 ;; allowed, we don't have to reject SFmode/SImode subregs. | |
338 (define_predicate "int_reg_operand" | |
339 (match_operand 0 "register_operand") | |
340 { | |
341 if (GET_CODE (op) == SUBREG) | |
342 { | |
343 if (TARGET_NO_SF_SUBREG && sf_subreg_operand (op, mode)) | |
344 return 0; | |
345 | |
346 op = SUBREG_REG (op); | |
347 } | |
348 | |
349 if (!REG_P (op)) | |
350 return 0; | |
351 | |
352 if (REGNO (op) >= FIRST_PSEUDO_REGISTER) | |
353 return 1; | |
354 | |
355 return INT_REGNO_P (REGNO (op)); | |
356 }) | |
357 | |
358 ;; Like int_reg_operand, but don't return true for pseudo registers | |
359 ;; We don't have to check for SF SUBREGS because pseudo registers | |
360 ;; are not allowed, and SF SUBREGs are ok within GPR registers. | |
361 (define_predicate "int_reg_operand_not_pseudo" | |
362 (match_operand 0 "register_operand") | |
363 { | |
364 if (GET_CODE (op) == SUBREG) | |
365 op = SUBREG_REG (op); | |
366 | |
367 if (!REG_P (op)) | |
368 return 0; | |
369 | |
370 if (REGNO (op) >= FIRST_PSEUDO_REGISTER) | |
371 return 0; | |
372 | |
373 return INT_REGNO_P (REGNO (op)); | |
374 }) | |
375 | |
376 ;; Like int_reg_operand, but only return true for base registers | |
377 (define_predicate "base_reg_operand" | |
378 (match_operand 0 "int_reg_operand") | |
379 { | |
380 if (GET_CODE (op) == SUBREG) | |
381 op = SUBREG_REG (op); | |
382 | |
383 if (!REG_P (op)) | |
384 return 0; | |
385 | |
386 return (REGNO (op) != FIRST_GPR_REGNO); | |
387 }) | |
388 | |
389 | |
390 ;; Return true if this is a traditional floating point register | |
391 (define_predicate "fpr_reg_operand" | |
392 (match_code "reg,subreg") | |
393 { | |
394 HOST_WIDE_INT r; | |
395 | |
396 if (GET_CODE (op) == SUBREG) | |
397 op = SUBREG_REG (op); | |
398 | |
399 if (!REG_P (op)) | |
400 return 0; | |
401 | |
402 r = REGNO (op); | |
403 if (r >= FIRST_PSEUDO_REGISTER) | |
404 return 1; | |
405 | |
406 return FP_REGNO_P (r); | |
407 }) | |
408 | |
409 ;; Return true if this is a register that can has D-form addressing (GPR and | |
410 ;; traditional FPR registers for scalars). ISA 3.0 (power9) adds D-form | |
411 ;; addressing for scalars in Altivec registers. | |
412 ;; | |
413 ;; If this is a pseudo only allow for GPR fusion in power8. If we have the | |
414 ;; power9 fusion allow the floating point types. | |
415 (define_predicate "toc_fusion_or_p9_reg_operand" | |
416 (match_code "reg,subreg") | |
417 { | |
418 HOST_WIDE_INT r; | |
419 bool gpr_p = (mode == QImode || mode == HImode || mode == SImode | |
420 || mode == SFmode | |
421 || (TARGET_POWERPC64 && (mode == DImode || mode == DFmode))); | |
422 bool fpr_p = (TARGET_P9_FUSION | |
423 && (mode == DFmode || mode == SFmode | |
424 || (TARGET_POWERPC64 && mode == DImode))); | |
425 bool vmx_p = (TARGET_P9_FUSION && TARGET_P9_VECTOR | |
426 && (mode == DFmode || mode == SFmode)); | |
427 | |
428 if (!TARGET_P8_FUSION) | |
429 return 0; | |
430 | |
431 if (GET_CODE (op) == SUBREG) | |
432 op = SUBREG_REG (op); | |
433 | |
434 if (!REG_P (op)) | |
435 return 0; | |
436 | |
437 r = REGNO (op); | |
438 if (r >= FIRST_PSEUDO_REGISTER) | |
439 return (gpr_p || fpr_p || vmx_p); | |
440 | |
441 if (INT_REGNO_P (r)) | |
442 return gpr_p; | |
443 | |
444 if (FP_REGNO_P (r)) | |
445 return fpr_p; | |
446 | |
447 if (ALTIVEC_REGNO_P (r)) | |
448 return vmx_p; | |
449 | |
450 return 0; | |
451 }) | |
452 | |
453 ;; Return 1 if op is a HTM specific SPR register. | |
454 (define_predicate "htm_spr_reg_operand" | |
455 (match_operand 0 "register_operand") | |
456 { | |
457 if (!TARGET_HTM) | |
458 return 0; | |
459 | |
460 if (GET_CODE (op) == SUBREG) | |
461 op = SUBREG_REG (op); | |
462 | |
463 if (!REG_P (op)) | |
464 return 0; | |
465 | |
466 switch (REGNO (op)) | |
467 { | |
468 case TFHAR_REGNO: | |
469 case TFIAR_REGNO: | |
470 case TEXASR_REGNO: | |
471 return 1; | |
472 default: | |
473 break; | |
474 } | |
475 | |
476 /* Unknown SPR. */ | |
477 return 0; | |
478 }) | |
479 | |
480 ;; Return 1 if op is a general purpose register that is an even register | |
481 ;; which suitable for a load/store quad operation | |
482 ;; Subregs are not allowed here because when they are combine can | |
483 ;; create (subreg:PTI (reg:TI pseudo)) which will cause reload to | |
484 ;; think the innermost reg needs reloading, in TImode instead of | |
485 ;; PTImode. So reload will choose a reg in TImode which has no | |
486 ;; requirement that the reg be even. | |
487 (define_predicate "quad_int_reg_operand" | |
488 (match_code "reg") | |
489 { | |
490 HOST_WIDE_INT r; | |
491 | |
492 if (!TARGET_QUAD_MEMORY && !TARGET_QUAD_MEMORY_ATOMIC) | |
493 return 0; | |
494 | |
495 r = REGNO (op); | |
496 if (r >= FIRST_PSEUDO_REGISTER) | |
497 return 1; | |
498 | |
499 return (INT_REGNO_P (r) && ((r & 1) == 0)); | |
500 }) | |
0 | 501 |
502 ;; Return 1 if op is a register that is a condition register field. | |
503 (define_predicate "cc_reg_operand" | |
111 | 504 (match_operand 0 "register_operand") |
505 { | |
506 if (GET_CODE (op) == SUBREG) | |
507 op = SUBREG_REG (op); | |
508 | |
509 if (!REG_P (op)) | |
510 return 0; | |
511 | |
512 if (REGNO (op) > LAST_VIRTUAL_REGISTER) | |
513 return 1; | |
514 | |
515 return CR_REGNO_P (REGNO (op)); | |
516 }) | |
0 | 517 |
518 ;; Return 1 if op is a register that is a condition register field not cr0. | |
519 (define_predicate "cc_reg_not_cr0_operand" | |
111 | 520 (match_operand 0 "register_operand") |
521 { | |
522 if (GET_CODE (op) == SUBREG) | |
523 op = SUBREG_REG (op); | |
0 | 524 |
111 | 525 if (!REG_P (op)) |
526 return 0; | |
527 | |
528 if (REGNO (op) > LAST_VIRTUAL_REGISTER) | |
529 return 1; | |
530 | |
531 return CR_REGNO_NOT_CR0_P (REGNO (op)); | |
532 }) | |
0 | 533 |
534 ;; Return 1 if op is a constant integer valid for D field | |
535 ;; or non-special register register. | |
536 (define_predicate "reg_or_short_operand" | |
537 (if_then_else (match_code "const_int") | |
538 (match_operand 0 "short_cint_operand") | |
539 (match_operand 0 "gpc_reg_operand"))) | |
540 | |
541 ;; Return 1 if op is a constant integer valid for DS field | |
542 ;; or non-special register. | |
543 (define_predicate "reg_or_aligned_short_operand" | |
544 (if_then_else (match_code "const_int") | |
545 (and (match_operand 0 "short_cint_operand") | |
546 (match_test "!(INTVAL (op) & 3)")) | |
547 (match_operand 0 "gpc_reg_operand"))) | |
548 | |
549 ;; Return 1 if op is a constant integer whose high-order 16 bits are zero | |
550 ;; or non-special register. | |
551 (define_predicate "reg_or_u_short_operand" | |
552 (if_then_else (match_code "const_int") | |
553 (match_operand 0 "u_short_cint_operand") | |
554 (match_operand 0 "gpc_reg_operand"))) | |
555 | |
111 | 556 ;; Return 1 if op is any constant integer or a non-special register. |
0 | 557 (define_predicate "reg_or_cint_operand" |
558 (ior (match_code "const_int") | |
559 (match_operand 0 "gpc_reg_operand"))) | |
560 | |
111 | 561 ;; Return 1 if op is constant zero or a non-special register. |
562 (define_predicate "reg_or_zero_operand" | |
563 (ior (match_operand 0 "zero_constant") | |
564 (match_operand 0 "gpc_reg_operand"))) | |
565 | |
566 ;; Return 1 if op is a constant integer valid for addition with addis, addi. | |
567 (define_predicate "add_cint_operand" | |
568 (and (match_code "const_int") | |
569 (match_test "((unsigned HOST_WIDE_INT) INTVAL (op) | |
570 + (mode == SImode ? 0x80000000 : 0x80008000)) | |
571 < (unsigned HOST_WIDE_INT) 0x100000000ll"))) | |
572 | |
0 | 573 ;; Return 1 if op is a constant integer valid for addition |
574 ;; or non-special register. | |
575 (define_predicate "reg_or_add_cint_operand" | |
576 (if_then_else (match_code "const_int") | |
111 | 577 (match_operand 0 "add_cint_operand") |
0 | 578 (match_operand 0 "gpc_reg_operand"))) |
579 | |
580 ;; Return 1 if op is a constant integer valid for subtraction | |
581 ;; or non-special register. | |
582 (define_predicate "reg_or_sub_cint_operand" | |
583 (if_then_else (match_code "const_int") | |
111 | 584 (match_test "(unsigned HOST_WIDE_INT) |
585 (- UINTVAL (op) + (mode == SImode ? 0x80000000 : 0x80008000)) | |
586 < (unsigned HOST_WIDE_INT) 0x100000000ll") | |
0 | 587 (match_operand 0 "gpc_reg_operand"))) |
588 | |
589 ;; Return 1 if op is any 32-bit unsigned constant integer | |
590 ;; or non-special register. | |
591 (define_predicate "reg_or_logical_cint_operand" | |
592 (if_then_else (match_code "const_int") | |
593 (match_test "(GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT | |
594 && INTVAL (op) >= 0) | |
595 || ((INTVAL (op) & GET_MODE_MASK (mode) | |
596 & (~ (unsigned HOST_WIDE_INT) 0xffffffff)) == 0)") | |
111 | 597 (match_operand 0 "gpc_reg_operand"))) |
598 | |
599 ;; Like reg_or_logical_cint_operand, but allow vsx registers | |
600 (define_predicate "vsx_reg_or_cint_operand" | |
601 (ior (match_operand 0 "vsx_register_operand") | |
602 (match_operand 0 "reg_or_logical_cint_operand"))) | |
0 | 603 |
604 ;; Return 1 if operand is a CONST_DOUBLE that can be set in a register | |
605 ;; with no more than one instruction per word. | |
606 (define_predicate "easy_fp_constant" | |
607 (match_code "const_double") | |
608 { | |
609 if (GET_MODE (op) != mode | |
610 || (!SCALAR_FLOAT_MODE_P (mode) && mode != DImode)) | |
611 return 0; | |
612 | |
613 /* Consider all constants with -msoft-float to be easy. */ | |
111 | 614 if ((TARGET_SOFT_FLOAT |
0 | 615 || (TARGET_HARD_FLOAT && (TARGET_SINGLE_FLOAT && ! TARGET_DOUBLE_FLOAT))) |
616 && mode != DImode) | |
617 return 1; | |
618 | |
111 | 619 /* 0.0D is not all zero bits. */ |
0 | 620 if (DECIMAL_FLOAT_MODE_P (mode)) |
621 return 0; | |
622 | |
111 | 623 /* The constant 0.0 is easy under VSX. */ |
624 if (TARGET_VSX && SCALAR_FLOAT_MODE_P (mode) && op == CONST0_RTX (mode)) | |
625 return 1; | |
626 | |
0 | 627 /* If we are using V.4 style PIC, consider all constants to be hard. */ |
628 if (flag_pic && DEFAULT_ABI == ABI_V4) | |
629 return 0; | |
630 | |
111 | 631 /* If we have real FPRs, consider floating point constants hard (other than |
632 0.0 under VSX), so that the constant gets pushed to memory during the | |
633 early RTL phases. This has the advantage that double precision constants | |
634 that can be represented in single precision without a loss of precision | |
635 will use single precision loads. */ | |
0 | 636 |
637 switch (mode) | |
638 { | |
111 | 639 case E_KFmode: |
640 case E_IFmode: | |
641 case E_TFmode: | |
642 case E_DFmode: | |
643 case E_SFmode: | |
644 return 0; | |
0 | 645 |
111 | 646 case E_DImode: |
647 return (num_insns_constant (op, DImode) <= 2); | |
0 | 648 |
111 | 649 case E_SImode: |
650 return 1; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
651 |
111 | 652 default: |
653 gcc_unreachable (); | |
654 } | |
655 }) | |
0 | 656 |
111 | 657 ;; Return 1 if the operand is a constant that can loaded with a XXSPLTIB |
658 ;; instruction and then a VUPKHSB, VECSB2W or VECSB2D instruction. | |
0 | 659 |
111 | 660 (define_predicate "xxspltib_constant_split" |
661 (match_code "const_vector,vec_duplicate,const_int") | |
662 { | |
663 int value = 256; | |
664 int num_insns = -1; | |
0 | 665 |
111 | 666 if (!xxspltib_constant_p (op, mode, &num_insns, &value)) |
667 return false; | |
668 | |
669 return num_insns > 1; | |
670 }) | |
671 | |
0 | 672 |
111 | 673 ;; Return 1 if the operand is constant that can loaded directly with a XXSPLTIB |
674 ;; instruction. | |
0 | 675 |
111 | 676 (define_predicate "xxspltib_constant_nosplit" |
677 (match_code "const_vector,vec_duplicate,const_int") | |
678 { | |
679 int value = 256; | |
680 int num_insns = -1; | |
0 | 681 |
111 | 682 if (!xxspltib_constant_p (op, mode, &num_insns, &value)) |
683 return false; | |
0 | 684 |
111 | 685 return num_insns == 1; |
0 | 686 }) |
687 | |
688 ;; Return 1 if the operand is a CONST_VECTOR and can be loaded into a | |
689 ;; vector register without using memory. | |
690 (define_predicate "easy_vector_constant" | |
691 (match_code "const_vector") | |
692 { | |
693 /* As the paired vectors are actually FPRs it seems that there is | |
694 no easy way to load a CONST_VECTOR without using memory. */ | |
695 if (TARGET_PAIRED_FLOAT) | |
696 return false; | |
697 | |
111 | 698 /* Because IEEE 128-bit floating point is considered a vector type |
699 in order to pass it in VSX registers, it might use this function | |
700 instead of easy_fp_constant. */ | |
701 if (FLOAT128_VECTOR_P (mode)) | |
702 return easy_fp_constant (op, mode); | |
703 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
704 if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)) |
0 | 705 { |
111 | 706 int value = 256; |
707 int num_insns = -1; | |
708 | |
709 if (zero_constant (op, mode) || all_ones_constant (op, mode)) | |
710 return true; | |
711 | |
712 if (TARGET_P9_VECTOR | |
713 && xxspltib_constant_p (op, mode, &num_insns, &value)) | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
714 return true; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
715 |
0 | 716 return easy_altivec_constant (op, mode); |
717 } | |
718 | |
719 return false; | |
720 }) | |
721 | |
722 ;; Same as easy_vector_constant but only for EASY_VECTOR_15_ADD_SELF. | |
723 (define_predicate "easy_vector_constant_add_self" | |
724 (and (match_code "const_vector") | |
725 (and (match_test "TARGET_ALTIVEC") | |
726 (match_test "easy_altivec_constant (op, mode)"))) | |
727 { | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
728 HOST_WIDE_INT val; |
111 | 729 int elt; |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
730 if (mode == V2DImode || mode == V2DFmode) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
731 return 0; |
111 | 732 elt = BYTES_BIG_ENDIAN ? GET_MODE_NUNITS (mode) - 1 : 0; |
733 val = const_vector_elt_as_int (op, elt); | |
0 | 734 val = ((val & 0xff) ^ 0x80) - 0x80; |
735 return EASY_VECTOR_15_ADD_SELF (val); | |
736 }) | |
737 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
738 ;; Same as easy_vector_constant but only for EASY_VECTOR_MSB. |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
739 (define_predicate "easy_vector_constant_msb" |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
740 (and (match_code "const_vector") |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
741 (and (match_test "TARGET_ALTIVEC") |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
742 (match_test "easy_altivec_constant (op, mode)"))) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
743 { |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
744 HOST_WIDE_INT val; |
111 | 745 int elt; |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
746 if (mode == V2DImode || mode == V2DFmode) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
747 return 0; |
111 | 748 elt = BYTES_BIG_ENDIAN ? GET_MODE_NUNITS (mode) - 1 : 0; |
749 val = const_vector_elt_as_int (op, elt); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
750 return EASY_VECTOR_MSB (val, GET_MODE_INNER (mode)); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
751 }) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
752 |
111 | 753 ;; Return true if this is an easy altivec constant that we form |
754 ;; by using VSLDOI. | |
755 (define_predicate "easy_vector_constant_vsldoi" | |
756 (and (match_code "const_vector") | |
757 (and (match_test "TARGET_ALTIVEC") | |
758 (and (match_test "easy_altivec_constant (op, mode)") | |
759 (match_test "vspltis_shifted (op) != 0"))))) | |
760 | |
761 ;; Return 1 if operand is a vector int register or is either a vector constant | |
762 ;; of all 0 bits of a vector constant of all 1 bits. | |
763 (define_predicate "vector_int_reg_or_same_bit" | |
764 (match_code "reg,subreg,const_vector") | |
765 { | |
766 if (GET_MODE_CLASS (mode) != MODE_VECTOR_INT) | |
767 return 0; | |
768 | |
769 else if (REG_P (op) || SUBREG_P (op)) | |
770 return vint_operand (op, mode); | |
771 | |
772 else | |
773 return op == CONST0_RTX (mode) || op == CONSTM1_RTX (mode); | |
774 }) | |
0 | 775 |
776 ;; Return 1 if operand is 0.0. | |
777 (define_predicate "zero_fp_constant" | |
778 (and (match_code "const_double") | |
779 (match_test "SCALAR_FLOAT_MODE_P (mode) | |
780 && op == CONST0_RTX (mode)"))) | |
781 | |
782 ;; Return 1 if the operand is in volatile memory. Note that during the | |
783 ;; RTL generation phase, memory_operand does not return TRUE for volatile | |
784 ;; memory references. So this function allows us to recognize volatile | |
785 ;; references where it's safe. | |
786 (define_predicate "volatile_mem_operand" | |
787 (and (and (match_code "mem") | |
788 (match_test "MEM_VOLATILE_P (op)")) | |
789 (if_then_else (match_test "reload_completed") | |
111 | 790 (match_operand 0 "memory_operand") |
791 (match_test "memory_address_p (mode, XEXP (op, 0))")))) | |
0 | 792 |
793 ;; Return 1 if the operand is an offsettable memory operand. | |
794 (define_predicate "offsettable_mem_operand" | |
795 (and (match_operand 0 "memory_operand") | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
796 (match_test "offsettable_nonstrict_memref_p (op)"))) |
0 | 797 |
111 | 798 ;; Return 1 if the operand is a simple offsettable memory operand |
799 ;; that does not include pre-increment, post-increment, etc. | |
800 (define_predicate "simple_offsettable_mem_operand" | |
801 (match_operand 0 "offsettable_mem_operand") | |
0 | 802 { |
111 | 803 rtx addr = XEXP (op, 0); |
804 | |
805 if (GET_CODE (addr) != PLUS && GET_CODE (addr) != LO_SUM) | |
806 return 0; | |
807 | |
808 if (!CONSTANT_P (XEXP (addr, 1))) | |
809 return 0; | |
810 | |
811 return base_reg_operand (XEXP (addr, 0), Pmode); | |
812 }) | |
0 | 813 |
111 | 814 ;; Return 1 if the operand is suitable for load/store quad memory. |
815 ;; This predicate only checks for non-atomic loads/stores (not lqarx/stqcx). | |
816 (define_predicate "quad_memory_operand" | |
817 (match_code "mem") | |
818 { | |
819 if (!TARGET_QUAD_MEMORY && !TARGET_SYNC_TI) | |
820 return false; | |
821 | |
822 if (GET_MODE_SIZE (mode) != 16 || !MEM_P (op) || MEM_ALIGN (op) < 128) | |
823 return false; | |
0 | 824 |
111 | 825 return quad_address_p (XEXP (op, 0), mode, false); |
826 }) | |
827 | |
828 ;; Return 1 if the operand is suitable for load/store to vector registers with | |
829 ;; d-form addressing (register+offset), which was added in ISA 3.0. | |
830 ;; Unlike quad_memory_operand, we do not have to check for alignment. | |
831 (define_predicate "vsx_quad_dform_memory_operand" | |
832 (match_code "mem") | |
833 { | |
834 if (!TARGET_P9_VECTOR || !MEM_P (op) || GET_MODE_SIZE (mode) != 16) | |
835 return false; | |
836 | |
837 return quad_address_p (XEXP (op, 0), mode, false); | |
0 | 838 }) |
839 | |
840 ;; Return 1 if the operand is an indexed or indirect memory operand. | |
841 (define_predicate "indexed_or_indirect_operand" | |
842 (match_code "mem") | |
843 { | |
844 op = XEXP (op, 0); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
845 if (VECTOR_MEM_ALTIVEC_P (mode) |
0 | 846 && GET_CODE (op) == AND |
847 && GET_CODE (XEXP (op, 1)) == CONST_INT | |
848 && INTVAL (XEXP (op, 1)) == -16) | |
849 op = XEXP (op, 0); | |
850 | |
851 return indexed_or_indirect_address (op, mode); | |
852 }) | |
853 | |
111 | 854 ;; Like indexed_or_indirect_operand, but also allow a GPR register if direct |
855 ;; moves are supported. | |
856 (define_predicate "reg_or_indexed_operand" | |
857 (match_code "mem,reg,subreg") | |
858 { | |
859 if (MEM_P (op)) | |
860 return indexed_or_indirect_operand (op, mode); | |
861 else if (TARGET_DIRECT_MOVE) | |
862 return register_operand (op, mode); | |
863 return | |
864 0; | |
865 }) | |
866 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
867 ;; Return 1 if the operand is an indexed or indirect memory operand with an |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
868 ;; AND -16 in it, used to recognize when we need to switch to Altivec loads |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
869 ;; to realign loops instead of VSX (altivec silently ignores the bottom bits, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
870 ;; while VSX uses the full address and traps) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
871 (define_predicate "altivec_indexed_or_indirect_operand" |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
872 (match_code "mem") |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
873 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
874 op = XEXP (op, 0); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
875 if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
876 && GET_CODE (op) == AND |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
877 && GET_CODE (XEXP (op, 1)) == CONST_INT |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
878 && INTVAL (XEXP (op, 1)) == -16) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
879 return indexed_or_indirect_address (XEXP (op, 0), mode); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
880 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
881 return 0; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
882 }) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
883 |
0 | 884 ;; Return 1 if the operand is an indexed or indirect address. |
885 (define_special_predicate "indexed_or_indirect_address" | |
886 (and (match_test "REG_P (op) | |
887 || (GET_CODE (op) == PLUS | |
888 /* Omit testing REG_P (XEXP (op, 0)). */ | |
889 && REG_P (XEXP (op, 1)))") | |
890 (match_operand 0 "address_operand"))) | |
891 | |
111 | 892 ;; Return 1 if the operand is an index-form address. |
893 (define_special_predicate "indexed_address" | |
894 (match_test "(GET_CODE (op) == PLUS | |
895 && REG_P (XEXP (op, 0)) | |
896 && REG_P (XEXP (op, 1)))")) | |
897 | |
898 ;; Return 1 if the operand is a MEM with an update-form address. This may | |
899 ;; also include update-indexed form. | |
900 (define_special_predicate "update_address_mem" | |
901 (match_test "(MEM_P (op) | |
902 && (GET_CODE (XEXP (op, 0)) == PRE_INC | |
903 || GET_CODE (XEXP (op, 0)) == PRE_DEC | |
904 || GET_CODE (XEXP (op, 0)) == PRE_MODIFY))")) | |
905 | |
906 ;; Return 1 if the operand is a MEM with an indexed-form address. | |
907 (define_special_predicate "indexed_address_mem" | |
908 (match_test "(MEM_P (op) | |
909 && (indexed_address (XEXP (op, 0), mode) | |
910 || (GET_CODE (XEXP (op, 0)) == PRE_MODIFY | |
911 && indexed_address (XEXP (XEXP (op, 0), 1), mode))))")) | |
0 | 912 |
913 ;; Return 1 if the operand is either a non-special register or can be used | |
914 ;; as the operand of a `mode' add insn. | |
915 (define_predicate "add_operand" | |
916 (if_then_else (match_code "const_int") | |
917 (match_test "satisfies_constraint_I (op) | |
918 || satisfies_constraint_L (op)") | |
919 (match_operand 0 "gpc_reg_operand"))) | |
920 | |
111 | 921 ;; Return 1 if the operand is either a non-special register, or 0, or -1. |
922 (define_predicate "adde_operand" | |
923 (if_then_else (match_code "const_int") | |
924 (match_test "INTVAL (op) == 0 || INTVAL (op) == -1") | |
925 (match_operand 0 "gpc_reg_operand"))) | |
926 | |
0 | 927 ;; Return 1 if OP is a constant but not a valid add_operand. |
928 (define_predicate "non_add_cint_operand" | |
929 (and (match_code "const_int") | |
930 (match_test "!satisfies_constraint_I (op) | |
931 && !satisfies_constraint_L (op)"))) | |
932 | |
933 ;; Return 1 if the operand is a constant that can be used as the operand | |
934 ;; of an OR or XOR. | |
935 (define_predicate "logical_const_operand" | |
111 | 936 (match_code "const_int") |
0 | 937 { |
111 | 938 HOST_WIDE_INT opl; |
0 | 939 |
111 | 940 opl = INTVAL (op) & GET_MODE_MASK (mode); |
0 | 941 |
942 return ((opl & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0 | |
943 || (opl & ~ (unsigned HOST_WIDE_INT) 0xffff0000) == 0); | |
944 }) | |
945 | |
946 ;; Return 1 if the operand is a non-special register or a constant that | |
947 ;; can be used as the operand of an OR or XOR. | |
948 (define_predicate "logical_operand" | |
949 (ior (match_operand 0 "gpc_reg_operand") | |
950 (match_operand 0 "logical_const_operand"))) | |
951 | |
952 ;; Return 1 if op is a constant that is not a logical operand, but could | |
953 ;; be split into one. | |
954 (define_predicate "non_logical_cint_operand" | |
111 | 955 (and (match_code "const_int,const_wide_int") |
0 | 956 (and (not (match_operand 0 "logical_operand")) |
957 (match_operand 0 "reg_or_logical_cint_operand")))) | |
958 | |
959 ;; Return 1 if the operand is either a non-special register or a | |
960 ;; constant that can be used as the operand of a logical AND. | |
961 (define_predicate "and_operand" | |
111 | 962 (ior (and (match_code "const_int") |
963 (match_test "rs6000_is_valid_and_mask (op, mode)")) | |
964 (if_then_else (match_test "fixed_regs[CR0_REGNO]") | |
965 (match_operand 0 "gpc_reg_operand") | |
966 (match_operand 0 "logical_operand")))) | |
0 | 967 |
968 ;; Return 1 if the operand is either a logical operand or a short cint operand. | |
969 (define_predicate "scc_eq_operand" | |
970 (ior (match_operand 0 "logical_operand") | |
971 (match_operand 0 "short_cint_operand"))) | |
972 | |
973 ;; Return 1 if the operand is a general non-special register or memory operand. | |
974 (define_predicate "reg_or_mem_operand" | |
111 | 975 (ior (match_operand 0 "memory_operand") |
976 (and (match_code "mem") | |
977 (match_test "macho_lo_sum_memory_operand (op, mode)")) | |
978 (match_operand 0 "volatile_mem_operand") | |
979 (match_operand 0 "gpc_reg_operand"))) | |
0 | 980 |
981 ;; Return 1 if the operand is CONST_DOUBLE 0, register or memory operand. | |
982 (define_predicate "zero_reg_mem_operand" | |
111 | 983 (ior (and (match_test "TARGET_VSX") |
984 (match_operand 0 "zero_fp_constant")) | |
0 | 985 (match_operand 0 "reg_or_mem_operand"))) |
986 | |
111 | 987 ;; Return 1 if the operand is a CONST_INT and it is the element for 64-bit |
988 ;; data types inside of a vector that scalar instructions operate on | |
989 (define_predicate "vsx_scalar_64bit" | |
990 (match_code "const_int") | |
991 { | |
992 return (INTVAL (op) == VECTOR_ELEMENT_SCALAR_64BIT); | |
993 }) | |
994 | |
0 | 995 ;; Return 1 if the operand is a general register or memory operand without |
996 ;; pre_inc or pre_dec or pre_modify, which produces invalid form of PowerPC | |
997 ;; lwa instruction. | |
998 (define_predicate "lwa_operand" | |
999 (match_code "reg,subreg,mem") | |
1000 { | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1001 rtx inner, addr, offset; |
0 | 1002 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1003 inner = op; |
0 | 1004 if (reload_completed && GET_CODE (inner) == SUBREG) |
1005 inner = SUBREG_REG (inner); | |
1006 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1007 if (gpc_reg_operand (inner, mode)) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1008 return true; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1009 if (!memory_operand (inner, mode)) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1010 return false; |
111 | 1011 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1012 addr = XEXP (inner, 0); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1013 if (GET_CODE (addr) == PRE_INC |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1014 || GET_CODE (addr) == PRE_DEC |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1015 || (GET_CODE (addr) == PRE_MODIFY |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1016 && !legitimate_indexed_address_p (XEXP (addr, 1), 0))) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1017 return false; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1018 if (GET_CODE (addr) == LO_SUM |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1019 && GET_CODE (XEXP (addr, 0)) == REG |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1020 && GET_CODE (XEXP (addr, 1)) == CONST) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1021 addr = XEXP (XEXP (addr, 1), 0); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1022 if (GET_CODE (addr) != PLUS) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1023 return true; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1024 offset = XEXP (addr, 1); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1025 if (GET_CODE (offset) != CONST_INT) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1026 return true; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1027 return INTVAL (offset) % 4 == 0; |
0 | 1028 }) |
1029 | |
1030 ;; Return 1 if the operand, used inside a MEM, is a SYMBOL_REF. | |
1031 (define_predicate "symbol_ref_operand" | |
1032 (and (match_code "symbol_ref") | |
1033 (match_test "(mode == VOIDmode || GET_MODE (op) == mode) | |
1034 && (DEFAULT_ABI != ABI_AIX || SYMBOL_REF_FUNCTION_P (op))"))) | |
1035 | |
1036 ;; Return 1 if op is an operand that can be loaded via the GOT. | |
1037 ;; or non-special register register field no cr0 | |
1038 (define_predicate "got_operand" | |
1039 (match_code "symbol_ref,const,label_ref")) | |
1040 | |
1041 ;; Return 1 if op is a simple reference that can be loaded via the GOT, | |
1042 ;; excluding labels involving addition. | |
1043 (define_predicate "got_no_const_operand" | |
1044 (match_code "symbol_ref,label_ref")) | |
1045 | |
1046 ;; Return 1 if op is a SYMBOL_REF for a TLS symbol. | |
1047 (define_predicate "rs6000_tls_symbol_ref" | |
1048 (and (match_code "symbol_ref") | |
1049 (match_test "RS6000_SYMBOL_REF_TLS_P (op)"))) | |
1050 | |
1051 ;; Return 1 if the operand, used inside a MEM, is a valid first argument | |
1052 ;; to CALL. This is a SYMBOL_REF, a pseudo-register, LR or CTR. | |
1053 (define_predicate "call_operand" | |
1054 (if_then_else (match_code "reg") | |
1055 (match_test "REGNO (op) == LR_REGNO | |
1056 || REGNO (op) == CTR_REGNO | |
1057 || REGNO (op) >= FIRST_PSEUDO_REGISTER") | |
1058 (match_code "symbol_ref"))) | |
1059 | |
1060 ;; Return 1 if the operand is a SYMBOL_REF for a function known to be in | |
1061 ;; this file. | |
1062 (define_predicate "current_file_function_operand" | |
1063 (and (match_code "symbol_ref") | |
1064 (match_test "(DEFAULT_ABI != ABI_AIX || SYMBOL_REF_FUNCTION_P (op)) | |
111 | 1065 && (SYMBOL_REF_LOCAL_P (op) |
1066 || (op == XEXP (DECL_RTL (current_function_decl), 0) | |
1067 && !decl_replaceable_p (current_function_decl))) | |
1068 && !((DEFAULT_ABI == ABI_AIX | |
1069 || DEFAULT_ABI == ABI_ELFv2) | |
1070 && (SYMBOL_REF_EXTERNAL_P (op) | |
1071 || SYMBOL_REF_WEAK (op)))"))) | |
0 | 1072 |
1073 ;; Return 1 if this operand is a valid input for a move insn. | |
1074 (define_predicate "input_operand" | |
111 | 1075 (match_code "symbol_ref,const,reg,subreg,mem, |
1076 const_double,const_wide_int,const_vector,const_int") | |
0 | 1077 { |
1078 /* Memory is always valid. */ | |
1079 if (memory_operand (op, mode)) | |
1080 return 1; | |
1081 | |
1082 /* For floating-point, easy constants are valid. */ | |
1083 if (SCALAR_FLOAT_MODE_P (mode) | |
1084 && easy_fp_constant (op, mode)) | |
1085 return 1; | |
1086 | |
1087 /* Allow any integer constant. */ | |
1088 if (GET_MODE_CLASS (mode) == MODE_INT | |
111 | 1089 && CONST_SCALAR_INT_P (op)) |
0 | 1090 return 1; |
1091 | |
1092 /* Allow easy vector constants. */ | |
1093 if (GET_CODE (op) == CONST_VECTOR | |
1094 && easy_vector_constant (op, mode)) | |
1095 return 1; | |
1096 | |
1097 /* For floating-point or multi-word mode, the only remaining valid type | |
1098 is a register. */ | |
1099 if (SCALAR_FLOAT_MODE_P (mode) | |
1100 || GET_MODE_SIZE (mode) > UNITS_PER_WORD) | |
1101 return register_operand (op, mode); | |
1102 | |
111 | 1103 /* We don't allow moving the carry bit around. */ |
1104 if (ca_operand (op, mode)) | |
1105 return 0; | |
1106 | |
0 | 1107 /* The only cases left are integral modes one word or smaller (we |
1108 do not get called for MODE_CC values). These can be in any | |
1109 register. */ | |
1110 if (register_operand (op, mode)) | |
1111 return 1; | |
1112 | |
1113 /* V.4 allows SYMBOL_REFs and CONSTs that are in the small data region | |
1114 to be valid. */ | |
1115 if (DEFAULT_ABI == ABI_V4 | |
1116 && (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == CONST) | |
1117 && small_data_operand (op, Pmode)) | |
1118 return 1; | |
1119 | |
1120 return 0; | |
1121 }) | |
1122 | |
111 | 1123 ;; Return 1 if this operand is a valid input for a vsx_splat insn. |
1124 (define_predicate "splat_input_operand" | |
0 | 1125 (match_code "reg,subreg,mem") |
1126 { | |
111 | 1127 machine_mode vmode; |
1128 | |
1129 if (mode == DFmode) | |
1130 vmode = V2DFmode; | |
1131 else if (mode == DImode) | |
1132 vmode = V2DImode; | |
1133 else if (mode == SImode && TARGET_P9_VECTOR) | |
1134 vmode = V4SImode; | |
1135 else if (mode == SFmode && TARGET_P9_VECTOR) | |
1136 vmode = V4SFmode; | |
1137 else | |
1138 return false; | |
0 | 1139 |
111 | 1140 if (MEM_P (op)) |
1141 { | |
1142 rtx addr = XEXP (op, 0); | |
1143 | |
1144 if (! volatile_ok && MEM_VOLATILE_P (op)) | |
1145 return 0; | |
1146 | |
1147 if (lra_in_progress || reload_completed) | |
1148 return indexed_or_indirect_address (addr, vmode); | |
1149 else | |
1150 return memory_address_addr_space_p (vmode, addr, MEM_ADDR_SPACE (op)); | |
1151 } | |
1152 return gpc_reg_operand (op, mode); | |
0 | 1153 }) |
1154 | |
111 | 1155 ;; Return true if operand is an operator used in rotate-and-mask instructions. |
1156 (define_predicate "rotate_mask_operator" | |
1157 (match_code "rotate,ashift,lshiftrt")) | |
1158 | |
0 | 1159 ;; Return true if operand is boolean operator. |
1160 (define_predicate "boolean_operator" | |
1161 (match_code "and,ior,xor")) | |
1162 | |
1163 ;; Return true if operand is OR-form of boolean operator. | |
1164 (define_predicate "boolean_or_operator" | |
1165 (match_code "ior,xor")) | |
1166 | |
1167 ;; Return true if operand is an equality operator. | |
1168 (define_special_predicate "equality_operator" | |
1169 (match_code "eq,ne")) | |
1170 | |
1171 ;; Return 1 if OP is a comparison operation that is valid for a branch | |
1172 ;; instruction. We check the opcode against the mode of the CC value. | |
1173 ;; validate_condition_mode is an assertion. | |
1174 (define_predicate "branch_comparison_operator" | |
1175 (and (match_operand 0 "comparison_operator") | |
1176 (and (match_test "GET_MODE_CLASS (GET_MODE (XEXP (op, 0))) == MODE_CC") | |
1177 (match_test "validate_condition_mode (GET_CODE (op), | |
1178 GET_MODE (XEXP (op, 0))), | |
1179 1")))) | |
1180 | |
111 | 1181 ;; Return 1 if OP is an unsigned comparison operator. |
1182 (define_predicate "unsigned_comparison_operator" | |
1183 (match_code "ltu,gtu,leu,geu")) | |
1184 | |
1185 ;; Return 1 if OP is a signed comparison operator. | |
1186 (define_predicate "signed_comparison_operator" | |
1187 (match_code "lt,gt,le,ge")) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1188 |
0 | 1189 ;; Return 1 if OP is a comparison operation that is valid for an SCC insn -- |
1190 ;; it must be a positive comparison. | |
1191 (define_predicate "scc_comparison_operator" | |
1192 (and (match_operand 0 "branch_comparison_operator") | |
1193 (match_code "eq,lt,gt,ltu,gtu,unordered"))) | |
1194 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1195 ;; Return 1 if OP is a comparison operation whose inverse would be valid for |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1196 ;; an SCC insn. |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1197 (define_predicate "scc_rev_comparison_operator" |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1198 (and (match_operand 0 "branch_comparison_operator") |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1199 (match_code "ne,le,ge,leu,geu,ordered"))) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1200 |
111 | 1201 ;; Return 1 if OP is a comparison operator suitable for floating point |
1202 ;; vector/scalar comparisons that generate a -1/0 mask. | |
1203 (define_predicate "fpmask_comparison_operator" | |
1204 (match_code "eq,gt,ge")) | |
1205 | |
1206 ;; Return 1 if OP is a comparison operator suitable for vector/scalar | |
1207 ;; comparisons that generate a 0/-1 mask (i.e. the inverse of | |
1208 ;; fpmask_comparison_operator). | |
1209 (define_predicate "invert_fpmask_comparison_operator" | |
1210 (match_code "ne,unlt,unle")) | |
1211 | |
1212 ;; Return 1 if OP is a comparison operation suitable for integer vector/scalar | |
1213 ;; comparisons that generate a -1/0 mask. | |
1214 (define_predicate "vecint_comparison_operator" | |
1215 (match_code "eq,gt,gtu")) | |
1216 | |
0 | 1217 ;; Return 1 if OP is a comparison operation that is valid for a branch |
1218 ;; insn, which is true if the corresponding bit in the CC register is set. | |
1219 (define_predicate "branch_positive_comparison_operator" | |
1220 (and (match_operand 0 "branch_comparison_operator") | |
1221 (match_code "eq,lt,gt,ltu,gtu,unordered"))) | |
1222 | |
1223 ;; Return 1 if OP is a load multiple operation, known to be a PARALLEL. | |
1224 (define_predicate "load_multiple_operation" | |
1225 (match_code "parallel") | |
1226 { | |
1227 int count = XVECLEN (op, 0); | |
1228 unsigned int dest_regno; | |
1229 rtx src_addr; | |
1230 int i; | |
1231 | |
1232 /* Perform a quick check so we don't blow up below. */ | |
1233 if (count <= 1 | |
1234 || GET_CODE (XVECEXP (op, 0, 0)) != SET | |
1235 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG | |
1236 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != MEM) | |
1237 return 0; | |
1238 | |
1239 dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0))); | |
1240 src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0); | |
1241 | |
1242 for (i = 1; i < count; i++) | |
1243 { | |
1244 rtx elt = XVECEXP (op, 0, i); | |
1245 | |
1246 if (GET_CODE (elt) != SET | |
1247 || GET_CODE (SET_DEST (elt)) != REG | |
1248 || GET_MODE (SET_DEST (elt)) != SImode | |
1249 || REGNO (SET_DEST (elt)) != dest_regno + i | |
1250 || GET_CODE (SET_SRC (elt)) != MEM | |
1251 || GET_MODE (SET_SRC (elt)) != SImode | |
1252 || GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS | |
1253 || ! rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr) | |
1254 || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT | |
1255 || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1)) != i * 4) | |
1256 return 0; | |
1257 } | |
1258 | |
1259 return 1; | |
1260 }) | |
1261 | |
1262 ;; Return 1 if OP is a store multiple operation, known to be a PARALLEL. | |
1263 ;; The second vector element is a CLOBBER. | |
1264 (define_predicate "store_multiple_operation" | |
1265 (match_code "parallel") | |
1266 { | |
1267 int count = XVECLEN (op, 0) - 1; | |
1268 unsigned int src_regno; | |
1269 rtx dest_addr; | |
1270 int i; | |
1271 | |
1272 /* Perform a quick check so we don't blow up below. */ | |
1273 if (count <= 1 | |
1274 || GET_CODE (XVECEXP (op, 0, 0)) != SET | |
1275 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != MEM | |
1276 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != REG) | |
1277 return 0; | |
1278 | |
1279 src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0))); | |
1280 dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0); | |
1281 | |
1282 for (i = 1; i < count; i++) | |
1283 { | |
1284 rtx elt = XVECEXP (op, 0, i + 1); | |
1285 | |
1286 if (GET_CODE (elt) != SET | |
1287 || GET_CODE (SET_SRC (elt)) != REG | |
1288 || GET_MODE (SET_SRC (elt)) != SImode | |
1289 || REGNO (SET_SRC (elt)) != src_regno + i | |
1290 || GET_CODE (SET_DEST (elt)) != MEM | |
1291 || GET_MODE (SET_DEST (elt)) != SImode | |
1292 || GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS | |
1293 || ! rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr) | |
1294 || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT | |
1295 || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1)) != i * 4) | |
1296 return 0; | |
1297 } | |
1298 | |
1299 return 1; | |
1300 }) | |
1301 | |
1302 ;; Return 1 if OP is valid for a save_world call in prologue, known to be | |
1303 ;; a PARLLEL. | |
1304 (define_predicate "save_world_operation" | |
1305 (match_code "parallel") | |
1306 { | |
1307 int index; | |
1308 int i; | |
1309 rtx elt; | |
1310 int count = XVECLEN (op, 0); | |
1311 | |
1312 if (count != 54) | |
1313 return 0; | |
1314 | |
1315 index = 0; | |
1316 if (GET_CODE (XVECEXP (op, 0, index++)) != CLOBBER | |
1317 || GET_CODE (XVECEXP (op, 0, index++)) != USE) | |
1318 return 0; | |
1319 | |
1320 for (i=1; i <= 18; i++) | |
1321 { | |
1322 elt = XVECEXP (op, 0, index++); | |
1323 if (GET_CODE (elt) != SET | |
1324 || GET_CODE (SET_DEST (elt)) != MEM | |
1325 || ! memory_operand (SET_DEST (elt), DFmode) | |
1326 || GET_CODE (SET_SRC (elt)) != REG | |
1327 || GET_MODE (SET_SRC (elt)) != DFmode) | |
1328 return 0; | |
1329 } | |
1330 | |
1331 for (i=1; i <= 12; i++) | |
1332 { | |
1333 elt = XVECEXP (op, 0, index++); | |
1334 if (GET_CODE (elt) != SET | |
1335 || GET_CODE (SET_DEST (elt)) != MEM | |
1336 || GET_CODE (SET_SRC (elt)) != REG | |
1337 || GET_MODE (SET_SRC (elt)) != V4SImode) | |
1338 return 0; | |
1339 } | |
1340 | |
1341 for (i=1; i <= 19; i++) | |
1342 { | |
1343 elt = XVECEXP (op, 0, index++); | |
1344 if (GET_CODE (elt) != SET | |
1345 || GET_CODE (SET_DEST (elt)) != MEM | |
1346 || ! memory_operand (SET_DEST (elt), Pmode) | |
1347 || GET_CODE (SET_SRC (elt)) != REG | |
1348 || GET_MODE (SET_SRC (elt)) != Pmode) | |
1349 return 0; | |
1350 } | |
1351 | |
1352 elt = XVECEXP (op, 0, index++); | |
1353 if (GET_CODE (elt) != SET | |
1354 || GET_CODE (SET_DEST (elt)) != MEM | |
1355 || ! memory_operand (SET_DEST (elt), Pmode) | |
1356 || GET_CODE (SET_SRC (elt)) != REG | |
1357 || REGNO (SET_SRC (elt)) != CR2_REGNO | |
1358 || GET_MODE (SET_SRC (elt)) != Pmode) | |
1359 return 0; | |
1360 | |
1361 if (GET_CODE (XVECEXP (op, 0, index++)) != SET | |
1362 || GET_CODE (XVECEXP (op, 0, index++)) != SET) | |
1363 return 0; | |
1364 return 1; | |
1365 }) | |
1366 | |
1367 ;; Return 1 if OP is valid for a restore_world call in epilogue, known to be | |
1368 ;; a PARLLEL. | |
1369 (define_predicate "restore_world_operation" | |
1370 (match_code "parallel") | |
1371 { | |
1372 int index; | |
1373 int i; | |
1374 rtx elt; | |
1375 int count = XVECLEN (op, 0); | |
1376 | |
1377 if (count != 59) | |
1378 return 0; | |
1379 | |
1380 index = 0; | |
1381 if (GET_CODE (XVECEXP (op, 0, index++)) != RETURN | |
1382 || GET_CODE (XVECEXP (op, 0, index++)) != USE | |
1383 || GET_CODE (XVECEXP (op, 0, index++)) != USE | |
1384 || GET_CODE (XVECEXP (op, 0, index++)) != CLOBBER) | |
1385 return 0; | |
1386 | |
1387 elt = XVECEXP (op, 0, index++); | |
1388 if (GET_CODE (elt) != SET | |
1389 || GET_CODE (SET_SRC (elt)) != MEM | |
1390 || ! memory_operand (SET_SRC (elt), Pmode) | |
1391 || GET_CODE (SET_DEST (elt)) != REG | |
1392 || REGNO (SET_DEST (elt)) != CR2_REGNO | |
1393 || GET_MODE (SET_DEST (elt)) != Pmode) | |
1394 return 0; | |
1395 | |
1396 for (i=1; i <= 19; i++) | |
1397 { | |
1398 elt = XVECEXP (op, 0, index++); | |
1399 if (GET_CODE (elt) != SET | |
1400 || GET_CODE (SET_SRC (elt)) != MEM | |
1401 || ! memory_operand (SET_SRC (elt), Pmode) | |
1402 || GET_CODE (SET_DEST (elt)) != REG | |
1403 || GET_MODE (SET_DEST (elt)) != Pmode) | |
1404 return 0; | |
1405 } | |
1406 | |
1407 for (i=1; i <= 12; i++) | |
1408 { | |
1409 elt = XVECEXP (op, 0, index++); | |
1410 if (GET_CODE (elt) != SET | |
1411 || GET_CODE (SET_SRC (elt)) != MEM | |
1412 || GET_CODE (SET_DEST (elt)) != REG | |
1413 || GET_MODE (SET_DEST (elt)) != V4SImode) | |
1414 return 0; | |
1415 } | |
1416 | |
1417 for (i=1; i <= 18; i++) | |
1418 { | |
1419 elt = XVECEXP (op, 0, index++); | |
1420 if (GET_CODE (elt) != SET | |
1421 || GET_CODE (SET_SRC (elt)) != MEM | |
1422 || ! memory_operand (SET_SRC (elt), DFmode) | |
1423 || GET_CODE (SET_DEST (elt)) != REG | |
1424 || GET_MODE (SET_DEST (elt)) != DFmode) | |
1425 return 0; | |
1426 } | |
1427 | |
1428 if (GET_CODE (XVECEXP (op, 0, index++)) != CLOBBER | |
1429 || GET_CODE (XVECEXP (op, 0, index++)) != CLOBBER | |
1430 || GET_CODE (XVECEXP (op, 0, index++)) != CLOBBER | |
1431 || GET_CODE (XVECEXP (op, 0, index++)) != CLOBBER | |
1432 || GET_CODE (XVECEXP (op, 0, index++)) != USE) | |
1433 return 0; | |
1434 return 1; | |
1435 }) | |
1436 | |
1437 ;; Return 1 if OP is valid for a vrsave call, known to be a PARALLEL. | |
1438 (define_predicate "vrsave_operation" | |
1439 (match_code "parallel") | |
1440 { | |
1441 int count = XVECLEN (op, 0); | |
1442 unsigned int dest_regno, src_regno; | |
1443 int i; | |
1444 | |
1445 if (count <= 1 | |
1446 || GET_CODE (XVECEXP (op, 0, 0)) != SET | |
1447 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG | |
1448 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != UNSPEC_VOLATILE | |
1449 || XINT (SET_SRC (XVECEXP (op, 0, 0)), 1) != UNSPECV_SET_VRSAVE) | |
1450 return 0; | |
1451 | |
1452 dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0))); | |
1453 src_regno = REGNO (XVECEXP (SET_SRC (XVECEXP (op, 0, 0)), 0, 1)); | |
1454 | |
1455 if (dest_regno != VRSAVE_REGNO || src_regno != VRSAVE_REGNO) | |
1456 return 0; | |
1457 | |
1458 for (i = 1; i < count; i++) | |
1459 { | |
1460 rtx elt = XVECEXP (op, 0, i); | |
1461 | |
1462 if (GET_CODE (elt) != CLOBBER | |
1463 && GET_CODE (elt) != SET) | |
1464 return 0; | |
1465 } | |
1466 | |
1467 return 1; | |
1468 }) | |
1469 | |
1470 ;; Return 1 if OP is valid for mfcr insn, known to be a PARALLEL. | |
1471 (define_predicate "mfcr_operation" | |
1472 (match_code "parallel") | |
1473 { | |
1474 int count = XVECLEN (op, 0); | |
1475 int i; | |
1476 | |
1477 /* Perform a quick check so we don't blow up below. */ | |
1478 if (count < 1 | |
1479 || GET_CODE (XVECEXP (op, 0, 0)) != SET | |
1480 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != UNSPEC | |
1481 || XVECLEN (SET_SRC (XVECEXP (op, 0, 0)), 0) != 2) | |
1482 return 0; | |
1483 | |
1484 for (i = 0; i < count; i++) | |
1485 { | |
1486 rtx exp = XVECEXP (op, 0, i); | |
1487 rtx unspec; | |
1488 int maskval; | |
1489 rtx src_reg; | |
1490 | |
1491 src_reg = XVECEXP (SET_SRC (exp), 0, 0); | |
1492 | |
1493 if (GET_CODE (src_reg) != REG | |
1494 || GET_MODE (src_reg) != CCmode | |
1495 || ! CR_REGNO_P (REGNO (src_reg))) | |
1496 return 0; | |
1497 | |
1498 if (GET_CODE (exp) != SET | |
1499 || GET_CODE (SET_DEST (exp)) != REG | |
1500 || GET_MODE (SET_DEST (exp)) != SImode | |
1501 || ! INT_REGNO_P (REGNO (SET_DEST (exp)))) | |
1502 return 0; | |
1503 unspec = SET_SRC (exp); | |
1504 maskval = 1 << (MAX_CR_REGNO - REGNO (src_reg)); | |
1505 | |
1506 if (GET_CODE (unspec) != UNSPEC | |
1507 || XINT (unspec, 1) != UNSPEC_MOVESI_FROM_CR | |
1508 || XVECLEN (unspec, 0) != 2 | |
1509 || XVECEXP (unspec, 0, 0) != src_reg | |
1510 || GET_CODE (XVECEXP (unspec, 0, 1)) != CONST_INT | |
1511 || INTVAL (XVECEXP (unspec, 0, 1)) != maskval) | |
1512 return 0; | |
1513 } | |
1514 return 1; | |
1515 }) | |
1516 | |
1517 ;; Return 1 if OP is valid for mtcrf insn, known to be a PARALLEL. | |
1518 (define_predicate "mtcrf_operation" | |
1519 (match_code "parallel") | |
1520 { | |
1521 int count = XVECLEN (op, 0); | |
1522 int i; | |
1523 rtx src_reg; | |
1524 | |
1525 /* Perform a quick check so we don't blow up below. */ | |
1526 if (count < 1 | |
1527 || GET_CODE (XVECEXP (op, 0, 0)) != SET | |
1528 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != UNSPEC | |
1529 || XVECLEN (SET_SRC (XVECEXP (op, 0, 0)), 0) != 2) | |
1530 return 0; | |
1531 src_reg = XVECEXP (SET_SRC (XVECEXP (op, 0, 0)), 0, 0); | |
1532 | |
1533 if (GET_CODE (src_reg) != REG | |
1534 || GET_MODE (src_reg) != SImode | |
1535 || ! INT_REGNO_P (REGNO (src_reg))) | |
1536 return 0; | |
1537 | |
1538 for (i = 0; i < count; i++) | |
1539 { | |
1540 rtx exp = XVECEXP (op, 0, i); | |
1541 rtx unspec; | |
1542 int maskval; | |
1543 | |
1544 if (GET_CODE (exp) != SET | |
1545 || GET_CODE (SET_DEST (exp)) != REG | |
1546 || GET_MODE (SET_DEST (exp)) != CCmode | |
1547 || ! CR_REGNO_P (REGNO (SET_DEST (exp)))) | |
1548 return 0; | |
1549 unspec = SET_SRC (exp); | |
1550 maskval = 1 << (MAX_CR_REGNO - REGNO (SET_DEST (exp))); | |
1551 | |
1552 if (GET_CODE (unspec) != UNSPEC | |
1553 || XINT (unspec, 1) != UNSPEC_MOVESI_TO_CR | |
1554 || XVECLEN (unspec, 0) != 2 | |
1555 || XVECEXP (unspec, 0, 0) != src_reg | |
1556 || GET_CODE (XVECEXP (unspec, 0, 1)) != CONST_INT | |
1557 || INTVAL (XVECEXP (unspec, 0, 1)) != maskval) | |
1558 return 0; | |
1559 } | |
1560 return 1; | |
1561 }) | |
1562 | |
111 | 1563 ;; Return 1 if OP is valid for crsave insn, known to be a PARALLEL. |
1564 (define_predicate "crsave_operation" | |
1565 (match_code "parallel") | |
1566 { | |
1567 int count = XVECLEN (op, 0); | |
1568 int i; | |
1569 | |
1570 for (i = 1; i < count; i++) | |
1571 { | |
1572 rtx exp = XVECEXP (op, 0, i); | |
1573 | |
1574 if (GET_CODE (exp) != USE | |
1575 || GET_CODE (XEXP (exp, 0)) != REG | |
1576 || GET_MODE (XEXP (exp, 0)) != CCmode | |
1577 || ! CR_REGNO_P (REGNO (XEXP (exp, 0)))) | |
1578 return 0; | |
1579 } | |
1580 return 1; | |
1581 }) | |
1582 | |
0 | 1583 ;; Return 1 if OP is valid for lmw insn, known to be a PARALLEL. |
1584 (define_predicate "lmw_operation" | |
1585 (match_code "parallel") | |
1586 { | |
1587 int count = XVECLEN (op, 0); | |
1588 unsigned int dest_regno; | |
1589 rtx src_addr; | |
1590 unsigned int base_regno; | |
1591 HOST_WIDE_INT offset; | |
1592 int i; | |
1593 | |
1594 /* Perform a quick check so we don't blow up below. */ | |
1595 if (count <= 1 | |
1596 || GET_CODE (XVECEXP (op, 0, 0)) != SET | |
1597 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG | |
1598 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != MEM) | |
1599 return 0; | |
1600 | |
1601 dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0))); | |
1602 src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0); | |
1603 | |
1604 if (dest_regno > 31 | |
1605 || count != 32 - (int) dest_regno) | |
1606 return 0; | |
1607 | |
1608 if (legitimate_indirect_address_p (src_addr, 0)) | |
1609 { | |
1610 offset = 0; | |
1611 base_regno = REGNO (src_addr); | |
1612 if (base_regno == 0) | |
1613 return 0; | |
1614 } | |
111 | 1615 else if (rs6000_legitimate_offset_address_p (SImode, src_addr, false, false)) |
0 | 1616 { |
1617 offset = INTVAL (XEXP (src_addr, 1)); | |
1618 base_regno = REGNO (XEXP (src_addr, 0)); | |
1619 } | |
1620 else | |
1621 return 0; | |
1622 | |
1623 for (i = 0; i < count; i++) | |
1624 { | |
1625 rtx elt = XVECEXP (op, 0, i); | |
1626 rtx newaddr; | |
1627 rtx addr_reg; | |
1628 HOST_WIDE_INT newoffset; | |
1629 | |
1630 if (GET_CODE (elt) != SET | |
1631 || GET_CODE (SET_DEST (elt)) != REG | |
1632 || GET_MODE (SET_DEST (elt)) != SImode | |
1633 || REGNO (SET_DEST (elt)) != dest_regno + i | |
1634 || GET_CODE (SET_SRC (elt)) != MEM | |
1635 || GET_MODE (SET_SRC (elt)) != SImode) | |
1636 return 0; | |
1637 newaddr = XEXP (SET_SRC (elt), 0); | |
1638 if (legitimate_indirect_address_p (newaddr, 0)) | |
1639 { | |
1640 newoffset = 0; | |
1641 addr_reg = newaddr; | |
1642 } | |
111 | 1643 else if (rs6000_legitimate_offset_address_p (SImode, newaddr, false, false)) |
0 | 1644 { |
1645 addr_reg = XEXP (newaddr, 0); | |
1646 newoffset = INTVAL (XEXP (newaddr, 1)); | |
1647 } | |
1648 else | |
1649 return 0; | |
1650 if (REGNO (addr_reg) != base_regno | |
1651 || newoffset != offset + 4 * i) | |
1652 return 0; | |
1653 } | |
1654 | |
1655 return 1; | |
1656 }) | |
1657 | |
1658 ;; Return 1 if OP is valid for stmw insn, known to be a PARALLEL. | |
1659 (define_predicate "stmw_operation" | |
1660 (match_code "parallel") | |
1661 { | |
1662 int count = XVECLEN (op, 0); | |
1663 unsigned int src_regno; | |
1664 rtx dest_addr; | |
1665 unsigned int base_regno; | |
1666 HOST_WIDE_INT offset; | |
1667 int i; | |
1668 | |
1669 /* Perform a quick check so we don't blow up below. */ | |
1670 if (count <= 1 | |
1671 || GET_CODE (XVECEXP (op, 0, 0)) != SET | |
1672 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != MEM | |
1673 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != REG) | |
1674 return 0; | |
1675 | |
1676 src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0))); | |
1677 dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0); | |
1678 | |
1679 if (src_regno > 31 | |
1680 || count != 32 - (int) src_regno) | |
1681 return 0; | |
1682 | |
1683 if (legitimate_indirect_address_p (dest_addr, 0)) | |
1684 { | |
1685 offset = 0; | |
1686 base_regno = REGNO (dest_addr); | |
1687 if (base_regno == 0) | |
1688 return 0; | |
1689 } | |
111 | 1690 else if (rs6000_legitimate_offset_address_p (SImode, dest_addr, false, false)) |
0 | 1691 { |
1692 offset = INTVAL (XEXP (dest_addr, 1)); | |
1693 base_regno = REGNO (XEXP (dest_addr, 0)); | |
1694 } | |
1695 else | |
1696 return 0; | |
1697 | |
1698 for (i = 0; i < count; i++) | |
1699 { | |
1700 rtx elt = XVECEXP (op, 0, i); | |
1701 rtx newaddr; | |
1702 rtx addr_reg; | |
1703 HOST_WIDE_INT newoffset; | |
1704 | |
1705 if (GET_CODE (elt) != SET | |
1706 || GET_CODE (SET_SRC (elt)) != REG | |
1707 || GET_MODE (SET_SRC (elt)) != SImode | |
1708 || REGNO (SET_SRC (elt)) != src_regno + i | |
1709 || GET_CODE (SET_DEST (elt)) != MEM | |
1710 || GET_MODE (SET_DEST (elt)) != SImode) | |
1711 return 0; | |
1712 newaddr = XEXP (SET_DEST (elt), 0); | |
1713 if (legitimate_indirect_address_p (newaddr, 0)) | |
1714 { | |
1715 newoffset = 0; | |
1716 addr_reg = newaddr; | |
1717 } | |
111 | 1718 else if (rs6000_legitimate_offset_address_p (SImode, newaddr, false, false)) |
0 | 1719 { |
1720 addr_reg = XEXP (newaddr, 0); | |
1721 newoffset = INTVAL (XEXP (newaddr, 1)); | |
1722 } | |
1723 else | |
1724 return 0; | |
1725 if (REGNO (addr_reg) != base_regno | |
1726 || newoffset != offset + 4 * i) | |
1727 return 0; | |
1728 } | |
1729 | |
1730 return 1; | |
1731 }) | |
111 | 1732 |
1733 ;; Return 1 if OP is a stack tie operand. | |
1734 (define_predicate "tie_operand" | |
1735 (match_code "parallel") | |
1736 { | |
1737 return (GET_CODE (XVECEXP (op, 0, 0)) == SET | |
1738 && GET_CODE (XEXP (XVECEXP (op, 0, 0), 0)) == MEM | |
1739 && GET_MODE (XEXP (XVECEXP (op, 0, 0), 0)) == BLKmode | |
1740 && XEXP (XVECEXP (op, 0, 0), 1) == const0_rtx); | |
1741 }) | |
1742 | |
1743 ;; Match a small code model toc reference (or medium and large | |
1744 ;; model toc references before reload). | |
1745 (define_predicate "small_toc_ref" | |
1746 (match_code "unspec,plus") | |
1747 { | |
1748 if (GET_CODE (op) == PLUS && add_cint_operand (XEXP (op, 1), mode)) | |
1749 op = XEXP (op, 0); | |
1750 | |
1751 return GET_CODE (op) == UNSPEC && XINT (op, 1) == UNSPEC_TOCREL; | |
1752 }) | |
1753 | |
1754 ;; Match the TOC memory operand that can be fused with an addis instruction. | |
1755 ;; This is used in matching a potential fused address before register | |
1756 ;; allocation. | |
1757 (define_predicate "toc_fusion_mem_raw" | |
1758 (match_code "mem") | |
1759 { | |
1760 if (!TARGET_TOC_FUSION_INT || !can_create_pseudo_p ()) | |
1761 return false; | |
1762 | |
1763 return small_toc_ref (XEXP (op, 0), Pmode); | |
1764 }) | |
1765 | |
1766 ;; Match the memory operand that has been fused with an addis instruction and | |
1767 ;; wrapped inside of an (unspec [...] UNSPEC_FUSION_ADDIS) wrapper. | |
1768 (define_predicate "toc_fusion_mem_wrapped" | |
1769 (match_code "mem") | |
1770 { | |
1771 rtx addr; | |
1772 | |
1773 if (!TARGET_TOC_FUSION_INT) | |
1774 return false; | |
1775 | |
1776 if (!MEM_P (op)) | |
1777 return false; | |
1778 | |
1779 addr = XEXP (op, 0); | |
1780 return (GET_CODE (addr) == UNSPEC && XINT (addr, 1) == UNSPEC_FUSION_ADDIS); | |
1781 }) | |
1782 | |
1783 ;; Match the first insn (addis) in fusing the combination of addis and loads to | |
1784 ;; GPR registers on power8. | |
1785 (define_predicate "fusion_gpr_addis" | |
1786 (match_code "const_int,high,plus") | |
1787 { | |
1788 HOST_WIDE_INT value; | |
1789 rtx int_const; | |
1790 | |
1791 if (GET_CODE (op) == HIGH) | |
1792 return 1; | |
1793 | |
1794 if (CONST_INT_P (op)) | |
1795 int_const = op; | |
1796 | |
1797 else if (GET_CODE (op) == PLUS | |
1798 && base_reg_operand (XEXP (op, 0), Pmode) | |
1799 && CONST_INT_P (XEXP (op, 1))) | |
1800 int_const = XEXP (op, 1); | |
1801 | |
1802 else | |
1803 return 0; | |
1804 | |
1805 value = INTVAL (int_const); | |
1806 if ((value & (HOST_WIDE_INT)0xffff) != 0) | |
1807 return 0; | |
1808 | |
1809 if ((value & (HOST_WIDE_INT)0xffff0000) == 0) | |
1810 return 0; | |
1811 | |
1812 /* Power8 currently will only do the fusion if the top 11 bits of the addis | |
1813 value are all 1's or 0's. Ignore this restriction if we are testing | |
1814 advanced fusion. */ | |
1815 if (TARGET_P9_FUSION) | |
1816 return 1; | |
1817 | |
1818 return (IN_RANGE (value >> 16, -32, 31)); | |
1819 }) | |
1820 | |
1821 ;; Match the second insn (lbz, lhz, lwz, ld) in fusing the combination of addis | |
1822 ;; and loads to GPR registers on power8. | |
1823 (define_predicate "fusion_gpr_mem_load" | |
1824 (match_code "mem,sign_extend,zero_extend") | |
1825 { | |
1826 rtx addr, base, offset; | |
1827 | |
1828 /* Handle sign/zero extend. */ | |
1829 if (GET_CODE (op) == ZERO_EXTEND | |
1830 || (TARGET_P8_FUSION_SIGN && GET_CODE (op) == SIGN_EXTEND)) | |
1831 { | |
1832 op = XEXP (op, 0); | |
1833 mode = GET_MODE (op); | |
1834 } | |
1835 | |
1836 if (!MEM_P (op)) | |
1837 return 0; | |
1838 | |
1839 switch (mode) | |
1840 { | |
1841 case E_QImode: | |
1842 case E_HImode: | |
1843 case E_SImode: | |
1844 break; | |
1845 | |
1846 case E_DImode: | |
1847 if (!TARGET_POWERPC64) | |
1848 return 0; | |
1849 break; | |
1850 | |
1851 default: | |
1852 return 0; | |
1853 } | |
1854 | |
1855 addr = XEXP (op, 0); | |
1856 if (GET_CODE (addr) != PLUS && GET_CODE (addr) != LO_SUM) | |
1857 return 0; | |
1858 | |
1859 base = XEXP (addr, 0); | |
1860 if (!base_reg_operand (base, GET_MODE (base))) | |
1861 return 0; | |
1862 | |
1863 offset = XEXP (addr, 1); | |
1864 | |
1865 if (GET_CODE (addr) == PLUS) | |
1866 return satisfies_constraint_I (offset); | |
1867 | |
1868 else if (GET_CODE (addr) == LO_SUM) | |
1869 { | |
1870 if (TARGET_XCOFF || (TARGET_ELF && TARGET_POWERPC64)) | |
1871 return small_toc_ref (offset, GET_MODE (offset)); | |
1872 | |
1873 else if (TARGET_ELF && !TARGET_POWERPC64) | |
1874 return CONSTANT_P (offset); | |
1875 } | |
1876 | |
1877 return 0; | |
1878 }) | |
1879 | |
1880 ;; Match a GPR load (lbz, lhz, lwz, ld) that uses a combined address in the | |
1881 ;; memory field with both the addis and the memory offset. Sign extension | |
1882 ;; is not handled here, since lha and lwa are not fused. | |
1883 ;; With P9 fusion, also match a fpr/vector load and float_extend | |
1884 (define_predicate "fusion_addis_mem_combo_load" | |
1885 (match_code "mem,zero_extend,float_extend") | |
1886 { | |
1887 rtx addr, base, offset; | |
1888 | |
1889 /* Handle zero/float extend. */ | |
1890 if (GET_CODE (op) == ZERO_EXTEND || GET_CODE (op) == FLOAT_EXTEND) | |
1891 { | |
1892 op = XEXP (op, 0); | |
1893 mode = GET_MODE (op); | |
1894 } | |
1895 | |
1896 if (!MEM_P (op)) | |
1897 return 0; | |
1898 | |
1899 switch (mode) | |
1900 { | |
1901 case E_QImode: | |
1902 case E_HImode: | |
1903 case E_SImode: | |
1904 break; | |
1905 | |
1906 /* Do not fuse 64-bit DImode in 32-bit since it splits into two | |
1907 separate instructions. */ | |
1908 case E_DImode: | |
1909 if (!TARGET_POWERPC64) | |
1910 return 0; | |
1911 break; | |
1912 | |
1913 /* ISA 2.08/power8 only had fusion of GPR loads. */ | |
1914 case E_SFmode: | |
1915 if (!TARGET_P9_FUSION) | |
1916 return 0; | |
1917 break; | |
1918 | |
1919 /* ISA 2.08/power8 only had fusion of GPR loads. Do not allow 64-bit | |
1920 DFmode in 32-bit if -msoft-float since it splits into two separate | |
1921 instructions. */ | |
1922 case E_DFmode: | |
1923 if ((!TARGET_POWERPC64 && !TARGET_DF_FPR) || !TARGET_P9_FUSION) | |
1924 return 0; | |
1925 break; | |
1926 | |
1927 default: | |
1928 return 0; | |
1929 } | |
1930 | |
1931 addr = XEXP (op, 0); | |
1932 if (GET_CODE (addr) != PLUS && GET_CODE (addr) != LO_SUM) | |
1933 return 0; | |
1934 | |
1935 base = XEXP (addr, 0); | |
1936 if (!fusion_gpr_addis (base, GET_MODE (base))) | |
1937 return 0; | |
1938 | |
1939 offset = XEXP (addr, 1); | |
1940 if (GET_CODE (addr) == PLUS) | |
1941 return satisfies_constraint_I (offset); | |
1942 | |
1943 else if (GET_CODE (addr) == LO_SUM) | |
1944 { | |
1945 if (TARGET_XCOFF || (TARGET_ELF && TARGET_POWERPC64)) | |
1946 return small_toc_ref (offset, GET_MODE (offset)); | |
1947 | |
1948 else if (TARGET_ELF && !TARGET_POWERPC64) | |
1949 return CONSTANT_P (offset); | |
1950 } | |
1951 | |
1952 return 0; | |
1953 }) | |
1954 | |
1955 ;; Like fusion_addis_mem_combo_load, but for stores | |
1956 (define_predicate "fusion_addis_mem_combo_store" | |
1957 (match_code "mem") | |
1958 { | |
1959 rtx addr, base, offset; | |
1960 | |
1961 if (!MEM_P (op) || !TARGET_P9_FUSION) | |
1962 return 0; | |
1963 | |
1964 switch (mode) | |
1965 { | |
1966 case E_QImode: | |
1967 case E_HImode: | |
1968 case E_SImode: | |
1969 case E_SFmode: | |
1970 break; | |
1971 | |
1972 /* Do not fuse 64-bit DImode in 32-bit since it splits into two | |
1973 separate instructions. */ | |
1974 case E_DImode: | |
1975 if (!TARGET_POWERPC64) | |
1976 return 0; | |
1977 break; | |
1978 | |
1979 /* Do not allow 64-bit DFmode in 32-bit if -msoft-float since it splits | |
1980 into two separate instructions. Do allow fusion if we have hardware | |
1981 floating point. */ | |
1982 case E_DFmode: | |
1983 if (!TARGET_POWERPC64 && !TARGET_DF_FPR) | |
1984 return 0; | |
1985 break; | |
1986 | |
1987 default: | |
1988 return 0; | |
1989 } | |
1990 | |
1991 addr = XEXP (op, 0); | |
1992 if (GET_CODE (addr) != PLUS && GET_CODE (addr) != LO_SUM) | |
1993 return 0; | |
1994 | |
1995 base = XEXP (addr, 0); | |
1996 if (!fusion_gpr_addis (base, GET_MODE (base))) | |
1997 return 0; | |
1998 | |
1999 offset = XEXP (addr, 1); | |
2000 if (GET_CODE (addr) == PLUS) | |
2001 return satisfies_constraint_I (offset); | |
2002 | |
2003 else if (GET_CODE (addr) == LO_SUM) | |
2004 { | |
2005 if (TARGET_XCOFF || (TARGET_ELF && TARGET_POWERPC64)) | |
2006 return small_toc_ref (offset, GET_MODE (offset)); | |
2007 | |
2008 else if (TARGET_ELF && !TARGET_POWERPC64) | |
2009 return CONSTANT_P (offset); | |
2010 } | |
2011 | |
2012 return 0; | |
2013 }) | |
2014 | |
2015 ;; Return true if the operand is a float_extend or zero extend of an | |
2016 ;; offsettable memory operand suitable for use in fusion | |
2017 (define_predicate "fusion_offsettable_mem_operand" | |
2018 (match_code "mem,zero_extend,float_extend") | |
2019 { | |
2020 if (GET_CODE (op) == ZERO_EXTEND || GET_CODE (op) == FLOAT_EXTEND) | |
2021 { | |
2022 op = XEXP (op, 0); | |
2023 mode = GET_MODE (op); | |
2024 } | |
2025 | |
2026 if (!memory_operand (op, mode)) | |
2027 return 0; | |
2028 | |
2029 return offsettable_nonstrict_memref_p (op); | |
2030 }) |