]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/c4x/predicates.md
host-hpux.c: Change copyright header to refer to version 3 of the GNU General Public...
[thirdparty/gcc.git] / gcc / config / c4x / predicates.md
1 ;; Predicate definitions for TMS320C[34]x.
2 ;; Copyright (C) 2005, 2007 Free Software Foundation, Inc.
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 ;; Nonzero if OP is a floating point value with value 0.0.
21
22 (define_predicate "fp_zero_operand"
23 (match_code "const_double")
24 {
25 REAL_VALUE_TYPE r;
26
27 if (GET_CODE (op) != CONST_DOUBLE)
28 return 0;
29 REAL_VALUE_FROM_CONST_DOUBLE (r, op);
30 return REAL_VALUES_EQUAL (r, dconst0);
31 })
32
33 ;; TODO: Add a comment here.
34
35 (define_predicate "const_operand"
36 (match_code "const_int,const_double")
37 {
38 switch (mode)
39 {
40 case QFmode:
41 case HFmode:
42 if (GET_CODE (op) != CONST_DOUBLE
43 || GET_MODE (op) != mode
44 || GET_MODE_CLASS (mode) != MODE_FLOAT)
45 return 0;
46
47 return c4x_immed_float_p (op);
48
49 #if Pmode != QImode
50 case Pmode:
51 #endif
52 case QImode:
53 if (GET_CODE (op) != CONST_INT
54 || (GET_MODE (op) != VOIDmode && GET_MODE (op) != mode)
55 || GET_MODE_CLASS (mode) != MODE_INT)
56 return 0;
57
58 return IS_HIGH_CONST (INTVAL (op)) || IS_INT16_CONST (INTVAL (op));
59
60 case HImode:
61 return 0;
62
63 default:
64 return 0;
65 }
66 })
67
68 ;; TODO: Add a comment here.
69
70 (define_predicate "stik_const_operand"
71 (match_code "const_int")
72 {
73 return c4x_K_constant (op);
74 })
75
76 ;; TODO: Add a comment here.
77
78 (define_predicate "not_const_operand"
79 (match_code "const_int")
80 {
81 return c4x_N_constant (op);
82 })
83
84 ;; TODO: Add a comment here.
85
86 (define_predicate "reg_operand"
87 (match_code "reg,subreg")
88 {
89 if (GET_CODE (op) == SUBREG
90 && GET_MODE (op) == QFmode)
91 return 0;
92 return register_operand (op, mode);
93 })
94
95 ;; TODO: Add a comment here.
96
97 (define_predicate "reg_or_const_operand"
98 (match_code "reg,subreg,const_int,const_double")
99 {
100 return reg_operand (op, mode) || const_operand (op, mode);
101 })
102
103 ;; Extended precision register R0-R1.
104
105 (define_predicate "r0r1_reg_operand"
106 (match_code "reg,subreg")
107 {
108 if (! reg_operand (op, mode))
109 return 0;
110 if (GET_CODE (op) == SUBREG)
111 op = SUBREG_REG (op);
112 return REG_P (op) && IS_R0R1_OR_PSEUDO_REG (op);
113 })
114
115 ;; Extended precision register R2-R3.
116
117 (define_predicate "r2r3_reg_operand"
118 (match_code "reg,subreg")
119 {
120 if (! reg_operand (op, mode))
121 return 0;
122 if (GET_CODE (op) == SUBREG)
123 op = SUBREG_REG (op);
124 return REG_P (op) && IS_R2R3_OR_PSEUDO_REG (op);
125 })
126
127 ;; Low extended precision register R0-R7.
128
129 (define_predicate "ext_low_reg_operand"
130 (match_code "reg,subreg")
131 {
132 if (! reg_operand (op, mode))
133 return 0;
134 if (GET_CODE (op) == SUBREG)
135 op = SUBREG_REG (op);
136 return REG_P (op) && IS_EXT_LOW_OR_PSEUDO_REG (op);
137 })
138
139 ;; Extended precision register.
140
141 (define_predicate "ext_reg_operand"
142 (match_code "reg,subreg")
143 {
144 if (! reg_operand (op, mode))
145 return 0;
146 if (GET_CODE (op) == SUBREG)
147 op = SUBREG_REG (op);
148 if (! REG_P (op))
149 return 0;
150 return IS_EXT_OR_PSEUDO_REG (op);
151 })
152
153 ;; Standard precision register.
154
155 (define_predicate "std_reg_operand"
156 (match_code "reg,subreg")
157 {
158 if (! reg_operand (op, mode))
159 return 0;
160 if (GET_CODE (op) == SUBREG)
161 op = SUBREG_REG (op);
162 return REG_P (op) && IS_STD_OR_PSEUDO_REG (op);
163 })
164
165 ;; Standard precision or normal register.
166
167 (define_predicate "std_or_reg_operand"
168 (match_code "reg,subreg")
169 {
170 if (reload_in_progress)
171 return std_reg_operand (op, mode);
172 return reg_operand (op, mode);
173 })
174
175 ;; Address register.
176
177 (define_predicate "addr_reg_operand"
178 (match_code "reg,subreg")
179 {
180 if (! reg_operand (op, mode))
181 return 0;
182 return c4x_a_register (op);
183 })
184
185 ;; Index register.
186
187 (define_predicate "index_reg_operand"
188 (match_code "reg,subreg")
189 {
190 if (! reg_operand (op, mode))
191 return 0;
192 if (GET_CODE (op) == SUBREG)
193 op = SUBREG_REG (op);
194 return c4x_x_register (op);
195 })
196
197 ;; DP register.
198
199 (define_predicate "dp_reg_operand"
200 (match_code "reg")
201 {
202 return REG_P (op) && IS_DP_OR_PSEUDO_REG (op);
203 })
204
205 ;; SP register.
206
207 (define_predicate "sp_reg_operand"
208 (match_code "reg")
209 {
210 return REG_P (op) && IS_SP_OR_PSEUDO_REG (op);
211 })
212
213 ;; ST register.
214
215 (define_predicate "st_reg_operand"
216 (match_code "reg")
217 {
218 return REG_P (op) && IS_ST_OR_PSEUDO_REG (op);
219 })
220
221 ;; RC register.
222
223 (define_predicate "rc_reg_operand"
224 (match_code "reg")
225 {
226 return REG_P (op) && IS_RC_OR_PSEUDO_REG (op);
227 })
228
229 ;; TODO: Add a comment here.
230
231 (define_predicate "call_address_operand"
232 (match_code "reg,symbol_ref,label_ref,const")
233 {
234 return (REG_P (op) || symbolic_address_operand (op, mode));
235 })
236
237 ;; Check dst operand of a move instruction.
238
239 (define_predicate "dst_operand"
240 (match_code "subreg,reg,mem")
241 {
242 if (GET_CODE (op) == SUBREG
243 && mixed_subreg_operand (op, mode))
244 return 0;
245
246 if (REG_P (op))
247 return reg_operand (op, mode);
248
249 return nonimmediate_operand (op, mode);
250 })
251
252 ;; Check src operand of two operand arithmetic instructions.
253
254 (define_predicate "src_operand"
255 (match_code "subreg,reg,mem,const_int,const_double")
256 {
257 if (GET_CODE (op) == SUBREG
258 && mixed_subreg_operand (op, mode))
259 return 0;
260
261 if (REG_P (op))
262 return reg_operand (op, mode);
263
264 if (mode == VOIDmode)
265 mode = GET_MODE (op);
266
267 if (GET_CODE (op) == CONST_INT)
268 return (mode == QImode || mode == Pmode || mode == HImode)
269 && c4x_I_constant (op);
270
271 /* We don't like CONST_DOUBLE integers. */
272 if (GET_CODE (op) == CONST_DOUBLE)
273 return c4x_H_constant (op);
274
275 /* Disallow symbolic addresses. Only the predicate
276 symbolic_address_operand will match these. */
277 if (GET_CODE (op) == SYMBOL_REF
278 || GET_CODE (op) == LABEL_REF
279 || GET_CODE (op) == CONST)
280 return 0;
281
282 /* If TARGET_LOAD_DIRECT_MEMS is nonzero, disallow direct memory
283 access to symbolic addresses. These operands will get forced
284 into a register and the movqi expander will generate a
285 HIGH/LO_SUM pair if TARGET_EXPOSE_LDP is nonzero. */
286 if (GET_CODE (op) == MEM
287 && ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
288 || GET_CODE (XEXP (op, 0)) == LABEL_REF
289 || GET_CODE (XEXP (op, 0)) == CONST)))
290 return !TARGET_EXPOSE_LDP &&
291 ! TARGET_LOAD_DIRECT_MEMS && GET_MODE (op) == mode;
292
293 return general_operand (op, mode);
294 })
295
296 ;; TODO: Add a comment here.
297
298 (define_predicate "src_hi_operand"
299 (match_code "subreg,reg,mem,const_double")
300 {
301 if (c4x_O_constant (op))
302 return 1;
303 return src_operand (op, mode);
304 })
305
306 ;; Check src operand of two operand logical instructions.
307
308 (define_predicate "lsrc_operand"
309 (match_code "subreg,reg,mem,const_int,const_double")
310 {
311 if (mode == VOIDmode)
312 mode = GET_MODE (op);
313
314 if (mode != QImode && mode != Pmode)
315 fatal_insn ("mode not QImode", op);
316
317 if (GET_CODE (op) == CONST_INT)
318 return c4x_L_constant (op) || c4x_J_constant (op);
319
320 return src_operand (op, mode);
321 })
322
323 ;; Check src operand of two operand tricky instructions.
324
325 (define_predicate "tsrc_operand"
326 (match_code "subreg,reg,mem,const_int,const_double")
327 {
328 if (mode == VOIDmode)
329 mode = GET_MODE (op);
330
331 if (mode != QImode && mode != Pmode)
332 fatal_insn ("mode not QImode", op);
333
334 if (GET_CODE (op) == CONST_INT)
335 return c4x_L_constant (op) || c4x_N_constant (op) || c4x_J_constant (op);
336
337 return src_operand (op, mode);
338 })
339
340 ;; Check src operand of two operand non immediate instructions.
341
342 (define_predicate "nonimmediate_src_operand"
343 (match_code "subreg,reg,mem")
344 {
345 if (GET_CODE (op) == CONST_INT || GET_CODE (op) == CONST_DOUBLE)
346 return 0;
347
348 return src_operand (op, mode);
349 })
350
351 ;; Check logical src operand of two operand non immediate instructions.
352
353 (define_predicate "nonimmediate_lsrc_operand"
354 (match_code "subreg,reg,mem")
355 {
356 if (GET_CODE (op) == CONST_INT || GET_CODE (op) == CONST_DOUBLE)
357 return 0;
358
359 return lsrc_operand (op, mode);
360 })
361
362 ;; Match any operand.
363
364 (define_predicate "any_operand"
365 (match_code "subreg,reg,mem,const_int,const_double")
366 {
367 return 1;
368 })
369
370 ;; Check for indirect operands allowable in parallel instruction.
371
372 (define_predicate "par_ind_operand"
373 (match_code "mem")
374 {
375 if (mode != VOIDmode && mode != GET_MODE (op))
376 return 0;
377
378 return c4x_S_indirect (op);
379 })
380
381 ;; Check for operands allowable in parallel instruction.
382
383 (define_predicate "parallel_operand"
384 (match_code "subreg,reg,mem")
385 {
386 return ext_low_reg_operand (op, mode) || par_ind_operand (op, mode);
387 })
388
389 ;; Symbolic address operand.
390
391 (define_predicate "symbolic_address_operand"
392 (match_code "symbol_ref,label_ref,const")
393 {
394 switch (GET_CODE (op))
395 {
396 case CONST:
397 case SYMBOL_REF:
398 case LABEL_REF:
399 return 1;
400 default:
401 return 0;
402 }
403 })