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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gcc-4.2.2/] [gcc/] [config/] [arm/] [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 ARM and Thumb
2
;; Copyright (C) 2004, 2007 Free Software Foundation, Inc.
3
;; Contributed by ARM Ltd.
4
 
5
;; This file is part of GCC.
6
 
7
;; GCC is free software; you can redistribute it and/or modify it
8
;; under the terms of the GNU General Public License as published
9
;; by the Free Software Foundation; either version 3, or (at your
10
;; option) any later version.
11
 
12
;; GCC is distributed in the hope that it will be useful, but WITHOUT
13
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14
;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15
;; 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
(define_predicate "s_register_operand"
22
  (match_code "reg,subreg")
23
{
24
  if (GET_CODE (op) == SUBREG)
25
    op = SUBREG_REG (op);
26
  /* We don't consider registers whose class is NO_REGS
27
     to be a register operand.  */
28
  /* XXX might have to check for lo regs only for thumb ??? */
29
  return (GET_CODE (op) == REG
30
          && (REGNO (op) >= FIRST_PSEUDO_REGISTER
31
              || REGNO_REG_CLASS (REGNO (op)) != NO_REGS));
32
})
33
 
34
;; Any hard register.
35
(define_predicate "arm_hard_register_operand"
36
  (match_code "reg")
37
{
38
  return REGNO (op) < FIRST_PSEUDO_REGISTER;
39
})
40
 
41
;; Any core register, or any pseudo.  */
42
(define_predicate "arm_general_register_operand"
43
  (match_code "reg,subreg")
44
{
45
  if (GET_CODE (op) == SUBREG)
46
    op = SUBREG_REG (op);
47
 
48
  return (GET_CODE (op) == REG
49
          && (REGNO (op) <= LAST_ARM_REGNUM
50
              || REGNO (op) >= FIRST_PSEUDO_REGISTER));
51
})
52
 
53
(define_predicate "f_register_operand"
54
  (match_code "reg,subreg")
55
{
56
  if (GET_CODE (op) == SUBREG)
57
    op = SUBREG_REG (op);
58
 
59
  /* We don't consider registers whose class is NO_REGS
60
     to be a register operand.  */
61
  return (GET_CODE (op) == REG
62
          && (REGNO (op) >= FIRST_PSEUDO_REGISTER
63
              || REGNO_REG_CLASS (REGNO (op)) == FPA_REGS));
64
})
65
 
66
;; Reg, subreg(reg) or const_int.
67
(define_predicate "reg_or_int_operand"
68
  (ior (match_code "const_int")
69
       (match_operand 0 "s_register_operand")))
70
 
71
(define_predicate "arm_immediate_operand"
72
  (and (match_code "const_int")
73
       (match_test "const_ok_for_arm (INTVAL (op))")))
74
 
75
(define_predicate "arm_neg_immediate_operand"
76
  (and (match_code "const_int")
77
       (match_test "const_ok_for_arm (-INTVAL (op))")))
78
 
79
(define_predicate "arm_not_immediate_operand"
80
  (and (match_code "const_int")
81
       (match_test "const_ok_for_arm (~INTVAL (op))")))
82
 
83
;; Something valid on the RHS of an ARM data-processing instruction
84
(define_predicate "arm_rhs_operand"
85
  (ior (match_operand 0 "s_register_operand")
86
       (match_operand 0 "arm_immediate_operand")))
87
 
88
(define_predicate "arm_rhsm_operand"
89
  (ior (match_operand 0 "arm_rhs_operand")
90
       (match_operand 0 "memory_operand")))
91
 
92
(define_predicate "arm_add_operand"
93
  (ior (match_operand 0 "arm_rhs_operand")
94
       (match_operand 0 "arm_neg_immediate_operand")))
95
 
96
(define_predicate "arm_addimm_operand"
97
  (ior (match_operand 0 "arm_immediate_operand")
98
       (match_operand 0 "arm_neg_immediate_operand")))
99
 
100
(define_predicate "arm_not_operand"
101
  (ior (match_operand 0 "arm_rhs_operand")
102
       (match_operand 0 "arm_not_immediate_operand")))
103
 
104
;; True if the operand is a memory reference which contains an
105
;; offsettable address.
106
(define_predicate "offsettable_memory_operand"
107
  (and (match_code "mem")
108
       (match_test
109
        "offsettable_address_p (reload_completed | reload_in_progress,
110
                                mode, XEXP (op, 0))")))
111
 
112
;; True if the operand is a memory operand that does not have an
113
;; automodified base register (and thus will not generate output reloads).
114
(define_predicate "call_memory_operand"
115
  (and (match_code "mem")
116
       (and (match_test "GET_RTX_CLASS (GET_CODE (XEXP (op, 0)))
117
                         != RTX_AUTOINC")
118
            (match_operand 0 "memory_operand"))))
119
 
120
(define_predicate "arm_reload_memory_operand"
121
  (and (match_code "mem,reg,subreg")
122
       (match_test "(!CONSTANT_P (op)
123
                     && (true_regnum(op) == -1
124
                         || (GET_CODE (op) == REG
125
                             && REGNO (op) >= FIRST_PSEUDO_REGISTER)))")))
126
 
127
;; True for valid operands for the rhs of an floating point insns.
128
;;   Allows regs or certain consts on FPA, just regs for everything else.
129
(define_predicate "arm_float_rhs_operand"
130
  (ior (match_operand 0 "s_register_operand")
131
       (and (match_code "const_double")
132
            (match_test "TARGET_FPA && arm_const_double_rtx (op)"))))
133
 
134
(define_predicate "arm_float_add_operand"
135
  (ior (match_operand 0 "arm_float_rhs_operand")
136
       (and (match_code "const_double")
137
            (match_test "TARGET_FPA && neg_const_double_rtx_ok_for_fpa (op)"))))
138
 
139
(define_predicate "vfp_compare_operand"
140
  (ior (match_operand 0 "s_register_operand")
141
       (and (match_code "const_double")
142
            (match_test "arm_const_double_rtx (op)"))))
143
 
144
(define_predicate "arm_float_compare_operand"
145
  (if_then_else (match_test "TARGET_VFP")
146
                (match_operand 0 "vfp_compare_operand")
147
                (match_operand 0 "arm_float_rhs_operand")))
148
 
149
;; True for valid index operands.
150
(define_predicate "index_operand"
151
  (ior (match_operand 0 "s_register_operand")
152
       (and (match_operand 0 "immediate_operand")
153
            (match_test "(GET_CODE (op) != CONST_INT
154
                          || (INTVAL (op) < 4096 && INTVAL (op) > -4096))"))))
155
 
156
;; True for operators that can be combined with a shift in ARM state.
157
(define_special_predicate "shiftable_operator"
158
  (and (match_code "plus,minus,ior,xor,and")
159
       (match_test "mode == GET_MODE (op)")))
160
 
161
;; True for logical binary operators.
162
(define_special_predicate "logical_binary_operator"
163
  (and (match_code "ior,xor,and")
164
       (match_test "mode == GET_MODE (op)")))
165
 
166
;; True for shift operators.
167
(define_special_predicate "shift_operator"
168
  (and (ior (ior (and (match_code "mult")
169
                      (match_test "power_of_two_operand (XEXP (op, 1), mode)"))
170
                 (and (match_code "rotate")
171
                      (match_test "GET_CODE (XEXP (op, 1)) == CONST_INT
172
                                   && ((unsigned HOST_WIDE_INT) INTVAL (XEXP (op, 1))) < 32")))
173
            (match_code "ashift,ashiftrt,lshiftrt,rotatert"))
174
       (match_test "mode == GET_MODE (op)")))
175
 
176
;; True for EQ & NE
177
(define_special_predicate "equality_operator"
178
  (match_code "eq,ne"))
179
 
180
;; True for comparisons other than LTGT or UNEQ.
181
(define_special_predicate "arm_comparison_operator"
182
  (match_code "eq,ne,le,lt,ge,gt,geu,gtu,leu,ltu,unordered,ordered,unlt,unle,unge,ungt"))
183
 
184
(define_special_predicate "minmax_operator"
185
  (and (match_code "smin,smax,umin,umax")
186
       (match_test "mode == GET_MODE (op)")))
187
 
188
(define_special_predicate "cc_register"
189
  (and (match_code "reg")
190
       (and (match_test "REGNO (op) == CC_REGNUM")
191
            (ior (match_test "mode == GET_MODE (op)")
192
                 (match_test "mode == VOIDmode && GET_MODE_CLASS (GET_MODE (op)) == MODE_CC")))))
193
 
194
(define_special_predicate "dominant_cc_register"
195
  (match_code "reg")
196
{
197
  if (mode == VOIDmode)
198
    {
199
      mode = GET_MODE (op);
200
 
201
      if (GET_MODE_CLASS (mode) != MODE_CC)
202
        return false;
203
    }
204
 
205
  return (cc_register (op, mode)
206
          && (mode == CC_DNEmode
207
             || mode == CC_DEQmode
208
             || mode == CC_DLEmode
209
             || mode == CC_DLTmode
210
             || mode == CC_DGEmode
211
             || mode == CC_DGTmode
212
             || mode == CC_DLEUmode
213
             || mode == CC_DLTUmode
214
             || mode == CC_DGEUmode
215
             || mode == CC_DGTUmode));
216
})
217
 
218
(define_special_predicate "arm_extendqisi_mem_op"
219
  (and (match_operand 0 "memory_operand")
220
       (match_test "arm_legitimate_address_p (mode, XEXP (op, 0), SIGN_EXTEND,
221
                                              0)")))
222
 
223
(define_predicate "power_of_two_operand"
224
  (match_code "const_int")
225
{
226
  HOST_WIDE_INT value = INTVAL (op);
227
 
228
  return value != 0 && (value & (value - 1)) == 0;
229
})
230
 
231
(define_predicate "nonimmediate_di_operand"
232
  (match_code "reg,subreg,mem")
233
{
234
   if (s_register_operand (op, mode))
235
     return true;
236
 
237
   if (GET_CODE (op) == SUBREG)
238
     op = SUBREG_REG (op);
239
 
240
   return GET_CODE (op) == MEM && memory_address_p (DImode, XEXP (op, 0));
241
})
242
 
243
(define_predicate "di_operand"
244
  (ior (match_code "const_int,const_double")
245
       (and (match_code "reg,subreg,mem")
246
            (match_operand 0 "nonimmediate_di_operand"))))
247
 
248
(define_predicate "nonimmediate_soft_df_operand"
249
  (match_code "reg,subreg,mem")
250
{
251
  if (s_register_operand (op, mode))
252
    return true;
253
 
254
  if (GET_CODE (op) == SUBREG)
255
    op = SUBREG_REG (op);
256
 
257
  return GET_CODE (op) == MEM && memory_address_p (DFmode, XEXP (op, 0));
258
})
259
 
260
(define_predicate "soft_df_operand"
261
  (ior (match_code "const_double")
262
       (and (match_code "reg,subreg,mem")
263
            (match_operand 0 "nonimmediate_soft_df_operand"))))
264
 
265
(define_predicate "const_shift_operand"
266
  (and (match_code "const_int")
267
       (ior (match_operand 0 "power_of_two_operand")
268
            (match_test "((unsigned HOST_WIDE_INT) INTVAL (op)) < 32"))))
269
 
270
 
271
(define_special_predicate "load_multiple_operation"
272
  (match_code "parallel")
273
{
274
  HOST_WIDE_INT count = XVECLEN (op, 0);
275
  int dest_regno;
276
  rtx src_addr;
277
  HOST_WIDE_INT i = 1, base = 0;
278
  rtx elt;
279
 
280
  if (count <= 1
281
      || GET_CODE (XVECEXP (op, 0, 0)) != SET)
282
    return false;
283
 
284
  /* Check to see if this might be a write-back.  */
285
  if (GET_CODE (SET_SRC (elt = XVECEXP (op, 0, 0))) == PLUS)
286
    {
287
      i++;
288
      base = 1;
289
 
290
      /* Now check it more carefully.  */
291
      if (GET_CODE (SET_DEST (elt)) != REG
292
          || GET_CODE (XEXP (SET_SRC (elt), 0)) != REG
293
          || GET_CODE (XEXP (SET_SRC (elt), 1)) != CONST_INT
294
          || INTVAL (XEXP (SET_SRC (elt), 1)) != (count - 1) * 4)
295
        return false;
296
    }
297
 
298
  /* Perform a quick check so we don't blow up below.  */
299
  if (count <= i
300
      || GET_CODE (XVECEXP (op, 0, i - 1)) != SET
301
      || GET_CODE (SET_DEST (XVECEXP (op, 0, i - 1))) != REG
302
      || GET_CODE (SET_SRC (XVECEXP (op, 0, i - 1))) != MEM)
303
    return false;
304
 
305
  dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, i - 1)));
306
  src_addr = XEXP (SET_SRC (XVECEXP (op, 0, i - 1)), 0);
307
 
308
  for (; i < count; i++)
309
    {
310
      elt = XVECEXP (op, 0, i);
311
 
312
      if (GET_CODE (elt) != SET
313
          || GET_CODE (SET_DEST (elt)) != REG
314
          || GET_MODE (SET_DEST (elt)) != SImode
315
          || REGNO (SET_DEST (elt)) != (unsigned int)(dest_regno + i - base)
316
          || GET_CODE (SET_SRC (elt)) != MEM
317
          || GET_MODE (SET_SRC (elt)) != SImode
318
          || GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS
319
          || !rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr)
320
          || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT
321
          || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1)) != (i - base) * 4)
322
        return false;
323
    }
324
 
325
  return true;
326
})
327
 
328
(define_special_predicate "store_multiple_operation"
329
  (match_code "parallel")
330
{
331
  HOST_WIDE_INT count = XVECLEN (op, 0);
332
  int src_regno;
333
  rtx dest_addr;
334
  HOST_WIDE_INT i = 1, base = 0;
335
  rtx elt;
336
 
337
  if (count <= 1
338
      || GET_CODE (XVECEXP (op, 0, 0)) != SET)
339
    return false;
340
 
341
  /* Check to see if this might be a write-back.  */
342
  if (GET_CODE (SET_SRC (elt = XVECEXP (op, 0, 0))) == PLUS)
343
    {
344
      i++;
345
      base = 1;
346
 
347
      /* Now check it more carefully.  */
348
      if (GET_CODE (SET_DEST (elt)) != REG
349
          || GET_CODE (XEXP (SET_SRC (elt), 0)) != REG
350
          || GET_CODE (XEXP (SET_SRC (elt), 1)) != CONST_INT
351
          || INTVAL (XEXP (SET_SRC (elt), 1)) != (count - 1) * 4)
352
        return false;
353
    }
354
 
355
  /* Perform a quick check so we don't blow up below.  */
356
  if (count <= i
357
      || GET_CODE (XVECEXP (op, 0, i - 1)) != SET
358
      || GET_CODE (SET_DEST (XVECEXP (op, 0, i - 1))) != MEM
359
      || GET_CODE (SET_SRC (XVECEXP (op, 0, i - 1))) != REG)
360
    return false;
361
 
362
  src_regno = REGNO (SET_SRC (XVECEXP (op, 0, i - 1)));
363
  dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, i - 1)), 0);
364
 
365
  for (; i < count; i++)
366
    {
367
      elt = XVECEXP (op, 0, i);
368
 
369
      if (GET_CODE (elt) != SET
370
          || GET_CODE (SET_SRC (elt)) != REG
371
          || GET_MODE (SET_SRC (elt)) != SImode
372
          || REGNO (SET_SRC (elt)) != (unsigned int)(src_regno + i - base)
373
          || GET_CODE (SET_DEST (elt)) != MEM
374
          || GET_MODE (SET_DEST (elt)) != SImode
375
          || GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS
376
          || !rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr)
377
          || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT
378
          || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1)) != (i - base) * 4)
379
        return false;
380
    }
381
 
382
  return true;
383
})
384
 
385
(define_special_predicate "multi_register_push"
386
  (match_code "parallel")
387
{
388
  if ((GET_CODE (XVECEXP (op, 0, 0)) != SET)
389
      || (GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != UNSPEC)
390
      || (XINT (SET_SRC (XVECEXP (op, 0, 0)), 1) != UNSPEC_PUSH_MULT))
391
    return false;
392
 
393
  return true;
394
})
395
 
396
;;-------------------------------------------------------------------------
397
;;
398
;; Thumb predicates
399
;;
400
 
401
(define_predicate "thumb_cmp_operand"
402
  (ior (and (match_code "reg,subreg")
403
            (match_operand 0 "s_register_operand"))
404
       (and (match_code "const_int")
405
            (match_test "((unsigned HOST_WIDE_INT) INTVAL (op)) < 256"))))
406
 
407
(define_predicate "thumb_cmpneg_operand"
408
  (and (match_code "const_int")
409
       (match_test "INTVAL (op) < 0 && INTVAL (op) > -256")))
410
 
411
;; Return TRUE if a result can be stored in OP without clobbering the
412
;; condition code register.  Prior to reload we only accept a
413
;; register.  After reload we have to be able to handle memory as
414
;; well, since a pseudo may not get a hard reg and reload cannot
415
;; handle output-reloads on jump insns.
416
 
417
;; We could possibly handle mem before reload as well, but that might
418
;; complicate things with the need to handle increment
419
;; side-effects.
420
(define_predicate "thumb_cbrch_target_operand"
421
  (and (match_code "reg,subreg,mem")
422
       (ior (match_operand 0 "s_register_operand")
423
            (and (match_test "reload_in_progress || reload_completed")
424
                 (match_operand 0 "memory_operand")))))
425
 
426
;;-------------------------------------------------------------------------
427
;;
428
;; MAVERICK predicates
429
;;
430
 
431
(define_predicate "cirrus_register_operand"
432
  (match_code "reg,subreg")
433
{
434
  if (GET_CODE (op) == SUBREG)
435
    op = SUBREG_REG (op);
436
 
437
  return (GET_CODE (op) == REG
438
          && (REGNO_REG_CLASS (REGNO (op)) == CIRRUS_REGS
439
              || REGNO_REG_CLASS (REGNO (op)) == GENERAL_REGS));
440
})
441
 
442
(define_predicate "cirrus_fp_register"
443
  (match_code "reg,subreg")
444
{
445
  if (GET_CODE (op) == SUBREG)
446
    op = SUBREG_REG (op);
447
 
448
  return (GET_CODE (op) == REG
449
          && (REGNO (op) >= FIRST_PSEUDO_REGISTER
450
              || REGNO_REG_CLASS (REGNO (op)) == CIRRUS_REGS));
451
})
452
 
453
(define_predicate "cirrus_shift_const"
454
  (and (match_code "const_int")
455
       (match_test "((unsigned HOST_WIDE_INT) INTVAL (op)) < 64")))
456
 
457
 

powered by: WebSVN 2.1.0

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