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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [gcc/] [genattrtab.c] - Blame information for rev 12

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 12 jlechner
/* Generate code from machine description to compute values of attributes.
2
   Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998,
3
   1999, 2000, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
4
   Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
5
 
6
This file is part of GCC.
7
 
8
GCC is free software; you can redistribute it and/or modify it under
9
the terms of the GNU General Public License as published by the Free
10
Software Foundation; either version 2, or (at your option) any later
11
version.
12
 
13
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14
WARRANTY; without even the implied warranty of MERCHANTABILITY or
15
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16
for more details.
17
 
18
You should have received a copy of the GNU General Public License
19
along with GCC; see the file COPYING.  If not, write to the Free
20
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
21
02110-1301, USA.  */
22
 
23
/* This program handles insn attributes and the DEFINE_DELAY and
24
   DEFINE_INSN_RESERVATION definitions.
25
 
26
   It produces a series of functions named `get_attr_...', one for each insn
27
   attribute.  Each of these is given the rtx for an insn and returns a member
28
   of the enum for the attribute.
29
 
30
   These subroutines have the form of a `switch' on the INSN_CODE (via
31
   `recog_memoized').  Each case either returns a constant attribute value
32
   or a value that depends on tests on other attributes, the form of
33
   operands, or some random C expression (encoded with a SYMBOL_REF
34
   expression).
35
 
36
   If the attribute `alternative', or a random C expression is present,
37
   `constrain_operands' is called.  If either of these cases of a reference to
38
   an operand is found, `extract_insn' is called.
39
 
40
   The special attribute `length' is also recognized.  For this operand,
41
   expressions involving the address of an operand or the current insn,
42
   (address (pc)), are valid.  In this case, an initial pass is made to
43
   set all lengths that do not depend on address.  Those that do are set to
44
   the maximum length.  Then each insn that depends on an address is checked
45
   and possibly has its length changed.  The process repeats until no further
46
   changed are made.  The resulting lengths are saved for use by
47
   `get_attr_length'.
48
 
49
   A special form of DEFINE_ATTR, where the expression for default value is a
50
   CONST expression, indicates an attribute that is constant for a given run
51
   of the compiler.  The subroutine generated for these attributes has no
52
   parameters as it does not depend on any particular insn.  Constant
53
   attributes are typically used to specify which variety of processor is
54
   used.
55
 
56
   Internal attributes are defined to handle DEFINE_DELAY and
57
   DEFINE_INSN_RESERVATION.  Special routines are output for these cases.
58
 
59
   This program works by keeping a list of possible values for each attribute.
60
   These include the basic attribute choices, default values for attribute, and
61
   all derived quantities.
62
 
63
   As the description file is read, the definition for each insn is saved in a
64
   `struct insn_def'.   When the file reading is complete, a `struct insn_ent'
65
   is created for each insn and chained to the corresponding attribute value,
66
   either that specified, or the default.
67
 
68
   An optimization phase is then run.  This simplifies expressions for each
69
   insn.  EQ_ATTR tests are resolved, whenever possible, to a test that
70
   indicates when the attribute has the specified value for the insn.  This
71
   avoids recursive calls during compilation.
72
 
73
   The strategy used when processing DEFINE_DELAY definitions is to create
74
   arbitrarily complex expressions and have the optimization simplify them.
75
 
76
   Once optimization is complete, any required routines and definitions
77
   will be written.
78
 
79
   An optimization that is not yet implemented is to hoist the constant
80
   expressions entirely out of the routines and definitions that are written.
81
   A way to do this is to iterate over all possible combinations of values
82
   for constant attributes and generate a set of functions for that given
83
   combination.  An initialization function would be written that evaluates
84
   the attributes and installs the corresponding set of routines and
85
   definitions (each would be accessed through a pointer).
86
 
87
   We use the flags in an RTX as follows:
88
   `unchanging' (ATTR_IND_SIMPLIFIED_P): This rtx is fully simplified
89
      independent of the insn code.
90
   `in_struct' (ATTR_CURR_SIMPLIFIED_P): This rtx is fully simplified
91
      for the insn code currently being processed (see optimize_attrs).
92
   `return_val' (ATTR_PERMANENT_P): This rtx is permanent and unique
93
      (see attr_rtx).  */
94
 
95
#define ATTR_IND_SIMPLIFIED_P(RTX) (RTX_FLAG((RTX), unchanging))
96
#define ATTR_CURR_SIMPLIFIED_P(RTX) (RTX_FLAG((RTX), in_struct))
97
#define ATTR_PERMANENT_P(RTX) (RTX_FLAG((RTX), return_val))
98
 
99
#if 0
100
#define strcmp_check(S1, S2) ((S1) == (S2)              \
101
                              ? 0                        \
102
                              : (gcc_assert (strcmp ((S1), (S2))), 1))
103
#else
104
#define strcmp_check(S1, S2) ((S1) != (S2))
105
#endif
106
 
107
#include "bconfig.h"
108
#include "system.h"
109
#include "coretypes.h"
110
#include "tm.h"
111
#include "rtl.h"
112
#include "ggc.h"
113
#include "gensupport.h"
114
 
115
#ifdef HAVE_SYS_RESOURCE_H
116
# include <sys/resource.h>
117
#endif
118
 
119
/* We must include obstack.h after <sys/time.h>, to avoid lossage with
120
   /usr/include/sys/stdtypes.h on Sun OS 4.x.  */
121
#include "obstack.h"
122
#include "errors.h"
123
 
124
#include "genattrtab.h"
125
 
126
static struct obstack obstack1, obstack2;
127
struct obstack *hash_obstack = &obstack1;
128
struct obstack *temp_obstack = &obstack2;
129
 
130
/* enough space to reserve for printing out ints */
131
#define MAX_DIGITS (HOST_BITS_PER_INT * 3 / 10 + 3)
132
 
133
/* Define structures used to record attributes and values.  */
134
 
135
/* As each DEFINE_INSN, DEFINE_PEEPHOLE, or DEFINE_ASM_ATTRIBUTES is
136
   encountered, we store all the relevant information into a
137
   `struct insn_def'.  This is done to allow attribute definitions to occur
138
   anywhere in the file.  */
139
 
140
struct insn_def
141
{
142
  struct insn_def *next;        /* Next insn in chain.  */
143
  rtx def;                      /* The DEFINE_...  */
144
  int insn_code;                /* Instruction number.  */
145
  int insn_index;               /* Expression numer in file, for errors.  */
146
  int lineno;                   /* Line number.  */
147
  int num_alternatives;         /* Number of alternatives.  */
148
  int vec_idx;                  /* Index of attribute vector in `def'.  */
149
};
150
 
151
/* Once everything has been read in, we store in each attribute value a list
152
   of insn codes that have that value.  Here is the structure used for the
153
   list.  */
154
 
155
struct insn_ent
156
{
157
  struct insn_ent *next;        /* Next in chain.  */
158
  struct insn_def *def;         /* Instruction definition.  */
159
};
160
 
161
/* Each value of an attribute (either constant or computed) is assigned a
162
   structure which is used as the listhead of the insns that have that
163
   value.  */
164
 
165
struct attr_value
166
{
167
  rtx value;                    /* Value of attribute.  */
168
  struct attr_value *next;      /* Next attribute value in chain.  */
169
  struct insn_ent *first_insn;  /* First insn with this value.  */
170
  int num_insns;                /* Number of insns with this value.  */
171
  int has_asm_insn;             /* True if this value used for `asm' insns */
172
};
173
 
174
/* Structure for each attribute.  */
175
 
176
struct attr_desc
177
{
178
  char *name;                   /* Name of attribute.  */
179
  struct attr_desc *next;       /* Next attribute.  */
180
  struct attr_value *first_value; /* First value of this attribute.  */
181
  struct attr_value *default_val; /* Default value for this attribute.  */
182
  int lineno : 24;              /* Line number.  */
183
  unsigned is_numeric   : 1;    /* Values of this attribute are numeric.  */
184
  unsigned is_const     : 1;    /* Attribute value constant for each run.  */
185
  unsigned is_special   : 1;    /* Don't call `write_attr_set'.  */
186
  unsigned static_p     : 1;    /* Make the output function static.  */
187
};
188
 
189
/* Structure for each DEFINE_DELAY.  */
190
 
191
struct delay_desc
192
{
193
  rtx def;                      /* DEFINE_DELAY expression.  */
194
  struct delay_desc *next;      /* Next DEFINE_DELAY.  */
195
  int num;                      /* Number of DEFINE_DELAY, starting at 1.  */
196
  int lineno;                   /* Line number.  */
197
};
198
 
199
/* Listheads of above structures.  */
200
 
201
/* This one is indexed by the first character of the attribute name.  */
202
#define MAX_ATTRS_INDEX 256
203
static struct attr_desc *attrs[MAX_ATTRS_INDEX];
204
static struct insn_def *defs;
205
static struct delay_desc *delays;
206
 
207
/* Other variables.  */
208
 
209
static int insn_code_number;
210
static int insn_index_number;
211
static int got_define_asm_attributes;
212
static int must_extract;
213
static int must_constrain;
214
static int address_used;
215
static int length_used;
216
static int num_delays;
217
static int have_annul_true, have_annul_false;
218
static int num_insn_ents;
219
 
220
int num_dfa_decls;
221
 
222
/* Stores, for each insn code, the number of constraint alternatives.  */
223
 
224
static int *insn_n_alternatives;
225
 
226
/* Stores, for each insn code, a bitmap that has bits on for each possible
227
   alternative.  */
228
 
229
static int *insn_alternatives;
230
 
231
/* Used to simplify expressions.  */
232
 
233
static rtx true_rtx, false_rtx;
234
 
235
/* Used to reduce calls to `strcmp' */
236
 
237
static const char *alternative_name;
238
static const char *length_str;
239
static const char *delay_type_str;
240
static const char *delay_1_0_str;
241
static const char *num_delay_slots_str;
242
 
243
/* Indicate that REG_DEAD notes are valid if dead_or_set_p is ever
244
   called.  */
245
 
246
int reload_completed = 0;
247
 
248
/* Some machines test `optimize' in macros called from rtlanal.c, so we need
249
   to define it here.  */
250
 
251
int optimize = 0;
252
 
253
/* Simplify an expression.  Only call the routine if there is something to
254
   simplify.  */
255
#define SIMPLIFY_TEST_EXP(EXP,INSN_CODE,INSN_INDEX)     \
256
  (ATTR_IND_SIMPLIFIED_P (EXP) || ATTR_CURR_SIMPLIFIED_P (EXP) ? (EXP)  \
257
   : simplify_test_exp (EXP, INSN_CODE, INSN_INDEX))
258
 
259
#define DEF_ATTR_STRING(S) (attr_string ((S), strlen (S)))
260
 
261
/* These are referenced by rtlanal.c and hence need to be defined somewhere.
262
   They won't actually be used.  */
263
 
264
rtx global_rtl[GR_MAX];
265
rtx pic_offset_table_rtx;
266
 
267
static void attr_hash_add_rtx   (int, rtx);
268
static void attr_hash_add_string (int, char *);
269
static rtx attr_rtx             (enum rtx_code, ...);
270
static rtx attr_rtx_1           (enum rtx_code, va_list);
271
static char *attr_string        (const char *, int);
272
static rtx check_attr_value     (rtx, struct attr_desc *);
273
static rtx convert_set_attr_alternative (rtx, struct insn_def *);
274
static rtx convert_set_attr     (rtx, struct insn_def *);
275
static void check_defs          (void);
276
static rtx make_canonical       (struct attr_desc *, rtx);
277
static struct attr_value *get_attr_value (rtx, struct attr_desc *, int);
278
static rtx copy_rtx_unchanging  (rtx);
279
static rtx copy_boolean         (rtx);
280
static void expand_delays       (void);
281
static void fill_attr           (struct attr_desc *);
282
static rtx substitute_address   (rtx, rtx (*) (rtx), rtx (*) (rtx));
283
static void make_length_attrs   (void);
284
static rtx identity_fn          (rtx);
285
static rtx zero_fn              (rtx);
286
static rtx one_fn               (rtx);
287
static rtx max_fn               (rtx);
288
static rtx min_fn               (rtx);
289
static void write_length_unit_log (void);
290
static rtx simplify_cond        (rtx, int, int);
291
static void clear_struct_flag (rtx);
292
static void remove_insn_ent  (struct attr_value *, struct insn_ent *);
293
static void insert_insn_ent  (struct attr_value *, struct insn_ent *);
294
static rtx insert_right_side    (enum rtx_code, rtx, rtx, int, int);
295
static rtx make_alternative_compare (int);
296
static int compute_alternative_mask (rtx, enum rtx_code);
297
static rtx evaluate_eq_attr     (rtx, rtx, int, int);
298
static rtx simplify_and_tree    (rtx, rtx *, int, int);
299
static rtx simplify_or_tree     (rtx, rtx *, int, int);
300
static rtx simplify_test_exp    (rtx, int, int);
301
static rtx simplify_test_exp_in_temp (rtx, int, int);
302
static void optimize_attrs      (void);
303
static void gen_attr            (rtx, int);
304
static int count_alternatives   (rtx);
305
static int compares_alternatives_p (rtx);
306
static int contained_in_p       (rtx, rtx);
307
static void gen_insn            (rtx, int);
308
static void gen_delay           (rtx, int);
309
static void write_test_expr     (rtx, int);
310
static int max_attr_value       (rtx, int*);
311
static int min_attr_value       (rtx, int*);
312
static int or_attr_value        (rtx, int*);
313
static void walk_attr_value     (rtx);
314
static void write_attr_get      (struct attr_desc *);
315
static rtx eliminate_known_true (rtx, rtx, int, int);
316
static void write_attr_set      (struct attr_desc *, int, rtx,
317
                                 const char *, const char *, rtx,
318
                                 int, int);
319
static void write_insn_cases    (struct insn_ent *, int);
320
static void write_attr_case     (struct attr_desc *, struct attr_value *,
321
                                 int, const char *, const char *, int, rtx);
322
static void write_attr_valueq   (struct attr_desc *, const char *);
323
static void write_attr_value    (struct attr_desc *, rtx);
324
static void write_upcase        (const char *);
325
static void write_indent        (int);
326
static void write_eligible_delay (const char *);
327
static int write_expr_attr_cache (rtx, struct attr_desc *);
328
static void write_const_num_delay_slots (void);
329
static char *next_comma_elt     (const char **);
330
static struct attr_desc *find_attr (const char **, int);
331
static struct attr_value *find_most_used  (struct attr_desc *);
332
static rtx attr_eq              (const char *, const char *);
333
static const char *attr_numeral (int);
334
static int attr_equal_p         (rtx, rtx);
335
static rtx attr_copy_rtx        (rtx);
336
static int attr_rtx_cost        (rtx);
337
static bool attr_alt_subset_p (rtx, rtx);
338
static bool attr_alt_subset_of_compl_p (rtx, rtx);
339
static rtx attr_alt_intersection (rtx, rtx);
340
static rtx attr_alt_union (rtx, rtx);
341
static rtx attr_alt_complement (rtx);
342
static rtx mk_attr_alt (int);
343
 
344
#define oballoc(size) obstack_alloc (hash_obstack, size)
345
 
346
/* Hash table for sharing RTL and strings.  */
347
 
348
/* Each hash table slot is a bucket containing a chain of these structures.
349
   Strings are given negative hash codes; RTL expressions are given positive
350
   hash codes.  */
351
 
352
struct attr_hash
353
{
354
  struct attr_hash *next;       /* Next structure in the bucket.  */
355
  int hashcode;                 /* Hash code of this rtx or string.  */
356
  union
357
    {
358
      char *str;                /* The string (negative hash codes) */
359
      rtx rtl;                  /* or the RTL recorded here.  */
360
    } u;
361
};
362
 
363
/* Now here is the hash table.  When recording an RTL, it is added to
364
   the slot whose index is the hash code mod the table size.  Note
365
   that the hash table is used for several kinds of RTL (see attr_rtx)
366
   and for strings.  While all these live in the same table, they are
367
   completely independent, and the hash code is computed differently
368
   for each.  */
369
 
370
#define RTL_HASH_SIZE 4093
371
struct attr_hash *attr_hash_table[RTL_HASH_SIZE];
372
 
373
/* Here is how primitive or already-shared RTL's hash
374
   codes are made.  */
375
#define RTL_HASH(RTL) ((long) (RTL) & 0777777)
376
 
377
/* Add an entry to the hash table for RTL with hash code HASHCODE.  */
378
 
379
static void
380
attr_hash_add_rtx (int hashcode, rtx rtl)
381
{
382
  struct attr_hash *h;
383
 
384
  h = obstack_alloc (hash_obstack, sizeof (struct attr_hash));
385
  h->hashcode = hashcode;
386
  h->u.rtl = rtl;
387
  h->next = attr_hash_table[hashcode % RTL_HASH_SIZE];
388
  attr_hash_table[hashcode % RTL_HASH_SIZE] = h;
389
}
390
 
391
/* Add an entry to the hash table for STRING with hash code HASHCODE.  */
392
 
393
static void
394
attr_hash_add_string (int hashcode, char *str)
395
{
396
  struct attr_hash *h;
397
 
398
  h = obstack_alloc (hash_obstack, sizeof (struct attr_hash));
399
  h->hashcode = -hashcode;
400
  h->u.str = str;
401
  h->next = attr_hash_table[hashcode % RTL_HASH_SIZE];
402
  attr_hash_table[hashcode % RTL_HASH_SIZE] = h;
403
}
404
 
405
/* Generate an RTL expression, but avoid duplicates.
406
   Set the ATTR_PERMANENT_P flag for these permanent objects.
407
 
408
   In some cases we cannot uniquify; then we return an ordinary
409
   impermanent rtx with ATTR_PERMANENT_P clear.
410
 
411
   Args are as follows:
412
 
413
   rtx attr_rtx (code, [element1, ..., elementn])  */
414
 
415
static rtx
416
attr_rtx_1 (enum rtx_code code, va_list p)
417
{
418
  rtx rt_val = NULL_RTX;/* RTX to return to caller...           */
419
  int hashcode;
420
  struct attr_hash *h;
421
  struct obstack *old_obstack = rtl_obstack;
422
 
423
  /* For each of several cases, search the hash table for an existing entry.
424
     Use that entry if one is found; otherwise create a new RTL and add it
425
     to the table.  */
426
 
427
  if (GET_RTX_CLASS (code) == RTX_UNARY)
428
    {
429
      rtx arg0 = va_arg (p, rtx);
430
 
431
      /* A permanent object cannot point to impermanent ones.  */
432
      if (! ATTR_PERMANENT_P (arg0))
433
        {
434
          rt_val = rtx_alloc (code);
435
          XEXP (rt_val, 0) = arg0;
436
          return rt_val;
437
        }
438
 
439
      hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0));
440
      for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
441
        if (h->hashcode == hashcode
442
            && GET_CODE (h->u.rtl) == code
443
            && XEXP (h->u.rtl, 0) == arg0)
444
          return h->u.rtl;
445
 
446
      if (h == 0)
447
        {
448
          rtl_obstack = hash_obstack;
449
          rt_val = rtx_alloc (code);
450
          XEXP (rt_val, 0) = arg0;
451
        }
452
    }
453
  else if (GET_RTX_CLASS (code) == RTX_BIN_ARITH
454
           || GET_RTX_CLASS (code) == RTX_COMM_ARITH
455
           || GET_RTX_CLASS (code) == RTX_COMPARE
456
           || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
457
    {
458
      rtx arg0 = va_arg (p, rtx);
459
      rtx arg1 = va_arg (p, rtx);
460
 
461
      /* A permanent object cannot point to impermanent ones.  */
462
      if (! ATTR_PERMANENT_P (arg0) || ! ATTR_PERMANENT_P (arg1))
463
        {
464
          rt_val = rtx_alloc (code);
465
          XEXP (rt_val, 0) = arg0;
466
          XEXP (rt_val, 1) = arg1;
467
          return rt_val;
468
        }
469
 
470
      hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0) + RTL_HASH (arg1));
471
      for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
472
        if (h->hashcode == hashcode
473
            && GET_CODE (h->u.rtl) == code
474
            && XEXP (h->u.rtl, 0) == arg0
475
            && XEXP (h->u.rtl, 1) == arg1)
476
          return h->u.rtl;
477
 
478
      if (h == 0)
479
        {
480
          rtl_obstack = hash_obstack;
481
          rt_val = rtx_alloc (code);
482
          XEXP (rt_val, 0) = arg0;
483
          XEXP (rt_val, 1) = arg1;
484
        }
485
    }
486
  else if (GET_RTX_LENGTH (code) == 1
487
           && GET_RTX_FORMAT (code)[0] == 's')
488
    {
489
      char *arg0 = va_arg (p, char *);
490
 
491
      arg0 = DEF_ATTR_STRING (arg0);
492
 
493
      hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0));
494
      for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
495
        if (h->hashcode == hashcode
496
            && GET_CODE (h->u.rtl) == code
497
            && XSTR (h->u.rtl, 0) == arg0)
498
          return h->u.rtl;
499
 
500
      if (h == 0)
501
        {
502
          rtl_obstack = hash_obstack;
503
          rt_val = rtx_alloc (code);
504
          XSTR (rt_val, 0) = arg0;
505
        }
506
    }
507
  else if (GET_RTX_LENGTH (code) == 2
508
           && GET_RTX_FORMAT (code)[0] == 's'
509
           && GET_RTX_FORMAT (code)[1] == 's')
510
    {
511
      char *arg0 = va_arg (p, char *);
512
      char *arg1 = va_arg (p, char *);
513
 
514
      hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0) + RTL_HASH (arg1));
515
      for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
516
        if (h->hashcode == hashcode
517
            && GET_CODE (h->u.rtl) == code
518
            && XSTR (h->u.rtl, 0) == arg0
519
            && XSTR (h->u.rtl, 1) == arg1)
520
          return h->u.rtl;
521
 
522
      if (h == 0)
523
        {
524
          rtl_obstack = hash_obstack;
525
          rt_val = rtx_alloc (code);
526
          XSTR (rt_val, 0) = arg0;
527
          XSTR (rt_val, 1) = arg1;
528
        }
529
    }
530
  else if (code == CONST_INT)
531
    {
532
      HOST_WIDE_INT arg0 = va_arg (p, HOST_WIDE_INT);
533
      if (arg0 == 0)
534
        return false_rtx;
535
      else if (arg0 == 1)
536
        return true_rtx;
537
      else
538
        goto nohash;
539
    }
540
  else
541
    {
542
      int i;            /* Array indices...                     */
543
      const char *fmt;  /* Current rtx's format...              */
544
    nohash:
545
      rt_val = rtx_alloc (code);        /* Allocate the storage space.  */
546
 
547
      fmt = GET_RTX_FORMAT (code);      /* Find the right format...  */
548
      for (i = 0; i < GET_RTX_LENGTH (code); i++)
549
        {
550
          switch (*fmt++)
551
            {
552
            case '0':           /* Unused field.  */
553
              break;
554
 
555
            case 'i':           /* An integer?  */
556
              XINT (rt_val, i) = va_arg (p, int);
557
              break;
558
 
559
            case 'w':           /* A wide integer? */
560
              XWINT (rt_val, i) = va_arg (p, HOST_WIDE_INT);
561
              break;
562
 
563
            case 's':           /* A string?  */
564
              XSTR (rt_val, i) = va_arg (p, char *);
565
              break;
566
 
567
            case 'e':           /* An expression?  */
568
            case 'u':           /* An insn?  Same except when printing.  */
569
              XEXP (rt_val, i) = va_arg (p, rtx);
570
              break;
571
 
572
            case 'E':           /* An RTX vector?  */
573
              XVEC (rt_val, i) = va_arg (p, rtvec);
574
              break;
575
 
576
            default:
577
              gcc_unreachable ();
578
            }
579
        }
580
      return rt_val;
581
    }
582
 
583
  rtl_obstack = old_obstack;
584
  attr_hash_add_rtx (hashcode, rt_val);
585
  ATTR_PERMANENT_P (rt_val) = 1;
586
  return rt_val;
587
}
588
 
589
static rtx
590
attr_rtx (enum rtx_code code, ...)
591
{
592
  rtx result;
593
  va_list p;
594
 
595
  va_start (p, code);
596
  result = attr_rtx_1 (code, p);
597
  va_end (p);
598
  return result;
599
}
600
 
601
/* Create a new string printed with the printf line arguments into a space
602
   of at most LEN bytes:
603
 
604
   rtx attr_printf (len, format, [arg1, ..., argn])  */
605
 
606
char *
607
attr_printf (unsigned int len, const char *fmt, ...)
608
{
609
  char str[256];
610
  va_list p;
611
 
612
  va_start (p, fmt);
613
 
614
  gcc_assert (len < sizeof str); /* Leave room for \0.  */
615
 
616
  vsprintf (str, fmt, p);
617
  va_end (p);
618
 
619
  return DEF_ATTR_STRING (str);
620
}
621
 
622
static rtx
623
attr_eq (const char *name, const char *value)
624
{
625
  return attr_rtx (EQ_ATTR, DEF_ATTR_STRING (name), DEF_ATTR_STRING (value));
626
}
627
 
628
static const char *
629
attr_numeral (int n)
630
{
631
  return XSTR (make_numeric_value (n), 0);
632
}
633
 
634
/* Return a permanent (possibly shared) copy of a string STR (not assumed
635
   to be null terminated) with LEN bytes.  */
636
 
637
static char *
638
attr_string (const char *str, int len)
639
{
640
  struct attr_hash *h;
641
  int hashcode;
642
  int i;
643
  char *new_str;
644
 
645
  /* Compute the hash code.  */
646
  hashcode = (len + 1) * 613 + (unsigned) str[0];
647
  for (i = 1; i <= len; i += 2)
648
    hashcode = ((hashcode * 613) + (unsigned) str[i]);
649
  if (hashcode < 0)
650
    hashcode = -hashcode;
651
 
652
  /* Search the table for the string.  */
653
  for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
654
    if (h->hashcode == -hashcode && h->u.str[0] == str[0]
655
        && !strncmp (h->u.str, str, len))
656
      return h->u.str;                  /* <-- return if found.  */
657
 
658
  /* Not found; create a permanent copy and add it to the hash table.  */
659
  new_str = obstack_alloc (hash_obstack, len + 1);
660
  memcpy (new_str, str, len);
661
  new_str[len] = '\0';
662
  attr_hash_add_string (hashcode, new_str);
663
 
664
  return new_str;                       /* Return the new string.  */
665
}
666
 
667
/* Check two rtx's for equality of contents,
668
   taking advantage of the fact that if both are hashed
669
   then they can't be equal unless they are the same object.  */
670
 
671
static int
672
attr_equal_p (rtx x, rtx y)
673
{
674
  return (x == y || (! (ATTR_PERMANENT_P (x) && ATTR_PERMANENT_P (y))
675
                     && rtx_equal_p (x, y)));
676
}
677
 
678
/* Copy an attribute value expression,
679
   descending to all depths, but not copying any
680
   permanent hashed subexpressions.  */
681
 
682
static rtx
683
attr_copy_rtx (rtx orig)
684
{
685
  rtx copy;
686
  int i, j;
687
  RTX_CODE code;
688
  const char *format_ptr;
689
 
690
  /* No need to copy a permanent object.  */
691
  if (ATTR_PERMANENT_P (orig))
692
    return orig;
693
 
694
  code = GET_CODE (orig);
695
 
696
  switch (code)
697
    {
698
    case REG:
699
    case CONST_INT:
700
    case CONST_DOUBLE:
701
    case CONST_VECTOR:
702
    case SYMBOL_REF:
703
    case CODE_LABEL:
704
    case PC:
705
    case CC0:
706
      return orig;
707
 
708
    default:
709
      break;
710
    }
711
 
712
  copy = rtx_alloc (code);
713
  PUT_MODE (copy, GET_MODE (orig));
714
  ATTR_IND_SIMPLIFIED_P (copy) = ATTR_IND_SIMPLIFIED_P (orig);
715
  ATTR_CURR_SIMPLIFIED_P (copy) = ATTR_CURR_SIMPLIFIED_P (orig);
716
  ATTR_PERMANENT_P (copy) = ATTR_PERMANENT_P (orig);
717
 
718
  format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
719
 
720
  for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
721
    {
722
      switch (*format_ptr++)
723
        {
724
        case 'e':
725
          XEXP (copy, i) = XEXP (orig, i);
726
          if (XEXP (orig, i) != NULL)
727
            XEXP (copy, i) = attr_copy_rtx (XEXP (orig, i));
728
          break;
729
 
730
        case 'E':
731
        case 'V':
732
          XVEC (copy, i) = XVEC (orig, i);
733
          if (XVEC (orig, i) != NULL)
734
            {
735
              XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
736
              for (j = 0; j < XVECLEN (copy, i); j++)
737
                XVECEXP (copy, i, j) = attr_copy_rtx (XVECEXP (orig, i, j));
738
            }
739
          break;
740
 
741
        case 'n':
742
        case 'i':
743
          XINT (copy, i) = XINT (orig, i);
744
          break;
745
 
746
        case 'w':
747
          XWINT (copy, i) = XWINT (orig, i);
748
          break;
749
 
750
        case 's':
751
        case 'S':
752
          XSTR (copy, i) = XSTR (orig, i);
753
          break;
754
 
755
        default:
756
          gcc_unreachable ();
757
        }
758
    }
759
  return copy;
760
}
761
 
762
/* Given a test expression for an attribute, ensure it is validly formed.
763
   IS_CONST indicates whether the expression is constant for each compiler
764
   run (a constant expression may not test any particular insn).
765
 
766
   Convert (eq_attr "att" "a1,a2") to (ior (eq_attr ... ) (eq_attrq ..))
767
   and (eq_attr "att" "!a1") to (not (eq_attr "att" "a1")).  Do the latter
768
   test first so that (eq_attr "att" "!a1,a2,a3") works as expected.
769
 
770
   Update the string address in EQ_ATTR expression to be the same used
771
   in the attribute (or `alternative_name') to speed up subsequent
772
   `find_attr' calls and eliminate most `strcmp' calls.
773
 
774
   Return the new expression, if any.  */
775
 
776
rtx
777
check_attr_test (rtx exp, int is_const, int lineno)
778
{
779
  struct attr_desc *attr;
780
  struct attr_value *av;
781
  const char *name_ptr, *p;
782
  rtx orexp, newexp;
783
 
784
  switch (GET_CODE (exp))
785
    {
786
    case EQ_ATTR:
787
      /* Handle negation test.  */
788
      if (XSTR (exp, 1)[0] == '!')
789
        return check_attr_test (attr_rtx (NOT,
790
                                          attr_eq (XSTR (exp, 0),
791
                                                   &XSTR (exp, 1)[1])),
792
                                is_const, lineno);
793
 
794
      else if (n_comma_elts (XSTR (exp, 1)) == 1)
795
        {
796
          attr = find_attr (&XSTR (exp, 0), 0);
797
          if (attr == NULL)
798
            {
799
              if (! strcmp (XSTR (exp, 0), "alternative"))
800
                return mk_attr_alt (1 << atoi (XSTR (exp, 1)));
801
              else
802
                fatal ("unknown attribute `%s' in EQ_ATTR", XSTR (exp, 0));
803
            }
804
 
805
          if (is_const && ! attr->is_const)
806
            fatal ("constant expression uses insn attribute `%s' in EQ_ATTR",
807
                   XSTR (exp, 0));
808
 
809
          /* Copy this just to make it permanent,
810
             so expressions using it can be permanent too.  */
811
          exp = attr_eq (XSTR (exp, 0), XSTR (exp, 1));
812
 
813
          /* It shouldn't be possible to simplify the value given to a
814
             constant attribute, so don't expand this until it's time to
815
             write the test expression.  */
816
          if (attr->is_const)
817
            ATTR_IND_SIMPLIFIED_P (exp) = 1;
818
 
819
          if (attr->is_numeric)
820
            {
821
              for (p = XSTR (exp, 1); *p; p++)
822
                if (! ISDIGIT (*p))
823
                  fatal ("attribute `%s' takes only numeric values",
824
                         XSTR (exp, 0));
825
            }
826
          else
827
            {
828
              for (av = attr->first_value; av; av = av->next)
829
                if (GET_CODE (av->value) == CONST_STRING
830
                    && ! strcmp (XSTR (exp, 1), XSTR (av->value, 0)))
831
                  break;
832
 
833
              if (av == NULL)
834
                fatal ("unknown value `%s' for `%s' attribute",
835
                       XSTR (exp, 1), XSTR (exp, 0));
836
            }
837
        }
838
      else
839
        {
840
          if (! strcmp (XSTR (exp, 0), "alternative"))
841
            {
842
              int set = 0;
843
 
844
              name_ptr = XSTR (exp, 1);
845
              while ((p = next_comma_elt (&name_ptr)) != NULL)
846
                set |= 1 << atoi (p);
847
 
848
              return mk_attr_alt (set);
849
            }
850
          else
851
            {
852
              /* Make an IOR tree of the possible values.  */
853
              orexp = false_rtx;
854
              name_ptr = XSTR (exp, 1);
855
              while ((p = next_comma_elt (&name_ptr)) != NULL)
856
                {
857
                  newexp = attr_eq (XSTR (exp, 0), p);
858
                  orexp = insert_right_side (IOR, orexp, newexp, -2, -2);
859
                }
860
 
861
              return check_attr_test (orexp, is_const, lineno);
862
            }
863
        }
864
      break;
865
 
866
    case ATTR_FLAG:
867
      break;
868
 
869
    case CONST_INT:
870
      /* Either TRUE or FALSE.  */
871
      if (XWINT (exp, 0))
872
        return true_rtx;
873
      else
874
        return false_rtx;
875
 
876
    case IOR:
877
    case AND:
878
      XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), is_const, lineno);
879
      XEXP (exp, 1) = check_attr_test (XEXP (exp, 1), is_const, lineno);
880
      break;
881
 
882
    case NOT:
883
      XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), is_const, lineno);
884
      break;
885
 
886
    case MATCH_OPERAND:
887
      if (is_const)
888
        fatal ("RTL operator \"%s\" not valid in constant attribute test",
889
               GET_RTX_NAME (GET_CODE (exp)));
890
      /* These cases can't be simplified.  */
891
      ATTR_IND_SIMPLIFIED_P (exp) = 1;
892
      break;
893
 
894
    case LE:  case LT:  case GT:  case GE:
895
    case LEU: case LTU: case GTU: case GEU:
896
    case NE:  case EQ:
897
      if (GET_CODE (XEXP (exp, 0)) == SYMBOL_REF
898
          && GET_CODE (XEXP (exp, 1)) == SYMBOL_REF)
899
        exp = attr_rtx (GET_CODE (exp),
900
                        attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 0), 0)),
901
                        attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 1), 0)));
902
      /* These cases can't be simplified.  */
903
      ATTR_IND_SIMPLIFIED_P (exp) = 1;
904
      break;
905
 
906
    case SYMBOL_REF:
907
      if (is_const)
908
        {
909
          /* These cases are valid for constant attributes, but can't be
910
             simplified.  */
911
          exp = attr_rtx (SYMBOL_REF, XSTR (exp, 0));
912
          ATTR_IND_SIMPLIFIED_P (exp) = 1;
913
          break;
914
        }
915
    default:
916
      fatal ("RTL operator \"%s\" not valid in attribute test",
917
             GET_RTX_NAME (GET_CODE (exp)));
918
    }
919
 
920
  return exp;
921
}
922
 
923
/* Given an expression, ensure that it is validly formed and that all named
924
   attribute values are valid for the given attribute.  Issue a fatal error
925
   if not.  If no attribute is specified, assume a numeric attribute.
926
 
927
   Return a perhaps modified replacement expression for the value.  */
928
 
929
static rtx
930
check_attr_value (rtx exp, struct attr_desc *attr)
931
{
932
  struct attr_value *av;
933
  const char *p;
934
  int i;
935
 
936
  switch (GET_CODE (exp))
937
    {
938
    case CONST_INT:
939
      if (attr && ! attr->is_numeric)
940
        {
941
          message_with_line (attr->lineno,
942
                             "CONST_INT not valid for non-numeric attribute %s",
943
                             attr->name);
944
          have_error = 1;
945
          break;
946
        }
947
 
948
      if (INTVAL (exp) < 0)
949
        {
950
          message_with_line (attr->lineno,
951
                             "negative numeric value specified for attribute %s",
952
                             attr->name);
953
          have_error = 1;
954
          break;
955
        }
956
      break;
957
 
958
    case CONST_STRING:
959
      if (! strcmp (XSTR (exp, 0), "*"))
960
        break;
961
 
962
      if (attr == 0 || attr->is_numeric)
963
        {
964
          p = XSTR (exp, 0);
965
          for (; *p; p++)
966
            if (! ISDIGIT (*p))
967
              {
968
                message_with_line (attr ? attr->lineno : 0,
969
                                   "non-numeric value for numeric attribute %s",
970
                                   attr ? attr->name : "internal");
971
                have_error = 1;
972
                break;
973
              }
974
          break;
975
        }
976
 
977
      for (av = attr->first_value; av; av = av->next)
978
        if (GET_CODE (av->value) == CONST_STRING
979
            && ! strcmp (XSTR (av->value, 0), XSTR (exp, 0)))
980
          break;
981
 
982
      if (av == NULL)
983
        {
984
          message_with_line (attr->lineno,
985
                             "unknown value `%s' for `%s' attribute",
986
                             XSTR (exp, 0), attr ? attr->name : "internal");
987
          have_error = 1;
988
        }
989
      break;
990
 
991
    case IF_THEN_ELSE:
992
      XEXP (exp, 0) = check_attr_test (XEXP (exp, 0),
993
                                       attr ? attr->is_const : 0,
994
                                       attr ? attr->lineno : 0);
995
      XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
996
      XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr);
997
      break;
998
 
999
    case PLUS:
1000
    case MINUS:
1001
    case MULT:
1002
    case DIV:
1003
    case MOD:
1004
      if (attr && !attr->is_numeric)
1005
        {
1006
          message_with_line (attr->lineno,
1007
                             "invalid operation `%s' for non-numeric attribute value",
1008
                             GET_RTX_NAME (GET_CODE (exp)));
1009
          have_error = 1;
1010
          break;
1011
        }
1012
      /* Fall through.  */
1013
 
1014
    case IOR:
1015
    case AND:
1016
      XEXP (exp, 0) = check_attr_value (XEXP (exp, 0), attr);
1017
      XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
1018
      break;
1019
 
1020
    case FFS:
1021
    case CLZ:
1022
    case CTZ:
1023
    case POPCOUNT:
1024
    case PARITY:
1025
      XEXP (exp, 0) = check_attr_value (XEXP (exp, 0), attr);
1026
      break;
1027
 
1028
    case COND:
1029
      if (XVECLEN (exp, 0) % 2 != 0)
1030
        {
1031
          message_with_line (attr->lineno,
1032
                             "first operand of COND must have even length");
1033
          have_error = 1;
1034
          break;
1035
        }
1036
 
1037
      for (i = 0; i < XVECLEN (exp, 0); i += 2)
1038
        {
1039
          XVECEXP (exp, 0, i) = check_attr_test (XVECEXP (exp, 0, i),
1040
                                                 attr ? attr->is_const : 0,
1041
                                                 attr ? attr->lineno : 0);
1042
          XVECEXP (exp, 0, i + 1)
1043
            = check_attr_value (XVECEXP (exp, 0, i + 1), attr);
1044
        }
1045
 
1046
      XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
1047
      break;
1048
 
1049
    case ATTR:
1050
      {
1051
        struct attr_desc *attr2 = find_attr (&XSTR (exp, 0), 0);
1052
        if (attr2 == NULL)
1053
          {
1054
            message_with_line (attr ? attr->lineno : 0,
1055
                               "unknown attribute `%s' in ATTR",
1056
                               XSTR (exp, 0));
1057
            have_error = 1;
1058
          }
1059
        else if (attr && attr->is_const && ! attr2->is_const)
1060
          {
1061
            message_with_line (attr->lineno,
1062
                "non-constant attribute `%s' referenced from `%s'",
1063
                XSTR (exp, 0), attr->name);
1064
            have_error = 1;
1065
          }
1066
        else if (attr
1067
                 && attr->is_numeric != attr2->is_numeric)
1068
          {
1069
            message_with_line (attr->lineno,
1070
                "numeric attribute mismatch calling `%s' from `%s'",
1071
                XSTR (exp, 0), attr->name);
1072
            have_error = 1;
1073
          }
1074
      }
1075
      break;
1076
 
1077
    case SYMBOL_REF:
1078
      /* A constant SYMBOL_REF is valid as a constant attribute test and
1079
         is expanded later by make_canonical into a COND.  In a non-constant
1080
         attribute test, it is left be.  */
1081
      return attr_rtx (SYMBOL_REF, XSTR (exp, 0));
1082
 
1083
    default:
1084
      message_with_line (attr ? attr->lineno : 0,
1085
                         "invalid operation `%s' for attribute value",
1086
                         GET_RTX_NAME (GET_CODE (exp)));
1087
      have_error = 1;
1088
      break;
1089
    }
1090
 
1091
  return exp;
1092
}
1093
 
1094
/* Given an SET_ATTR_ALTERNATIVE expression, convert to the canonical SET.
1095
   It becomes a COND with each test being (eq_attr "alternative" "n") */
1096
 
1097
static rtx
1098
convert_set_attr_alternative (rtx exp, struct insn_def *id)
1099
{
1100
  int num_alt = id->num_alternatives;
1101
  rtx condexp;
1102
  int i;
1103
 
1104
  if (XVECLEN (exp, 1) != num_alt)
1105
    {
1106
      message_with_line (id->lineno,
1107
                         "bad number of entries in SET_ATTR_ALTERNATIVE");
1108
      have_error = 1;
1109
      return NULL_RTX;
1110
    }
1111
 
1112
  /* Make a COND with all tests but the last.  Select the last value via the
1113
     default.  */
1114
  condexp = rtx_alloc (COND);
1115
  XVEC (condexp, 0) = rtvec_alloc ((num_alt - 1) * 2);
1116
 
1117
  for (i = 0; i < num_alt - 1; i++)
1118
    {
1119
      const char *p;
1120
      p = attr_numeral (i);
1121
 
1122
      XVECEXP (condexp, 0, 2 * i) = attr_eq (alternative_name, p);
1123
      XVECEXP (condexp, 0, 2 * i + 1) = XVECEXP (exp, 1, i);
1124
    }
1125
 
1126
  XEXP (condexp, 1) = XVECEXP (exp, 1, i);
1127
 
1128
  return attr_rtx (SET, attr_rtx (ATTR, XSTR (exp, 0)), condexp);
1129
}
1130
 
1131
/* Given a SET_ATTR, convert to the appropriate SET.  If a comma-separated
1132
   list of values is given, convert to SET_ATTR_ALTERNATIVE first.  */
1133
 
1134
static rtx
1135
convert_set_attr (rtx exp, struct insn_def *id)
1136
{
1137
  rtx newexp;
1138
  const char *name_ptr;
1139
  char *p;
1140
  int n;
1141
 
1142
  /* See how many alternative specified.  */
1143
  n = n_comma_elts (XSTR (exp, 1));
1144
  if (n == 1)
1145
    return attr_rtx (SET,
1146
                     attr_rtx (ATTR, XSTR (exp, 0)),
1147
                     attr_rtx (CONST_STRING, XSTR (exp, 1)));
1148
 
1149
  newexp = rtx_alloc (SET_ATTR_ALTERNATIVE);
1150
  XSTR (newexp, 0) = XSTR (exp, 0);
1151
  XVEC (newexp, 1) = rtvec_alloc (n);
1152
 
1153
  /* Process each comma-separated name.  */
1154
  name_ptr = XSTR (exp, 1);
1155
  n = 0;
1156
  while ((p = next_comma_elt (&name_ptr)) != NULL)
1157
    XVECEXP (newexp, 1, n++) = attr_rtx (CONST_STRING, p);
1158
 
1159
  return convert_set_attr_alternative (newexp, id);
1160
}
1161
 
1162
/* Scan all definitions, checking for validity.  Also, convert any SET_ATTR
1163
   and SET_ATTR_ALTERNATIVE expressions to the corresponding SET
1164
   expressions.  */
1165
 
1166
static void
1167
check_defs (void)
1168
{
1169
  struct insn_def *id;
1170
  struct attr_desc *attr;
1171
  int i;
1172
  rtx value;
1173
 
1174
  for (id = defs; id; id = id->next)
1175
    {
1176
      if (XVEC (id->def, id->vec_idx) == NULL)
1177
        continue;
1178
 
1179
      for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
1180
        {
1181
          value = XVECEXP (id->def, id->vec_idx, i);
1182
          switch (GET_CODE (value))
1183
            {
1184
            case SET:
1185
              if (GET_CODE (XEXP (value, 0)) != ATTR)
1186
                {
1187
                  message_with_line (id->lineno, "bad attribute set");
1188
                  have_error = 1;
1189
                  value = NULL_RTX;
1190
                }
1191
              break;
1192
 
1193
            case SET_ATTR_ALTERNATIVE:
1194
              value = convert_set_attr_alternative (value, id);
1195
              break;
1196
 
1197
            case SET_ATTR:
1198
              value = convert_set_attr (value, id);
1199
              break;
1200
 
1201
            default:
1202
              message_with_line (id->lineno, "invalid attribute code %s",
1203
                                 GET_RTX_NAME (GET_CODE (value)));
1204
              have_error = 1;
1205
              value = NULL_RTX;
1206
            }
1207
          if (value == NULL_RTX)
1208
            continue;
1209
 
1210
          if ((attr = find_attr (&XSTR (XEXP (value, 0), 0), 0)) == NULL)
1211
            {
1212
              message_with_line (id->lineno, "unknown attribute %s",
1213
                                 XSTR (XEXP (value, 0), 0));
1214
              have_error = 1;
1215
              continue;
1216
            }
1217
 
1218
          XVECEXP (id->def, id->vec_idx, i) = value;
1219
          XEXP (value, 1) = check_attr_value (XEXP (value, 1), attr);
1220
        }
1221
    }
1222
}
1223
 
1224
/* Given a valid expression for an attribute value, remove any IF_THEN_ELSE
1225
   expressions by converting them into a COND.  This removes cases from this
1226
   program.  Also, replace an attribute value of "*" with the default attribute
1227
   value.  */
1228
 
1229
static rtx
1230
make_canonical (struct attr_desc *attr, rtx exp)
1231
{
1232
  int i;
1233
  rtx newexp;
1234
 
1235
  switch (GET_CODE (exp))
1236
    {
1237
    case CONST_INT:
1238
      exp = make_numeric_value (INTVAL (exp));
1239
      break;
1240
 
1241
    case CONST_STRING:
1242
      if (! strcmp (XSTR (exp, 0), "*"))
1243
        {
1244
          if (attr == 0 || attr->default_val == 0)
1245
            fatal ("(attr_value \"*\") used in invalid context");
1246
          exp = attr->default_val->value;
1247
        }
1248
      else
1249
        XSTR (exp, 0) = DEF_ATTR_STRING (XSTR (exp, 0));
1250
 
1251
      break;
1252
 
1253
    case SYMBOL_REF:
1254
      if (!attr->is_const || ATTR_IND_SIMPLIFIED_P (exp))
1255
        break;
1256
      /* The SYMBOL_REF is constant for a given run, so mark it as unchanging.
1257
         This makes the COND something that won't be considered an arbitrary
1258
         expression by walk_attr_value.  */
1259
      ATTR_IND_SIMPLIFIED_P (exp) = 1;
1260
      exp = check_attr_value (exp, attr);
1261
      break;
1262
 
1263
    case IF_THEN_ELSE:
1264
      newexp = rtx_alloc (COND);
1265
      XVEC (newexp, 0) = rtvec_alloc (2);
1266
      XVECEXP (newexp, 0, 0) = XEXP (exp, 0);
1267
      XVECEXP (newexp, 0, 1) = XEXP (exp, 1);
1268
 
1269
      XEXP (newexp, 1) = XEXP (exp, 2);
1270
 
1271
      exp = newexp;
1272
      /* Fall through to COND case since this is now a COND.  */
1273
 
1274
    case COND:
1275
      {
1276
        int allsame = 1;
1277
        rtx defval;
1278
 
1279
        /* First, check for degenerate COND.  */
1280
        if (XVECLEN (exp, 0) == 0)
1281
          return make_canonical (attr, XEXP (exp, 1));
1282
        defval = XEXP (exp, 1) = make_canonical (attr, XEXP (exp, 1));
1283
 
1284
        for (i = 0; i < XVECLEN (exp, 0); i += 2)
1285
          {
1286
            XVECEXP (exp, 0, i) = copy_boolean (XVECEXP (exp, 0, i));
1287
            XVECEXP (exp, 0, i + 1)
1288
              = make_canonical (attr, XVECEXP (exp, 0, i + 1));
1289
            if (! rtx_equal_p (XVECEXP (exp, 0, i + 1), defval))
1290
              allsame = 0;
1291
          }
1292
        if (allsame)
1293
          return defval;
1294
      }
1295
      break;
1296
 
1297
    default:
1298
      break;
1299
    }
1300
 
1301
  return exp;
1302
}
1303
 
1304
static rtx
1305
copy_boolean (rtx exp)
1306
{
1307
  if (GET_CODE (exp) == AND || GET_CODE (exp) == IOR)
1308
    return attr_rtx (GET_CODE (exp), copy_boolean (XEXP (exp, 0)),
1309
                     copy_boolean (XEXP (exp, 1)));
1310
  if (GET_CODE (exp) == MATCH_OPERAND)
1311
    {
1312
      XSTR (exp, 1) = DEF_ATTR_STRING (XSTR (exp, 1));
1313
      XSTR (exp, 2) = DEF_ATTR_STRING (XSTR (exp, 2));
1314
    }
1315
  else if (GET_CODE (exp) == EQ_ATTR)
1316
    {
1317
      XSTR (exp, 0) = DEF_ATTR_STRING (XSTR (exp, 0));
1318
      XSTR (exp, 1) = DEF_ATTR_STRING (XSTR (exp, 1));
1319
    }
1320
 
1321
  return exp;
1322
}
1323
 
1324
/* Given a value and an attribute description, return a `struct attr_value *'
1325
   that represents that value.  This is either an existing structure, if the
1326
   value has been previously encountered, or a newly-created structure.
1327
 
1328
   `insn_code' is the code of an insn whose attribute has the specified
1329
   value (-2 if not processing an insn).  We ensure that all insns for
1330
   a given value have the same number of alternatives if the value checks
1331
   alternatives.  */
1332
 
1333
static struct attr_value *
1334
get_attr_value (rtx value, struct attr_desc *attr, int insn_code)
1335
{
1336
  struct attr_value *av;
1337
  int num_alt = 0;
1338
 
1339
  value = make_canonical (attr, value);
1340
  if (compares_alternatives_p (value))
1341
    {
1342
      if (insn_code < 0 || insn_alternatives == NULL)
1343
        fatal ("(eq_attr \"alternatives\" ...) used in non-insn context");
1344
      else
1345
        num_alt = insn_alternatives[insn_code];
1346
    }
1347
 
1348
  for (av = attr->first_value; av; av = av->next)
1349
    if (rtx_equal_p (value, av->value)
1350
        && (num_alt == 0 || av->first_insn == NULL
1351
            || insn_alternatives[av->first_insn->def->insn_code]))
1352
      return av;
1353
 
1354
  av = oballoc (sizeof (struct attr_value));
1355
  av->value = value;
1356
  av->next = attr->first_value;
1357
  attr->first_value = av;
1358
  av->first_insn = NULL;
1359
  av->num_insns = 0;
1360
  av->has_asm_insn = 0;
1361
 
1362
  return av;
1363
}
1364
 
1365
/* After all DEFINE_DELAYs have been read in, create internal attributes
1366
   to generate the required routines.
1367
 
1368
   First, we compute the number of delay slots for each insn (as a COND of
1369
   each of the test expressions in DEFINE_DELAYs).  Then, if more than one
1370
   delay type is specified, we compute a similar function giving the
1371
   DEFINE_DELAY ordinal for each insn.
1372
 
1373
   Finally, for each [DEFINE_DELAY, slot #] pair, we compute an attribute that
1374
   tells whether a given insn can be in that delay slot.
1375
 
1376
   Normal attribute filling and optimization expands these to contain the
1377
   information needed to handle delay slots.  */
1378
 
1379
static void
1380
expand_delays (void)
1381
{
1382
  struct delay_desc *delay;
1383
  rtx condexp;
1384
  rtx newexp;
1385
  int i;
1386
  char *p;
1387
 
1388
  /* First, generate data for `num_delay_slots' function.  */
1389
 
1390
  condexp = rtx_alloc (COND);
1391
  XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
1392
  XEXP (condexp, 1) = make_numeric_value (0);
1393
 
1394
  for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
1395
    {
1396
      XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
1397
      XVECEXP (condexp, 0, i + 1)
1398
        = make_numeric_value (XVECLEN (delay->def, 1) / 3);
1399
    }
1400
 
1401
  make_internal_attr (num_delay_slots_str, condexp, ATTR_NONE);
1402
 
1403
  /* If more than one delay type, do the same for computing the delay type.  */
1404
  if (num_delays > 1)
1405
    {
1406
      condexp = rtx_alloc (COND);
1407
      XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
1408
      XEXP (condexp, 1) = make_numeric_value (0);
1409
 
1410
      for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
1411
        {
1412
          XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
1413
          XVECEXP (condexp, 0, i + 1) = make_numeric_value (delay->num);
1414
        }
1415
 
1416
      make_internal_attr (delay_type_str, condexp, ATTR_SPECIAL);
1417
    }
1418
 
1419
  /* For each delay possibility and delay slot, compute an eligibility
1420
     attribute for non-annulled insns and for each type of annulled (annul
1421
     if true and annul if false).  */
1422
  for (delay = delays; delay; delay = delay->next)
1423
    {
1424
      for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
1425
        {
1426
          condexp = XVECEXP (delay->def, 1, i);
1427
          if (condexp == 0)
1428
            condexp = false_rtx;
1429
          newexp = attr_rtx (IF_THEN_ELSE, condexp,
1430
                             make_numeric_value (1), make_numeric_value (0));
1431
 
1432
          p = attr_printf (sizeof "*delay__" + MAX_DIGITS * 2,
1433
                           "*delay_%d_%d", delay->num, i / 3);
1434
          make_internal_attr (p, newexp, ATTR_SPECIAL);
1435
 
1436
          if (have_annul_true)
1437
            {
1438
              condexp = XVECEXP (delay->def, 1, i + 1);
1439
              if (condexp == 0) condexp = false_rtx;
1440
              newexp = attr_rtx (IF_THEN_ELSE, condexp,
1441
                                 make_numeric_value (1),
1442
                                 make_numeric_value (0));
1443
              p = attr_printf (sizeof "*annul_true__" + MAX_DIGITS * 2,
1444
                               "*annul_true_%d_%d", delay->num, i / 3);
1445
              make_internal_attr (p, newexp, ATTR_SPECIAL);
1446
            }
1447
 
1448
          if (have_annul_false)
1449
            {
1450
              condexp = XVECEXP (delay->def, 1, i + 2);
1451
              if (condexp == 0) condexp = false_rtx;
1452
              newexp = attr_rtx (IF_THEN_ELSE, condexp,
1453
                                 make_numeric_value (1),
1454
                                 make_numeric_value (0));
1455
              p = attr_printf (sizeof "*annul_false__" + MAX_DIGITS * 2,
1456
                               "*annul_false_%d_%d", delay->num, i / 3);
1457
              make_internal_attr (p, newexp, ATTR_SPECIAL);
1458
            }
1459
        }
1460
    }
1461
}
1462
 
1463
/* Once all attributes and insns have been read and checked, we construct for
1464
   each attribute value a list of all the insns that have that value for
1465
   the attribute.  */
1466
 
1467
static void
1468
fill_attr (struct attr_desc *attr)
1469
{
1470
  struct attr_value *av;
1471
  struct insn_ent *ie;
1472
  struct insn_def *id;
1473
  int i;
1474
  rtx value;
1475
 
1476
  /* Don't fill constant attributes.  The value is independent of
1477
     any particular insn.  */
1478
  if (attr->is_const)
1479
    return;
1480
 
1481
  for (id = defs; id; id = id->next)
1482
    {
1483
      /* If no value is specified for this insn for this attribute, use the
1484
         default.  */
1485
      value = NULL;
1486
      if (XVEC (id->def, id->vec_idx))
1487
        for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
1488
          if (! strcmp_check (XSTR (XEXP (XVECEXP (id->def, id->vec_idx, i), 0), 0),
1489
                              attr->name))
1490
            value = XEXP (XVECEXP (id->def, id->vec_idx, i), 1);
1491
 
1492
      if (value == NULL)
1493
        av = attr->default_val;
1494
      else
1495
        av = get_attr_value (value, attr, id->insn_code);
1496
 
1497
      ie = oballoc (sizeof (struct insn_ent));
1498
      ie->def = id;
1499
      insert_insn_ent (av, ie);
1500
    }
1501
}
1502
 
1503
/* Given an expression EXP, see if it is a COND or IF_THEN_ELSE that has a
1504
   test that checks relative positions of insns (uses MATCH_DUP or PC).
1505
   If so, replace it with what is obtained by passing the expression to
1506
   ADDRESS_FN.  If not but it is a COND or IF_THEN_ELSE, call this routine
1507
   recursively on each value (including the default value).  Otherwise,
1508
   return the value returned by NO_ADDRESS_FN applied to EXP.  */
1509
 
1510
static rtx
1511
substitute_address (rtx exp, rtx (*no_address_fn) (rtx),
1512
                    rtx (*address_fn) (rtx))
1513
{
1514
  int i;
1515
  rtx newexp;
1516
 
1517
  if (GET_CODE (exp) == COND)
1518
    {
1519
      /* See if any tests use addresses.  */
1520
      address_used = 0;
1521
      for (i = 0; i < XVECLEN (exp, 0); i += 2)
1522
        walk_attr_value (XVECEXP (exp, 0, i));
1523
 
1524
      if (address_used)
1525
        return (*address_fn) (exp);
1526
 
1527
      /* Make a new copy of this COND, replacing each element.  */
1528
      newexp = rtx_alloc (COND);
1529
      XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0));
1530
      for (i = 0; i < XVECLEN (exp, 0); i += 2)
1531
        {
1532
          XVECEXP (newexp, 0, i) = XVECEXP (exp, 0, i);
1533
          XVECEXP (newexp, 0, i + 1)
1534
            = substitute_address (XVECEXP (exp, 0, i + 1),
1535
                                  no_address_fn, address_fn);
1536
        }
1537
 
1538
      XEXP (newexp, 1) = substitute_address (XEXP (exp, 1),
1539
                                             no_address_fn, address_fn);
1540
 
1541
      return newexp;
1542
    }
1543
 
1544
  else if (GET_CODE (exp) == IF_THEN_ELSE)
1545
    {
1546
      address_used = 0;
1547
      walk_attr_value (XEXP (exp, 0));
1548
      if (address_used)
1549
        return (*address_fn) (exp);
1550
 
1551
      return attr_rtx (IF_THEN_ELSE,
1552
                       substitute_address (XEXP (exp, 0),
1553
                                           no_address_fn, address_fn),
1554
                       substitute_address (XEXP (exp, 1),
1555
                                           no_address_fn, address_fn),
1556
                       substitute_address (XEXP (exp, 2),
1557
                                           no_address_fn, address_fn));
1558
    }
1559
 
1560
  return (*no_address_fn) (exp);
1561
}
1562
 
1563
/* Make new attributes from the `length' attribute.  The following are made,
1564
   each corresponding to a function called from `shorten_branches' or
1565
   `get_attr_length':
1566
 
1567
   *insn_default_length         This is the length of the insn to be returned
1568
                                by `get_attr_length' before `shorten_branches'
1569
                                has been called.  In each case where the length
1570
                                depends on relative addresses, the largest
1571
                                possible is used.  This routine is also used
1572
                                to compute the initial size of the insn.
1573
 
1574
   *insn_variable_length_p      This returns 1 if the insn's length depends
1575
                                on relative addresses, zero otherwise.
1576
 
1577
   *insn_current_length         This is only called when it is known that the
1578
                                insn has a variable length and returns the
1579
                                current length, based on relative addresses.
1580
  */
1581
 
1582
static void
1583
make_length_attrs (void)
1584
{
1585
  static const char *new_names[] =
1586
    {
1587
      "*insn_default_length",
1588
      "*insn_min_length",
1589
      "*insn_variable_length_p",
1590
      "*insn_current_length"
1591
    };
1592
  static rtx (*const no_address_fn[]) (rtx)
1593
    = {identity_fn,identity_fn, zero_fn, zero_fn};
1594
  static rtx (*const address_fn[]) (rtx)
1595
    = {max_fn, min_fn, one_fn, identity_fn};
1596
  size_t i;
1597
  struct attr_desc *length_attr, *new_attr;
1598
  struct attr_value *av, *new_av;
1599
  struct insn_ent *ie, *new_ie;
1600
 
1601
  /* See if length attribute is defined.  If so, it must be numeric.  Make
1602
     it special so we don't output anything for it.  */
1603
  length_attr = find_attr (&length_str, 0);
1604
  if (length_attr == 0)
1605
    return;
1606
 
1607
  if (! length_attr->is_numeric)
1608
    fatal ("length attribute must be numeric");
1609
 
1610
  length_attr->is_const = 0;
1611
  length_attr->is_special = 1;
1612
 
1613
  /* Make each new attribute, in turn.  */
1614
  for (i = 0; i < ARRAY_SIZE (new_names); i++)
1615
    {
1616
      make_internal_attr (new_names[i],
1617
                          substitute_address (length_attr->default_val->value,
1618
                                              no_address_fn[i], address_fn[i]),
1619
                          ATTR_NONE);
1620
      new_attr = find_attr (&new_names[i], 0);
1621
      for (av = length_attr->first_value; av; av = av->next)
1622
        for (ie = av->first_insn; ie; ie = ie->next)
1623
          {
1624
            new_av = get_attr_value (substitute_address (av->value,
1625
                                                         no_address_fn[i],
1626
                                                         address_fn[i]),
1627
                                     new_attr, ie->def->insn_code);
1628
            new_ie = oballoc (sizeof (struct insn_ent));
1629
            new_ie->def = ie->def;
1630
            insert_insn_ent (new_av, new_ie);
1631
          }
1632
    }
1633
}
1634
 
1635
/* Utility functions called from above routine.  */
1636
 
1637
static rtx
1638
identity_fn (rtx exp)
1639
{
1640
  return exp;
1641
}
1642
 
1643
static rtx
1644
zero_fn (rtx exp ATTRIBUTE_UNUSED)
1645
{
1646
  return make_numeric_value (0);
1647
}
1648
 
1649
static rtx
1650
one_fn (rtx exp ATTRIBUTE_UNUSED)
1651
{
1652
  return make_numeric_value (1);
1653
}
1654
 
1655
static rtx
1656
max_fn (rtx exp)
1657
{
1658
  int unknown;
1659
  return make_numeric_value (max_attr_value (exp, &unknown));
1660
}
1661
 
1662
static rtx
1663
min_fn (rtx exp)
1664
{
1665
  int unknown;
1666
  return make_numeric_value (min_attr_value (exp, &unknown));
1667
}
1668
 
1669
static void
1670
write_length_unit_log (void)
1671
{
1672
  struct attr_desc *length_attr = find_attr (&length_str, 0);
1673
  struct attr_value *av;
1674
  struct insn_ent *ie;
1675
  unsigned int length_unit_log, length_or;
1676
  int unknown = 0;
1677
 
1678
  if (length_attr == 0)
1679
    return;
1680
  length_or = or_attr_value (length_attr->default_val->value, &unknown);
1681
  for (av = length_attr->first_value; av; av = av->next)
1682
    for (ie = av->first_insn; ie; ie = ie->next)
1683
      length_or |= or_attr_value (av->value, &unknown);
1684
 
1685
  if (unknown)
1686
    length_unit_log = 0;
1687
  else
1688
    {
1689
      length_or = ~length_or;
1690
      for (length_unit_log = 0; length_or & 1; length_or >>= 1)
1691
        length_unit_log++;
1692
    }
1693
  printf ("int length_unit_log = %u;\n", length_unit_log);
1694
}
1695
 
1696
/* Take a COND expression and see if any of the conditions in it can be
1697
   simplified.  If any are known true or known false for the particular insn
1698
   code, the COND can be further simplified.
1699
 
1700
   Also call ourselves on any COND operations that are values of this COND.
1701
 
1702
   We do not modify EXP; rather, we make and return a new rtx.  */
1703
 
1704
static rtx
1705
simplify_cond (rtx exp, int insn_code, int insn_index)
1706
{
1707
  int i, j;
1708
  /* We store the desired contents here,
1709
     then build a new expression if they don't match EXP.  */
1710
  rtx defval = XEXP (exp, 1);
1711
  rtx new_defval = XEXP (exp, 1);
1712
  int len = XVECLEN (exp, 0);
1713
  rtx *tests = xmalloc (len * sizeof (rtx));
1714
  int allsame = 1;
1715
  rtx ret;
1716
 
1717
  /* This lets us free all storage allocated below, if appropriate.  */
1718
  obstack_finish (rtl_obstack);
1719
 
1720
  memcpy (tests, XVEC (exp, 0)->elem, len * sizeof (rtx));
1721
 
1722
  /* See if default value needs simplification.  */
1723
  if (GET_CODE (defval) == COND)
1724
    new_defval = simplify_cond (defval, insn_code, insn_index);
1725
 
1726
  /* Simplify the subexpressions, and see what tests we can get rid of.  */
1727
 
1728
  for (i = 0; i < len; i += 2)
1729
    {
1730
      rtx newtest, newval;
1731
 
1732
      /* Simplify this test.  */
1733
      newtest = simplify_test_exp_in_temp (tests[i], insn_code, insn_index);
1734
      tests[i] = newtest;
1735
 
1736
      newval = tests[i + 1];
1737
      /* See if this value may need simplification.  */
1738
      if (GET_CODE (newval) == COND)
1739
        newval = simplify_cond (newval, insn_code, insn_index);
1740
 
1741
      /* Look for ways to delete or combine this test.  */
1742
      if (newtest == true_rtx)
1743
        {
1744
          /* If test is true, make this value the default
1745
             and discard this + any following tests.  */
1746
          len = i;
1747
          defval = tests[i + 1];
1748
          new_defval = newval;
1749
        }
1750
 
1751
      else if (newtest == false_rtx)
1752
        {
1753
          /* If test is false, discard it and its value.  */
1754
          for (j = i; j < len - 2; j++)
1755
            tests[j] = tests[j + 2];
1756
          i -= 2;
1757
          len -= 2;
1758
        }
1759
 
1760
      else if (i > 0 && attr_equal_p (newval, tests[i - 1]))
1761
        {
1762
          /* If this value and the value for the prev test are the same,
1763
             merge the tests.  */
1764
 
1765
          tests[i - 2]
1766
            = insert_right_side (IOR, tests[i - 2], newtest,
1767
                                 insn_code, insn_index);
1768
 
1769
          /* Delete this test/value.  */
1770
          for (j = i; j < len - 2; j++)
1771
            tests[j] = tests[j + 2];
1772
          len -= 2;
1773
          i -= 2;
1774
        }
1775
 
1776
      else
1777
        tests[i + 1] = newval;
1778
    }
1779
 
1780
  /* If the last test in a COND has the same value
1781
     as the default value, that test isn't needed.  */
1782
 
1783
  while (len > 0 && attr_equal_p (tests[len - 1], new_defval))
1784
    len -= 2;
1785
 
1786
  /* See if we changed anything.  */
1787
  if (len != XVECLEN (exp, 0) || new_defval != XEXP (exp, 1))
1788
    allsame = 0;
1789
  else
1790
    for (i = 0; i < len; i++)
1791
      if (! attr_equal_p (tests[i], XVECEXP (exp, 0, i)))
1792
        {
1793
          allsame = 0;
1794
          break;
1795
        }
1796
 
1797
  if (len == 0)
1798
    {
1799
      if (GET_CODE (defval) == COND)
1800
        ret = simplify_cond (defval, insn_code, insn_index);
1801
      else
1802
        ret = defval;
1803
    }
1804
  else if (allsame)
1805
    ret = exp;
1806
  else
1807
    {
1808
      rtx newexp = rtx_alloc (COND);
1809
 
1810
      XVEC (newexp, 0) = rtvec_alloc (len);
1811
      memcpy (XVEC (newexp, 0)->elem, tests, len * sizeof (rtx));
1812
      XEXP (newexp, 1) = new_defval;
1813
      ret = newexp;
1814
    }
1815
  free (tests);
1816
  return ret;
1817
}
1818
 
1819
/* Remove an insn entry from an attribute value.  */
1820
 
1821
static void
1822
remove_insn_ent (struct attr_value *av, struct insn_ent *ie)
1823
{
1824
  struct insn_ent *previe;
1825
 
1826
  if (av->first_insn == ie)
1827
    av->first_insn = ie->next;
1828
  else
1829
    {
1830
      for (previe = av->first_insn; previe->next != ie; previe = previe->next)
1831
        ;
1832
      previe->next = ie->next;
1833
    }
1834
 
1835
  av->num_insns--;
1836
  if (ie->def->insn_code == -1)
1837
    av->has_asm_insn = 0;
1838
 
1839
  num_insn_ents--;
1840
}
1841
 
1842
/* Insert an insn entry in an attribute value list.  */
1843
 
1844
static void
1845
insert_insn_ent (struct attr_value *av, struct insn_ent *ie)
1846
{
1847
  ie->next = av->first_insn;
1848
  av->first_insn = ie;
1849
  av->num_insns++;
1850
  if (ie->def->insn_code == -1)
1851
    av->has_asm_insn = 1;
1852
 
1853
  num_insn_ents++;
1854
}
1855
 
1856
/* This is a utility routine to take an expression that is a tree of either
1857
   AND or IOR expressions and insert a new term.  The new term will be
1858
   inserted at the right side of the first node whose code does not match
1859
   the root.  A new node will be created with the root's code.  Its left
1860
   side will be the old right side and its right side will be the new
1861
   term.
1862
 
1863
   If the `term' is itself a tree, all its leaves will be inserted.  */
1864
 
1865
static rtx
1866
insert_right_side (enum rtx_code code, rtx exp, rtx term, int insn_code, int insn_index)
1867
{
1868
  rtx newexp;
1869
 
1870
  /* Avoid consing in some special cases.  */
1871
  if (code == AND && term == true_rtx)
1872
    return exp;
1873
  if (code == AND && term == false_rtx)
1874
    return false_rtx;
1875
  if (code == AND && exp == true_rtx)
1876
    return term;
1877
  if (code == AND && exp == false_rtx)
1878
    return false_rtx;
1879
  if (code == IOR && term == true_rtx)
1880
    return true_rtx;
1881
  if (code == IOR && term == false_rtx)
1882
    return exp;
1883
  if (code == IOR && exp == true_rtx)
1884
    return true_rtx;
1885
  if (code == IOR && exp == false_rtx)
1886
    return term;
1887
  if (attr_equal_p (exp, term))
1888
    return exp;
1889
 
1890
  if (GET_CODE (term) == code)
1891
    {
1892
      exp = insert_right_side (code, exp, XEXP (term, 0),
1893
                               insn_code, insn_index);
1894
      exp = insert_right_side (code, exp, XEXP (term, 1),
1895
                               insn_code, insn_index);
1896
 
1897
      return exp;
1898
    }
1899
 
1900
  if (GET_CODE (exp) == code)
1901
    {
1902
      rtx new = insert_right_side (code, XEXP (exp, 1),
1903
                                   term, insn_code, insn_index);
1904
      if (new != XEXP (exp, 1))
1905
        /* Make a copy of this expression and call recursively.  */
1906
        newexp = attr_rtx (code, XEXP (exp, 0), new);
1907
      else
1908
        newexp = exp;
1909
    }
1910
  else
1911
    {
1912
      /* Insert the new term.  */
1913
      newexp = attr_rtx (code, exp, term);
1914
    }
1915
 
1916
  return simplify_test_exp_in_temp (newexp, insn_code, insn_index);
1917
}
1918
 
1919
/* If we have an expression which AND's a bunch of
1920
        (not (eq_attrq "alternative" "n"))
1921
   terms, we may have covered all or all but one of the possible alternatives.
1922
   If so, we can optimize.  Similarly for IOR's of EQ_ATTR.
1923
 
1924
   This routine is passed an expression and either AND or IOR.  It returns a
1925
   bitmask indicating which alternatives are mentioned within EXP.  */
1926
 
1927
static int
1928
compute_alternative_mask (rtx exp, enum rtx_code code)
1929
{
1930
  const char *string;
1931
  if (GET_CODE (exp) == code)
1932
    return compute_alternative_mask (XEXP (exp, 0), code)
1933
           | compute_alternative_mask (XEXP (exp, 1), code);
1934
 
1935
  else if (code == AND && GET_CODE (exp) == NOT
1936
           && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
1937
           && XSTR (XEXP (exp, 0), 0) == alternative_name)
1938
    string = XSTR (XEXP (exp, 0), 1);
1939
 
1940
  else if (code == IOR && GET_CODE (exp) == EQ_ATTR
1941
           && XSTR (exp, 0) == alternative_name)
1942
    string = XSTR (exp, 1);
1943
 
1944
  else if (GET_CODE (exp) == EQ_ATTR_ALT)
1945
    {
1946
      if (code == AND && XINT (exp, 1))
1947
        return XINT (exp, 0);
1948
 
1949
      if (code == IOR && !XINT (exp, 1))
1950
        return XINT (exp, 0);
1951
 
1952
      return 0;
1953
    }
1954
  else
1955
    return 0;
1956
 
1957
  if (string[1] == 0)
1958
    return 1 << (string[0] - '0');
1959
  return 1 << atoi (string);
1960
}
1961
 
1962
/* Given I, a single-bit mask, return RTX to compare the `alternative'
1963
   attribute with the value represented by that bit.  */
1964
 
1965
static rtx
1966
make_alternative_compare (int mask)
1967
{
1968
  return mk_attr_alt (mask);
1969
}
1970
 
1971
/* If we are processing an (eq_attr "attr" "value") test, we find the value
1972
   of "attr" for this insn code.  From that value, we can compute a test
1973
   showing when the EQ_ATTR will be true.  This routine performs that
1974
   computation.  If a test condition involves an address, we leave the EQ_ATTR
1975
   intact because addresses are only valid for the `length' attribute.
1976
 
1977
   EXP is the EQ_ATTR expression and VALUE is the value of that attribute
1978
   for the insn corresponding to INSN_CODE and INSN_INDEX.  */
1979
 
1980
static rtx
1981
evaluate_eq_attr (rtx exp, rtx value, int insn_code, int insn_index)
1982
{
1983
  rtx orexp, andexp;
1984
  rtx right;
1985
  rtx newexp;
1986
  int i;
1987
 
1988
  switch (GET_CODE (value))
1989
    {
1990
    case CONST_STRING:
1991
      if (! strcmp_check (XSTR (value, 0), XSTR (exp, 1)))
1992
        newexp = true_rtx;
1993
      else
1994
        newexp = false_rtx;
1995
      break;
1996
 
1997
    case SYMBOL_REF:
1998
      {
1999
        char *p;
2000
        char string[256];
2001
 
2002
        gcc_assert (GET_CODE (exp) == EQ_ATTR);
2003
        gcc_assert (strlen (XSTR (exp, 0)) + strlen (XSTR (exp, 1)) + 2
2004
                    <= 256);
2005
 
2006
        strcpy (string, XSTR (exp, 0));
2007
        strcat (string, "_");
2008
        strcat (string, XSTR (exp, 1));
2009
        for (p = string; *p; p++)
2010
          *p = TOUPPER (*p);
2011
 
2012
        newexp = attr_rtx (EQ, value,
2013
                           attr_rtx (SYMBOL_REF,
2014
                                     DEF_ATTR_STRING (string)));
2015
        break;
2016
      }
2017
 
2018
    case COND:
2019
      /* We construct an IOR of all the cases for which the
2020
         requested attribute value is present.  Since we start with
2021
         FALSE, if it is not present, FALSE will be returned.
2022
 
2023
         Each case is the AND of the NOT's of the previous conditions with the
2024
         current condition; in the default case the current condition is TRUE.
2025
 
2026
         For each possible COND value, call ourselves recursively.
2027
 
2028
         The extra TRUE and FALSE expressions will be eliminated by another
2029
         call to the simplification routine.  */
2030
 
2031
      orexp = false_rtx;
2032
      andexp = true_rtx;
2033
 
2034
      for (i = 0; i < XVECLEN (value, 0); i += 2)
2035
        {
2036
          rtx this = simplify_test_exp_in_temp (XVECEXP (value, 0, i),
2037
                                                insn_code, insn_index);
2038
 
2039
          right = insert_right_side (AND, andexp, this,
2040
                                     insn_code, insn_index);
2041
          right = insert_right_side (AND, right,
2042
                                     evaluate_eq_attr (exp,
2043
                                                       XVECEXP (value, 0,
2044
                                                                i + 1),
2045
                                                       insn_code, insn_index),
2046
                                     insn_code, insn_index);
2047
          orexp = insert_right_side (IOR, orexp, right,
2048
                                     insn_code, insn_index);
2049
 
2050
          /* Add this condition into the AND expression.  */
2051
          newexp = attr_rtx (NOT, this);
2052
          andexp = insert_right_side (AND, andexp, newexp,
2053
                                      insn_code, insn_index);
2054
        }
2055
 
2056
      /* Handle the default case.  */
2057
      right = insert_right_side (AND, andexp,
2058
                                 evaluate_eq_attr (exp, XEXP (value, 1),
2059
                                                   insn_code, insn_index),
2060
                                 insn_code, insn_index);
2061
      newexp = insert_right_side (IOR, orexp, right, insn_code, insn_index);
2062
      break;
2063
 
2064
    default:
2065
      gcc_unreachable ();
2066
    }
2067
 
2068
  /* If uses an address, must return original expression.  But set the
2069
     ATTR_IND_SIMPLIFIED_P bit so we don't try to simplify it again.  */
2070
 
2071
  address_used = 0;
2072
  walk_attr_value (newexp);
2073
 
2074
  if (address_used)
2075
    {
2076
      if (! ATTR_IND_SIMPLIFIED_P (exp))
2077
        return copy_rtx_unchanging (exp);
2078
      return exp;
2079
    }
2080
  else
2081
    return newexp;
2082
}
2083
 
2084
/* This routine is called when an AND of a term with a tree of AND's is
2085
   encountered.  If the term or its complement is present in the tree, it
2086
   can be replaced with TRUE or FALSE, respectively.
2087
 
2088
   Note that (eq_attr "att" "v1") and (eq_attr "att" "v2") cannot both
2089
   be true and hence are complementary.
2090
 
2091
   There is one special case:  If we see
2092
        (and (not (eq_attr "att" "v1"))
2093
             (eq_attr "att" "v2"))
2094
   this can be replaced by (eq_attr "att" "v2").  To do this we need to
2095
   replace the term, not anything in the AND tree.  So we pass a pointer to
2096
   the term.  */
2097
 
2098
static rtx
2099
simplify_and_tree (rtx exp, rtx *pterm, int insn_code, int insn_index)
2100
{
2101
  rtx left, right;
2102
  rtx newexp;
2103
  rtx temp;
2104
  int left_eliminates_term, right_eliminates_term;
2105
 
2106
  if (GET_CODE (exp) == AND)
2107
    {
2108
      left  = simplify_and_tree (XEXP (exp, 0), pterm, insn_code, insn_index);
2109
      right = simplify_and_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
2110
      if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2111
        {
2112
          newexp = attr_rtx (AND, left, right);
2113
 
2114
          exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2115
        }
2116
    }
2117
 
2118
  else if (GET_CODE (exp) == IOR)
2119
    {
2120
      /* For the IOR case, we do the same as above, except that we can
2121
         only eliminate `term' if both sides of the IOR would do so.  */
2122
      temp = *pterm;
2123
      left = simplify_and_tree (XEXP (exp, 0), &temp, insn_code, insn_index);
2124
      left_eliminates_term = (temp == true_rtx);
2125
 
2126
      temp = *pterm;
2127
      right = simplify_and_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
2128
      right_eliminates_term = (temp == true_rtx);
2129
 
2130
      if (left_eliminates_term && right_eliminates_term)
2131
        *pterm = true_rtx;
2132
 
2133
      if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2134
        {
2135
          newexp = attr_rtx (IOR, left, right);
2136
 
2137
          exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2138
        }
2139
    }
2140
 
2141
  /* Check for simplifications.  Do some extra checking here since this
2142
     routine is called so many times.  */
2143
 
2144
  if (exp == *pterm)
2145
    return true_rtx;
2146
 
2147
  else if (GET_CODE (exp) == NOT && XEXP (exp, 0) == *pterm)
2148
    return false_rtx;
2149
 
2150
  else if (GET_CODE (*pterm) == NOT && exp == XEXP (*pterm, 0))
2151
    return false_rtx;
2152
 
2153
  else if (GET_CODE (exp) == EQ_ATTR_ALT && GET_CODE (*pterm) == EQ_ATTR_ALT)
2154
    {
2155
      if (attr_alt_subset_p (*pterm, exp))
2156
        return true_rtx;
2157
 
2158
      if (attr_alt_subset_of_compl_p (*pterm, exp))
2159
        return false_rtx;
2160
 
2161
      if (attr_alt_subset_p (exp, *pterm))
2162
        *pterm = true_rtx;
2163
 
2164
      return exp;
2165
    }
2166
 
2167
  else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == EQ_ATTR)
2168
    {
2169
      if (XSTR (exp, 0) != XSTR (*pterm, 0))
2170
        return exp;
2171
 
2172
      if (! strcmp_check (XSTR (exp, 1), XSTR (*pterm, 1)))
2173
        return true_rtx;
2174
      else
2175
        return false_rtx;
2176
    }
2177
 
2178
  else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
2179
           && GET_CODE (XEXP (exp, 0)) == EQ_ATTR)
2180
    {
2181
      if (XSTR (*pterm, 0) != XSTR (XEXP (exp, 0), 0))
2182
        return exp;
2183
 
2184
      if (! strcmp_check (XSTR (*pterm, 1), XSTR (XEXP (exp, 0), 1)))
2185
        return false_rtx;
2186
      else
2187
        return true_rtx;
2188
    }
2189
 
2190
  else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
2191
           && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR)
2192
    {
2193
      if (XSTR (exp, 0) != XSTR (XEXP (*pterm, 0), 0))
2194
        return exp;
2195
 
2196
      if (! strcmp_check (XSTR (exp, 1), XSTR (XEXP (*pterm, 0), 1)))
2197
        return false_rtx;
2198
      else
2199
        *pterm = true_rtx;
2200
    }
2201
 
2202
  else if (GET_CODE (exp) == NOT && GET_CODE (*pterm) == NOT)
2203
    {
2204
      if (attr_equal_p (XEXP (exp, 0), XEXP (*pterm, 0)))
2205
        return true_rtx;
2206
    }
2207
 
2208
  else if (GET_CODE (exp) == NOT)
2209
    {
2210
      if (attr_equal_p (XEXP (exp, 0), *pterm))
2211
        return false_rtx;
2212
    }
2213
 
2214
  else if (GET_CODE (*pterm) == NOT)
2215
    {
2216
      if (attr_equal_p (XEXP (*pterm, 0), exp))
2217
        return false_rtx;
2218
    }
2219
 
2220
  else if (attr_equal_p (exp, *pterm))
2221
    return true_rtx;
2222
 
2223
  return exp;
2224
}
2225
 
2226
/* Similar to `simplify_and_tree', but for IOR trees.  */
2227
 
2228
static rtx
2229
simplify_or_tree (rtx exp, rtx *pterm, int insn_code, int insn_index)
2230
{
2231
  rtx left, right;
2232
  rtx newexp;
2233
  rtx temp;
2234
  int left_eliminates_term, right_eliminates_term;
2235
 
2236
  if (GET_CODE (exp) == IOR)
2237
    {
2238
      left  = simplify_or_tree (XEXP (exp, 0), pterm, insn_code, insn_index);
2239
      right = simplify_or_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
2240
      if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2241
        {
2242
          newexp = attr_rtx (GET_CODE (exp), left, right);
2243
 
2244
          exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2245
        }
2246
    }
2247
 
2248
  else if (GET_CODE (exp) == AND)
2249
    {
2250
      /* For the AND case, we do the same as above, except that we can
2251
         only eliminate `term' if both sides of the AND would do so.  */
2252
      temp = *pterm;
2253
      left = simplify_or_tree (XEXP (exp, 0), &temp, insn_code, insn_index);
2254
      left_eliminates_term = (temp == false_rtx);
2255
 
2256
      temp = *pterm;
2257
      right = simplify_or_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
2258
      right_eliminates_term = (temp == false_rtx);
2259
 
2260
      if (left_eliminates_term && right_eliminates_term)
2261
        *pterm = false_rtx;
2262
 
2263
      if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2264
        {
2265
          newexp = attr_rtx (GET_CODE (exp), left, right);
2266
 
2267
          exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2268
        }
2269
    }
2270
 
2271
  if (attr_equal_p (exp, *pterm))
2272
    return false_rtx;
2273
 
2274
  else if (GET_CODE (exp) == NOT && attr_equal_p (XEXP (exp, 0), *pterm))
2275
    return true_rtx;
2276
 
2277
  else if (GET_CODE (*pterm) == NOT && attr_equal_p (XEXP (*pterm, 0), exp))
2278
    return true_rtx;
2279
 
2280
  else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
2281
           && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
2282
           && XSTR (*pterm, 0) == XSTR (XEXP (exp, 0), 0))
2283
    *pterm = false_rtx;
2284
 
2285
  else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
2286
           && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR
2287
           && XSTR (exp, 0) == XSTR (XEXP (*pterm, 0), 0))
2288
    return false_rtx;
2289
 
2290
  return exp;
2291
}
2292
 
2293
/* Compute approximate cost of the expression.  Used to decide whether
2294
   expression is cheap enough for inline.  */
2295
static int
2296
attr_rtx_cost (rtx x)
2297
{
2298
  int cost = 0;
2299
  enum rtx_code code;
2300
  if (!x)
2301
    return 0;
2302
  code = GET_CODE (x);
2303
  switch (code)
2304
    {
2305
    case MATCH_OPERAND:
2306
      if (XSTR (x, 1)[0])
2307
        return 10;
2308
      else
2309
        return 0;
2310
 
2311
    case EQ_ATTR_ALT:
2312
      return 0;
2313
 
2314
    case EQ_ATTR:
2315
      /* Alternatives don't result into function call.  */
2316
      if (!strcmp_check (XSTR (x, 0), alternative_name))
2317
        return 0;
2318
      else
2319
        return 5;
2320
    default:
2321
      {
2322
        int i, j;
2323
        const char *fmt = GET_RTX_FORMAT (code);
2324
        for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
2325
          {
2326
            switch (fmt[i])
2327
              {
2328
              case 'V':
2329
              case 'E':
2330
                for (j = 0; j < XVECLEN (x, i); j++)
2331
                  cost += attr_rtx_cost (XVECEXP (x, i, j));
2332
                break;
2333
              case 'e':
2334
                cost += attr_rtx_cost (XEXP (x, i));
2335
                break;
2336
              }
2337
          }
2338
      }
2339
      break;
2340
    }
2341
  return cost;
2342
}
2343
 
2344
/* Simplify test expression and use temporary obstack in order to avoid
2345
   memory bloat.  Use ATTR_IND_SIMPLIFIED to avoid unnecessary simplifications
2346
   and avoid unnecessary copying if possible.  */
2347
 
2348
static rtx
2349
simplify_test_exp_in_temp (rtx exp, int insn_code, int insn_index)
2350
{
2351
  rtx x;
2352
  struct obstack *old;
2353
  if (ATTR_IND_SIMPLIFIED_P (exp))
2354
    return exp;
2355
  old = rtl_obstack;
2356
  rtl_obstack = temp_obstack;
2357
  x = simplify_test_exp (exp, insn_code, insn_index);
2358
  rtl_obstack = old;
2359
  if (x == exp || rtl_obstack == temp_obstack)
2360
    return x;
2361
  return attr_copy_rtx (x);
2362
}
2363
 
2364
/* Returns true if S1 is a subset of S2.  */
2365
 
2366
static bool
2367
attr_alt_subset_p (rtx s1, rtx s2)
2368
{
2369
  switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
2370
    {
2371
    case (0 << 1) | 0:
2372
      return !(XINT (s1, 0) &~ XINT (s2, 0));
2373
 
2374
    case (0 << 1) | 1:
2375
      return !(XINT (s1, 0) & XINT (s2, 0));
2376
 
2377
    case (1 << 1) | 0:
2378
      return false;
2379
 
2380
    case (1 << 1) | 1:
2381
      return !(XINT (s2, 0) &~ XINT (s1, 0));
2382
 
2383
    default:
2384
      gcc_unreachable ();
2385
    }
2386
}
2387
 
2388
/* Returns true if S1 is a subset of complement of S2.  */
2389
 
2390
static bool
2391
attr_alt_subset_of_compl_p (rtx s1, rtx s2)
2392
{
2393
  switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
2394
    {
2395
    case (0 << 1) | 0:
2396
      return !(XINT (s1, 0) & XINT (s2, 0));
2397
 
2398
    case (0 << 1) | 1:
2399
      return !(XINT (s1, 0) & ~XINT (s2, 0));
2400
 
2401
    case (1 << 1) | 0:
2402
      return !(XINT (s2, 0) &~ XINT (s1, 0));
2403
 
2404
    case (1 << 1) | 1:
2405
      return false;
2406
 
2407
    default:
2408
      gcc_unreachable ();
2409
    }
2410
}
2411
 
2412
/* Return EQ_ATTR_ALT expression representing intersection of S1 and S2.  */
2413
 
2414
static rtx
2415
attr_alt_intersection (rtx s1, rtx s2)
2416
{
2417
  rtx result = rtx_alloc (EQ_ATTR_ALT);
2418
 
2419
  switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
2420
    {
2421
    case (0 << 1) | 0:
2422
      XINT (result, 0) = XINT (s1, 0) & XINT (s2, 0);
2423
      break;
2424
    case (0 << 1) | 1:
2425
      XINT (result, 0) = XINT (s1, 0) & ~XINT (s2, 0);
2426
      break;
2427
    case (1 << 1) | 0:
2428
      XINT (result, 0) = XINT (s2, 0) & ~XINT (s1, 0);
2429
      break;
2430
    case (1 << 1) | 1:
2431
      XINT (result, 0) = XINT (s1, 0) | XINT (s2, 0);
2432
      break;
2433
    default:
2434
      gcc_unreachable ();
2435
    }
2436
  XINT (result, 1) = XINT (s1, 1) & XINT (s2, 1);
2437
 
2438
  return result;
2439
}
2440
 
2441
/* Return EQ_ATTR_ALT expression representing union of S1 and S2.  */
2442
 
2443
static rtx
2444
attr_alt_union (rtx s1, rtx s2)
2445
{
2446
  rtx result = rtx_alloc (EQ_ATTR_ALT);
2447
 
2448
  switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
2449
    {
2450
    case (0 << 1) | 0:
2451
      XINT (result, 0) = XINT (s1, 0) | XINT (s2, 0);
2452
      break;
2453
    case (0 << 1) | 1:
2454
      XINT (result, 0) = XINT (s2, 0) & ~XINT (s1, 0);
2455
      break;
2456
    case (1 << 1) | 0:
2457
      XINT (result, 0) = XINT (s1, 0) & ~XINT (s2, 0);
2458
      break;
2459
    case (1 << 1) | 1:
2460
      XINT (result, 0) = XINT (s1, 0) & XINT (s2, 0);
2461
      break;
2462
    default:
2463
      gcc_unreachable ();
2464
    }
2465
 
2466
  XINT (result, 1) = XINT (s1, 1) | XINT (s2, 1);
2467
  return result;
2468
}
2469
 
2470
/* Return EQ_ATTR_ALT expression representing complement of S.  */
2471
 
2472
static rtx
2473
attr_alt_complement (rtx s)
2474
{
2475
  rtx result = rtx_alloc (EQ_ATTR_ALT);
2476
 
2477
  XINT (result, 0) = XINT (s, 0);
2478
  XINT (result, 1) = 1 - XINT (s, 1);
2479
 
2480
  return result;
2481
}
2482
 
2483
/* Return EQ_ATTR_ALT expression representing set containing elements set
2484
   in E.  */
2485
 
2486
static rtx
2487
mk_attr_alt (int e)
2488
{
2489
  rtx result = rtx_alloc (EQ_ATTR_ALT);
2490
 
2491
  XINT (result, 0) = e;
2492
  XINT (result, 1) = 0;
2493
 
2494
  return result;
2495
}
2496
 
2497
/* Given an expression, see if it can be simplified for a particular insn
2498
   code based on the values of other attributes being tested.  This can
2499
   eliminate nested get_attr_... calls.
2500
 
2501
   Note that if an endless recursion is specified in the patterns, the
2502
   optimization will loop.  However, it will do so in precisely the cases where
2503
   an infinite recursion loop could occur during compilation.  It's better that
2504
   it occurs here!  */
2505
 
2506
static rtx
2507
simplify_test_exp (rtx exp, int insn_code, int insn_index)
2508
{
2509
  rtx left, right;
2510
  struct attr_desc *attr;
2511
  struct attr_value *av;
2512
  struct insn_ent *ie;
2513
  int i;
2514
  rtx newexp = exp;
2515
  bool left_alt, right_alt;
2516
 
2517
  /* Don't re-simplify something we already simplified.  */
2518
  if (ATTR_IND_SIMPLIFIED_P (exp) || ATTR_CURR_SIMPLIFIED_P (exp))
2519
    return exp;
2520
 
2521
  switch (GET_CODE (exp))
2522
    {
2523
    case AND:
2524
      left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
2525
      if (left == false_rtx)
2526
        return false_rtx;
2527
      right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
2528
      if (right == false_rtx)
2529
        return false_rtx;
2530
 
2531
      if (GET_CODE (left) == EQ_ATTR_ALT
2532
          && GET_CODE (right) == EQ_ATTR_ALT)
2533
        {
2534
          exp = attr_alt_intersection (left, right);
2535
          return simplify_test_exp (exp, insn_code, insn_index);
2536
        }
2537
 
2538
      /* If either side is an IOR and we have (eq_attr "alternative" ..")
2539
         present on both sides, apply the distributive law since this will
2540
         yield simplifications.  */
2541
      if ((GET_CODE (left) == IOR || GET_CODE (right) == IOR)
2542
          && compute_alternative_mask (left, IOR)
2543
          && compute_alternative_mask (right, IOR))
2544
        {
2545
          if (GET_CODE (left) == IOR)
2546
            {
2547
              rtx tem = left;
2548
              left = right;
2549
              right = tem;
2550
            }
2551
 
2552
          newexp = attr_rtx (IOR,
2553
                             attr_rtx (AND, left, XEXP (right, 0)),
2554
                             attr_rtx (AND, left, XEXP (right, 1)));
2555
 
2556
          return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2557
        }
2558
 
2559
      /* Try with the term on both sides.  */
2560
      right = simplify_and_tree (right, &left, insn_code, insn_index);
2561
      if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
2562
        left = simplify_and_tree (left, &right, insn_code, insn_index);
2563
 
2564
      if (left == false_rtx || right == false_rtx)
2565
        return false_rtx;
2566
      else if (left == true_rtx)
2567
        {
2568
          return right;
2569
        }
2570
      else if (right == true_rtx)
2571
        {
2572
          return left;
2573
        }
2574
      /* See if all or all but one of the insn's alternatives are specified
2575
         in this tree.  Optimize if so.  */
2576
 
2577
      if (GET_CODE (left) == NOT)
2578
        left_alt = (GET_CODE (XEXP (left, 0)) == EQ_ATTR
2579
                    && XSTR (XEXP (left, 0), 0) == alternative_name);
2580
      else
2581
        left_alt = (GET_CODE (left) == EQ_ATTR_ALT
2582
                    && XINT (left, 1));
2583
 
2584
      if (GET_CODE (right) == NOT)
2585
        right_alt = (GET_CODE (XEXP (right, 0)) == EQ_ATTR
2586
                     && XSTR (XEXP (right, 0), 0) == alternative_name);
2587
      else
2588
        right_alt = (GET_CODE (right) == EQ_ATTR_ALT
2589
                     && XINT (right, 1));
2590
 
2591
      if (insn_code >= 0
2592
          && (GET_CODE (left) == AND
2593
              || left_alt
2594
              || GET_CODE (right) == AND
2595
              || right_alt))
2596
        {
2597
          i = compute_alternative_mask (exp, AND);
2598
          if (i & ~insn_alternatives[insn_code])
2599
            fatal ("invalid alternative specified for pattern number %d",
2600
                   insn_index);
2601
 
2602
          /* If all alternatives are excluded, this is false.  */
2603
          i ^= insn_alternatives[insn_code];
2604
          if (i == 0)
2605
            return false_rtx;
2606
          else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
2607
            {
2608
              /* If just one excluded, AND a comparison with that one to the
2609
                 front of the tree.  The others will be eliminated by
2610
                 optimization.  We do not want to do this if the insn has one
2611
                 alternative and we have tested none of them!  */
2612
              left = make_alternative_compare (i);
2613
              right = simplify_and_tree (exp, &left, insn_code, insn_index);
2614
              newexp = attr_rtx (AND, left, right);
2615
 
2616
              return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2617
            }
2618
        }
2619
 
2620
      if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2621
        {
2622
          newexp = attr_rtx (AND, left, right);
2623
          return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2624
        }
2625
      break;
2626
 
2627
    case IOR:
2628
      left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
2629
      if (left == true_rtx)
2630
        return true_rtx;
2631
      right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
2632
      if (right == true_rtx)
2633
        return true_rtx;
2634
 
2635
      if (GET_CODE (left) == EQ_ATTR_ALT
2636
          && GET_CODE (right) == EQ_ATTR_ALT)
2637
        {
2638
          exp = attr_alt_union (left, right);
2639
          return simplify_test_exp (exp, insn_code, insn_index);
2640
        }
2641
 
2642
      right = simplify_or_tree (right, &left, insn_code, insn_index);
2643
      if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
2644
        left = simplify_or_tree (left, &right, insn_code, insn_index);
2645
 
2646
      if (right == true_rtx || left == true_rtx)
2647
        return true_rtx;
2648
      else if (left == false_rtx)
2649
        {
2650
          return right;
2651
        }
2652
      else if (right == false_rtx)
2653
        {
2654
          return left;
2655
        }
2656
 
2657
      /* Test for simple cases where the distributive law is useful.  I.e.,
2658
            convert (ior (and (x) (y))
2659
                         (and (x) (z)))
2660
            to      (and (x)
2661
                         (ior (y) (z)))
2662
       */
2663
 
2664
      else if (GET_CODE (left) == AND && GET_CODE (right) == AND
2665
               && attr_equal_p (XEXP (left, 0), XEXP (right, 0)))
2666
        {
2667
          newexp = attr_rtx (IOR, XEXP (left, 1), XEXP (right, 1));
2668
 
2669
          left = XEXP (left, 0);
2670
          right = newexp;
2671
          newexp = attr_rtx (AND, left, right);
2672
          return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2673
        }
2674
 
2675
      /* See if all or all but one of the insn's alternatives are specified
2676
         in this tree.  Optimize if so.  */
2677
 
2678
      else if (insn_code >= 0
2679
               && (GET_CODE (left) == IOR
2680
                   || (GET_CODE (left) == EQ_ATTR_ALT
2681
                       && !XINT (left, 1))
2682
                   || (GET_CODE (left) == EQ_ATTR
2683
                       && XSTR (left, 0) == alternative_name)
2684
                   || GET_CODE (right) == IOR
2685
                   || (GET_CODE (right) == EQ_ATTR_ALT
2686
                       && !XINT (right, 1))
2687
                   || (GET_CODE (right) == EQ_ATTR
2688
                       && XSTR (right, 0) == alternative_name)))
2689
        {
2690
          i = compute_alternative_mask (exp, IOR);
2691
          if (i & ~insn_alternatives[insn_code])
2692
            fatal ("invalid alternative specified for pattern number %d",
2693
                   insn_index);
2694
 
2695
          /* If all alternatives are included, this is true.  */
2696
          i ^= insn_alternatives[insn_code];
2697
          if (i == 0)
2698
            return true_rtx;
2699
          else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
2700
            {
2701
              /* If just one excluded, IOR a comparison with that one to the
2702
                 front of the tree.  The others will be eliminated by
2703
                 optimization.  We do not want to do this if the insn has one
2704
                 alternative and we have tested none of them!  */
2705
              left = make_alternative_compare (i);
2706
              right = simplify_and_tree (exp, &left, insn_code, insn_index);
2707
              newexp = attr_rtx (IOR, attr_rtx (NOT, left), right);
2708
 
2709
              return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2710
            }
2711
        }
2712
 
2713
      if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2714
        {
2715
          newexp = attr_rtx (IOR, left, right);
2716
          return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2717
        }
2718
      break;
2719
 
2720
    case NOT:
2721
      if (GET_CODE (XEXP (exp, 0)) == NOT)
2722
        {
2723
          left = SIMPLIFY_TEST_EXP (XEXP (XEXP (exp, 0), 0),
2724
                                    insn_code, insn_index);
2725
          return left;
2726
        }
2727
 
2728
      left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
2729
      if (GET_CODE (left) == NOT)
2730
        return XEXP (left, 0);
2731
 
2732
      if (left == false_rtx)
2733
        return true_rtx;
2734
      if (left == true_rtx)
2735
        return false_rtx;
2736
 
2737
      if (GET_CODE (left) == EQ_ATTR_ALT)
2738
        {
2739
          exp = attr_alt_complement (left);
2740
          return simplify_test_exp (exp, insn_code, insn_index);
2741
        }
2742
 
2743
      /* Try to apply De`Morgan's laws.  */
2744
      if (GET_CODE (left) == IOR)
2745
        {
2746
          newexp = attr_rtx (AND,
2747
                             attr_rtx (NOT, XEXP (left, 0)),
2748
                             attr_rtx (NOT, XEXP (left, 1)));
2749
 
2750
          newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2751
        }
2752
      else if (GET_CODE (left) == AND)
2753
        {
2754
          newexp = attr_rtx (IOR,
2755
                             attr_rtx (NOT, XEXP (left, 0)),
2756
                             attr_rtx (NOT, XEXP (left, 1)));
2757
 
2758
          newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2759
        }
2760
      else if (left != XEXP (exp, 0))
2761
        {
2762
          newexp = attr_rtx (NOT, left);
2763
        }
2764
      break;
2765
 
2766
    case EQ_ATTR_ALT:
2767
      if (!XINT (exp, 0))
2768
        return XINT (exp, 1) ? true_rtx : false_rtx;
2769
      break;
2770
 
2771
    case EQ_ATTR:
2772
      if (XSTR (exp, 0) == alternative_name)
2773
        {
2774
          newexp = mk_attr_alt (1 << atoi (XSTR (exp, 1)));
2775
          break;
2776
        }
2777
 
2778
      /* Look at the value for this insn code in the specified attribute.
2779
         We normally can replace this comparison with the condition that
2780
         would give this insn the values being tested for.  */
2781
      if (insn_code >= 0
2782
          && (attr = find_attr (&XSTR (exp, 0), 0)) != NULL)
2783
        for (av = attr->first_value; av; av = av->next)
2784
          for (ie = av->first_insn; ie; ie = ie->next)
2785
            if (ie->def->insn_code == insn_code)
2786
              {
2787
                rtx x;
2788
                x = evaluate_eq_attr (exp, av->value, insn_code, insn_index);
2789
                x = SIMPLIFY_TEST_EXP (x, insn_code, insn_index);
2790
                if (attr_rtx_cost(x) < 20)
2791
                  return x;
2792
              }
2793
      break;
2794
 
2795
    default:
2796
      break;
2797
    }
2798
 
2799
  /* We have already simplified this expression.  Simplifying it again
2800
     won't buy anything unless we weren't given a valid insn code
2801
     to process (i.e., we are canonicalizing something.).  */
2802
  if (insn_code != -2
2803
      && ! ATTR_IND_SIMPLIFIED_P (newexp))
2804
    return copy_rtx_unchanging (newexp);
2805
 
2806
  return newexp;
2807
}
2808
 
2809
/* Optimize the attribute lists by seeing if we can determine conditional
2810
   values from the known values of other attributes.  This will save subroutine
2811
   calls during the compilation.  */
2812
 
2813
static void
2814
optimize_attrs (void)
2815
{
2816
  struct attr_desc *attr;
2817
  struct attr_value *av;
2818
  struct insn_ent *ie;
2819
  rtx newexp;
2820
  int i;
2821
  struct attr_value_list
2822
  {
2823
    struct attr_value *av;
2824
    struct insn_ent *ie;
2825
    struct attr_desc *attr;
2826
    struct attr_value_list *next;
2827
  };
2828
  struct attr_value_list **insn_code_values;
2829
  struct attr_value_list *ivbuf;
2830
  struct attr_value_list *iv;
2831
 
2832
  /* For each insn code, make a list of all the insn_ent's for it,
2833
     for all values for all attributes.  */
2834
 
2835
  if (num_insn_ents == 0)
2836
    return;
2837
 
2838
  /* Make 2 extra elements, for "code" values -2 and -1.  */
2839
  insn_code_values = xcalloc ((insn_code_number + 2),
2840
                              sizeof (struct attr_value_list *));
2841
 
2842
  /* Offset the table address so we can index by -2 or -1.  */
2843
  insn_code_values += 2;
2844
 
2845
  iv = ivbuf = xmalloc (num_insn_ents * sizeof (struct attr_value_list));
2846
 
2847
  for (i = 0; i < MAX_ATTRS_INDEX; i++)
2848
    for (attr = attrs[i]; attr; attr = attr->next)
2849
      for (av = attr->first_value; av; av = av->next)
2850
        for (ie = av->first_insn; ie; ie = ie->next)
2851
          {
2852
            iv->attr = attr;
2853
            iv->av = av;
2854
            iv->ie = ie;
2855
            iv->next = insn_code_values[ie->def->insn_code];
2856
            insn_code_values[ie->def->insn_code] = iv;
2857
            iv++;
2858
          }
2859
 
2860
  /* Sanity check on num_insn_ents.  */
2861
  gcc_assert (iv == ivbuf + num_insn_ents);
2862
 
2863
  /* Process one insn code at a time.  */
2864
  for (i = -2; i < insn_code_number; i++)
2865
    {
2866
      /* Clear the ATTR_CURR_SIMPLIFIED_P flag everywhere relevant.
2867
         We use it to mean "already simplified for this insn".  */
2868
      for (iv = insn_code_values[i]; iv; iv = iv->next)
2869
        clear_struct_flag (iv->av->value);
2870
 
2871
      for (iv = insn_code_values[i]; iv; iv = iv->next)
2872
        {
2873
          struct obstack *old = rtl_obstack;
2874
 
2875
          attr = iv->attr;
2876
          av = iv->av;
2877
          ie = iv->ie;
2878
          if (GET_CODE (av->value) != COND)
2879
            continue;
2880
 
2881
          rtl_obstack = temp_obstack;
2882
          newexp = av->value;
2883
          while (GET_CODE (newexp) == COND)
2884
            {
2885
              rtx newexp2 = simplify_cond (newexp, ie->def->insn_code,
2886
                                           ie->def->insn_index);
2887
              if (newexp2 == newexp)
2888
                break;
2889
              newexp = newexp2;
2890
            }
2891
 
2892
          rtl_obstack = old;
2893
          if (newexp != av->value)
2894
            {
2895
              newexp = attr_copy_rtx (newexp);
2896
              remove_insn_ent (av, ie);
2897
              av = get_attr_value (newexp, attr, ie->def->insn_code);
2898
              iv->av = av;
2899
              insert_insn_ent (av, ie);
2900
            }
2901
        }
2902
    }
2903
 
2904
  free (ivbuf);
2905
  free (insn_code_values - 2);
2906
}
2907
 
2908
/* Clear the ATTR_CURR_SIMPLIFIED_P flag in EXP and its subexpressions.  */
2909
 
2910
static void
2911
clear_struct_flag (rtx x)
2912
{
2913
  int i;
2914
  int j;
2915
  enum rtx_code code;
2916
  const char *fmt;
2917
 
2918
  ATTR_CURR_SIMPLIFIED_P (x) = 0;
2919
  if (ATTR_IND_SIMPLIFIED_P (x))
2920
    return;
2921
 
2922
  code = GET_CODE (x);
2923
 
2924
  switch (code)
2925
    {
2926
    case REG:
2927
    case CONST_INT:
2928
    case CONST_DOUBLE:
2929
    case CONST_VECTOR:
2930
    case SYMBOL_REF:
2931
    case CODE_LABEL:
2932
    case PC:
2933
    case CC0:
2934
    case EQ_ATTR:
2935
    case ATTR_FLAG:
2936
      return;
2937
 
2938
    default:
2939
      break;
2940
    }
2941
 
2942
  /* Compare the elements.  If any pair of corresponding elements
2943
     fail to match, return 0 for the whole things.  */
2944
 
2945
  fmt = GET_RTX_FORMAT (code);
2946
  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
2947
    {
2948
      switch (fmt[i])
2949
        {
2950
        case 'V':
2951
        case 'E':
2952
          for (j = 0; j < XVECLEN (x, i); j++)
2953
            clear_struct_flag (XVECEXP (x, i, j));
2954
          break;
2955
 
2956
        case 'e':
2957
          clear_struct_flag (XEXP (x, i));
2958
          break;
2959
        }
2960
    }
2961
}
2962
 
2963
/* Create table entries for DEFINE_ATTR.  */
2964
 
2965
static void
2966
gen_attr (rtx exp, int lineno)
2967
{
2968
  struct attr_desc *attr;
2969
  struct attr_value *av;
2970
  const char *name_ptr;
2971
  char *p;
2972
 
2973
  /* Make a new attribute structure.  Check for duplicate by looking at
2974
     attr->default_val, since it is initialized by this routine.  */
2975
  attr = find_attr (&XSTR (exp, 0), 1);
2976
  if (attr->default_val)
2977
    {
2978
      message_with_line (lineno, "duplicate definition for attribute %s",
2979
                         attr->name);
2980
      message_with_line (attr->lineno, "previous definition");
2981
      have_error = 1;
2982
      return;
2983
    }
2984
  attr->lineno = lineno;
2985
 
2986
  if (*XSTR (exp, 1) == '\0')
2987
    attr->is_numeric = 1;
2988
  else
2989
    {
2990
      name_ptr = XSTR (exp, 1);
2991
      while ((p = next_comma_elt (&name_ptr)) != NULL)
2992
        {
2993
          av = oballoc (sizeof (struct attr_value));
2994
          av->value = attr_rtx (CONST_STRING, p);
2995
          av->next = attr->first_value;
2996
          attr->first_value = av;
2997
          av->first_insn = NULL;
2998
          av->num_insns = 0;
2999
          av->has_asm_insn = 0;
3000
        }
3001
    }
3002
 
3003
  if (GET_CODE (XEXP (exp, 2)) == CONST)
3004
    {
3005
      attr->is_const = 1;
3006
      if (attr->is_numeric)
3007
        {
3008
          message_with_line (lineno,
3009
                             "constant attributes may not take numeric values");
3010
          have_error = 1;
3011
        }
3012
 
3013
      /* Get rid of the CONST node.  It is allowed only at top-level.  */
3014
      XEXP (exp, 2) = XEXP (XEXP (exp, 2), 0);
3015
    }
3016
 
3017
  if (! strcmp_check (attr->name, length_str) && ! attr->is_numeric)
3018
    {
3019
      message_with_line (lineno,
3020
                         "`length' attribute must take numeric values");
3021
      have_error = 1;
3022
    }
3023
 
3024
  /* Set up the default value.  */
3025
  XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr);
3026
  attr->default_val = get_attr_value (XEXP (exp, 2), attr, -2);
3027
}
3028
 
3029
/* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of
3030
   alternatives in the constraints.  Assume all MATCH_OPERANDs have the same
3031
   number of alternatives as this should be checked elsewhere.  */
3032
 
3033
static int
3034
count_alternatives (rtx exp)
3035
{
3036
  int i, j, n;
3037
  const char *fmt;
3038
 
3039
  if (GET_CODE (exp) == MATCH_OPERAND)
3040
    return n_comma_elts (XSTR (exp, 2));
3041
 
3042
  for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
3043
       i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
3044
    switch (*fmt++)
3045
      {
3046
      case 'e':
3047
      case 'u':
3048
        n = count_alternatives (XEXP (exp, i));
3049
        if (n)
3050
          return n;
3051
        break;
3052
 
3053
      case 'E':
3054
      case 'V':
3055
        if (XVEC (exp, i) != NULL)
3056
          for (j = 0; j < XVECLEN (exp, i); j++)
3057
            {
3058
              n = count_alternatives (XVECEXP (exp, i, j));
3059
              if (n)
3060
                return n;
3061
            }
3062
      }
3063
 
3064
  return 0;
3065
}
3066
 
3067
/* Returns nonzero if the given expression contains an EQ_ATTR with the
3068
   `alternative' attribute.  */
3069
 
3070
static int
3071
compares_alternatives_p (rtx exp)
3072
{
3073
  int i, j;
3074
  const char *fmt;
3075
 
3076
  if (GET_CODE (exp) == EQ_ATTR && XSTR (exp, 0) == alternative_name)
3077
    return 1;
3078
 
3079
  for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
3080
       i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
3081
    switch (*fmt++)
3082
      {
3083
      case 'e':
3084
      case 'u':
3085
        if (compares_alternatives_p (XEXP (exp, i)))
3086
          return 1;
3087
        break;
3088
 
3089
      case 'E':
3090
        for (j = 0; j < XVECLEN (exp, i); j++)
3091
          if (compares_alternatives_p (XVECEXP (exp, i, j)))
3092
            return 1;
3093
        break;
3094
      }
3095
 
3096
  return 0;
3097
}
3098
 
3099
/* Returns nonzero is INNER is contained in EXP.  */
3100
 
3101
static int
3102
contained_in_p (rtx inner, rtx exp)
3103
{
3104
  int i, j;
3105
  const char *fmt;
3106
 
3107
  if (rtx_equal_p (inner, exp))
3108
    return 1;
3109
 
3110
  for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
3111
       i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
3112
    switch (*fmt++)
3113
      {
3114
      case 'e':
3115
      case 'u':
3116
        if (contained_in_p (inner, XEXP (exp, i)))
3117
          return 1;
3118
        break;
3119
 
3120
      case 'E':
3121
        for (j = 0; j < XVECLEN (exp, i); j++)
3122
          if (contained_in_p (inner, XVECEXP (exp, i, j)))
3123
            return 1;
3124
        break;
3125
      }
3126
 
3127
  return 0;
3128
}
3129
 
3130
/* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES.  */
3131
 
3132
static void
3133
gen_insn (rtx exp, int lineno)
3134
{
3135
  struct insn_def *id;
3136
 
3137
  id = oballoc (sizeof (struct insn_def));
3138
  id->next = defs;
3139
  defs = id;
3140
  id->def = exp;
3141
  id->lineno = lineno;
3142
 
3143
  switch (GET_CODE (exp))
3144
    {
3145
    case DEFINE_INSN:
3146
      id->insn_code = insn_code_number;
3147
      id->insn_index = insn_index_number;
3148
      id->num_alternatives = count_alternatives (exp);
3149
      if (id->num_alternatives == 0)
3150
        id->num_alternatives = 1;
3151
      id->vec_idx = 4;
3152
      break;
3153
 
3154
    case DEFINE_PEEPHOLE:
3155
      id->insn_code = insn_code_number;
3156
      id->insn_index = insn_index_number;
3157
      id->num_alternatives = count_alternatives (exp);
3158
      if (id->num_alternatives == 0)
3159
        id->num_alternatives = 1;
3160
      id->vec_idx = 3;
3161
      break;
3162
 
3163
    case DEFINE_ASM_ATTRIBUTES:
3164
      id->insn_code = -1;
3165
      id->insn_index = -1;
3166
      id->num_alternatives = 1;
3167
      id->vec_idx = 0;
3168
      got_define_asm_attributes = 1;
3169
      break;
3170
 
3171
    default:
3172
      gcc_unreachable ();
3173
    }
3174
}
3175
 
3176
/* Process a DEFINE_DELAY.  Validate the vector length, check if annul
3177
   true or annul false is specified, and make a `struct delay_desc'.  */
3178
 
3179
static void
3180
gen_delay (rtx def, int lineno)
3181
{
3182
  struct delay_desc *delay;
3183
  int i;
3184
 
3185
  if (XVECLEN (def, 1) % 3 != 0)
3186
    {
3187
      message_with_line (lineno,
3188
                         "number of elements in DEFINE_DELAY must be multiple of three");
3189
      have_error = 1;
3190
      return;
3191
    }
3192
 
3193
  for (i = 0; i < XVECLEN (def, 1); i += 3)
3194
    {
3195
      if (XVECEXP (def, 1, i + 1))
3196
        have_annul_true = 1;
3197
      if (XVECEXP (def, 1, i + 2))
3198
        have_annul_false = 1;
3199
    }
3200
 
3201
  delay = oballoc (sizeof (struct delay_desc));
3202
  delay->def = def;
3203
  delay->num = ++num_delays;
3204
  delay->next = delays;
3205
  delay->lineno = lineno;
3206
  delays = delay;
3207
}
3208
 
3209
/* Given a piece of RTX, print a C expression to test its truth value.
3210
   We use AND and IOR both for logical and bit-wise operations, so
3211
   interpret them as logical unless they are inside a comparison expression.
3212
   The first bit of FLAGS will be nonzero in that case.
3213
 
3214
   Set the second bit of FLAGS to make references to attribute values use
3215
   a cached local variable instead of calling a function.  */
3216
 
3217
static void
3218
write_test_expr (rtx exp, int flags)
3219
{
3220
  int comparison_operator = 0;
3221
  RTX_CODE code;
3222
  struct attr_desc *attr;
3223
 
3224
  /* In order not to worry about operator precedence, surround our part of
3225
     the expression with parentheses.  */
3226
 
3227
  printf ("(");
3228
  code = GET_CODE (exp);
3229
  switch (code)
3230
    {
3231
    /* Binary operators.  */
3232
    case GEU: case GTU:
3233
    case LEU: case LTU:
3234
      printf ("(unsigned) ");
3235
      /* Fall through.  */
3236
 
3237
    case EQ: case NE:
3238
    case GE: case GT:
3239
    case LE: case LT:
3240
      comparison_operator = 1;
3241
 
3242
    case PLUS:   case MINUS:  case MULT:     case DIV:      case MOD:
3243
    case AND:    case IOR:    case XOR:
3244
    case ASHIFT: case LSHIFTRT: case ASHIFTRT:
3245
      write_test_expr (XEXP (exp, 0), flags | comparison_operator);
3246
      switch (code)
3247
        {
3248
        case EQ:
3249
          printf (" == ");
3250
          break;
3251
        case NE:
3252
          printf (" != ");
3253
          break;
3254
        case GE:
3255
          printf (" >= ");
3256
          break;
3257
        case GT:
3258
          printf (" > ");
3259
          break;
3260
        case GEU:
3261
          printf (" >= (unsigned) ");
3262
          break;
3263
        case GTU:
3264
          printf (" > (unsigned) ");
3265
          break;
3266
        case LE:
3267
          printf (" <= ");
3268
          break;
3269
        case LT:
3270
          printf (" < ");
3271
          break;
3272
        case LEU:
3273
          printf (" <= (unsigned) ");
3274
          break;
3275
        case LTU:
3276
          printf (" < (unsigned) ");
3277
          break;
3278
        case PLUS:
3279
          printf (" + ");
3280
          break;
3281
        case MINUS:
3282
          printf (" - ");
3283
          break;
3284
        case MULT:
3285
          printf (" * ");
3286
          break;
3287
        case DIV:
3288
          printf (" / ");
3289
          break;
3290
        case MOD:
3291
          printf (" %% ");
3292
          break;
3293
        case AND:
3294
          if (flags & 1)
3295
            printf (" & ");
3296
          else
3297
            printf (" && ");
3298
          break;
3299
        case IOR:
3300
          if (flags & 1)
3301
            printf (" | ");
3302
          else
3303
            printf (" || ");
3304
          break;
3305
        case XOR:
3306
          printf (" ^ ");
3307
          break;
3308
        case ASHIFT:
3309
          printf (" << ");
3310
          break;
3311
        case LSHIFTRT:
3312
        case ASHIFTRT:
3313
          printf (" >> ");
3314
          break;
3315
        default:
3316
          gcc_unreachable ();
3317
        }
3318
 
3319
      write_test_expr (XEXP (exp, 1), flags | comparison_operator);
3320
      break;
3321
 
3322
    case NOT:
3323
      /* Special-case (not (eq_attrq "alternative" "x")) */
3324
      if (! (flags & 1) && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
3325
          && XSTR (XEXP (exp, 0), 0) == alternative_name)
3326
        {
3327
          printf ("which_alternative != %s", XSTR (XEXP (exp, 0), 1));
3328
          break;
3329
        }
3330
 
3331
      /* Otherwise, fall through to normal unary operator.  */
3332
 
3333
    /* Unary operators.  */
3334
    case ABS:  case NEG:
3335
      switch (code)
3336
        {
3337
        case NOT:
3338
          if (flags & 1)
3339
            printf ("~ ");
3340
          else
3341
            printf ("! ");
3342
          break;
3343
        case ABS:
3344
          printf ("abs ");
3345
          break;
3346
        case NEG:
3347
          printf ("-");
3348
          break;
3349
        default:
3350
          gcc_unreachable ();
3351
        }
3352
 
3353
      write_test_expr (XEXP (exp, 0), flags);
3354
      break;
3355
 
3356
    case EQ_ATTR_ALT:
3357
        {
3358
          int set = XINT (exp, 0), bit = 0;
3359
 
3360
          if (flags & 1)
3361
            fatal ("EQ_ATTR_ALT not valid inside comparison");
3362
 
3363
          if (!set)
3364
            fatal ("Empty EQ_ATTR_ALT should be optimized out");
3365
 
3366
          if (!(set & (set - 1)))
3367
            {
3368
              if (!(set & 0xffff))
3369
                {
3370
                  bit += 16;
3371
                  set >>= 16;
3372
                }
3373
              if (!(set & 0xff))
3374
                {
3375
                  bit += 8;
3376
                  set >>= 8;
3377
                }
3378
              if (!(set & 0xf))
3379
                {
3380
                  bit += 4;
3381
                  set >>= 4;
3382
                }
3383
              if (!(set & 0x3))
3384
                {
3385
                  bit += 2;
3386
                  set >>= 2;
3387
                }
3388
              if (!(set & 1))
3389
                bit++;
3390
 
3391
              printf ("which_alternative %s= %d",
3392
                      XINT (exp, 1) ? "!" : "=", bit);
3393
            }
3394
          else
3395
            {
3396
              printf ("%s((1 << which_alternative) & 0x%x)",
3397
                      XINT (exp, 1) ? "!" : "", set);
3398
            }
3399
        }
3400
      break;
3401
 
3402
    /* Comparison test of an attribute with a value.  Most of these will
3403
       have been removed by optimization.   Handle "alternative"
3404
       specially and give error if EQ_ATTR present inside a comparison.  */
3405
    case EQ_ATTR:
3406
      if (flags & 1)
3407
        fatal ("EQ_ATTR not valid inside comparison");
3408
 
3409
      if (XSTR (exp, 0) == alternative_name)
3410
        {
3411
          printf ("which_alternative == %s", XSTR (exp, 1));
3412
          break;
3413
        }
3414
 
3415
      attr = find_attr (&XSTR (exp, 0), 0);
3416
      gcc_assert (attr);
3417
 
3418
      /* Now is the time to expand the value of a constant attribute.  */
3419
      if (attr->is_const)
3420
        {
3421
          write_test_expr (evaluate_eq_attr (exp, attr->default_val->value,
3422
                                             -2, -2),
3423
                           flags);
3424
        }
3425
      else
3426
        {
3427
          if (flags & 2)
3428
            printf ("attr_%s", attr->name);
3429
          else
3430
            printf ("get_attr_%s (insn)", attr->name);
3431
          printf (" == ");
3432
          write_attr_valueq (attr, XSTR (exp, 1));
3433
        }
3434
      break;
3435
 
3436
    /* Comparison test of flags for define_delays.  */
3437
    case ATTR_FLAG:
3438
      if (flags & 1)
3439
        fatal ("ATTR_FLAG not valid inside comparison");
3440
      printf ("(flags & ATTR_FLAG_%s) != 0", XSTR (exp, 0));
3441
      break;
3442
 
3443
    /* See if an operand matches a predicate.  */
3444
    case MATCH_OPERAND:
3445
      /* If only a mode is given, just ensure the mode matches the operand.
3446
         If neither a mode nor predicate is given, error.  */
3447
      if (XSTR (exp, 1) == NULL || *XSTR (exp, 1) == '\0')
3448
        {
3449
          if (GET_MODE (exp) == VOIDmode)
3450
            fatal ("null MATCH_OPERAND specified as test");
3451
          else
3452
            printf ("GET_MODE (operands[%d]) == %smode",
3453
                    XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
3454
        }
3455
      else
3456
        printf ("%s (operands[%d], %smode)",
3457
                XSTR (exp, 1), XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
3458
      break;
3459
 
3460
    /* Constant integer.  */
3461
    case CONST_INT:
3462
      printf (HOST_WIDE_INT_PRINT_DEC, XWINT (exp, 0));
3463
      break;
3464
 
3465
    /* A random C expression.  */
3466
    case SYMBOL_REF:
3467
      print_c_condition (XSTR (exp, 0));
3468
      break;
3469
 
3470
    /* The address of the branch target.  */
3471
    case MATCH_DUP:
3472
      printf ("INSN_ADDRESSES_SET_P () ? INSN_ADDRESSES (INSN_UID (GET_CODE (operands[%d]) == LABEL_REF ? XEXP (operands[%d], 0) : operands[%d])) : 0",
3473
              XINT (exp, 0), XINT (exp, 0), XINT (exp, 0));
3474
      break;
3475
 
3476
    case PC:
3477
      /* The address of the current insn.  We implement this actually as the
3478
         address of the current insn for backward branches, but the last
3479
         address of the next insn for forward branches, and both with
3480
         adjustments that account for the worst-case possible stretching of
3481
         intervening alignments between this insn and its destination.  */
3482
      printf ("insn_current_reference_address (insn)");
3483
      break;
3484
 
3485
    case CONST_STRING:
3486
      printf ("%s", XSTR (exp, 0));
3487
      break;
3488
 
3489
    case IF_THEN_ELSE:
3490
      write_test_expr (XEXP (exp, 0), flags & 2);
3491
      printf (" ? ");
3492
      write_test_expr (XEXP (exp, 1), flags | 1);
3493
      printf (" : ");
3494
      write_test_expr (XEXP (exp, 2), flags | 1);
3495
      break;
3496
 
3497
    default:
3498
      fatal ("bad RTX code `%s' in attribute calculation\n",
3499
             GET_RTX_NAME (code));
3500
    }
3501
 
3502
  printf (")");
3503
}
3504
 
3505
/* Given an attribute value, return the maximum CONST_STRING argument
3506
   encountered.  Set *UNKNOWNP and return INT_MAX if the value is unknown.  */
3507
 
3508
static int
3509
max_attr_value (rtx exp, int *unknownp)
3510
{
3511
  int current_max;
3512
  int i, n;
3513
 
3514
  switch (GET_CODE (exp))
3515
    {
3516
    case CONST_STRING:
3517
      current_max = atoi (XSTR (exp, 0));
3518
      break;
3519
 
3520
    case COND:
3521
      current_max = max_attr_value (XEXP (exp, 1), unknownp);
3522
      for (i = 0; i < XVECLEN (exp, 0); i += 2)
3523
        {
3524
          n = max_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
3525
          if (n > current_max)
3526
            current_max = n;
3527
        }
3528
      break;
3529
 
3530
    case IF_THEN_ELSE:
3531
      current_max = max_attr_value (XEXP (exp, 1), unknownp);
3532
      n = max_attr_value (XEXP (exp, 2), unknownp);
3533
      if (n > current_max)
3534
        current_max = n;
3535
      break;
3536
 
3537
    default:
3538
      *unknownp = 1;
3539
      current_max = INT_MAX;
3540
      break;
3541
    }
3542
 
3543
  return current_max;
3544
}
3545
 
3546
/* Given an attribute value, return the minimum CONST_STRING argument
3547
   encountered.  Set *UNKNOWNP and return 0 if the value is unknown.  */
3548
 
3549
static int
3550
min_attr_value (rtx exp, int *unknownp)
3551
{
3552
  int current_min;
3553
  int i, n;
3554
 
3555
  switch (GET_CODE (exp))
3556
    {
3557
    case CONST_STRING:
3558
      current_min = atoi (XSTR (exp, 0));
3559
      break;
3560
 
3561
    case COND:
3562
      current_min = min_attr_value (XEXP (exp, 1), unknownp);
3563
      for (i = 0; i < XVECLEN (exp, 0); i += 2)
3564
        {
3565
          n = min_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
3566
          if (n < current_min)
3567
            current_min = n;
3568
        }
3569
      break;
3570
 
3571
    case IF_THEN_ELSE:
3572
      current_min = min_attr_value (XEXP (exp, 1), unknownp);
3573
      n = min_attr_value (XEXP (exp, 2), unknownp);
3574
      if (n < current_min)
3575
        current_min = n;
3576
      break;
3577
 
3578
    default:
3579
      *unknownp = 1;
3580
      current_min = INT_MAX;
3581
      break;
3582
    }
3583
 
3584
  return current_min;
3585
}
3586
 
3587
/* Given an attribute value, return the result of ORing together all
3588
   CONST_STRING arguments encountered.  Set *UNKNOWNP and return -1
3589
   if the numeric value is not known.  */
3590
 
3591
static int
3592
or_attr_value (rtx exp, int *unknownp)
3593
{
3594
  int current_or;
3595
  int i;
3596
 
3597
  switch (GET_CODE (exp))
3598
    {
3599
    case CONST_STRING:
3600
      current_or = atoi (XSTR (exp, 0));
3601
      break;
3602
 
3603
    case COND:
3604
      current_or = or_attr_value (XEXP (exp, 1), unknownp);
3605
      for (i = 0; i < XVECLEN (exp, 0); i += 2)
3606
        current_or |= or_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
3607
      break;
3608
 
3609
    case IF_THEN_ELSE:
3610
      current_or = or_attr_value (XEXP (exp, 1), unknownp);
3611
      current_or |= or_attr_value (XEXP (exp, 2), unknownp);
3612
      break;
3613
 
3614
    default:
3615
      *unknownp = 1;
3616
      current_or = -1;
3617
      break;
3618
    }
3619
 
3620
  return current_or;
3621
}
3622
 
3623
/* Scan an attribute value, possibly a conditional, and record what actions
3624
   will be required to do any conditional tests in it.
3625
 
3626
   Specifically, set
3627
        `must_extract'    if we need to extract the insn operands
3628
        `must_constrain'  if we must compute `which_alternative'
3629
        `address_used'    if an address expression was used
3630
        `length_used'     if an (eq_attr "length" ...) was used
3631
 */
3632
 
3633
static void
3634
walk_attr_value (rtx exp)
3635
{
3636
  int i, j;
3637
  const char *fmt;
3638
  RTX_CODE code;
3639
 
3640
  if (exp == NULL)
3641
    return;
3642
 
3643
  code = GET_CODE (exp);
3644
  switch (code)
3645
    {
3646
    case SYMBOL_REF:
3647
      if (! ATTR_IND_SIMPLIFIED_P (exp))
3648
        /* Since this is an arbitrary expression, it can look at anything.
3649
           However, constant expressions do not depend on any particular
3650
           insn.  */
3651
        must_extract = must_constrain = 1;
3652
      return;
3653
 
3654
    case MATCH_OPERAND:
3655
      must_extract = 1;
3656
      return;
3657
 
3658
    case EQ_ATTR_ALT:
3659
      must_extract = must_constrain = 1;
3660
      break;
3661
 
3662
    case EQ_ATTR:
3663
      if (XSTR (exp, 0) == alternative_name)
3664
        must_extract = must_constrain = 1;
3665
      else if (strcmp_check (XSTR (exp, 0), length_str) == 0)
3666
        length_used = 1;
3667
      return;
3668
 
3669
    case MATCH_DUP:
3670
      must_extract = 1;
3671
      address_used = 1;
3672
      return;
3673
 
3674
    case PC:
3675
      address_used = 1;
3676
      return;
3677
 
3678
    case ATTR_FLAG:
3679
      return;
3680
 
3681
    default:
3682
      break;
3683
    }
3684
 
3685
  for (i = 0, fmt = GET_RTX_FORMAT (code); i < GET_RTX_LENGTH (code); i++)
3686
    switch (*fmt++)
3687
      {
3688
      case 'e':
3689
      case 'u':
3690
        walk_attr_value (XEXP (exp, i));
3691
        break;
3692
 
3693
      case 'E':
3694
        if (XVEC (exp, i) != NULL)
3695
          for (j = 0; j < XVECLEN (exp, i); j++)
3696
            walk_attr_value (XVECEXP (exp, i, j));
3697
        break;
3698
      }
3699
}
3700
 
3701
/* Write out a function to obtain the attribute for a given INSN.  */
3702
 
3703
static void
3704
write_attr_get (struct attr_desc *attr)
3705
{
3706
  struct attr_value *av, *common_av;
3707
 
3708
  /* Find the most used attribute value.  Handle that as the `default' of the
3709
     switch we will generate.  */
3710
  common_av = find_most_used (attr);
3711
 
3712
  /* Write out start of function, then all values with explicit `case' lines,
3713
     then a `default', then the value with the most uses.  */
3714
  if (attr->static_p)
3715
    printf ("static ");
3716
  if (!attr->is_numeric)
3717
    printf ("enum attr_%s\n", attr->name);
3718
  else
3719
    printf ("int\n");
3720
 
3721
  /* If the attribute name starts with a star, the remainder is the name of
3722
     the subroutine to use, instead of `get_attr_...'.  */
3723
  if (attr->name[0] == '*')
3724
    printf ("%s (rtx insn ATTRIBUTE_UNUSED)\n", &attr->name[1]);
3725
  else if (attr->is_const == 0)
3726
    printf ("get_attr_%s (rtx insn ATTRIBUTE_UNUSED)\n", attr->name);
3727
  else
3728
    {
3729
      printf ("get_attr_%s (void)\n", attr->name);
3730
      printf ("{\n");
3731
 
3732
      for (av = attr->first_value; av; av = av->next)
3733
        if (av->num_insns == 1)
3734
          write_attr_set (attr, 2, av->value, "return", ";",
3735
                          true_rtx, av->first_insn->def->insn_code,
3736
                          av->first_insn->def->insn_index);
3737
        else if (av->num_insns != 0)
3738
          write_attr_set (attr, 2, av->value, "return", ";",
3739
                          true_rtx, -2, 0);
3740
 
3741
      printf ("}\n\n");
3742
      return;
3743
    }
3744
 
3745
  printf ("{\n");
3746
  printf ("  switch (recog_memoized (insn))\n");
3747
  printf ("    {\n");
3748
 
3749
  for (av = attr->first_value; av; av = av->next)
3750
    if (av != common_av)
3751
      write_attr_case (attr, av, 1, "return", ";", 4, true_rtx);
3752
 
3753
  write_attr_case (attr, common_av, 0, "return", ";", 4, true_rtx);
3754
  printf ("    }\n}\n\n");
3755
}
3756
 
3757
/* Given an AND tree of known true terms (because we are inside an `if' with
3758
   that as the condition or are in an `else' clause) and an expression,
3759
   replace any known true terms with TRUE.  Use `simplify_and_tree' to do
3760
   the bulk of the work.  */
3761
 
3762
static rtx
3763
eliminate_known_true (rtx known_true, rtx exp, int insn_code, int insn_index)
3764
{
3765
  rtx term;
3766
 
3767
  known_true = SIMPLIFY_TEST_EXP (known_true, insn_code, insn_index);
3768
 
3769
  if (GET_CODE (known_true) == AND)
3770
    {
3771
      exp = eliminate_known_true (XEXP (known_true, 0), exp,
3772
                                  insn_code, insn_index);
3773
      exp = eliminate_known_true (XEXP (known_true, 1), exp,
3774
                                  insn_code, insn_index);
3775
    }
3776
  else
3777
    {
3778
      term = known_true;
3779
      exp = simplify_and_tree (exp, &term, insn_code, insn_index);
3780
    }
3781
 
3782
  return exp;
3783
}
3784
 
3785
/* Write out a series of tests and assignment statements to perform tests and
3786
   sets of an attribute value.  We are passed an indentation amount and prefix
3787
   and suffix strings to write around each attribute value (e.g., "return"
3788
   and ";").  */
3789
 
3790
static void
3791
write_attr_set (struct attr_desc *attr, int indent, rtx value,
3792
                const char *prefix, const char *suffix, rtx known_true,
3793
                int insn_code, int insn_index)
3794
{
3795
  if (GET_CODE (value) == COND)
3796
    {
3797
      /* Assume the default value will be the default of the COND unless we
3798
         find an always true expression.  */
3799
      rtx default_val = XEXP (value, 1);
3800
      rtx our_known_true = known_true;
3801
      rtx newexp;
3802
      int first_if = 1;
3803
      int i;
3804
 
3805
      for (i = 0; i < XVECLEN (value, 0); i += 2)
3806
        {
3807
          rtx testexp;
3808
          rtx inner_true;
3809
 
3810
          testexp = eliminate_known_true (our_known_true,
3811
                                          XVECEXP (value, 0, i),
3812
                                          insn_code, insn_index);
3813
          newexp = attr_rtx (NOT, testexp);
3814
          newexp = insert_right_side (AND, our_known_true, newexp,
3815
                                      insn_code, insn_index);
3816
 
3817
          /* If the test expression is always true or if the next `known_true'
3818
             expression is always false, this is the last case, so break
3819
             out and let this value be the `else' case.  */
3820
          if (testexp == true_rtx || newexp == false_rtx)
3821
            {
3822
              default_val = XVECEXP (value, 0, i + 1);
3823
              break;
3824
            }
3825
 
3826
          /* Compute the expression to pass to our recursive call as being
3827
             known true.  */
3828
          inner_true = insert_right_side (AND, our_known_true,
3829
                                          testexp, insn_code, insn_index);
3830
 
3831
          /* If this is always false, skip it.  */
3832
          if (inner_true == false_rtx)
3833
            continue;
3834
 
3835
          write_indent (indent);
3836
          printf ("%sif ", first_if ? "" : "else ");
3837
          first_if = 0;
3838
          write_test_expr (testexp, 0);
3839
          printf ("\n");
3840
          write_indent (indent + 2);
3841
          printf ("{\n");
3842
 
3843
          write_attr_set (attr, indent + 4,
3844
                          XVECEXP (value, 0, i + 1), prefix, suffix,
3845
                          inner_true, insn_code, insn_index);
3846
          write_indent (indent + 2);
3847
          printf ("}\n");
3848
          our_known_true = newexp;
3849
        }
3850
 
3851
      if (! first_if)
3852
        {
3853
          write_indent (indent);
3854
          printf ("else\n");
3855
          write_indent (indent + 2);
3856
          printf ("{\n");
3857
        }
3858
 
3859
      write_attr_set (attr, first_if ? indent : indent + 4, default_val,
3860
                      prefix, suffix, our_known_true, insn_code, insn_index);
3861
 
3862
      if (! first_if)
3863
        {
3864
          write_indent (indent + 2);
3865
          printf ("}\n");
3866
        }
3867
    }
3868
  else
3869
    {
3870
      write_indent (indent);
3871
      printf ("%s ", prefix);
3872
      write_attr_value (attr, value);
3873
      printf ("%s\n", suffix);
3874
    }
3875
}
3876
 
3877
/* Write a series of case statements for every instruction in list IE.
3878
   INDENT is the amount of indentation to write before each case.  */
3879
 
3880
static void
3881
write_insn_cases (struct insn_ent *ie, int indent)
3882
{
3883
  for (; ie != 0; ie = ie->next)
3884
    if (ie->def->insn_code != -1)
3885
      {
3886
        write_indent (indent);
3887
        if (GET_CODE (ie->def->def) == DEFINE_PEEPHOLE)
3888
          printf ("case %d:  /* define_peephole, line %d */\n",
3889
                  ie->def->insn_code, ie->def->lineno);
3890
        else
3891
          printf ("case %d:  /* %s */\n",
3892
                  ie->def->insn_code, XSTR (ie->def->def, 0));
3893
      }
3894
}
3895
 
3896
/* Write out the computation for one attribute value.  */
3897
 
3898
static void
3899
write_attr_case (struct attr_desc *attr, struct attr_value *av,
3900
                 int write_case_lines, const char *prefix, const char *suffix,
3901
                 int indent, rtx known_true)
3902
{
3903
  if (av->num_insns == 0)
3904
    return;
3905
 
3906
  if (av->has_asm_insn)
3907
    {
3908
      write_indent (indent);
3909
      printf ("case -1:\n");
3910
      write_indent (indent + 2);
3911
      printf ("if (GET_CODE (PATTERN (insn)) != ASM_INPUT\n");
3912
      write_indent (indent + 2);
3913
      printf ("    && asm_noperands (PATTERN (insn)) < 0)\n");
3914
      write_indent (indent + 2);
3915
      printf ("  fatal_insn_not_found (insn);\n");
3916
    }
3917
 
3918
  if (write_case_lines)
3919
    write_insn_cases (av->first_insn, indent);
3920
  else
3921
    {
3922
      write_indent (indent);
3923
      printf ("default:\n");
3924
    }
3925
 
3926
  /* See what we have to do to output this value.  */
3927
  must_extract = must_constrain = address_used = 0;
3928
  walk_attr_value (av->value);
3929
 
3930
  if (must_constrain)
3931
    {
3932
      write_indent (indent + 2);
3933
      printf ("extract_constrain_insn_cached (insn);\n");
3934
    }
3935
  else if (must_extract)
3936
    {
3937
      write_indent (indent + 2);
3938
      printf ("extract_insn_cached (insn);\n");
3939
    }
3940
 
3941
  if (av->num_insns == 1)
3942
    write_attr_set (attr, indent + 2, av->value, prefix, suffix,
3943
                    known_true, av->first_insn->def->insn_code,
3944
                    av->first_insn->def->insn_index);
3945
  else
3946
    write_attr_set (attr, indent + 2, av->value, prefix, suffix,
3947
                    known_true, -2, 0);
3948
 
3949
  if (strncmp (prefix, "return", 6))
3950
    {
3951
      write_indent (indent + 2);
3952
      printf ("break;\n");
3953
    }
3954
  printf ("\n");
3955
}
3956
 
3957
/* Search for uses of non-const attributes and write code to cache them.  */
3958
 
3959
static int
3960
write_expr_attr_cache (rtx p, struct attr_desc *attr)
3961
{
3962
  const char *fmt;
3963
  int i, ie, j, je;
3964
 
3965
  if (GET_CODE (p) == EQ_ATTR)
3966
    {
3967
      if (XSTR (p, 0) != attr->name)
3968
        return 0;
3969
 
3970
      if (!attr->is_numeric)
3971
        printf ("  enum attr_%s ", attr->name);
3972
      else
3973
        printf ("  int ");
3974
 
3975
      printf ("attr_%s = get_attr_%s (insn);\n", attr->name, attr->name);
3976
      return 1;
3977
    }
3978
 
3979
  fmt = GET_RTX_FORMAT (GET_CODE (p));
3980
  ie = GET_RTX_LENGTH (GET_CODE (p));
3981
  for (i = 0; i < ie; i++)
3982
    {
3983
      switch (*fmt++)
3984
        {
3985
        case 'e':
3986
          if (write_expr_attr_cache (XEXP (p, i), attr))
3987
            return 1;
3988
          break;
3989
 
3990
        case 'E':
3991
          je = XVECLEN (p, i);
3992
          for (j = 0; j < je; ++j)
3993
            if (write_expr_attr_cache (XVECEXP (p, i, j), attr))
3994
              return 1;
3995
          break;
3996
        }
3997
    }
3998
 
3999
  return 0;
4000
}
4001
 
4002
/* Utilities to write in various forms.  */
4003
 
4004
static void
4005
write_attr_valueq (struct attr_desc *attr, const char *s)
4006
{
4007
  if (attr->is_numeric)
4008
    {
4009
      int num = atoi (s);
4010
 
4011
      printf ("%d", num);
4012
 
4013
      if (num > 9 || num < 0)
4014
        printf (" /* 0x%x */", num);
4015
    }
4016
  else
4017
    {
4018
      write_upcase (attr->name);
4019
      printf ("_");
4020
      write_upcase (s);
4021
    }
4022
}
4023
 
4024
static void
4025
write_attr_value (struct attr_desc *attr, rtx value)
4026
{
4027
  int op;
4028
 
4029
  switch (GET_CODE (value))
4030
    {
4031
    case CONST_STRING:
4032
      write_attr_valueq (attr, XSTR (value, 0));
4033
      break;
4034
 
4035
    case CONST_INT:
4036
      printf (HOST_WIDE_INT_PRINT_DEC, INTVAL (value));
4037
      break;
4038
 
4039
    case SYMBOL_REF:
4040
      print_c_condition (XSTR (value, 0));
4041
      break;
4042
 
4043
    case ATTR:
4044
      {
4045
        struct attr_desc *attr2 = find_attr (&XSTR (value, 0), 0);
4046
        printf ("get_attr_%s (%s)", attr2->name,
4047
                (attr2->is_const ? "" : "insn"));
4048
      }
4049
      break;
4050
 
4051
    case PLUS:
4052
      op = '+';
4053
      goto do_operator;
4054
    case MINUS:
4055
      op = '-';
4056
      goto do_operator;
4057
    case MULT:
4058
      op = '*';
4059
      goto do_operator;
4060
    case DIV:
4061
      op = '/';
4062
      goto do_operator;
4063
    case MOD:
4064
      op = '%';
4065
      goto do_operator;
4066
 
4067
    do_operator:
4068
      write_attr_value (attr, XEXP (value, 0));
4069
      putchar (' ');
4070
      putchar (op);
4071
      putchar (' ');
4072
      write_attr_value (attr, XEXP (value, 1));
4073
      break;
4074
 
4075
    default:
4076
      gcc_unreachable ();
4077
    }
4078
}
4079
 
4080
static void
4081
write_upcase (const char *str)
4082
{
4083
  while (*str)
4084
    {
4085
      /* The argument of TOUPPER should not have side effects.  */
4086
      putchar (TOUPPER(*str));
4087
      str++;
4088
    }
4089
}
4090
 
4091
static void
4092
write_indent (int indent)
4093
{
4094
  for (; indent > 8; indent -= 8)
4095
    printf ("\t");
4096
 
4097
  for (; indent; indent--)
4098
    printf (" ");
4099
}
4100
 
4101
/* Write a subroutine that is given an insn that requires a delay slot, a
4102
   delay slot ordinal, and a candidate insn.  It returns nonzero if the
4103
   candidate can be placed in the specified delay slot of the insn.
4104
 
4105
   We can write as many as three subroutines.  `eligible_for_delay'
4106
   handles normal delay slots, `eligible_for_annul_true' indicates that
4107
   the specified insn can be annulled if the branch is true, and likewise
4108
   for `eligible_for_annul_false'.
4109
 
4110
   KIND is a string distinguishing these three cases ("delay", "annul_true",
4111
   or "annul_false").  */
4112
 
4113
static void
4114
write_eligible_delay (const char *kind)
4115
{
4116
  struct delay_desc *delay;
4117
  int max_slots;
4118
  char str[50];
4119
  const char *pstr;
4120
  struct attr_desc *attr;
4121
  struct attr_value *av, *common_av;
4122
  int i;
4123
 
4124
  /* Compute the maximum number of delay slots required.  We use the delay
4125
     ordinal times this number plus one, plus the slot number as an index into
4126
     the appropriate predicate to test.  */
4127
 
4128
  for (delay = delays, max_slots = 0; delay; delay = delay->next)
4129
    if (XVECLEN (delay->def, 1) / 3 > max_slots)
4130
      max_slots = XVECLEN (delay->def, 1) / 3;
4131
 
4132
  /* Write function prelude.  */
4133
 
4134
  printf ("int\n");
4135
  printf ("eligible_for_%s (rtx delay_insn ATTRIBUTE_UNUSED, int slot, rtx candidate_insn, int flags ATTRIBUTE_UNUSED)\n",
4136
          kind);
4137
  printf ("{\n");
4138
  printf ("  rtx insn;\n");
4139
  printf ("\n");
4140
  printf ("  gcc_assert (slot < %d);\n", max_slots);
4141
  printf ("\n");
4142
  /* Allow dbr_schedule to pass labels, etc.  This can happen if try_split
4143
     converts a compound instruction into a loop.  */
4144
  printf ("  if (!INSN_P (candidate_insn))\n");
4145
  printf ("    return 0;\n");
4146
  printf ("\n");
4147
 
4148
  /* If more than one delay type, find out which type the delay insn is.  */
4149
 
4150
  if (num_delays > 1)
4151
    {
4152
      attr = find_attr (&delay_type_str, 0);
4153
      gcc_assert (attr);
4154
      common_av = find_most_used (attr);
4155
 
4156
      printf ("  insn = delay_insn;\n");
4157
      printf ("  switch (recog_memoized (insn))\n");
4158
      printf ("    {\n");
4159
 
4160
      sprintf (str, " * %d;\n      break;", max_slots);
4161
      for (av = attr->first_value; av; av = av->next)
4162
        if (av != common_av)
4163
          write_attr_case (attr, av, 1, "slot +=", str, 4, true_rtx);
4164
 
4165
      write_attr_case (attr, common_av, 0, "slot +=", str, 4, true_rtx);
4166
      printf ("    }\n\n");
4167
 
4168
      /* Ensure matched.  Otherwise, shouldn't have been called.  */
4169
      printf ("  gcc_assert (slot >= %d);\n\n", max_slots);
4170
    }
4171
 
4172
  /* If just one type of delay slot, write simple switch.  */
4173
  if (num_delays == 1 && max_slots == 1)
4174
    {
4175
      printf ("  insn = candidate_insn;\n");
4176
      printf ("  switch (recog_memoized (insn))\n");
4177
      printf ("    {\n");
4178
 
4179
      attr = find_attr (&delay_1_0_str, 0);
4180
      gcc_assert (attr);
4181
      common_av = find_most_used (attr);
4182
 
4183
      for (av = attr->first_value; av; av = av->next)
4184
        if (av != common_av)
4185
          write_attr_case (attr, av, 1, "return", ";", 4, true_rtx);
4186
 
4187
      write_attr_case (attr, common_av, 0, "return", ";", 4, true_rtx);
4188
      printf ("    }\n");
4189
    }
4190
 
4191
  else
4192
    {
4193
      /* Write a nested CASE.  The first indicates which condition we need to
4194
         test, and the inner CASE tests the condition.  */
4195
      printf ("  insn = candidate_insn;\n");
4196
      printf ("  switch (slot)\n");
4197
      printf ("    {\n");
4198
 
4199
      for (delay = delays; delay; delay = delay->next)
4200
        for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
4201
          {
4202
            printf ("    case %d:\n",
4203
                    (i / 3) + (num_delays == 1 ? 0 : delay->num * max_slots));
4204
            printf ("      switch (recog_memoized (insn))\n");
4205
            printf ("\t{\n");
4206
 
4207
            sprintf (str, "*%s_%d_%d", kind, delay->num, i / 3);
4208
            pstr = str;
4209
            attr = find_attr (&pstr, 0);
4210
            gcc_assert (attr);
4211
            common_av = find_most_used (attr);
4212
 
4213
            for (av = attr->first_value; av; av = av->next)
4214
              if (av != common_av)
4215
                write_attr_case (attr, av, 1, "return", ";", 8, true_rtx);
4216
 
4217
            write_attr_case (attr, common_av, 0, "return", ";", 8, true_rtx);
4218
            printf ("      }\n");
4219
          }
4220
 
4221
      printf ("    default:\n");
4222
      printf ("      gcc_unreachable ();\n");
4223
      printf ("    }\n");
4224
    }
4225
 
4226
  printf ("}\n\n");
4227
}
4228
 
4229
/* This page contains miscellaneous utility routines.  */
4230
 
4231
/* Given a pointer to a (char *), return a malloc'ed string containing the
4232
   next comma-separated element.  Advance the pointer to after the string
4233
   scanned, or the end-of-string.  Return NULL if at end of string.  */
4234
 
4235
static char *
4236
next_comma_elt (const char **pstr)
4237
{
4238
  const char *start;
4239
 
4240
  start = scan_comma_elt (pstr);
4241
 
4242
  if (start == NULL)
4243
    return NULL;
4244
 
4245
  return attr_string (start, *pstr - start);
4246
}
4247
 
4248
/* Return a `struct attr_desc' pointer for a given named attribute.  If CREATE
4249
   is nonzero, build a new attribute, if one does not exist.  *NAME_P is
4250
   replaced by a pointer to a canonical copy of the string.  */
4251
 
4252
static struct attr_desc *
4253
find_attr (const char **name_p, int create)
4254
{
4255
  struct attr_desc *attr;
4256
  int index;
4257
  const char *name = *name_p;
4258
 
4259
  /* Before we resort to using `strcmp', see if the string address matches
4260
     anywhere.  In most cases, it should have been canonicalized to do so.  */
4261
  if (name == alternative_name)
4262
    return NULL;
4263
 
4264
  index = name[0] & (MAX_ATTRS_INDEX - 1);
4265
  for (attr = attrs[index]; attr; attr = attr->next)
4266
    if (name == attr->name)
4267
      return attr;
4268
 
4269
  /* Otherwise, do it the slow way.  */
4270
  for (attr = attrs[index]; attr; attr = attr->next)
4271
    if (name[0] == attr->name[0] && ! strcmp (name, attr->name))
4272
      {
4273
        *name_p = attr->name;
4274
        return attr;
4275
      }
4276
 
4277
  if (! create)
4278
    return NULL;
4279
 
4280
  attr = oballoc (sizeof (struct attr_desc));
4281
  attr->name = DEF_ATTR_STRING (name);
4282
  attr->first_value = attr->default_val = NULL;
4283
  attr->is_numeric = attr->is_const = attr->is_special = 0;
4284
  attr->static_p = 0;
4285
  attr->next = attrs[index];
4286
  attrs[index] = attr;
4287
 
4288
  *name_p = attr->name;
4289
 
4290
  return attr;
4291
}
4292
 
4293
/* Create internal attribute with the given default value.  */
4294
 
4295
void
4296
make_internal_attr (const char *name, rtx value, int special)
4297
{
4298
  struct attr_desc *attr;
4299
 
4300
  attr = find_attr (&name, 1);
4301
  gcc_assert (!attr->default_val);
4302
 
4303
  attr->is_numeric = 1;
4304
  attr->is_const = 0;
4305
  attr->is_special = (special & ATTR_SPECIAL) != 0;
4306
  attr->static_p = (special & ATTR_STATIC) != 0;
4307
  attr->default_val = get_attr_value (value, attr, -2);
4308
}
4309
 
4310
/* Find the most used value of an attribute.  */
4311
 
4312
static struct attr_value *
4313
find_most_used (struct attr_desc *attr)
4314
{
4315
  struct attr_value *av;
4316
  struct attr_value *most_used;
4317
  int nuses;
4318
 
4319
  most_used = NULL;
4320
  nuses = -1;
4321
 
4322
  for (av = attr->first_value; av; av = av->next)
4323
    if (av->num_insns > nuses)
4324
      nuses = av->num_insns, most_used = av;
4325
 
4326
  return most_used;
4327
}
4328
 
4329
/* Return (attr_value "n") */
4330
 
4331
rtx
4332
make_numeric_value (int n)
4333
{
4334
  static rtx int_values[20];
4335
  rtx exp;
4336
  char *p;
4337
 
4338
  gcc_assert (n >= 0);
4339
 
4340
  if (n < 20 && int_values[n])
4341
    return int_values[n];
4342
 
4343
  p = attr_printf (MAX_DIGITS, "%d", n);
4344
  exp = attr_rtx (CONST_STRING, p);
4345
 
4346
  if (n < 20)
4347
    int_values[n] = exp;
4348
 
4349
  return exp;
4350
}
4351
 
4352
static rtx
4353
copy_rtx_unchanging (rtx orig)
4354
{
4355
  if (ATTR_IND_SIMPLIFIED_P (orig) || ATTR_CURR_SIMPLIFIED_P (orig))
4356
    return orig;
4357
 
4358
  ATTR_CURR_SIMPLIFIED_P (orig) = 1;
4359
  return orig;
4360
}
4361
 
4362
/* Determine if an insn has a constant number of delay slots, i.e., the
4363
   number of delay slots is not a function of the length of the insn.  */
4364
 
4365
static void
4366
write_const_num_delay_slots (void)
4367
{
4368
  struct attr_desc *attr = find_attr (&num_delay_slots_str, 0);
4369
  struct attr_value *av;
4370
 
4371
  if (attr)
4372
    {
4373
      printf ("int\nconst_num_delay_slots (rtx insn)\n");
4374
      printf ("{\n");
4375
      printf ("  switch (recog_memoized (insn))\n");
4376
      printf ("    {\n");
4377
 
4378
      for (av = attr->first_value; av; av = av->next)
4379
        {
4380
          length_used = 0;
4381
          walk_attr_value (av->value);
4382
          if (length_used)
4383
            write_insn_cases (av->first_insn, 4);
4384
        }
4385
 
4386
      printf ("    default:\n");
4387
      printf ("      return 1;\n");
4388
      printf ("    }\n}\n\n");
4389
    }
4390
}
4391
 
4392
int
4393
main (int argc, char **argv)
4394
{
4395
  rtx desc;
4396
  struct attr_desc *attr;
4397
  struct insn_def *id;
4398
  rtx tem;
4399
  int i;
4400
 
4401
  progname = "genattrtab";
4402
 
4403
  if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
4404
    return (FATAL_EXIT_CODE);
4405
 
4406
  obstack_init (hash_obstack);
4407
  obstack_init (temp_obstack);
4408
 
4409
  /* Set up true and false rtx's */
4410
  true_rtx = rtx_alloc (CONST_INT);
4411
  XWINT (true_rtx, 0) = 1;
4412
  false_rtx = rtx_alloc (CONST_INT);
4413
  XWINT (false_rtx, 0) = 0;
4414
  ATTR_IND_SIMPLIFIED_P (true_rtx) = ATTR_IND_SIMPLIFIED_P (false_rtx) = 1;
4415
  ATTR_PERMANENT_P (true_rtx) = ATTR_PERMANENT_P (false_rtx) = 1;
4416
 
4417
  alternative_name = DEF_ATTR_STRING ("alternative");
4418
  length_str = DEF_ATTR_STRING ("length");
4419
  delay_type_str = DEF_ATTR_STRING ("*delay_type");
4420
  delay_1_0_str = DEF_ATTR_STRING ("*delay_1_0");
4421
  num_delay_slots_str = DEF_ATTR_STRING ("*num_delay_slots");
4422
 
4423
  printf ("/* Generated automatically by the program `genattrtab'\n\
4424
from the machine description file `md'.  */\n\n");
4425
 
4426
  /* Read the machine description.  */
4427
 
4428
  initiate_automaton_gen (argc, argv);
4429
  while (1)
4430
    {
4431
      int lineno;
4432
 
4433
      desc = read_md_rtx (&lineno, &insn_code_number);
4434
      if (desc == NULL)
4435
        break;
4436
 
4437
      switch (GET_CODE (desc))
4438
        {
4439
        case DEFINE_INSN:
4440
        case DEFINE_PEEPHOLE:
4441
        case DEFINE_ASM_ATTRIBUTES:
4442
          gen_insn (desc, lineno);
4443
          break;
4444
 
4445
        case DEFINE_ATTR:
4446
          gen_attr (desc, lineno);
4447
          break;
4448
 
4449
        case DEFINE_DELAY:
4450
          gen_delay (desc, lineno);
4451
          break;
4452
 
4453
        case DEFINE_CPU_UNIT:
4454
          gen_cpu_unit (desc);
4455
          break;
4456
 
4457
        case DEFINE_QUERY_CPU_UNIT:
4458
          gen_query_cpu_unit (desc);
4459
          break;
4460
 
4461
        case DEFINE_BYPASS:
4462
          gen_bypass (desc);
4463
          break;
4464
 
4465
        case EXCLUSION_SET:
4466
          gen_excl_set (desc);
4467
          break;
4468
 
4469
        case PRESENCE_SET:
4470
          gen_presence_set (desc);
4471
          break;
4472
 
4473
        case FINAL_PRESENCE_SET:
4474
          gen_final_presence_set (desc);
4475
          break;
4476
 
4477
        case ABSENCE_SET:
4478
          gen_absence_set (desc);
4479
          break;
4480
 
4481
        case FINAL_ABSENCE_SET:
4482
          gen_final_absence_set (desc);
4483
          break;
4484
 
4485
        case DEFINE_AUTOMATON:
4486
          gen_automaton (desc);
4487
          break;
4488
 
4489
        case AUTOMATA_OPTION:
4490
          gen_automata_option (desc);
4491
          break;
4492
 
4493
        case DEFINE_RESERVATION:
4494
          gen_reserv (desc);
4495
          break;
4496
 
4497
        case DEFINE_INSN_RESERVATION:
4498
          gen_insn_reserv (desc);
4499
          break;
4500
 
4501
        default:
4502
          break;
4503
        }
4504
      if (GET_CODE (desc) != DEFINE_ASM_ATTRIBUTES)
4505
        insn_index_number++;
4506
    }
4507
 
4508
  if (have_error)
4509
    return FATAL_EXIT_CODE;
4510
 
4511
  insn_code_number++;
4512
 
4513
  /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one.  */
4514
  if (! got_define_asm_attributes)
4515
    {
4516
      tem = rtx_alloc (DEFINE_ASM_ATTRIBUTES);
4517
      XVEC (tem, 0) = rtvec_alloc (0);
4518
      gen_insn (tem, 0);
4519
    }
4520
 
4521
  /* Expand DEFINE_DELAY information into new attribute.  */
4522
  if (num_delays)
4523
    expand_delays ();
4524
 
4525
  /* Build DFA, output some functions and expand DFA information
4526
     to new attributes.  */
4527
  if (num_dfa_decls)
4528
    expand_automata ();
4529
 
4530
  printf ("#include \"config.h\"\n");
4531
  printf ("#include \"system.h\"\n");
4532
  printf ("#include \"coretypes.h\"\n");
4533
  printf ("#include \"tm.h\"\n");
4534
  printf ("#include \"rtl.h\"\n");
4535
  printf ("#include \"tm_p.h\"\n");
4536
  printf ("#include \"insn-config.h\"\n");
4537
  printf ("#include \"recog.h\"\n");
4538
  printf ("#include \"regs.h\"\n");
4539
  printf ("#include \"real.h\"\n");
4540
  printf ("#include \"output.h\"\n");
4541
  printf ("#include \"insn-attr.h\"\n");
4542
  printf ("#include \"toplev.h\"\n");
4543
  printf ("#include \"flags.h\"\n");
4544
  printf ("#include \"function.h\"\n");
4545
  printf ("\n");
4546
  printf ("#define operands recog_data.operand\n\n");
4547
 
4548
  /* Make `insn_alternatives'.  */
4549
  insn_alternatives = oballoc (insn_code_number * sizeof (int));
4550
  for (id = defs; id; id = id->next)
4551
    if (id->insn_code >= 0)
4552
      insn_alternatives[id->insn_code] = (1 << id->num_alternatives) - 1;
4553
 
4554
  /* Make `insn_n_alternatives'.  */
4555
  insn_n_alternatives = oballoc (insn_code_number * sizeof (int));
4556
  for (id = defs; id; id = id->next)
4557
    if (id->insn_code >= 0)
4558
      insn_n_alternatives[id->insn_code] = id->num_alternatives;
4559
 
4560
  /* Prepare to write out attribute subroutines by checking everything stored
4561
     away and building the attribute cases.  */
4562
 
4563
  check_defs ();
4564
 
4565
  for (i = 0; i < MAX_ATTRS_INDEX; i++)
4566
    for (attr = attrs[i]; attr; attr = attr->next)
4567
      attr->default_val->value
4568
        = check_attr_value (attr->default_val->value, attr);
4569
 
4570
  if (have_error)
4571
    return FATAL_EXIT_CODE;
4572
 
4573
  for (i = 0; i < MAX_ATTRS_INDEX; i++)
4574
    for (attr = attrs[i]; attr; attr = attr->next)
4575
      fill_attr (attr);
4576
 
4577
  /* Construct extra attributes for `length'.  */
4578
  make_length_attrs ();
4579
 
4580
  /* Perform any possible optimizations to speed up compilation.  */
4581
  optimize_attrs ();
4582
 
4583
  /* Now write out all the `gen_attr_...' routines.  Do these before the
4584
     special routines so that they get defined before they are used.  */
4585
 
4586
  for (i = 0; i < MAX_ATTRS_INDEX; i++)
4587
    for (attr = attrs[i]; attr; attr = attr->next)
4588
      {
4589
        if (! attr->is_special && ! attr->is_const)
4590
          {
4591
            int insn_alts_p;
4592
 
4593
            insn_alts_p
4594
              = (attr->name [0] == '*'
4595
                 && strcmp (&attr->name[1], INSN_ALTS_FUNC_NAME) == 0);
4596
            if (insn_alts_p)
4597
              printf ("\n#if AUTOMATON_ALTS\n");
4598
            write_attr_get (attr);
4599
            if (insn_alts_p)
4600
              printf ("#endif\n\n");
4601
          }
4602
      }
4603
 
4604
  /* Write out delay eligibility information, if DEFINE_DELAY present.
4605
     (The function to compute the number of delay slots will be written
4606
     below.)  */
4607
  if (num_delays)
4608
    {
4609
      write_eligible_delay ("delay");
4610
      if (have_annul_true)
4611
        write_eligible_delay ("annul_true");
4612
      if (have_annul_false)
4613
        write_eligible_delay ("annul_false");
4614
    }
4615
 
4616
  /* Output code for pipeline hazards recognition based on DFA
4617
     (deterministic finite-state automata).  */
4618
  if (num_dfa_decls)
4619
    write_automata ();
4620
 
4621
  /* Write out constant delay slot info.  */
4622
  write_const_num_delay_slots ();
4623
 
4624
  write_length_unit_log ();
4625
 
4626
  fflush (stdout);
4627
  return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
4628
}
4629
 
4630
/* Define this so we can link with print-rtl.o to get debug_rtx function.  */
4631
const char *
4632
get_insn_name (int code ATTRIBUTE_UNUSED)
4633
{
4634
  return NULL;
4635
}

powered by: WebSVN 2.1.0

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