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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gcc-4.5.1/] [gcc/] [genattrtab.c] - Blame information for rev 859

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

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

powered by: WebSVN 2.1.0

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