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