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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gcc-4.2.2/] [gcc/] [genattrtab.c] - Blame information for rev 816

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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