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/] [h8300/] [predicates.md] - Blame information for rev 154

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 38 julius
;; Predicate definitions for Renesas H8/300.
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 valid source operand for an integer move
21
;; instruction.
22
 
23
(define_predicate "general_operand_src"
24
  (match_code "const_int,const_double,const,symbol_ref,label_ref,subreg,reg,mem")
25
{
26
  if (GET_MODE (op) == mode
27
      && GET_CODE (op) == MEM
28
      && GET_CODE (XEXP (op, 0)) == POST_INC)
29
    return 1;
30
  return general_operand (op, mode);
31
})
32
 
33
;; Return true if OP is a valid destination operand for an integer
34
;; move instruction.
35
 
36
(define_predicate "general_operand_dst"
37
  (match_code "subreg,reg,mem")
38
{
39
  if (GET_MODE (op) == mode
40
      && GET_CODE (op) == MEM
41
      && GET_CODE (XEXP (op, 0)) == PRE_DEC)
42
    return 1;
43
  return general_operand (op, mode);
44
})
45
 
46
;; Likewise the second operand.
47
 
48
(define_predicate "h8300_src_operand"
49
  (match_code "const_int,const_double,const,symbol_ref,label_ref,subreg,reg,mem")
50
{
51
  if (TARGET_H8300SX)
52
    return general_operand (op, mode);
53
  return nonmemory_operand (op, mode);
54
})
55
 
56
;; Return true if OP is a suitable first operand for a general
57
;; arithmetic insn such as "add".
58
 
59
(define_predicate "h8300_dst_operand"
60
  (match_code "subreg,reg,mem")
61
{
62
  if (TARGET_H8300SX)
63
    return nonimmediate_operand (op, mode);
64
  return register_operand (op, mode);
65
})
66
 
67
;; Check that an operand is either a register or an unsigned 4-bit
68
;; constant.
69
 
70
(define_predicate "nibble_operand"
71
  (match_code "const_int")
72
{
73
  return (GET_CODE (op) == CONST_INT && TARGET_H8300SX
74
          && INTVAL (op) >= 0 && INTVAL (op) <= 15);
75
})
76
 
77
;; Check that an operand is either a register or an unsigned 4-bit
78
;; constant.
79
 
80
(define_predicate "reg_or_nibble_operand"
81
  (match_code "const_int,subreg,reg")
82
{
83
  return (nibble_operand (op, mode) || register_operand (op, mode));
84
})
85
 
86
;; Return true if X is a shift operation of type H8SX_SHIFT_UNARY.
87
 
88
(define_predicate "h8sx_unary_shift_operator"
89
  (match_code "ashiftrt,lshiftrt,ashift,rotate")
90
{
91
  return (BINARY_P (op) && NON_COMMUTATIVE_P (op)
92
          && (h8sx_classify_shift (GET_MODE (op), GET_CODE (op), XEXP (op, 1))
93
              == H8SX_SHIFT_UNARY));
94
})
95
 
96
;; Likewise H8SX_SHIFT_BINARY.
97
 
98
(define_predicate "h8sx_binary_shift_operator"
99
  (match_code "ashiftrt,lshiftrt,ashift")
100
{
101
  return (BINARY_P (op) && NON_COMMUTATIVE_P (op)
102
          && (h8sx_classify_shift (GET_MODE (op), GET_CODE (op), XEXP (op, 1))
103
              == H8SX_SHIFT_BINARY));
104
})
105
 
106
;; Return true if OP is a binary operator in which it would be safe to
107
;; replace register operands with memory operands.
108
 
109
(define_predicate "h8sx_binary_memory_operator"
110
  (match_code "plus,minus,and,ior,xor,ashift,ashiftrt,lshiftrt,rotate")
111
{
112
  if (!TARGET_H8300SX)
113
    return false;
114
 
115
  if (GET_MODE (op) != QImode
116
      && GET_MODE (op) != HImode
117
      && GET_MODE (op) != SImode)
118
    return false;
119
 
120
  switch (GET_CODE (op))
121
    {
122
    case PLUS:
123
    case MINUS:
124
    case AND:
125
    case IOR:
126
    case XOR:
127
      return true;
128
 
129
    default:
130
      return h8sx_unary_shift_operator (op, mode);
131
    }
132
})
133
 
134
;; Like h8sx_binary_memory_operator, but applies to unary operators.
135
 
136
(define_predicate "h8sx_unary_memory_operator"
137
  (match_code "neg,not")
138
{
139
  if (!TARGET_H8300SX)
140
    return false;
141
 
142
  if (GET_MODE (op) != QImode
143
      && GET_MODE (op) != HImode
144
      && GET_MODE (op) != SImode)
145
    return false;
146
 
147
  switch (GET_CODE (op))
148
    {
149
    case NEG:
150
    case NOT:
151
      return true;
152
 
153
    default:
154
      return false;
155
    }
156
})
157
 
158
;; Return true if X is an ldm.l pattern.  X is known to be parallel.
159
 
160
(define_predicate "h8300_ldm_parallel"
161
  (match_code "parallel")
162
{
163
  return h8300_ldm_stm_parallel (XVEC (op, 0), 1, 0);
164
})
165
 
166
;; Likewise stm.l.
167
 
168
(define_predicate "h8300_stm_parallel"
169
  (match_code "parallel")
170
{
171
  return h8300_ldm_stm_parallel (XVEC (op, 0), 0, 0);
172
})
173
 
174
;; Likewise rts/l and rte/l.  Note that the .md pattern will check for
175
;; the return so there's no need to do that here.
176
 
177
(define_predicate "h8300_return_parallel"
178
  (match_code "parallel")
179
{
180
  return h8300_ldm_stm_parallel (XVEC (op, 0), 1, 1);
181
})
182
 
183
;; Return true if OP is a constant that contains only one 1 in its
184
;; binary representation.
185
 
186
(define_predicate "single_one_operand"
187
  (match_code "const_int")
188
{
189
  if (GET_CODE (op) == CONST_INT)
190
    {
191
      /* We really need to do this masking because 0x80 in QImode is
192
         represented as -128 for example.  */
193
      if (exact_log2 (INTVAL (op) & GET_MODE_MASK (mode)) >= 0)
194
        return 1;
195
    }
196
 
197
  return 0;
198
})
199
 
200
;; Return true if OP is a constant that contains only one 0 in its
201
;; binary representation.
202
 
203
(define_predicate "single_zero_operand"
204
  (match_code "const_int")
205
{
206
  if (GET_CODE (op) == CONST_INT)
207
    {
208
      /* We really need to do this masking because 0x80 in QImode is
209
         represented as -128 for example.  */
210
      if (exact_log2 (~INTVAL (op) & GET_MODE_MASK (mode)) >= 0)
211
        return 1;
212
    }
213
 
214
  return 0;
215
})
216
 
217
;; Return true if OP is a valid call operand.
218
 
219
(define_predicate "call_insn_operand"
220
  (match_code "mem")
221
{
222
  if (GET_CODE (op) == MEM)
223
    {
224
      rtx inside = XEXP (op, 0);
225
      if (register_operand (inside, Pmode))
226
        return 1;
227
      if (CONSTANT_ADDRESS_P (inside))
228
        return 1;
229
    }
230
  return 0;
231
})
232
 
233
;; Return true if OP is a valid call operand, and OP represents an
234
;; operand for a small call (4 bytes instead of 6 bytes).
235
 
236
(define_predicate "small_call_insn_operand"
237
  (match_code "mem")
238
{
239
  if (GET_CODE (op) == MEM)
240
    {
241
      rtx inside = XEXP (op, 0);
242
 
243
      /* Register indirect is a small call.  */
244
      if (register_operand (inside, Pmode))
245
        return 1;
246
 
247
      /* A call through the function vector is a small call too.  */
248
      if (GET_CODE (inside) == SYMBOL_REF
249
          && (SYMBOL_REF_FLAGS (inside) & SYMBOL_FLAG_FUNCVEC_FUNCTION))
250
        return 1;
251
    }
252
  /* Otherwise it's a large call.  */
253
  return 0;
254
})
255
 
256
;; Return true if OP is a valid jump operand.
257
 
258
(define_predicate "jump_address_operand"
259
  (match_code "reg,mem")
260
{
261
  if (GET_CODE (op) == REG)
262
    return mode == Pmode;
263
 
264
  if (GET_CODE (op) == MEM)
265
    {
266
      rtx inside = XEXP (op, 0);
267
      if (register_operand (inside, Pmode))
268
        return 1;
269
      if (CONSTANT_ADDRESS_P (inside))
270
        return 1;
271
    }
272
  return 0;
273
})
274
 
275
;; Return 1 if an addition/subtraction of a constant integer can be
276
;; transformed into two consecutive adds/subs that are faster than the
277
;; straightforward way.  Otherwise, return 0.
278
 
279
(define_predicate "two_insn_adds_subs_operand"
280
  (match_code "const_int")
281
{
282
  if (TARGET_H8300SX)
283
    return 0;
284
 
285
  if (GET_CODE (op) == CONST_INT)
286
    {
287
      HOST_WIDE_INT value = INTVAL (op);
288
 
289
      /* Force VALUE to be positive so that we do not have to consider
290
         the negative case.  */
291
      if (value < 0)
292
        value = -value;
293
      if (TARGET_H8300H || TARGET_H8300S)
294
        {
295
          /* A constant addition/subtraction takes 2 states in QImode,
296
             4 states in HImode, and 6 states in SImode.  Thus, the
297
             only case we can win is when SImode is used, in which
298
             case, two adds/subs are used, taking 4 states.  */
299
          if (mode == SImode
300
              && (value == 2 + 1
301
                  || value == 4 + 1
302
                  || value == 4 + 2
303
                  || value == 4 + 4))
304
            return 1;
305
        }
306
      else
307
        {
308
          /* We do not profit directly by splitting addition or
309
             subtraction of 3 and 4.  However, since these are
310
             implemented as a sequence of adds or subs, they do not
311
             clobber (cc0) unlike a sequence of add.b and add.x.  */
312
          if (mode == HImode
313
              && (value == 2 + 1
314
                  || value == 2 + 2))
315
            return 1;
316
        }
317
    }
318
 
319
  return 0;
320
})
321
 
322
;; Recognize valid operands for bit-field instructions.
323
 
324
(define_predicate "bit_operand"
325
  (match_code "reg,subreg,mem")
326
{
327
  /* We can accept any nonimmediate operand, except that MEM operands must
328
     be limited to those that use addresses valid for the 'U' constraint.  */
329
  if (!nonimmediate_operand (op, mode))
330
    return 0;
331
 
332
  /* H8SX accepts pretty much anything here.  */
333
  if (TARGET_H8300SX)
334
    return 1;
335
 
336
  /* Accept any mem during RTL generation.  Otherwise, the code that does
337
     insv and extzv will think that we cannot handle memory.  However,
338
     to avoid reload problems, we only accept 'U' MEM operands after RTL
339
     generation.  This means that any named pattern which uses this predicate
340
     must force its operands to match 'U' before emitting RTL.  */
341
 
342
  if (GET_CODE (op) == REG)
343
    return 1;
344
  if (GET_CODE (op) == SUBREG)
345
    return 1;
346
  return (GET_CODE (op) == MEM
347
          && OK_FOR_U (op));
348
})
349
 
350
;; Return nonzero if OP is a MEM suitable for bit manipulation insns.
351
 
352
(define_predicate "bit_memory_operand"
353
  (match_code "mem")
354
{
355
  return (GET_CODE (op) == MEM
356
          && OK_FOR_U (op));
357
})
358
 
359
;; Return nonzero if X is a stack pointer.
360
 
361
(define_predicate "stack_pointer_operand"
362
  (match_code "reg")
363
{
364
  return op == stack_pointer_rtx;
365
})
366
 
367
;; Return nonzero if X is a constant whose absolute value is greater
368
;; than 2.
369
 
370
(define_predicate "const_int_gt_2_operand"
371
  (match_code "const_int")
372
{
373
  return (GET_CODE (op) == CONST_INT
374
          && abs (INTVAL (op)) > 2);
375
})
376
 
377
;; Return nonzero if X is a constant whose absolute value is no
378
;; smaller than 8.
379
 
380
(define_predicate "const_int_ge_8_operand"
381
  (match_code "const_int")
382
{
383
  return (GET_CODE (op) == CONST_INT
384
          && abs (INTVAL (op)) >= 8);
385
})
386
 
387
;; Return nonzero if X is a constant expressible in QImode.
388
 
389
(define_predicate "const_int_qi_operand"
390
  (match_code "const_int")
391
{
392
  return (GET_CODE (op) == CONST_INT
393
          && (INTVAL (op) & 0xff) == INTVAL (op));
394
})
395
 
396
;; Return nonzero if X is a constant expressible in HImode.
397
 
398
(define_predicate "const_int_hi_operand"
399
  (match_code "const_int")
400
{
401
  return (GET_CODE (op) == CONST_INT
402
          && (INTVAL (op) & 0xffff) == INTVAL (op));
403
})
404
 
405
;; Return nonzero if X is a constant suitable for inc/dec.
406
 
407
(define_predicate "incdec_operand"
408
  (match_code "const_int")
409
{
410
  return (GET_CODE (op) == CONST_INT
411
          && (CONST_OK_FOR_M (INTVAL (op))
412
              || CONST_OK_FOR_O (INTVAL (op))));
413
})
414
 
415
;; Recognize valid operators for bit instructions.
416
 
417
(define_predicate "bit_operator"
418
  (match_code "xor,and,ior")
419
{
420
  enum rtx_code code = GET_CODE (op);
421
 
422
  return (code == XOR
423
          || code == AND
424
          || code == IOR);
425
})
426
 
427
;; Return nonzero if OP is a shift operator.
428
 
429
(define_predicate "nshift_operator"
430
  (match_code "ashiftrt,lshiftrt,ashift")
431
{
432
  switch (GET_CODE (op))
433
    {
434
    case ASHIFTRT:
435
    case LSHIFTRT:
436
    case ASHIFT:
437
      return 1;
438
 
439
    default:
440
      return 0;
441
    }
442
})
443
 
444
;; Return nonzero if X is either EQ or NE.
445
 
446
(define_predicate "eqne_operator"
447
  (match_code "eq,ne")
448
{
449
  enum rtx_code code = GET_CODE (op);
450
 
451
  return (code == EQ || code == NE);
452
})
453
 
454
;; Return nonzero if X is either GT or LE.
455
 
456
(define_predicate "gtle_operator"
457
  (match_code "gt,le,gtu,leu")
458
{
459
  enum rtx_code code = GET_CODE (op);
460
 
461
  return (code == GT || code == LE);
462
})
463
 
464
;; Return nonzero if X is either GTU or LEU.
465
 
466
(define_predicate "gtuleu_operator"
467
  (match_code "gtu,leu")
468
{
469
  enum rtx_code code = GET_CODE (op);
470
 
471
  return (code == GTU || code == LEU);
472
})
473
 
474
;; Return nonzero if X is either IOR or XOR.
475
 
476
(define_predicate "iorxor_operator"
477
  (match_code "ior,xor")
478
{
479
  enum rtx_code code = GET_CODE (op);
480
 
481
  return (code == IOR || code == XOR);
482
})

powered by: WebSVN 2.1.0

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