Mercurial > hg > CbC > CbC_gcc
annotate gcc/config/rs6000/predicates.md @ 131:84e7813d76e9
gcc-8.2
author | mir3636 |
---|---|
date | Thu, 25 Oct 2018 07:37:49 +0900 |
parents | 04ced10e8804 |
children | 1830386684a0 |
rev | line source |
---|---|
0 | 1 ;; Predicate definitions for POWER and PowerPC. |
131 | 2 ;; Copyright (C) 2005-2018 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 | |
131 | 409 ;; Return true if this is a register that can has D-form addressing (GPR, |
410 ;; traditional FPR registers, and Altivec registers for scalars). Unlike | |
411 ;; power8 fusion, this fusion does not depend on putting the ADDIS instruction | |
412 ;; into the GPR register being loaded. | |
413 (define_predicate "p9_fusion_reg_operand" | |
111 | 414 (match_code "reg,subreg") |
415 { | |
416 HOST_WIDE_INT r; | |
417 bool gpr_p = (mode == QImode || mode == HImode || mode == SImode | |
418 || mode == SFmode | |
419 || (TARGET_POWERPC64 && (mode == DImode || mode == DFmode))); | |
420 bool fpr_p = (TARGET_P9_FUSION | |
421 && (mode == DFmode || mode == SFmode | |
422 || (TARGET_POWERPC64 && mode == DImode))); | |
423 bool vmx_p = (TARGET_P9_FUSION && TARGET_P9_VECTOR | |
424 && (mode == DFmode || mode == SFmode)); | |
425 | |
426 if (!TARGET_P8_FUSION) | |
427 return 0; | |
428 | |
429 if (GET_CODE (op) == SUBREG) | |
430 op = SUBREG_REG (op); | |
431 | |
432 if (!REG_P (op)) | |
433 return 0; | |
434 | |
435 r = REGNO (op); | |
436 if (r >= FIRST_PSEUDO_REGISTER) | |
437 return (gpr_p || fpr_p || vmx_p); | |
438 | |
439 if (INT_REGNO_P (r)) | |
440 return gpr_p; | |
441 | |
442 if (FP_REGNO_P (r)) | |
443 return fpr_p; | |
444 | |
445 if (ALTIVEC_REGNO_P (r)) | |
446 return vmx_p; | |
447 | |
448 return 0; | |
449 }) | |
450 | |
451 ;; Return 1 if op is a HTM specific SPR register. | |
452 (define_predicate "htm_spr_reg_operand" | |
453 (match_operand 0 "register_operand") | |
454 { | |
455 if (!TARGET_HTM) | |
456 return 0; | |
457 | |
458 if (GET_CODE (op) == SUBREG) | |
459 op = SUBREG_REG (op); | |
460 | |
461 if (!REG_P (op)) | |
462 return 0; | |
463 | |
464 switch (REGNO (op)) | |
465 { | |
466 case TFHAR_REGNO: | |
467 case TFIAR_REGNO: | |
468 case TEXASR_REGNO: | |
469 return 1; | |
470 default: | |
471 break; | |
472 } | |
473 | |
474 /* Unknown SPR. */ | |
475 return 0; | |
476 }) | |
477 | |
478 ;; Return 1 if op is a general purpose register that is an even register | |
479 ;; which suitable for a load/store quad operation | |
480 ;; Subregs are not allowed here because when they are combine can | |
481 ;; create (subreg:PTI (reg:TI pseudo)) which will cause reload to | |
482 ;; think the innermost reg needs reloading, in TImode instead of | |
483 ;; PTImode. So reload will choose a reg in TImode which has no | |
484 ;; requirement that the reg be even. | |
485 (define_predicate "quad_int_reg_operand" | |
486 (match_code "reg") | |
487 { | |
488 HOST_WIDE_INT r; | |
489 | |
490 if (!TARGET_QUAD_MEMORY && !TARGET_QUAD_MEMORY_ATOMIC) | |
491 return 0; | |
492 | |
493 r = REGNO (op); | |
494 if (r >= FIRST_PSEUDO_REGISTER) | |
495 return 1; | |
496 | |
497 return (INT_REGNO_P (r) && ((r & 1) == 0)); | |
498 }) | |
0 | 499 |
500 ;; Return 1 if op is a register that is a condition register field. | |
501 (define_predicate "cc_reg_operand" | |
111 | 502 (match_operand 0 "register_operand") |
503 { | |
504 if (GET_CODE (op) == SUBREG) | |
505 op = SUBREG_REG (op); | |
506 | |
507 if (!REG_P (op)) | |
508 return 0; | |
509 | |
510 if (REGNO (op) > LAST_VIRTUAL_REGISTER) | |
511 return 1; | |
512 | |
513 return CR_REGNO_P (REGNO (op)); | |
514 }) | |
0 | 515 |
516 ;; Return 1 if op is a register that is a condition register field not cr0. | |
517 (define_predicate "cc_reg_not_cr0_operand" | |
111 | 518 (match_operand 0 "register_operand") |
519 { | |
520 if (GET_CODE (op) == SUBREG) | |
521 op = SUBREG_REG (op); | |
0 | 522 |
111 | 523 if (!REG_P (op)) |
524 return 0; | |
525 | |
526 if (REGNO (op) > LAST_VIRTUAL_REGISTER) | |
527 return 1; | |
528 | |
529 return CR_REGNO_NOT_CR0_P (REGNO (op)); | |
530 }) | |
0 | 531 |
532 ;; Return 1 if op is a constant integer valid for D field | |
533 ;; or non-special register register. | |
534 (define_predicate "reg_or_short_operand" | |
535 (if_then_else (match_code "const_int") | |
536 (match_operand 0 "short_cint_operand") | |
537 (match_operand 0 "gpc_reg_operand"))) | |
538 | |
539 ;; Return 1 if op is a constant integer valid for DS field | |
540 ;; or non-special register. | |
541 (define_predicate "reg_or_aligned_short_operand" | |
542 (if_then_else (match_code "const_int") | |
543 (and (match_operand 0 "short_cint_operand") | |
544 (match_test "!(INTVAL (op) & 3)")) | |
545 (match_operand 0 "gpc_reg_operand"))) | |
546 | |
547 ;; Return 1 if op is a constant integer whose high-order 16 bits are zero | |
548 ;; or non-special register. | |
549 (define_predicate "reg_or_u_short_operand" | |
550 (if_then_else (match_code "const_int") | |
551 (match_operand 0 "u_short_cint_operand") | |
552 (match_operand 0 "gpc_reg_operand"))) | |
553 | |
111 | 554 ;; Return 1 if op is any constant integer or a non-special register. |
0 | 555 (define_predicate "reg_or_cint_operand" |
556 (ior (match_code "const_int") | |
557 (match_operand 0 "gpc_reg_operand"))) | |
558 | |
111 | 559 ;; Return 1 if op is constant zero or a non-special register. |
560 (define_predicate "reg_or_zero_operand" | |
561 (ior (match_operand 0 "zero_constant") | |
562 (match_operand 0 "gpc_reg_operand"))) | |
563 | |
564 ;; Return 1 if op is a constant integer valid for addition with addis, addi. | |
565 (define_predicate "add_cint_operand" | |
566 (and (match_code "const_int") | |
567 (match_test "((unsigned HOST_WIDE_INT) INTVAL (op) | |
568 + (mode == SImode ? 0x80000000 : 0x80008000)) | |
569 < (unsigned HOST_WIDE_INT) 0x100000000ll"))) | |
570 | |
0 | 571 ;; Return 1 if op is a constant integer valid for addition |
572 ;; or non-special register. | |
573 (define_predicate "reg_or_add_cint_operand" | |
574 (if_then_else (match_code "const_int") | |
111 | 575 (match_operand 0 "add_cint_operand") |
0 | 576 (match_operand 0 "gpc_reg_operand"))) |
577 | |
578 ;; Return 1 if op is a constant integer valid for subtraction | |
579 ;; or non-special register. | |
580 (define_predicate "reg_or_sub_cint_operand" | |
581 (if_then_else (match_code "const_int") | |
111 | 582 (match_test "(unsigned HOST_WIDE_INT) |
583 (- UINTVAL (op) + (mode == SImode ? 0x80000000 : 0x80008000)) | |
584 < (unsigned HOST_WIDE_INT) 0x100000000ll") | |
0 | 585 (match_operand 0 "gpc_reg_operand"))) |
586 | |
587 ;; Return 1 if op is any 32-bit unsigned constant integer | |
588 ;; or non-special register. | |
589 (define_predicate "reg_or_logical_cint_operand" | |
590 (if_then_else (match_code "const_int") | |
591 (match_test "(GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT | |
592 && INTVAL (op) >= 0) | |
593 || ((INTVAL (op) & GET_MODE_MASK (mode) | |
594 & (~ (unsigned HOST_WIDE_INT) 0xffffffff)) == 0)") | |
111 | 595 (match_operand 0 "gpc_reg_operand"))) |
596 | |
597 ;; Like reg_or_logical_cint_operand, but allow vsx registers | |
598 (define_predicate "vsx_reg_or_cint_operand" | |
599 (ior (match_operand 0 "vsx_register_operand") | |
600 (match_operand 0 "reg_or_logical_cint_operand"))) | |
0 | 601 |
602 ;; Return 1 if operand is a CONST_DOUBLE that can be set in a register | |
603 ;; with no more than one instruction per word. | |
604 (define_predicate "easy_fp_constant" | |
605 (match_code "const_double") | |
606 { | |
607 if (GET_MODE (op) != mode | |
608 || (!SCALAR_FLOAT_MODE_P (mode) && mode != DImode)) | |
609 return 0; | |
610 | |
611 /* Consider all constants with -msoft-float to be easy. */ | |
131 | 612 if (TARGET_SOFT_FLOAT && mode != DImode) |
0 | 613 return 1; |
614 | |
111 | 615 /* 0.0D is not all zero bits. */ |
0 | 616 if (DECIMAL_FLOAT_MODE_P (mode)) |
617 return 0; | |
618 | |
111 | 619 /* The constant 0.0 is easy under VSX. */ |
620 if (TARGET_VSX && SCALAR_FLOAT_MODE_P (mode) && op == CONST0_RTX (mode)) | |
621 return 1; | |
622 | |
0 | 623 /* If we are using V.4 style PIC, consider all constants to be hard. */ |
624 if (flag_pic && DEFAULT_ABI == ABI_V4) | |
625 return 0; | |
626 | |
111 | 627 /* If we have real FPRs, consider floating point constants hard (other than |
628 0.0 under VSX), so that the constant gets pushed to memory during the | |
629 early RTL phases. This has the advantage that double precision constants | |
630 that can be represented in single precision without a loss of precision | |
631 will use single precision loads. */ | |
0 | 632 |
633 switch (mode) | |
634 { | |
111 | 635 case E_KFmode: |
636 case E_IFmode: | |
637 case E_TFmode: | |
638 case E_DFmode: | |
639 case E_SFmode: | |
640 return 0; | |
0 | 641 |
111 | 642 case E_DImode: |
643 return (num_insns_constant (op, DImode) <= 2); | |
0 | 644 |
111 | 645 case E_SImode: |
646 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
|
647 |
111 | 648 default: |
649 gcc_unreachable (); | |
650 } | |
651 }) | |
0 | 652 |
111 | 653 ;; Return 1 if the operand is a constant that can loaded with a XXSPLTIB |
654 ;; instruction and then a VUPKHSB, VECSB2W or VECSB2D instruction. | |
0 | 655 |
111 | 656 (define_predicate "xxspltib_constant_split" |
657 (match_code "const_vector,vec_duplicate,const_int") | |
658 { | |
659 int value = 256; | |
660 int num_insns = -1; | |
0 | 661 |
111 | 662 if (!xxspltib_constant_p (op, mode, &num_insns, &value)) |
663 return false; | |
664 | |
665 return num_insns > 1; | |
666 }) | |
667 | |
0 | 668 |
111 | 669 ;; Return 1 if the operand is constant that can loaded directly with a XXSPLTIB |
670 ;; instruction. | |
0 | 671 |
111 | 672 (define_predicate "xxspltib_constant_nosplit" |
673 (match_code "const_vector,vec_duplicate,const_int") | |
674 { | |
675 int value = 256; | |
676 int num_insns = -1; | |
0 | 677 |
111 | 678 if (!xxspltib_constant_p (op, mode, &num_insns, &value)) |
679 return false; | |
0 | 680 |
111 | 681 return num_insns == 1; |
0 | 682 }) |
683 | |
684 ;; Return 1 if the operand is a CONST_VECTOR and can be loaded into a | |
685 ;; vector register without using memory. | |
686 (define_predicate "easy_vector_constant" | |
687 (match_code "const_vector") | |
688 { | |
111 | 689 /* Because IEEE 128-bit floating point is considered a vector type |
690 in order to pass it in VSX registers, it might use this function | |
691 instead of easy_fp_constant. */ | |
692 if (FLOAT128_VECTOR_P (mode)) | |
693 return easy_fp_constant (op, mode); | |
694 | |
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
|
695 if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)) |
0 | 696 { |
111 | 697 int value = 256; |
698 int num_insns = -1; | |
699 | |
700 if (zero_constant (op, mode) || all_ones_constant (op, mode)) | |
701 return true; | |
702 | |
703 if (TARGET_P9_VECTOR | |
704 && 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
|
705 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
|
706 |
0 | 707 return easy_altivec_constant (op, mode); |
708 } | |
709 | |
710 return false; | |
711 }) | |
712 | |
713 ;; Same as easy_vector_constant but only for EASY_VECTOR_15_ADD_SELF. | |
714 (define_predicate "easy_vector_constant_add_self" | |
715 (and (match_code "const_vector") | |
716 (and (match_test "TARGET_ALTIVEC") | |
717 (match_test "easy_altivec_constant (op, mode)"))) | |
718 { | |
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
|
719 HOST_WIDE_INT val; |
111 | 720 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
|
721 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
|
722 return 0; |
111 | 723 elt = BYTES_BIG_ENDIAN ? GET_MODE_NUNITS (mode) - 1 : 0; |
724 val = const_vector_elt_as_int (op, elt); | |
0 | 725 val = ((val & 0xff) ^ 0x80) - 0x80; |
726 return EASY_VECTOR_15_ADD_SELF (val); | |
727 }) | |
728 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
729 ;; 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
|
730 (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
|
731 (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
|
732 (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
|
733 (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
|
734 { |
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
|
735 HOST_WIDE_INT val; |
111 | 736 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
|
737 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
|
738 return 0; |
111 | 739 elt = BYTES_BIG_ENDIAN ? GET_MODE_NUNITS (mode) - 1 : 0; |
740 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
|
741 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
|
742 }) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
743 |
111 | 744 ;; Return true if this is an easy altivec constant that we form |
745 ;; by using VSLDOI. | |
746 (define_predicate "easy_vector_constant_vsldoi" | |
747 (and (match_code "const_vector") | |
748 (and (match_test "TARGET_ALTIVEC") | |
749 (and (match_test "easy_altivec_constant (op, mode)") | |
750 (match_test "vspltis_shifted (op) != 0"))))) | |
751 | |
752 ;; Return 1 if operand is a vector int register or is either a vector constant | |
753 ;; of all 0 bits of a vector constant of all 1 bits. | |
754 (define_predicate "vector_int_reg_or_same_bit" | |
755 (match_code "reg,subreg,const_vector") | |
756 { | |
757 if (GET_MODE_CLASS (mode) != MODE_VECTOR_INT) | |
758 return 0; | |
759 | |
760 else if (REG_P (op) || SUBREG_P (op)) | |
761 return vint_operand (op, mode); | |
762 | |
763 else | |
764 return op == CONST0_RTX (mode) || op == CONSTM1_RTX (mode); | |
765 }) | |
0 | 766 |
767 ;; Return 1 if operand is 0.0. | |
768 (define_predicate "zero_fp_constant" | |
769 (and (match_code "const_double") | |
770 (match_test "SCALAR_FLOAT_MODE_P (mode) | |
771 && op == CONST0_RTX (mode)"))) | |
772 | |
773 ;; Return 1 if the operand is in volatile memory. Note that during the | |
774 ;; RTL generation phase, memory_operand does not return TRUE for volatile | |
775 ;; memory references. So this function allows us to recognize volatile | |
776 ;; references where it's safe. | |
777 (define_predicate "volatile_mem_operand" | |
778 (and (and (match_code "mem") | |
779 (match_test "MEM_VOLATILE_P (op)")) | |
780 (if_then_else (match_test "reload_completed") | |
111 | 781 (match_operand 0 "memory_operand") |
782 (match_test "memory_address_p (mode, XEXP (op, 0))")))) | |
0 | 783 |
784 ;; Return 1 if the operand is an offsettable memory operand. | |
785 (define_predicate "offsettable_mem_operand" | |
786 (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
|
787 (match_test "offsettable_nonstrict_memref_p (op)"))) |
0 | 788 |
111 | 789 ;; Return 1 if the operand is a simple offsettable memory operand |
790 ;; that does not include pre-increment, post-increment, etc. | |
791 (define_predicate "simple_offsettable_mem_operand" | |
792 (match_operand 0 "offsettable_mem_operand") | |
0 | 793 { |
111 | 794 rtx addr = XEXP (op, 0); |
795 | |
796 if (GET_CODE (addr) != PLUS && GET_CODE (addr) != LO_SUM) | |
797 return 0; | |
798 | |
799 if (!CONSTANT_P (XEXP (addr, 1))) | |
800 return 0; | |
801 | |
802 return base_reg_operand (XEXP (addr, 0), Pmode); | |
803 }) | |
0 | 804 |
111 | 805 ;; Return 1 if the operand is suitable for load/store quad memory. |
806 ;; This predicate only checks for non-atomic loads/stores (not lqarx/stqcx). | |
807 (define_predicate "quad_memory_operand" | |
808 (match_code "mem") | |
809 { | |
810 if (!TARGET_QUAD_MEMORY && !TARGET_SYNC_TI) | |
811 return false; | |
812 | |
813 if (GET_MODE_SIZE (mode) != 16 || !MEM_P (op) || MEM_ALIGN (op) < 128) | |
814 return false; | |
0 | 815 |
111 | 816 return quad_address_p (XEXP (op, 0), mode, false); |
817 }) | |
818 | |
819 ;; Return 1 if the operand is suitable for load/store to vector registers with | |
820 ;; d-form addressing (register+offset), which was added in ISA 3.0. | |
821 ;; Unlike quad_memory_operand, we do not have to check for alignment. | |
822 (define_predicate "vsx_quad_dform_memory_operand" | |
823 (match_code "mem") | |
824 { | |
825 if (!TARGET_P9_VECTOR || !MEM_P (op) || GET_MODE_SIZE (mode) != 16) | |
826 return false; | |
827 | |
828 return quad_address_p (XEXP (op, 0), mode, false); | |
0 | 829 }) |
830 | |
831 ;; Return 1 if the operand is an indexed or indirect memory operand. | |
832 (define_predicate "indexed_or_indirect_operand" | |
833 (match_code "mem") | |
834 { | |
835 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
|
836 if (VECTOR_MEM_ALTIVEC_P (mode) |
0 | 837 && GET_CODE (op) == AND |
838 && GET_CODE (XEXP (op, 1)) == CONST_INT | |
839 && INTVAL (XEXP (op, 1)) == -16) | |
840 op = XEXP (op, 0); | |
841 | |
842 return indexed_or_indirect_address (op, mode); | |
843 }) | |
844 | |
111 | 845 ;; Like indexed_or_indirect_operand, but also allow a GPR register if direct |
846 ;; moves are supported. | |
847 (define_predicate "reg_or_indexed_operand" | |
848 (match_code "mem,reg,subreg") | |
849 { | |
850 if (MEM_P (op)) | |
851 return indexed_or_indirect_operand (op, mode); | |
852 else if (TARGET_DIRECT_MOVE) | |
853 return register_operand (op, mode); | |
854 return | |
855 0; | |
856 }) | |
857 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
858 ;; 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
|
859 ;; 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
|
860 ;; 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
|
861 ;; 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
|
862 (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
|
863 (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
|
864 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
865 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
|
866 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
|
867 && 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
|
868 && 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
|
869 && 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
|
870 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
|
871 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
872 return 0; |
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 |
0 | 875 ;; Return 1 if the operand is an indexed or indirect address. |
876 (define_special_predicate "indexed_or_indirect_address" | |
877 (and (match_test "REG_P (op) | |
878 || (GET_CODE (op) == PLUS | |
879 /* Omit testing REG_P (XEXP (op, 0)). */ | |
880 && REG_P (XEXP (op, 1)))") | |
881 (match_operand 0 "address_operand"))) | |
882 | |
111 | 883 ;; Return 1 if the operand is an index-form address. |
884 (define_special_predicate "indexed_address" | |
885 (match_test "(GET_CODE (op) == PLUS | |
886 && REG_P (XEXP (op, 0)) | |
887 && REG_P (XEXP (op, 1)))")) | |
888 | |
889 ;; Return 1 if the operand is a MEM with an update-form address. This may | |
890 ;; also include update-indexed form. | |
891 (define_special_predicate "update_address_mem" | |
892 (match_test "(MEM_P (op) | |
893 && (GET_CODE (XEXP (op, 0)) == PRE_INC | |
894 || GET_CODE (XEXP (op, 0)) == PRE_DEC | |
895 || GET_CODE (XEXP (op, 0)) == PRE_MODIFY))")) | |
896 | |
897 ;; Return 1 if the operand is a MEM with an indexed-form address. | |
898 (define_special_predicate "indexed_address_mem" | |
899 (match_test "(MEM_P (op) | |
900 && (indexed_address (XEXP (op, 0), mode) | |
901 || (GET_CODE (XEXP (op, 0)) == PRE_MODIFY | |
902 && indexed_address (XEXP (XEXP (op, 0), 1), mode))))")) | |
0 | 903 |
904 ;; Return 1 if the operand is either a non-special register or can be used | |
905 ;; as the operand of a `mode' add insn. | |
906 (define_predicate "add_operand" | |
907 (if_then_else (match_code "const_int") | |
908 (match_test "satisfies_constraint_I (op) | |
909 || satisfies_constraint_L (op)") | |
910 (match_operand 0 "gpc_reg_operand"))) | |
911 | |
111 | 912 ;; Return 1 if the operand is either a non-special register, or 0, or -1. |
913 (define_predicate "adde_operand" | |
914 (if_then_else (match_code "const_int") | |
915 (match_test "INTVAL (op) == 0 || INTVAL (op) == -1") | |
916 (match_operand 0 "gpc_reg_operand"))) | |
917 | |
0 | 918 ;; Return 1 if OP is a constant but not a valid add_operand. |
919 (define_predicate "non_add_cint_operand" | |
920 (and (match_code "const_int") | |
921 (match_test "!satisfies_constraint_I (op) | |
922 && !satisfies_constraint_L (op)"))) | |
923 | |
924 ;; Return 1 if the operand is a constant that can be used as the operand | |
925 ;; of an OR or XOR. | |
926 (define_predicate "logical_const_operand" | |
111 | 927 (match_code "const_int") |
0 | 928 { |
111 | 929 HOST_WIDE_INT opl; |
0 | 930 |
111 | 931 opl = INTVAL (op) & GET_MODE_MASK (mode); |
0 | 932 |
933 return ((opl & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0 | |
934 || (opl & ~ (unsigned HOST_WIDE_INT) 0xffff0000) == 0); | |
935 }) | |
936 | |
937 ;; Return 1 if the operand is a non-special register or a constant that | |
938 ;; can be used as the operand of an OR or XOR. | |
939 (define_predicate "logical_operand" | |
940 (ior (match_operand 0 "gpc_reg_operand") | |
941 (match_operand 0 "logical_const_operand"))) | |
942 | |
943 ;; Return 1 if op is a constant that is not a logical operand, but could | |
944 ;; be split into one. | |
945 (define_predicate "non_logical_cint_operand" | |
111 | 946 (and (match_code "const_int,const_wide_int") |
0 | 947 (and (not (match_operand 0 "logical_operand")) |
948 (match_operand 0 "reg_or_logical_cint_operand")))) | |
949 | |
950 ;; Return 1 if the operand is either a non-special register or a | |
951 ;; constant that can be used as the operand of a logical AND. | |
952 (define_predicate "and_operand" | |
111 | 953 (ior (and (match_code "const_int") |
954 (match_test "rs6000_is_valid_and_mask (op, mode)")) | |
955 (if_then_else (match_test "fixed_regs[CR0_REGNO]") | |
956 (match_operand 0 "gpc_reg_operand") | |
957 (match_operand 0 "logical_operand")))) | |
0 | 958 |
959 ;; Return 1 if the operand is either a logical operand or a short cint operand. | |
960 (define_predicate "scc_eq_operand" | |
961 (ior (match_operand 0 "logical_operand") | |
962 (match_operand 0 "short_cint_operand"))) | |
963 | |
964 ;; Return 1 if the operand is a general non-special register or memory operand. | |
965 (define_predicate "reg_or_mem_operand" | |
111 | 966 (ior (match_operand 0 "memory_operand") |
967 (and (match_code "mem") | |
968 (match_test "macho_lo_sum_memory_operand (op, mode)")) | |
969 (match_operand 0 "volatile_mem_operand") | |
970 (match_operand 0 "gpc_reg_operand"))) | |
0 | 971 |
972 ;; Return 1 if the operand is CONST_DOUBLE 0, register or memory operand. | |
973 (define_predicate "zero_reg_mem_operand" | |
111 | 974 (ior (and (match_test "TARGET_VSX") |
975 (match_operand 0 "zero_fp_constant")) | |
0 | 976 (match_operand 0 "reg_or_mem_operand"))) |
977 | |
111 | 978 ;; Return 1 if the operand is a CONST_INT and it is the element for 64-bit |
979 ;; data types inside of a vector that scalar instructions operate on | |
980 (define_predicate "vsx_scalar_64bit" | |
981 (match_code "const_int") | |
982 { | |
983 return (INTVAL (op) == VECTOR_ELEMENT_SCALAR_64BIT); | |
984 }) | |
985 | |
0 | 986 ;; Return 1 if the operand is a general register or memory operand without |
987 ;; pre_inc or pre_dec or pre_modify, which produces invalid form of PowerPC | |
988 ;; lwa instruction. | |
989 (define_predicate "lwa_operand" | |
990 (match_code "reg,subreg,mem") | |
991 { | |
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
|
992 rtx inner, addr, offset; |
0 | 993 |
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
|
994 inner = op; |
0 | 995 if (reload_completed && GET_CODE (inner) == SUBREG) |
996 inner = SUBREG_REG (inner); | |
997 | |
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
|
998 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
|
999 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
|
1000 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
|
1001 return false; |
111 | 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 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
|
1004 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
|
1005 || 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
|
1006 || (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
|
1007 && !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
|
1008 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
|
1009 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
|
1010 && 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
|
1011 && 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
|
1012 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
|
1013 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
|
1014 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
|
1015 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
|
1016 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
|
1017 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
|
1018 return INTVAL (offset) % 4 == 0; |
0 | 1019 }) |
1020 | |
1021 ;; Return 1 if the operand, used inside a MEM, is a SYMBOL_REF. | |
1022 (define_predicate "symbol_ref_operand" | |
1023 (and (match_code "symbol_ref") | |
1024 (match_test "(mode == VOIDmode || GET_MODE (op) == mode) | |
1025 && (DEFAULT_ABI != ABI_AIX || SYMBOL_REF_FUNCTION_P (op))"))) | |
1026 | |
1027 ;; Return 1 if op is an operand that can be loaded via the GOT. | |
1028 ;; or non-special register register field no cr0 | |
1029 (define_predicate "got_operand" | |
1030 (match_code "symbol_ref,const,label_ref")) | |
1031 | |
1032 ;; Return 1 if op is a simple reference that can be loaded via the GOT, | |
1033 ;; excluding labels involving addition. | |
1034 (define_predicate "got_no_const_operand" | |
1035 (match_code "symbol_ref,label_ref")) | |
1036 | |
1037 ;; Return 1 if op is a SYMBOL_REF for a TLS symbol. | |
1038 (define_predicate "rs6000_tls_symbol_ref" | |
1039 (and (match_code "symbol_ref") | |
1040 (match_test "RS6000_SYMBOL_REF_TLS_P (op)"))) | |
1041 | |
1042 ;; Return 1 if the operand, used inside a MEM, is a valid first argument | |
1043 ;; to CALL. This is a SYMBOL_REF, a pseudo-register, LR or CTR. | |
1044 (define_predicate "call_operand" | |
1045 (if_then_else (match_code "reg") | |
1046 (match_test "REGNO (op) == LR_REGNO | |
1047 || REGNO (op) == CTR_REGNO | |
1048 || REGNO (op) >= FIRST_PSEUDO_REGISTER") | |
1049 (match_code "symbol_ref"))) | |
1050 | |
1051 ;; Return 1 if the operand is a SYMBOL_REF for a function known to be in | |
1052 ;; this file. | |
1053 (define_predicate "current_file_function_operand" | |
1054 (and (match_code "symbol_ref") | |
1055 (match_test "(DEFAULT_ABI != ABI_AIX || SYMBOL_REF_FUNCTION_P (op)) | |
111 | 1056 && (SYMBOL_REF_LOCAL_P (op) |
1057 || (op == XEXP (DECL_RTL (current_function_decl), 0) | |
1058 && !decl_replaceable_p (current_function_decl))) | |
1059 && !((DEFAULT_ABI == ABI_AIX | |
1060 || DEFAULT_ABI == ABI_ELFv2) | |
1061 && (SYMBOL_REF_EXTERNAL_P (op) | |
1062 || SYMBOL_REF_WEAK (op)))"))) | |
0 | 1063 |
1064 ;; Return 1 if this operand is a valid input for a move insn. | |
1065 (define_predicate "input_operand" | |
111 | 1066 (match_code "symbol_ref,const,reg,subreg,mem, |
1067 const_double,const_wide_int,const_vector,const_int") | |
0 | 1068 { |
1069 /* Memory is always valid. */ | |
1070 if (memory_operand (op, mode)) | |
1071 return 1; | |
1072 | |
1073 /* For floating-point, easy constants are valid. */ | |
1074 if (SCALAR_FLOAT_MODE_P (mode) | |
1075 && easy_fp_constant (op, mode)) | |
1076 return 1; | |
1077 | |
1078 /* Allow any integer constant. */ | |
1079 if (GET_MODE_CLASS (mode) == MODE_INT | |
111 | 1080 && CONST_SCALAR_INT_P (op)) |
0 | 1081 return 1; |
1082 | |
1083 /* Allow easy vector constants. */ | |
1084 if (GET_CODE (op) == CONST_VECTOR | |
1085 && easy_vector_constant (op, mode)) | |
1086 return 1; | |
1087 | |
1088 /* For floating-point or multi-word mode, the only remaining valid type | |
1089 is a register. */ | |
1090 if (SCALAR_FLOAT_MODE_P (mode) | |
1091 || GET_MODE_SIZE (mode) > UNITS_PER_WORD) | |
1092 return register_operand (op, mode); | |
1093 | |
111 | 1094 /* We don't allow moving the carry bit around. */ |
1095 if (ca_operand (op, mode)) | |
1096 return 0; | |
1097 | |
0 | 1098 /* The only cases left are integral modes one word or smaller (we |
1099 do not get called for MODE_CC values). These can be in any | |
1100 register. */ | |
1101 if (register_operand (op, mode)) | |
1102 return 1; | |
1103 | |
1104 /* V.4 allows SYMBOL_REFs and CONSTs that are in the small data region | |
1105 to be valid. */ | |
1106 if (DEFAULT_ABI == ABI_V4 | |
1107 && (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == CONST) | |
1108 && small_data_operand (op, Pmode)) | |
1109 return 1; | |
1110 | |
1111 return 0; | |
1112 }) | |
1113 | |
111 | 1114 ;; Return 1 if this operand is a valid input for a vsx_splat insn. |
1115 (define_predicate "splat_input_operand" | |
0 | 1116 (match_code "reg,subreg,mem") |
1117 { | |
111 | 1118 machine_mode vmode; |
1119 | |
1120 if (mode == DFmode) | |
1121 vmode = V2DFmode; | |
1122 else if (mode == DImode) | |
1123 vmode = V2DImode; | |
1124 else if (mode == SImode && TARGET_P9_VECTOR) | |
1125 vmode = V4SImode; | |
1126 else if (mode == SFmode && TARGET_P9_VECTOR) | |
1127 vmode = V4SFmode; | |
1128 else | |
1129 return false; | |
0 | 1130 |
111 | 1131 if (MEM_P (op)) |
1132 { | |
1133 rtx addr = XEXP (op, 0); | |
1134 | |
1135 if (! volatile_ok && MEM_VOLATILE_P (op)) | |
1136 return 0; | |
1137 | |
1138 if (lra_in_progress || reload_completed) | |
1139 return indexed_or_indirect_address (addr, vmode); | |
1140 else | |
1141 return memory_address_addr_space_p (vmode, addr, MEM_ADDR_SPACE (op)); | |
1142 } | |
1143 return gpc_reg_operand (op, mode); | |
0 | 1144 }) |
1145 | |
111 | 1146 ;; Return true if operand is an operator used in rotate-and-mask instructions. |
1147 (define_predicate "rotate_mask_operator" | |
1148 (match_code "rotate,ashift,lshiftrt")) | |
1149 | |
0 | 1150 ;; Return true if operand is boolean operator. |
1151 (define_predicate "boolean_operator" | |
1152 (match_code "and,ior,xor")) | |
1153 | |
1154 ;; Return true if operand is OR-form of boolean operator. | |
1155 (define_predicate "boolean_or_operator" | |
1156 (match_code "ior,xor")) | |
1157 | |
1158 ;; Return true if operand is an equality operator. | |
1159 (define_special_predicate "equality_operator" | |
1160 (match_code "eq,ne")) | |
1161 | |
1162 ;; Return 1 if OP is a comparison operation that is valid for a branch | |
1163 ;; instruction. We check the opcode against the mode of the CC value. | |
1164 ;; validate_condition_mode is an assertion. | |
1165 (define_predicate "branch_comparison_operator" | |
1166 (and (match_operand 0 "comparison_operator") | |
1167 (and (match_test "GET_MODE_CLASS (GET_MODE (XEXP (op, 0))) == MODE_CC") | |
1168 (match_test "validate_condition_mode (GET_CODE (op), | |
1169 GET_MODE (XEXP (op, 0))), | |
1170 1")))) | |
1171 | |
111 | 1172 ;; Return 1 if OP is an unsigned comparison operator. |
1173 (define_predicate "unsigned_comparison_operator" | |
1174 (match_code "ltu,gtu,leu,geu")) | |
1175 | |
1176 ;; Return 1 if OP is a signed comparison operator. | |
1177 (define_predicate "signed_comparison_operator" | |
1178 (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
|
1179 |
0 | 1180 ;; Return 1 if OP is a comparison operation that is valid for an SCC insn -- |
1181 ;; it must be a positive comparison. | |
1182 (define_predicate "scc_comparison_operator" | |
1183 (and (match_operand 0 "branch_comparison_operator") | |
1184 (match_code "eq,lt,gt,ltu,gtu,unordered"))) | |
1185 | |
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
|
1186 ;; 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
|
1187 ;; 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
|
1188 (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
|
1189 (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
|
1190 (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
|
1191 |
111 | 1192 ;; Return 1 if OP is a comparison operator suitable for floating point |
1193 ;; vector/scalar comparisons that generate a -1/0 mask. | |
1194 (define_predicate "fpmask_comparison_operator" | |
1195 (match_code "eq,gt,ge")) | |
1196 | |
1197 ;; Return 1 if OP is a comparison operator suitable for vector/scalar | |
1198 ;; comparisons that generate a 0/-1 mask (i.e. the inverse of | |
1199 ;; fpmask_comparison_operator). | |
1200 (define_predicate "invert_fpmask_comparison_operator" | |
1201 (match_code "ne,unlt,unle")) | |
1202 | |
1203 ;; Return 1 if OP is a comparison operation suitable for integer vector/scalar | |
1204 ;; comparisons that generate a -1/0 mask. | |
1205 (define_predicate "vecint_comparison_operator" | |
1206 (match_code "eq,gt,gtu")) | |
1207 | |
0 | 1208 ;; Return 1 if OP is a comparison operation that is valid for a branch |
1209 ;; insn, which is true if the corresponding bit in the CC register is set. | |
1210 (define_predicate "branch_positive_comparison_operator" | |
1211 (and (match_operand 0 "branch_comparison_operator") | |
1212 (match_code "eq,lt,gt,ltu,gtu,unordered"))) | |
1213 | |
1214 ;; Return 1 if OP is valid for a save_world call in prologue, known to be | |
1215 ;; a PARLLEL. | |
1216 (define_predicate "save_world_operation" | |
1217 (match_code "parallel") | |
1218 { | |
1219 int index; | |
1220 int i; | |
1221 rtx elt; | |
1222 int count = XVECLEN (op, 0); | |
1223 | |
1224 if (count != 54) | |
1225 return 0; | |
1226 | |
1227 index = 0; | |
1228 if (GET_CODE (XVECEXP (op, 0, index++)) != CLOBBER | |
1229 || GET_CODE (XVECEXP (op, 0, index++)) != USE) | |
1230 return 0; | |
1231 | |
1232 for (i=1; i <= 18; i++) | |
1233 { | |
1234 elt = XVECEXP (op, 0, index++); | |
1235 if (GET_CODE (elt) != SET | |
1236 || GET_CODE (SET_DEST (elt)) != MEM | |
1237 || ! memory_operand (SET_DEST (elt), DFmode) | |
1238 || GET_CODE (SET_SRC (elt)) != REG | |
1239 || GET_MODE (SET_SRC (elt)) != DFmode) | |
1240 return 0; | |
1241 } | |
1242 | |
1243 for (i=1; i <= 12; i++) | |
1244 { | |
1245 elt = XVECEXP (op, 0, index++); | |
1246 if (GET_CODE (elt) != SET | |
1247 || GET_CODE (SET_DEST (elt)) != MEM | |
1248 || GET_CODE (SET_SRC (elt)) != REG | |
1249 || GET_MODE (SET_SRC (elt)) != V4SImode) | |
1250 return 0; | |
1251 } | |
1252 | |
1253 for (i=1; i <= 19; i++) | |
1254 { | |
1255 elt = XVECEXP (op, 0, index++); | |
1256 if (GET_CODE (elt) != SET | |
1257 || GET_CODE (SET_DEST (elt)) != MEM | |
1258 || ! memory_operand (SET_DEST (elt), Pmode) | |
1259 || GET_CODE (SET_SRC (elt)) != REG | |
1260 || GET_MODE (SET_SRC (elt)) != Pmode) | |
1261 return 0; | |
1262 } | |
1263 | |
1264 elt = XVECEXP (op, 0, index++); | |
1265 if (GET_CODE (elt) != SET | |
1266 || GET_CODE (SET_DEST (elt)) != MEM | |
1267 || ! memory_operand (SET_DEST (elt), Pmode) | |
1268 || GET_CODE (SET_SRC (elt)) != REG | |
1269 || REGNO (SET_SRC (elt)) != CR2_REGNO | |
1270 || GET_MODE (SET_SRC (elt)) != Pmode) | |
1271 return 0; | |
1272 | |
1273 if (GET_CODE (XVECEXP (op, 0, index++)) != SET | |
1274 || GET_CODE (XVECEXP (op, 0, index++)) != SET) | |
1275 return 0; | |
1276 return 1; | |
1277 }) | |
1278 | |
1279 ;; Return 1 if OP is valid for a restore_world call in epilogue, known to be | |
1280 ;; a PARLLEL. | |
1281 (define_predicate "restore_world_operation" | |
1282 (match_code "parallel") | |
1283 { | |
1284 int index; | |
1285 int i; | |
1286 rtx elt; | |
1287 int count = XVECLEN (op, 0); | |
1288 | |
131 | 1289 if (count != 58) |
0 | 1290 return 0; |
1291 | |
1292 index = 0; | |
1293 if (GET_CODE (XVECEXP (op, 0, index++)) != RETURN | |
1294 || GET_CODE (XVECEXP (op, 0, index++)) != USE | |
1295 || GET_CODE (XVECEXP (op, 0, index++)) != CLOBBER) | |
1296 return 0; | |
1297 | |
1298 elt = XVECEXP (op, 0, index++); | |
1299 if (GET_CODE (elt) != SET | |
1300 || GET_CODE (SET_SRC (elt)) != MEM | |
1301 || ! memory_operand (SET_SRC (elt), Pmode) | |
1302 || GET_CODE (SET_DEST (elt)) != REG | |
1303 || REGNO (SET_DEST (elt)) != CR2_REGNO | |
1304 || GET_MODE (SET_DEST (elt)) != Pmode) | |
1305 return 0; | |
1306 | |
1307 for (i=1; i <= 19; i++) | |
1308 { | |
1309 elt = XVECEXP (op, 0, index++); | |
1310 if (GET_CODE (elt) != SET | |
1311 || GET_CODE (SET_SRC (elt)) != MEM | |
1312 || ! memory_operand (SET_SRC (elt), Pmode) | |
1313 || GET_CODE (SET_DEST (elt)) != REG | |
1314 || GET_MODE (SET_DEST (elt)) != Pmode) | |
1315 return 0; | |
1316 } | |
1317 | |
1318 for (i=1; i <= 12; i++) | |
1319 { | |
1320 elt = XVECEXP (op, 0, index++); | |
1321 if (GET_CODE (elt) != SET | |
1322 || GET_CODE (SET_SRC (elt)) != MEM | |
1323 || GET_CODE (SET_DEST (elt)) != REG | |
1324 || GET_MODE (SET_DEST (elt)) != V4SImode) | |
1325 return 0; | |
1326 } | |
1327 | |
1328 for (i=1; i <= 18; i++) | |
1329 { | |
1330 elt = XVECEXP (op, 0, index++); | |
1331 if (GET_CODE (elt) != SET | |
1332 || GET_CODE (SET_SRC (elt)) != MEM | |
1333 || ! memory_operand (SET_SRC (elt), DFmode) | |
1334 || GET_CODE (SET_DEST (elt)) != REG | |
1335 || GET_MODE (SET_DEST (elt)) != DFmode) | |
1336 return 0; | |
1337 } | |
1338 | |
1339 if (GET_CODE (XVECEXP (op, 0, index++)) != CLOBBER | |
1340 || GET_CODE (XVECEXP (op, 0, index++)) != CLOBBER | |
1341 || GET_CODE (XVECEXP (op, 0, index++)) != CLOBBER | |
1342 || GET_CODE (XVECEXP (op, 0, index++)) != CLOBBER | |
1343 || GET_CODE (XVECEXP (op, 0, index++)) != USE) | |
1344 return 0; | |
1345 return 1; | |
1346 }) | |
1347 | |
1348 ;; Return 1 if OP is valid for a vrsave call, known to be a PARALLEL. | |
1349 (define_predicate "vrsave_operation" | |
1350 (match_code "parallel") | |
1351 { | |
1352 int count = XVECLEN (op, 0); | |
1353 unsigned int dest_regno, src_regno; | |
1354 int i; | |
1355 | |
1356 if (count <= 1 | |
1357 || GET_CODE (XVECEXP (op, 0, 0)) != SET | |
1358 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG | |
1359 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != UNSPEC_VOLATILE | |
1360 || XINT (SET_SRC (XVECEXP (op, 0, 0)), 1) != UNSPECV_SET_VRSAVE) | |
1361 return 0; | |
1362 | |
1363 dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0))); | |
1364 src_regno = REGNO (XVECEXP (SET_SRC (XVECEXP (op, 0, 0)), 0, 1)); | |
1365 | |
1366 if (dest_regno != VRSAVE_REGNO || src_regno != VRSAVE_REGNO) | |
1367 return 0; | |
1368 | |
1369 for (i = 1; i < count; i++) | |
1370 { | |
1371 rtx elt = XVECEXP (op, 0, i); | |
1372 | |
1373 if (GET_CODE (elt) != CLOBBER | |
1374 && GET_CODE (elt) != SET) | |
1375 return 0; | |
1376 } | |
1377 | |
1378 return 1; | |
1379 }) | |
1380 | |
1381 ;; Return 1 if OP is valid for mfcr insn, known to be a PARALLEL. | |
1382 (define_predicate "mfcr_operation" | |
1383 (match_code "parallel") | |
1384 { | |
1385 int count = XVECLEN (op, 0); | |
1386 int i; | |
1387 | |
1388 /* Perform a quick check so we don't blow up below. */ | |
1389 if (count < 1 | |
1390 || GET_CODE (XVECEXP (op, 0, 0)) != SET | |
1391 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != UNSPEC | |
1392 || XVECLEN (SET_SRC (XVECEXP (op, 0, 0)), 0) != 2) | |
1393 return 0; | |
1394 | |
1395 for (i = 0; i < count; i++) | |
1396 { | |
1397 rtx exp = XVECEXP (op, 0, i); | |
1398 rtx unspec; | |
1399 int maskval; | |
1400 rtx src_reg; | |
1401 | |
1402 src_reg = XVECEXP (SET_SRC (exp), 0, 0); | |
1403 | |
1404 if (GET_CODE (src_reg) != REG | |
1405 || GET_MODE (src_reg) != CCmode | |
1406 || ! CR_REGNO_P (REGNO (src_reg))) | |
1407 return 0; | |
1408 | |
1409 if (GET_CODE (exp) != SET | |
1410 || GET_CODE (SET_DEST (exp)) != REG | |
1411 || GET_MODE (SET_DEST (exp)) != SImode | |
1412 || ! INT_REGNO_P (REGNO (SET_DEST (exp)))) | |
1413 return 0; | |
1414 unspec = SET_SRC (exp); | |
1415 maskval = 1 << (MAX_CR_REGNO - REGNO (src_reg)); | |
1416 | |
1417 if (GET_CODE (unspec) != UNSPEC | |
1418 || XINT (unspec, 1) != UNSPEC_MOVESI_FROM_CR | |
1419 || XVECLEN (unspec, 0) != 2 | |
1420 || XVECEXP (unspec, 0, 0) != src_reg | |
1421 || GET_CODE (XVECEXP (unspec, 0, 1)) != CONST_INT | |
1422 || INTVAL (XVECEXP (unspec, 0, 1)) != maskval) | |
1423 return 0; | |
1424 } | |
1425 return 1; | |
1426 }) | |
1427 | |
1428 ;; Return 1 if OP is valid for mtcrf insn, known to be a PARALLEL. | |
1429 (define_predicate "mtcrf_operation" | |
1430 (match_code "parallel") | |
1431 { | |
1432 int count = XVECLEN (op, 0); | |
1433 int i; | |
1434 rtx src_reg; | |
1435 | |
1436 /* Perform a quick check so we don't blow up below. */ | |
1437 if (count < 1 | |
1438 || GET_CODE (XVECEXP (op, 0, 0)) != SET | |
1439 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != UNSPEC | |
1440 || XVECLEN (SET_SRC (XVECEXP (op, 0, 0)), 0) != 2) | |
1441 return 0; | |
1442 src_reg = XVECEXP (SET_SRC (XVECEXP (op, 0, 0)), 0, 0); | |
1443 | |
1444 if (GET_CODE (src_reg) != REG | |
1445 || GET_MODE (src_reg) != SImode | |
1446 || ! INT_REGNO_P (REGNO (src_reg))) | |
1447 return 0; | |
1448 | |
1449 for (i = 0; i < count; i++) | |
1450 { | |
1451 rtx exp = XVECEXP (op, 0, i); | |
1452 rtx unspec; | |
1453 int maskval; | |
1454 | |
1455 if (GET_CODE (exp) != SET | |
1456 || GET_CODE (SET_DEST (exp)) != REG | |
1457 || GET_MODE (SET_DEST (exp)) != CCmode | |
1458 || ! CR_REGNO_P (REGNO (SET_DEST (exp)))) | |
1459 return 0; | |
1460 unspec = SET_SRC (exp); | |
1461 maskval = 1 << (MAX_CR_REGNO - REGNO (SET_DEST (exp))); | |
1462 | |
1463 if (GET_CODE (unspec) != UNSPEC | |
1464 || XINT (unspec, 1) != UNSPEC_MOVESI_TO_CR | |
1465 || XVECLEN (unspec, 0) != 2 | |
1466 || XVECEXP (unspec, 0, 0) != src_reg | |
1467 || GET_CODE (XVECEXP (unspec, 0, 1)) != CONST_INT | |
1468 || INTVAL (XVECEXP (unspec, 0, 1)) != maskval) | |
1469 return 0; | |
1470 } | |
1471 return 1; | |
1472 }) | |
1473 | |
111 | 1474 ;; Return 1 if OP is valid for crsave insn, known to be a PARALLEL. |
1475 (define_predicate "crsave_operation" | |
1476 (match_code "parallel") | |
1477 { | |
1478 int count = XVECLEN (op, 0); | |
1479 int i; | |
1480 | |
1481 for (i = 1; i < count; i++) | |
1482 { | |
1483 rtx exp = XVECEXP (op, 0, i); | |
1484 | |
1485 if (GET_CODE (exp) != USE | |
1486 || GET_CODE (XEXP (exp, 0)) != REG | |
1487 || GET_MODE (XEXP (exp, 0)) != CCmode | |
1488 || ! CR_REGNO_P (REGNO (XEXP (exp, 0)))) | |
1489 return 0; | |
1490 } | |
1491 return 1; | |
1492 }) | |
1493 | |
0 | 1494 ;; Return 1 if OP is valid for lmw insn, known to be a PARALLEL. |
1495 (define_predicate "lmw_operation" | |
1496 (match_code "parallel") | |
1497 { | |
1498 int count = XVECLEN (op, 0); | |
1499 unsigned int dest_regno; | |
1500 rtx src_addr; | |
1501 unsigned int base_regno; | |
1502 HOST_WIDE_INT offset; | |
1503 int i; | |
1504 | |
1505 /* Perform a quick check so we don't blow up below. */ | |
1506 if (count <= 1 | |
1507 || GET_CODE (XVECEXP (op, 0, 0)) != SET | |
1508 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG | |
1509 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != MEM) | |
1510 return 0; | |
1511 | |
1512 dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0))); | |
1513 src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0); | |
1514 | |
1515 if (dest_regno > 31 | |
1516 || count != 32 - (int) dest_regno) | |
1517 return 0; | |
1518 | |
1519 if (legitimate_indirect_address_p (src_addr, 0)) | |
1520 { | |
1521 offset = 0; | |
1522 base_regno = REGNO (src_addr); | |
1523 if (base_regno == 0) | |
1524 return 0; | |
1525 } | |
111 | 1526 else if (rs6000_legitimate_offset_address_p (SImode, src_addr, false, false)) |
0 | 1527 { |
1528 offset = INTVAL (XEXP (src_addr, 1)); | |
1529 base_regno = REGNO (XEXP (src_addr, 0)); | |
1530 } | |
1531 else | |
1532 return 0; | |
1533 | |
1534 for (i = 0; i < count; i++) | |
1535 { | |
1536 rtx elt = XVECEXP (op, 0, i); | |
1537 rtx newaddr; | |
1538 rtx addr_reg; | |
1539 HOST_WIDE_INT newoffset; | |
1540 | |
1541 if (GET_CODE (elt) != SET | |
1542 || GET_CODE (SET_DEST (elt)) != REG | |
1543 || GET_MODE (SET_DEST (elt)) != SImode | |
1544 || REGNO (SET_DEST (elt)) != dest_regno + i | |
1545 || GET_CODE (SET_SRC (elt)) != MEM | |
1546 || GET_MODE (SET_SRC (elt)) != SImode) | |
1547 return 0; | |
1548 newaddr = XEXP (SET_SRC (elt), 0); | |
1549 if (legitimate_indirect_address_p (newaddr, 0)) | |
1550 { | |
1551 newoffset = 0; | |
1552 addr_reg = newaddr; | |
1553 } | |
111 | 1554 else if (rs6000_legitimate_offset_address_p (SImode, newaddr, false, false)) |
0 | 1555 { |
1556 addr_reg = XEXP (newaddr, 0); | |
1557 newoffset = INTVAL (XEXP (newaddr, 1)); | |
1558 } | |
1559 else | |
1560 return 0; | |
1561 if (REGNO (addr_reg) != base_regno | |
1562 || newoffset != offset + 4 * i) | |
1563 return 0; | |
1564 } | |
1565 | |
1566 return 1; | |
1567 }) | |
1568 | |
1569 ;; Return 1 if OP is valid for stmw insn, known to be a PARALLEL. | |
1570 (define_predicate "stmw_operation" | |
1571 (match_code "parallel") | |
1572 { | |
1573 int count = XVECLEN (op, 0); | |
1574 unsigned int src_regno; | |
1575 rtx dest_addr; | |
1576 unsigned int base_regno; | |
1577 HOST_WIDE_INT offset; | |
1578 int i; | |
1579 | |
1580 /* Perform a quick check so we don't blow up below. */ | |
1581 if (count <= 1 | |
1582 || GET_CODE (XVECEXP (op, 0, 0)) != SET | |
1583 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != MEM | |
1584 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != REG) | |
1585 return 0; | |
1586 | |
1587 src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0))); | |
1588 dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0); | |
1589 | |
1590 if (src_regno > 31 | |
1591 || count != 32 - (int) src_regno) | |
1592 return 0; | |
1593 | |
1594 if (legitimate_indirect_address_p (dest_addr, 0)) | |
1595 { | |
1596 offset = 0; | |
1597 base_regno = REGNO (dest_addr); | |
1598 if (base_regno == 0) | |
1599 return 0; | |
1600 } | |
111 | 1601 else if (rs6000_legitimate_offset_address_p (SImode, dest_addr, false, false)) |
0 | 1602 { |
1603 offset = INTVAL (XEXP (dest_addr, 1)); | |
1604 base_regno = REGNO (XEXP (dest_addr, 0)); | |
1605 } | |
1606 else | |
1607 return 0; | |
1608 | |
1609 for (i = 0; i < count; i++) | |
1610 { | |
1611 rtx elt = XVECEXP (op, 0, i); | |
1612 rtx newaddr; | |
1613 rtx addr_reg; | |
1614 HOST_WIDE_INT newoffset; | |
1615 | |
1616 if (GET_CODE (elt) != SET | |
1617 || GET_CODE (SET_SRC (elt)) != REG | |
1618 || GET_MODE (SET_SRC (elt)) != SImode | |
1619 || REGNO (SET_SRC (elt)) != src_regno + i | |
1620 || GET_CODE (SET_DEST (elt)) != MEM | |
1621 || GET_MODE (SET_DEST (elt)) != SImode) | |
1622 return 0; | |
1623 newaddr = XEXP (SET_DEST (elt), 0); | |
1624 if (legitimate_indirect_address_p (newaddr, 0)) | |
1625 { | |
1626 newoffset = 0; | |
1627 addr_reg = newaddr; | |
1628 } | |
111 | 1629 else if (rs6000_legitimate_offset_address_p (SImode, newaddr, false, false)) |
0 | 1630 { |
1631 addr_reg = XEXP (newaddr, 0); | |
1632 newoffset = INTVAL (XEXP (newaddr, 1)); | |
1633 } | |
1634 else | |
1635 return 0; | |
1636 if (REGNO (addr_reg) != base_regno | |
1637 || newoffset != offset + 4 * i) | |
1638 return 0; | |
1639 } | |
1640 | |
1641 return 1; | |
1642 }) | |
111 | 1643 |
1644 ;; Return 1 if OP is a stack tie operand. | |
1645 (define_predicate "tie_operand" | |
1646 (match_code "parallel") | |
1647 { | |
1648 return (GET_CODE (XVECEXP (op, 0, 0)) == SET | |
1649 && GET_CODE (XEXP (XVECEXP (op, 0, 0), 0)) == MEM | |
1650 && GET_MODE (XEXP (XVECEXP (op, 0, 0), 0)) == BLKmode | |
1651 && XEXP (XVECEXP (op, 0, 0), 1) == const0_rtx); | |
1652 }) | |
1653 | |
1654 ;; Match a small code model toc reference (or medium and large | |
1655 ;; model toc references before reload). | |
1656 (define_predicate "small_toc_ref" | |
1657 (match_code "unspec,plus") | |
1658 { | |
1659 if (GET_CODE (op) == PLUS && add_cint_operand (XEXP (op, 1), mode)) | |
1660 op = XEXP (op, 0); | |
1661 | |
1662 return GET_CODE (op) == UNSPEC && XINT (op, 1) == UNSPEC_TOCREL; | |
1663 }) | |
1664 | |
1665 ;; Match the first insn (addis) in fusing the combination of addis and loads to | |
1666 ;; GPR registers on power8. | |
1667 (define_predicate "fusion_gpr_addis" | |
1668 (match_code "const_int,high,plus") | |
1669 { | |
1670 HOST_WIDE_INT value; | |
1671 rtx int_const; | |
1672 | |
1673 if (GET_CODE (op) == HIGH) | |
1674 return 1; | |
1675 | |
1676 if (CONST_INT_P (op)) | |
1677 int_const = op; | |
1678 | |
1679 else if (GET_CODE (op) == PLUS | |
1680 && base_reg_operand (XEXP (op, 0), Pmode) | |
1681 && CONST_INT_P (XEXP (op, 1))) | |
1682 int_const = XEXP (op, 1); | |
1683 | |
1684 else | |
1685 return 0; | |
1686 | |
1687 value = INTVAL (int_const); | |
1688 if ((value & (HOST_WIDE_INT)0xffff) != 0) | |
1689 return 0; | |
1690 | |
1691 if ((value & (HOST_WIDE_INT)0xffff0000) == 0) | |
1692 return 0; | |
1693 | |
1694 /* Power8 currently will only do the fusion if the top 11 bits of the addis | |
1695 value are all 1's or 0's. Ignore this restriction if we are testing | |
1696 advanced fusion. */ | |
1697 if (TARGET_P9_FUSION) | |
1698 return 1; | |
1699 | |
1700 return (IN_RANGE (value >> 16, -32, 31)); | |
1701 }) | |
1702 | |
1703 ;; Match the second insn (lbz, lhz, lwz, ld) in fusing the combination of addis | |
1704 ;; and loads to GPR registers on power8. | |
1705 (define_predicate "fusion_gpr_mem_load" | |
1706 (match_code "mem,sign_extend,zero_extend") | |
1707 { | |
1708 rtx addr, base, offset; | |
1709 | |
1710 /* Handle sign/zero extend. */ | |
1711 if (GET_CODE (op) == ZERO_EXTEND | |
1712 || (TARGET_P8_FUSION_SIGN && GET_CODE (op) == SIGN_EXTEND)) | |
1713 { | |
1714 op = XEXP (op, 0); | |
1715 mode = GET_MODE (op); | |
1716 } | |
1717 | |
1718 if (!MEM_P (op)) | |
1719 return 0; | |
1720 | |
1721 switch (mode) | |
1722 { | |
1723 case E_QImode: | |
1724 case E_HImode: | |
1725 case E_SImode: | |
1726 break; | |
1727 | |
1728 case E_DImode: | |
1729 if (!TARGET_POWERPC64) | |
1730 return 0; | |
1731 break; | |
1732 | |
1733 default: | |
1734 return 0; | |
1735 } | |
1736 | |
1737 addr = XEXP (op, 0); | |
1738 if (GET_CODE (addr) != PLUS && GET_CODE (addr) != LO_SUM) | |
1739 return 0; | |
1740 | |
1741 base = XEXP (addr, 0); | |
1742 if (!base_reg_operand (base, GET_MODE (base))) | |
1743 return 0; | |
1744 | |
1745 offset = XEXP (addr, 1); | |
1746 | |
1747 if (GET_CODE (addr) == PLUS) | |
1748 return satisfies_constraint_I (offset); | |
1749 | |
1750 else if (GET_CODE (addr) == LO_SUM) | |
1751 { | |
1752 if (TARGET_XCOFF || (TARGET_ELF && TARGET_POWERPC64)) | |
1753 return small_toc_ref (offset, GET_MODE (offset)); | |
1754 | |
1755 else if (TARGET_ELF && !TARGET_POWERPC64) | |
1756 return CONSTANT_P (offset); | |
1757 } | |
1758 | |
1759 return 0; | |
1760 }) | |
1761 | |
1762 ;; Match a GPR load (lbz, lhz, lwz, ld) that uses a combined address in the | |
1763 ;; memory field with both the addis and the memory offset. Sign extension | |
1764 ;; is not handled here, since lha and lwa are not fused. | |
1765 ;; With P9 fusion, also match a fpr/vector load and float_extend | |
1766 (define_predicate "fusion_addis_mem_combo_load" | |
1767 (match_code "mem,zero_extend,float_extend") | |
1768 { | |
1769 rtx addr, base, offset; | |
1770 | |
1771 /* Handle zero/float extend. */ | |
1772 if (GET_CODE (op) == ZERO_EXTEND || GET_CODE (op) == FLOAT_EXTEND) | |
1773 { | |
1774 op = XEXP (op, 0); | |
1775 mode = GET_MODE (op); | |
1776 } | |
1777 | |
1778 if (!MEM_P (op)) | |
1779 return 0; | |
1780 | |
1781 switch (mode) | |
1782 { | |
1783 case E_QImode: | |
1784 case E_HImode: | |
1785 case E_SImode: | |
1786 break; | |
1787 | |
1788 /* Do not fuse 64-bit DImode in 32-bit since it splits into two | |
1789 separate instructions. */ | |
1790 case E_DImode: | |
1791 if (!TARGET_POWERPC64) | |
1792 return 0; | |
1793 break; | |
1794 | |
1795 /* ISA 2.08/power8 only had fusion of GPR loads. */ | |
1796 case E_SFmode: | |
1797 if (!TARGET_P9_FUSION) | |
1798 return 0; | |
1799 break; | |
1800 | |
1801 /* ISA 2.08/power8 only had fusion of GPR loads. Do not allow 64-bit | |
1802 DFmode in 32-bit if -msoft-float since it splits into two separate | |
1803 instructions. */ | |
1804 case E_DFmode: | |
131 | 1805 if ((!TARGET_POWERPC64 && !TARGET_HARD_FLOAT) || !TARGET_P9_FUSION) |
111 | 1806 return 0; |
1807 break; | |
1808 | |
1809 default: | |
1810 return 0; | |
1811 } | |
1812 | |
1813 addr = XEXP (op, 0); | |
1814 if (GET_CODE (addr) != PLUS && GET_CODE (addr) != LO_SUM) | |
1815 return 0; | |
1816 | |
1817 base = XEXP (addr, 0); | |
1818 if (!fusion_gpr_addis (base, GET_MODE (base))) | |
1819 return 0; | |
1820 | |
1821 offset = XEXP (addr, 1); | |
1822 if (GET_CODE (addr) == PLUS) | |
1823 return satisfies_constraint_I (offset); | |
1824 | |
1825 else if (GET_CODE (addr) == LO_SUM) | |
1826 { | |
1827 if (TARGET_XCOFF || (TARGET_ELF && TARGET_POWERPC64)) | |
1828 return small_toc_ref (offset, GET_MODE (offset)); | |
1829 | |
1830 else if (TARGET_ELF && !TARGET_POWERPC64) | |
1831 return CONSTANT_P (offset); | |
1832 } | |
1833 | |
1834 return 0; | |
1835 }) | |
1836 | |
1837 ;; Like fusion_addis_mem_combo_load, but for stores | |
1838 (define_predicate "fusion_addis_mem_combo_store" | |
1839 (match_code "mem") | |
1840 { | |
1841 rtx addr, base, offset; | |
1842 | |
1843 if (!MEM_P (op) || !TARGET_P9_FUSION) | |
1844 return 0; | |
1845 | |
1846 switch (mode) | |
1847 { | |
1848 case E_QImode: | |
1849 case E_HImode: | |
1850 case E_SImode: | |
1851 case E_SFmode: | |
1852 break; | |
1853 | |
1854 /* Do not fuse 64-bit DImode in 32-bit since it splits into two | |
1855 separate instructions. */ | |
1856 case E_DImode: | |
1857 if (!TARGET_POWERPC64) | |
1858 return 0; | |
1859 break; | |
1860 | |
1861 /* Do not allow 64-bit DFmode in 32-bit if -msoft-float since it splits | |
1862 into two separate instructions. Do allow fusion if we have hardware | |
1863 floating point. */ | |
1864 case E_DFmode: | |
131 | 1865 if (!TARGET_POWERPC64 && !TARGET_HARD_FLOAT) |
111 | 1866 return 0; |
1867 break; | |
1868 | |
1869 default: | |
1870 return 0; | |
1871 } | |
1872 | |
1873 addr = XEXP (op, 0); | |
1874 if (GET_CODE (addr) != PLUS && GET_CODE (addr) != LO_SUM) | |
1875 return 0; | |
1876 | |
1877 base = XEXP (addr, 0); | |
1878 if (!fusion_gpr_addis (base, GET_MODE (base))) | |
1879 return 0; | |
1880 | |
1881 offset = XEXP (addr, 1); | |
1882 if (GET_CODE (addr) == PLUS) | |
1883 return satisfies_constraint_I (offset); | |
1884 | |
1885 else if (GET_CODE (addr) == LO_SUM) | |
1886 { | |
1887 if (TARGET_XCOFF || (TARGET_ELF && TARGET_POWERPC64)) | |
1888 return small_toc_ref (offset, GET_MODE (offset)); | |
1889 | |
1890 else if (TARGET_ELF && !TARGET_POWERPC64) | |
1891 return CONSTANT_P (offset); | |
1892 } | |
1893 | |
1894 return 0; | |
1895 }) | |
1896 | |
1897 ;; Return true if the operand is a float_extend or zero extend of an | |
1898 ;; offsettable memory operand suitable for use in fusion | |
1899 (define_predicate "fusion_offsettable_mem_operand" | |
1900 (match_code "mem,zero_extend,float_extend") | |
1901 { | |
1902 if (GET_CODE (op) == ZERO_EXTEND || GET_CODE (op) == FLOAT_EXTEND) | |
1903 { | |
1904 op = XEXP (op, 0); | |
1905 mode = GET_MODE (op); | |
1906 } | |
1907 | |
1908 if (!memory_operand (op, mode)) | |
1909 return 0; | |
1910 | |
1911 return offsettable_nonstrict_memref_p (op); | |
1912 }) |