OSDN Git Service

config/
[pf3gnuchains/gcc-fork.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 })