]>
Commit | Line | Data |
---|---|---|
41b6a5e2 | 1 | ;; Predicate definitions for Motorola 68000. |
a945c346 | 2 | ;; Copyright (C) 2005-2024 Free Software Foundation, Inc. |
41b6a5e2 KH |
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 | |
2f83c7d6 | 8 | ;; the Free Software Foundation; either version 3, or (at your option) |
41b6a5e2 KH |
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 | |
2f83c7d6 NC |
17 | ;; along with GCC; see the file COPYING3. If not see |
18 | ;; <http://www.gnu.org/licenses/>. | |
41b6a5e2 KH |
19 | |
20 | ;; Special case of a general operand that's used as a source | |
21 | ;; operand. Use this to permit reads from PC-relative memory when | |
22 | ;; -mpcrel is specified. | |
23 | ||
24 | (define_predicate "general_src_operand" | |
25 | (match_code "const_int,const_double,const,symbol_ref,label_ref,subreg,reg,mem") | |
26 | { | |
27 | if (TARGET_PCREL | |
28 | && GET_CODE (op) == MEM | |
29 | && (GET_CODE (XEXP (op, 0)) == SYMBOL_REF | |
30 | || GET_CODE (XEXP (op, 0)) == LABEL_REF | |
31 | || GET_CODE (XEXP (op, 0)) == CONST)) | |
32 | return 1; | |
33 | return general_operand (op, mode); | |
34 | }) | |
35 | ||
36 | ;; Special case of a nonimmediate operand that's used as a source. Use | |
37 | ;; this to permit reads from PC-relative memory when -mpcrel is | |
38 | ;; specified. | |
39 | ||
40 | (define_predicate "nonimmediate_src_operand" | |
41 | (match_code "subreg,reg,mem") | |
42 | { | |
43 | if (TARGET_PCREL && GET_CODE (op) == MEM | |
44 | && (GET_CODE (XEXP (op, 0)) == SYMBOL_REF | |
45 | || GET_CODE (XEXP (op, 0)) == LABEL_REF | |
46 | || GET_CODE (XEXP (op, 0)) == CONST)) | |
47 | return 1; | |
48 | return nonimmediate_operand (op, mode); | |
49 | }) | |
50 | ||
51 | ;; Special case of a memory operand that's used as a source. Use this | |
52 | ;; to permit reads from PC-relative memory when -mpcrel is specified. | |
53 | ||
54 | (define_predicate "memory_src_operand" | |
55 | (match_code "subreg,mem") | |
56 | { | |
57 | if (TARGET_PCREL && GET_CODE (op) == MEM | |
58 | && (GET_CODE (XEXP (op, 0)) == SYMBOL_REF | |
59 | || GET_CODE (XEXP (op, 0)) == LABEL_REF | |
60 | || GET_CODE (XEXP (op, 0)) == CONST)) | |
61 | return 1; | |
62 | return memory_operand (op, mode); | |
63 | }) | |
64 | ||
65 | ;; Similar to general_operand, but exclude stack_pointer_rtx. | |
66 | ||
67 | (define_predicate "not_sp_operand" | |
68 | (match_code "subreg,reg,mem") | |
69 | { | |
70 | return op != stack_pointer_rtx && nonimmediate_operand (op, mode); | |
71 | }) | |
72 | ||
73 | ;; Predicate that accepts only a pc-relative address. This is needed | |
74 | ;; because pc-relative addresses don't satisfy the predicate | |
75 | ;; "general_src_operand". | |
76 | ||
77 | (define_predicate "pcrel_address" | |
4fbe09f9 | 78 | (match_code "symbol_ref,label_ref,const")) |
41b6a5e2 KH |
79 | |
80 | ;; Accept integer operands in the range 0..0xffffffff. We have to | |
81 | ;; check the range carefully since this predicate is used in DImode | |
82 | ;; contexts. Also, we need some extra crud to make it work when | |
83 | ;; hosted on 64-bit machines. | |
84 | ||
85 | (define_predicate "const_uint32_operand" | |
86 | (match_code "const_int,const_double") | |
87 | { | |
88 | /* It doesn't make sense to ask this question with a mode that is | |
89 | not larger than 32 bits. */ | |
4fbe09f9 | 90 | gcc_assert (GET_MODE_BITSIZE (mode) > 32); |
41b6a5e2 KH |
91 | |
92 | #if HOST_BITS_PER_WIDE_INT > 32 | |
93 | /* All allowed constants will fit a CONST_INT. */ | |
94 | return (GET_CODE (op) == CONST_INT | |
95 | && (INTVAL (op) >= 0 && INTVAL (op) <= 0xffffffffL)); | |
96 | #else | |
97 | return (GET_CODE (op) == CONST_INT | |
98 | || (GET_CODE (op) == CONST_DOUBLE && CONST_DOUBLE_HIGH (op) == 0)); | |
99 | #endif | |
100 | }) | |
101 | ||
102 | ;; Accept integer operands in the range -0x80000000..0x7fffffff. We | |
103 | ;; have to check the range carefully since this predicate is used in | |
104 | ;; DImode contexts. | |
105 | ||
106 | (define_predicate "const_sint32_operand" | |
107 | (match_code "const_int") | |
108 | { | |
109 | /* It doesn't make sense to ask this question with a mode that is | |
110 | not larger than 32 bits. */ | |
4fbe09f9 | 111 | gcc_assert (GET_MODE_BITSIZE (mode) > 32); |
41b6a5e2 KH |
112 | |
113 | /* All allowed constants will fit a CONST_INT. */ | |
114 | return (GET_CODE (op) == CONST_INT | |
115 | && (INTVAL (op) >= (-0x7fffffff - 1) && INTVAL (op) <= 0x7fffffff)); | |
116 | }) | |
117 | ||
f90b7a5a PB |
118 | (define_predicate "m68k_cstore_comparison_operator" |
119 | (if_then_else (match_test "TARGET_68881") | |
120 | (match_operand 0 "comparison_operator") | |
121 | (match_operand 0 "ordered_comparison_operator"))) | |
122 | ||
41b6a5e2 KH |
123 | ;; Check for sign_extend or zero_extend. Used for bit-count operands. |
124 | ||
125 | (define_predicate "extend_operator" | |
4fbe09f9 | 126 | (match_code "sign_extend,zero_extend")) |
41b6a5e2 KH |
127 | |
128 | ;; Returns true if OP is either a symbol reference or a sum of a | |
75df395f MK |
129 | ;; symbol reference and a constant. This predicate is for "raw" |
130 | ;; symbol references not yet processed by legitimize*_address, | |
131 | ;; hence we do not handle UNSPEC_{XGOT, TLS, XTLS} here. | |
41b6a5e2 KH |
132 | |
133 | (define_predicate "symbolic_operand" | |
134 | (match_code "symbol_ref,label_ref,const") | |
135 | { | |
136 | switch (GET_CODE (op)) | |
137 | { | |
138 | case SYMBOL_REF: | |
139 | case LABEL_REF: | |
140 | return true; | |
141 | ||
142 | case CONST: | |
143 | op = XEXP (op, 0); | |
99c9cbcc MF |
144 | if (GET_CODE (op) == UNSPEC) |
145 | return false; | |
41b6a5e2 KH |
146 | return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF |
147 | || GET_CODE (XEXP (op, 0)) == LABEL_REF) | |
148 | && GET_CODE (XEXP (op, 1)) == CONST_INT); | |
149 | ||
150 | #if 0 /* Deleted, with corresponding change in m68k.h, | |
151 | so as to fit the specs. No CONST_DOUBLE is ever symbolic. */ | |
152 | case CONST_DOUBLE: | |
153 | return GET_MODE (op) == mode; | |
154 | #endif | |
155 | ||
156 | default: | |
157 | return false; | |
158 | } | |
159 | }) | |
160 | ||
4e2b26aa | 161 | ;; A constant that can be used the address in a call insn |
29ca003a RS |
162 | (define_predicate "const_call_operand" |
163 | (ior (match_operand 0 "const_int_operand") | |
164 | (and (match_test "m68k_symbolic_call != NULL") | |
165 | (match_operand 0 "symbolic_operand")))) | |
166 | ||
167 | ;; An operand that can be used as the address in a call insn. | |
168 | (define_predicate "call_operand" | |
169 | (ior (match_operand 0 "const_call_operand") | |
170 | (match_operand 0 "register_operand"))) | |
171 | ||
4e2b26aa NS |
172 | ;; A constant that can be used the address in a sibcall insn |
173 | (define_predicate "const_sibcall_operand" | |
174 | (ior (match_operand 0 "const_int_operand") | |
175 | (and (match_test "m68k_symbolic_jump != NULL") | |
176 | (match_operand 0 "symbolic_operand")))) | |
177 | ||
f7e70894 RS |
178 | ;; An operand that can be used as the address in a sibcall insn. |
179 | (define_predicate "sibcall_operand" | |
4e2b26aa | 180 | (ior (match_operand 0 "const_sibcall_operand") |
f7e70894 RS |
181 | (and (match_code "reg") |
182 | (match_test "REGNO (op) == STATIC_CHAIN_REGNUM")))) | |
183 | ||
41b6a5e2 KH |
184 | ;; TODO: Add a comment here. |
185 | ||
186 | (define_predicate "post_inc_operand" | |
4fbe09f9 KH |
187 | (and (match_code "mem") |
188 | (match_test "GET_CODE (XEXP (op, 0)) == POST_INC"))) | |
41b6a5e2 KH |
189 | |
190 | ;; TODO: Add a comment here. | |
191 | ||
192 | (define_predicate "pre_dec_operand" | |
4fbe09f9 KH |
193 | (and (match_code "mem") |
194 | (match_test "GET_CODE (XEXP (op, 0)) == PRE_DEC"))) | |
c47b0cb4 | 195 | |
f90b7a5a PB |
196 | ;; A zero constant. |
197 | (define_predicate "const0_operand" | |
198 | (and (match_code "const_int,const_double,const_vector") | |
199 | (match_test "op == CONST0_RTX (mode)"))) | |
200 | ||
201 | ;; A one constant (operand for conditional_trap). | |
202 | (define_predicate "const1_operand" | |
203 | (and (match_code "const_int") | |
204 | (match_test "op == const1_rtx"))) | |
205 | ||
6cebc6cb BS |
206 | ;; A valid operand for a conditional operation. |
207 | ;; ColdFire has tst patterns for HImode and QImode, but not cmp patterns. | |
208 | (define_predicate "m68k_comparison_operand" | |
209 | (if_then_else (match_test "TARGET_COLDFIRE && mode != SImode") | |
f90b7a5a PB |
210 | (and (match_code "const_int") |
211 | (match_test "op == const0_rtx")) | |
212 | (match_operand 0 "general_src_operand"))) | |
213 | ||
c47b0cb4 MK |
214 | ;; An operand for movsi_const0 pattern. |
215 | (define_predicate "movsi_const0_operand" | |
216 | (and (match_operand 0 "nonimmediate_operand") | |
217 | (match_test "(TARGET_68010 || TARGET_COLDFIRE) | |
218 | || !(MEM_P (op) && MEM_VOLATILE_P (op))"))) | |
219 | ||
220 | ;; A non-symbolic call operand. | |
221 | ;; We need to special case 'const_int' to ignore its mode while matching. | |
222 | (define_predicate "non_symbolic_call_operand" | |
223 | (and (match_operand 0 "call_operand") | |
224 | (ior (and (match_code "const_int") | |
225 | (match_test "!symbolic_operand (op, mode)")) | |
226 | (match_test "!symbolic_operand (op,mode)")))) | |
67595cbb RZ |
227 | |
228 | ;; Special case of general_src_operand, which rejects a few fp | |
229 | ;; constants (which we prefer in registers) before reload. | |
6cebc6cb | 230 | ;; Used only in comparisons, and we do want to allow zero. |
67595cbb RZ |
231 | |
232 | (define_predicate "fp_src_operand" | |
233 | (match_operand 0 "general_src_operand") | |
234 | { | |
6cebc6cb BS |
235 | return (!CONSTANT_P (op) |
236 | || op == CONST0_RTX (mode) | |
237 | || (TARGET_68881 | |
238 | && (!standard_68881_constant_p (op) | |
239 | || reload_in_progress | |
240 | || reload_completed))); | |
67595cbb | 241 | }) |
5e7821eb | 242 | |
57d7fe86 JL |
243 | ;; Used to detect constants that are valid for addq/subq instructions |
244 | (define_predicate "addq_subq_operand" | |
245 | (match_code "const_int") | |
246 | { | |
247 | return ((INTVAL (op) <= 8 && INTVAL (op) > 0) | |
248 | || (INTVAL (op) >= -8 && INTVAL (op) < 0)); | |
249 | }) | |
250 | ||
251 | ;; Used to detect equality and non-equality operators | |
252 | (define_predicate "equality_comparison_operator" | |
253 | (match_code "eq,ne")) | |
254 | ||
5e7821eb JL |
255 | ;; Used to detect when an operand is either a register |
256 | ;; or a constant that is all ones in its lower bits. | |
257 | ;; Used by insv pattern to help detect when we're initializing | |
258 | ;; a bitfield to all ones. | |
259 | ||
260 | (define_predicate "reg_or_pow2_m1_operand" | |
261 | (match_code "reg,const_int") | |
262 | { | |
bcff0913 | 263 | return (REG_P (op) || pow2_m1_operand (op, VOIDmode)); |
5e7821eb | 264 | }) |
bcff0913 JL |
265 | |
266 | ;; Used to detect a constant that is all ones in its lower bits. | |
267 | (define_predicate "pow2_m1_operand" | |
268 | (match_code "const_int") | |
269 | { | |
270 | return (GET_CODE (op) == CONST_INT && exact_log2 (INTVAL (op) + 1) >= 0); | |
271 | }) | |
272 | ||
273 | ;; Used to detect valid targets for conditional branches | |
274 | ;; Used to detect (pc) or (label_ref) in some jumping patterns to cut down | |
275 | (define_predicate "pc_or_label_operand" | |
276 | (match_code "pc,label_ref")) | |
83ad4fac JL |
277 | |
278 | (define_predicate "swap_peephole_relational_operator" | |
279 | (match_code "gtu,leu,gt,le")) | |
6cebc6cb BS |
280 | |
281 | (define_predicate "address_reg_operand" | |
282 | (match_test ("ADDRESS_REG_P (op)"))) |