Mercurial > hg > CbC > CbC_gcc
annotate gcc/config/v850/predicates.md @ 145:1830386684a0
gcc-9.2.0
author | anatofuz |
---|---|
date | Thu, 13 Feb 2020 11:34:05 +0900 |
parents | 84e7813d76e9 |
children |
rev | line source |
---|---|
0 | 1 ;; Predicate definitions for NEC V850. |
145 | 2 ;; Copyright (C) 2005-2020 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 true if OP is either a register or 0. | |
21 | |
22 (define_predicate "reg_or_0_operand" | |
23 (match_code "reg,subreg,const_int,const_double") | |
24 { | |
25 if (GET_CODE (op) == CONST_INT) | |
26 return INTVAL (op) == 0; | |
27 | |
28 else if (GET_CODE (op) == CONST_DOUBLE) | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
29 return satisfies_constraint_G (op); |
0 | 30 |
31 else | |
32 return register_operand (op, mode); | |
33 }) | |
34 | |
35 ;; Return true if OP is either a register or a signed five bit | |
36 ;; integer. | |
37 | |
38 (define_predicate "reg_or_int5_operand" | |
39 (match_code "reg,subreg,const_int") | |
40 { | |
41 if (GET_CODE (op) == CONST_INT) | |
42 return CONST_OK_FOR_J (INTVAL (op)); | |
43 | |
44 else | |
45 return register_operand (op, mode); | |
46 }) | |
47 | |
48 ;; Return true if OP is either a register or a signed nine bit | |
49 ;; integer. | |
50 | |
51 (define_predicate "reg_or_int9_operand" | |
52 (match_code "reg,subreg,const_int") | |
53 { | |
54 if (GET_CODE (op) == CONST_INT) | |
55 return CONST_OK_FOR_O (INTVAL (op)); | |
56 | |
57 return register_operand (op, mode); | |
58 }) | |
59 | |
60 ;; Return true if OP is either a register or a const integer. | |
61 | |
62 (define_predicate "reg_or_const_operand" | |
63 (match_code "reg,const_int") | |
64 { | |
65 if (GET_CODE (op) == CONST_INT) | |
66 return TRUE; | |
67 | |
68 return register_operand (op, mode); | |
69 }) | |
70 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
71 ;; Return true if OP is a even number register. |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
72 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
73 (define_predicate "even_reg_operand" |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
74 (match_code "reg") |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
75 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
76 return (GET_CODE (op) == REG |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
77 && (REGNO (op) >= FIRST_PSEUDO_REGISTER |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
78 || ((REGNO (op) > 0) && (REGNO (op) < 32) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
79 && ((REGNO (op) & 1)==0)))); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
80 }) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
81 |
0 | 82 ;; Return true if OP is a valid call operand. |
83 | |
84 (define_predicate "call_address_operand" | |
85 (match_code "reg,symbol_ref") | |
86 { | |
87 /* Only registers are valid call operands if TARGET_LONG_CALLS. */ | |
88 if (TARGET_LONG_CALLS) | |
89 return GET_CODE (op) == REG; | |
90 return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == REG); | |
91 }) | |
92 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
93 ;; Return true if OP is a valid source operand for SImode move. |
0 | 94 |
95 (define_predicate "movsi_source_operand" | |
96 (match_code "label_ref,symbol_ref,const_int,const_double,const,high,mem,reg,subreg") | |
97 { | |
98 /* Some constants, as well as symbolic operands | |
99 must be done with HIGH & LO_SUM patterns. */ | |
100 if (CONSTANT_P (op) | |
101 && GET_CODE (op) != HIGH | |
102 && !(GET_CODE (op) == CONST_INT | |
103 && (CONST_OK_FOR_J (INTVAL (op)) | |
104 || CONST_OK_FOR_K (INTVAL (op)) | |
105 || CONST_OK_FOR_L (INTVAL (op))))) | |
106 return special_symbolref_operand (op, mode); | |
107 else | |
108 return general_operand (op, mode); | |
109 }) | |
110 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
111 ;; Return true if OP is a valid operand for 23 bit displacement |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
112 ;; operations. |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
113 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
114 (define_predicate "disp23_operand" |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
115 (match_code "const_int") |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
116 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
117 if (GET_CODE (op) == CONST_INT |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
118 && ((unsigned)(INTVAL (op)) >= 0x8000) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
119 && ((unsigned)(INTVAL (op)) < 0x400000)) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
120 return 1; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
121 else |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
122 return 0; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
123 }) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
124 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
125 ;; Return true if OP is a symbol ref with 16-bit signed value. |
0 | 126 |
127 (define_predicate "special_symbolref_operand" | |
128 (match_code "symbol_ref") | |
129 { | |
130 if (GET_CODE (op) == CONST | |
131 && GET_CODE (XEXP (op, 0)) == PLUS | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
132 && satisfies_constraint_K (XEXP (XEXP (op, 0), 1))) |
0 | 133 op = XEXP (XEXP (op, 0), 0); |
134 | |
135 if (GET_CODE (op) == SYMBOL_REF) | |
136 return (SYMBOL_REF_FLAGS (op) | |
137 & (SYMBOL_FLAG_ZDA | SYMBOL_FLAG_TDA | SYMBOL_FLAG_SDA)) != 0; | |
138 | |
139 return FALSE; | |
140 }) | |
141 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
142 ;; Return true if OP is a valid operand for bit related operations |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
143 ;; containing only single 1 in its binary representation. |
0 | 144 |
145 (define_predicate "power_of_two_operand" | |
146 (match_code "const_int") | |
147 { | |
148 if (GET_CODE (op) != CONST_INT) | |
149 return 0; | |
150 | |
151 if (exact_log2 (INTVAL (op)) == -1) | |
152 return 0; | |
153 return 1; | |
154 }) | |
155 | |
156 ;; Return nonzero if the given RTX is suitable for collapsing into a | |
157 ;; jump to a function prologue. | |
158 | |
159 (define_predicate "pattern_is_ok_for_prologue" | |
160 (match_code "parallel") | |
161 { | |
162 int count = XVECLEN (op, 0); | |
163 int i; | |
164 rtx vector_element; | |
165 | |
166 /* If there are no registers to save then the function prologue | |
167 is not suitable. */ | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
168 if (count <= (TARGET_LONG_CALLS ? 3 : 2)) |
0 | 169 return 0; |
170 | |
171 /* The pattern matching has already established that we are adjusting the | |
172 stack and pushing at least one register. We must now check that the | |
173 remaining entries in the vector to make sure that they are also register | |
174 pushes, except for the last entry which should be a CLOBBER of r10. | |
175 | |
176 The test below performs the C equivalent of this machine description | |
177 pattern match: | |
178 | |
179 (set (mem:SI (plus:SI (reg:SI 3) | |
180 (match_operand:SI 2 "immediate_operand" "i"))) | |
181 (match_operand:SI 3 "register_is_ok_for_epilogue" "r")) | |
182 | |
183 */ | |
184 | |
185 for (i = 2; i < count - (TARGET_LONG_CALLS ? 2: 1); i++) | |
186 { | |
187 rtx dest; | |
188 rtx src; | |
189 rtx plus; | |
190 | |
191 vector_element = XVECEXP (op, 0, i); | |
192 | |
193 if (GET_CODE (vector_element) != SET) | |
194 return 0; | |
195 | |
196 dest = SET_DEST (vector_element); | |
197 src = SET_SRC (vector_element); | |
198 | |
199 if (GET_CODE (dest) != MEM | |
200 || GET_MODE (dest) != SImode | |
201 || GET_CODE (src) != REG | |
202 || GET_MODE (src) != SImode | |
203 || ! register_is_ok_for_epilogue (src, SImode)) | |
204 return 0; | |
205 | |
206 plus = XEXP (dest, 0); | |
207 | |
208 if ( GET_CODE (plus) != PLUS | |
209 || GET_CODE (XEXP (plus, 0)) != REG | |
210 || GET_MODE (XEXP (plus, 0)) != SImode | |
211 || REGNO (XEXP (plus, 0)) != STACK_POINTER_REGNUM | |
212 || GET_CODE (XEXP (plus, 1)) != CONST_INT) | |
213 return 0; | |
214 | |
215 /* If the register is being pushed somewhere other than the stack | |
216 space just acquired by the first operand then abandon this quest. | |
217 Note: the test is <= because both values are negative. */ | |
218 if (INTVAL (XEXP (plus, 1)) | |
219 <= INTVAL (XEXP (SET_SRC (XVECEXP (op, 0, 0)), 1))) | |
220 { | |
221 return 0; | |
222 } | |
223 } | |
224 | |
225 /* Make sure that the last entries in the vector are clobbers. */ | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
226 vector_element = XVECEXP (op, 0, i++); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
227 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
228 if (GET_CODE (vector_element) != CLOBBER |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
229 || GET_CODE (XEXP (vector_element, 0)) != REG |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
230 || REGNO (XEXP (vector_element, 0)) != 10) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
231 return 0; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
232 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
233 if (TARGET_LONG_CALLS) |
0 | 234 { |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
235 vector_element = XVECEXP (op, 0, i++); |
0 | 236 |
237 if (GET_CODE (vector_element) != CLOBBER | |
238 || GET_CODE (XEXP (vector_element, 0)) != REG | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
239 || REGNO (XEXP (vector_element, 0)) != 11) |
0 | 240 return 0; |
241 } | |
242 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
243 return i == count; |
0 | 244 }) |
245 | |
246 ;; Return nonzero if the given RTX is suitable for collapsing into | |
247 ;; jump to a function epilogue. | |
248 | |
249 (define_predicate "pattern_is_ok_for_epilogue" | |
250 (match_code "parallel") | |
251 { | |
252 int count = XVECLEN (op, 0); | |
253 int i; | |
254 | |
255 /* If there are no registers to restore then the function epilogue | |
256 is not suitable. */ | |
257 if (count <= 2) | |
258 return 0; | |
259 | |
260 /* The pattern matching has already established that we are performing a | |
261 function epilogue and that we are popping at least one register. We must | |
262 now check the remaining entries in the vector to make sure that they are | |
263 also register pops. There is no good reason why there should ever be | |
264 anything else in this vector, but being paranoid always helps... | |
265 | |
266 The test below performs the C equivalent of this machine description | |
267 pattern match: | |
268 | |
269 (set (match_operand:SI n "register_is_ok_for_epilogue" "r") | |
270 (mem:SI (plus:SI (reg:SI 3) (match_operand:SI n "immediate_operand" "i")))) | |
271 */ | |
272 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
273 for (i = 2; i < count; i++) |
0 | 274 { |
275 rtx vector_element = XVECEXP (op, 0, i); | |
276 rtx dest; | |
277 rtx src; | |
278 rtx plus; | |
279 | |
280 if (GET_CODE (vector_element) != SET) | |
281 return 0; | |
282 | |
283 dest = SET_DEST (vector_element); | |
284 src = SET_SRC (vector_element); | |
285 | |
286 if (GET_CODE (dest) != REG | |
287 || GET_MODE (dest) != SImode | |
288 || ! register_is_ok_for_epilogue (dest, SImode) | |
289 || GET_CODE (src) != MEM | |
290 || GET_MODE (src) != SImode) | |
291 return 0; | |
292 | |
293 plus = XEXP (src, 0); | |
294 | |
295 if (GET_CODE (plus) != PLUS | |
296 || GET_CODE (XEXP (plus, 0)) != REG | |
297 || GET_MODE (XEXP (plus, 0)) != SImode | |
298 || REGNO (XEXP (plus, 0)) != STACK_POINTER_REGNUM | |
299 || GET_CODE (XEXP (plus, 1)) != CONST_INT) | |
300 return 0; | |
301 } | |
302 | |
303 return 1; | |
304 }) | |
305 | |
306 ;; Return true if the given RTX is a register which can be restored by | |
307 ;; a function epilogue. | |
308 | |
309 (define_predicate "register_is_ok_for_epilogue" | |
310 (match_code "reg") | |
311 { | |
312 /* The save/restore routines can only cope with registers 20 - 31. */ | |
313 return ((GET_CODE (op) == REG) | |
314 && (((REGNO (op) >= 20) && REGNO (op) <= 31))); | |
315 }) | |
316 | |
317 ;; Return nonzero if the given RTX is suitable for collapsing into a | |
318 ;; DISPOSE instruction. | |
319 | |
320 (define_predicate "pattern_is_ok_for_dispose" | |
321 (match_code "parallel") | |
322 { | |
323 int count = XVECLEN (op, 0); | |
324 int i; | |
325 | |
326 /* If there are no registers to restore then | |
327 the dispose instruction is not suitable. */ | |
328 if (count <= 2) | |
329 return 0; | |
330 | |
331 /* The pattern matching has already established that we are performing a | |
332 function epilogue and that we are popping at least one register. We must | |
333 now check the remaining entries in the vector to make sure that they are | |
334 also register pops. There is no good reason why there should ever be | |
335 anything else in this vector, but being paranoid always helps... | |
336 | |
337 The test below performs the C equivalent of this machine description | |
338 pattern match: | |
339 | |
340 (set (match_operand:SI n "register_is_ok_for_epilogue" "r") | |
341 (mem:SI (plus:SI (reg:SI 3) | |
342 (match_operand:SI n "immediate_operand" "i")))) | |
343 */ | |
344 | |
345 for (i = 3; i < count; i++) | |
346 { | |
347 rtx vector_element = XVECEXP (op, 0, i); | |
348 rtx dest; | |
349 rtx src; | |
350 rtx plus; | |
351 | |
352 if (GET_CODE (vector_element) != SET) | |
353 return 0; | |
354 | |
355 dest = SET_DEST (vector_element); | |
356 src = SET_SRC (vector_element); | |
357 | |
358 if ( GET_CODE (dest) != REG | |
359 || GET_MODE (dest) != SImode | |
360 || ! register_is_ok_for_epilogue (dest, SImode) | |
361 || GET_CODE (src) != MEM | |
362 || GET_MODE (src) != SImode) | |
363 return 0; | |
364 | |
365 plus = XEXP (src, 0); | |
366 | |
367 if ( GET_CODE (plus) != PLUS | |
368 || GET_CODE (XEXP (plus, 0)) != REG | |
369 || GET_MODE (XEXP (plus, 0)) != SImode | |
370 || REGNO (XEXP (plus, 0)) != STACK_POINTER_REGNUM | |
371 || GET_CODE (XEXP (plus, 1)) != CONST_INT) | |
372 return 0; | |
373 } | |
374 | |
375 return 1; | |
376 }) | |
377 | |
378 ;; Return nonzero if the given RTX is suitable for collapsing into a | |
379 ;; PREPARE instruction. | |
380 | |
381 (define_predicate "pattern_is_ok_for_prepare" | |
382 (match_code "parallel") | |
383 { | |
384 int count = XVECLEN (op, 0); | |
385 int i; | |
386 | |
387 /* If there are no registers to restore then the prepare instruction | |
388 is not suitable. */ | |
389 if (count <= 1) | |
390 return 0; | |
391 | |
392 /* The pattern matching has already established that we are adjusting the | |
393 stack and pushing at least one register. We must now check that the | |
394 remaining entries in the vector to make sure that they are also register | |
395 pushes. | |
396 | |
397 The test below performs the C equivalent of this machine description | |
398 pattern match: | |
399 | |
400 (set (mem:SI (plus:SI (reg:SI 3) | |
401 (match_operand:SI 2 "immediate_operand" "i"))) | |
402 (match_operand:SI 3 "register_is_ok_for_epilogue" "r")) | |
403 | |
404 */ | |
405 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
406 for (i = 1; i < count; i++) |
0 | 407 { |
408 rtx vector_element = XVECEXP (op, 0, i); | |
409 rtx dest; | |
410 rtx src; | |
411 rtx plus; | |
412 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
413 if (GET_CODE (vector_element) == CLOBBER) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
414 continue; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
415 |
0 | 416 if (GET_CODE (vector_element) != SET) |
417 return 0; | |
418 | |
419 dest = SET_DEST (vector_element); | |
420 src = SET_SRC (vector_element); | |
421 | |
422 if ( GET_CODE (dest) != MEM | |
423 || GET_MODE (dest) != SImode | |
424 || GET_CODE (src) != REG | |
425 || GET_MODE (src) != SImode | |
426 || ! register_is_ok_for_epilogue (src, SImode) | |
427 ) | |
428 return 0; | |
429 | |
430 plus = XEXP (dest, 0); | |
431 | |
432 if ( GET_CODE (plus) != PLUS | |
433 || GET_CODE (XEXP (plus, 0)) != REG | |
434 || GET_MODE (XEXP (plus, 0)) != SImode | |
435 || REGNO (XEXP (plus, 0)) != STACK_POINTER_REGNUM | |
436 || GET_CODE (XEXP (plus, 1)) != CONST_INT) | |
437 return 0; | |
438 | |
439 /* If the register is being pushed somewhere other than the stack | |
440 space just acquired by the first operand then abandon this quest. | |
441 Note: the test is <= because both values are negative. */ | |
442 if (INTVAL (XEXP (plus, 1)) | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
443 < INTVAL (XEXP (SET_SRC (XVECEXP (op, 0, 0)), 1))) |
0 | 444 return 0; |
445 } | |
446 | |
447 return 1; | |
448 }) | |
449 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
450 ;; Return true if OP is a valid operand for bit related operations |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
451 ;; containing only single 0 in its binary representation. |
0 | 452 |
453 (define_predicate "not_power_of_two_operand" | |
454 (match_code "const_int") | |
455 { | |
456 unsigned int mask; | |
457 | |
458 if (mode == QImode) | |
459 mask = 0xff; | |
460 else if (mode == HImode) | |
461 mask = 0xffff; | |
462 else if (mode == SImode) | |
463 mask = 0xffffffff; | |
464 else | |
465 return 0; | |
466 | |
467 if (GET_CODE (op) != CONST_INT) | |
468 return 0; | |
469 | |
470 if (exact_log2 (~INTVAL (op) & mask) == -1) | |
471 return 0; | |
472 return 1; | |
473 }) | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
474 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
475 ;; Return true if OP is a float value operand with value as 1. |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
476 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
477 (define_predicate "const_float_1_operand" |
131 | 478 (match_code "const_double") |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
479 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
480 if (GET_CODE (op) != CONST_DOUBLE |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
481 || mode != GET_MODE (op) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
482 || (mode != DFmode && mode != SFmode)) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
483 return 0; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
484 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
485 return op == CONST1_RTX(mode); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
486 }) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
487 |
111 | 488 (define_predicate "label_ref_operand" |
489 (match_code "label_ref") | |
490 ) | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
491 |
111 | 492 |
493 (define_predicate "e3v5_shift_operand" | |
494 (match_code "const_int,reg") | |
495 { | |
496 if (CONST_INT_P (op)) | |
497 return IN_RANGE (INTVAL (op), 0, 31); | |
498 return true; | |
499 } | |
500 ) | |
501 | |
502 (define_predicate "ior_operator" | |
503 (match_code "ior") | |
504 { | |
505 return (GET_CODE (op) == IOR); | |
506 }) | |
507 | |
508 ;; Return true if the floating point comparison operation | |
509 ;; given produces a canonical answer. | |
510 (define_predicate "v850_float_z_comparison_operator" | |
511 (match_code "lt,le,eq,gt,ge") | |
512 { | |
513 enum rtx_code code = GET_CODE (op); | |
514 | |
515 if (GET_RTX_CLASS (code) != RTX_COMPARE | |
516 && GET_RTX_CLASS (code) != RTX_COMM_COMPARE) | |
517 return 0; | |
518 | |
519 if (mode != GET_MODE (op) && mode != VOIDmode) | |
520 return 0; | |
521 | |
522 if ((GET_CODE (XEXP (op, 0)) != REG | |
523 || REGNO (XEXP (op, 0)) != CC_REGNUM) | |
524 || XEXP (op, 1) != const0_rtx) | |
525 return 0; | |
526 | |
527 if (GET_MODE (XEXP (op, 0)) == CC_FPU_LTmode) | |
528 return code == LT; | |
529 if (GET_MODE (XEXP (op, 0)) == CC_FPU_LEmode) | |
530 return code == LE; | |
531 if (GET_MODE (XEXP (op, 0)) == CC_FPU_EQmode) | |
532 return code == EQ; | |
533 if (GET_MODE (XEXP (op, 0)) == CC_FPU_GTmode) | |
534 return code == GT; | |
535 if (GET_MODE (XEXP (op, 0)) == CC_FPU_GEmode) | |
536 return code == GE; | |
537 | |
538 /* Note we do not accept CC_FPU_NEmode here. See | |
539 v850_float_nz_comparison for the reason why. */ | |
540 return 0; | |
541 }) | |
542 | |
543 ;; Return true if the floating point comparison operation | |
544 ;; given produces an inverted answer. | |
545 (define_predicate "v850_float_nz_comparison_operator" | |
546 (match_code "ne") | |
547 { | |
548 enum rtx_code code = GET_CODE (op); | |
549 | |
550 /* The V850E2V3 does not have a floating point NZ comparison operator. | |
551 Instead it is implemented as an EQ comparison and this function ensures | |
552 that the branch_nz_normal and set_nz_insn patterns are used to examine | |
553 (and invert) the result of the floating point comparison. */ | |
554 | |
555 if (GET_RTX_CLASS (code) != RTX_COMPARE | |
556 && GET_RTX_CLASS (code) != RTX_COMM_COMPARE) | |
557 return 0; | |
558 | |
559 if (mode != GET_MODE (op) && mode != VOIDmode) | |
560 return 0; | |
561 | |
562 if ((GET_CODE (XEXP (op, 0)) != REG | |
563 || REGNO (XEXP (op, 0)) != CC_REGNUM) | |
564 || XEXP (op, 1) != const0_rtx) | |
565 return 0; | |
566 | |
567 if (GET_MODE (XEXP (op, 0)) == CC_FPU_NEmode) | |
568 return code == NE; | |
569 | |
570 return 0; | |
571 }) |