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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gcc-4.2.2/] [gcc/] [config/] [sh/] [predicates.md] - Blame information for rev 858

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

Line No. Rev Author Line
1 38 julius
;; Predicate definitions for Renesas / SuperH SH.
2
;; Copyright (C) 2005, 2006, 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
;; TODO: Add a comment here.
21
 
22
(define_predicate "trapping_target_operand"
23
  (match_code "if_then_else")
24
{
25
  rtx cond, mem, res, tar, and;
26
 
27
  if (GET_MODE (op) != PDImode)
28
    return 0;
29
  cond = XEXP (op, 0);
30
  mem = XEXP (op, 1);
31
  res = XEXP (op, 2);
32
  if (GET_CODE (mem) != MEM
33
      || (GET_CODE (res) != SIGN_EXTEND && GET_CODE (res) != TRUNCATE))
34
    return 0;
35
  tar = XEXP (res, 0);
36
  if (!rtx_equal_p (XEXP (mem, 0), tar)
37
      || GET_MODE (tar) != Pmode)
38
    return 0;
39
  if (GET_CODE (cond) == CONST)
40
    {
41
      cond = XEXP (cond, 0);
42
      if (!EXTRA_CONSTRAINT_Csy (tar))
43
        return 0;
44
      if (GET_CODE (tar) == CONST)
45
        tar = XEXP (tar, 0);
46
    }
47
  else if (!arith_reg_operand (tar, VOIDmode)
48
           && ! EXTRA_CONSTRAINT_Csy (tar))
49
    return 0;
50
  if (GET_CODE (cond) != EQ)
51
    return 0;
52
  and = XEXP (cond, 0);
53
  return (GET_CODE (and) == AND
54
          && rtx_equal_p (XEXP (and, 0), tar)
55
          && GET_CODE (XEXP (and, 1)) == CONST_INT
56
          && GET_CODE (XEXP (cond, 1)) == CONST_INT
57
          && INTVAL (XEXP (and, 1)) == 3
58
          && INTVAL (XEXP (cond, 1)) == 3);
59
})
60
 
61
;; TODO: Add a comment here.
62
 
63
(define_predicate "and_operand"
64
  (match_code "subreg,reg,const_int")
65
{
66
  if (logical_operand (op, mode))
67
    return 1;
68
 
69
  /* Check mshflo.l / mshflhi.l opportunities.  */
70
  if (TARGET_SHMEDIA
71
      && mode == DImode
72
      && GET_CODE (op) == CONST_INT
73
      && CONST_OK_FOR_J16 (INTVAL (op)))
74
    return 1;
75
 
76
  return 0;
77
})
78
 
79
;; Like arith_reg_dest, but this predicate is defined with
80
;; define_special_predicate, not define_predicate.
81
 
82
(define_special_predicate "any_arith_reg_dest"
83
  (match_code "subreg,reg")
84
{
85
  return arith_reg_dest (op, mode);
86
})
87
 
88
;; Like register_operand, but this predicate is defined with
89
;; define_special_predicate, not define_predicate.
90
 
91
(define_special_predicate "any_register_operand"
92
  (match_code "subreg,reg")
93
{
94
  return register_operand (op, mode);
95
})
96
 
97
;; Returns 1 if OP is a valid source operand for an arithmetic insn.
98
 
99
(define_predicate "arith_operand"
100
  (match_code "subreg,reg,const_int,truncate")
101
{
102
  if (arith_reg_operand (op, mode))
103
    return 1;
104
 
105
  if (TARGET_SHMEDIA)
106
    {
107
      /* FIXME: We should be checking whether the CONST_INT fits in a
108
         CONST_OK_FOR_I16 here, but this causes reload_cse to crash when
109
         attempting to transform a sequence of two 64-bit sets of the
110
         same register from literal constants into a set and an add,
111
         when the difference is too wide for an add.  */
112
      if (GET_CODE (op) == CONST_INT
113
          || EXTRA_CONSTRAINT_Css (op))
114
        return 1;
115
      else if (GET_CODE (op) == TRUNCATE
116
               && ! system_reg_operand (XEXP (op, 0), VOIDmode)
117
               && (mode == VOIDmode || mode == GET_MODE (op))
118
               && (GET_MODE_SIZE (GET_MODE (op))
119
                   < GET_MODE_SIZE (GET_MODE (XEXP (op, 0))))
120
               && (! FP_REGISTER_P (REGNO (XEXP (op, 0)))
121
                   || GET_MODE_SIZE (GET_MODE (op)) == 4))
122
        return register_operand (XEXP (op, 0), VOIDmode);
123
      else
124
        return 0;
125
    }
126
  else if (GET_CODE (op) == CONST_INT && CONST_OK_FOR_I08 (INTVAL (op)))
127
    return 1;
128
 
129
  return 0;
130
})
131
 
132
;; Like above, but for DImode destinations: forbid paradoxical DImode
133
;; subregs, because this would lead to missing sign extensions when
134
;; truncating from DImode to SImode.
135
 
136
(define_predicate "arith_reg_dest"
137
  (match_code "subreg,reg")
138
{
139
  if (mode == DImode && GET_CODE (op) == SUBREG
140
      && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) < 8
141
      && TARGET_SHMEDIA)
142
    return 0;
143
  return arith_reg_operand (op, mode);
144
})
145
 
146
;; Returns 1 if OP is a normal arithmetic register.
147
 
148
(define_predicate "arith_reg_operand"
149
  (match_code "subreg,reg,sign_extend")
150
{
151
  if (register_operand (op, mode))
152
    {
153
      int regno;
154
 
155
      if (GET_CODE (op) == REG)
156
        regno = REGNO (op);
157
      else if (GET_CODE (op) == SUBREG && GET_CODE (SUBREG_REG (op)) == REG)
158
        regno = REGNO (SUBREG_REG (op));
159
      else
160
        return 1;
161
 
162
      return (regno != T_REG && regno != PR_REG
163
              && ! TARGET_REGISTER_P (regno)
164
              && (regno != FPUL_REG || TARGET_SH4)
165
              && regno != MACH_REG && regno != MACL_REG);
166
    }
167
  /* Allow a no-op sign extension - compare LOAD_EXTEND_OP.
168
     We allow SImode here, as not using an FP register is just a matter of
169
     proper register allocation.  */
170
  if (TARGET_SHMEDIA
171
      && GET_MODE (op) == DImode && GET_CODE (op) == SIGN_EXTEND
172
      && GET_MODE (XEXP (op, 0)) == SImode
173
      && GET_CODE (XEXP (op, 0)) != SUBREG)
174
    return register_operand (XEXP (op, 0), VOIDmode);
175
#if 0 /* Can't do this because of PROMOTE_MODE for unsigned vars.  */
176
  if (GET_MODE (op) == SImode && GET_CODE (op) == SIGN_EXTEND
177
      && GET_MODE (XEXP (op, 0)) == HImode
178
      && GET_CODE (XEXP (op, 0)) == REG
179
      && REGNO (XEXP (op, 0)) <= LAST_GENERAL_REG)
180
    return register_operand (XEXP (op, 0), VOIDmode);
181
#endif
182
  if (GET_MODE_CLASS (GET_MODE (op)) == MODE_VECTOR_INT
183
      && GET_CODE (op) == SUBREG
184
      && GET_MODE (SUBREG_REG (op)) == DImode
185
      && GET_CODE (SUBREG_REG (op)) == SIGN_EXTEND
186
      && GET_MODE (XEXP (SUBREG_REG (op), 0)) == SImode
187
      && GET_CODE (XEXP (SUBREG_REG (op), 0)) != SUBREG)
188
    return register_operand (XEXP (SUBREG_REG (op), 0), VOIDmode);
189
  return 0;
190
})
191
 
192
;; Returns 1 if OP is a valid source operand for a compare insn.
193
 
194
(define_predicate "arith_reg_or_0_operand"
195
  (match_code "subreg,reg,const_int,const_vector")
196
{
197
  if (arith_reg_operand (op, mode))
198
    return 1;
199
 
200
  if (EXTRA_CONSTRAINT_Z (op))
201
    return 1;
202
 
203
  return 0;
204
})
205
 
206
;; TODO: Add a comment here.
207
 
208
(define_predicate "binary_float_operator"
209
  (and (match_code "plus,minus,mult,div")
210
       (match_test "GET_MODE (op) == mode")))
211
 
212
;; TODO: Add a comment here.
213
 
214
(define_predicate "binary_logical_operator"
215
  (and (match_code "and,ior,xor")
216
       (match_test "GET_MODE (op) == mode")))
217
 
218
;; Return 1 of OP is an address suitable for a cache manipulation operation.
219
;; MODE has the meaning as in address_operand.
220
 
221
(define_special_predicate "cache_address_operand"
222
  (match_code "plus,reg")
223
{
224
  if (GET_CODE (op) == PLUS)
225
    {
226
      if (GET_CODE (XEXP (op, 0)) != REG)
227
        return 0;
228
      if (GET_CODE (XEXP (op, 1)) != CONST_INT
229
          || (INTVAL (XEXP (op, 1)) & 31))
230
        return 0;
231
    }
232
  else if (GET_CODE (op) != REG)
233
    return 0;
234
  return address_operand (op, mode);
235
})
236
 
237
;; Return 1 if OP is a valid source operand for shmedia cmpgt / cmpgtu.
238
 
239
(define_predicate "cmp_operand"
240
  (match_code "subreg,reg,const_int")
241
{
242
  if (GET_CODE (op) == CONST_INT && CONST_OK_FOR_N (INTVAL (op)))
243
    return 1;
244
  if (TARGET_SHMEDIA
245
      && mode != DImode && GET_CODE (op) == SUBREG
246
      && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) > 4)
247
    return 0;
248
  return arith_reg_operand (op, mode);
249
})
250
 
251
;; TODO: Add a comment here.
252
 
253
(define_predicate "cmpsi_operand"
254
  (match_code "subreg,reg,const_int")
255
{
256
  if (GET_CODE (op) == REG && REGNO (op) == T_REG
257
      && GET_MODE (op) == SImode
258
      && TARGET_SH1)
259
    return 1;
260
  return arith_operand (op, mode);
261
})
262
 
263
;; TODO: Add a comment here.
264
 
265
(define_predicate "commutative_float_operator"
266
  (and (match_code "plus,mult")
267
       (match_test "GET_MODE (op) == mode")))
268
 
269
;; TODO: Add a comment here.
270
 
271
(define_predicate "equality_comparison_operator"
272
  (match_code "eq,ne"))
273
 
274
;; TODO: Add a comment here.
275
 
276
(define_predicate "extend_reg_operand"
277
  (match_code "subreg,reg,truncate")
278
{
279
  return (GET_CODE (op) == TRUNCATE
280
          ? arith_operand
281
          : arith_reg_operand) (op, mode);
282
})
283
 
284
;; TODO: Add a comment here.
285
 
286
(define_predicate "extend_reg_or_0_operand"
287
  (match_code "subreg,reg,truncate,const_int")
288
{
289
  return (GET_CODE (op) == TRUNCATE
290
          ? arith_operand
291
          : arith_reg_or_0_operand) (op, mode);
292
})
293
 
294
;; Like arith_reg_operand, but this predicate does not accept SIGN_EXTEND.
295
 
296
(define_predicate "ext_dest_operand"
297
  (match_code "subreg,reg")
298
{
299
  return arith_reg_operand (op, mode);
300
})
301
 
302
;; TODO: Add a comment here.
303
 
304
(define_predicate "fp_arith_reg_dest"
305
  (match_code "subreg,reg")
306
{
307
  if (mode == DImode && GET_CODE (op) == SUBREG
308
      && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) < 8)
309
    return 0;
310
  return fp_arith_reg_operand (op, mode);
311
})
312
 
313
;; TODO: Add a comment here.
314
 
315
(define_predicate "fp_arith_reg_operand"
316
  (match_code "subreg,reg")
317
{
318
  if (register_operand (op, mode))
319
    {
320
      int regno;
321
 
322
      if (GET_CODE (op) == REG)
323
        regno = REGNO (op);
324
      else if (GET_CODE (op) == SUBREG && GET_CODE (SUBREG_REG (op)) == REG)
325
        regno = REGNO (SUBREG_REG (op));
326
      else
327
        return 1;
328
 
329
      return (regno >= FIRST_PSEUDO_REGISTER
330
              || FP_REGISTER_P (regno));
331
    }
332
  return 0;
333
})
334
 
335
;; TODO: Add a comment here.
336
 
337
(define_predicate "fpscr_operand"
338
  (match_code "reg")
339
{
340
  return (GET_CODE (op) == REG
341
          && (REGNO (op) == FPSCR_REG
342
              || (REGNO (op) >= FIRST_PSEUDO_REGISTER
343
                  && !(reload_in_progress || reload_completed)))
344
          && GET_MODE (op) == PSImode);
345
})
346
 
347
;; TODO: Add a comment here.
348
 
349
(define_predicate "fpul_operand"
350
  (match_code "reg")
351
{
352
  if (TARGET_SHMEDIA)
353
    return fp_arith_reg_operand (op, mode);
354
 
355
  return (GET_CODE (op) == REG
356
          && (REGNO (op) == FPUL_REG || REGNO (op) >= FIRST_PSEUDO_REGISTER)
357
          && GET_MODE (op) == mode);
358
})
359
 
360
;; TODO: Add a comment here.
361
 
362
(define_predicate "general_extend_operand"
363
  (match_code "subreg,reg,mem,truncate")
364
{
365
  return (GET_CODE (op) == TRUNCATE
366
          ? arith_operand
367
          : nonimmediate_operand) (op, mode);
368
})
369
 
370
;; Returns 1 if OP can be source of a simple move operation. Same as
371
;; general_operand, but a LABEL_REF is valid, PRE_DEC is invalid as
372
;; are subregs of system registers.
373
 
374
(define_predicate "general_movsrc_operand"
375
  (match_code "subreg,reg,const_int,const_double,mem,symbol_ref,label_ref,const,const_vector")
376
{
377
  if (GET_CODE (op) == MEM)
378
    {
379
      rtx inside = XEXP (op, 0);
380
      if (GET_CODE (inside) == CONST)
381
        inside = XEXP (inside, 0);
382
 
383
      if (GET_CODE (inside) == LABEL_REF)
384
        return 1;
385
 
386
      if (GET_CODE (inside) == PLUS
387
          && GET_CODE (XEXP (inside, 0)) == LABEL_REF
388
          && GET_CODE (XEXP (inside, 1)) == CONST_INT)
389
        return 1;
390
 
391
      /* Only post inc allowed.  */
392
      if (GET_CODE (inside) == PRE_DEC)
393
        return 0;
394
    }
395
 
396
  if ((mode == QImode || mode == HImode)
397
      && (GET_CODE (op) == SUBREG
398
          && GET_CODE (XEXP (op, 0)) == REG
399
          && system_reg_operand (XEXP (op, 0), mode)))
400
    return 0;
401
 
402
  if (TARGET_SHMEDIA
403
      && (GET_CODE (op) == PARALLEL || GET_CODE (op) == CONST_VECTOR)
404
      && sh_rep_vec (op, mode))
405
    return 1;
406
  if (TARGET_SHMEDIA && 1
407
      && GET_CODE (op) == SUBREG && GET_MODE (op) == mode
408
      && SUBREG_REG (op) == const0_rtx && subreg_lowpart_p (op))
409
    /* FIXME */ abort (); /* return 1; */
410
  return general_operand (op, mode);
411
})
412
 
413
;; Returns 1 if OP can be a destination of a move. Same as
414
;; general_operand, but no preinc allowed.
415
 
416
(define_predicate "general_movdst_operand"
417
  (match_code "subreg,reg,mem")
418
{
419
  /* Only pre dec allowed.  */
420
  if (GET_CODE (op) == MEM && GET_CODE (XEXP (op, 0)) == POST_INC)
421
    return 0;
422
  if (mode == DImode && TARGET_SHMEDIA && GET_CODE (op) == SUBREG
423
      && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) < 8
424
      && ! (high_life_started || reload_completed))
425
    return 0;
426
 
427
  return general_operand (op, mode);
428
})
429
 
430
;; Returns 1 if OP is a MEM that can be source of a simple move operation.
431
 
432
(define_predicate "unaligned_load_operand"
433
  (match_code "mem")
434
{
435
  rtx inside;
436
 
437
  if (GET_CODE (op) != MEM || GET_MODE (op) != mode)
438
    return 0;
439
 
440
  inside = XEXP (op, 0);
441
 
442
  if (GET_CODE (inside) == POST_INC)
443
    inside = XEXP (inside, 0);
444
 
445
  if (GET_CODE (inside) == REG)
446
    return 1;
447
 
448
  return 0;
449
})
450
 
451
;; TODO: Add a comment here.
452
 
453
(define_predicate "greater_comparison_operator"
454
  (match_code "gt,ge,gtu,geu"))
455
 
456
;; TODO: Add a comment here.
457
 
458
(define_predicate "inqhi_operand"
459
  (match_code "truncate")
460
{
461
  if (GET_CODE (op) != TRUNCATE || mode != GET_MODE (op))
462
    return 0;
463
  op = XEXP (op, 0);
464
  /* Can't use true_regnum here because copy_cost wants to know about
465
     SECONDARY_INPUT_RELOAD_CLASS.  */
466
  return GET_CODE (op) == REG && FP_REGISTER_P (REGNO (op));
467
})
468
 
469
;; TODO: Add a comment here.
470
 
471
(define_special_predicate "int_gpr_dest"
472
  (match_code "subreg,reg")
473
{
474
  enum machine_mode op_mode = GET_MODE (op);
475
 
476
  if (GET_MODE_CLASS (op_mode) != MODE_INT
477
      || GET_MODE_SIZE (op_mode) >= UNITS_PER_WORD)
478
    return 0;
479
  if (! reload_completed)
480
    return 0;
481
  return true_regnum (op) <= LAST_GENERAL_REG;
482
})
483
 
484
;; TODO: Add a comment here.
485
 
486
(define_predicate "less_comparison_operator"
487
  (match_code "lt,le,ltu,leu"))
488
 
489
;; Returns 1 if OP is a valid source operand for a logical operation.
490
 
491
(define_predicate "logical_operand"
492
  (match_code "subreg,reg,const_int")
493
{
494
  if (TARGET_SHMEDIA
495
      && mode != DImode && GET_CODE (op) == SUBREG
496
      && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) > 4)
497
    return 0;
498
 
499
  if (arith_reg_operand (op, mode))
500
    return 1;
501
 
502
  if (TARGET_SHMEDIA)
503
    {
504
      if (GET_CODE (op) == CONST_INT && CONST_OK_FOR_I10 (INTVAL (op)))
505
        return 1;
506
      else
507
        return 0;
508
    }
509
  else if (GET_CODE (op) == CONST_INT && CONST_OK_FOR_K08 (INTVAL (op)))
510
    return 1;
511
 
512
  return 0;
513
})
514
 
515
;; TODO: Add a comment here.
516
 
517
(define_predicate "logical_operator"
518
  (match_code "and,ior,xor"))
519
 
520
;; Like arith_reg_operand, but for register source operands of narrow
521
;; logical SHMEDIA operations: forbid subregs of DImode / TImode regs.
522
 
523
(define_predicate "logical_reg_operand"
524
  (match_code "subreg,reg")
525
{
526
  if (TARGET_SHMEDIA
527
      && GET_CODE (op) == SUBREG
528
      && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) > 4
529
      && mode != DImode)
530
    return 0;
531
  return arith_reg_operand (op, mode);
532
})
533
 
534
;; TODO: Add a comment here.
535
 
536
(define_predicate "mextr_bit_offset"
537
  (match_code "const_int")
538
{
539
  HOST_WIDE_INT i;
540
 
541
  if (GET_CODE (op) != CONST_INT)
542
    return 0;
543
  i = INTVAL (op);
544
  return i >= 1 * 8 && i <= 7 * 8 && (i & 7) == 0;
545
})
546
 
547
;; TODO: Add a comment here.
548
 
549
(define_predicate "minuend_operand"
550
  (match_code "subreg,reg,truncate,const_int")
551
{
552
  return op == constm1_rtx || extend_reg_or_0_operand (op, mode);
553
})
554
 
555
;; TODO: Add a comment here.
556
 
557
(define_predicate "noncommutative_float_operator"
558
  (and (match_code "minus,div")
559
       (match_test "GET_MODE (op) == mode")))
560
 
561
;; TODO: Add a comment here.
562
 
563
(define_predicate "sh_const_vec"
564
  (match_code "const_vector")
565
{
566
  int i;
567
 
568
  if (GET_CODE (op) != CONST_VECTOR
569
      || (GET_MODE (op) != mode && mode != VOIDmode))
570
    return 0;
571
  i = XVECLEN (op, 0) - 1;
572
  for (; i >= 0; i--)
573
    if (GET_CODE (XVECEXP (op, 0, i)) != CONST_INT)
574
      return 0;
575
  return 1;
576
})
577
 
578
;; Determine if OP is a constant vector matching MODE with only one
579
;; element that is not a sign extension.  Two byte-sized elements
580
;; count as one.
581
 
582
(define_predicate "sh_1el_vec"
583
  (match_code "const_vector")
584
{
585
  int unit_size;
586
  int i, last, least, sign_ix;
587
  rtx sign;
588
 
589
  if (GET_CODE (op) != CONST_VECTOR
590
      || (GET_MODE (op) != mode && mode != VOIDmode))
591
    return 0;
592
  /* Determine numbers of last and of least significant elements.  */
593
  last = XVECLEN (op, 0) - 1;
594
  least = TARGET_LITTLE_ENDIAN ? 0 : last;
595
  if (GET_CODE (XVECEXP (op, 0, least)) != CONST_INT)
596
    return 0;
597
  sign_ix = least;
598
  if (GET_MODE_UNIT_SIZE (mode) == 1)
599
    sign_ix = TARGET_LITTLE_ENDIAN ? 1 : last - 1;
600
  if (GET_CODE (XVECEXP (op, 0, sign_ix)) != CONST_INT)
601
    return 0;
602
  unit_size = GET_MODE_UNIT_SIZE (GET_MODE (op));
603
  sign = (INTVAL (XVECEXP (op, 0, sign_ix)) >> (unit_size * BITS_PER_UNIT - 1)
604
          ? constm1_rtx : const0_rtx);
605
  i = XVECLEN (op, 0) - 1;
606
  do
607
    if (i != least && i != sign_ix && XVECEXP (op, 0, i) != sign)
608
      return 0;
609
  while (--i);
610
  return 1;
611
})
612
 
613
;; Like register_operand, but take into account that SHMEDIA can use
614
;; the constant zero like a general register.
615
 
616
(define_predicate "sh_register_operand"
617
  (match_code "reg,subreg,const_int,const_double")
618
{
619
  if (op == CONST0_RTX (mode) && TARGET_SHMEDIA)
620
    return 1;
621
  return register_operand (op, mode);
622
})
623
 
624
;; TODO: Add a comment here.
625
 
626
(define_predicate "sh_rep_vec"
627
  (match_code "const_vector,parallel")
628
{
629
  int i;
630
  rtx x, y;
631
 
632
  if ((GET_CODE (op) != CONST_VECTOR && GET_CODE (op) != PARALLEL)
633
      || (GET_MODE (op) != mode && mode != VOIDmode))
634
    return 0;
635
  i = XVECLEN (op, 0) - 2;
636
  x = XVECEXP (op, 0, i + 1);
637
  if (GET_MODE_UNIT_SIZE (mode) == 1)
638
    {
639
      y = XVECEXP (op, 0, i);
640
      for (i -= 2; i >= 0; i -= 2)
641
        if (! rtx_equal_p (XVECEXP (op, 0, i + 1), x)
642
            || ! rtx_equal_p (XVECEXP (op, 0, i), y))
643
          return 0;
644
    }
645
  else
646
    for (; i >= 0; i--)
647
      if (XVECEXP (op, 0, i) != x)
648
        return 0;
649
  return 1;
650
})
651
 
652
;; TODO: Add a comment here.
653
 
654
(define_predicate "shift_count_operand"
655
  (match_code "const_int,const_double,const,symbol_ref,label_ref,subreg,reg,zero_extend,sign_extend")
656
{
657
  return (CONSTANT_P (op)
658
          ? (GET_CODE (op) == CONST_INT
659
             ? (unsigned) INTVAL (op) < GET_MODE_BITSIZE (mode)
660
             : nonmemory_operand (op, mode))
661
          : shift_count_reg_operand (op, mode));
662
})
663
 
664
;; TODO: Add a comment here.
665
 
666
(define_predicate "shift_count_reg_operand"
667
  (match_code "subreg,reg,zero_extend,sign_extend")
668
{
669
  if ((GET_CODE (op) == ZERO_EXTEND || GET_CODE (op) == SIGN_EXTEND
670
       || (GET_CODE (op) == SUBREG && SUBREG_BYTE (op) == 0))
671
      && (mode == VOIDmode || mode == GET_MODE (op))
672
      && GET_MODE_BITSIZE (GET_MODE (XEXP (op, 0))) >= 6
673
      && GET_MODE_CLASS (GET_MODE (XEXP (op, 0))) == MODE_INT)
674
    {
675
      mode = VOIDmode;
676
      do
677
        op = XEXP (op, 0);
678
      while ((GET_CODE (op) == ZERO_EXTEND || GET_CODE (op) == SIGN_EXTEND
679
              || GET_CODE (op) == TRUNCATE)
680
             && GET_MODE_BITSIZE (GET_MODE (XEXP (op, 0))) >= 6
681
             && GET_MODE_CLASS (GET_MODE (XEXP (op, 0))) == MODE_INT);
682
 
683
    }
684
  return arith_reg_operand (op, mode);
685
})
686
 
687
;; TODO: Add a comment here.
688
 
689
(define_predicate "shift_operator"
690
  (match_code "ashift,ashiftrt,lshiftrt"))
691
 
692
;; TODO: Add a comment here.
693
 
694
(define_predicate "symbol_ref_operand"
695
  (match_code "symbol_ref"))
696
 
697
;; Same as target_reg_operand, except that label_refs and symbol_refs
698
;; are accepted before reload.
699
 
700
(define_special_predicate "target_operand"
701
  (match_code "subreg,reg,label_ref,symbol_ref,const,unspec")
702
{
703
  if (mode != VOIDmode && mode != Pmode)
704
    return 0;
705
 
706
  if ((GET_MODE (op) == Pmode || GET_MODE (op) == VOIDmode)
707
      && EXTRA_CONSTRAINT_Csy (op))
708
    return ! reload_completed;
709
 
710
  return target_reg_operand (op, mode);
711
})
712
 
713
;; Accept pseudos and branch target registers.
714
 
715
(define_special_predicate "target_reg_operand"
716
  (match_code "subreg,reg")
717
{
718
  if (mode == VOIDmode
719
     ? GET_MODE (op) != Pmode && GET_MODE (op) != PDImode
720
     : mode != GET_MODE (op))
721
    return 0;
722
 
723
  if (GET_CODE (op) == SUBREG)
724
    op = XEXP (op, 0);
725
 
726
  if (GET_CODE (op) != REG)
727
    return 0;
728
 
729
  /* We must protect ourselves from matching pseudos that are virtual
730
     register, because they will eventually be replaced with hardware
731
     registers that aren't branch-target registers.  */
732
  if (REGNO (op) > LAST_VIRTUAL_REGISTER
733
      || TARGET_REGISTER_P (REGNO (op)))
734
    return 1;
735
 
736
  return 0;
737
})
738
 
739
;; TODO: Add a comment here.
740
 
741
(define_special_predicate "trunc_hi_operand"
742
  (match_code "subreg,reg,truncate")
743
{
744
  enum machine_mode op_mode = GET_MODE (op);
745
 
746
  if (op_mode != SImode && op_mode != DImode
747
      && op_mode != V4HImode && op_mode != V2SImode)
748
    return 0;
749
  return extend_reg_operand (op, mode);
750
})
751
 
752
;; Return 1 of OP is an address suitable for an unaligned access instruction.
753
 
754
(define_special_predicate "ua_address_operand"
755
  (match_code "subreg,reg,plus")
756
{
757
  if (GET_CODE (op) == PLUS
758
      && (GET_CODE (XEXP (op, 1)) != CONST_INT
759
          || ! CONST_OK_FOR_I06 (INTVAL (XEXP (op, 1)))))
760
    return 0;
761
  return address_operand (op, QImode);
762
})
763
 
764
;; TODO: Add a comment here.
765
 
766
(define_predicate "ua_offset"
767
  (match_code "const_int")
768
{
769
  return GET_CODE (op) == CONST_INT && CONST_OK_FOR_I06 (INTVAL (op));
770
})
771
 
772
;; TODO: Add a comment here.
773
 
774
(define_predicate "unary_float_operator"
775
  (and (match_code "abs,neg,sqrt")
776
       (match_test "GET_MODE (op) == mode")))
777
 
778
;; Return 1 if OP is a valid source operand for xor.
779
 
780
(define_predicate "xor_operand"
781
  (match_code "subreg,reg,const_int")
782
{
783
  if (GET_CODE (op) == CONST_INT)
784
    return (TARGET_SHMEDIA
785
            ? (CONST_OK_FOR_I06 (INTVAL (op))
786
               || (no_new_pseudos && INTVAL (op) == 0xff))
787
            : CONST_OK_FOR_K08 (INTVAL (op)));
788
  if (TARGET_SHMEDIA
789
      && mode != DImode && GET_CODE (op) == SUBREG
790
      && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) > 4)
791
    return 0;
792
  return arith_reg_operand (op, mode);
793
})

powered by: WebSVN 2.1.0

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