]>
Commit | Line | Data |
---|---|---|
0d4a78eb | 1 | ;; Predicate definitions for the Blackfin. |
a945c346 | 2 | ;; Copyright (C) 2005-2024 Free Software Foundation, Inc. |
4729dc92 | 3 | ;; Contributed by Analog Devices. |
0d4a78eb BS |
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 | |
2f83c7d6 | 9 | ;; the Free Software Foundation; either version 3, or (at your option) |
0d4a78eb BS |
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 | |
2f83c7d6 NC |
18 | ;; along with GCC; see the file COPYING3. If not see |
19 | ;; <http://www.gnu.org/licenses/>. | |
0d4a78eb BS |
20 | |
21 | ;; Return nonzero iff OP is one of the integer constants 1 or 2. | |
22 | (define_predicate "pos_scale_operand" | |
23 | (and (match_code "const_int") | |
24 | (match_test "INTVAL (op) == 1 || INTVAL (op) == 2"))) | |
25 | ||
26 | ;; Return nonzero iff OP is one of the integer constants 2 or 4. | |
27 | (define_predicate "scale_by_operand" | |
28 | (and (match_code "const_int") | |
29 | (match_test "INTVAL (op) == 2 || INTVAL (op) == 4"))) | |
30 | ||
31 | ;; Return nonzero if OP is a constant that consists of two parts; lower | |
32 | ;; bits all zero and upper bits all ones. In this case, we can perform | |
33 | ;; an AND operation with a sequence of two shifts. Don't return nonzero | |
34 | ;; if the constant would be cheap to load. | |
35 | (define_predicate "highbits_operand" | |
36 | (and (match_code "const_int") | |
9fdd7520 | 37 | (match_test "log2constp (-INTVAL (op)) && !satisfies_constraint_Ks7 (op)"))) |
0d4a78eb BS |
38 | |
39 | ;; Return nonzero if OP is suitable as a right-hand side operand for an | |
40 | ;; andsi3 operation. | |
41 | (define_predicate "rhs_andsi3_operand" | |
42 | (ior (match_operand 0 "register_operand") | |
43 | (and (match_code "const_int") | |
44 | (match_test "log2constp (~INTVAL (op)) || INTVAL (op) == 255 || INTVAL (op) == 65535")))) | |
45 | ||
46 | ;; Return nonzero if OP is a register or a constant with exactly one bit | |
47 | ;; set. | |
48 | (define_predicate "regorlog2_operand" | |
49 | (ior (match_operand 0 "register_operand") | |
50 | (and (match_code "const_int") | |
51 | (match_test "log2constp (INTVAL (op))")))) | |
52 | ||
7ddcf3d2 BS |
53 | ;; Return nonzero if OP is a register or an integer constant. |
54 | (define_predicate "reg_or_const_int_operand" | |
55 | (ior (match_operand 0 "register_operand") | |
56 | (match_code "const_int"))) | |
57 | ||
75d8b2d0 | 58 | (define_predicate "const01_operand" |
554006bd BS |
59 | (and (match_code "const_int") |
60 | (match_test "op == const0_rtx || op == const1_rtx"))) | |
75d8b2d0 | 61 | |
c7cb1555 BS |
62 | (define_predicate "const1_operand" |
63 | (and (match_code "const_int") | |
64 | (match_test "op == const1_rtx"))) | |
65 | ||
66 | (define_predicate "const3_operand" | |
67 | (and (match_code "const_int") | |
68 | (match_test "INTVAL (op) == 3"))) | |
69 | ||
75d8b2d0 BS |
70 | (define_predicate "vec_shift_operand" |
71 | (ior (and (match_code "const_int") | |
72 | (match_test "INTVAL (op) >= -16 && INTVAL (op) < 15")) | |
73 | (match_operand 0 "register_operand"))) | |
74 | ||
0d4a78eb BS |
75 | ;; Like register_operand, but make sure that hard regs have a valid mode. |
76 | (define_predicate "valid_reg_operand" | |
77 | (match_operand 0 "register_operand") | |
78 | { | |
79 | if (GET_CODE (op) == SUBREG) | |
80 | op = SUBREG_REG (op); | |
81 | if (REGNO (op) < FIRST_PSEUDO_REGISTER) | |
f939c3e6 | 82 | return targetm.hard_regno_mode_ok (REGNO (op), mode); |
0d4a78eb BS |
83 | return 1; |
84 | }) | |
85 | ||
36662eb1 BS |
86 | ;; Return nonzero if OP is a D register. |
87 | (define_predicate "d_register_operand" | |
88 | (and (match_code "reg") | |
89 | (match_test "D_REGNO_P (REGNO (op))"))) | |
90 | ||
b3187e24 BS |
91 | (define_predicate "p_register_operand" |
92 | (and (match_code "reg") | |
93 | (match_test "P_REGNO_P (REGNO (op))"))) | |
94 | ||
95 | (define_predicate "dp_register_operand" | |
96 | (and (match_code "reg") | |
97 | (match_test "D_REGNO_P (REGNO (op)) || P_REGNO_P (REGNO (op))"))) | |
98 | ||
b03149e1 JZ |
99 | ;; Return nonzero if OP is a LC register. |
100 | (define_predicate "lc_register_operand" | |
101 | (and (match_code "reg") | |
102 | (match_test "REGNO (op) == REG_LC0 || REGNO (op) == REG_LC1"))) | |
103 | ||
104 | ;; Return nonzero if OP is a LT register. | |
105 | (define_predicate "lt_register_operand" | |
106 | (and (match_code "reg") | |
107 | (match_test "REGNO (op) == REG_LT0 || REGNO (op) == REG_LT1"))) | |
108 | ||
109 | ;; Return nonzero if OP is a LB register. | |
110 | (define_predicate "lb_register_operand" | |
111 | (and (match_code "reg") | |
112 | (match_test "REGNO (op) == REG_LB0 || REGNO (op) == REG_LB1"))) | |
113 | ||
942fd98f | 114 | ;; Return nonzero if OP is a register or a 7-bit signed constant. |
0d4a78eb BS |
115 | (define_predicate "reg_or_7bit_operand" |
116 | (ior (match_operand 0 "register_operand") | |
117 | (and (match_code "const_int") | |
9fdd7520 | 118 | (match_test "satisfies_constraint_Ks7 (op)")))) |
0d4a78eb | 119 | |
b03149e1 JZ |
120 | ;; Return nonzero if OP is a register other than DREG and PREG. |
121 | (define_predicate "nondp_register_operand" | |
122 | (match_operand 0 "register_operand") | |
123 | { | |
124 | unsigned int regno; | |
125 | if (GET_CODE (op) == SUBREG) | |
126 | op = SUBREG_REG (op); | |
127 | ||
128 | regno = REGNO (op); | |
129 | return (regno >= FIRST_PSEUDO_REGISTER || !DP_REGNO_P (regno)); | |
130 | }) | |
131 | ||
132 | ;; Return nonzero if OP is a register other than DREG and PREG, or MEM. | |
133 | (define_predicate "nondp_reg_or_memory_operand" | |
134 | (ior (match_operand 0 "nondp_register_operand") | |
135 | (match_operand 0 "memory_operand"))) | |
136 | ||
942fd98f | 137 | ;; Return nonzero if OP is a register or, when negated, a 7-bit signed |
d4e85050 BS |
138 | ;; constant. |
139 | (define_predicate "reg_or_neg7bit_operand" | |
140 | (ior (match_operand 0 "register_operand") | |
141 | (and (match_code "const_int") | |
9fdd7520 | 142 | (match_test "satisfies_constraint_KN7 (op)")))) |
d4e85050 | 143 | |
0d4a78eb BS |
144 | ;; Used for secondary reloads, this function returns 1 if OP is of the |
145 | ;; form (plus (fp) (const_int)). | |
146 | (define_predicate "fp_plus_const_operand" | |
147 | (match_code "plus") | |
148 | { | |
149 | rtx op1, op2; | |
150 | ||
151 | op1 = XEXP (op, 0); | |
152 | op2 = XEXP (op, 1); | |
153 | return (REG_P (op1) | |
154 | && (REGNO (op1) == FRAME_POINTER_REGNUM | |
155 | || REGNO (op1) == STACK_POINTER_REGNUM) | |
156 | && GET_CODE (op2) == CONST_INT); | |
157 | }) | |
158 | ||
159 | ;; Returns 1 if OP is a symbolic operand, i.e. a symbol_ref or a label_ref, | |
160 | ;; possibly with an offset. | |
161 | (define_predicate "symbolic_operand" | |
162 | (ior (match_code "symbol_ref,label_ref") | |
163 | (and (match_code "const") | |
164 | (match_test "GET_CODE (XEXP (op,0)) == PLUS | |
165 | && (GET_CODE (XEXP (XEXP (op, 0), 0)) == SYMBOL_REF | |
166 | || GET_CODE (XEXP (XEXP (op, 0), 0)) == LABEL_REF) | |
167 | && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT")))) | |
168 | ||
169 | ;; Returns 1 if OP is a plain constant or matched by symbolic_operand. | |
170 | (define_predicate "symbolic_or_const_operand" | |
171 | (ior (match_code "const_int,const_double") | |
172 | (match_operand 0 "symbolic_operand"))) | |
173 | ||
6d459e2b BS |
174 | ;; Returns 1 if OP is a SYMBOL_REF. |
175 | (define_predicate "symbol_ref_operand" | |
176 | (match_code "symbol_ref")) | |
177 | ||
cae48a9d | 178 | ;; True for any non-virtual and non-eliminable register. Used in places where |
0d4a78eb BS |
179 | ;; instantiation of such a register may cause the pattern to not be recognized. |
180 | (define_predicate "register_no_elim_operand" | |
181 | (match_operand 0 "register_operand") | |
182 | { | |
183 | if (GET_CODE (op) == SUBREG) | |
184 | op = SUBREG_REG (op); | |
185 | return !(op == arg_pointer_rtx | |
186 | || op == frame_pointer_rtx | |
cae48a9d | 187 | || VIRTUAL_REGISTER_P (op)); |
0d4a78eb BS |
188 | }) |
189 | ||
f90b7a5a PB |
190 | ;; Test for an operator valid in a BImode conditional branch |
191 | (define_predicate "bfin_bimode_comparison_operator" | |
0d4a78eb | 192 | (match_code "eq,ne")) |
36662eb1 | 193 | |
f90b7a5a PB |
194 | ;; Test for an operator whose result is accessible with movbisi. |
195 | (define_predicate "bfin_direct_comparison_operator" | |
196 | (match_code "eq,lt,le,leu,ltu")) | |
197 | ||
c7cb1555 | 198 | ;; The following three are used to compute the addrtype attribute. They return |
36662eb1 BS |
199 | ;; true if passed a memory address usable for a 16-bit load or store using a |
200 | ;; P or I register, respectively. If neither matches, we know we have a | |
942fd98f | 201 | ;; 32-bit instruction. |
c7cb1555 BS |
202 | ;; We subdivide the P case into normal P registers, and SP/FP. We can assume |
203 | ;; that speculative loads through SP and FP are no problem, so this has | |
204 | ;; an effect on the anomaly workaround code. | |
205 | ||
36662eb1 BS |
206 | (define_predicate "mem_p_address_operand" |
207 | (match_code "mem") | |
208 | { | |
209 | if (effective_address_32bit_p (op, mode)) | |
210 | return 0; | |
211 | op = XEXP (op, 0); | |
212 | if (GET_CODE (op) == PLUS || GET_RTX_CLASS (GET_CODE (op)) == RTX_AUTOINC) | |
213 | op = XEXP (op, 0); | |
214 | gcc_assert (REG_P (op)); | |
c7cb1555 BS |
215 | return PREG_P (op) && op != stack_pointer_rtx && op != frame_pointer_rtx; |
216 | }) | |
217 | ||
218 | (define_predicate "mem_spfp_address_operand" | |
219 | (match_code "mem") | |
220 | { | |
221 | if (effective_address_32bit_p (op, mode)) | |
222 | return 0; | |
223 | op = XEXP (op, 0); | |
224 | if (GET_CODE (op) == PLUS || GET_RTX_CLASS (GET_CODE (op)) == RTX_AUTOINC) | |
225 | op = XEXP (op, 0); | |
226 | gcc_assert (REG_P (op)); | |
227 | return op == stack_pointer_rtx || op == frame_pointer_rtx; | |
36662eb1 BS |
228 | }) |
229 | ||
230 | (define_predicate "mem_i_address_operand" | |
231 | (match_code "mem") | |
232 | { | |
233 | if (effective_address_32bit_p (op, mode)) | |
234 | return 0; | |
235 | op = XEXP (op, 0); | |
236 | if (GET_CODE (op) == PLUS || GET_RTX_CLASS (GET_CODE (op)) == RTX_AUTOINC) | |
237 | op = XEXP (op, 0); | |
238 | gcc_assert (REG_P (op)); | |
239 | return IREG_P (op); | |
240 | }) | |
c51392f1 RS |
241 | |
242 | (define_predicate "push_multiple_operation" | |
243 | (and (match_code "parallel") | |
244 | (match_test "analyze_push_multiple_operation (op)"))) | |
245 | ||
246 | (define_predicate "pop_multiple_operation" | |
247 | (and (match_code "parallel") | |
248 | (match_test "analyze_pop_multiple_operation (op)"))) |