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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [config/] [sh/] [predicates.md] - Blame information for rev 709

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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