111
|
1 ;; Predicate definitions for code generation on the EPIPHANY cpu.
|
131
|
2 ;; Copyright (C) 1994-2018 Free Software Foundation, Inc.
|
111
|
3 ;; Contributed by Embecosm on behalf of Adapteva, Inc.
|
|
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
|
|
9 ;; the Free Software Foundation; either version 3, or (at your option)
|
|
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
|
|
18 ;; along with GCC; see the file COPYING3. If not see
|
|
19 ;; <http://www.gnu.org/licenses/>.
|
|
20
|
|
21 ;; Returns true iff OP is a symbol reference that is a valid operand
|
|
22 ;; in a jump or call instruction.
|
|
23
|
|
24 (define_predicate "symbolic_operand"
|
|
25 (match_code "symbol_ref,label_ref,const")
|
|
26 {
|
|
27 if (GET_CODE (op) == SYMBOL_REF)
|
|
28 return (!epiphany_is_long_call_p (op)
|
|
29 && (!flag_pic || SYMBOL_REF_LOCAL_P (op)));
|
|
30 if (GET_CODE (op) == LABEL_REF)
|
|
31 return true;
|
|
32 if (GET_CODE (op) == CONST)
|
|
33 {
|
|
34 op = XEXP (op, 0);
|
|
35 if (GET_CODE (op) != PLUS || !symbolic_operand (XEXP (op, 0), mode))
|
|
36 return false;
|
|
37 /* The idea here is that a 'small' constant offset should be OK.
|
|
38 What exactly is considered 'small' is a bit arbitrary. */
|
|
39 return satisfies_constraint_L (XEXP (op, 1));
|
|
40 }
|
|
41 gcc_unreachable ();
|
|
42 })
|
|
43
|
|
44 ;; Acceptable arguments to the call insn.
|
|
45
|
|
46 (define_predicate "call_address_operand"
|
|
47 (ior (match_code "reg")
|
|
48 (match_operand 0 "symbolic_operand")))
|
|
49
|
|
50 (define_predicate "call_operand"
|
|
51 (match_code "mem")
|
|
52 {
|
|
53 op = XEXP (op, 0);
|
|
54 return call_address_operand (op, mode);
|
|
55 })
|
|
56
|
|
57 ;; general purpose register.
|
|
58 (define_predicate "gpr_operand"
|
|
59 (match_code "reg,subreg")
|
|
60 {
|
|
61 int regno;
|
|
62
|
|
63 if (!register_operand (op, mode))
|
|
64 return 0;
|
|
65 if (GET_CODE (op) == SUBREG)
|
|
66 op = XEXP (op, 0);
|
|
67 regno = REGNO (op);
|
|
68 return regno >= FIRST_PSEUDO_REGISTER || regno <= 63;
|
|
69 })
|
|
70
|
|
71 (define_special_predicate "any_gpr_operand"
|
|
72 (match_code "subreg,reg")
|
|
73 {
|
|
74 return gpr_operand (op, mode);
|
|
75 })
|
|
76
|
|
77 ;; register suitable for integer add / sub operations; besides general purpose
|
|
78 ;; registers we allow fake hard registers that are eliminated to a real
|
|
79 ;; hard register via an offset.
|
|
80 (define_predicate "add_reg_operand"
|
|
81 (match_code "reg,subreg")
|
|
82 {
|
|
83 int regno;
|
|
84
|
|
85 if (!register_operand (op, mode))
|
|
86 return 0;
|
|
87 if (GET_CODE (op) == SUBREG)
|
|
88 op = XEXP (op, 0);
|
|
89 regno = REGNO (op);
|
|
90 return (regno >= FIRST_PSEUDO_REGISTER || regno <= 63
|
|
91 || regno == FRAME_POINTER_REGNUM
|
|
92 || regno == ARG_POINTER_REGNUM);
|
|
93 })
|
|
94
|
|
95 ;; Also allows suitable constants
|
|
96 (define_predicate "add_operand"
|
|
97 (match_code "reg,subreg,const_int,symbol_ref,label_ref,const")
|
|
98 {
|
|
99 if (GET_CODE (op) == REG || GET_CODE (op) == SUBREG)
|
|
100 return add_reg_operand (op, mode);
|
|
101 return satisfies_constraint_L (op) || satisfies_constraint_CnL (op);
|
|
102 })
|
|
103
|
|
104 ;; Ordinary 3rd operand for arithmetic operations
|
|
105 (define_predicate "arith_operand"
|
|
106 (match_code "reg,subreg,const_int,symbol_ref,label_ref,const")
|
|
107 {
|
|
108 if (GET_CODE (op) == REG || GET_CODE (op) == SUBREG)
|
|
109 return register_operand (op, mode);
|
|
110 return satisfies_constraint_L (op);
|
|
111 })
|
|
112
|
|
113 ;; Constant integer 3rd operand for arithmetic operations
|
|
114 (define_predicate "arith_int_operand"
|
|
115 (match_code "const_int,symbol_ref,label_ref,const")
|
|
116 {
|
|
117 return satisfies_constraint_L (op);
|
|
118 })
|
|
119
|
|
120 ;; Return true if OP is an acceptable argument for a single word move source.
|
|
121
|
|
122 (define_predicate "move_src_operand"
|
|
123 (match_code
|
|
124 "symbol_ref,label_ref,const,const_int,const_double,reg,subreg,mem,unspec")
|
|
125 {
|
|
126 switch (GET_CODE (op))
|
|
127 {
|
|
128 case SYMBOL_REF :
|
|
129 case LABEL_REF :
|
|
130 case CONST :
|
|
131 return 1;
|
|
132 case CONST_INT :
|
|
133 return immediate_operand (op, mode);
|
|
134 case CONST_DOUBLE :
|
|
135 /* SImode constants should always fit into a CONST_INT. Large
|
|
136 unsigned 32-bit constants are represented as negative CONST_INTs. */
|
|
137 gcc_assert (GET_MODE (op) != SImode);
|
|
138 /* We can handle 32-bit floating point constants. */
|
|
139 if (mode == SFmode)
|
|
140 return GET_MODE (op) == SFmode;
|
|
141 return 0;
|
|
142 case REG :
|
|
143 return op != frame_pointer_rtx && register_operand (op, mode);
|
|
144 case SUBREG :
|
|
145 /* (subreg (mem ...) ...) can occur here if the inner part was once a
|
|
146 pseudo-reg and is now a stack slot. */
|
|
147 if (GET_CODE (SUBREG_REG (op)) == MEM)
|
|
148 return address_operand (XEXP (SUBREG_REG (op), 0), mode);
|
|
149 else
|
|
150 return register_operand (op, mode);
|
|
151 case MEM :
|
|
152 return address_operand (XEXP (op, 0), mode);
|
|
153 case UNSPEC:
|
|
154 return satisfies_constraint_Sra (op);
|
|
155 default :
|
|
156 return 0;
|
|
157 }
|
|
158 })
|
|
159
|
|
160 ;; Return true if OP is an acceptable argument for a double word move source.
|
|
161
|
|
162 (define_predicate "move_double_src_operand"
|
|
163 (match_code "reg,subreg,mem,const_int,const_double,const_vector")
|
|
164 {
|
|
165 if (GET_CODE (op) == MEM && misaligned_operand (op, mode)
|
|
166 && !address_operand (plus_constant (Pmode, XEXP (op, 0), 4), SImode))
|
|
167 return 0;
|
|
168 return general_operand (op, mode);
|
|
169 })
|
|
170
|
|
171 ;; Return true if OP is an acceptable argument for a move destination.
|
|
172
|
|
173 (define_predicate "move_dest_operand"
|
|
174 (match_code "reg,subreg,mem")
|
|
175 {
|
|
176 switch (GET_CODE (op))
|
|
177 {
|
|
178 case REG :
|
|
179 return register_operand (op, mode);
|
|
180 case SUBREG :
|
|
181 /* (subreg (mem ...) ...) can occur here if the inner part was once a
|
|
182 pseudo-reg and is now a stack slot. */
|
|
183 if (GET_CODE (SUBREG_REG (op)) == MEM)
|
|
184 {
|
|
185 return address_operand (XEXP (SUBREG_REG (op), 0), mode);
|
|
186 }
|
|
187 else
|
|
188 {
|
|
189 return register_operand (op, mode);
|
|
190 }
|
|
191 case MEM :
|
|
192 if (GET_MODE_SIZE (mode) == 8 && misaligned_operand (op, mode)
|
|
193 && !address_operand (plus_constant (Pmode, XEXP (op, 0), 4), SImode))
|
|
194 return 0;
|
|
195 return address_operand (XEXP (op, 0), mode);
|
|
196 default :
|
|
197 return 0;
|
|
198 }
|
|
199 })
|
|
200
|
|
201 (define_special_predicate "stacktop_operand"
|
|
202 (match_code "mem")
|
|
203 {
|
|
204 if (mode != VOIDmode && GET_MODE (op) != mode)
|
|
205 return false;
|
|
206 return rtx_equal_p (XEXP (op, 0), stack_pointer_rtx);
|
|
207 })
|
|
208
|
|
209 ;; Return 1 if OP is a comparison operator valid for the mode of CC.
|
|
210 ;; This allows the use of MATCH_OPERATOR to recognize all the branch insns.
|
|
211 ;;
|
|
212 ;; Some insns only set a few bits in the condition code. So only allow those
|
|
213 ;; comparisons that use the bits that are valid.
|
|
214
|
|
215 (define_predicate "proper_comparison_operator"
|
|
216 (match_code "eq, ne, le, lt, ge, gt, leu, ltu, geu, gtu, unordered, ordered, uneq, unge, ungt, unle, unlt, ltgt")
|
|
217 {
|
|
218 enum rtx_code code = GET_CODE (op);
|
|
219 rtx cc = XEXP (op, 0);
|
|
220
|
|
221 /* combine can try strange things. */
|
|
222 if (!REG_P (cc))
|
|
223 return 0;
|
|
224 switch (GET_MODE (cc))
|
|
225 {
|
|
226 case E_CC_Zmode:
|
|
227 case E_CC_N_NEmode:
|
|
228 case E_CC_FP_EQmode:
|
|
229 return REGNO (cc) == CC_REGNUM && (code == EQ || code == NE);
|
|
230 case E_CC_C_LTUmode:
|
|
231 return REGNO (cc) == CC_REGNUM && (code == LTU || code == GEU);
|
|
232 case E_CC_C_GTUmode:
|
|
233 return REGNO (cc) == CC_REGNUM && (code == GTU || code == LEU);
|
|
234 case E_CC_FPmode:
|
|
235 return (REGNO (cc) == CCFP_REGNUM
|
|
236 && (code == EQ || code == NE || code == LT || code == LE));
|
|
237 case E_CC_FP_GTEmode:
|
|
238 return (REGNO (cc) == CC_REGNUM
|
|
239 && (code == EQ || code == NE || code == GT || code == GE
|
|
240 || code == UNLE || code == UNLT));
|
|
241 case E_CC_FP_ORDmode:
|
|
242 return REGNO (cc) == CC_REGNUM && (code == ORDERED || code == UNORDERED);
|
|
243 case E_CC_FP_UNEQmode:
|
|
244 return REGNO (cc) == CC_REGNUM && (code == UNEQ || code == LTGT);
|
|
245 case E_CCmode:
|
|
246 return REGNO (cc) == CC_REGNUM;
|
|
247 /* From combiner. */
|
|
248 case E_QImode: case E_SImode: case E_SFmode: case E_HImode:
|
|
249 /* From cse.c:dead_libcall_p. */
|
|
250 case E_DFmode:
|
|
251 return 0;
|
|
252 default:
|
|
253 gcc_unreachable ();
|
|
254 }
|
|
255 })
|
|
256
|
|
257 (define_predicate "addsub_operator"
|
|
258 (match_code "plus, minus"))
|
|
259
|
|
260 (define_predicate "cc_operand"
|
|
261 (and (match_code "reg")
|
|
262 (match_test "REGNO (op) == CC_REGNUM || REGNO (op) == CCFP_REGNUM")))
|
|
263
|
|
264 (define_predicate "const0_operand"
|
|
265 (match_code "const_int, const_double")
|
|
266 {
|
|
267 if (mode == VOIDmode)
|
|
268 mode = GET_MODE (op);
|
|
269 return op == CONST0_RTX (mode);
|
|
270 })
|
|
271
|
|
272 (define_predicate "const_float_1_operand"
|
|
273 (match_code "const_double")
|
|
274 {
|
|
275 return op == CONST1_RTX (mode);
|
|
276 })
|
|
277
|
|
278 (define_predicate "cc_move_operand"
|
|
279 (and (match_code "reg")
|
|
280 (ior (match_test "REGNO (op) == CC_REGNUM")
|
|
281 (match_test "gpr_operand (op, mode)"))))
|
|
282
|
|
283 (define_predicate "float_operation"
|
|
284 (match_code "parallel")
|
|
285 {
|
|
286 /* Most patterns start out with one SET and one CLOBBER, and gain a USE
|
|
287 or two of FP_NEAREST_REGNUM / FP_TRUNCATE_REGNUM / FP_ANYFP_REGNUM
|
|
288 after mode switching. The longer patterns are
|
|
289 all beyond length 4, and before mode switching, end with a
|
|
290 CLOBBER of CCFP_REGNUM. */
|
|
291 int count = XVECLEN (op, 0);
|
|
292 bool inserted = MACHINE_FUNCTION (cfun)->control_use_inserted;
|
|
293 int i;
|
|
294
|
|
295 if (count == 2
|
|
296 /* Vector ashift has an extra use for the constant factor required to
|
|
297 implement the shift as multiply. */
|
|
298 || (count == 3 && GET_CODE (XVECEXP (op, 0, 0)) == SET
|
|
299 && GET_CODE (XEXP (XVECEXP (op, 0, 0), 1)) == ASHIFT))
|
|
300 return !inserted;
|
|
301
|
|
302 /* combine / recog will pass any old garbage here before checking the
|
|
303 rest of the insn. */
|
|
304 if (count <= 3)
|
|
305 return false;
|
|
306
|
|
307 i = 1;
|
|
308 if (count > 4)
|
|
309 for (i = 2; i < count; i++)
|
|
310 {
|
|
311 rtx x = XVECEXP (op, 0, i);
|
|
312
|
|
313 if (GET_CODE (x) == CLOBBER)
|
|
314 {
|
|
315 if (!REG_P (XEXP (x, 0)))
|
|
316 return false;
|
|
317 if (REGNO (XEXP (x, 0)) == CCFP_REGNUM)
|
|
318 {
|
|
319 if (count == i + 1)
|
|
320 return !inserted;
|
|
321 break;
|
|
322 }
|
|
323 /* Just an ordinary clobber, keep looking. */
|
|
324 }
|
|
325 else if (GET_CODE (x) == USE
|
|
326 || (GET_CODE (x) == SET && i == 2))
|
|
327 continue;
|
|
328 else
|
|
329 return false;
|
|
330 }
|
|
331 if (count != i + 3 || !inserted)
|
|
332 return false;
|
|
333 for (i = i+1; i < count; i++)
|
|
334 {
|
|
335 rtx x = XVECEXP (op, 0, i);
|
|
336
|
|
337 if (GET_CODE (x) != USE && GET_CODE (x) != CLOBBER)
|
|
338 return false;
|
|
339 x = XEXP (x, 0);
|
|
340 if (!REG_P (x)
|
|
341 || (REGNO (x) != FP_NEAREST_REGNUM
|
|
342 && REGNO (x) != FP_TRUNCATE_REGNUM
|
|
343 && REGNO (x) != FP_ANYFP_REGNUM))
|
|
344 return false;
|
|
345 }
|
|
346 return true;
|
|
347 })
|
|
348
|
|
349 (define_predicate "set_fp_mode_operand"
|
|
350 (ior (match_test "gpr_operand (op, mode)")
|
|
351 (and (match_code "const")
|
|
352 (match_test "satisfies_constraint_Cfm (op)"))))
|
|
353
|
|
354 (define_predicate "post_modify_address"
|
|
355 (match_code "post_modify,post_inc,post_dec"))
|
|
356
|
|
357 (define_predicate "post_modify_operand"
|
|
358 (and (match_code "mem")
|
|
359 (match_test "post_modify_address (XEXP (op, 0), Pmode)")))
|
|
360
|
|
361 ; used in the memory clobber of stack_adjust_str, allows addresses with
|
|
362 ; large offsets.
|
|
363 (define_predicate "memclob_operand"
|
|
364 (match_code "mem"))
|
|
365
|
|
366 (define_predicate "nonsymbolic_immediate_operand"
|
|
367 (ior (match_test "immediate_operand (op, mode)")
|
|
368 (match_code "const_vector"))) /* Is this specific enough? */
|
|
369
|
|
370 ;; Return true if OP is misaligned memory operand
|
|
371 (define_predicate "misaligned_operand"
|
|
372 (and (match_code "mem")
|
|
373 (match_test "MEM_ALIGN (op) < GET_MODE_ALIGNMENT (mode)")))
|