OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.2.2/] [gcc/] [config/] [m32r/] [predicates.md] - Blame information for rev 38

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 38 julius
;; Predicate definitions for Renesas M32R.
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
;; .
19
 
20
;; Return true if OP is a register or the constant 0.
21
 
22
(define_predicate "reg_or_zero_operand"
23
  (match_code "reg,subreg,const_int")
24
{
25
  if (GET_CODE (op) == REG || GET_CODE (op) == SUBREG)
26
    return register_operand (op, mode);
27
 
28
  if (GET_CODE (op) != CONST_INT)
29
    return 0;
30
 
31
  return INTVAL (op) == 0;
32
})
33
 
34
;; Return nonzero if the operand is suitable for use in a conditional
35
;; move sequence.
36
 
37
(define_predicate "conditional_move_operand"
38
  (match_code "reg,subreg,const_int")
39
{
40
  /* Only defined for simple integers so far...  */
41
  if (mode != SImode && mode != HImode && mode != QImode)
42
    return FALSE;
43
 
44
  /* At the moment we can handle moving registers and loading constants.  */
45
  /* To be added: Addition/subtraction/bitops/multiplication of registers.  */
46
 
47
  switch (GET_CODE (op))
48
    {
49
    case REG:
50
      return 1;
51
 
52
    case CONST_INT:
53
      return INT8_P (INTVAL (op));
54
 
55
    default:
56
#if 0
57
      fprintf (stderr, "Test for cond move op of type: %s\n",
58
               GET_RTX_NAME (GET_CODE (op)));
59
#endif
60
      return 0;
61
    }
62
})
63
 
64
;; Return true if the code is a test of the carry bit.
65
 
66
(define_predicate "carry_compare_operand"
67
  (match_code "eq,ne")
68
{
69
  rtx x;
70
 
71
  if (GET_MODE (op) != CCmode && GET_MODE (op) != VOIDmode)
72
    return FALSE;
73
 
74
  if (GET_CODE (op) != NE && GET_CODE (op) != EQ)
75
    return FALSE;
76
 
77
  x = XEXP (op, 0);
78
  if (GET_CODE (x) != REG || REGNO (x) != CARRY_REGNUM)
79
    return FALSE;
80
 
81
  x = XEXP (op, 1);
82
  if (GET_CODE (x) != CONST_INT || INTVAL (x) != 0)
83
    return FALSE;
84
 
85
  return TRUE;
86
})
87
 
88
;; Return 1 if OP is an EQ or NE comparison operator.
89
 
90
(define_predicate "eqne_comparison_operator"
91
  (match_code "eq,ne")
92
{
93
  enum rtx_code code = GET_CODE (op);
94
 
95
  return (code == EQ || code == NE);
96
})
97
 
98
;; Return 1 if OP is a signed comparison operator.
99
 
100
(define_predicate "signed_comparison_operator"
101
  (match_code "eq,ne,lt,le,gt,ge")
102
{
103
  enum rtx_code code = GET_CODE (op);
104
 
105
  return (COMPARISON_P (op)
106
          && (code == EQ || code == NE
107
              || code == LT || code == LE || code == GT || code == GE));
108
})
109
 
110
;; Return true if OP is an acceptable argument for a move destination.
111
 
112
(define_predicate "move_dest_operand"
113
  (match_code "reg,subreg,mem")
114
{
115
  switch (GET_CODE (op))
116
    {
117
    case REG :
118
      return register_operand (op, mode);
119
    case SUBREG :
120
      /* (subreg (mem ...) ...) can occur here if the inner part was once a
121
         pseudo-reg and is now a stack slot.  */
122
      if (GET_CODE (SUBREG_REG (op)) == MEM)
123
        return address_operand (XEXP (SUBREG_REG (op), 0), mode);
124
      else
125
        return register_operand (op, mode);
126
    case MEM :
127
      if (GET_CODE (XEXP (op, 0)) == POST_INC)
128
        return 0;               /* stores can't do post inc */
129
      return address_operand (XEXP (op, 0), mode);
130
    default :
131
      return 0;
132
    }
133
})
134
 
135
;; Return true if OP is an acceptable argument for a single word move
136
;; source.
137
 
138
(define_predicate "move_src_operand"
139
  (match_code "reg,subreg,mem,const_int,const_double,label_ref,const,symbol_ref")
140
{
141
  switch (GET_CODE (op))
142
    {
143
    case LABEL_REF :
144
    case SYMBOL_REF :
145
    case CONST :
146
      return addr24_operand (op, mode);
147
    case CONST_INT :
148
      /* ??? We allow more cse opportunities if we only allow constants
149
         loadable with one insn, and split the rest into two.  The instances
150
         where this would help should be rare and the current way is
151
         simpler.  */
152
      if (HOST_BITS_PER_WIDE_INT > 32)
153
        {
154
          HOST_WIDE_INT rest = INTVAL (op) >> 31;
155
          return (rest == 0 || rest == -1);
156
        }
157
      else
158
        return 1;
159
    case CONST_DOUBLE :
160
      if (mode == SFmode)
161
        return 1;
162
      else if (mode == SImode)
163
        {
164
          /* Large unsigned constants are represented as const_double's.  */
165
          unsigned HOST_WIDE_INT low, high;
166
 
167
          low = CONST_DOUBLE_LOW (op);
168
          high = CONST_DOUBLE_HIGH (op);
169
          return high == 0 && low <= (unsigned) 0xffffffff;
170
        }
171
      else
172
        return 0;
173
    case REG :
174
      return register_operand (op, mode);
175
    case SUBREG :
176
      /* (subreg (mem ...) ...) can occur here if the inner part was once a
177
         pseudo-reg and is now a stack slot.  */
178
      if (GET_CODE (SUBREG_REG (op)) == MEM)
179
        return address_operand (XEXP (SUBREG_REG (op), 0), mode);
180
      else
181
        return register_operand (op, mode);
182
    case MEM :
183
      if (GET_CODE (XEXP (op, 0)) == PRE_INC
184
          || GET_CODE (XEXP (op, 0)) == PRE_DEC)
185
        return 0;               /* loads can't do pre-{inc,dec} */
186
      return address_operand (XEXP (op, 0), mode);
187
    default :
188
      return 0;
189
    }
190
})
191
 
192
;; Return true if OP is an acceptable argument for a double word move
193
;; source.
194
 
195
(define_predicate "move_double_src_operand"
196
  (match_code "reg,subreg,mem,const_int,const_double")
197
{
198
  switch (GET_CODE (op))
199
    {
200
    case CONST_INT :
201
    case CONST_DOUBLE :
202
      return 1;
203
    case REG :
204
      return register_operand (op, mode);
205
    case SUBREG :
206
      /* (subreg (mem ...) ...) can occur here if the inner part was once a
207
         pseudo-reg and is now a stack slot.  */
208
      if (GET_CODE (SUBREG_REG (op)) == MEM)
209
        return move_double_src_operand (SUBREG_REG (op), mode);
210
      else
211
        return register_operand (op, mode);
212
    case MEM :
213
      /* Disallow auto inc/dec for now.  */
214
      if (GET_CODE (XEXP (op, 0)) == PRE_DEC
215
          || GET_CODE (XEXP (op, 0)) == PRE_INC)
216
        return 0;
217
      return address_operand (XEXP (op, 0), mode);
218
    default :
219
      return 0;
220
    }
221
})
222
 
223
;; Return true if OP is a const_int requiring two instructions to
224
;; load.
225
 
226
(define_predicate "two_insn_const_operand"
227
  (match_code "const_int")
228
{
229
  if (GET_CODE (op) != CONST_INT)
230
    return 0;
231
  if (INT16_P (INTVAL (op))
232
      || UINT24_P (INTVAL (op))
233
      || UPPER16_P (INTVAL (op)))
234
    return 0;
235
  return 1;
236
})
237
 
238
;; Returns 1 if OP is a symbol reference.
239
 
240
(define_predicate "symbolic_operand"
241
  (match_code "symbol_ref,label_ref,const")
242
{
243
  switch (GET_CODE (op))
244
    {
245
    case SYMBOL_REF:
246
    case LABEL_REF:
247
    case CONST :
248
      return 1;
249
 
250
    default:
251
      return 0;
252
    }
253
})
254
 
255
;; Return true if OP is a signed 8 bit immediate value.
256
 
257
(define_predicate "int8_operand"
258
  (match_code "const_int")
259
{
260
  if (GET_CODE (op) != CONST_INT)
261
    return 0;
262
  return INT8_P (INTVAL (op));
263
})
264
 
265
;; Return true if OP is an unsigned 16 bit immediate value.
266
 
267
(define_predicate "uint16_operand"
268
  (match_code "const_int")
269
{
270
  if (GET_CODE (op) != CONST_INT)
271
    return 0;
272
  return UINT16_P (INTVAL (op));
273
})
274
 
275
;; Return true if OP is a register or signed 16 bit value.
276
 
277
(define_predicate "reg_or_int16_operand"
278
  (match_code "reg,subreg,const_int")
279
{
280
  if (GET_CODE (op) == REG || GET_CODE (op) == SUBREG)
281
    return register_operand (op, mode);
282
  if (GET_CODE (op) != CONST_INT)
283
    return 0;
284
  return INT16_P (INTVAL (op));
285
})
286
 
287
;; Return true if OP is a register or an unsigned 16 bit value.
288
 
289
(define_predicate "reg_or_uint16_operand"
290
  (match_code "reg,subreg,const_int")
291
{
292
  if (GET_CODE (op) == REG || GET_CODE (op) == SUBREG)
293
    return register_operand (op, mode);
294
  if (GET_CODE (op) != CONST_INT)
295
    return 0;
296
  return UINT16_P (INTVAL (op));
297
})
298
 
299
;; Return true if OP is a register or signed 16 bit value for
300
;; compares.
301
 
302
(define_predicate "reg_or_cmp_int16_operand"
303
  (match_code "reg,subreg,const_int")
304
{
305
  if (GET_CODE (op) == REG || GET_CODE (op) == SUBREG)
306
    return register_operand (op, mode);
307
  if (GET_CODE (op) != CONST_INT)
308
    return 0;
309
  return CMP_INT16_P (INTVAL (op));
310
})
311
 
312
;; Return true if OP is a register or an integer value that can be
313
;; used is SEQ/SNE.  We can use either XOR of the value or ADD of the
314
;; negative of the value for the constant.  Don't allow 0, because
315
;; that is special cased.
316
 
317
(define_predicate "reg_or_eq_int16_operand"
318
  (match_code "reg,subreg,const_int")
319
{
320
  HOST_WIDE_INT value;
321
 
322
  if (GET_CODE (op) == REG || GET_CODE (op) == SUBREG)
323
    return register_operand (op, mode);
324
 
325
  if (GET_CODE (op) != CONST_INT)
326
    return 0;
327
 
328
  value = INTVAL (op);
329
  return (value != 0) && (UINT16_P (value) || CMP_INT16_P (-value));
330
})
331
 
332
;; Return true if OP is a signed 16 bit immediate value useful in
333
;; comparisons.
334
 
335
(define_predicate "cmp_int16_operand"
336
  (match_code "const_int")
337
{
338
  if (GET_CODE (op) != CONST_INT)
339
    return 0;
340
  return CMP_INT16_P (INTVAL (op));
341
})
342
 
343
;; Acceptable arguments to the call insn.
344
 
345
(define_predicate "call_address_operand"
346
  (match_code "symbol_ref,label_ref,const")
347
{
348
  return symbolic_operand (op, mode);
349
 
350
/* Constants and values in registers are not OK, because
351
   the m32r BL instruction can only support PC relative branching.  */
352
})
353
 
354
;; Return true if OP is an acceptable input argument for a zero/sign
355
;; extend operation.
356
 
357
(define_predicate "extend_operand"
358
  (match_code "reg,subreg,mem")
359
{
360
  rtx addr;
361
 
362
  switch (GET_CODE (op))
363
    {
364
    case REG :
365
    case SUBREG :
366
      return register_operand (op, mode);
367
 
368
    case MEM :
369
      addr = XEXP (op, 0);
370
      if (GET_CODE (addr) == PRE_INC || GET_CODE (addr) == PRE_DEC)
371
        return 0;               /* loads can't do pre inc/pre dec */
372
 
373
      return address_operand (addr, mode);
374
 
375
    default :
376
      return 0;
377
    }
378
})
379
 
380
;; Return nonzero if the operand is an insn that is a small
381
;; insn. Allow const_int 0 as well, which is a placeholder for NOP
382
;; slots.
383
 
384
(define_predicate "small_insn_p"
385
  (match_code "insn,call_insn,jump_insn")
386
{
387
  if (GET_CODE (op) == CONST_INT && INTVAL (op) == 0)
388
    return 1;
389
 
390
  if (! INSN_P (op))
391
    return 0;
392
 
393
  return get_attr_length (op) == 2;
394
})
395
 
396
;; Return true if op is an integer constant, less than or equal to
397
;; MAX_MOVE_BYTES.
398
 
399
(define_predicate "m32r_block_immediate_operand"
400
  (match_code "const_int")
401
{
402
  if (GET_CODE (op) != CONST_INT
403
      || INTVAL (op) > MAX_MOVE_BYTES
404
      || INTVAL (op) <= 0)
405
    return 0;
406
 
407
  return 1;
408
})
409
 
410
;; Return nonzero if the operand is an insn that is a large insn.
411
 
412
(define_predicate "large_insn_p"
413
  (match_code "insn,call_insn,jump_insn")
414
{
415
  if (! INSN_P (op))
416
    return 0;
417
 
418
  return get_attr_length (op) != 2;
419
})
420
 
421
;; Returns 1 if OP is an acceptable operand for seth/add3.
422
 
423
(define_predicate "seth_add3_operand"
424
  (match_code "symbol_ref,label_ref,const")
425
{
426
  if (flag_pic)
427
    return 0;
428
 
429
  if (GET_CODE (op) == SYMBOL_REF
430
      || GET_CODE (op) == LABEL_REF)
431
    return 1;
432
 
433
  if (GET_CODE (op) == CONST
434
      && GET_CODE (XEXP (op, 0)) == PLUS
435
      && GET_CODE (XEXP (XEXP (op, 0), 0)) == SYMBOL_REF
436
      && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT
437
      && INT16_P (INTVAL (XEXP (XEXP (op, 0), 1))))
438
    return 1;
439
 
440
  return 0;
441
})

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.