Mercurial > hg > CbC > CbC_gcc
annotate gcc/config/s390/predicates.md @ 111:04ced10e8804
gcc 7
author | kono |
---|---|
date | Fri, 27 Oct 2017 22:46:09 +0900 |
parents | 77e2b8dfacca |
children | 84e7813d76e9 |
rev | line source |
---|---|
0 | 1 ;; Predicate definitions for S/390 and zSeries. |
111 | 2 ;; Copyright (C) 2005-2017 Free Software Foundation, Inc. |
0 | 3 ;; Contributed by Hartmut Penner (hpenner@de.ibm.com) and |
4 ;; Ulrich Weigand (uweigand@de.ibm.com). | |
5 ;; | |
6 ;; This file is part of GCC. | |
7 ;; | |
8 ;; GCC is free software; you can redistribute it and/or modify | |
9 ;; it under the terms of the GNU General Public License as published by | |
10 ;; the Free Software Foundation; either version 3, or (at your option) | |
11 ;; any later version. | |
12 ;; | |
13 ;; GCC is distributed in the hope that it will be useful, | |
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 ;; GNU General Public License for more details. | |
17 ;; | |
18 ;; You should have received a copy of the GNU General Public License | |
19 ;; along with GCC; see the file COPYING3. If not see | |
20 ;; <http://www.gnu.org/licenses/>. | |
21 | |
22 ;; OP is the current operation. | |
23 ;; MODE is the current operation mode. | |
24 | |
25 ;; operands -------------------------------------------------------------- | |
26 | |
111 | 27 ;; Return true if OP a const 0 operand (int/float/vector). |
0 | 28 (define_predicate "const0_operand" |
111 | 29 (and (match_code "const_int,const_wide_int,const_double,const_vector") |
0 | 30 (match_test "op == CONST0_RTX (mode)"))) |
31 | |
111 | 32 ;; Return true if OP an all ones operand (int/vector). |
33 (define_predicate "all_ones_operand" | |
34 (and (match_code "const_int, const_wide_int, const_vector") | |
35 (match_test "INTEGRAL_MODE_P (GET_MODE (op))") | |
36 (match_test "op == CONSTM1_RTX (mode)"))) | |
37 | |
38 ;; Return true if OP is a 4 bit mask operand | |
39 (define_predicate "const_mask_operand" | |
40 (and (match_code "const_int") | |
41 (match_test "UINTVAL (op) < 16"))) | |
42 | |
0 | 43 ;; Return true if OP is constant. |
44 | |
45 (define_special_predicate "consttable_operand" | |
111 | 46 (and (match_code "symbol_ref, label_ref, const, const_int, const_wide_int, const_double, const_vector") |
0 | 47 (match_test "CONSTANT_P (op)"))) |
48 | |
49 ;; Return true if OP is a valid S-type operand. | |
50 | |
51 (define_predicate "s_operand" | |
52 (and (match_code "subreg, mem") | |
53 (match_operand 0 "general_operand")) | |
54 { | |
55 /* Just like memory_operand, allow (subreg (mem ...)) | |
56 after reload. */ | |
57 if (reload_completed | |
58 && GET_CODE (op) == SUBREG | |
59 && GET_CODE (SUBREG_REG (op)) == MEM) | |
60 op = SUBREG_REG (op); | |
61 | |
62 if (GET_CODE (op) != MEM) | |
63 return false; | |
64 if (!s390_legitimate_address_without_index_p (op)) | |
65 return false; | |
66 | |
67 return true; | |
68 }) | |
69 | |
70 ;; Return true if OP is a valid operand for the BRAS instruction. | |
71 ;; Allow SYMBOL_REFs and @PLT stubs. | |
72 | |
73 (define_special_predicate "bras_sym_operand" | |
74 (ior (and (match_code "symbol_ref") | |
75 (match_test "!flag_pic || SYMBOL_REF_LOCAL_P (op)")) | |
76 (and (match_code "const") | |
77 (and (match_test "GET_CODE (XEXP (op, 0)) == UNSPEC") | |
78 (match_test "XINT (XEXP (op, 0), 1) == UNSPEC_PLT"))))) | |
79 | |
80 ;; Return true if OP is a PLUS that is not a legitimate | |
81 ;; operand for the LA instruction. | |
82 | |
83 (define_predicate "s390_plus_operand" | |
84 (and (match_code "plus") | |
85 (and (match_test "mode == Pmode") | |
86 (match_test "!legitimate_la_operand_p (op)")))) | |
87 | |
111 | 88 ;; Return true if OP is a valid operand as scalar shift count or setmem. |
0 | 89 |
111 | 90 (define_predicate "setmem_operand" |
0 | 91 (match_code "reg, subreg, plus, const_int") |
92 { | |
93 HOST_WIDE_INT offset; | |
94 rtx base; | |
95 | |
111 | 96 if (GET_MODE (op) != VOIDmode |
97 && GET_MODE_CLASS (GET_MODE (op)) != MODE_INT) | |
98 return false; | |
99 | |
0 | 100 /* Extract base register and offset. */ |
111 | 101 if (!s390_decompose_addrstyle_without_index (op, &base, &offset)) |
0 | 102 return false; |
103 | |
104 /* Don't allow any non-base hard registers. Doing so without | |
105 confusing reload and/or regrename would be tricky, and doesn't | |
106 buy us much anyway. */ | |
107 if (base && REGNO (base) < FIRST_PSEUDO_REGISTER && !ADDR_REG_P (base)) | |
108 return false; | |
109 | |
110 /* Unfortunately we have to reject constants that are invalid | |
111 for an address, or else reload will get confused. */ | |
112 if (!DISP_IN_RANGE (offset)) | |
113 return false; | |
114 | |
115 return true; | |
116 }) | |
117 | |
111 | 118 ; An integer operand with the lowest order 6 bits all ones. |
119 (define_predicate "const_int_6bitset_operand" | |
120 (and (match_code "const_int") | |
121 (match_test "(INTVAL (op) & 63) == 63"))) | |
122 (define_predicate "nonzero_shift_count_operand" | |
123 (and (match_code "const_int") | |
124 (match_test "IN_RANGE (INTVAL (op), 1, GET_MODE_BITSIZE (mode) - 1)"))) | |
125 | |
0 | 126 ;; Return true if OP a valid operand for the LARL instruction. |
127 | |
128 (define_predicate "larl_operand" | |
111 | 129 (match_code "label_ref, symbol_ref, const") |
0 | 130 { |
131 /* Allow labels and local symbols. */ | |
132 if (GET_CODE (op) == LABEL_REF) | |
133 return true; | |
111 | 134 if (SYMBOL_REF_P (op)) |
135 return (!SYMBOL_FLAG_NOTALIGN2_P (op) | |
0 | 136 && SYMBOL_REF_TLS_MODEL (op) == 0 |
111 | 137 && s390_rel_address_ok_p (op)); |
0 | 138 |
139 /* Everything else must have a CONST, so strip it. */ | |
140 if (GET_CODE (op) != CONST) | |
141 return false; | |
142 op = XEXP (op, 0); | |
143 | |
144 /* Allow adding *even* in-range constants. */ | |
145 if (GET_CODE (op) == PLUS) | |
146 { | |
147 if (GET_CODE (XEXP (op, 1)) != CONST_INT | |
148 || (INTVAL (XEXP (op, 1)) & 1) != 0) | |
149 return false; | |
111 | 150 if (INTVAL (XEXP (op, 1)) >= HOST_WIDE_INT_1 << 31 |
151 || INTVAL (XEXP (op, 1)) < -(HOST_WIDE_INT_1 << 31)) | |
0 | 152 return false; |
153 op = XEXP (op, 0); | |
154 } | |
155 | |
156 /* Labels and local symbols allowed here as well. */ | |
157 if (GET_CODE (op) == LABEL_REF) | |
158 return true; | |
111 | 159 if (SYMBOL_REF_P (op)) |
160 return (!SYMBOL_FLAG_NOTALIGN2_P (op) | |
0 | 161 && SYMBOL_REF_TLS_MODEL (op) == 0 |
111 | 162 && s390_rel_address_ok_p (op)); |
163 | |
0 | 164 |
165 /* Now we must have a @GOTENT offset or @PLT stub | |
166 or an @INDNTPOFF TLS offset. */ | |
167 if (GET_CODE (op) == UNSPEC | |
168 && XINT (op, 1) == UNSPEC_GOTENT) | |
169 return true; | |
170 if (GET_CODE (op) == UNSPEC | |
171 && XINT (op, 1) == UNSPEC_PLT) | |
172 return true; | |
173 if (GET_CODE (op) == UNSPEC | |
174 && XINT (op, 1) == UNSPEC_INDNTPOFF) | |
175 return true; | |
176 | |
177 return false; | |
178 }) | |
179 | |
111 | 180 ; Predicate that always allows wraparound of the one-bit range. |
181 (define_predicate "contiguous_bitmask_operand" | |
182 (match_code "const_int") | |
183 { | |
184 return s390_contiguous_bitmask_p (INTVAL (op), true, | |
185 GET_MODE_BITSIZE (mode), NULL, NULL); | |
186 }) | |
187 | |
188 ; Same without wraparound. | |
189 (define_predicate "contiguous_bitmask_nowrap_operand" | |
190 (match_code "const_int") | |
191 { | |
192 return s390_contiguous_bitmask_p | |
193 (INTVAL (op), false, GET_MODE_BITSIZE (mode), NULL, NULL); | |
194 }) | |
195 | |
196 ;; Return true if OP is ligitimate for any LOC instruction. | |
197 | |
198 (define_predicate "loc_operand" | |
199 (ior (match_operand 0 "nonimmediate_operand") | |
200 (and (match_code "const_int") | |
201 (match_test "INTVAL (op) <= 32767 && INTVAL (op) >= -32768")))) | |
202 | |
203 (define_predicate "reload_const_wide_int_operand" | |
204 (and (match_code "const_wide_int") | |
205 (match_test "legitimate_reload_constant_p (op)"))) | |
206 | |
207 | |
0 | 208 ;; operators -------------------------------------------------------------- |
209 | |
210 ;; Return nonzero if OP is a valid comparison operator | |
211 ;; for a branch condition. | |
212 | |
213 (define_predicate "s390_comparison" | |
214 (match_code "eq, ne, lt, gt, le, ge, ltu, gtu, leu, geu, | |
215 uneq, unlt, ungt, unle, unge, ltgt, | |
216 unordered, ordered") | |
217 { | |
218 if (GET_CODE (XEXP (op, 0)) != REG | |
219 || REGNO (XEXP (op, 0)) != CC_REGNUM | |
111 | 220 || (XEXP (op, 1) != const0_rtx |
221 && !(CONST_INT_P (XEXP (op, 1)) | |
222 && GET_MODE (XEXP (op, 0)) == CCRAWmode | |
223 && INTVAL (XEXP (op, 1)) >= 0 | |
224 && INTVAL (XEXP (op, 1)) <= 15))) | |
0 | 225 return false; |
226 | |
227 return (s390_branch_condition_mask (op) >= 0); | |
228 }) | |
229 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
230 ;; Return true if op is the cc register. |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
231 (define_predicate "cc_reg_operand" |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
232 (and (match_code "reg") |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
233 (match_test "REGNO (op) == CC_REGNUM"))) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
234 |
0 | 235 (define_predicate "s390_signed_integer_comparison" |
236 (match_code "eq, ne, lt, gt, le, ge") | |
237 { | |
238 return (s390_compare_and_branch_condition_mask (op) >= 0); | |
239 }) | |
240 | |
241 (define_predicate "s390_unsigned_integer_comparison" | |
242 (match_code "eq, ne, ltu, gtu, leu, geu") | |
243 { | |
244 return (s390_compare_and_branch_condition_mask (op) >= 0); | |
245 }) | |
246 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
247 ;; Return nonzero if OP is a valid comparison operator for the |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
248 ;; cstore expanders -- respectively cstorecc4 and integer cstore. |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
249 (define_predicate "s390_eqne_operator" |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
250 (match_code "eq, ne")) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
251 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
252 (define_predicate "s390_scond_operator" |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
253 (match_code "ltu, gtu, leu, geu")) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
254 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
255 (define_predicate "s390_brx_operator" |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
256 (match_code "le, gt")) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
257 |
0 | 258 ;; Return nonzero if OP is a valid comparison operator |
259 ;; for an ALC condition. | |
260 | |
261 (define_predicate "s390_alc_comparison" | |
262 (match_code "zero_extend, sign_extend, ltu, gtu, leu, geu") | |
263 { | |
264 while (GET_CODE (op) == ZERO_EXTEND || GET_CODE (op) == SIGN_EXTEND) | |
265 op = XEXP (op, 0); | |
266 | |
267 if (!COMPARISON_P (op)) | |
268 return false; | |
269 | |
270 if (GET_CODE (XEXP (op, 0)) != REG | |
271 || REGNO (XEXP (op, 0)) != CC_REGNUM | |
111 | 272 || (XEXP (op, 1) != const0_rtx |
273 && !(CONST_INT_P (XEXP (op, 1)) | |
274 && GET_MODE (XEXP (op, 0)) == CCRAWmode | |
275 && INTVAL (XEXP (op, 1)) >= 0 | |
276 && INTVAL (XEXP (op, 1)) <= 15))) | |
0 | 277 return false; |
278 | |
279 switch (GET_MODE (XEXP (op, 0))) | |
280 { | |
111 | 281 case E_CCL1mode: |
0 | 282 return GET_CODE (op) == LTU; |
283 | |
111 | 284 case E_CCL2mode: |
0 | 285 return GET_CODE (op) == LEU; |
286 | |
111 | 287 case E_CCL3mode: |
0 | 288 return GET_CODE (op) == GEU; |
289 | |
111 | 290 case E_CCUmode: |
0 | 291 return GET_CODE (op) == GTU; |
292 | |
111 | 293 case E_CCURmode: |
0 | 294 return GET_CODE (op) == LTU; |
295 | |
111 | 296 case E_CCSmode: |
0 | 297 return GET_CODE (op) == UNGT; |
298 | |
111 | 299 case E_CCSRmode: |
0 | 300 return GET_CODE (op) == UNLT; |
301 | |
302 default: | |
303 return false; | |
304 } | |
305 }) | |
306 | |
307 ;; Return nonzero if OP is a valid comparison operator | |
308 ;; for an SLB condition. | |
309 | |
310 (define_predicate "s390_slb_comparison" | |
311 (match_code "zero_extend, sign_extend, ltu, gtu, leu, geu") | |
312 { | |
313 while (GET_CODE (op) == ZERO_EXTEND || GET_CODE (op) == SIGN_EXTEND) | |
314 op = XEXP (op, 0); | |
315 | |
316 if (!COMPARISON_P (op)) | |
317 return false; | |
318 | |
319 if (GET_CODE (XEXP (op, 0)) != REG | |
320 || REGNO (XEXP (op, 0)) != CC_REGNUM | |
321 || XEXP (op, 1) != const0_rtx) | |
322 return false; | |
323 | |
324 switch (GET_MODE (XEXP (op, 0))) | |
325 { | |
111 | 326 case E_CCL1mode: |
0 | 327 return GET_CODE (op) == GEU; |
328 | |
111 | 329 case E_CCL2mode: |
0 | 330 return GET_CODE (op) == GTU; |
331 | |
111 | 332 case E_CCL3mode: |
0 | 333 return GET_CODE (op) == LTU; |
334 | |
111 | 335 case E_CCUmode: |
0 | 336 return GET_CODE (op) == LEU; |
337 | |
111 | 338 case E_CCURmode: |
0 | 339 return GET_CODE (op) == GEU; |
340 | |
111 | 341 case E_CCSmode: |
0 | 342 return GET_CODE (op) == LE; |
343 | |
111 | 344 case E_CCSRmode: |
0 | 345 return GET_CODE (op) == GE; |
346 | |
347 default: | |
348 return false; | |
349 } | |
350 }) | |
351 | |
352 ;; Return true if OP is a load multiple operation. It is known to be a | |
353 ;; PARALLEL and the first section will be tested. | |
354 | |
355 (define_special_predicate "load_multiple_operation" | |
356 (match_code "parallel") | |
357 { | |
111 | 358 machine_mode elt_mode; |
0 | 359 int count = XVECLEN (op, 0); |
360 unsigned int dest_regno; | |
361 rtx src_addr; | |
362 int i, off; | |
363 | |
364 /* Perform a quick check so we don't blow up below. */ | |
365 if (count <= 1 | |
366 || GET_CODE (XVECEXP (op, 0, 0)) != SET | |
367 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG | |
368 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != MEM) | |
369 return false; | |
370 | |
371 dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0))); | |
372 src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0); | |
373 elt_mode = GET_MODE (SET_DEST (XVECEXP (op, 0, 0))); | |
374 | |
375 /* Check, is base, or base + displacement. */ | |
376 | |
377 if (GET_CODE (src_addr) == REG) | |
378 off = 0; | |
379 else if (GET_CODE (src_addr) == PLUS | |
380 && GET_CODE (XEXP (src_addr, 0)) == REG | |
381 && GET_CODE (XEXP (src_addr, 1)) == CONST_INT) | |
382 { | |
383 off = INTVAL (XEXP (src_addr, 1)); | |
384 src_addr = XEXP (src_addr, 0); | |
385 } | |
386 else | |
387 return false; | |
388 | |
389 for (i = 1; i < count; i++) | |
390 { | |
391 rtx elt = XVECEXP (op, 0, i); | |
392 | |
393 if (GET_CODE (elt) != SET | |
394 || GET_CODE (SET_DEST (elt)) != REG | |
395 || GET_MODE (SET_DEST (elt)) != elt_mode | |
396 || REGNO (SET_DEST (elt)) != dest_regno + i | |
397 || GET_CODE (SET_SRC (elt)) != MEM | |
398 || GET_MODE (SET_SRC (elt)) != elt_mode | |
399 || GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS | |
400 || ! rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr) | |
401 || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT | |
402 || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1)) | |
403 != off + i * GET_MODE_SIZE (elt_mode)) | |
404 return false; | |
405 } | |
406 | |
407 return true; | |
408 }) | |
409 | |
111 | 410 ;; For an execute pattern the target instruction is embedded into the |
411 ;; RTX but will not get checked for validity by recog automatically. | |
412 ;; The execute_operation predicate extracts the target RTX and invokes | |
413 ;; recog. | |
414 (define_special_predicate "execute_operation" | |
415 (match_code "parallel") | |
416 { | |
417 rtx pattern = op; | |
418 rtx_insn *insn; | |
419 int icode; | |
420 | |
421 /* This is redundant but since this predicate is evaluated | |
422 first when recognizing the insn we can prevent the more | |
423 expensive code below from being executed for many cases. */ | |
424 if (GET_CODE (XVECEXP (pattern, 0, 0)) != UNSPEC | |
425 || XINT (XVECEXP (pattern, 0, 0), 1) != UNSPEC_EXECUTE) | |
426 return false; | |
427 | |
428 /* Keep in sync with s390_execute_target. */ | |
429 if (XVECLEN (pattern, 0) == 2) | |
430 { | |
431 pattern = copy_rtx (XVECEXP (pattern, 0, 1)); | |
432 } | |
433 else | |
434 { | |
435 rtvec vec = rtvec_alloc (XVECLEN (pattern, 0) - 1); | |
436 int i; | |
437 | |
438 for (i = 0; i < XVECLEN (pattern, 0) - 1; i++) | |
439 RTVEC_ELT (vec, i) = copy_rtx (XVECEXP (pattern, 0, i + 1)); | |
440 | |
441 pattern = gen_rtx_PARALLEL (VOIDmode, vec); | |
442 } | |
443 | |
444 /* Since we do not have the wrapping insn here we have to build one. */ | |
445 insn = make_insn_raw (pattern); | |
446 icode = recog_memoized (insn); | |
447 if (icode < 0) | |
448 return false; | |
449 | |
450 extract_constrain_insn (insn); | |
451 | |
452 return which_alternative >= 0; | |
453 }) | |
454 | |
0 | 455 ;; Return true if OP is a store multiple operation. It is known to be a |
456 ;; PARALLEL and the first section will be tested. | |
457 | |
458 (define_special_predicate "store_multiple_operation" | |
459 (match_code "parallel") | |
460 { | |
111 | 461 machine_mode elt_mode; |
0 | 462 int count = XVECLEN (op, 0); |
463 unsigned int src_regno; | |
464 rtx dest_addr; | |
465 int i, off; | |
466 | |
467 /* Perform a quick check so we don't blow up below. */ | |
468 if (count <= 1 | |
469 || GET_CODE (XVECEXP (op, 0, 0)) != SET | |
470 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != MEM | |
471 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != REG) | |
472 return false; | |
473 | |
474 src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0))); | |
475 dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0); | |
476 elt_mode = GET_MODE (SET_SRC (XVECEXP (op, 0, 0))); | |
477 | |
478 /* Check, is base, or base + displacement. */ | |
479 | |
480 if (GET_CODE (dest_addr) == REG) | |
481 off = 0; | |
482 else if (GET_CODE (dest_addr) == PLUS | |
483 && GET_CODE (XEXP (dest_addr, 0)) == REG | |
484 && GET_CODE (XEXP (dest_addr, 1)) == CONST_INT) | |
485 { | |
486 off = INTVAL (XEXP (dest_addr, 1)); | |
487 dest_addr = XEXP (dest_addr, 0); | |
488 } | |
489 else | |
490 return false; | |
491 | |
492 for (i = 1; i < count; i++) | |
493 { | |
494 rtx elt = XVECEXP (op, 0, i); | |
495 | |
496 if (GET_CODE (elt) != SET | |
497 || GET_CODE (SET_SRC (elt)) != REG | |
498 || GET_MODE (SET_SRC (elt)) != elt_mode | |
499 || REGNO (SET_SRC (elt)) != src_regno + i | |
500 || GET_CODE (SET_DEST (elt)) != MEM | |
501 || GET_MODE (SET_DEST (elt)) != elt_mode | |
502 || GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS | |
503 || ! rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr) | |
504 || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT | |
505 || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1)) | |
506 != off + i * GET_MODE_SIZE (elt_mode)) | |
507 return false; | |
508 } | |
509 return true; | |
510 }) | |
111 | 511 |
512 (define_predicate "const_shift_by_byte_operand" | |
513 (match_code "const_int") | |
514 { | |
515 unsigned HOST_WIDE_INT val = INTVAL (op); | |
516 return val <= 128 && val % 8 == 0; | |
517 }) |