]>
Commit | Line | Data |
---|---|---|
27b36d57 | 1 | ;; Predicate definitions for SPARC. |
71e45bc2 | 2 | ;; Copyright (C) 2005, 2007, 2008, 2010, 2011, 2012 |
3 | ;; Free Software Foundation, Inc. | |
27b36d57 | 4 | ;; |
5 | ;; This file is part of GCC. | |
6 | ;; | |
7 | ;; GCC is free software; you can redistribute it and/or modify | |
8 | ;; it under the terms of the GNU General Public License as published by | |
038d1e19 | 9 | ;; the Free Software Foundation; either version 3, or (at your option) |
27b36d57 | 10 | ;; any later version. |
11 | ;; | |
12 | ;; GCC is distributed in the hope that it will be useful, | |
13 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | ;; GNU General Public License for more details. | |
16 | ;; | |
17 | ;; You should have received a copy of the GNU General Public License | |
038d1e19 | 18 | ;; along with GCC; see the file COPYING3. If not see |
19 | ;; <http://www.gnu.org/licenses/>. | |
27b36d57 | 20 | |
21 | ;; Predicates for numerical constants. | |
22 | ||
23 | ;; Return true if OP is the zero constant for MODE. | |
24 | (define_predicate "const_zero_operand" | |
25 | (and (match_code "const_int,const_double,const_vector") | |
26 | (match_test "op == CONST0_RTX (mode)"))) | |
27 | ||
bbfdec17 | 28 | ;; Return true if the integer representation of OP is |
29 | ;; all-ones. | |
30 | (define_predicate "const_all_ones_operand" | |
31 | (match_code "const_int,const_double,const_vector") | |
32 | { | |
33 | if (GET_CODE (op) == CONST_INT && INTVAL (op) == -1) | |
34 | return true; | |
35 | #if HOST_BITS_PER_WIDE_INT == 32 | |
36 | if (GET_CODE (op) == CONST_DOUBLE | |
37 | && GET_MODE (op) == VOIDmode | |
38 | && CONST_DOUBLE_HIGH (op) == ~(HOST_WIDE_INT)0 | |
39 | && CONST_DOUBLE_LOW (op) == ~(HOST_WIDE_INT)0) | |
40 | return true; | |
41 | #endif | |
42 | if (GET_CODE (op) == CONST_VECTOR) | |
43 | { | |
44 | int i, num_elem = CONST_VECTOR_NUNITS (op); | |
45 | ||
46 | for (i = 0; i < num_elem; i++) | |
47 | { | |
48 | rtx n = CONST_VECTOR_ELT (op, i); | |
49 | if (! const_all_ones_operand (n, mode)) | |
50 | return false; | |
51 | } | |
52 | return true; | |
53 | } | |
54 | return false; | |
55 | }) | |
56 | ||
27b36d57 | 57 | ;; Return true if OP is the integer constant 4096. |
58 | (define_predicate "const_4096_operand" | |
59 | (and (match_code "const_int") | |
60 | (match_test "INTVAL (op) == 4096"))) | |
61 | ||
62 | ;; Return true if OP is a constant that is representable by a 13-bit | |
63 | ;; signed field. This is an acceptable immediate operand for most | |
64 | ;; 3-address instructions. | |
65 | (define_predicate "small_int_operand" | |
66 | (and (match_code "const_int") | |
67 | (match_test "SPARC_SIMM13_P (INTVAL (op))"))) | |
68 | ||
69 | ;; Return true if OP is a constant operand for the umul instruction. That | |
70 | ;; instruction sign-extends immediate values just like all other SPARC | |
71 | ;; instructions, but interprets the extended result as an unsigned number. | |
72 | (define_predicate "uns_small_int_operand" | |
73 | (match_code "const_int,const_double") | |
74 | { | |
75 | #if HOST_BITS_PER_WIDE_INT == 32 | |
76 | return ((GET_CODE (op) == CONST_INT && (unsigned) INTVAL (op) < 0x1000) | |
77 | || (GET_CODE (op) == CONST_DOUBLE | |
78 | && CONST_DOUBLE_HIGH (op) == 0 | |
79 | && (unsigned) CONST_DOUBLE_LOW (op) - 0xFFFFF000 < 0x1000)); | |
80 | #else | |
81 | return (GET_CODE (op) == CONST_INT | |
82 | && ((INTVAL (op) >= 0 && INTVAL (op) < 0x1000) | |
83 | || (INTVAL (op) >= 0xFFFFF000 | |
84 | && INTVAL (op) <= 0xFFFFFFFF))); | |
85 | #endif | |
86 | }) | |
87 | ||
88 | ;; Return true if OP is a constant that can be loaded by the sethi instruction. | |
89 | ;; The first test avoids emitting sethi to load zero for example. | |
90 | (define_predicate "const_high_operand" | |
91 | (and (match_code "const_int") | |
c3f211ea | 92 | (and (not (match_operand 0 "small_int_operand")) |
27b36d57 | 93 | (match_test "SPARC_SETHI_P (INTVAL (op) & GET_MODE_MASK (mode))")))) |
94 | ||
35f85e39 | 95 | ;; Return true if OP is a constant whose 1's complement can be loaded by the |
96 | ;; sethi instruction. | |
97 | (define_predicate "const_compl_high_operand" | |
98 | (and (match_code "const_int") | |
99 | (and (not (match_operand 0 "small_int_operand")) | |
100 | (match_test "SPARC_SETHI_P (~INTVAL (op) & GET_MODE_MASK (mode))")))) | |
27b36d57 | 101 | |
c3f211ea | 102 | ;; Return true if OP is a FP constant that needs to be loaded by the sethi/losum |
103 | ;; pair of instructions. | |
104 | (define_predicate "fp_const_high_losum_operand" | |
105 | (match_operand 0 "const_double_operand") | |
106 | { | |
107 | gcc_assert (mode == SFmode); | |
108 | return fp_high_losum_p (op); | |
109 | }) | |
110 | ||
83c0aede | 111 | ;; Return true if OP is a const_double or const_vector. |
112 | (define_predicate "const_double_or_vector_operand" | |
113 | (match_code "const_double,const_vector")) | |
114 | ||
a3664b60 | 115 | ;; Return true if OP is Zero, or if the target is V7. |
116 | (define_predicate "zero_or_v7_operand" | |
803dea20 | 117 | (and (match_code "const_int") |
118 | (ior (match_test "INTVAL (op) == 0") | |
119 | (match_test "!TARGET_V8 && !TARGET_V9")))) | |
c3f211ea | 120 | |
27b36d57 | 121 | ;; Predicates for symbolic constants. |
122 | ||
123 | ;; Return true if OP is either a symbol reference or a sum of a symbol | |
124 | ;; reference and a constant. | |
125 | (define_predicate "symbolic_operand" | |
126 | (match_code "symbol_ref,label_ref,const") | |
127 | { | |
128 | enum machine_mode omode = GET_MODE (op); | |
129 | ||
130 | if (omode != mode && omode != VOIDmode && mode != VOIDmode) | |
131 | return false; | |
132 | ||
133 | switch (GET_CODE (op)) | |
134 | { | |
135 | case SYMBOL_REF: | |
136 | return !SYMBOL_REF_TLS_MODEL (op); | |
137 | ||
138 | case LABEL_REF: | |
139 | return true; | |
140 | ||
141 | case CONST: | |
142 | op = XEXP (op, 0); | |
143 | return (((GET_CODE (XEXP (op, 0)) == SYMBOL_REF | |
144 | && !SYMBOL_REF_TLS_MODEL (XEXP (op, 0))) | |
145 | || GET_CODE (XEXP (op, 0)) == LABEL_REF) | |
146 | && GET_CODE (XEXP (op, 1)) == CONST_INT); | |
147 | ||
148 | default: | |
149 | gcc_unreachable (); | |
150 | } | |
151 | }) | |
152 | ||
153 | ;; Return true if OP is a symbolic operand for the TLS Global Dynamic model. | |
154 | (define_predicate "tgd_symbolic_operand" | |
155 | (and (match_code "symbol_ref") | |
76d4bacb | 156 | (match_test "SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_GLOBAL_DYNAMIC"))) |
27b36d57 | 157 | |
158 | ;; Return true if OP is a symbolic operand for the TLS Local Dynamic model. | |
159 | (define_predicate "tld_symbolic_operand" | |
160 | (and (match_code "symbol_ref") | |
76d4bacb | 161 | (match_test "SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_LOCAL_DYNAMIC"))) |
27b36d57 | 162 | |
163 | ;; Return true if OP is a symbolic operand for the TLS Initial Exec model. | |
164 | (define_predicate "tie_symbolic_operand" | |
165 | (and (match_code "symbol_ref") | |
76d4bacb | 166 | (match_test "SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_INITIAL_EXEC"))) |
27b36d57 | 167 | |
168 | ;; Return true if OP is a symbolic operand for the TLS Local Exec model. | |
169 | (define_predicate "tle_symbolic_operand" | |
170 | (and (match_code "symbol_ref") | |
76d4bacb | 171 | (match_test "SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_LOCAL_EXEC"))) |
27b36d57 | 172 | |
173 | ;; Return true if the operand is an argument used in generating PIC references | |
174 | ;; in either the medium/low or embedded medium/anywhere code models on V9. | |
175 | ;; Check for (const (minus (symbol_ref:GOT) | |
176 | ;; (const (minus (label) (pc))))) | |
177 | (define_predicate "medium_pic_operand" | |
178 | (match_code "const") | |
179 | { | |
180 | /* Check for (const (minus (symbol_ref:GOT) | |
181 | (const (minus (label) (pc))))). */ | |
182 | op = XEXP (op, 0); | |
183 | return GET_CODE (op) == MINUS | |
184 | && GET_CODE (XEXP (op, 0)) == SYMBOL_REF | |
185 | && GET_CODE (XEXP (op, 1)) == CONST | |
186 | && GET_CODE (XEXP (XEXP (op, 1), 0)) == MINUS; | |
187 | }) | |
188 | ||
189 | ;; Return true if OP is a LABEL_REF of mode MODE. | |
190 | (define_predicate "label_ref_operand" | |
191 | (and (match_code "label_ref") | |
192 | (match_test "GET_MODE (op) == mode"))) | |
193 | ||
194 | ;; Return true if OP is a data segment reference. This includes the readonly | |
195 | ;; data segment or, in other words, anything but the text segment. | |
196 | ;; This is needed in the embedded medium/anywhere code model on V9. These | |
197 | ;; values are accessed with EMBMEDANY_BASE_REG. */ | |
198 | (define_predicate "data_segment_operand" | |
199 | (match_code "symbol_ref,plus,const") | |
200 | { | |
201 | switch (GET_CODE (op)) | |
202 | { | |
203 | case SYMBOL_REF : | |
204 | return ! SYMBOL_REF_FUNCTION_P (op); | |
205 | case PLUS : | |
206 | /* Assume canonical format of symbol + constant. | |
207 | Fall through. */ | |
208 | case CONST : | |
209 | return data_segment_operand (XEXP (op, 0), VOIDmode); | |
210 | default : | |
211 | gcc_unreachable (); | |
212 | } | |
213 | }) | |
214 | ||
215 | ;; Return true if OP is a text segment reference. | |
216 | ;; This is needed in the embedded medium/anywhere code model on V9. | |
217 | (define_predicate "text_segment_operand" | |
218 | (match_code "label_ref,symbol_ref,plus,const") | |
219 | { | |
220 | switch (GET_CODE (op)) | |
221 | { | |
222 | case LABEL_REF : | |
223 | return true; | |
224 | case SYMBOL_REF : | |
225 | return SYMBOL_REF_FUNCTION_P (op); | |
226 | case PLUS : | |
227 | /* Assume canonical format of symbol + constant. | |
228 | Fall through. */ | |
229 | case CONST : | |
230 | return text_segment_operand (XEXP (op, 0), VOIDmode); | |
231 | default : | |
232 | gcc_unreachable (); | |
233 | } | |
234 | }) | |
235 | ||
236 | ||
237 | ;; Predicates for registers. | |
238 | ||
239 | ;; Return true if OP is either the zero constant or a register. | |
240 | (define_predicate "register_or_zero_operand" | |
241 | (ior (match_operand 0 "register_operand") | |
242 | (match_operand 0 "const_zero_operand"))) | |
243 | ||
bef6482d | 244 | (define_predicate "register_or_v9_zero_operand" |
245 | (ior (match_operand 0 "register_operand") | |
246 | (and (match_test "TARGET_V9") | |
247 | (match_operand 0 "const_zero_operand")))) | |
248 | ||
bbfdec17 | 249 | ;; Return true if OP is either the zero constant, the all-ones |
250 | ;; constant, or a register. | |
251 | (define_predicate "register_or_zero_or_all_ones_operand" | |
252 | (ior (match_operand 0 "register_or_zero_operand") | |
253 | (match_operand 0 "const_all_ones_operand"))) | |
254 | ||
27b36d57 | 255 | ;; Return true if OP is a register operand in a floating point register. |
256 | (define_predicate "fp_register_operand" | |
257 | (match_operand 0 "register_operand") | |
258 | { | |
259 | if (GET_CODE (op) == SUBREG) | |
260 | op = SUBREG_REG (op); /* Possibly a MEM */ | |
261 | return REG_P (op) && SPARC_FP_REG_P (REGNO (op)); | |
262 | }) | |
263 | ||
264 | ;; Return true if OP is an integer register. | |
265 | (define_special_predicate "int_register_operand" | |
266 | (ior (match_test "register_operand (op, SImode)") | |
267 | (match_test "TARGET_ARCH64 && register_operand (op, DImode)"))) | |
268 | ||
269 | ;; Return true if OP is a floating point condition code register. | |
270 | (define_predicate "fcc_register_operand" | |
271 | (match_code "reg") | |
272 | { | |
273 | if (mode != VOIDmode && mode != GET_MODE (op)) | |
274 | return false; | |
275 | if (mode == VOIDmode | |
276 | && (GET_MODE (op) != CCFPmode && GET_MODE (op) != CCFPEmode)) | |
277 | return false; | |
278 | ||
279 | #if 0 /* ??? 1 when %fcc0-3 are pseudos first. See gen_compare_reg(). */ | |
280 | if (reg_renumber == 0) | |
281 | return REGNO (op) >= FIRST_PSEUDO_REGISTER; | |
282 | return REGNO_OK_FOR_CCFP_P (REGNO (op)); | |
283 | #else | |
284 | return ((unsigned) REGNO (op) - SPARC_FIRST_V9_FCC_REG) < 4; | |
285 | #endif | |
286 | }) | |
287 | ||
288 | ;; Return true if OP is the floating point condition code register fcc0. | |
289 | (define_predicate "fcc0_register_operand" | |
290 | (match_code "reg") | |
291 | { | |
292 | if (mode != VOIDmode && mode != GET_MODE (op)) | |
293 | return false; | |
294 | if (mode == VOIDmode | |
295 | && (GET_MODE (op) != CCFPmode && GET_MODE (op) != CCFPEmode)) | |
296 | return false; | |
297 | ||
298 | return REGNO (op) == SPARC_FCC_REG; | |
299 | }) | |
300 | ||
301 | ;; Return true if OP is an integer or floating point condition code register. | |
302 | (define_predicate "icc_or_fcc_register_operand" | |
303 | (match_code "reg") | |
304 | { | |
305 | if (REGNO (op) == SPARC_ICC_REG) | |
306 | { | |
307 | if (mode != VOIDmode && mode != GET_MODE (op)) | |
308 | return false; | |
309 | if (mode == VOIDmode | |
310 | && GET_MODE (op) != CCmode && GET_MODE (op) != CCXmode) | |
311 | return false; | |
312 | ||
313 | return true; | |
314 | } | |
315 | ||
316 | return fcc_register_operand (op, mode); | |
317 | }) | |
318 | ||
319 | ||
320 | ;; Predicates for arithmetic instructions. | |
321 | ||
322 | ;; Return true if OP is a register, or is a constant that is representable | |
323 | ;; by a 13-bit signed field. This is an acceptable operand for most | |
324 | ;; 3-address instructions. | |
325 | (define_predicate "arith_operand" | |
326 | (ior (match_operand 0 "register_operand") | |
327 | (match_operand 0 "small_int_operand"))) | |
328 | ||
329 | ;; 64-bit: Same as above. | |
330 | ;; 32-bit: Return true if OP is a register, or is a constant that is | |
331 | ;; representable by a couple of 13-bit signed fields. This is an | |
332 | ;; acceptable operand for most 3-address splitters. | |
333 | (define_predicate "arith_double_operand" | |
334 | (match_code "const_int,const_double,reg,subreg") | |
335 | { | |
336 | bool arith_simple_operand = arith_operand (op, mode); | |
337 | HOST_WIDE_INT m1, m2; | |
338 | ||
339 | if (TARGET_ARCH64 || arith_simple_operand) | |
340 | return arith_simple_operand; | |
341 | ||
342 | #if HOST_BITS_PER_WIDE_INT == 32 | |
343 | if (GET_CODE (op) != CONST_DOUBLE) | |
344 | return false; | |
345 | m1 = CONST_DOUBLE_LOW (op); | |
346 | m2 = CONST_DOUBLE_HIGH (op); | |
347 | #else | |
348 | if (GET_CODE (op) != CONST_INT) | |
349 | return false; | |
3bb6b41e | 350 | m1 = trunc_int_for_mode (INTVAL (op), SImode); |
351 | m2 = trunc_int_for_mode (INTVAL (op) >> 32, SImode); | |
27b36d57 | 352 | #endif |
353 | ||
354 | return SPARC_SIMM13_P (m1) && SPARC_SIMM13_P (m2); | |
355 | }) | |
356 | ||
357 | ;; Return true if OP is suitable as second operand for add/sub. | |
358 | (define_predicate "arith_add_operand" | |
359 | (ior (match_operand 0 "arith_operand") | |
360 | (match_operand 0 "const_4096_operand"))) | |
635e0e88 | 361 | |
27b36d57 | 362 | ;; Return true if OP is suitable as second double operand for add/sub. |
363 | (define_predicate "arith_double_add_operand" | |
364 | (match_code "const_int,const_double,reg,subreg") | |
365 | { | |
366 | bool _arith_double_operand = arith_double_operand (op, mode); | |
367 | ||
368 | if (_arith_double_operand) | |
369 | return true; | |
370 | ||
371 | return TARGET_ARCH64 && const_4096_operand (op, mode); | |
372 | }) | |
373 | ||
374 | ;; Return true if OP is a register, or is a CONST_INT that can fit in a | |
375 | ;; signed 10-bit immediate field. This is an acceptable SImode operand for | |
376 | ;; the movrcc instructions. | |
377 | (define_predicate "arith10_operand" | |
378 | (ior (match_operand 0 "register_operand") | |
379 | (and (match_code "const_int") | |
380 | (match_test "SPARC_SIMM10_P (INTVAL (op))")))) | |
381 | ||
382 | ;; Return true if OP is a register, or is a CONST_INT that can fit in a | |
383 | ;; signed 11-bit immediate field. This is an acceptable SImode operand for | |
384 | ;; the movcc instructions. | |
385 | (define_predicate "arith11_operand" | |
386 | (ior (match_operand 0 "register_operand") | |
387 | (and (match_code "const_int") | |
388 | (match_test "SPARC_SIMM11_P (INTVAL (op))")))) | |
389 | ||
390 | ;; Return true if OP is a register or a constant for the umul instruction. | |
391 | (define_predicate "uns_arith_operand" | |
392 | (ior (match_operand 0 "register_operand") | |
393 | (match_operand 0 "uns_small_int_operand"))) | |
394 | ||
6c940e8d | 395 | ;; Return true if OP is a register, or is a CONST_INT that can fit in a |
396 | ;; signed 5-bit immediate field. This is an acceptable second operand for | |
397 | ;; the cbcond instructions. | |
398 | (define_predicate "arith5_operand" | |
399 | (ior (match_operand 0 "register_operand") | |
400 | (and (match_code "const_int") | |
401 | (match_test "SPARC_SIMM5_P (INTVAL (op))")))) | |
402 | ||
27b36d57 | 403 | |
2bd0405c | 404 | ;; Predicates for miscellaneous instructions. |
27b36d57 | 405 | |
406 | ;; Return true if OP is valid for the lhs of a comparison insn. | |
407 | (define_predicate "compare_operand" | |
3bb6b41e | 408 | (match_code "reg,subreg,zero_extract") |
27b36d57 | 409 | { |
410 | if (GET_CODE (op) == ZERO_EXTRACT) | |
411 | return (register_operand (XEXP (op, 0), mode) | |
412 | && small_int_operand (XEXP (op, 1), mode) | |
413 | && small_int_operand (XEXP (op, 2), mode) | |
414 | /* This matches cmp_zero_extract. */ | |
415 | && ((mode == SImode | |
416 | && INTVAL (XEXP (op, 2)) > 19) | |
417 | /* This matches cmp_zero_extract_sp64. */ | |
418 | || (TARGET_ARCH64 | |
419 | && mode == DImode | |
420 | && INTVAL (XEXP (op, 2)) > 51))); | |
421 | else | |
422 | return register_operand (op, mode); | |
423 | }) | |
424 | ||
425 | ;; Return true if OP is a valid operand for the source of a move insn. | |
426 | (define_predicate "input_operand" | |
427 | (match_code "const_int,const_double,const_vector,reg,subreg,mem") | |
428 | { | |
429 | enum mode_class mclass; | |
430 | ||
431 | /* If both modes are non-void they must be the same. */ | |
432 | if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op)) | |
433 | return false; | |
434 | ||
b6a32a23 | 435 | mclass = GET_MODE_CLASS (mode); |
436 | ||
27b36d57 | 437 | /* Allow any 1-instruction integer constant. */ |
b6a32a23 | 438 | if (mclass == MODE_INT |
635e0e88 | 439 | && mode != TImode |
27b36d57 | 440 | && (small_int_operand (op, mode) || const_high_operand (op, mode))) |
441 | return true; | |
442 | ||
443 | /* If 32-bit mode and this is a DImode constant, allow it | |
444 | so that the splits can be generated. */ | |
445 | if (TARGET_ARCH32 | |
446 | && mode == DImode | |
447 | && (GET_CODE (op) == CONST_DOUBLE || GET_CODE (op) == CONST_INT)) | |
448 | return true; | |
449 | ||
e76144f9 | 450 | if (mclass == MODE_FLOAT && GET_CODE (op) == CONST_DOUBLE) |
451 | return true; | |
452 | ||
635e0e88 | 453 | if (mclass == MODE_VECTOR_INT && const_all_ones_operand (op, mode)) |
27b36d57 | 454 | return true; |
455 | ||
635e0e88 | 456 | if (register_or_zero_operand (op, mode)) |
b6a32a23 | 457 | return true; |
458 | ||
459 | /* If this is a SUBREG, look inside so that we handle paradoxical ones. */ | |
27b36d57 | 460 | if (GET_CODE (op) == SUBREG) |
461 | op = SUBREG_REG (op); | |
462 | ||
463 | /* Check for valid MEM forms. */ | |
464 | if (GET_CODE (op) == MEM) | |
465 | return memory_address_p (mode, XEXP (op, 0)); | |
466 | ||
467 | return false; | |
468 | }) | |
469 | ||
470 | ;; Return true if OP is an address suitable for a call insn. | |
471 | ;; Call insn on SPARC can take a PC-relative constant address | |
472 | ;; or any regular memory address. | |
473 | (define_predicate "call_address_operand" | |
474 | (ior (match_operand 0 "symbolic_operand") | |
475 | (match_test "memory_address_p (Pmode, op)"))) | |
476 | ||
477 | ;; Return true if OP is an operand suitable for a call insn. | |
478 | (define_predicate "call_operand" | |
479 | (and (match_code "mem") | |
480 | (match_test "call_address_operand (XEXP (op, 0), mode)"))) | |
481 | ||
482 | ||
66533357 | 483 | (define_predicate "mem_noofs_operand" |
484 | (and (match_code "mem") | |
485 | (match_code "reg" "0"))) | |
486 | ||
27b36d57 | 487 | ;; Predicates for operators. |
488 | ||
489 | ;; Return true if OP is a comparison operator. This allows the use of | |
490 | ;; MATCH_OPERATOR to recognize all the branch insns. | |
491 | (define_predicate "noov_compare_operator" | |
492 | (match_code "ne,eq,ge,gt,le,lt,geu,gtu,leu,ltu") | |
493 | { | |
494 | enum rtx_code code = GET_CODE (op); | |
495 | if (GET_MODE (XEXP (op, 0)) == CC_NOOVmode | |
496 | || GET_MODE (XEXP (op, 0)) == CCX_NOOVmode) | |
497 | /* These are the only branches which work with CC_NOOVmode. */ | |
498 | return (code == EQ || code == NE || code == GE || code == LT); | |
499 | return true; | |
500 | }) | |
501 | ||
502 | ;; Return true if OP is a 64-bit comparison operator. This allows the use of | |
503 | ;; MATCH_OPERATOR to recognize all the branch insns. | |
504 | (define_predicate "noov_compare64_operator" | |
505 | (and (match_code "ne,eq,ge,gt,le,lt,geu,gtu,leu,ltu") | |
506 | (match_test "TARGET_V9")) | |
507 | { | |
508 | enum rtx_code code = GET_CODE (op); | |
509 | if (GET_MODE (XEXP (op, 0)) == CCX_NOOVmode) | |
510 | /* These are the only branches which work with CCX_NOOVmode. */ | |
511 | return (code == EQ || code == NE || code == GE || code == LT); | |
512 | return (GET_MODE (XEXP (op, 0)) == CCXmode); | |
513 | }) | |
514 | ||
515 | ;; Return true if OP is a comparison operator suitable for use in V9 | |
516 | ;; conditional move or branch on register contents instructions. | |
517 | (define_predicate "v9_register_compare_operator" | |
518 | (match_code "eq,ne,ge,lt,le,gt")) | |
519 | ||
520 | ;; Return true if OP is an operator which can set the condition codes | |
521 | ;; explicitly. We do not include PLUS and MINUS because these | |
522 | ;; require CC_NOOVmode, which we handle explicitly. | |
523 | (define_predicate "cc_arith_operator" | |
524 | (match_code "and,ior,xor")) | |
525 | ||
526 | ;; Return true if OP is an operator which can bitwise complement its | |
527 | ;; second operand and set the condition codes explicitly. | |
528 | ;; XOR is not here because combine canonicalizes (xor (not ...) ...) | |
529 | ;; and (xor ... (not ...)) to (not (xor ...)). */ | |
530 | (define_predicate "cc_arith_not_operator" | |
531 | (match_code "and,ior")) |