genattrtab.c revision 50397
1/* Generate code from machine description to compute values of attributes.
2   Copyright (C) 1991, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
3   Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
4
5This file is part of GNU CC.
6
7GNU CC is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12GNU CC is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU CC; see the file COPYING.  If not, write to
19the Free Software Foundation, 59 Temple Place - Suite 330,
20Boston, MA 02111-1307, USA.  */
21
22/* This program handles insn attributes and the DEFINE_DELAY and
23   DEFINE_FUNCTION_UNIT definitions.
24
25   It produces a series of functions named `get_attr_...', one for each insn
26   attribute.  Each of these is given the rtx for an insn and returns a member
27   of the enum for the attribute.
28
29   These subroutines have the form of a `switch' on the INSN_CODE (via
30   `recog_memoized').  Each case either returns a constant attribute value
31   or a value that depends on tests on other attributes, the form of
32   operands, or some random C expression (encoded with a SYMBOL_REF
33   expression).
34
35   If the attribute `alternative', or a random C expression is present,
36   `constrain_operands' is called.  If either of these cases of a reference to
37   an operand is found, `insn_extract' is called.
38
39   The special attribute `length' is also recognized.  For this operand,
40   expressions involving the address of an operand or the current insn,
41   (address (pc)), are valid.  In this case, an initial pass is made to
42   set all lengths that do not depend on address.  Those that do are set to
43   the maximum length.  Then each insn that depends on an address is checked
44   and possibly has its length changed.  The process repeats until no further
45   changed are made.  The resulting lengths are saved for use by
46   `get_attr_length'.
47
48   A special form of DEFINE_ATTR, where the expression for default value is a
49   CONST expression, indicates an attribute that is constant for a given run
50   of the compiler.  The subroutine generated for these attributes has no
51   parameters as it does not depend on any particular insn.  Constant
52   attributes are typically used to specify which variety of processor is
53   used.
54
55   Internal attributes are defined to handle DEFINE_DELAY and
56   DEFINE_FUNCTION_UNIT.  Special routines are output for these cases.
57
58   This program works by keeping a list of possible values for each attribute.
59   These include the basic attribute choices, default values for attribute, and
60   all derived quantities.
61
62   As the description file is read, the definition for each insn is saved in a
63   `struct insn_def'.   When the file reading is complete, a `struct insn_ent'
64   is created for each insn and chained to the corresponding attribute value,
65   either that specified, or the default.
66
67   An optimization phase is then run.  This simplifies expressions for each
68   insn.  EQ_ATTR tests are resolved, whenever possible, to a test that
69   indicates when the attribute has the specified value for the insn.  This
70   avoids recursive calls during compilation.
71
72   The strategy used when processing DEFINE_DELAY and DEFINE_FUNCTION_UNIT
73   definitions is to create arbitrarily complex expressions and have the
74   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' (RTX_UNCHANGING_P): This rtx is fully simplified
89      independent of the insn code.
90   `in_struct' (MEM_IN_STRUCT_P): This rtx is fully simplified
91      for the insn code currently being processed (see optimize_attrs).
92   `integrated' (RTX_INTEGRATED_P): This rtx is permanent and unique
93      (see attr_rtx).
94   `volatil' (MEM_VOLATILE_P): During simplify_by_exploding the value of an
95      EQ_ATTR rtx is true if !volatil and false if volatil.  */
96
97
98#include "hconfig.h"
99/* varargs must always be included after *config.h, but before stdio.h.  */
100#ifdef __STDC__
101#include <stdarg.h>
102#else
103#include <varargs.h>
104#endif
105#include "system.h"
106#include "rtl.h"
107#include "insn-config.h"	/* For REGISTER_CONSTRAINTS */
108
109#ifdef HAVE_SYS_RESOURCE_H
110# include <sys/resource.h>
111#endif
112
113/* We must include obstack.h after <sys/time.h>, to avoid lossage with
114   /usr/include/sys/stdtypes.h on Sun OS 4.x.  */
115#include "obstack.h"
116
117static struct obstack obstack, obstack1, obstack2;
118struct obstack *rtl_obstack = &obstack;
119struct obstack *hash_obstack = &obstack1;
120struct obstack *temp_obstack = &obstack2;
121
122#define obstack_chunk_alloc xmalloc
123#define obstack_chunk_free free
124
125/* Define this so we can link with print-rtl.o to get debug_rtx function.  */
126char **insn_name_ptr = 0;
127
128static void fatal PVPROTO ((char *, ...)) ATTRIBUTE_PRINTF_1;
129void fancy_abort PROTO((void));
130
131/* enough space to reserve for printing out ints */
132#define MAX_DIGITS (HOST_BITS_PER_INT * 3 / 10 + 3)
133
134/* Define structures used to record attributes and values.  */
135
136/* As each DEFINE_INSN, DEFINE_PEEPHOLE, or DEFINE_ASM_ATTRIBUTES is
137   encountered, we store all the relevant information into a
138   `struct insn_def'.  This is done to allow attribute definitions to occur
139   anywhere in the file.  */
140
141struct insn_def
142{
143  int insn_code;		/* Instruction number.  */
144  int insn_index;		/* Expression numer in file, for errors.  */
145  struct insn_def *next;	/* Next insn in chain.  */
146  rtx def;			/* The DEFINE_...  */
147  int num_alternatives;		/* Number of alternatives.  */
148  int vec_idx;			/* Index of attribute vector in `def'.  */
149};
150
151/* Once everything has been read in, we store in each attribute value a list
152   of insn codes that have that value.  Here is the structure used for the
153   list.  */
154
155struct insn_ent
156{
157  int insn_code;		/* Instruction number.  */
158  int insn_index;		/* Index of definition in file */
159  struct insn_ent *next;	/* Next in chain.  */
160};
161
162/* Each value of an attribute (either constant or computed) is assigned a
163   structure which is used as the listhead of the insns that have that
164   value.  */
165
166struct attr_value
167{
168  rtx value;			/* Value of attribute.  */
169  struct attr_value *next;	/* Next attribute value in chain.  */
170  struct insn_ent *first_insn;	/* First insn with this value.  */
171  int num_insns;		/* Number of insns with this value.  */
172  int has_asm_insn;		/* True if this value used for `asm' insns */
173};
174
175/* Structure for each attribute.  */
176
177struct attr_desc
178{
179  char *name;			/* Name of attribute.  */
180  struct attr_desc *next;	/* Next attribute.  */
181  unsigned is_numeric	: 1;	/* Values of this attribute are numeric.  */
182  unsigned negative_ok	: 1;	/* Allow negative numeric values.  */
183  unsigned unsigned_p	: 1;	/* Make the output function unsigned int.  */
184  unsigned is_const	: 1;	/* Attribute value constant for each run.  */
185  unsigned is_special	: 1;	/* Don't call `write_attr_set'.  */
186  unsigned func_units_p	: 1;	/* this is the function_units attribute */
187  unsigned blockage_p	: 1;	/* this is the blockage range function */
188  struct attr_value *first_value; /* First value of this attribute.  */
189  struct attr_value *default_val; /* Default value for this attribute.  */
190};
191
192#define NULL_ATTR (struct attr_desc *) NULL
193
194/* A range of values.  */
195
196struct range
197{
198  int min;
199  int max;
200};
201
202/* Structure for each DEFINE_DELAY.  */
203
204struct delay_desc
205{
206  rtx def;			/* DEFINE_DELAY expression.  */
207  struct delay_desc *next;	/* Next DEFINE_DELAY.  */
208  int num;			/* Number of DEFINE_DELAY, starting at 1.  */
209};
210
211/* Record information about each DEFINE_FUNCTION_UNIT.  */
212
213struct function_unit_op
214{
215  rtx condexp;			/* Expression TRUE for applicable insn.  */
216  struct function_unit_op *next; /* Next operation for this function unit.  */
217  int num;			/* Ordinal for this operation type in unit.  */
218  int ready;			/* Cost until data is ready.  */
219  int issue_delay;		/* Cost until unit can accept another insn.  */
220  rtx conflict_exp;		/* Expression TRUE for insns incurring issue delay.  */
221  rtx issue_exp;		/* Expression computing issue delay.  */
222};
223
224/* Record information about each function unit mentioned in a
225   DEFINE_FUNCTION_UNIT.  */
226
227struct function_unit
228{
229  char *name;			/* Function unit name.  */
230  struct function_unit *next;	/* Next function unit.  */
231  int num;			/* Ordinal of this unit type.  */
232  int multiplicity;		/* Number of units of this type.  */
233  int simultaneity;		/* Maximum number of simultaneous insns
234				   on this function unit or 0 if unlimited.  */
235  rtx condexp;			/* Expression TRUE for insn needing unit.  */
236  int num_opclasses;		/* Number of different operation types.  */
237  struct function_unit_op *ops;	/* Pointer to first operation type.  */
238  int needs_conflict_function;	/* Nonzero if a conflict function required.  */
239  int needs_blockage_function;	/* Nonzero if a blockage function required.  */
240  int needs_range_function;	/* Nonzero if blockage range function needed.*/
241  rtx default_cost;		/* Conflict cost, if constant.  */
242  struct range issue_delay;	/* Range of issue delay values.  */
243  int max_blockage;		/* Maximum time an insn blocks the unit.  */
244};
245
246/* Listheads of above structures.  */
247
248/* This one is indexed by the first character of the attribute name.  */
249#define MAX_ATTRS_INDEX 256
250static struct attr_desc *attrs[MAX_ATTRS_INDEX];
251static struct insn_def *defs;
252static struct delay_desc *delays;
253static struct function_unit *units;
254
255/* An expression where all the unknown terms are EQ_ATTR tests can be
256   rearranged into a COND provided we can enumerate all possible
257   combinations of the unknown values.  The set of combinations become the
258   tests of the COND; the value of the expression given that combination is
259   computed and becomes the corresponding value.  To do this, we must be
260   able to enumerate all values for each attribute used in the expression
261   (currently, we give up if we find a numeric attribute).
262
263   If the set of EQ_ATTR tests used in an expression tests the value of N
264   different attributes, the list of all possible combinations can be made
265   by walking the N-dimensional attribute space defined by those
266   attributes.  We record each of these as a struct dimension.
267
268   The algorithm relies on sharing EQ_ATTR nodes: if two nodes in an
269   expression are the same, the will also have the same address.  We find
270   all the EQ_ATTR nodes by marking them MEM_VOLATILE_P.  This bit later
271   represents the value of an EQ_ATTR node, so once all nodes are marked,
272   they are also given an initial value of FALSE.
273
274   We then separate the set of EQ_ATTR nodes into dimensions for each
275   attribute and put them on the VALUES list.  Terms are added as needed by
276   `add_values_to_cover' so that all possible values of the attribute are
277   tested.
278
279   Each dimension also has a current value.  This is the node that is
280   currently considered to be TRUE.  If this is one of the nodes added by
281   `add_values_to_cover', all the EQ_ATTR tests in the original expression
282   will be FALSE.  Otherwise, only the CURRENT_VALUE will be true.
283
284   NUM_VALUES is simply the length of the VALUES list and is there for
285   convenience.
286
287   Once the dimensions are created, the algorithm enumerates all possible
288   values and computes the current value of the given expression.  */
289
290struct dimension
291{
292  struct attr_desc *attr;	/* Attribute for this dimension.  */
293  rtx values;			/* List of attribute values used.  */
294  rtx current_value;		/* Position in the list for the TRUE value.  */
295  int num_values;		/* Length of the values list.  */
296};
297
298/* Other variables.  */
299
300static int insn_code_number;
301static int insn_index_number;
302static int got_define_asm_attributes;
303static int must_extract;
304static int must_constrain;
305static int address_used;
306static int length_used;
307static int num_delays;
308static int have_annul_true, have_annul_false;
309static int num_units, num_unit_opclasses;
310static int num_insn_ents;
311
312/* Used as operand to `operate_exp':  */
313
314enum operator {PLUS_OP, MINUS_OP, POS_MINUS_OP, EQ_OP, OR_OP, ORX_OP, MAX_OP, MIN_OP, RANGE_OP};
315
316/* Stores, for each insn code, the number of constraint alternatives.  */
317
318static int *insn_n_alternatives;
319
320/* Stores, for each insn code, a bitmap that has bits on for each possible
321   alternative.  */
322
323static int *insn_alternatives;
324
325/* If nonzero, assume that the `alternative' attr has this value.
326   This is the hashed, unique string for the numeral
327   whose value is chosen alternative.  */
328
329static char *current_alternative_string;
330
331/* Used to simplify expressions.  */
332
333static rtx true_rtx, false_rtx;
334
335/* Used to reduce calls to `strcmp' */
336
337static char *alternative_name;
338
339/* Indicate that REG_DEAD notes are valid if dead_or_set_p is ever
340   called.  */
341
342int reload_completed = 0;
343
344/* Some machines test `optimize' in macros called from rtlanal.c, so we need
345   to define it here.  */
346
347int optimize = 0;
348
349/* Simplify an expression.  Only call the routine if there is something to
350   simplify.  */
351#define SIMPLIFY_TEST_EXP(EXP,INSN_CODE,INSN_INDEX)	\
352  (RTX_UNCHANGING_P (EXP) || MEM_IN_STRUCT_P (EXP) ? (EXP)	\
353   : simplify_test_exp (EXP, INSN_CODE, INSN_INDEX))
354
355/* Simplify (eq_attr ("alternative") ...)
356   when we are working with a particular alternative.  */
357#define SIMPLIFY_ALTERNATIVE(EXP)				\
358  if (current_alternative_string				\
359      && GET_CODE ((EXP)) == EQ_ATTR				\
360      && XSTR ((EXP), 0) == alternative_name)			\
361    (EXP) = (XSTR ((EXP), 1) == current_alternative_string	\
362	    ? true_rtx : false_rtx);
363
364/* These are referenced by rtlanal.c and hence need to be defined somewhere.
365   They won't actually be used.  */
366
367struct _global_rtl global_rtl;
368rtx pic_offset_table_rtx;
369
370static void attr_hash_add_rtx	PROTO((int, rtx));
371static void attr_hash_add_string PROTO((int, char *));
372static rtx attr_rtx		PVPROTO((enum rtx_code, ...));
373static char *attr_printf	PVPROTO((int, char *, ...));
374static char *attr_string        PROTO((char *, int));
375static rtx check_attr_test	PROTO((rtx, int));
376static rtx check_attr_value	PROTO((rtx, struct attr_desc *));
377static rtx convert_set_attr_alternative PROTO((rtx, int, int, int));
378static rtx convert_set_attr	PROTO((rtx, int, int, int));
379static void check_defs		PROTO((void));
380#if 0
381static rtx convert_const_symbol_ref PROTO((rtx, struct attr_desc *));
382#endif
383static rtx make_canonical	PROTO((struct attr_desc *, rtx));
384static struct attr_value *get_attr_value PROTO((rtx, struct attr_desc *, int));
385static rtx copy_rtx_unchanging	PROTO((rtx));
386static rtx copy_boolean		PROTO((rtx));
387static void expand_delays	PROTO((void));
388static rtx operate_exp		PROTO((enum operator, rtx, rtx));
389static void expand_units	PROTO((void));
390static rtx simplify_knowing	PROTO((rtx, rtx));
391static rtx encode_units_mask	PROTO((rtx));
392static void fill_attr		PROTO((struct attr_desc *));
393/* dpx2 compiler chokes if we specify the arg types of the args.  */
394static rtx substitute_address	PROTO((rtx, rtx (*) (), rtx (*) ()));
395static void make_length_attrs	PROTO((void));
396static rtx identity_fn		PROTO((rtx));
397static rtx zero_fn		PROTO((rtx));
398static rtx one_fn		PROTO((rtx));
399static rtx max_fn		PROTO((rtx));
400static void write_length_unit_log PROTO ((void));
401static rtx simplify_cond	PROTO((rtx, int, int));
402#if 0
403static rtx simplify_by_alternatives PROTO((rtx, int, int));
404#endif
405static rtx simplify_by_exploding PROTO((rtx));
406static int find_and_mark_used_attributes PROTO((rtx, rtx *, int *));
407static void unmark_used_attributes PROTO((rtx, struct dimension *, int));
408static int add_values_to_cover	PROTO((struct dimension *));
409static int increment_current_value PROTO((struct dimension *, int));
410static rtx test_for_current_value PROTO((struct dimension *, int));
411static rtx simplify_with_current_value PROTO((rtx, struct dimension *, int));
412static rtx simplify_with_current_value_aux PROTO((rtx));
413static void clear_struct_flag PROTO((rtx));
414static int count_sub_rtxs    PROTO((rtx, int));
415static void remove_insn_ent  PROTO((struct attr_value *, struct insn_ent *));
416static void insert_insn_ent  PROTO((struct attr_value *, struct insn_ent *));
417static rtx insert_right_side	PROTO((enum rtx_code, rtx, rtx, int, int));
418static rtx make_alternative_compare PROTO((int));
419static int compute_alternative_mask PROTO((rtx, enum rtx_code));
420static rtx evaluate_eq_attr	PROTO((rtx, rtx, int, int));
421static rtx simplify_and_tree	PROTO((rtx, rtx *, int, int));
422static rtx simplify_or_tree	PROTO((rtx, rtx *, int, int));
423static rtx simplify_test_exp	PROTO((rtx, int, int));
424static void optimize_attrs	PROTO((void));
425static void gen_attr		PROTO((rtx));
426static int count_alternatives	PROTO((rtx));
427static int compares_alternatives_p PROTO((rtx));
428static int contained_in_p	PROTO((rtx, rtx));
429static void gen_insn		PROTO((rtx));
430static void gen_delay		PROTO((rtx));
431static void gen_unit		PROTO((rtx));
432static void write_test_expr	PROTO((rtx, int));
433static int max_attr_value	PROTO((rtx));
434static int or_attr_value	PROTO((rtx));
435static void walk_attr_value	PROTO((rtx));
436static void write_attr_get	PROTO((struct attr_desc *));
437static rtx eliminate_known_true PROTO((rtx, rtx, int, int));
438static void write_attr_set	PROTO((struct attr_desc *, int, rtx, char *,
439				       char *, rtx, int, int));
440static void write_attr_case	PROTO((struct attr_desc *, struct attr_value *,
441				       int, char *, char *, int, rtx));
442static void write_unit_name	PROTO((char *, int, char *));
443static void write_attr_valueq	PROTO((struct attr_desc *, char *));
444static void write_attr_value	PROTO((struct attr_desc *, rtx));
445static void write_upcase	PROTO((char *));
446static void write_indent	PROTO((int));
447static void write_eligible_delay PROTO((char *));
448static void write_function_unit_info PROTO((void));
449static void write_complex_function PROTO((struct function_unit *, char *,
450					  char *));
451static int write_expr_attr_cache PROTO((rtx, struct attr_desc *));
452static void write_toplevel_expr	PROTO((rtx));
453static int n_comma_elts		PROTO((char *));
454static char *next_comma_elt	PROTO((char **));
455static struct attr_desc *find_attr PROTO((char *, int));
456static void make_internal_attr	PROTO((char *, rtx, int));
457static struct attr_value *find_most_used  PROTO((struct attr_desc *));
458static rtx find_single_value	PROTO((struct attr_desc *));
459static rtx make_numeric_value	PROTO((int));
460static void extend_range	PROTO((struct range *, int, int));
461char *xrealloc			PROTO((char *, unsigned));
462char *xmalloc			PROTO((unsigned));
463
464#define oballoc(size) obstack_alloc (hash_obstack, size)
465
466
467/* Hash table for sharing RTL and strings.  */
468
469/* Each hash table slot is a bucket containing a chain of these structures.
470   Strings are given negative hash codes; RTL expressions are given positive
471   hash codes.  */
472
473struct attr_hash
474{
475  struct attr_hash *next;	/* Next structure in the bucket.  */
476  int hashcode;			/* Hash code of this rtx or string.  */
477  union
478    {
479      char *str;		/* The string (negative hash codes) */
480      rtx rtl;			/* or the RTL recorded here.  */
481    } u;
482};
483
484/* Now here is the hash table.  When recording an RTL, it is added to
485   the slot whose index is the hash code mod the table size.  Note
486   that the hash table is used for several kinds of RTL (see attr_rtx)
487   and for strings.  While all these live in the same table, they are
488   completely independent, and the hash code is computed differently
489   for each.  */
490
491#define RTL_HASH_SIZE 4093
492struct attr_hash *attr_hash_table[RTL_HASH_SIZE];
493
494/* Here is how primitive or already-shared RTL's hash
495   codes are made.  */
496#define RTL_HASH(RTL) ((long) (RTL) & 0777777)
497
498/* Add an entry to the hash table for RTL with hash code HASHCODE.  */
499
500static void
501attr_hash_add_rtx (hashcode, rtl)
502     int hashcode;
503     rtx rtl;
504{
505  register struct attr_hash *h;
506
507  h = (struct attr_hash *) obstack_alloc (hash_obstack,
508					  sizeof (struct attr_hash));
509  h->hashcode = hashcode;
510  h->u.rtl = rtl;
511  h->next = attr_hash_table[hashcode % RTL_HASH_SIZE];
512  attr_hash_table[hashcode % RTL_HASH_SIZE] = h;
513}
514
515/* Add an entry to the hash table for STRING with hash code HASHCODE.  */
516
517static void
518attr_hash_add_string (hashcode, str)
519     int hashcode;
520     char *str;
521{
522  register struct attr_hash *h;
523
524  h = (struct attr_hash *) obstack_alloc (hash_obstack,
525					  sizeof (struct attr_hash));
526  h->hashcode = -hashcode;
527  h->u.str = str;
528  h->next = attr_hash_table[hashcode % RTL_HASH_SIZE];
529  attr_hash_table[hashcode % RTL_HASH_SIZE] = h;
530}
531
532/* Generate an RTL expression, but avoid duplicates.
533   Set the RTX_INTEGRATED_P flag for these permanent objects.
534
535   In some cases we cannot uniquify; then we return an ordinary
536   impermanent rtx with RTX_INTEGRATED_P clear.
537
538   Args are like gen_rtx, but without the mode:
539
540   rtx attr_rtx (code, [element1, ..., elementn])  */
541
542/*VARARGS1*/
543static rtx
544attr_rtx VPROTO((enum rtx_code code, ...))
545{
546#ifndef __STDC__
547  enum rtx_code code;
548#endif
549  va_list p;
550  register int i;		/* Array indices...			*/
551  register char *fmt;		/* Current rtx's format...		*/
552  register rtx rt_val;		/* RTX to return to caller...		*/
553  int hashcode;
554  register struct attr_hash *h;
555  struct obstack *old_obstack = rtl_obstack;
556
557  VA_START (p, code);
558
559#ifndef __STDC__
560  code = va_arg (p, enum rtx_code);
561#endif
562
563  /* For each of several cases, search the hash table for an existing entry.
564     Use that entry if one is found; otherwise create a new RTL and add it
565     to the table.  */
566
567  if (GET_RTX_CLASS (code) == '1')
568    {
569      rtx arg0 = va_arg (p, rtx);
570
571      /* A permanent object cannot point to impermanent ones.  */
572      if (! RTX_INTEGRATED_P (arg0))
573	{
574	  rt_val = rtx_alloc (code);
575	  XEXP (rt_val, 0) = arg0;
576	  va_end (p);
577	  return rt_val;
578	}
579
580      hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0));
581      for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
582	if (h->hashcode == hashcode
583	    && GET_CODE (h->u.rtl) == code
584	    && XEXP (h->u.rtl, 0) == arg0)
585	  goto found;
586
587      if (h == 0)
588	{
589	  rtl_obstack = hash_obstack;
590	  rt_val = rtx_alloc (code);
591	  XEXP (rt_val, 0) = arg0;
592	}
593    }
594  else if (GET_RTX_CLASS (code) == 'c'
595	   || GET_RTX_CLASS (code) == '2'
596	   || GET_RTX_CLASS (code) == '<')
597    {
598      rtx arg0 = va_arg (p, rtx);
599      rtx arg1 = va_arg (p, rtx);
600
601      /* A permanent object cannot point to impermanent ones.  */
602      if (! RTX_INTEGRATED_P (arg0) || ! RTX_INTEGRATED_P (arg1))
603	{
604	  rt_val = rtx_alloc (code);
605	  XEXP (rt_val, 0) = arg0;
606	  XEXP (rt_val, 1) = arg1;
607	  va_end (p);
608	  return rt_val;
609	}
610
611      hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0) + RTL_HASH (arg1));
612      for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
613	if (h->hashcode == hashcode
614	    && GET_CODE (h->u.rtl) == code
615	    && XEXP (h->u.rtl, 0) == arg0
616	    && XEXP (h->u.rtl, 1) == arg1)
617	  goto found;
618
619      if (h == 0)
620	{
621	  rtl_obstack = hash_obstack;
622	  rt_val = rtx_alloc (code);
623	  XEXP (rt_val, 0) = arg0;
624	  XEXP (rt_val, 1) = arg1;
625	}
626    }
627  else if (GET_RTX_LENGTH (code) == 1
628	   && GET_RTX_FORMAT (code)[0] == 's')
629    {
630      char * arg0 = va_arg (p, char *);
631
632      if (code == SYMBOL_REF)
633	arg0 = attr_string (arg0, strlen (arg0));
634
635      hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0));
636      for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
637	if (h->hashcode == hashcode
638	    && GET_CODE (h->u.rtl) == code
639	    && XSTR (h->u.rtl, 0) == arg0)
640	  goto found;
641
642      if (h == 0)
643	{
644	  rtl_obstack = hash_obstack;
645	  rt_val = rtx_alloc (code);
646	  XSTR (rt_val, 0) = arg0;
647	}
648    }
649  else if (GET_RTX_LENGTH (code) == 2
650	   && GET_RTX_FORMAT (code)[0] == 's'
651	   && GET_RTX_FORMAT (code)[1] == 's')
652    {
653      char *arg0 = va_arg (p, char *);
654      char *arg1 = va_arg (p, char *);
655
656      hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0) + RTL_HASH (arg1));
657      for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
658	if (h->hashcode == hashcode
659	    && GET_CODE (h->u.rtl) == code
660	    && XSTR (h->u.rtl, 0) == arg0
661	    && XSTR (h->u.rtl, 1) == arg1)
662	  goto found;
663
664      if (h == 0)
665	{
666	  rtl_obstack = hash_obstack;
667	  rt_val = rtx_alloc (code);
668	  XSTR (rt_val, 0) = arg0;
669	  XSTR (rt_val, 1) = arg1;
670	}
671    }
672  else if (code == CONST_INT)
673    {
674      HOST_WIDE_INT arg0 = va_arg (p, HOST_WIDE_INT);
675      if (arg0 == 0)
676	return false_rtx;
677      if (arg0 == 1)
678	return true_rtx;
679      goto nohash;
680    }
681  else
682    {
683    nohash:
684      rt_val = rtx_alloc (code);	/* Allocate the storage space.  */
685
686      fmt = GET_RTX_FORMAT (code);	/* Find the right format...  */
687      for (i = 0; i < GET_RTX_LENGTH (code); i++)
688	{
689	  switch (*fmt++)
690	    {
691	    case '0':		/* Unused field.  */
692	      break;
693
694	    case 'i':		/* An integer?  */
695	      XINT (rt_val, i) = va_arg (p, int);
696	      break;
697
698	    case 'w':		/* A wide integer? */
699	      XWINT (rt_val, i) = va_arg (p, HOST_WIDE_INT);
700	      break;
701
702	    case 's':		/* A string?  */
703	      XSTR (rt_val, i) = va_arg (p, char *);
704	      break;
705
706	    case 'e':		/* An expression?  */
707	    case 'u':		/* An insn?  Same except when printing.  */
708	      XEXP (rt_val, i) = va_arg (p, rtx);
709	      break;
710
711	    case 'E':		/* An RTX vector?  */
712	      XVEC (rt_val, i) = va_arg (p, rtvec);
713	      break;
714
715	    default:
716	      abort();
717	    }
718	}
719      va_end (p);
720      return rt_val;
721    }
722
723  rtl_obstack = old_obstack;
724  va_end (p);
725  attr_hash_add_rtx (hashcode, rt_val);
726  RTX_INTEGRATED_P (rt_val) = 1;
727  return rt_val;
728
729 found:
730  va_end (p);
731  return h->u.rtl;
732}
733
734/* Create a new string printed with the printf line arguments into a space
735   of at most LEN bytes:
736
737   rtx attr_printf (len, format, [arg1, ..., argn])  */
738
739/*VARARGS2*/
740static char *
741attr_printf VPROTO((register int len, char *fmt, ...))
742{
743#ifndef __STDC__
744  register int len;
745  char *fmt;
746#endif
747  va_list p;
748  register char *str;
749
750  VA_START (p, fmt);
751
752#ifndef __STDC__
753  len = va_arg (p, int);
754  fmt = va_arg (p, char *);
755#endif
756
757  /* Print the string into a temporary location.  */
758  str = (char *) alloca (len);
759  vsprintf (str, fmt, p);
760  va_end (p);
761
762  return attr_string (str, strlen (str));
763}
764
765rtx
766attr_eq (name, value)
767     char *name, *value;
768{
769  return attr_rtx (EQ_ATTR, attr_string (name, strlen (name)),
770		   attr_string (value, strlen (value)));
771}
772
773char *
774attr_numeral (n)
775     int n;
776{
777  return XSTR (make_numeric_value (n), 0);
778}
779
780/* Return a permanent (possibly shared) copy of a string STR (not assumed
781   to be null terminated) with LEN bytes.  */
782
783static char *
784attr_string (str, len)
785     char *str;
786     int len;
787{
788  register struct attr_hash *h;
789  int hashcode;
790  int i;
791  register char *new_str;
792
793  /* Compute the hash code.  */
794  hashcode = (len + 1) * 613 + (unsigned)str[0];
795  for (i = 1; i <= len; i += 2)
796    hashcode = ((hashcode * 613) + (unsigned)str[i]);
797  if (hashcode < 0)
798    hashcode = -hashcode;
799
800  /* Search the table for the string.  */
801  for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
802    if (h->hashcode == -hashcode && h->u.str[0] == str[0]
803	&& !strncmp (h->u.str, str, len))
804      return h->u.str;			/* <-- return if found.  */
805
806  /* Not found; create a permanent copy and add it to the hash table.  */
807  new_str = (char *) obstack_alloc (hash_obstack, len + 1);
808  bcopy (str, new_str, len);
809  new_str[len] = '\0';
810  attr_hash_add_string (hashcode, new_str);
811
812  return new_str;			/* Return the new string.  */
813}
814
815/* Check two rtx's for equality of contents,
816   taking advantage of the fact that if both are hashed
817   then they can't be equal unless they are the same object.  */
818
819int
820attr_equal_p (x, y)
821     rtx x, y;
822{
823  return (x == y || (! (RTX_INTEGRATED_P (x) && RTX_INTEGRATED_P (y))
824		     && rtx_equal_p (x, y)));
825}
826
827/* Copy an attribute value expression,
828   descending to all depths, but not copying any
829   permanent hashed subexpressions.  */
830
831rtx
832attr_copy_rtx (orig)
833     register rtx orig;
834{
835  register rtx copy;
836  register int i, j;
837  register RTX_CODE code;
838  register char *format_ptr;
839
840  /* No need to copy a permanent object.  */
841  if (RTX_INTEGRATED_P (orig))
842    return orig;
843
844  code = GET_CODE (orig);
845
846  switch (code)
847    {
848    case REG:
849    case QUEUED:
850    case CONST_INT:
851    case CONST_DOUBLE:
852    case SYMBOL_REF:
853    case CODE_LABEL:
854    case PC:
855    case CC0:
856      return orig;
857
858    default:
859      break;
860    }
861
862  copy = rtx_alloc (code);
863  PUT_MODE (copy, GET_MODE (orig));
864  copy->in_struct = orig->in_struct;
865  copy->volatil = orig->volatil;
866  copy->unchanging = orig->unchanging;
867  copy->integrated = orig->integrated;
868
869  format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
870
871  for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
872    {
873      switch (*format_ptr++)
874	{
875	case 'e':
876	  XEXP (copy, i) = XEXP (orig, i);
877	  if (XEXP (orig, i) != NULL)
878	    XEXP (copy, i) = attr_copy_rtx (XEXP (orig, i));
879	  break;
880
881	case 'E':
882	case 'V':
883	  XVEC (copy, i) = XVEC (orig, i);
884	  if (XVEC (orig, i) != NULL)
885	    {
886	      XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
887	      for (j = 0; j < XVECLEN (copy, i); j++)
888		XVECEXP (copy, i, j) = attr_copy_rtx (XVECEXP (orig, i, j));
889	    }
890	  break;
891
892	case 'n':
893	case 'i':
894	  XINT (copy, i) = XINT (orig, i);
895	  break;
896
897	case 'w':
898	  XWINT (copy, i) = XWINT (orig, i);
899	  break;
900
901	case 's':
902	case 'S':
903	  XSTR (copy, i) = XSTR (orig, i);
904	  break;
905
906	default:
907	  abort ();
908	}
909    }
910  return copy;
911}
912
913/* Given a test expression for an attribute, ensure it is validly formed.
914   IS_CONST indicates whether the expression is constant for each compiler
915   run (a constant expression may not test any particular insn).
916
917   Convert (eq_attr "att" "a1,a2") to (ior (eq_attr ... ) (eq_attrq ..))
918   and (eq_attr "att" "!a1") to (not (eq_attr "att" "a1")).  Do the latter
919   test first so that (eq_attr "att" "!a1,a2,a3") works as expected.
920
921   Update the string address in EQ_ATTR expression to be the same used
922   in the attribute (or `alternative_name') to speed up subsequent
923   `find_attr' calls and eliminate most `strcmp' calls.
924
925   Return the new expression, if any.   */
926
927static rtx
928check_attr_test (exp, is_const)
929     rtx exp;
930     int is_const;
931{
932  struct attr_desc *attr;
933  struct attr_value *av;
934  char *name_ptr, *p;
935  rtx orexp, newexp;
936
937  switch (GET_CODE (exp))
938    {
939    case EQ_ATTR:
940      /* Handle negation test.  */
941      if (XSTR (exp, 1)[0] == '!')
942	return check_attr_test (attr_rtx (NOT,
943					  attr_eq (XSTR (exp, 0),
944						   &XSTR (exp, 1)[1])),
945				is_const);
946
947      else if (n_comma_elts (XSTR (exp, 1)) == 1)
948	{
949	  attr = find_attr (XSTR (exp, 0), 0);
950	  if (attr == NULL)
951	    {
952	      if (! strcmp (XSTR (exp, 0), "alternative"))
953		{
954		  XSTR (exp, 0) = alternative_name;
955		  /* This can't be simplified any further.  */
956		  RTX_UNCHANGING_P (exp) = 1;
957		  return exp;
958		}
959	      else
960		fatal ("Unknown attribute `%s' in EQ_ATTR", XSTR (exp, 0));
961	    }
962
963	  if (is_const && ! attr->is_const)
964	    fatal ("Constant expression uses insn attribute `%s' in EQ_ATTR",
965		   XSTR (exp, 0));
966
967	  /* Copy this just to make it permanent,
968	     so expressions using it can be permanent too.  */
969	  exp = attr_eq (XSTR (exp, 0), XSTR (exp, 1));
970
971	  /* It shouldn't be possible to simplify the value given to a
972	     constant attribute, so don't expand this until it's time to
973	     write the test expression.  */
974	  if (attr->is_const)
975	    RTX_UNCHANGING_P (exp) = 1;
976
977	  if (attr->is_numeric)
978	    {
979	      for (p = XSTR (exp, 1); *p; p++)
980		if (*p < '0' || *p > '9')
981		   fatal ("Attribute `%s' takes only numeric values",
982			  XSTR (exp, 0));
983	    }
984	  else
985	    {
986	      for (av = attr->first_value; av; av = av->next)
987		if (GET_CODE (av->value) == CONST_STRING
988		    && ! strcmp (XSTR (exp, 1), XSTR (av->value, 0)))
989		  break;
990
991	      if (av == NULL)
992		fatal ("Unknown value `%s' for `%s' attribute",
993		       XSTR (exp, 1), XSTR (exp, 0));
994	    }
995	}
996      else
997	{
998	  /* Make an IOR tree of the possible values.  */
999	  orexp = false_rtx;
1000	  name_ptr = XSTR (exp, 1);
1001	  while ((p = next_comma_elt (&name_ptr)) != NULL)
1002	    {
1003	      newexp = attr_eq (XSTR (exp, 0), p);
1004	      orexp = insert_right_side (IOR, orexp, newexp, -2, -2);
1005	    }
1006
1007	  return check_attr_test (orexp, is_const);
1008	}
1009      break;
1010
1011    case ATTR_FLAG:
1012      break;
1013
1014    case CONST_INT:
1015      /* Either TRUE or FALSE.  */
1016      if (XWINT (exp, 0))
1017	return true_rtx;
1018      else
1019	return false_rtx;
1020
1021    case IOR:
1022    case AND:
1023      XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), is_const);
1024      XEXP (exp, 1) = check_attr_test (XEXP (exp, 1), is_const);
1025      break;
1026
1027    case NOT:
1028      XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), is_const);
1029      break;
1030
1031    case MATCH_INSN:
1032    case MATCH_OPERAND:
1033      if (is_const)
1034	fatal ("RTL operator \"%s\" not valid in constant attribute test",
1035	       GET_RTX_NAME (GET_CODE (exp)));
1036      /* These cases can't be simplified.  */
1037      RTX_UNCHANGING_P (exp) = 1;
1038      break;
1039
1040    case LE:  case LT:  case GT:  case GE:
1041    case LEU: case LTU: case GTU: case GEU:
1042    case NE:  case EQ:
1043      if (GET_CODE (XEXP (exp, 0)) == SYMBOL_REF
1044	  && GET_CODE (XEXP (exp, 1)) == SYMBOL_REF)
1045	exp = attr_rtx (GET_CODE (exp),
1046			attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 0), 0)),
1047			attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 1), 0)));
1048      /* These cases can't be simplified.  */
1049      RTX_UNCHANGING_P (exp) = 1;
1050      break;
1051
1052    case SYMBOL_REF:
1053      if (is_const)
1054	{
1055	  /* These cases are valid for constant attributes, but can't be
1056	     simplified.  */
1057	  exp = attr_rtx (SYMBOL_REF, XSTR (exp, 0));
1058	  RTX_UNCHANGING_P (exp) = 1;
1059	  break;
1060	}
1061    default:
1062      fatal ("RTL operator \"%s\" not valid in attribute test",
1063	     GET_RTX_NAME (GET_CODE (exp)));
1064    }
1065
1066  return exp;
1067}
1068
1069/* Given an expression, ensure that it is validly formed and that all named
1070   attribute values are valid for the given attribute.  Issue a fatal error
1071   if not.  If no attribute is specified, assume a numeric attribute.
1072
1073   Return a perhaps modified replacement expression for the value.  */
1074
1075static rtx
1076check_attr_value (exp, attr)
1077     rtx exp;
1078     struct attr_desc *attr;
1079{
1080  struct attr_value *av;
1081  char *p;
1082  int i;
1083
1084  switch (GET_CODE (exp))
1085    {
1086    case CONST_INT:
1087      if (attr && ! attr->is_numeric)
1088	fatal ("CONST_INT not valid for non-numeric `%s' attribute",
1089	       attr->name);
1090
1091      if (INTVAL (exp) < 0)
1092	fatal ("Negative numeric value specified for `%s' attribute",
1093	       attr->name);
1094
1095      break;
1096
1097    case CONST_STRING:
1098      if (! strcmp (XSTR (exp, 0), "*"))
1099	break;
1100
1101      if (attr == 0 || attr->is_numeric)
1102	{
1103	  p = XSTR (exp, 0);
1104	  if (attr && attr->negative_ok && *p == '-')
1105	    p++;
1106	  for (; *p; p++)
1107	    if (*p > '9' || *p < '0')
1108	      fatal ("Non-numeric value for numeric `%s' attribute",
1109		     attr ? attr->name : "internal");
1110	  break;
1111	}
1112
1113      for (av = attr->first_value; av; av = av->next)
1114	if (GET_CODE (av->value) == CONST_STRING
1115	    && ! strcmp (XSTR (av->value, 0), XSTR (exp, 0)))
1116	  break;
1117
1118      if (av == NULL)
1119	fatal ("Unknown value `%s' for `%s' attribute",
1120	       XSTR (exp, 0), attr ? attr->name : "internal");
1121
1122      break;
1123
1124    case IF_THEN_ELSE:
1125      XEXP (exp, 0) = check_attr_test (XEXP (exp, 0),
1126				       attr ? attr->is_const : 0);
1127      XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
1128      XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr);
1129      break;
1130
1131    case IOR:
1132    case AND:
1133      XEXP (exp, 0) = check_attr_value (XEXP (exp, 0), attr);
1134      XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
1135      break;
1136
1137    case FFS:
1138      XEXP (exp, 0) = check_attr_value (XEXP (exp, 0), attr);
1139      break;
1140
1141    case COND:
1142      if (XVECLEN (exp, 0) % 2 != 0)
1143	fatal ("First operand of COND must have even length");
1144
1145      for (i = 0; i < XVECLEN (exp, 0); i += 2)
1146	{
1147	  XVECEXP (exp, 0, i) = check_attr_test (XVECEXP (exp, 0, i),
1148						 attr ? attr->is_const : 0);
1149	  XVECEXP (exp, 0, i + 1)
1150	    = check_attr_value (XVECEXP (exp, 0, i + 1), attr);
1151	}
1152
1153      XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
1154      break;
1155
1156    case SYMBOL_REF:
1157      if (attr && attr->is_const)
1158	/* A constant SYMBOL_REF is valid as a constant attribute test and
1159	   is expanded later by make_canonical into a COND.  */
1160	return attr_rtx (SYMBOL_REF, XSTR (exp, 0));
1161      /* Otherwise, fall through...  */
1162
1163    default:
1164      fatal ("Invalid operation `%s' for attribute value",
1165	     GET_RTX_NAME (GET_CODE (exp)));
1166    }
1167
1168  return exp;
1169}
1170
1171/* Given an SET_ATTR_ALTERNATIVE expression, convert to the canonical SET.
1172   It becomes a COND with each test being (eq_attr "alternative "n") */
1173
1174static rtx
1175convert_set_attr_alternative (exp, num_alt, insn_code, insn_index)
1176     rtx exp;
1177     int num_alt;
1178     int insn_code, insn_index;
1179{
1180  rtx condexp;
1181  int i;
1182
1183  if (XVECLEN (exp, 1) != num_alt)
1184    fatal ("Bad number of entries in SET_ATTR_ALTERNATIVE for insn %d",
1185	   insn_index);
1186
1187  /* Make a COND with all tests but the last.  Select the last value via the
1188     default.  */
1189  condexp = rtx_alloc (COND);
1190  XVEC (condexp, 0) = rtvec_alloc ((num_alt - 1) * 2);
1191
1192  for (i = 0; i < num_alt - 1; i++)
1193    {
1194      char *p;
1195      p = attr_numeral (i);
1196
1197      XVECEXP (condexp, 0, 2 * i) = attr_eq (alternative_name, p);
1198#if 0
1199      /* Sharing this EQ_ATTR rtl causes trouble.  */
1200      XVECEXP (condexp, 0, 2 * i) = rtx_alloc (EQ_ATTR);
1201      XSTR (XVECEXP (condexp, 0, 2 * i), 0) = alternative_name;
1202      XSTR (XVECEXP (condexp, 0, 2 * i), 1) = p;
1203#endif
1204      XVECEXP (condexp, 0, 2 * i + 1) = XVECEXP (exp, 1, i);
1205    }
1206
1207  XEXP (condexp, 1) = XVECEXP (exp, 1, i);
1208
1209  return attr_rtx (SET, attr_rtx (ATTR, XSTR (exp, 0)), condexp);
1210}
1211
1212/* Given a SET_ATTR, convert to the appropriate SET.  If a comma-separated
1213   list of values is given, convert to SET_ATTR_ALTERNATIVE first.  */
1214
1215static rtx
1216convert_set_attr (exp, num_alt, insn_code, insn_index)
1217     rtx exp;
1218     int num_alt;
1219     int insn_code, insn_index;
1220{
1221  rtx newexp;
1222  char *name_ptr;
1223  char *p;
1224  int n;
1225
1226  /* See how many alternative specified.  */
1227  n = n_comma_elts (XSTR (exp, 1));
1228  if (n == 1)
1229    return attr_rtx (SET,
1230		     attr_rtx (ATTR, XSTR (exp, 0)),
1231		     attr_rtx (CONST_STRING, XSTR (exp, 1)));
1232
1233  newexp = rtx_alloc (SET_ATTR_ALTERNATIVE);
1234  XSTR (newexp, 0) = XSTR (exp, 0);
1235  XVEC (newexp, 1) = rtvec_alloc (n);
1236
1237  /* Process each comma-separated name.  */
1238  name_ptr = XSTR (exp, 1);
1239  n = 0;
1240  while ((p = next_comma_elt (&name_ptr)) != NULL)
1241    XVECEXP (newexp, 1, n++) = attr_rtx (CONST_STRING, p);
1242
1243  return convert_set_attr_alternative (newexp, num_alt, insn_code, insn_index);
1244}
1245
1246/* Scan all definitions, checking for validity.  Also, convert any SET_ATTR
1247   and SET_ATTR_ALTERNATIVE expressions to the corresponding SET
1248   expressions.  */
1249
1250static void
1251check_defs ()
1252{
1253  struct insn_def *id;
1254  struct attr_desc *attr;
1255  int i;
1256  rtx value;
1257
1258  for (id = defs; id; id = id->next)
1259    {
1260      if (XVEC (id->def, id->vec_idx) == NULL)
1261	continue;
1262
1263      for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
1264	{
1265	  value = XVECEXP (id->def, id->vec_idx, i);
1266	  switch (GET_CODE (value))
1267	    {
1268	    case SET:
1269	      if (GET_CODE (XEXP (value, 0)) != ATTR)
1270		fatal ("Bad attribute set in pattern %d", id->insn_index);
1271	      break;
1272
1273	    case SET_ATTR_ALTERNATIVE:
1274	      value = convert_set_attr_alternative (value,
1275						    id->num_alternatives,
1276						    id->insn_code,
1277						    id->insn_index);
1278	      break;
1279
1280	    case SET_ATTR:
1281	      value = convert_set_attr (value, id->num_alternatives,
1282					id->insn_code, id->insn_index);
1283	      break;
1284
1285	    default:
1286	      fatal ("Invalid attribute code `%s' for pattern %d",
1287		     GET_RTX_NAME (GET_CODE (value)), id->insn_index);
1288	    }
1289
1290	  if ((attr = find_attr (XSTR (XEXP (value, 0), 0), 0)) == NULL)
1291	    fatal ("Unknown attribute `%s' for pattern number %d",
1292		   XSTR (XEXP (value, 0), 0), id->insn_index);
1293
1294	  XVECEXP (id->def, id->vec_idx, i) = value;
1295	  XEXP (value, 1) = check_attr_value (XEXP (value, 1), attr);
1296	}
1297    }
1298}
1299
1300#if 0
1301/* Given a constant SYMBOL_REF expression, convert to a COND that
1302   explicitly tests each enumerated value.  */
1303
1304static rtx
1305convert_const_symbol_ref (exp, attr)
1306     rtx exp;
1307     struct attr_desc *attr;
1308{
1309  rtx condexp;
1310  struct attr_value *av;
1311  int i;
1312  int num_alt = 0;
1313
1314  for (av = attr->first_value; av; av = av->next)
1315    num_alt++;
1316
1317  /* Make a COND with all tests but the last, and in the original order.
1318     Select the last value via the default.  Note that the attr values
1319     are constructed in reverse order.  */
1320
1321  condexp = rtx_alloc (COND);
1322  XVEC (condexp, 0) = rtvec_alloc ((num_alt - 1) * 2);
1323  av = attr->first_value;
1324  XEXP (condexp, 1) = av->value;
1325
1326  for (i = num_alt - 2; av = av->next, i >= 0; i--)
1327    {
1328      char *p, *string;
1329      rtx value;
1330
1331      string = p = (char *) oballoc (2
1332				     + strlen (attr->name)
1333				     + strlen (XSTR (av->value, 0)));
1334      strcpy (p, attr->name);
1335      strcat (p, "_");
1336      strcat (p, XSTR (av->value, 0));
1337      for (; *p != '\0'; p++)
1338	if (*p >= 'a' && *p <= 'z')
1339	  *p -= 'a' - 'A';
1340
1341      value = attr_rtx (SYMBOL_REF, string);
1342      RTX_UNCHANGING_P (value) = 1;
1343
1344      XVECEXP (condexp, 0, 2 * i) = attr_rtx (EQ, exp, value);
1345
1346      XVECEXP (condexp, 0, 2 * i + 1) = av->value;
1347    }
1348
1349  return condexp;
1350}
1351#endif
1352
1353/* Given a valid expression for an attribute value, remove any IF_THEN_ELSE
1354   expressions by converting them into a COND.  This removes cases from this
1355   program.  Also, replace an attribute value of "*" with the default attribute
1356   value.  */
1357
1358static rtx
1359make_canonical (attr, exp)
1360     struct attr_desc *attr;
1361     rtx exp;
1362{
1363  int i;
1364  rtx newexp;
1365
1366  switch (GET_CODE (exp))
1367    {
1368    case CONST_INT:
1369      exp = make_numeric_value (INTVAL (exp));
1370      break;
1371
1372    case CONST_STRING:
1373      if (! strcmp (XSTR (exp, 0), "*"))
1374	{
1375	  if (attr == 0 || attr->default_val == 0)
1376	    fatal ("(attr_value \"*\") used in invalid context.");
1377	  exp = attr->default_val->value;
1378	}
1379
1380      break;
1381
1382    case SYMBOL_REF:
1383      if (!attr->is_const || RTX_UNCHANGING_P (exp))
1384	break;
1385      /* The SYMBOL_REF is constant for a given run, so mark it as unchanging.
1386	 This makes the COND something that won't be considered an arbitrary
1387	 expression by walk_attr_value.  */
1388      RTX_UNCHANGING_P (exp) = 1;
1389#if 0
1390      /* ??? Why do we do this?  With attribute values { A B C D E }, this
1391         tends to generate (!(x==A) && !(x==B) && !(x==C) && !(x==D)) rather
1392	 than (x==E). */
1393      exp = convert_const_symbol_ref (exp, attr);
1394      RTX_UNCHANGING_P (exp) = 1;
1395      exp = check_attr_value (exp, attr);
1396      /* Goto COND case since this is now a COND.  Note that while the
1397         new expression is rescanned, all symbol_ref notes are marked as
1398	 unchanging.  */
1399      goto cond;
1400#else
1401      exp = check_attr_value (exp, attr);
1402      break;
1403#endif
1404
1405    case IF_THEN_ELSE:
1406      newexp = rtx_alloc (COND);
1407      XVEC (newexp, 0) = rtvec_alloc (2);
1408      XVECEXP (newexp, 0, 0) = XEXP (exp, 0);
1409      XVECEXP (newexp, 0, 1) = XEXP (exp, 1);
1410
1411      XEXP (newexp, 1) = XEXP (exp, 2);
1412
1413      exp = newexp;
1414      /* Fall through to COND case since this is now a COND.  */
1415
1416    case COND:
1417      {
1418	int allsame = 1;
1419	rtx defval;
1420
1421	/* First, check for degenerate COND.  */
1422	if (XVECLEN (exp, 0) == 0)
1423	  return make_canonical (attr, XEXP (exp, 1));
1424	defval = XEXP (exp, 1) = make_canonical (attr, XEXP (exp, 1));
1425
1426	for (i = 0; i < XVECLEN (exp, 0); i += 2)
1427	  {
1428	    XVECEXP (exp, 0, i) = copy_boolean (XVECEXP (exp, 0, i));
1429	    XVECEXP (exp, 0, i + 1)
1430	      = make_canonical (attr, XVECEXP (exp, 0, i + 1));
1431	    if (! rtx_equal_p (XVECEXP (exp, 0, i + 1), defval))
1432	      allsame = 0;
1433	  }
1434	if (allsame)
1435	  return defval;
1436      }
1437      break;
1438
1439    default:
1440      break;
1441    }
1442
1443  return exp;
1444}
1445
1446static rtx
1447copy_boolean (exp)
1448     rtx exp;
1449{
1450  if (GET_CODE (exp) == AND || GET_CODE (exp) == IOR)
1451    return attr_rtx (GET_CODE (exp), copy_boolean (XEXP (exp, 0)),
1452		     copy_boolean (XEXP (exp, 1)));
1453  return exp;
1454}
1455
1456/* Given a value and an attribute description, return a `struct attr_value *'
1457   that represents that value.  This is either an existing structure, if the
1458   value has been previously encountered, or a newly-created structure.
1459
1460   `insn_code' is the code of an insn whose attribute has the specified
1461   value (-2 if not processing an insn).  We ensure that all insns for
1462   a given value have the same number of alternatives if the value checks
1463   alternatives.  */
1464
1465static struct attr_value *
1466get_attr_value (value, attr, insn_code)
1467     rtx value;
1468     struct attr_desc *attr;
1469     int insn_code;
1470{
1471  struct attr_value *av;
1472  int num_alt = 0;
1473
1474  value = make_canonical (attr, value);
1475  if (compares_alternatives_p (value))
1476    {
1477      if (insn_code < 0 || insn_alternatives == NULL)
1478	fatal ("(eq_attr \"alternatives\" ...) used in non-insn context");
1479      else
1480	num_alt = insn_alternatives[insn_code];
1481    }
1482
1483  for (av = attr->first_value; av; av = av->next)
1484    if (rtx_equal_p (value, av->value)
1485	&& (num_alt == 0 || av->first_insn == NULL
1486	    || insn_alternatives[av->first_insn->insn_code]))
1487      return av;
1488
1489  av = (struct attr_value *) oballoc (sizeof (struct attr_value));
1490  av->value = value;
1491  av->next = attr->first_value;
1492  attr->first_value = av;
1493  av->first_insn = NULL;
1494  av->num_insns = 0;
1495  av->has_asm_insn = 0;
1496
1497  return av;
1498}
1499
1500/* After all DEFINE_DELAYs have been read in, create internal attributes
1501   to generate the required routines.
1502
1503   First, we compute the number of delay slots for each insn (as a COND of
1504   each of the test expressions in DEFINE_DELAYs).  Then, if more than one
1505   delay type is specified, we compute a similar function giving the
1506   DEFINE_DELAY ordinal for each insn.
1507
1508   Finally, for each [DEFINE_DELAY, slot #] pair, we compute an attribute that
1509   tells whether a given insn can be in that delay slot.
1510
1511   Normal attribute filling and optimization expands these to contain the
1512   information needed to handle delay slots.  */
1513
1514static void
1515expand_delays ()
1516{
1517  struct delay_desc *delay;
1518  rtx condexp;
1519  rtx newexp;
1520  int i;
1521  char *p;
1522
1523  /* First, generate data for `num_delay_slots' function.  */
1524
1525  condexp = rtx_alloc (COND);
1526  XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
1527  XEXP (condexp, 1) = make_numeric_value (0);
1528
1529  for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
1530    {
1531      XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
1532      XVECEXP (condexp, 0, i + 1)
1533	= make_numeric_value (XVECLEN (delay->def, 1) / 3);
1534    }
1535
1536  make_internal_attr ("*num_delay_slots", condexp, 0);
1537
1538  /* If more than one delay type, do the same for computing the delay type.  */
1539  if (num_delays > 1)
1540    {
1541      condexp = rtx_alloc (COND);
1542      XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
1543      XEXP (condexp, 1) = make_numeric_value (0);
1544
1545      for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
1546	{
1547	  XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
1548	  XVECEXP (condexp, 0, i + 1) = make_numeric_value (delay->num);
1549	}
1550
1551      make_internal_attr ("*delay_type", condexp, 1);
1552    }
1553
1554  /* For each delay possibility and delay slot, compute an eligibility
1555     attribute for non-annulled insns and for each type of annulled (annul
1556     if true and annul if false).  */
1557 for (delay = delays; delay; delay = delay->next)
1558   {
1559     for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
1560       {
1561	 condexp = XVECEXP (delay->def, 1, i);
1562	 if (condexp == 0) condexp = false_rtx;
1563	 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1564			    make_numeric_value (1), make_numeric_value (0));
1565
1566	 p = attr_printf (sizeof ("*delay__") + MAX_DIGITS*2, "*delay_%d_%d",
1567			  delay->num, i / 3);
1568	 make_internal_attr (p, newexp, 1);
1569
1570	 if (have_annul_true)
1571	   {
1572	     condexp = XVECEXP (delay->def, 1, i + 1);
1573	     if (condexp == 0) condexp = false_rtx;
1574	     newexp = attr_rtx (IF_THEN_ELSE, condexp,
1575				make_numeric_value (1),
1576				make_numeric_value (0));
1577	     p = attr_printf (sizeof ("*annul_true__") + MAX_DIGITS*2,
1578			      "*annul_true_%d_%d", delay->num, i / 3);
1579	     make_internal_attr (p, newexp, 1);
1580	   }
1581
1582	 if (have_annul_false)
1583	   {
1584	     condexp = XVECEXP (delay->def, 1, i + 2);
1585	     if (condexp == 0) condexp = false_rtx;
1586	     newexp = attr_rtx (IF_THEN_ELSE, condexp,
1587				make_numeric_value (1),
1588				make_numeric_value (0));
1589	     p = attr_printf (sizeof ("*annul_false__") + MAX_DIGITS*2,
1590			      "*annul_false_%d_%d", delay->num, i / 3);
1591	     make_internal_attr (p, newexp, 1);
1592	   }
1593       }
1594   }
1595}
1596
1597/* This function is given a left and right side expression and an operator.
1598   Each side is a conditional expression, each alternative of which has a
1599   numerical value.  The function returns another conditional expression
1600   which, for every possible set of condition values, returns a value that is
1601   the operator applied to the values of the two sides.
1602
1603   Since this is called early, it must also support IF_THEN_ELSE.  */
1604
1605static rtx
1606operate_exp (op, left, right)
1607     enum operator op;
1608     rtx left, right;
1609{
1610  int left_value, right_value;
1611  rtx newexp;
1612  int i;
1613
1614  /* If left is a string, apply operator to it and the right side.  */
1615  if (GET_CODE (left) == CONST_STRING)
1616    {
1617      /* If right is also a string, just perform the operation.  */
1618      if (GET_CODE (right) == CONST_STRING)
1619	{
1620	  left_value = atoi (XSTR (left, 0));
1621	  right_value = atoi (XSTR (right, 0));
1622	  switch (op)
1623	    {
1624	    case PLUS_OP:
1625	      i = left_value + right_value;
1626	      break;
1627
1628	    case MINUS_OP:
1629	      i = left_value - right_value;
1630	      break;
1631
1632	    case POS_MINUS_OP:  /* The positive part of LEFT - RIGHT.  */
1633	      if (left_value > right_value)
1634		i = left_value - right_value;
1635	      else
1636		i = 0;
1637	      break;
1638
1639	    case OR_OP:
1640	    case ORX_OP:
1641	      i = left_value | right_value;
1642	      break;
1643
1644	    case EQ_OP:
1645	      i = left_value == right_value;
1646	      break;
1647
1648	    case RANGE_OP:
1649	      i = (left_value << (HOST_BITS_PER_INT / 2)) | right_value;
1650	      break;
1651
1652	    case MAX_OP:
1653	      if (left_value > right_value)
1654		i = left_value;
1655	      else
1656		i = right_value;
1657	      break;
1658
1659	    case MIN_OP:
1660	      if (left_value < right_value)
1661		i = left_value;
1662	      else
1663		i = right_value;
1664	      break;
1665
1666	    default:
1667	      abort ();
1668	    }
1669
1670	  if (i == left_value)
1671	    return left;
1672	  if (i == right_value)
1673	    return right;
1674	  return make_numeric_value (i);
1675	}
1676      else if (GET_CODE (right) == IF_THEN_ELSE)
1677	{
1678	  /* Apply recursively to all values within.  */
1679	  rtx newleft = operate_exp (op, left, XEXP (right, 1));
1680	  rtx newright = operate_exp (op, left, XEXP (right, 2));
1681	  if (rtx_equal_p (newleft, newright))
1682	    return newleft;
1683	  return attr_rtx (IF_THEN_ELSE, XEXP (right, 0), newleft, newright);
1684	}
1685      else if (GET_CODE (right) == COND)
1686	{
1687	  int allsame = 1;
1688	  rtx defval;
1689
1690	  newexp = rtx_alloc (COND);
1691	  XVEC (newexp, 0) = rtvec_alloc (XVECLEN (right, 0));
1692	  defval = XEXP (newexp, 1) = operate_exp (op, left, XEXP (right, 1));
1693
1694	  for (i = 0; i < XVECLEN (right, 0); i += 2)
1695	    {
1696	      XVECEXP (newexp, 0, i) = XVECEXP (right, 0, i);
1697	      XVECEXP (newexp, 0, i + 1)
1698		= operate_exp (op, left, XVECEXP (right, 0, i + 1));
1699	      if (! rtx_equal_p (XVECEXP (newexp, 0, i + 1),
1700				 defval))
1701		allsame = 0;
1702	    }
1703
1704	  /* If the resulting cond is trivial (all alternatives
1705	     give the same value), optimize it away.  */
1706	  if (allsame)
1707	    {
1708	      obstack_free (rtl_obstack, newexp);
1709	      return operate_exp (op, left, XEXP (right, 1));
1710	    }
1711
1712	  /* If the result is the same as the RIGHT operand,
1713	     just use that.  */
1714	  if (rtx_equal_p (newexp, right))
1715	    {
1716	      obstack_free (rtl_obstack, newexp);
1717	      return right;
1718	    }
1719
1720	  return newexp;
1721	}
1722      else
1723	fatal ("Badly formed attribute value");
1724    }
1725
1726  /* A hack to prevent expand_units from completely blowing up: ORX_OP does
1727     not associate through IF_THEN_ELSE.  */
1728  else if (op == ORX_OP && GET_CODE (right) == IF_THEN_ELSE)
1729    {
1730      return attr_rtx (IOR, left, right);
1731    }
1732
1733  /* Otherwise, do recursion the other way.  */
1734  else if (GET_CODE (left) == IF_THEN_ELSE)
1735    {
1736      rtx newleft = operate_exp (op, XEXP (left, 1), right);
1737      rtx newright = operate_exp (op, XEXP (left, 2), right);
1738      if (rtx_equal_p (newleft, newright))
1739	return newleft;
1740      return attr_rtx (IF_THEN_ELSE, XEXP (left, 0), newleft, newright);
1741    }
1742  else if (GET_CODE (left) == COND)
1743    {
1744      int allsame = 1;
1745      rtx defval;
1746
1747      newexp = rtx_alloc (COND);
1748      XVEC (newexp, 0) = rtvec_alloc (XVECLEN (left, 0));
1749      defval = XEXP (newexp, 1) = operate_exp (op, XEXP (left, 1), right);
1750
1751      for (i = 0; i < XVECLEN (left, 0); i += 2)
1752	{
1753	  XVECEXP (newexp, 0, i) = XVECEXP (left, 0, i);
1754	  XVECEXP (newexp, 0, i + 1)
1755	    = operate_exp (op, XVECEXP (left, 0, i + 1), right);
1756	  if (! rtx_equal_p (XVECEXP (newexp, 0, i + 1),
1757			     defval))
1758	    allsame = 0;
1759	}
1760
1761      /* If the cond is trivial (all alternatives give the same value),
1762	 optimize it away.  */
1763      if (allsame)
1764	{
1765	  obstack_free (rtl_obstack, newexp);
1766	  return operate_exp (op, XEXP (left, 1), right);
1767	}
1768
1769      /* If the result is the same as the LEFT operand,
1770	 just use that.  */
1771      if (rtx_equal_p (newexp, left))
1772	{
1773	  obstack_free (rtl_obstack, newexp);
1774	  return left;
1775	}
1776
1777      return newexp;
1778    }
1779
1780  else
1781    fatal ("Badly formed attribute value.");
1782  /* NOTREACHED */
1783  return NULL;
1784}
1785
1786/* Once all attributes and DEFINE_FUNCTION_UNITs have been read, we
1787   construct a number of attributes.
1788
1789   The first produces a function `function_units_used' which is given an
1790   insn and produces an encoding showing which function units are required
1791   for the execution of that insn.  If the value is non-negative, the insn
1792   uses that unit; otherwise, the value is a one's compliment mask of units
1793   used.
1794
1795   The second produces a function `result_ready_cost' which is used to
1796   determine the time that the result of an insn will be ready and hence
1797   a worst-case schedule.
1798
1799   Both of these produce quite complex expressions which are then set as the
1800   default value of internal attributes.  Normal attribute simplification
1801   should produce reasonable expressions.
1802
1803   For each unit, a `<name>_unit_ready_cost' function will take an
1804   insn and give the delay until that unit will be ready with the result
1805   and a `<name>_unit_conflict_cost' function is given an insn already
1806   executing on the unit and a candidate to execute and will give the
1807   cost from the time the executing insn started until the candidate
1808   can start (ignore limitations on the number of simultaneous insns).
1809
1810   For each unit, a `<name>_unit_blockage' function is given an insn
1811   already executing on the unit and a candidate to execute and will
1812   give the delay incurred due to function unit conflicts.  The range of
1813   blockage cost values for a given executing insn is given by the
1814   `<name>_unit_blockage_range' function.  These values are encoded in
1815   an int where the upper half gives the minimum value and the lower
1816   half gives the maximum value.  */
1817
1818static void
1819expand_units ()
1820{
1821  struct function_unit *unit, **unit_num;
1822  struct function_unit_op *op, **op_array, ***unit_ops;
1823  rtx unitsmask;
1824  rtx readycost;
1825  rtx newexp;
1826  char *str;
1827  int i, j, u, num, nvalues;
1828
1829  /* Rebuild the condition for the unit to share the RTL expressions.
1830     Sharing is required by simplify_by_exploding.  Build the issue delay
1831     expressions.  Validate the expressions we were given for the conditions
1832     and conflict vector.  Then make attributes for use in the conflict
1833     function.  */
1834
1835  for (unit = units; unit; unit = unit->next)
1836    {
1837      unit->condexp = check_attr_test (unit->condexp, 0);
1838
1839      for (op = unit->ops; op; op = op->next)
1840	{
1841	  rtx issue_delay = make_numeric_value (op->issue_delay);
1842	  rtx issue_exp = issue_delay;
1843
1844	  /* Build, validate, and simplify the issue delay expression.  */
1845	  if (op->conflict_exp != true_rtx)
1846	    issue_exp = attr_rtx (IF_THEN_ELSE, op->conflict_exp,
1847				  issue_exp, make_numeric_value (0));
1848	  issue_exp = check_attr_value (make_canonical (NULL_ATTR,
1849							issue_exp),
1850					NULL_ATTR);
1851	  issue_exp = simplify_knowing (issue_exp, unit->condexp);
1852	  op->issue_exp = issue_exp;
1853
1854	  /* Make an attribute for use in the conflict function if needed.  */
1855	  unit->needs_conflict_function = (unit->issue_delay.min
1856					   != unit->issue_delay.max);
1857	  if (unit->needs_conflict_function)
1858	    {
1859	      str = attr_printf (strlen (unit->name) + sizeof ("*_cost_") + MAX_DIGITS,
1860				 "*%s_cost_%d", unit->name, op->num);
1861	      make_internal_attr (str, issue_exp, 1);
1862	    }
1863
1864	  /* Validate the condition.  */
1865	  op->condexp = check_attr_test (op->condexp, 0);
1866	}
1867    }
1868
1869  /* Compute the mask of function units used.  Initially, the unitsmask is
1870     zero.   Set up a conditional to compute each unit's contribution.  */
1871  unitsmask = make_numeric_value (0);
1872  newexp = rtx_alloc (IF_THEN_ELSE);
1873  XEXP (newexp, 2) = make_numeric_value (0);
1874
1875  /* If we have just a few units, we may be all right expanding the whole
1876     thing.  But the expansion is 2**N in space on the number of opclasses,
1877     so we can't do this for very long -- Alpha and MIPS in particular have
1878     problems with this.  So in that situation, we fall back on an alternate
1879     implementation method.  */
1880#define NUM_UNITOP_CUTOFF 20
1881
1882  if (num_unit_opclasses < NUM_UNITOP_CUTOFF)
1883    {
1884      /* Merge each function unit into the unit mask attributes.  */
1885      for (unit = units; unit; unit = unit->next)
1886        {
1887          XEXP (newexp, 0) = unit->condexp;
1888          XEXP (newexp, 1) = make_numeric_value (1 << unit->num);
1889          unitsmask = operate_exp (OR_OP, unitsmask, newexp);
1890        }
1891    }
1892  else
1893    {
1894      /* Merge each function unit into the unit mask attributes.  */
1895      for (unit = units; unit; unit = unit->next)
1896        {
1897          XEXP (newexp, 0) = unit->condexp;
1898          XEXP (newexp, 1) = make_numeric_value (1 << unit->num);
1899          unitsmask = operate_exp (ORX_OP, unitsmask, attr_copy_rtx (newexp));
1900        }
1901    }
1902
1903  /* Simplify the unit mask expression, encode it, and make an attribute
1904     for the function_units_used function.  */
1905  unitsmask = simplify_by_exploding (unitsmask);
1906
1907  if (num_unit_opclasses < NUM_UNITOP_CUTOFF)
1908    unitsmask = encode_units_mask (unitsmask);
1909  else
1910    {
1911      /* We can no longer encode unitsmask at compile time, so emit code to
1912         calculate it at runtime.  Rather, put a marker for where we'd do
1913	 the code, and actually output it in write_attr_get().  */
1914      unitsmask = attr_rtx (FFS, unitsmask);
1915    }
1916
1917  make_internal_attr ("*function_units_used", unitsmask, 10);
1918
1919  /* Create an array of ops for each unit.  Add an extra unit for the
1920     result_ready_cost function that has the ops of all other units.  */
1921  unit_ops = (struct function_unit_op ***)
1922    alloca ((num_units + 1) * sizeof (struct function_unit_op **));
1923  unit_num = (struct function_unit **)
1924    alloca ((num_units + 1) * sizeof (struct function_unit *));
1925
1926  unit_num[num_units] = unit = (struct function_unit *)
1927    alloca (sizeof (struct function_unit));
1928  unit->num = num_units;
1929  unit->num_opclasses = 0;
1930
1931  for (unit = units; unit; unit = unit->next)
1932    {
1933      unit_num[num_units]->num_opclasses += unit->num_opclasses;
1934      unit_num[unit->num] = unit;
1935      unit_ops[unit->num] = op_array = (struct function_unit_op **)
1936	alloca (unit->num_opclasses * sizeof (struct function_unit_op *));
1937
1938      for (op = unit->ops; op; op = op->next)
1939	op_array[op->num] = op;
1940    }
1941
1942  /* Compose the array of ops for the extra unit.  */
1943  unit_ops[num_units] = op_array = (struct function_unit_op **)
1944    alloca (unit_num[num_units]->num_opclasses
1945	    * sizeof (struct function_unit_op *));
1946
1947  for (unit = units, i = 0; unit; i += unit->num_opclasses, unit = unit->next)
1948    bcopy ((char *) unit_ops[unit->num], (char *) &op_array[i],
1949	   unit->num_opclasses * sizeof (struct function_unit_op *));
1950
1951  /* Compute the ready cost function for each unit by computing the
1952     condition for each non-default value.  */
1953  for (u = 0; u <= num_units; u++)
1954    {
1955      rtx orexp;
1956      int value;
1957
1958      unit = unit_num[u];
1959      op_array = unit_ops[unit->num];
1960      num = unit->num_opclasses;
1961
1962      /* Sort the array of ops into increasing ready cost order.  */
1963      for (i = 0; i < num; i++)
1964	for (j = num - 1; j > i; j--)
1965	  if (op_array[j-1]->ready < op_array[j]->ready)
1966	    {
1967	      op = op_array[j];
1968	      op_array[j] = op_array[j-1];
1969	      op_array[j-1] = op;
1970	    }
1971
1972      /* Determine how many distinct non-default ready cost values there
1973	 are.  We use a default ready cost value of 1.  */
1974      nvalues = 0; value = 1;
1975      for (i = num - 1; i >= 0; i--)
1976	if (op_array[i]->ready > value)
1977	  {
1978	    value = op_array[i]->ready;
1979	    nvalues++;
1980	  }
1981
1982      if (nvalues == 0)
1983	readycost = make_numeric_value (1);
1984      else
1985	{
1986	  /* Construct the ready cost expression as a COND of each value from
1987	     the largest to the smallest.  */
1988	  readycost = rtx_alloc (COND);
1989	  XVEC (readycost, 0) = rtvec_alloc (nvalues * 2);
1990	  XEXP (readycost, 1) = make_numeric_value (1);
1991
1992	  nvalues = 0; orexp = false_rtx; value = op_array[0]->ready;
1993	  for (i = 0; i < num; i++)
1994	    {
1995	      op = op_array[i];
1996	      if (op->ready <= 1)
1997		break;
1998	      else if (op->ready == value)
1999		orexp = insert_right_side (IOR, orexp, op->condexp, -2, -2);
2000	      else
2001		{
2002		  XVECEXP (readycost, 0, nvalues * 2) = orexp;
2003		  XVECEXP (readycost, 0, nvalues * 2 + 1)
2004		    = make_numeric_value (value);
2005		  nvalues++;
2006		  value = op->ready;
2007		  orexp = op->condexp;
2008		}
2009	    }
2010	  XVECEXP (readycost, 0, nvalues * 2) = orexp;
2011	  XVECEXP (readycost, 0, nvalues * 2 + 1) = make_numeric_value (value);
2012	}
2013
2014      if (u < num_units)
2015	{
2016	  rtx max_blockage = 0, min_blockage = 0;
2017
2018	  /* Simplify the readycost expression by only considering insns
2019	     that use the unit.  */
2020	  readycost = simplify_knowing (readycost, unit->condexp);
2021
2022	  /* Determine the blockage cost the executing insn (E) given
2023	     the candidate insn (C).  This is the maximum of the issue
2024	     delay, the pipeline delay, and the simultaneity constraint.
2025	     Each function_unit_op represents the characteristics of the
2026	     candidate insn, so in the expressions below, C is a known
2027	     term and E is an unknown term.
2028
2029	     We compute the blockage cost for each E for every possible C.
2030	     Thus OP represents E, and READYCOST is a list of values for
2031	     every possible C.
2032
2033	     The issue delay function for C is op->issue_exp and is used to
2034	     write the `<name>_unit_conflict_cost' function.  Symbolicly
2035	     this is "ISSUE-DELAY (E,C)".
2036
2037	     The pipeline delay results form the FIFO constraint on the
2038	     function unit and is "READY-COST (E) + 1 - READY-COST (C)".
2039
2040	     The simultaneity constraint is based on how long it takes to
2041	     fill the unit given the minimum issue delay.  FILL-TIME is the
2042	     constant "MIN (ISSUE-DELAY (*,*)) * (SIMULTANEITY - 1)", and
2043	     the simultaneity constraint is "READY-COST (E) - FILL-TIME"
2044	     if SIMULTANEITY is non-zero and zero otherwise.
2045
2046	     Thus, BLOCKAGE (E,C) when SIMULTANEITY is zero is
2047
2048	         MAX (ISSUE-DELAY (E,C),
2049		      READY-COST (E) - (READY-COST (C) - 1))
2050
2051	     and otherwise
2052
2053	         MAX (ISSUE-DELAY (E,C),
2054		      READY-COST (E) - (READY-COST (C) - 1),
2055		      READY-COST (E) - FILL-TIME)
2056
2057	     The `<name>_unit_blockage' function is computed by determining
2058	     this value for each candidate insn.  As these values are
2059	     computed, we also compute the upper and lower bounds for
2060	     BLOCKAGE (E,*).  These are combined to form the function
2061	     `<name>_unit_blockage_range'.  Finally, the maximum blockage
2062	     cost, MAX (BLOCKAGE (*,*)), is computed.  */
2063
2064	  for (op = unit->ops; op; op = op->next)
2065	    {
2066#ifdef HAIFA
2067	      rtx blockage = op->issue_exp;
2068#else
2069	      rtx blockage = operate_exp (POS_MINUS_OP, readycost,
2070					  make_numeric_value (1));
2071
2072	      if (unit->simultaneity != 0)
2073		{
2074		  rtx filltime = make_numeric_value ((unit->simultaneity - 1)
2075						     * unit->issue_delay.min);
2076		  blockage = operate_exp (MIN_OP, blockage, filltime);
2077		}
2078
2079	      blockage = operate_exp (POS_MINUS_OP,
2080				      make_numeric_value (op->ready),
2081				      blockage);
2082
2083	      blockage = operate_exp (MAX_OP, blockage, op->issue_exp);
2084#endif
2085	      blockage = simplify_knowing (blockage, unit->condexp);
2086
2087	      /* Add this op's contribution to MAX (BLOCKAGE (E,*)) and
2088		 MIN (BLOCKAGE (E,*)).  */
2089	      if (max_blockage == 0)
2090		max_blockage = min_blockage = blockage;
2091	      else
2092		{
2093		  max_blockage
2094		    = simplify_knowing (operate_exp (MAX_OP, max_blockage,
2095						     blockage),
2096					unit->condexp);
2097		  min_blockage
2098		    = simplify_knowing (operate_exp (MIN_OP, min_blockage,
2099						     blockage),
2100					unit->condexp);
2101		}
2102
2103	      /* Make an attribute for use in the blockage function.  */
2104	      str = attr_printf (strlen (unit->name) + sizeof ("*_block_") + MAX_DIGITS,
2105				 "*%s_block_%d", unit->name, op->num);
2106	      make_internal_attr (str, blockage, 1);
2107	    }
2108
2109	  /* Record MAX (BLOCKAGE (*,*)).  */
2110	  unit->max_blockage = max_attr_value (max_blockage);
2111
2112	  /* See if the upper and lower bounds of BLOCKAGE (E,*) are the
2113	     same.  If so, the blockage function carries no additional
2114	     information and is not written.  */
2115	  newexp = operate_exp (EQ_OP, max_blockage, min_blockage);
2116	  newexp = simplify_knowing (newexp, unit->condexp);
2117	  unit->needs_blockage_function
2118	    = (GET_CODE (newexp) != CONST_STRING
2119	       || atoi (XSTR (newexp, 0)) != 1);
2120
2121	  /* If the all values of BLOCKAGE (E,C) have the same value,
2122	     neither blockage function is written.  */
2123	  unit->needs_range_function
2124	    = (unit->needs_blockage_function
2125	       || GET_CODE (max_blockage) != CONST_STRING);
2126
2127	  if (unit->needs_range_function)
2128	    {
2129	      /* Compute the blockage range function and make an attribute
2130		 for writing its value.  */
2131	      newexp = operate_exp (RANGE_OP, min_blockage, max_blockage);
2132	      newexp = simplify_knowing (newexp, unit->condexp);
2133
2134	      str = attr_printf (strlen (unit->name) + sizeof ("*_unit_blockage_range"),
2135				 "*%s_unit_blockage_range", unit->name);
2136	      make_internal_attr (str, newexp, 20);
2137	    }
2138
2139	  str = attr_printf (strlen (unit->name) + sizeof ("*_unit_ready_cost"),
2140			     "*%s_unit_ready_cost", unit->name);
2141	}
2142      else
2143	str = "*result_ready_cost";
2144
2145      /* Make an attribute for the ready_cost function.  Simplifying
2146	 further with simplify_by_exploding doesn't win.  */
2147      make_internal_attr (str, readycost, 0);
2148    }
2149
2150  /* For each unit that requires a conflict cost function, make an attribute
2151     that maps insns to the operation number.  */
2152  for (unit = units; unit; unit = unit->next)
2153    {
2154      rtx caseexp;
2155
2156      if (! unit->needs_conflict_function
2157	  && ! unit->needs_blockage_function)
2158	continue;
2159
2160      caseexp = rtx_alloc (COND);
2161      XVEC (caseexp, 0) = rtvec_alloc ((unit->num_opclasses - 1) * 2);
2162
2163      for (op = unit->ops; op; op = op->next)
2164	{
2165	  /* Make our adjustment to the COND being computed.  If we are the
2166	     last operation class, place our values into the default of the
2167	     COND.  */
2168	  if (op->num == unit->num_opclasses - 1)
2169	    {
2170	      XEXP (caseexp, 1) = make_numeric_value (op->num);
2171	    }
2172	  else
2173	    {
2174	      XVECEXP (caseexp, 0, op->num * 2) = op->condexp;
2175	      XVECEXP (caseexp, 0, op->num * 2 + 1)
2176		= make_numeric_value (op->num);
2177	    }
2178	}
2179
2180      /* Simplifying caseexp with simplify_by_exploding doesn't win.  */
2181      str = attr_printf (strlen (unit->name) + sizeof ("*_cases"),
2182			 "*%s_cases", unit->name);
2183      make_internal_attr (str, caseexp, 1);
2184    }
2185}
2186
2187/* Simplify EXP given KNOWN_TRUE.  */
2188
2189static rtx
2190simplify_knowing (exp, known_true)
2191     rtx exp, known_true;
2192{
2193  if (GET_CODE (exp) != CONST_STRING)
2194    {
2195      exp = attr_rtx (IF_THEN_ELSE, known_true, exp,
2196		      make_numeric_value (max_attr_value (exp)));
2197      exp = simplify_by_exploding (exp);
2198    }
2199  return exp;
2200}
2201
2202/* Translate the CONST_STRING expressions in X to change the encoding of
2203   value.  On input, the value is a bitmask with a one bit for each unit
2204   used; on output, the value is the unit number (zero based) if one
2205   and only one unit is used or the one's compliment of the bitmask.  */
2206
2207static rtx
2208encode_units_mask (x)
2209     rtx x;
2210{
2211  register int i;
2212  register int j;
2213  register enum rtx_code code;
2214  register char *fmt;
2215
2216  code = GET_CODE (x);
2217
2218  switch (code)
2219    {
2220    case CONST_STRING:
2221      i = atoi (XSTR (x, 0));
2222      if (i < 0)
2223	abort (); /* The sign bit encodes a one's compliment mask.  */
2224      else if (i != 0 && i == (i & -i))
2225	/* Only one bit is set, so yield that unit number.  */
2226	for (j = 0; (i >>= 1) != 0; j++)
2227	  ;
2228      else
2229	j = ~i;
2230      return attr_rtx (CONST_STRING, attr_printf (MAX_DIGITS, "%d", j));
2231
2232    case REG:
2233    case QUEUED:
2234    case CONST_INT:
2235    case CONST_DOUBLE:
2236    case SYMBOL_REF:
2237    case CODE_LABEL:
2238    case PC:
2239    case CC0:
2240    case EQ_ATTR:
2241      return x;
2242
2243    default:
2244      break;
2245    }
2246
2247  /* Compare the elements.  If any pair of corresponding elements
2248     fail to match, return 0 for the whole things.  */
2249
2250  fmt = GET_RTX_FORMAT (code);
2251  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
2252    {
2253      switch (fmt[i])
2254	{
2255	case 'V':
2256	case 'E':
2257	  for (j = 0; j < XVECLEN (x, i); j++)
2258	    XVECEXP (x, i, j) = encode_units_mask (XVECEXP (x, i, j));
2259	  break;
2260
2261	case 'e':
2262	  XEXP (x, i) = encode_units_mask (XEXP (x, i));
2263	  break;
2264	}
2265    }
2266  return x;
2267}
2268
2269/* Once all attributes and insns have been read and checked, we construct for
2270   each attribute value a list of all the insns that have that value for
2271   the attribute.  */
2272
2273static void
2274fill_attr (attr)
2275     struct attr_desc *attr;
2276{
2277  struct attr_value *av;
2278  struct insn_ent *ie;
2279  struct insn_def *id;
2280  int i;
2281  rtx value;
2282
2283  /* Don't fill constant attributes.  The value is independent of
2284     any particular insn.  */
2285  if (attr->is_const)
2286    return;
2287
2288  for (id = defs; id; id = id->next)
2289    {
2290      /* If no value is specified for this insn for this attribute, use the
2291	 default.  */
2292      value = NULL;
2293      if (XVEC (id->def, id->vec_idx))
2294	for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
2295	  if (! strcmp (XSTR (XEXP (XVECEXP (id->def, id->vec_idx, i), 0), 0),
2296			attr->name))
2297	    value = XEXP (XVECEXP (id->def, id->vec_idx, i), 1);
2298
2299      if (value == NULL)
2300	av = attr->default_val;
2301      else
2302	av = get_attr_value (value, attr, id->insn_code);
2303
2304      ie = (struct insn_ent *) oballoc (sizeof (struct insn_ent));
2305      ie->insn_code = id->insn_code;
2306      ie->insn_index = id->insn_code;
2307      insert_insn_ent (av, ie);
2308    }
2309}
2310
2311/* Given an expression EXP, see if it is a COND or IF_THEN_ELSE that has a
2312   test that checks relative positions of insns (uses MATCH_DUP or PC).
2313   If so, replace it with what is obtained by passing the expression to
2314   ADDRESS_FN.  If not but it is a COND or IF_THEN_ELSE, call this routine
2315   recursively on each value (including the default value).  Otherwise,
2316   return the value returned by NO_ADDRESS_FN applied to EXP.  */
2317
2318static rtx
2319substitute_address (exp, no_address_fn, address_fn)
2320     rtx exp;
2321     rtx (*no_address_fn) ();
2322     rtx (*address_fn) ();
2323{
2324  int i;
2325  rtx newexp;
2326
2327  if (GET_CODE (exp) == COND)
2328    {
2329      /* See if any tests use addresses.  */
2330      address_used = 0;
2331      for (i = 0; i < XVECLEN (exp, 0); i += 2)
2332	walk_attr_value (XVECEXP (exp, 0, i));
2333
2334      if (address_used)
2335	return (*address_fn) (exp);
2336
2337      /* Make a new copy of this COND, replacing each element.  */
2338      newexp = rtx_alloc (COND);
2339      XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0));
2340      for (i = 0; i < XVECLEN (exp, 0); i += 2)
2341	{
2342	  XVECEXP (newexp, 0, i) = XVECEXP (exp, 0, i);
2343	  XVECEXP (newexp, 0, i + 1)
2344	    = substitute_address (XVECEXP (exp, 0, i + 1),
2345				  no_address_fn, address_fn);
2346	}
2347
2348      XEXP (newexp, 1) = substitute_address (XEXP (exp, 1),
2349					     no_address_fn, address_fn);
2350
2351      return newexp;
2352    }
2353
2354  else if (GET_CODE (exp) == IF_THEN_ELSE)
2355    {
2356      address_used = 0;
2357      walk_attr_value (XEXP (exp, 0));
2358      if (address_used)
2359	return (*address_fn) (exp);
2360
2361      return attr_rtx (IF_THEN_ELSE,
2362		       substitute_address (XEXP (exp, 0),
2363					   no_address_fn, address_fn),
2364		       substitute_address (XEXP (exp, 1),
2365					   no_address_fn, address_fn),
2366		       substitute_address (XEXP (exp, 2),
2367					   no_address_fn, address_fn));
2368    }
2369
2370  return (*no_address_fn) (exp);
2371}
2372
2373/* Make new attributes from the `length' attribute.  The following are made,
2374   each corresponding to a function called from `shorten_branches' or
2375   `get_attr_length':
2376
2377   *insn_default_length		This is the length of the insn to be returned
2378				by `get_attr_length' before `shorten_branches'
2379				has been called.  In each case where the length
2380				depends on relative addresses, the largest
2381				possible is used.  This routine is also used
2382				to compute the initial size of the insn.
2383
2384   *insn_variable_length_p	This returns 1 if the insn's length depends
2385				on relative addresses, zero otherwise.
2386
2387   *insn_current_length		This is only called when it is known that the
2388				insn has a variable length and returns the
2389				current length, based on relative addresses.
2390  */
2391
2392static void
2393make_length_attrs ()
2394{
2395  static char *new_names[] = {"*insn_default_length",
2396			      "*insn_variable_length_p",
2397			      "*insn_current_length"};
2398  static rtx (*no_address_fn[]) PROTO((rtx)) = {identity_fn, zero_fn, zero_fn};
2399  static rtx (*address_fn[]) PROTO((rtx)) = {max_fn, one_fn, identity_fn};
2400  size_t i;
2401  struct attr_desc *length_attr, *new_attr;
2402  struct attr_value *av, *new_av;
2403  struct insn_ent *ie, *new_ie;
2404
2405  /* See if length attribute is defined.  If so, it must be numeric.  Make
2406     it special so we don't output anything for it.  */
2407  length_attr = find_attr ("length", 0);
2408  if (length_attr == 0)
2409    return;
2410
2411  if (! length_attr->is_numeric)
2412    fatal ("length attribute must be numeric.");
2413
2414  length_attr->is_const = 0;
2415  length_attr->is_special = 1;
2416
2417  /* Make each new attribute, in turn.  */
2418  for (i = 0; i < sizeof new_names / sizeof new_names[0]; i++)
2419    {
2420      make_internal_attr (new_names[i],
2421			  substitute_address (length_attr->default_val->value,
2422					      no_address_fn[i], address_fn[i]),
2423			  0);
2424      new_attr = find_attr (new_names[i], 0);
2425      for (av = length_attr->first_value; av; av = av->next)
2426	for (ie = av->first_insn; ie; ie = ie->next)
2427	  {
2428	    new_av = get_attr_value (substitute_address (av->value,
2429							 no_address_fn[i],
2430							 address_fn[i]),
2431				     new_attr, ie->insn_code);
2432	    new_ie = (struct insn_ent *) oballoc (sizeof (struct insn_ent));
2433	    new_ie->insn_code = ie->insn_code;
2434	    new_ie->insn_index = ie->insn_index;
2435	    insert_insn_ent (new_av, new_ie);
2436	  }
2437    }
2438}
2439
2440/* Utility functions called from above routine.  */
2441
2442static rtx
2443identity_fn (exp)
2444     rtx exp;
2445{
2446  return exp;
2447}
2448
2449static rtx
2450zero_fn (exp)
2451     rtx exp ATTRIBUTE_UNUSED;
2452{
2453  return make_numeric_value (0);
2454}
2455
2456static rtx
2457one_fn (exp)
2458     rtx exp ATTRIBUTE_UNUSED;
2459{
2460  return make_numeric_value (1);
2461}
2462
2463static rtx
2464max_fn (exp)
2465     rtx exp;
2466{
2467  return make_numeric_value (max_attr_value (exp));
2468}
2469
2470static void
2471write_length_unit_log ()
2472{
2473  struct attr_desc *length_attr = find_attr ("length", 0);
2474  struct attr_value *av;
2475  struct insn_ent *ie;
2476  unsigned int length_unit_log, length_or;
2477
2478  if (length_attr == 0)
2479    return;
2480  length_or = or_attr_value (length_attr->default_val->value);
2481    for (av = length_attr->first_value; av; av = av->next)
2482      for (ie = av->first_insn; ie; ie = ie->next)
2483	length_or |= or_attr_value (av->value);
2484  length_or = ~length_or;
2485  for (length_unit_log = 0; length_or & 1; length_or >>= 1)
2486    length_unit_log++;
2487  printf ("int length_unit_log = %u;\n", length_unit_log);
2488}
2489
2490/* Take a COND expression and see if any of the conditions in it can be
2491   simplified.  If any are known true or known false for the particular insn
2492   code, the COND can be further simplified.
2493
2494   Also call ourselves on any COND operations that are values of this COND.
2495
2496   We do not modify EXP; rather, we make and return a new rtx.  */
2497
2498static rtx
2499simplify_cond (exp, insn_code, insn_index)
2500     rtx exp;
2501     int insn_code, insn_index;
2502{
2503  int i, j;
2504  /* We store the desired contents here,
2505     then build a new expression if they don't match EXP.  */
2506  rtx defval = XEXP (exp, 1);
2507  rtx new_defval = XEXP (exp, 1);
2508  int len = XVECLEN (exp, 0);
2509  rtunion *tests = (rtunion *) alloca (len * sizeof (rtunion));
2510  int allsame = 1;
2511  char *first_spacer;
2512
2513  /* This lets us free all storage allocated below, if appropriate.  */
2514  first_spacer = (char *) obstack_finish (rtl_obstack);
2515
2516  bcopy ((char *) XVEC (exp, 0)->elem, (char *) tests, len * sizeof (rtunion));
2517
2518  /* See if default value needs simplification.  */
2519  if (GET_CODE (defval) == COND)
2520    new_defval = simplify_cond (defval, insn_code, insn_index);
2521
2522  /* Simplify the subexpressions, and see what tests we can get rid of.  */
2523
2524  for (i = 0; i < len; i += 2)
2525    {
2526      rtx newtest, newval;
2527
2528      /* Simplify this test.  */
2529      newtest = SIMPLIFY_TEST_EXP (tests[i].rtx, insn_code, insn_index);
2530      tests[i].rtx = newtest;
2531
2532      newval = tests[i + 1].rtx;
2533      /* See if this value may need simplification.  */
2534      if (GET_CODE (newval) == COND)
2535	newval = simplify_cond (newval, insn_code, insn_index);
2536
2537      /* Look for ways to delete or combine this test.  */
2538      if (newtest == true_rtx)
2539	{
2540	  /* If test is true, make this value the default
2541	     and discard this + any following tests.  */
2542	  len = i;
2543	  defval = tests[i + 1].rtx;
2544	  new_defval = newval;
2545	}
2546
2547      else if (newtest == false_rtx)
2548	{
2549	  /* If test is false, discard it and its value.  */
2550	  for (j = i; j < len - 2; j++)
2551	    tests[j].rtx = tests[j + 2].rtx;
2552	  len -= 2;
2553	}
2554
2555      else if (i > 0 && attr_equal_p (newval, tests[i - 1].rtx))
2556	{
2557	  /* If this value and the value for the prev test are the same,
2558	     merge the tests.  */
2559
2560	  tests[i - 2].rtx
2561	    = insert_right_side (IOR, tests[i - 2].rtx, newtest,
2562				 insn_code, insn_index);
2563
2564	  /* Delete this test/value.  */
2565	  for (j = i; j < len - 2; j++)
2566	    tests[j].rtx = tests[j + 2].rtx;
2567	  len -= 2;
2568	}
2569
2570      else
2571	tests[i + 1].rtx = newval;
2572    }
2573
2574  /* If the last test in a COND has the same value
2575     as the default value, that test isn't needed.  */
2576
2577  while (len > 0 && attr_equal_p (tests[len - 1].rtx, new_defval))
2578    len -= 2;
2579
2580  /* See if we changed anything.  */
2581  if (len != XVECLEN (exp, 0) || new_defval != XEXP (exp, 1))
2582    allsame = 0;
2583  else
2584    for (i = 0; i < len; i++)
2585      if (! attr_equal_p (tests[i].rtx, XVECEXP (exp, 0, i)))
2586	{
2587	  allsame = 0;
2588	  break;
2589	}
2590
2591  if (len == 0)
2592    {
2593      obstack_free (rtl_obstack, first_spacer);
2594      if (GET_CODE (defval) == COND)
2595	return simplify_cond (defval, insn_code, insn_index);
2596      return defval;
2597    }
2598  else if (allsame)
2599    {
2600      obstack_free (rtl_obstack, first_spacer);
2601      return exp;
2602    }
2603  else
2604    {
2605      rtx newexp = rtx_alloc (COND);
2606
2607      XVEC (newexp, 0) = rtvec_alloc (len);
2608      bcopy ((char *) tests, (char *) XVEC (newexp, 0)->elem,
2609	     len * sizeof (rtunion));
2610      XEXP (newexp, 1) = new_defval;
2611      return newexp;
2612    }
2613}
2614
2615/* Remove an insn entry from an attribute value.  */
2616
2617static void
2618remove_insn_ent (av, ie)
2619     struct attr_value *av;
2620     struct insn_ent *ie;
2621{
2622  struct insn_ent *previe;
2623
2624  if (av->first_insn == ie)
2625    av->first_insn = ie->next;
2626  else
2627    {
2628      for (previe = av->first_insn; previe->next != ie; previe = previe->next)
2629	;
2630      previe->next = ie->next;
2631    }
2632
2633  av->num_insns--;
2634  if (ie->insn_code == -1)
2635    av->has_asm_insn = 0;
2636
2637  num_insn_ents--;
2638}
2639
2640/* Insert an insn entry in an attribute value list.  */
2641
2642static void
2643insert_insn_ent (av, ie)
2644     struct attr_value *av;
2645     struct insn_ent *ie;
2646{
2647  ie->next = av->first_insn;
2648  av->first_insn = ie;
2649  av->num_insns++;
2650  if (ie->insn_code == -1)
2651    av->has_asm_insn = 1;
2652
2653  num_insn_ents++;
2654}
2655
2656/* This is a utility routine to take an expression that is a tree of either
2657   AND or IOR expressions and insert a new term.  The new term will be
2658   inserted at the right side of the first node whose code does not match
2659   the root.  A new node will be created with the root's code.  Its left
2660   side will be the old right side and its right side will be the new
2661   term.
2662
2663   If the `term' is itself a tree, all its leaves will be inserted.  */
2664
2665static rtx
2666insert_right_side (code, exp, term, insn_code, insn_index)
2667     enum rtx_code code;
2668     rtx exp;
2669     rtx term;
2670     int insn_code, insn_index;
2671{
2672  rtx newexp;
2673
2674  /* Avoid consing in some special cases.  */
2675  if (code == AND && term == true_rtx)
2676    return exp;
2677  if (code == AND && term == false_rtx)
2678    return false_rtx;
2679  if (code == AND && exp == true_rtx)
2680    return term;
2681  if (code == AND && exp == false_rtx)
2682    return false_rtx;
2683  if (code == IOR && term == true_rtx)
2684    return true_rtx;
2685  if (code == IOR && term == false_rtx)
2686    return exp;
2687  if (code == IOR && exp == true_rtx)
2688    return true_rtx;
2689  if (code == IOR && exp == false_rtx)
2690    return term;
2691  if (attr_equal_p (exp, term))
2692    return exp;
2693
2694  if (GET_CODE (term) == code)
2695    {
2696      exp = insert_right_side (code, exp, XEXP (term, 0),
2697			       insn_code, insn_index);
2698      exp = insert_right_side (code, exp, XEXP (term, 1),
2699			       insn_code, insn_index);
2700
2701      return exp;
2702    }
2703
2704  if (GET_CODE (exp) == code)
2705    {
2706      rtx new = insert_right_side (code, XEXP (exp, 1),
2707				   term, insn_code, insn_index);
2708      if (new != XEXP (exp, 1))
2709	/* Make a copy of this expression and call recursively.  */
2710	newexp = attr_rtx (code, XEXP (exp, 0), new);
2711      else
2712	newexp = exp;
2713    }
2714  else
2715    {
2716      /* Insert the new term.  */
2717      newexp = attr_rtx (code, exp, term);
2718    }
2719
2720  return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2721}
2722
2723/* If we have an expression which AND's a bunch of
2724	(not (eq_attrq "alternative" "n"))
2725   terms, we may have covered all or all but one of the possible alternatives.
2726   If so, we can optimize.  Similarly for IOR's of EQ_ATTR.
2727
2728   This routine is passed an expression and either AND or IOR.  It returns a
2729   bitmask indicating which alternatives are mentioned within EXP.  */
2730
2731static int
2732compute_alternative_mask (exp, code)
2733     rtx exp;
2734     enum rtx_code code;
2735{
2736  char *string;
2737  if (GET_CODE (exp) == code)
2738    return compute_alternative_mask (XEXP (exp, 0), code)
2739	   | compute_alternative_mask (XEXP (exp, 1), code);
2740
2741  else if (code == AND && GET_CODE (exp) == NOT
2742	   && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
2743	   && XSTR (XEXP (exp, 0), 0) == alternative_name)
2744    string = XSTR (XEXP (exp, 0), 1);
2745
2746  else if (code == IOR && GET_CODE (exp) == EQ_ATTR
2747	   && XSTR (exp, 0) == alternative_name)
2748    string = XSTR (exp, 1);
2749
2750  else
2751    return 0;
2752
2753  if (string[1] == 0)
2754    return 1 << (string[0] - '0');
2755  return 1 << atoi (string);
2756}
2757
2758/* Given I, a single-bit mask, return RTX to compare the `alternative'
2759   attribute with the value represented by that bit.  */
2760
2761static rtx
2762make_alternative_compare (mask)
2763     int mask;
2764{
2765  rtx newexp;
2766  int i;
2767
2768  /* Find the bit.  */
2769  for (i = 0; (mask & (1 << i)) == 0; i++)
2770    ;
2771
2772  newexp = attr_rtx (EQ_ATTR, alternative_name, attr_numeral (i));
2773  RTX_UNCHANGING_P (newexp) = 1;
2774
2775  return newexp;
2776}
2777
2778/* If we are processing an (eq_attr "attr" "value") test, we find the value
2779   of "attr" for this insn code.  From that value, we can compute a test
2780   showing when the EQ_ATTR will be true.  This routine performs that
2781   computation.  If a test condition involves an address, we leave the EQ_ATTR
2782   intact because addresses are only valid for the `length' attribute.
2783
2784   EXP is the EQ_ATTR expression and VALUE is the value of that attribute
2785   for the insn corresponding to INSN_CODE and INSN_INDEX.  */
2786
2787static rtx
2788evaluate_eq_attr (exp, value, insn_code, insn_index)
2789     rtx exp;
2790     rtx value;
2791     int insn_code, insn_index;
2792{
2793  rtx orexp, andexp;
2794  rtx right;
2795  rtx newexp;
2796  int i;
2797
2798  if (GET_CODE (value) == CONST_STRING)
2799    {
2800      if (! strcmp (XSTR (value, 0), XSTR (exp, 1)))
2801	newexp = true_rtx;
2802      else
2803	newexp = false_rtx;
2804    }
2805  else if (GET_CODE (value) == SYMBOL_REF)
2806    {
2807      char *p, *string;
2808
2809      if (GET_CODE (exp) != EQ_ATTR)
2810	abort();
2811
2812      string = (char *) alloca (2 + strlen (XSTR (exp, 0))
2813				+ strlen (XSTR (exp, 1)));
2814      strcpy (string, XSTR (exp, 0));
2815      strcat (string, "_");
2816      strcat (string, XSTR (exp, 1));
2817      for (p = string; *p ; p++)
2818	if (*p >= 'a' && *p <= 'z')
2819	  *p -= 'a' - 'A';
2820
2821      newexp = attr_rtx (EQ, value,
2822			 attr_rtx (SYMBOL_REF,
2823				   attr_string(string, strlen(string))));
2824    }
2825  else if (GET_CODE (value) == COND)
2826    {
2827      /* We construct an IOR of all the cases for which the requested attribute
2828	 value is present.  Since we start with FALSE, if it is not present,
2829	 FALSE will be returned.
2830
2831	 Each case is the AND of the NOT's of the previous conditions with the
2832	 current condition; in the default case the current condition is TRUE.
2833
2834	 For each possible COND value, call ourselves recursively.
2835
2836	 The extra TRUE and FALSE expressions will be eliminated by another
2837	 call to the simplification routine.  */
2838
2839      orexp = false_rtx;
2840      andexp = true_rtx;
2841
2842      if (current_alternative_string)
2843	clear_struct_flag (value);
2844
2845      for (i = 0; i < XVECLEN (value, 0); i += 2)
2846	{
2847	  rtx this = SIMPLIFY_TEST_EXP (XVECEXP (value, 0, i),
2848					insn_code, insn_index);
2849
2850	  SIMPLIFY_ALTERNATIVE (this);
2851
2852	  right = insert_right_side (AND, andexp, this,
2853				     insn_code, insn_index);
2854	  right = insert_right_side (AND, right,
2855				     evaluate_eq_attr (exp,
2856						       XVECEXP (value, 0,
2857								i + 1),
2858						       insn_code, insn_index),
2859				     insn_code, insn_index);
2860	  orexp = insert_right_side (IOR, orexp, right,
2861				     insn_code, insn_index);
2862
2863	  /* Add this condition into the AND expression.  */
2864	  newexp = attr_rtx (NOT, this);
2865	  andexp = insert_right_side (AND, andexp, newexp,
2866				      insn_code, insn_index);
2867	}
2868
2869      /* Handle the default case.  */
2870      right = insert_right_side (AND, andexp,
2871				 evaluate_eq_attr (exp, XEXP (value, 1),
2872						   insn_code, insn_index),
2873				 insn_code, insn_index);
2874      newexp = insert_right_side (IOR, orexp, right, insn_code, insn_index);
2875    }
2876  else
2877    abort ();
2878
2879  /* If uses an address, must return original expression.  But set the
2880     RTX_UNCHANGING_P bit so we don't try to simplify it again.  */
2881
2882  address_used = 0;
2883  walk_attr_value (newexp);
2884
2885  if (address_used)
2886    {
2887      /* This had `&& current_alternative_string', which seems to be wrong.  */
2888      if (! RTX_UNCHANGING_P (exp))
2889	return copy_rtx_unchanging (exp);
2890      return exp;
2891    }
2892  else
2893    return newexp;
2894}
2895
2896/* This routine is called when an AND of a term with a tree of AND's is
2897   encountered.  If the term or its complement is present in the tree, it
2898   can be replaced with TRUE or FALSE, respectively.
2899
2900   Note that (eq_attr "att" "v1") and (eq_attr "att" "v2") cannot both
2901   be true and hence are complementary.
2902
2903   There is one special case:  If we see
2904	(and (not (eq_attr "att" "v1"))
2905	     (eq_attr "att" "v2"))
2906   this can be replaced by (eq_attr "att" "v2").  To do this we need to
2907   replace the term, not anything in the AND tree.  So we pass a pointer to
2908   the term.  */
2909
2910static rtx
2911simplify_and_tree (exp, pterm, insn_code, insn_index)
2912     rtx exp;
2913     rtx *pterm;
2914     int insn_code, insn_index;
2915{
2916  rtx left, right;
2917  rtx newexp;
2918  rtx temp;
2919  int left_eliminates_term, right_eliminates_term;
2920
2921  if (GET_CODE (exp) == AND)
2922    {
2923      left = simplify_and_tree (XEXP (exp, 0), pterm,  insn_code, insn_index);
2924      right = simplify_and_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
2925      if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2926	{
2927	  newexp = attr_rtx (GET_CODE (exp), left, right);
2928
2929	  exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2930	}
2931    }
2932
2933  else if (GET_CODE (exp) == IOR)
2934    {
2935      /* For the IOR case, we do the same as above, except that we can
2936         only eliminate `term' if both sides of the IOR would do so.  */
2937      temp = *pterm;
2938      left = simplify_and_tree (XEXP (exp, 0), &temp,  insn_code, insn_index);
2939      left_eliminates_term = (temp == true_rtx);
2940
2941      temp = *pterm;
2942      right = simplify_and_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
2943      right_eliminates_term = (temp == true_rtx);
2944
2945      if (left_eliminates_term && right_eliminates_term)
2946	*pterm = true_rtx;
2947
2948      if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2949	{
2950	  newexp = attr_rtx (GET_CODE (exp), left, right);
2951
2952	  exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2953	}
2954    }
2955
2956  /* Check for simplifications.  Do some extra checking here since this
2957     routine is called so many times.  */
2958
2959  if (exp == *pterm)
2960    return true_rtx;
2961
2962  else if (GET_CODE (exp) == NOT && XEXP (exp, 0) == *pterm)
2963    return false_rtx;
2964
2965  else if (GET_CODE (*pterm) == NOT && exp == XEXP (*pterm, 0))
2966    return false_rtx;
2967
2968  else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == EQ_ATTR)
2969    {
2970      if (XSTR (exp, 0) != XSTR (*pterm, 0))
2971	return exp;
2972
2973      if (! strcmp (XSTR (exp, 1), XSTR (*pterm, 1)))
2974	return true_rtx;
2975      else
2976	return false_rtx;
2977    }
2978
2979  else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
2980	   && GET_CODE (XEXP (exp, 0)) == EQ_ATTR)
2981    {
2982      if (XSTR (*pterm, 0) != XSTR (XEXP (exp, 0), 0))
2983	return exp;
2984
2985      if (! strcmp (XSTR (*pterm, 1), XSTR (XEXP (exp, 0), 1)))
2986	return false_rtx;
2987      else
2988	return true_rtx;
2989    }
2990
2991  else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
2992	   && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR)
2993    {
2994      if (XSTR (exp, 0) != XSTR (XEXP (*pterm, 0), 0))
2995	return exp;
2996
2997      if (! strcmp (XSTR (exp, 1), XSTR (XEXP (*pterm, 0), 1)))
2998	return false_rtx;
2999      else
3000	*pterm = true_rtx;
3001    }
3002
3003  else if (GET_CODE (exp) == NOT && GET_CODE (*pterm) == NOT)
3004    {
3005      if (attr_equal_p (XEXP (exp, 0), XEXP (*pterm, 0)))
3006	return true_rtx;
3007    }
3008
3009  else if (GET_CODE (exp) == NOT)
3010    {
3011      if (attr_equal_p (XEXP (exp, 0), *pterm))
3012	return false_rtx;
3013    }
3014
3015  else if (GET_CODE (*pterm) == NOT)
3016    {
3017      if (attr_equal_p (XEXP (*pterm, 0), exp))
3018	return false_rtx;
3019    }
3020
3021  else if (attr_equal_p (exp, *pterm))
3022    return true_rtx;
3023
3024  return exp;
3025}
3026
3027/* Similar to `simplify_and_tree', but for IOR trees.  */
3028
3029static rtx
3030simplify_or_tree (exp, pterm, insn_code, insn_index)
3031     rtx exp;
3032     rtx *pterm;
3033     int insn_code, insn_index;
3034{
3035  rtx left, right;
3036  rtx newexp;
3037  rtx temp;
3038  int left_eliminates_term, right_eliminates_term;
3039
3040  if (GET_CODE (exp) == IOR)
3041    {
3042      left = simplify_or_tree (XEXP (exp, 0), pterm,  insn_code, insn_index);
3043      right = simplify_or_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
3044      if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
3045	{
3046	  newexp = attr_rtx (GET_CODE (exp), left, right);
3047
3048	  exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3049	}
3050    }
3051
3052  else if (GET_CODE (exp) == AND)
3053    {
3054      /* For the AND case, we do the same as above, except that we can
3055         only eliminate `term' if both sides of the AND would do so.  */
3056      temp = *pterm;
3057      left = simplify_or_tree (XEXP (exp, 0), &temp,  insn_code, insn_index);
3058      left_eliminates_term = (temp == false_rtx);
3059
3060      temp = *pterm;
3061      right = simplify_or_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
3062      right_eliminates_term = (temp == false_rtx);
3063
3064      if (left_eliminates_term && right_eliminates_term)
3065	*pterm = false_rtx;
3066
3067      if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
3068	{
3069	  newexp = attr_rtx (GET_CODE (exp), left, right);
3070
3071	  exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3072	}
3073    }
3074
3075  if (attr_equal_p (exp, *pterm))
3076    return false_rtx;
3077
3078  else if (GET_CODE (exp) == NOT && attr_equal_p (XEXP (exp, 0), *pterm))
3079    return true_rtx;
3080
3081  else if (GET_CODE (*pterm) == NOT && attr_equal_p (XEXP (*pterm, 0), exp))
3082    return true_rtx;
3083
3084  else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
3085	   && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
3086	   && XSTR (*pterm, 0) == XSTR (XEXP (exp, 0), 0))
3087    *pterm = false_rtx;
3088
3089  else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
3090	   && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR
3091	   && XSTR (exp, 0) == XSTR (XEXP (*pterm, 0), 0))
3092    return false_rtx;
3093
3094  return exp;
3095}
3096
3097/* Given an expression, see if it can be simplified for a particular insn
3098   code based on the values of other attributes being tested.  This can
3099   eliminate nested get_attr_... calls.
3100
3101   Note that if an endless recursion is specified in the patterns, the
3102   optimization will loop.  However, it will do so in precisely the cases where
3103   an infinite recursion loop could occur during compilation.  It's better that
3104   it occurs here!  */
3105
3106static rtx
3107simplify_test_exp (exp, insn_code, insn_index)
3108     rtx exp;
3109     int insn_code, insn_index;
3110{
3111  rtx left, right;
3112  struct attr_desc *attr;
3113  struct attr_value *av;
3114  struct insn_ent *ie;
3115  int i;
3116  rtx newexp = exp;
3117  char *spacer = (char *) obstack_finish (rtl_obstack);
3118
3119  /* Don't re-simplify something we already simplified.  */
3120  if (RTX_UNCHANGING_P (exp) || MEM_IN_STRUCT_P (exp))
3121    return exp;
3122
3123  switch (GET_CODE (exp))
3124    {
3125    case AND:
3126      left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
3127      SIMPLIFY_ALTERNATIVE (left);
3128      if (left == false_rtx)
3129	{
3130	  obstack_free (rtl_obstack, spacer);
3131	  return false_rtx;
3132	}
3133      right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
3134      SIMPLIFY_ALTERNATIVE (right);
3135      if (left == false_rtx)
3136	{
3137	  obstack_free (rtl_obstack, spacer);
3138	  return false_rtx;
3139	}
3140
3141      /* If either side is an IOR and we have (eq_attr "alternative" ..")
3142	 present on both sides, apply the distributive law since this will
3143	 yield simplifications.  */
3144      if ((GET_CODE (left) == IOR || GET_CODE (right) == IOR)
3145	  && compute_alternative_mask (left, IOR)
3146	  && compute_alternative_mask (right, IOR))
3147	{
3148	  if (GET_CODE (left) == IOR)
3149	    {
3150	      rtx tem = left;
3151	      left = right;
3152	      right = tem;
3153	    }
3154
3155	  newexp = attr_rtx (IOR,
3156			     attr_rtx (AND, left, XEXP (right, 0)),
3157			     attr_rtx (AND, left, XEXP (right, 1)));
3158
3159	  return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3160	}
3161
3162      /* Try with the term on both sides.  */
3163      right = simplify_and_tree (right, &left, insn_code, insn_index);
3164      if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
3165	left = simplify_and_tree (left, &right, insn_code, insn_index);
3166
3167      if (left == false_rtx || right == false_rtx)
3168	{
3169	  obstack_free (rtl_obstack, spacer);
3170	  return false_rtx;
3171	}
3172      else if (left == true_rtx)
3173	{
3174	  return right;
3175	}
3176      else if (right == true_rtx)
3177	{
3178	  return left;
3179	}
3180      /* See if all or all but one of the insn's alternatives are specified
3181	 in this tree.  Optimize if so.  */
3182
3183      else if (insn_code >= 0
3184	       && (GET_CODE (left) == AND
3185		   || (GET_CODE (left) == NOT
3186		       && GET_CODE (XEXP (left, 0)) == EQ_ATTR
3187		       && XSTR (XEXP (left, 0), 0) == alternative_name)
3188		   || GET_CODE (right) == AND
3189		   || (GET_CODE (right) == NOT
3190		       && GET_CODE (XEXP (right, 0)) == EQ_ATTR
3191		       && XSTR (XEXP (right, 0), 0) == alternative_name)))
3192	{
3193	  i = compute_alternative_mask (exp, AND);
3194	  if (i & ~insn_alternatives[insn_code])
3195	    fatal ("Invalid alternative specified for pattern number %d",
3196		   insn_index);
3197
3198	  /* If all alternatives are excluded, this is false.  */
3199	  i ^= insn_alternatives[insn_code];
3200	  if (i == 0)
3201	    return false_rtx;
3202	  else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
3203	    {
3204	      /* If just one excluded, AND a comparison with that one to the
3205		 front of the tree.  The others will be eliminated by
3206		 optimization.  We do not want to do this if the insn has one
3207		 alternative and we have tested none of them!  */
3208	      left = make_alternative_compare (i);
3209	      right = simplify_and_tree (exp, &left, insn_code, insn_index);
3210	      newexp = attr_rtx (AND, left, right);
3211
3212	      return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3213	    }
3214	}
3215
3216      if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
3217	{
3218	  newexp = attr_rtx (AND, left, right);
3219	  return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3220	}
3221      break;
3222
3223    case IOR:
3224      left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
3225      SIMPLIFY_ALTERNATIVE (left);
3226      if (left == true_rtx)
3227	{
3228	  obstack_free (rtl_obstack, spacer);
3229	  return true_rtx;
3230	}
3231      right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
3232      SIMPLIFY_ALTERNATIVE (right);
3233      if (right == true_rtx)
3234	{
3235	  obstack_free (rtl_obstack, spacer);
3236	  return true_rtx;
3237	}
3238
3239      right = simplify_or_tree (right, &left, insn_code, insn_index);
3240      if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
3241	left = simplify_or_tree (left, &right, insn_code, insn_index);
3242
3243      if (right == true_rtx || left == true_rtx)
3244	{
3245	  obstack_free (rtl_obstack, spacer);
3246	  return true_rtx;
3247	}
3248      else if (left == false_rtx)
3249	{
3250	  return right;
3251	}
3252      else if (right == false_rtx)
3253	{
3254	  return left;
3255	}
3256
3257      /* Test for simple cases where the distributive law is useful.  I.e.,
3258	    convert (ior (and (x) (y))
3259			 (and (x) (z)))
3260	    to      (and (x)
3261			 (ior (y) (z)))
3262       */
3263
3264      else if (GET_CODE (left) == AND && GET_CODE (right) == AND
3265	  && attr_equal_p (XEXP (left, 0), XEXP (right, 0)))
3266	{
3267	  newexp = attr_rtx (IOR, XEXP (left, 1), XEXP (right, 1));
3268
3269	  left = XEXP (left, 0);
3270	  right = newexp;
3271	  newexp = attr_rtx (AND, left, right);
3272	  return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3273	}
3274
3275      /* See if all or all but one of the insn's alternatives are specified
3276	 in this tree.  Optimize if so.  */
3277
3278      else if (insn_code >= 0
3279	  && (GET_CODE (left) == IOR
3280	      || (GET_CODE (left) == EQ_ATTR
3281		  && XSTR (left, 0) == alternative_name)
3282	      || GET_CODE (right) == IOR
3283	      || (GET_CODE (right) == EQ_ATTR
3284		  && XSTR (right, 0) == alternative_name)))
3285	{
3286	  i = compute_alternative_mask (exp, IOR);
3287	  if (i & ~insn_alternatives[insn_code])
3288	    fatal ("Invalid alternative specified for pattern number %d",
3289		   insn_index);
3290
3291	  /* If all alternatives are included, this is true.  */
3292	  i ^= insn_alternatives[insn_code];
3293	  if (i == 0)
3294	    return true_rtx;
3295	  else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
3296	    {
3297	      /* If just one excluded, IOR a comparison with that one to the
3298		 front of the tree.  The others will be eliminated by
3299		 optimization.  We do not want to do this if the insn has one
3300		 alternative and we have tested none of them!  */
3301	      left = make_alternative_compare (i);
3302	      right = simplify_and_tree (exp, &left, insn_code, insn_index);
3303	      newexp = attr_rtx (IOR, attr_rtx (NOT, left), right);
3304
3305	      return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3306	    }
3307	}
3308
3309      if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
3310	{
3311	  newexp = attr_rtx (IOR, left, right);
3312	  return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3313	}
3314      break;
3315
3316    case NOT:
3317      if (GET_CODE (XEXP (exp, 0)) == NOT)
3318	{
3319	  left = SIMPLIFY_TEST_EXP (XEXP (XEXP (exp, 0), 0),
3320				    insn_code, insn_index);
3321	  SIMPLIFY_ALTERNATIVE (left);
3322	  return left;
3323	}
3324
3325      left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
3326      SIMPLIFY_ALTERNATIVE (left);
3327      if (GET_CODE (left) == NOT)
3328	return XEXP (left, 0);
3329
3330      if (left == false_rtx)
3331	{
3332	  obstack_free (rtl_obstack, spacer);
3333	  return true_rtx;
3334	}
3335      else if (left == true_rtx)
3336	{
3337	  obstack_free (rtl_obstack, spacer);
3338	  return false_rtx;
3339	}
3340
3341      /* Try to apply De`Morgan's laws.  */
3342      else if (GET_CODE (left) == IOR)
3343	{
3344	  newexp = attr_rtx (AND,
3345			     attr_rtx (NOT, XEXP (left, 0)),
3346			     attr_rtx (NOT, XEXP (left, 1)));
3347
3348	  newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3349	}
3350      else if (GET_CODE (left) == AND)
3351	{
3352	  newexp = attr_rtx (IOR,
3353			     attr_rtx (NOT, XEXP (left, 0)),
3354			     attr_rtx (NOT, XEXP (left, 1)));
3355
3356	  newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3357	}
3358      else if (left != XEXP (exp, 0))
3359	{
3360	  newexp = attr_rtx (NOT, left);
3361	}
3362      break;
3363
3364    case EQ_ATTR:
3365      if (current_alternative_string && XSTR (exp, 0) == alternative_name)
3366	return (XSTR (exp, 1) == current_alternative_string
3367		? true_rtx : false_rtx);
3368
3369      /* Look at the value for this insn code in the specified attribute.
3370	 We normally can replace this comparison with the condition that
3371	 would give this insn the values being tested for.   */
3372      if (XSTR (exp, 0) != alternative_name
3373	  && (attr = find_attr (XSTR (exp, 0), 0)) != NULL)
3374	for (av = attr->first_value; av; av = av->next)
3375	  for (ie = av->first_insn; ie; ie = ie->next)
3376	    if (ie->insn_code == insn_code)
3377	      return evaluate_eq_attr (exp, av->value, insn_code, insn_index);
3378      break;
3379
3380    default:
3381      break;
3382    }
3383
3384  /* We have already simplified this expression.  Simplifying it again
3385     won't buy anything unless we weren't given a valid insn code
3386     to process (i.e., we are canonicalizing something.).  */
3387  if (insn_code != -2 /* Seems wrong: && current_alternative_string.  */
3388      && ! RTX_UNCHANGING_P (newexp))
3389    return copy_rtx_unchanging (newexp);
3390
3391  return newexp;
3392}
3393
3394/* Optimize the attribute lists by seeing if we can determine conditional
3395   values from the known values of other attributes.  This will save subroutine
3396   calls during the compilation.  */
3397
3398static void
3399optimize_attrs ()
3400{
3401  struct attr_desc *attr;
3402  struct attr_value *av;
3403  struct insn_ent *ie;
3404  rtx newexp;
3405  int something_changed = 1;
3406  int i;
3407  struct attr_value_list { struct attr_value *av;
3408			   struct insn_ent *ie;
3409			   struct attr_desc * attr;
3410			   struct attr_value_list *next; };
3411  struct attr_value_list **insn_code_values;
3412  struct attr_value_list *ivbuf;
3413  struct attr_value_list *iv;
3414
3415  /* For each insn code, make a list of all the insn_ent's for it,
3416     for all values for all attributes.  */
3417
3418  if (num_insn_ents == 0)
3419    return;
3420
3421  /* Make 2 extra elements, for "code" values -2 and -1.  */
3422  insn_code_values
3423    = (struct attr_value_list **) alloca ((insn_code_number + 2)
3424					  * sizeof (struct attr_value_list *));
3425  bzero ((char *) insn_code_values,
3426	 (insn_code_number + 2) * sizeof (struct attr_value_list *));
3427
3428  /* Offset the table address so we can index by -2 or -1.  */
3429  insn_code_values += 2;
3430
3431  /* Allocate the attr_value_list structures using xmalloc rather than
3432     alloca, because using alloca can overflow the maximum permitted
3433     stack limit on SPARC Lynx.  */
3434  iv = ivbuf = ((struct attr_value_list *)
3435		xmalloc (num_insn_ents * sizeof (struct attr_value_list)));
3436
3437  for (i = 0; i < MAX_ATTRS_INDEX; i++)
3438    for (attr = attrs[i]; attr; attr = attr->next)
3439      for (av = attr->first_value; av; av = av->next)
3440	for (ie = av->first_insn; ie; ie = ie->next)
3441	  {
3442	    iv->attr = attr;
3443	    iv->av = av;
3444	    iv->ie = ie;
3445	    iv->next = insn_code_values[ie->insn_code];
3446	    insn_code_values[ie->insn_code] = iv;
3447	    iv++;
3448	  }
3449
3450  /* Sanity check on num_insn_ents.  */
3451  if (iv != ivbuf + num_insn_ents)
3452    abort ();
3453
3454  /* Process one insn code at a time.  */
3455  for (i = -2; i < insn_code_number; i++)
3456    {
3457      /* Clear the MEM_IN_STRUCT_P flag everywhere relevant.
3458	 We use it to mean "already simplified for this insn".  */
3459      for (iv = insn_code_values[i]; iv; iv = iv->next)
3460	clear_struct_flag (iv->av->value);
3461
3462      /* Loop until nothing changes for one iteration.  */
3463      something_changed = 1;
3464      while (something_changed)
3465	{
3466	  something_changed = 0;
3467	  for (iv = insn_code_values[i]; iv; iv = iv->next)
3468	    {
3469	      struct obstack *old = rtl_obstack;
3470	      char *spacer = (char *) obstack_finish (temp_obstack);
3471
3472	      attr = iv->attr;
3473	      av = iv->av;
3474	      ie = iv->ie;
3475	      if (GET_CODE (av->value) != COND)
3476		continue;
3477
3478	      rtl_obstack = temp_obstack;
3479#if 0 /* This was intended as a speed up, but it was slower.  */
3480	      if (insn_n_alternatives[ie->insn_code] > 6
3481		  && count_sub_rtxs (av->value, 200) >= 200)
3482		newexp = simplify_by_alternatives (av->value, ie->insn_code,
3483						   ie->insn_index);
3484	      else
3485#endif
3486		newexp = simplify_cond (av->value, ie->insn_code,
3487					ie->insn_index);
3488
3489	      rtl_obstack = old;
3490	      if (newexp != av->value)
3491		{
3492		  newexp = attr_copy_rtx (newexp);
3493		  remove_insn_ent (av, ie);
3494		  av = get_attr_value (newexp, attr, ie->insn_code);
3495		  iv->av = av;
3496		  insert_insn_ent (av, ie);
3497		  something_changed = 1;
3498		}
3499	      obstack_free (temp_obstack, spacer);
3500	    }
3501	}
3502    }
3503
3504  free (ivbuf);
3505}
3506
3507#if 0
3508static rtx
3509simplify_by_alternatives (exp, insn_code, insn_index)
3510     rtx exp;
3511     int insn_code, insn_index;
3512{
3513  int i;
3514  int len = insn_n_alternatives[insn_code];
3515  rtx newexp = rtx_alloc (COND);
3516  rtx ultimate;
3517
3518
3519  XVEC (newexp, 0) = rtvec_alloc (len * 2);
3520
3521  /* It will not matter what value we use as the default value
3522     of the new COND, since that default will never be used.
3523     Choose something of the right type.  */
3524  for (ultimate = exp; GET_CODE (ultimate) == COND;)
3525    ultimate = XEXP (ultimate, 1);
3526  XEXP (newexp, 1) = ultimate;
3527
3528  for (i = 0; i < insn_n_alternatives[insn_code]; i++)
3529    {
3530      current_alternative_string = attr_numeral (i);
3531      XVECEXP (newexp, 0, i * 2) = make_alternative_compare (1 << i);
3532      XVECEXP (newexp, 0, i * 2 + 1)
3533	= simplify_cond (exp, insn_code, insn_index);
3534    }
3535
3536  current_alternative_string = 0;
3537  return simplify_cond (newexp, insn_code, insn_index);
3538}
3539#endif
3540
3541/* If EXP is a suitable expression, reorganize it by constructing an
3542   equivalent expression that is a COND with the tests being all combinations
3543   of attribute values and the values being simple constants.  */
3544
3545static rtx
3546simplify_by_exploding (exp)
3547     rtx exp;
3548{
3549  rtx list = 0, link, condexp, defval = NULL_RTX;
3550  struct dimension *space;
3551  rtx *condtest, *condval;
3552  int i, j, total, ndim = 0;
3553  int most_tests, num_marks, new_marks;
3554
3555  /* Locate all the EQ_ATTR expressions.  */
3556  if (! find_and_mark_used_attributes (exp, &list, &ndim) || ndim == 0)
3557    {
3558      unmark_used_attributes (list, 0, 0);
3559      return exp;
3560    }
3561
3562  /* Create an attribute space from the list of used attributes.  For each
3563     dimension in the attribute space, record the attribute, list of values
3564     used, and number of values used.  Add members to the list of values to
3565     cover the domain of the attribute.  This makes the expanded COND form
3566     order independent.  */
3567
3568  space = (struct dimension *) alloca (ndim * sizeof (struct dimension));
3569
3570  total = 1;
3571  for (ndim = 0; list; ndim++)
3572    {
3573      /* Pull the first attribute value from the list and record that
3574	 attribute as another dimension in the attribute space.  */
3575      char *name = XSTR (XEXP (list, 0), 0);
3576      rtx *prev;
3577
3578      if ((space[ndim].attr = find_attr (name, 0)) == 0
3579	  || space[ndim].attr->is_numeric)
3580	{
3581	  unmark_used_attributes (list, space, ndim);
3582	  return exp;
3583	}
3584
3585      /* Add all remaining attribute values that refer to this attribute.  */
3586      space[ndim].num_values = 0;
3587      space[ndim].values = 0;
3588      prev = &list;
3589      for (link = list; link; link = *prev)
3590	if (! strcmp (XSTR (XEXP (link, 0), 0), name))
3591	  {
3592	    space[ndim].num_values++;
3593	    *prev = XEXP (link, 1);
3594	    XEXP (link, 1) = space[ndim].values;
3595	    space[ndim].values = link;
3596	  }
3597	else
3598	  prev = &XEXP (link, 1);
3599
3600      /* Add sufficient members to the list of values to make the list
3601	 mutually exclusive and record the total size of the attribute
3602	 space.  */
3603      total *= add_values_to_cover (&space[ndim]);
3604    }
3605
3606  /* Sort the attribute space so that the attributes go from non-constant
3607     to constant and from most values to least values.  */
3608  for (i = 0; i < ndim; i++)
3609    for (j = ndim - 1; j > i; j--)
3610      if ((space[j-1].attr->is_const && !space[j].attr->is_const)
3611	  || space[j-1].num_values < space[j].num_values)
3612	{
3613	  struct dimension tmp;
3614	  tmp = space[j];
3615	  space[j] = space[j-1];
3616	  space[j-1] = tmp;
3617	}
3618
3619  /* Establish the initial current value.  */
3620  for (i = 0; i < ndim; i++)
3621    space[i].current_value = space[i].values;
3622
3623  condtest = (rtx *) alloca (total * sizeof (rtx));
3624  condval = (rtx *) alloca (total * sizeof (rtx));
3625
3626  /* Expand the tests and values by iterating over all values in the
3627     attribute space.  */
3628  for (i = 0;; i++)
3629    {
3630      condtest[i] = test_for_current_value (space, ndim);
3631      condval[i] = simplify_with_current_value (exp, space, ndim);
3632      if (! increment_current_value (space, ndim))
3633	break;
3634    }
3635  if (i != total - 1)
3636    abort ();
3637
3638  /* We are now finished with the original expression.  */
3639  unmark_used_attributes (0, space, ndim);
3640
3641  /* Find the most used constant value and make that the default.  */
3642  most_tests = -1;
3643  for (i = num_marks = 0; i < total; i++)
3644    if (GET_CODE (condval[i]) == CONST_STRING
3645	&& ! MEM_VOLATILE_P (condval[i]))
3646      {
3647	/* Mark the unmarked constant value and count how many are marked.  */
3648	MEM_VOLATILE_P (condval[i]) = 1;
3649	for (j = new_marks = 0; j < total; j++)
3650	  if (GET_CODE (condval[j]) == CONST_STRING
3651	      && MEM_VOLATILE_P (condval[j]))
3652	    new_marks++;
3653	if (new_marks - num_marks > most_tests)
3654	  {
3655	    most_tests = new_marks - num_marks;
3656	    defval = condval[i];
3657	  }
3658	num_marks = new_marks;
3659      }
3660  /* Clear all the marks.  */
3661  for (i = 0; i < total; i++)
3662    MEM_VOLATILE_P (condval[i]) = 0;
3663
3664  /* Give up if nothing is constant.  */
3665  if (num_marks == 0)
3666    return exp;
3667
3668  /* If all values are the default, use that.  */
3669  if (total == most_tests)
3670    return defval;
3671
3672  /* Make a COND with the most common constant value the default.  (A more
3673     complex method where tests with the same value were combined didn't
3674     seem to improve things.)  */
3675  condexp = rtx_alloc (COND);
3676  XVEC (condexp, 0) = rtvec_alloc ((total - most_tests) * 2);
3677  XEXP (condexp, 1) = defval;
3678  for (i = j = 0; i < total; i++)
3679    if (condval[i] != defval)
3680      {
3681	XVECEXP (condexp, 0, 2 * j) = condtest[i];
3682	XVECEXP (condexp, 0, 2 * j + 1) = condval[i];
3683	j++;
3684      }
3685
3686  return condexp;
3687}
3688
3689/* Set the MEM_VOLATILE_P flag for all EQ_ATTR expressions in EXP and
3690   verify that EXP can be simplified to a constant term if all the EQ_ATTR
3691   tests have known value.  */
3692
3693static int
3694find_and_mark_used_attributes (exp, terms, nterms)
3695     rtx exp, *terms;
3696     int *nterms;
3697{
3698  int i;
3699
3700  switch (GET_CODE (exp))
3701    {
3702    case EQ_ATTR:
3703      if (! MEM_VOLATILE_P (exp))
3704	{
3705	  rtx link = rtx_alloc (EXPR_LIST);
3706	  XEXP (link, 0) = exp;
3707	  XEXP (link, 1) = *terms;
3708	  *terms = link;
3709	  *nterms += 1;
3710	  MEM_VOLATILE_P (exp) = 1;
3711	}
3712    case CONST_STRING:
3713    case CONST_INT:
3714      return 1;
3715
3716    case IF_THEN_ELSE:
3717      if (! find_and_mark_used_attributes (XEXP (exp, 2), terms, nterms))
3718	return 0;
3719    case IOR:
3720    case AND:
3721      if (! find_and_mark_used_attributes (XEXP (exp, 1), terms, nterms))
3722	return 0;
3723    case NOT:
3724      if (! find_and_mark_used_attributes (XEXP (exp, 0), terms, nterms))
3725	return 0;
3726      return 1;
3727
3728    case COND:
3729      for (i = 0; i < XVECLEN (exp, 0); i++)
3730	if (! find_and_mark_used_attributes (XVECEXP (exp, 0, i), terms, nterms))
3731	  return 0;
3732      if (! find_and_mark_used_attributes (XEXP (exp, 1), terms, nterms))
3733	return 0;
3734      return 1;
3735
3736    default:
3737      return 0;
3738    }
3739}
3740
3741/* Clear the MEM_VOLATILE_P flag in all EQ_ATTR expressions on LIST and
3742   in the values of the NDIM-dimensional attribute space SPACE.  */
3743
3744static void
3745unmark_used_attributes (list, space, ndim)
3746     rtx list;
3747     struct dimension *space;
3748     int ndim;
3749{
3750  rtx link, exp;
3751  int i;
3752
3753  for (i = 0; i < ndim; i++)
3754    unmark_used_attributes (space[i].values, 0, 0);
3755
3756  for (link = list; link; link = XEXP (link, 1))
3757    {
3758      exp = XEXP (link, 0);
3759      if (GET_CODE (exp) == EQ_ATTR)
3760	MEM_VOLATILE_P (exp) = 0;
3761    }
3762}
3763
3764/* Update the attribute dimension DIM so that all values of the attribute
3765   are tested.  Return the updated number of values.  */
3766
3767static int
3768add_values_to_cover (dim)
3769     struct dimension *dim;
3770{
3771  struct attr_value *av;
3772  rtx exp, link, *prev;
3773  int nalt = 0;
3774
3775  for (av = dim->attr->first_value; av; av = av->next)
3776    if (GET_CODE (av->value) == CONST_STRING)
3777      nalt++;
3778
3779  if (nalt < dim->num_values)
3780    abort ();
3781  else if (nalt == dim->num_values)
3782    ; /* Ok.  */
3783  else if (nalt * 2 < dim->num_values * 3)
3784    {
3785      /* Most all the values of the attribute are used, so add all the unused
3786	 values.  */
3787      prev = &dim->values;
3788      for (link = dim->values; link; link = *prev)
3789	prev = &XEXP (link, 1);
3790
3791      for (av = dim->attr->first_value; av; av = av->next)
3792	if (GET_CODE (av->value) == CONST_STRING)
3793	  {
3794	    exp = attr_eq (dim->attr->name, XSTR (av->value, 0));
3795	    if (MEM_VOLATILE_P (exp))
3796	      continue;
3797
3798	    link = rtx_alloc (EXPR_LIST);
3799	    XEXP (link, 0) = exp;
3800	    XEXP (link, 1) = 0;
3801	    *prev = link;
3802	    prev = &XEXP (link, 1);
3803	  }
3804      dim->num_values = nalt;
3805    }
3806  else
3807    {
3808      rtx orexp = false_rtx;
3809
3810      /* Very few values are used, so compute a mutually exclusive
3811	 expression.  (We could do this for numeric values if that becomes
3812	 important.)  */
3813      prev = &dim->values;
3814      for (link = dim->values; link; link = *prev)
3815	{
3816	  orexp = insert_right_side (IOR, orexp, XEXP (link, 0), -2, -2);
3817	  prev = &XEXP (link, 1);
3818	}
3819      link = rtx_alloc (EXPR_LIST);
3820      XEXP (link, 0) = attr_rtx (NOT, orexp);
3821      XEXP (link, 1) = 0;
3822      *prev = link;
3823      dim->num_values++;
3824    }
3825  return dim->num_values;
3826}
3827
3828/* Increment the current value for the NDIM-dimensional attribute space SPACE
3829   and return FALSE if the increment overflowed.  */
3830
3831static int
3832increment_current_value (space, ndim)
3833     struct dimension *space;
3834     int ndim;
3835{
3836  int i;
3837
3838  for (i = ndim - 1; i >= 0; i--)
3839    {
3840      if ((space[i].current_value = XEXP (space[i].current_value, 1)) == 0)
3841	space[i].current_value = space[i].values;
3842      else
3843	return 1;
3844    }
3845  return 0;
3846}
3847
3848/* Construct an expression corresponding to the current value for the
3849   NDIM-dimensional attribute space SPACE.  */
3850
3851static rtx
3852test_for_current_value (space, ndim)
3853     struct dimension *space;
3854     int ndim;
3855{
3856  int i;
3857  rtx exp = true_rtx;
3858
3859  for (i = 0; i < ndim; i++)
3860    exp = insert_right_side (AND, exp, XEXP (space[i].current_value, 0),
3861			     -2, -2);
3862
3863  return exp;
3864}
3865
3866/* Given the current value of the NDIM-dimensional attribute space SPACE,
3867   set the corresponding EQ_ATTR expressions to that value and reduce
3868   the expression EXP as much as possible.  On input [and output], all
3869   known EQ_ATTR expressions are set to FALSE.  */
3870
3871static rtx
3872simplify_with_current_value (exp, space, ndim)
3873     rtx exp;
3874     struct dimension *space;
3875     int ndim;
3876{
3877  int i;
3878  rtx x;
3879
3880  /* Mark each current value as TRUE.  */
3881  for (i = 0; i < ndim; i++)
3882    {
3883      x = XEXP (space[i].current_value, 0);
3884      if (GET_CODE (x) == EQ_ATTR)
3885	MEM_VOLATILE_P (x) = 0;
3886    }
3887
3888  exp = simplify_with_current_value_aux (exp);
3889
3890  /* Change each current value back to FALSE.  */
3891  for (i = 0; i < ndim; i++)
3892    {
3893      x = XEXP (space[i].current_value, 0);
3894      if (GET_CODE (x) == EQ_ATTR)
3895	MEM_VOLATILE_P (x) = 1;
3896    }
3897
3898  return exp;
3899}
3900
3901/* Reduce the expression EXP based on the MEM_VOLATILE_P settings of
3902   all EQ_ATTR expressions.  */
3903
3904static rtx
3905simplify_with_current_value_aux (exp)
3906     rtx exp;
3907{
3908  register int i;
3909  rtx cond;
3910
3911  switch (GET_CODE (exp))
3912    {
3913    case EQ_ATTR:
3914      if (MEM_VOLATILE_P (exp))
3915	return false_rtx;
3916      else
3917	return true_rtx;
3918    case CONST_STRING:
3919    case CONST_INT:
3920      return exp;
3921
3922    case IF_THEN_ELSE:
3923      cond = simplify_with_current_value_aux (XEXP (exp, 0));
3924      if (cond == true_rtx)
3925	return simplify_with_current_value_aux (XEXP (exp, 1));
3926      else if (cond == false_rtx)
3927	return simplify_with_current_value_aux (XEXP (exp, 2));
3928      else
3929	return attr_rtx (IF_THEN_ELSE, cond,
3930			 simplify_with_current_value_aux (XEXP (exp, 1)),
3931			 simplify_with_current_value_aux (XEXP (exp, 2)));
3932
3933    case IOR:
3934      cond = simplify_with_current_value_aux (XEXP (exp, 1));
3935      if (cond == true_rtx)
3936	return cond;
3937      else if (cond == false_rtx)
3938	return simplify_with_current_value_aux (XEXP (exp, 0));
3939      else
3940	return attr_rtx (IOR, cond,
3941			 simplify_with_current_value_aux (XEXP (exp, 0)));
3942
3943    case AND:
3944      cond = simplify_with_current_value_aux (XEXP (exp, 1));
3945      if (cond == true_rtx)
3946	return simplify_with_current_value_aux (XEXP (exp, 0));
3947      else if (cond == false_rtx)
3948	return cond;
3949      else
3950	return attr_rtx (AND, cond,
3951			 simplify_with_current_value_aux (XEXP (exp, 0)));
3952
3953    case NOT:
3954      cond = simplify_with_current_value_aux (XEXP (exp, 0));
3955      if (cond == true_rtx)
3956	return false_rtx;
3957      else if (cond == false_rtx)
3958	return true_rtx;
3959      else
3960	return attr_rtx (NOT, cond);
3961
3962    case COND:
3963      for (i = 0; i < XVECLEN (exp, 0); i += 2)
3964	{
3965	  cond = simplify_with_current_value_aux (XVECEXP (exp, 0, i));
3966	  if (cond == true_rtx)
3967	    return simplify_with_current_value_aux (XVECEXP (exp, 0, i + 1));
3968	  else if (cond == false_rtx)
3969	    continue;
3970	  else
3971	    abort (); /* With all EQ_ATTR's of known value, a case should
3972			 have been selected.  */
3973	}
3974      return simplify_with_current_value_aux (XEXP (exp, 1));
3975
3976    default:
3977      abort ();
3978    }
3979}
3980
3981/* Clear the MEM_IN_STRUCT_P flag in EXP and its subexpressions.  */
3982
3983static void
3984clear_struct_flag (x)
3985     rtx x;
3986{
3987  register int i;
3988  register int j;
3989  register enum rtx_code code;
3990  register char *fmt;
3991
3992  MEM_IN_STRUCT_P (x) = 0;
3993  if (RTX_UNCHANGING_P (x))
3994    return;
3995
3996  code = GET_CODE (x);
3997
3998  switch (code)
3999    {
4000    case REG:
4001    case QUEUED:
4002    case CONST_INT:
4003    case CONST_DOUBLE:
4004    case SYMBOL_REF:
4005    case CODE_LABEL:
4006    case PC:
4007    case CC0:
4008    case EQ_ATTR:
4009    case ATTR_FLAG:
4010      return;
4011
4012    default:
4013      break;
4014    }
4015
4016  /* Compare the elements.  If any pair of corresponding elements
4017     fail to match, return 0 for the whole things.  */
4018
4019  fmt = GET_RTX_FORMAT (code);
4020  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
4021    {
4022      switch (fmt[i])
4023	{
4024	case 'V':
4025	case 'E':
4026	  for (j = 0; j < XVECLEN (x, i); j++)
4027	    clear_struct_flag (XVECEXP (x, i, j));
4028	  break;
4029
4030	case 'e':
4031	  clear_struct_flag (XEXP (x, i));
4032	  break;
4033	}
4034    }
4035}
4036
4037/* Return the number of RTX objects making up the expression X.
4038   But if we count more than MAX objects, stop counting.  */
4039
4040static int
4041count_sub_rtxs (x, max)
4042     rtx x;
4043     int max;
4044{
4045  register int i;
4046  register int j;
4047  register enum rtx_code code;
4048  register char *fmt;
4049  int total = 0;
4050
4051  code = GET_CODE (x);
4052
4053  switch (code)
4054    {
4055    case REG:
4056    case QUEUED:
4057    case CONST_INT:
4058    case CONST_DOUBLE:
4059    case SYMBOL_REF:
4060    case CODE_LABEL:
4061    case PC:
4062    case CC0:
4063    case EQ_ATTR:
4064    case ATTR_FLAG:
4065      return 1;
4066
4067    default:
4068      break;
4069    }
4070
4071  /* Compare the elements.  If any pair of corresponding elements
4072     fail to match, return 0 for the whole things.  */
4073
4074  fmt = GET_RTX_FORMAT (code);
4075  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
4076    {
4077      if (total >= max)
4078	return total;
4079
4080      switch (fmt[i])
4081	{
4082	case 'V':
4083	case 'E':
4084	  for (j = 0; j < XVECLEN (x, i); j++)
4085	    total += count_sub_rtxs (XVECEXP (x, i, j), max);
4086	  break;
4087
4088	case 'e':
4089	  total += count_sub_rtxs (XEXP (x, i), max);
4090	  break;
4091	}
4092    }
4093  return total;
4094
4095}
4096
4097/* Create table entries for DEFINE_ATTR.  */
4098
4099static void
4100gen_attr (exp)
4101     rtx exp;
4102{
4103  struct attr_desc *attr;
4104  struct attr_value *av;
4105  char *name_ptr;
4106  char *p;
4107
4108  /* Make a new attribute structure.  Check for duplicate by looking at
4109     attr->default_val, since it is initialized by this routine.  */
4110  attr = find_attr (XSTR (exp, 0), 1);
4111  if (attr->default_val)
4112    fatal ("Duplicate definition for `%s' attribute", attr->name);
4113
4114  if (*XSTR (exp, 1) == '\0')
4115      attr->is_numeric = 1;
4116  else
4117    {
4118      name_ptr = XSTR (exp, 1);
4119      while ((p = next_comma_elt (&name_ptr)) != NULL)
4120	{
4121	  av = (struct attr_value *) oballoc (sizeof (struct attr_value));
4122	  av->value = attr_rtx (CONST_STRING, p);
4123	  av->next = attr->first_value;
4124	  attr->first_value = av;
4125	  av->first_insn = NULL;
4126	  av->num_insns = 0;
4127	  av->has_asm_insn = 0;
4128	}
4129    }
4130
4131  if (GET_CODE (XEXP (exp, 2)) == CONST)
4132    {
4133      attr->is_const = 1;
4134      if (attr->is_numeric)
4135	fatal ("Constant attributes may not take numeric values");
4136      /* Get rid of the CONST node.  It is allowed only at top-level.  */
4137      XEXP (exp, 2) = XEXP (XEXP (exp, 2), 0);
4138    }
4139
4140  if (! strcmp (attr->name, "length") && ! attr->is_numeric)
4141    fatal ("`length' attribute must take numeric values");
4142
4143  /* Set up the default value.  */
4144  XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr);
4145  attr->default_val = get_attr_value (XEXP (exp, 2), attr, -2);
4146}
4147
4148/* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of
4149   alternatives in the constraints.  Assume all MATCH_OPERANDs have the same
4150   number of alternatives as this should be checked elsewhere.  */
4151
4152static int
4153count_alternatives (exp)
4154     rtx exp;
4155{
4156  int i, j, n;
4157  char *fmt;
4158
4159  if (GET_CODE (exp) == MATCH_OPERAND)
4160    return n_comma_elts (XSTR (exp, 2));
4161
4162  for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
4163       i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
4164    switch (*fmt++)
4165      {
4166      case 'e':
4167      case 'u':
4168	n = count_alternatives (XEXP (exp, i));
4169	if (n)
4170	  return n;
4171	break;
4172
4173      case 'E':
4174      case 'V':
4175	if (XVEC (exp, i) != NULL)
4176	  for (j = 0; j < XVECLEN (exp, i); j++)
4177	    {
4178	      n = count_alternatives (XVECEXP (exp, i, j));
4179	      if (n)
4180		return n;
4181	    }
4182      }
4183
4184  return 0;
4185}
4186
4187/* Returns non-zero if the given expression contains an EQ_ATTR with the
4188   `alternative' attribute.  */
4189
4190static int
4191compares_alternatives_p (exp)
4192     rtx exp;
4193{
4194  int i, j;
4195  char *fmt;
4196
4197  if (GET_CODE (exp) == EQ_ATTR && XSTR (exp, 0) == alternative_name)
4198    return 1;
4199
4200  for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
4201       i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
4202    switch (*fmt++)
4203      {
4204      case 'e':
4205      case 'u':
4206	if (compares_alternatives_p (XEXP (exp, i)))
4207	  return 1;
4208	break;
4209
4210      case 'E':
4211	for (j = 0; j < XVECLEN (exp, i); j++)
4212	  if (compares_alternatives_p (XVECEXP (exp, i, j)))
4213	    return 1;
4214	break;
4215      }
4216
4217  return 0;
4218}
4219
4220/* Returns non-zero is INNER is contained in EXP.  */
4221
4222static int
4223contained_in_p (inner, exp)
4224     rtx inner;
4225     rtx exp;
4226{
4227  int i, j;
4228  char *fmt;
4229
4230  if (rtx_equal_p (inner, exp))
4231    return 1;
4232
4233  for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
4234       i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
4235    switch (*fmt++)
4236      {
4237      case 'e':
4238      case 'u':
4239	if (contained_in_p (inner, XEXP (exp, i)))
4240	  return 1;
4241	break;
4242
4243      case 'E':
4244	for (j = 0; j < XVECLEN (exp, i); j++)
4245	  if (contained_in_p (inner, XVECEXP (exp, i, j)))
4246	    return 1;
4247	break;
4248      }
4249
4250  return 0;
4251}
4252
4253/* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES.  */
4254
4255static void
4256gen_insn (exp)
4257     rtx exp;
4258{
4259  struct insn_def *id;
4260
4261  id = (struct insn_def *) oballoc (sizeof (struct insn_def));
4262  id->next = defs;
4263  defs = id;
4264  id->def = exp;
4265
4266  switch (GET_CODE (exp))
4267    {
4268    case DEFINE_INSN:
4269      id->insn_code = insn_code_number++;
4270      id->insn_index = insn_index_number++;
4271      id->num_alternatives = count_alternatives (exp);
4272      if (id->num_alternatives == 0)
4273	id->num_alternatives = 1;
4274      id->vec_idx = 4;
4275      break;
4276
4277    case DEFINE_PEEPHOLE:
4278      id->insn_code = insn_code_number++;
4279      id->insn_index = insn_index_number++;
4280      id->num_alternatives = count_alternatives (exp);
4281      if (id->num_alternatives == 0)
4282	id->num_alternatives = 1;
4283      id->vec_idx = 3;
4284      break;
4285
4286    case DEFINE_ASM_ATTRIBUTES:
4287      id->insn_code = -1;
4288      id->insn_index = -1;
4289      id->num_alternatives = 1;
4290      id->vec_idx = 0;
4291      got_define_asm_attributes = 1;
4292      break;
4293
4294    default:
4295      abort ();
4296    }
4297}
4298
4299/* Process a DEFINE_DELAY.  Validate the vector length, check if annul
4300   true or annul false is specified, and make a `struct delay_desc'.  */
4301
4302static void
4303gen_delay (def)
4304     rtx def;
4305{
4306  struct delay_desc *delay;
4307  int i;
4308
4309  if (XVECLEN (def, 1) % 3 != 0)
4310    fatal ("Number of elements in DEFINE_DELAY must be multiple of three.");
4311
4312  for (i = 0; i < XVECLEN (def, 1); i += 3)
4313    {
4314      if (XVECEXP (def, 1, i + 1))
4315	have_annul_true = 1;
4316      if (XVECEXP (def, 1, i + 2))
4317	have_annul_false = 1;
4318    }
4319
4320  delay = (struct delay_desc *) oballoc (sizeof (struct delay_desc));
4321  delay->def = def;
4322  delay->num = ++num_delays;
4323  delay->next = delays;
4324  delays = delay;
4325}
4326
4327/* Process a DEFINE_FUNCTION_UNIT.
4328
4329   This gives information about a function unit contained in the CPU.
4330   We fill in a `struct function_unit_op' and a `struct function_unit'
4331   with information used later by `expand_unit'.  */
4332
4333static void
4334gen_unit (def)
4335     rtx def;
4336{
4337  struct function_unit *unit;
4338  struct function_unit_op *op;
4339  char *name = XSTR (def, 0);
4340  int multiplicity = XINT (def, 1);
4341  int simultaneity = XINT (def, 2);
4342  rtx condexp = XEXP (def, 3);
4343  int ready_cost = MAX (XINT (def, 4), 1);
4344  int issue_delay = MAX (XINT (def, 5), 1);
4345
4346  /* See if we have already seen this function unit.  If so, check that
4347     the multiplicity and simultaneity values are the same.  If not, make
4348     a structure for this function unit.  */
4349  for (unit = units; unit; unit = unit->next)
4350    if (! strcmp (unit->name, name))
4351      {
4352	if (unit->multiplicity != multiplicity
4353	    || unit->simultaneity != simultaneity)
4354	  fatal ("Differing specifications given for `%s' function unit.",
4355		 unit->name);
4356	break;
4357      }
4358
4359  if (unit == 0)
4360    {
4361      unit = (struct function_unit *) oballoc (sizeof (struct function_unit));
4362      unit->name = name;
4363      unit->multiplicity = multiplicity;
4364      unit->simultaneity = simultaneity;
4365      unit->issue_delay.min = unit->issue_delay.max = issue_delay;
4366      unit->num = num_units++;
4367      unit->num_opclasses = 0;
4368      unit->condexp = false_rtx;
4369      unit->ops = 0;
4370      unit->next = units;
4371      units = unit;
4372    }
4373
4374  /* Make a new operation class structure entry and initialize it.  */
4375  op = (struct function_unit_op *) oballoc (sizeof (struct function_unit_op));
4376  op->condexp = condexp;
4377  op->num = unit->num_opclasses++;
4378  op->ready = ready_cost;
4379  op->issue_delay = issue_delay;
4380  op->next = unit->ops;
4381  unit->ops = op;
4382  num_unit_opclasses++;
4383
4384  /* Set our issue expression based on whether or not an optional conflict
4385     vector was specified.  */
4386  if (XVEC (def, 6))
4387    {
4388      /* Compute the IOR of all the specified expressions.  */
4389      rtx orexp = false_rtx;
4390      int i;
4391
4392      for (i = 0; i < XVECLEN (def, 6); i++)
4393	orexp = insert_right_side (IOR, orexp, XVECEXP (def, 6, i), -2, -2);
4394
4395      op->conflict_exp = orexp;
4396      extend_range (&unit->issue_delay, 1, issue_delay);
4397    }
4398  else
4399    {
4400      op->conflict_exp = true_rtx;
4401      extend_range (&unit->issue_delay, issue_delay, issue_delay);
4402    }
4403
4404  /* Merge our conditional into that of the function unit so we can determine
4405     which insns are used by the function unit.  */
4406  unit->condexp = insert_right_side (IOR, unit->condexp, op->condexp, -2, -2);
4407}
4408
4409/* Given a piece of RTX, print a C expression to test its truth value.
4410   We use AND and IOR both for logical and bit-wise operations, so
4411   interpret them as logical unless they are inside a comparison expression.
4412   The first bit of FLAGS will be non-zero in that case.
4413
4414   Set the second bit of FLAGS to make references to attribute values use
4415   a cached local variable instead of calling a function.  */
4416
4417static void
4418write_test_expr (exp, flags)
4419     rtx exp;
4420     int flags;
4421{
4422  int comparison_operator = 0;
4423  RTX_CODE code;
4424  struct attr_desc *attr;
4425
4426  /* In order not to worry about operator precedence, surround our part of
4427     the expression with parentheses.  */
4428
4429  printf ("(");
4430  code = GET_CODE (exp);
4431  switch (code)
4432    {
4433    /* Binary operators.  */
4434    case EQ: case NE:
4435    case GE: case GT: case GEU: case GTU:
4436    case LE: case LT: case LEU: case LTU:
4437      comparison_operator = 1;
4438
4439    case PLUS:   case MINUS:  case MULT:     case DIV:      case MOD:
4440    case AND:    case IOR:    case XOR:
4441    case ASHIFT: case LSHIFTRT: case ASHIFTRT:
4442      write_test_expr (XEXP (exp, 0), flags | comparison_operator);
4443      switch (code)
4444        {
4445	case EQ:
4446	  printf (" == ");
4447	  break;
4448	case NE:
4449	  printf (" != ");
4450	  break;
4451	case GE:
4452	  printf (" >= ");
4453	  break;
4454	case GT:
4455	  printf (" > ");
4456	  break;
4457	case GEU:
4458	  printf (" >= (unsigned) ");
4459	  break;
4460	case GTU:
4461	  printf (" > (unsigned) ");
4462	  break;
4463	case LE:
4464	  printf (" <= ");
4465	  break;
4466	case LT:
4467	  printf (" < ");
4468	  break;
4469	case LEU:
4470	  printf (" <= (unsigned) ");
4471	  break;
4472	case LTU:
4473	  printf (" < (unsigned) ");
4474	  break;
4475	case PLUS:
4476	  printf (" + ");
4477	  break;
4478	case MINUS:
4479	  printf (" - ");
4480	  break;
4481	case MULT:
4482	  printf (" * ");
4483	  break;
4484	case DIV:
4485	  printf (" / ");
4486	  break;
4487	case MOD:
4488	  printf (" %% ");
4489	  break;
4490	case AND:
4491	  if (flags & 1)
4492	    printf (" & ");
4493	  else
4494	    printf (" && ");
4495	  break;
4496	case IOR:
4497	  if (flags & 1)
4498	    printf (" | ");
4499	  else
4500	    printf (" || ");
4501	  break;
4502	case XOR:
4503	  printf (" ^ ");
4504	  break;
4505	case ASHIFT:
4506	  printf (" << ");
4507	  break;
4508	case LSHIFTRT:
4509	case ASHIFTRT:
4510	  printf (" >> ");
4511	  break;
4512	default:
4513	  abort ();
4514        }
4515
4516      write_test_expr (XEXP (exp, 1), flags | comparison_operator);
4517      break;
4518
4519    case NOT:
4520      /* Special-case (not (eq_attrq "alternative" "x")) */
4521      if (! (flags & 1) && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
4522	  && XSTR (XEXP (exp, 0), 0) == alternative_name)
4523	{
4524	  printf ("which_alternative != %s", XSTR (XEXP (exp, 0), 1));
4525	  break;
4526	}
4527
4528      /* Otherwise, fall through to normal unary operator.  */
4529
4530    /* Unary operators.  */
4531    case ABS:  case NEG:
4532      switch (code)
4533	{
4534	case NOT:
4535	  if (flags & 1)
4536	    printf ("~ ");
4537	  else
4538	    printf ("! ");
4539	  break;
4540	case ABS:
4541	  printf ("abs ");
4542	  break;
4543	case NEG:
4544	  printf ("-");
4545	  break;
4546	default:
4547	  abort ();
4548	}
4549
4550      write_test_expr (XEXP (exp, 0), flags);
4551      break;
4552
4553    /* Comparison test of an attribute with a value.  Most of these will
4554       have been removed by optimization.   Handle "alternative"
4555       specially and give error if EQ_ATTR present inside a comparison.  */
4556    case EQ_ATTR:
4557      if (flags & 1)
4558	fatal ("EQ_ATTR not valid inside comparison");
4559
4560      if (XSTR (exp, 0) == alternative_name)
4561	{
4562	  printf ("which_alternative == %s", XSTR (exp, 1));
4563	  break;
4564	}
4565
4566      attr = find_attr (XSTR (exp, 0), 0);
4567      if (! attr) abort ();
4568
4569      /* Now is the time to expand the value of a constant attribute.  */
4570      if (attr->is_const)
4571	{
4572	  write_test_expr (evaluate_eq_attr (exp, attr->default_val->value,
4573					     -2, -2),
4574			   flags);
4575	}
4576      else
4577	{
4578	  if (flags & 2)
4579	    printf ("attr_%s", attr->name);
4580	  else
4581	    printf ("get_attr_%s (insn)", attr->name);
4582	  printf (" == ");
4583	  write_attr_valueq (attr, XSTR (exp, 1));
4584	}
4585      break;
4586
4587    /* Comparison test of flags for define_delays.  */
4588    case ATTR_FLAG:
4589      if (flags & 1)
4590	fatal ("ATTR_FLAG not valid inside comparison");
4591      printf ("(flags & ATTR_FLAG_%s) != 0", XSTR (exp, 0));
4592      break;
4593
4594    /* See if an operand matches a predicate.  */
4595    case MATCH_OPERAND:
4596      /* If only a mode is given, just ensure the mode matches the operand.
4597	 If neither a mode nor predicate is given, error.  */
4598     if (XSTR (exp, 1) == NULL || *XSTR (exp, 1) == '\0')
4599	{
4600	  if (GET_MODE (exp) == VOIDmode)
4601	    fatal ("Null MATCH_OPERAND specified as test");
4602	  else
4603	    printf ("GET_MODE (operands[%d]) == %smode",
4604		    XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
4605	}
4606      else
4607	printf ("%s (operands[%d], %smode)",
4608		XSTR (exp, 1), XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
4609      break;
4610
4611    case MATCH_INSN:
4612      printf ("%s (insn)", XSTR (exp, 0));
4613      break;
4614
4615    /* Constant integer.  */
4616    case CONST_INT:
4617      printf (HOST_WIDE_INT_PRINT_DEC, XWINT (exp, 0));
4618      break;
4619
4620    /* A random C expression.  */
4621    case SYMBOL_REF:
4622      printf ("%s", XSTR (exp, 0));
4623      break;
4624
4625    /* The address of the branch target.  */
4626    case MATCH_DUP:
4627      printf ("insn_addresses[INSN_UID (GET_CODE (operands[%d]) == LABEL_REF ? XEXP (operands[%d], 0) : operands[%d])]",
4628	      XINT (exp, 0), XINT (exp, 0), XINT (exp, 0));
4629      break;
4630
4631    case PC:
4632      /* The address of the current insn.  We implement this actually as the
4633	 address of the current insn for backward branches, but the last
4634	 address of the next insn for forward branches, and both with
4635	 adjustments that account for the worst-case possible stretching of
4636	 intervening alignments between this insn and its destination.  */
4637      printf("insn_current_reference_address (insn)");
4638      break;
4639
4640    case CONST_STRING:
4641      printf ("%s", XSTR (exp, 0));
4642      break;
4643
4644    case IF_THEN_ELSE:
4645      write_test_expr (XEXP (exp, 0), flags & 2);
4646      printf (" ? ");
4647      write_test_expr (XEXP (exp, 1), flags | 1);
4648      printf (" : ");
4649      write_test_expr (XEXP (exp, 2), flags | 1);
4650      break;
4651
4652    default:
4653      fatal ("bad RTX code `%s' in attribute calculation\n",
4654	     GET_RTX_NAME (code));
4655    }
4656
4657  printf (")");
4658}
4659
4660/* Given an attribute value, return the maximum CONST_STRING argument
4661   encountered.  It is assumed that they are all numeric.  */
4662
4663static int
4664max_attr_value (exp)
4665     rtx exp;
4666{
4667  int current_max = 0;
4668  int n;
4669  int i;
4670
4671  if (GET_CODE (exp) == CONST_STRING)
4672    return atoi (XSTR (exp, 0));
4673
4674  else if (GET_CODE (exp) == COND)
4675    {
4676      for (i = 0; i < XVECLEN (exp, 0); i += 2)
4677	{
4678	  n = max_attr_value (XVECEXP (exp, 0, i + 1));
4679	  if (n > current_max)
4680	    current_max = n;
4681	}
4682
4683      n = max_attr_value (XEXP (exp, 1));
4684      if (n > current_max)
4685	current_max = n;
4686    }
4687
4688  else if (GET_CODE (exp) == IF_THEN_ELSE)
4689    {
4690      current_max = max_attr_value (XEXP (exp, 1));
4691      n = max_attr_value (XEXP (exp, 2));
4692      if (n > current_max)
4693	current_max = n;
4694    }
4695
4696  else
4697    abort ();
4698
4699  return current_max;
4700}
4701
4702/* Given an attribute value, return the result of ORing together all
4703   CONST_STRING arguments encountered.  It is assumed that they are
4704   all numeric.  */
4705
4706static int
4707or_attr_value (exp)
4708     rtx exp;
4709{
4710  int current_or = 0;
4711  int i;
4712
4713  if (GET_CODE (exp) == CONST_STRING)
4714    return atoi (XSTR (exp, 0));
4715
4716  else if (GET_CODE (exp) == COND)
4717    {
4718      for (i = 0; i < XVECLEN (exp, 0); i += 2)
4719	{
4720	  current_or |= or_attr_value (XVECEXP (exp, 0, i + 1));
4721	}
4722
4723      current_or |= or_attr_value (XEXP (exp, 1));
4724    }
4725
4726  else if (GET_CODE (exp) == IF_THEN_ELSE)
4727    {
4728      current_or = or_attr_value (XEXP (exp, 1));
4729      current_or |= or_attr_value (XEXP (exp, 2));
4730    }
4731
4732  else
4733    abort ();
4734
4735  return current_or;
4736}
4737
4738/* Scan an attribute value, possibly a conditional, and record what actions
4739   will be required to do any conditional tests in it.
4740
4741   Specifically, set
4742	`must_extract'	  if we need to extract the insn operands
4743	`must_constrain'  if we must compute `which_alternative'
4744	`address_used'	  if an address expression was used
4745	`length_used'	  if an (eq_attr "length" ...) was used
4746 */
4747
4748static void
4749walk_attr_value (exp)
4750     rtx exp;
4751{
4752  register int i, j;
4753  register char *fmt;
4754  RTX_CODE code;
4755
4756  if (exp == NULL)
4757    return;
4758
4759  code = GET_CODE (exp);
4760  switch (code)
4761    {
4762    case SYMBOL_REF:
4763      if (! RTX_UNCHANGING_P (exp))
4764	/* Since this is an arbitrary expression, it can look at anything.
4765	   However, constant expressions do not depend on any particular
4766	   insn.  */
4767	must_extract = must_constrain = 1;
4768      return;
4769
4770    case MATCH_OPERAND:
4771      must_extract = 1;
4772      return;
4773
4774    case EQ_ATTR:
4775      if (XSTR (exp, 0) == alternative_name)
4776	must_extract = must_constrain = 1;
4777      else if (strcmp (XSTR (exp, 0), "length") == 0)
4778	length_used = 1;
4779      return;
4780
4781    case MATCH_DUP:
4782      must_extract = 1;
4783      address_used = 1;
4784      return;
4785
4786    case PC:
4787      address_used = 1;
4788      return;
4789
4790    case ATTR_FLAG:
4791      return;
4792
4793    default:
4794      break;
4795    }
4796
4797  for (i = 0, fmt = GET_RTX_FORMAT (code); i < GET_RTX_LENGTH (code); i++)
4798    switch (*fmt++)
4799      {
4800      case 'e':
4801      case 'u':
4802	walk_attr_value (XEXP (exp, i));
4803	break;
4804
4805      case 'E':
4806	if (XVEC (exp, i) != NULL)
4807	  for (j = 0; j < XVECLEN (exp, i); j++)
4808	    walk_attr_value (XVECEXP (exp, i, j));
4809	break;
4810      }
4811}
4812
4813/* Write out a function to obtain the attribute for a given INSN.  */
4814
4815static void
4816write_attr_get (attr)
4817     struct attr_desc *attr;
4818{
4819  struct attr_value *av, *common_av;
4820
4821  /* Find the most used attribute value.  Handle that as the `default' of the
4822     switch we will generate.  */
4823  common_av = find_most_used (attr);
4824
4825  /* Write out start of function, then all values with explicit `case' lines,
4826     then a `default', then the value with the most uses.  */
4827  if (!attr->is_numeric)
4828    printf ("enum attr_%s\n", attr->name);
4829  else if (attr->unsigned_p)
4830    printf ("unsigned int\n");
4831  else
4832    printf ("int\n");
4833
4834  /* If the attribute name starts with a star, the remainder is the name of
4835     the subroutine to use, instead of `get_attr_...'.  */
4836  if (attr->name[0] == '*')
4837    printf ("%s (insn)\n", &attr->name[1]);
4838  else if (attr->is_const == 0)
4839    printf ("get_attr_%s (insn)\n", attr->name);
4840  else
4841    {
4842      printf ("get_attr_%s ()\n", attr->name);
4843      printf ("{\n");
4844
4845      for (av = attr->first_value; av; av = av->next)
4846	if (av->num_insns != 0)
4847	  write_attr_set (attr, 2, av->value, "return", ";",
4848			  true_rtx, av->first_insn->insn_code,
4849			  av->first_insn->insn_index);
4850
4851      printf ("}\n\n");
4852      return;
4853    }
4854
4855  printf ("     rtx insn;\n");
4856  printf ("{\n");
4857
4858  if (GET_CODE (common_av->value) == FFS)
4859    {
4860      rtx p = XEXP (common_av->value, 0);
4861
4862      /* No need to emit code to abort if the insn is unrecognized; the
4863         other get_attr_foo functions will do that when we call them.  */
4864
4865      write_toplevel_expr (p);
4866
4867      printf ("\n  if (accum && accum == (accum & -accum))\n");
4868      printf ("    {\n");
4869      printf ("      int i;\n");
4870      printf ("      for (i = 0; accum >>= 1; ++i) continue;\n");
4871      printf ("      accum = i;\n");
4872      printf ("    }\n  else\n");
4873      printf ("    accum = ~accum;\n");
4874      printf ("  return accum;\n}\n\n");
4875    }
4876  else
4877    {
4878      printf ("  switch (recog_memoized (insn))\n");
4879      printf ("    {\n");
4880
4881      for (av = attr->first_value; av; av = av->next)
4882	if (av != common_av)
4883	  write_attr_case (attr, av, 1, "return", ";", 4, true_rtx);
4884
4885      write_attr_case (attr, common_av, 0, "return", ";", 4, true_rtx);
4886      printf ("    }\n}\n\n");
4887    }
4888}
4889
4890/* Given an AND tree of known true terms (because we are inside an `if' with
4891   that as the condition or are in an `else' clause) and an expression,
4892   replace any known true terms with TRUE.  Use `simplify_and_tree' to do
4893   the bulk of the work.  */
4894
4895static rtx
4896eliminate_known_true (known_true, exp, insn_code, insn_index)
4897     rtx known_true;
4898     rtx exp;
4899     int insn_code, insn_index;
4900{
4901  rtx term;
4902
4903  known_true = SIMPLIFY_TEST_EXP (known_true, insn_code, insn_index);
4904
4905  if (GET_CODE (known_true) == AND)
4906    {
4907      exp = eliminate_known_true (XEXP (known_true, 0), exp,
4908				  insn_code, insn_index);
4909      exp = eliminate_known_true (XEXP (known_true, 1), exp,
4910				  insn_code, insn_index);
4911    }
4912  else
4913    {
4914      term = known_true;
4915      exp = simplify_and_tree (exp, &term, insn_code, insn_index);
4916    }
4917
4918  return exp;
4919}
4920
4921/* Write out a series of tests and assignment statements to perform tests and
4922   sets of an attribute value.  We are passed an indentation amount and prefix
4923   and suffix strings to write around each attribute value (e.g., "return"
4924   and ";").  */
4925
4926static void
4927write_attr_set (attr, indent, value, prefix, suffix, known_true,
4928		insn_code, insn_index)
4929     struct attr_desc *attr;
4930     int indent;
4931     rtx value;
4932     char *prefix;
4933     char *suffix;
4934     rtx known_true;
4935     int insn_code, insn_index;
4936{
4937  if (GET_CODE (value) == CONST_STRING)
4938    {
4939      write_indent (indent);
4940      printf ("%s ", prefix);
4941      write_attr_value (attr, value);
4942      printf ("%s\n", suffix);
4943    }
4944  else if (GET_CODE (value) == COND)
4945    {
4946      /* Assume the default value will be the default of the COND unless we
4947	 find an always true expression.  */
4948      rtx default_val = XEXP (value, 1);
4949      rtx our_known_true = known_true;
4950      rtx newexp;
4951      int first_if = 1;
4952      int i;
4953
4954      for (i = 0; i < XVECLEN (value, 0); i += 2)
4955	{
4956	  rtx testexp;
4957	  rtx inner_true;
4958
4959	  testexp = eliminate_known_true (our_known_true,
4960					  XVECEXP (value, 0, i),
4961					  insn_code, insn_index);
4962	  newexp = attr_rtx (NOT, testexp);
4963	  newexp  = insert_right_side (AND, our_known_true, newexp,
4964				       insn_code, insn_index);
4965
4966	  /* If the test expression is always true or if the next `known_true'
4967	     expression is always false, this is the last case, so break
4968	     out and let this value be the `else' case.  */
4969	  if (testexp == true_rtx || newexp == false_rtx)
4970	    {
4971	      default_val = XVECEXP (value, 0, i + 1);
4972	      break;
4973	    }
4974
4975	  /* Compute the expression to pass to our recursive call as being
4976	     known true.  */
4977	  inner_true = insert_right_side (AND, our_known_true,
4978					  testexp, insn_code, insn_index);
4979
4980	  /* If this is always false, skip it.  */
4981	  if (inner_true == false_rtx)
4982	    continue;
4983
4984	  write_indent (indent);
4985	  printf ("%sif ", first_if ? "" : "else ");
4986	  first_if = 0;
4987	  write_test_expr (testexp, 0);
4988	  printf ("\n");
4989	  write_indent (indent + 2);
4990	  printf ("{\n");
4991
4992	  write_attr_set (attr, indent + 4,
4993			  XVECEXP (value, 0, i + 1), prefix, suffix,
4994			  inner_true, insn_code, insn_index);
4995	  write_indent (indent + 2);
4996	  printf ("}\n");
4997	  our_known_true = newexp;
4998	}
4999
5000      if (! first_if)
5001	{
5002	  write_indent (indent);
5003	  printf ("else\n");
5004	  write_indent (indent + 2);
5005	  printf ("{\n");
5006	}
5007
5008      write_attr_set (attr, first_if ? indent : indent + 4, default_val,
5009		      prefix, suffix, our_known_true, insn_code, insn_index);
5010
5011      if (! first_if)
5012	{
5013	  write_indent (indent + 2);
5014	  printf ("}\n");
5015	}
5016    }
5017  else
5018    abort ();
5019}
5020
5021/* Write out the computation for one attribute value.  */
5022
5023static void
5024write_attr_case (attr, av, write_case_lines, prefix, suffix, indent,
5025		 known_true)
5026     struct attr_desc *attr;
5027     struct attr_value *av;
5028     int write_case_lines;
5029     char *prefix, *suffix;
5030     int indent;
5031     rtx known_true;
5032{
5033  struct insn_ent *ie;
5034
5035  if (av->num_insns == 0)
5036    return;
5037
5038  if (av->has_asm_insn)
5039    {
5040      write_indent (indent);
5041      printf ("case -1:\n");
5042      write_indent (indent + 2);
5043      printf ("if (GET_CODE (PATTERN (insn)) != ASM_INPUT\n");
5044      write_indent (indent + 2);
5045      printf ("    && asm_noperands (PATTERN (insn)) < 0)\n");
5046      write_indent (indent + 2);
5047      printf ("  fatal_insn_not_found (insn);\n");
5048    }
5049
5050  if (write_case_lines)
5051    {
5052      for (ie = av->first_insn; ie; ie = ie->next)
5053	if (ie->insn_code != -1)
5054	  {
5055	    write_indent (indent);
5056	    printf ("case %d:\n", ie->insn_code);
5057	  }
5058    }
5059  else
5060    {
5061      write_indent (indent);
5062      printf ("default:\n");
5063    }
5064
5065  /* See what we have to do to output this value.  */
5066  must_extract = must_constrain = address_used = 0;
5067  walk_attr_value (av->value);
5068
5069  if (must_extract)
5070    {
5071      write_indent (indent + 2);
5072      printf ("insn_extract (insn);\n");
5073    }
5074
5075  if (must_constrain)
5076    {
5077#ifdef REGISTER_CONSTRAINTS
5078      write_indent (indent + 2);
5079      printf ("if (! constrain_operands (INSN_CODE (insn), reload_completed))\n");
5080      write_indent (indent + 2);
5081      printf ("  fatal_insn_not_found (insn);\n");
5082#endif
5083    }
5084
5085  write_attr_set (attr, indent + 2, av->value, prefix, suffix,
5086		  known_true, av->first_insn->insn_code,
5087		  av->first_insn->insn_index);
5088
5089  if (strncmp (prefix, "return", 6))
5090    {
5091      write_indent (indent + 2);
5092      printf ("break;\n");
5093    }
5094  printf ("\n");
5095}
5096
5097/* Search for uses of non-const attributes and write code to cache them.  */
5098
5099static int
5100write_expr_attr_cache (p, attr)
5101     rtx p;
5102     struct attr_desc *attr;
5103{
5104  char *fmt;
5105  int i, ie, j, je;
5106
5107  if (GET_CODE (p) == EQ_ATTR)
5108    {
5109      if (XSTR (p, 0) != attr->name)
5110	return 0;
5111
5112      if (!attr->is_numeric)
5113	printf ("  register enum attr_%s ", attr->name);
5114      else if (attr->unsigned_p)
5115	printf ("  register unsigned int ");
5116      else
5117	printf ("  register int ");
5118
5119      printf ("attr_%s = get_attr_%s (insn);\n", attr->name, attr->name);
5120      return 1;
5121    }
5122
5123  fmt = GET_RTX_FORMAT (GET_CODE (p));
5124  ie = GET_RTX_LENGTH (GET_CODE (p));
5125  for (i = 0; i < ie; i++)
5126    {
5127      switch (*fmt++)
5128	{
5129	case 'e':
5130	  if (write_expr_attr_cache (XEXP (p, i), attr))
5131	    return 1;
5132	  break;
5133
5134	case 'E':
5135	  je = XVECLEN (p, i);
5136	  for (j = 0; j < je; ++j)
5137	    if (write_expr_attr_cache (XVECEXP (p, i, j), attr))
5138	      return 1;
5139	  break;
5140	}
5141    }
5142
5143  return 0;
5144}
5145
5146/* Evaluate an expression at top level.  A front end to write_test_expr,
5147   in which we cache attribute values and break up excessively large
5148   expressions to cater to older compilers.  */
5149
5150static void
5151write_toplevel_expr (p)
5152     rtx p;
5153{
5154  struct attr_desc *attr;
5155  int i;
5156
5157  for (i = 0; i < MAX_ATTRS_INDEX; ++i)
5158    for (attr = attrs[i]; attr ; attr = attr->next)
5159      if (!attr->is_const)
5160	write_expr_attr_cache (p, attr);
5161
5162  printf("  register unsigned long accum = 0;\n\n");
5163
5164  while (GET_CODE (p) == IOR)
5165    {
5166      rtx e;
5167      if (GET_CODE (XEXP (p, 0)) == IOR)
5168	e = XEXP (p, 1), p = XEXP (p, 0);
5169      else
5170	e = XEXP (p, 0), p = XEXP (p, 1);
5171
5172      printf ("  accum |= ");
5173      write_test_expr (e, 3);
5174      printf (";\n");
5175    }
5176  printf ("  accum |= ");
5177  write_test_expr (p, 3);
5178  printf (";\n");
5179}
5180
5181/* Utilities to write names in various forms.  */
5182
5183static void
5184write_unit_name (prefix, num, suffix)
5185     char *prefix;
5186     int num;
5187     char *suffix;
5188{
5189  struct function_unit *unit;
5190
5191  for (unit = units; unit; unit = unit->next)
5192    if (unit->num == num)
5193      {
5194	printf ("%s%s%s", prefix, unit->name, suffix);
5195	return;
5196      }
5197
5198  printf ("%s<unknown>%s", prefix, suffix);
5199}
5200
5201static void
5202write_attr_valueq (attr, s)
5203     struct attr_desc *attr;
5204     char *s;
5205{
5206  if (attr->is_numeric)
5207    {
5208      int num = atoi (s);
5209
5210      printf ("%d", num);
5211
5212      /* Make the blockage range values and function units used values easier
5213         to read.  */
5214      if (attr->func_units_p)
5215	{
5216	  if (num == -1)
5217	    printf (" /* units: none */");
5218	  else if (num >= 0)
5219	    write_unit_name (" /* units: ", num, " */");
5220	  else
5221	    {
5222	      int i;
5223	      char *sep = " /* units: ";
5224	      for (i = 0, num = ~num; num; i++, num >>= 1)
5225		if (num & 1)
5226		  {
5227		    write_unit_name (sep, i, (num == 1) ? " */" : "");
5228		    sep = ", ";
5229		  }
5230	    }
5231	}
5232
5233      else if (attr->blockage_p)
5234	printf (" /* min %d, max %d */", num >> (HOST_BITS_PER_INT / 2),
5235		num & ((1 << (HOST_BITS_PER_INT / 2)) - 1));
5236
5237      else if (num > 9 || num < 0)
5238	printf (" /* 0x%x */", num);
5239    }
5240  else
5241    {
5242      write_upcase (attr->name);
5243      printf ("_");
5244      write_upcase (s);
5245    }
5246}
5247
5248static void
5249write_attr_value (attr, value)
5250     struct attr_desc *attr;
5251     rtx value;
5252{
5253  if (GET_CODE (value) != CONST_STRING)
5254    abort ();
5255
5256  write_attr_valueq (attr, XSTR (value, 0));
5257}
5258
5259static void
5260write_upcase (str)
5261     char *str;
5262{
5263  while (*str)
5264    if (*str < 'a' || *str > 'z')
5265      printf ("%c", *str++);
5266    else
5267      printf ("%c", *str++ - 'a' + 'A');
5268}
5269
5270static void
5271write_indent (indent)
5272     int indent;
5273{
5274  for (; indent > 8; indent -= 8)
5275    printf ("\t");
5276
5277  for (; indent; indent--)
5278    printf (" ");
5279}
5280
5281/* Write a subroutine that is given an insn that requires a delay slot, a
5282   delay slot ordinal, and a candidate insn.  It returns non-zero if the
5283   candidate can be placed in the specified delay slot of the insn.
5284
5285   We can write as many as three subroutines.  `eligible_for_delay'
5286   handles normal delay slots, `eligible_for_annul_true' indicates that
5287   the specified insn can be annulled if the branch is true, and likewise
5288   for `eligible_for_annul_false'.
5289
5290   KIND is a string distinguishing these three cases ("delay", "annul_true",
5291   or "annul_false").  */
5292
5293static void
5294write_eligible_delay (kind)
5295     char *kind;
5296{
5297  struct delay_desc *delay;
5298  int max_slots;
5299  char str[50];
5300  struct attr_desc *attr;
5301  struct attr_value *av, *common_av;
5302  int i;
5303
5304  /* Compute the maximum number of delay slots required.  We use the delay
5305     ordinal times this number plus one, plus the slot number as an index into
5306     the appropriate predicate to test.  */
5307
5308  for (delay = delays, max_slots = 0; delay; delay = delay->next)
5309    if (XVECLEN (delay->def, 1) / 3 > max_slots)
5310      max_slots = XVECLEN (delay->def, 1) / 3;
5311
5312  /* Write function prelude.  */
5313
5314  printf ("int\n");
5315  printf ("eligible_for_%s (delay_insn, slot, candidate_insn, flags)\n",
5316	   kind);
5317  printf ("     rtx delay_insn;\n");
5318  printf ("     int slot;\n");
5319  printf ("     rtx candidate_insn;\n");
5320  printf ("     int flags;\n");
5321  printf ("{\n");
5322  printf ("  rtx insn;\n");
5323  printf ("\n");
5324  printf ("  if (slot >= %d)\n", max_slots);
5325  printf ("    abort ();\n");
5326  printf ("\n");
5327
5328  /* If more than one delay type, find out which type the delay insn is.  */
5329
5330  if (num_delays > 1)
5331    {
5332      attr = find_attr ("*delay_type", 0);
5333      if (! attr) abort ();
5334      common_av = find_most_used (attr);
5335
5336      printf ("  insn = delay_insn;\n");
5337      printf ("  switch (recog_memoized (insn))\n");
5338      printf ("    {\n");
5339
5340      sprintf (str, " * %d;\n      break;", max_slots);
5341      for (av = attr->first_value; av; av = av->next)
5342	if (av != common_av)
5343	  write_attr_case (attr, av, 1, "slot +=", str, 4, true_rtx);
5344
5345      write_attr_case (attr, common_av, 0, "slot +=", str, 4, true_rtx);
5346      printf ("    }\n\n");
5347
5348      /* Ensure matched.  Otherwise, shouldn't have been called.  */
5349      printf ("  if (slot < %d)\n", max_slots);
5350      printf ("    abort ();\n\n");
5351    }
5352
5353  /* If just one type of delay slot, write simple switch.  */
5354  if (num_delays == 1 && max_slots == 1)
5355    {
5356      printf ("  insn = candidate_insn;\n");
5357      printf ("  switch (recog_memoized (insn))\n");
5358      printf ("    {\n");
5359
5360      attr = find_attr ("*delay_1_0", 0);
5361      if (! attr) abort ();
5362      common_av = find_most_used (attr);
5363
5364      for (av = attr->first_value; av; av = av->next)
5365	if (av != common_av)
5366	  write_attr_case (attr, av, 1, "return", ";", 4, true_rtx);
5367
5368      write_attr_case (attr, common_av, 0, "return", ";", 4, true_rtx);
5369      printf ("    }\n");
5370    }
5371
5372  else
5373    {
5374      /* Write a nested CASE.  The first indicates which condition we need to
5375	 test, and the inner CASE tests the condition.  */
5376      printf ("  insn = candidate_insn;\n");
5377      printf ("  switch (slot)\n");
5378      printf ("    {\n");
5379
5380      for (delay = delays; delay; delay = delay->next)
5381	for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
5382	  {
5383	    printf ("    case %d:\n",
5384		    (i / 3) + (num_delays == 1 ? 0 : delay->num * max_slots));
5385	    printf ("      switch (recog_memoized (insn))\n");
5386	    printf ("\t{\n");
5387
5388	    sprintf (str, "*%s_%d_%d", kind, delay->num, i / 3);
5389	    attr = find_attr (str, 0);
5390	    if (! attr) abort ();
5391	    common_av = find_most_used (attr);
5392
5393	    for (av = attr->first_value; av; av = av->next)
5394	      if (av != common_av)
5395		write_attr_case (attr, av, 1, "return", ";", 8, true_rtx);
5396
5397	    write_attr_case (attr, common_av, 0, "return", ";", 8, true_rtx);
5398	    printf ("      }\n");
5399	  }
5400
5401      printf ("    default:\n");
5402      printf ("      abort ();\n");
5403      printf ("    }\n");
5404    }
5405
5406  printf ("}\n\n");
5407}
5408
5409/* Write routines to compute conflict cost for function units.  Then write a
5410   table describing the available function units.  */
5411
5412static void
5413write_function_unit_info ()
5414{
5415  struct function_unit *unit;
5416  int i;
5417
5418  /* Write out conflict routines for function units.  Don't bother writing
5419     one if there is only one issue delay value.  */
5420
5421  for (unit = units; unit; unit = unit->next)
5422    {
5423      if (unit->needs_blockage_function)
5424	write_complex_function (unit, "blockage", "block");
5425
5426      /* If the minimum and maximum conflict costs are the same, there
5427	 is only one value, so we don't need a function.  */
5428      if (! unit->needs_conflict_function)
5429	{
5430	  unit->default_cost = make_numeric_value (unit->issue_delay.max);
5431	  continue;
5432	}
5433
5434      /* The function first computes the case from the candidate insn.  */
5435      unit->default_cost = make_numeric_value (0);
5436      write_complex_function (unit, "conflict_cost", "cost");
5437    }
5438
5439  /* Now that all functions have been written, write the table describing
5440     the function units.   The name is included for documentation purposes
5441     only.  */
5442
5443  printf ("struct function_unit_desc function_units[] = {\n");
5444
5445  /* Write out the descriptions in numeric order, but don't force that order
5446     on the list.  Doing so increases the runtime of genattrtab.c.  */
5447  for (i = 0; i < num_units; i++)
5448    {
5449      for (unit = units; unit; unit = unit->next)
5450	if (unit->num == i)
5451	  break;
5452
5453      printf ("  {\"%s\", %d, %d, %d, %s, %d, %s_unit_ready_cost, ",
5454	      unit->name, 1 << unit->num, unit->multiplicity,
5455	      unit->simultaneity, XSTR (unit->default_cost, 0),
5456	      unit->issue_delay.max, unit->name);
5457
5458      if (unit->needs_conflict_function)
5459	printf ("%s_unit_conflict_cost, ", unit->name);
5460      else
5461	printf ("0, ");
5462
5463      printf ("%d, ", unit->max_blockage);
5464
5465      if (unit->needs_range_function)
5466	printf ("%s_unit_blockage_range, ", unit->name);
5467      else
5468	printf ("0, ");
5469
5470      if (unit->needs_blockage_function)
5471	printf ("%s_unit_blockage", unit->name);
5472      else
5473	printf ("0");
5474
5475      printf ("}, \n");
5476    }
5477
5478  printf ("};\n\n");
5479}
5480
5481static void
5482write_complex_function (unit, name, connection)
5483     struct function_unit *unit;
5484     char *name, *connection;
5485{
5486  struct attr_desc *case_attr, *attr;
5487  struct attr_value *av, *common_av;
5488  rtx value;
5489  char *str;
5490  int using_case;
5491  int i;
5492
5493  printf ("static int\n");
5494  printf ("%s_unit_%s (executing_insn, candidate_insn)\n",
5495	  unit->name, name);
5496  printf ("     rtx executing_insn;\n");
5497  printf ("     rtx candidate_insn;\n");
5498  printf ("{\n");
5499  printf ("  rtx insn;\n");
5500  printf ("  int casenum;\n\n");
5501  printf ("  insn = executing_insn;\n");
5502  printf ("  switch (recog_memoized (insn))\n");
5503  printf ("    {\n");
5504
5505  /* Write the `switch' statement to get the case value.  */
5506  str = (char *) alloca (strlen (unit->name) + strlen (name) + strlen (connection) + 10);
5507  sprintf (str, "*%s_cases", unit->name);
5508  case_attr = find_attr (str, 0);
5509  if (! case_attr) abort ();
5510  common_av = find_most_used (case_attr);
5511
5512  for (av = case_attr->first_value; av; av = av->next)
5513    if (av != common_av)
5514      write_attr_case (case_attr, av, 1,
5515		       "casenum =", ";", 4, unit->condexp);
5516
5517  write_attr_case (case_attr, common_av, 0,
5518		   "casenum =", ";", 4, unit->condexp);
5519  printf ("    }\n\n");
5520
5521  /* Now write an outer switch statement on each case.  Then write
5522     the tests on the executing function within each.  */
5523  printf ("  insn = candidate_insn;\n");
5524  printf ("  switch (casenum)\n");
5525  printf ("    {\n");
5526
5527  for (i = 0; i < unit->num_opclasses; i++)
5528    {
5529      /* Ensure using this case.  */
5530      using_case = 0;
5531      for (av = case_attr->first_value; av; av = av->next)
5532	if (av->num_insns
5533	    && contained_in_p (make_numeric_value (i), av->value))
5534	  using_case = 1;
5535
5536      if (! using_case)
5537	continue;
5538
5539      printf ("    case %d:\n", i);
5540      sprintf (str, "*%s_%s_%d", unit->name, connection, i);
5541      attr = find_attr (str, 0);
5542      if (! attr) abort ();
5543
5544      /* If single value, just write it.  */
5545      value = find_single_value (attr);
5546      if (value)
5547	write_attr_set (attr, 6, value, "return", ";\n", true_rtx, -2, -2);
5548      else
5549	{
5550	  common_av = find_most_used (attr);
5551	  printf ("      switch (recog_memoized (insn))\n");
5552	  printf ("\t{\n");
5553
5554	  for (av = attr->first_value; av; av = av->next)
5555	    if (av != common_av)
5556	      write_attr_case (attr, av, 1,
5557			       "return", ";", 8, unit->condexp);
5558
5559	  write_attr_case (attr, common_av, 0,
5560			   "return", ";", 8, unit->condexp);
5561	  printf ("      }\n\n");
5562	}
5563    }
5564
5565  /* This default case should not be needed, but gcc's analysis is not
5566     good enough to realize that the default case is not needed for the
5567     second switch statement.  */
5568  printf ("    default:\n      abort ();\n");
5569  printf ("    }\n}\n\n");
5570}
5571
5572/* This page contains miscellaneous utility routines.  */
5573
5574/* Given a string, return the number of comma-separated elements in it.
5575   Return 0 for the null string.  */
5576
5577static int
5578n_comma_elts (s)
5579     char *s;
5580{
5581  int n;
5582
5583  if (*s == '\0')
5584    return 0;
5585
5586  for (n = 1; *s; s++)
5587    if (*s == ',')
5588      n++;
5589
5590  return n;
5591}
5592
5593/* Given a pointer to a (char *), return a malloc'ed string containing the
5594   next comma-separated element.  Advance the pointer to after the string
5595   scanned, or the end-of-string.  Return NULL if at end of string.  */
5596
5597static char *
5598next_comma_elt (pstr)
5599     char **pstr;
5600{
5601  char *out_str;
5602  char *p;
5603
5604  if (**pstr == '\0')
5605    return NULL;
5606
5607  /* Find end of string to compute length.  */
5608  for (p = *pstr; *p != ',' && *p != '\0'; p++)
5609    ;
5610
5611  out_str = attr_string (*pstr, p - *pstr);
5612  *pstr = p;
5613
5614  if (**pstr == ',')
5615    (*pstr)++;
5616
5617  return out_str;
5618}
5619
5620/* Return a `struct attr_desc' pointer for a given named attribute.  If CREATE
5621   is non-zero, build a new attribute, if one does not exist.  */
5622
5623static struct attr_desc *
5624find_attr (name, create)
5625     char *name;
5626     int create;
5627{
5628  struct attr_desc *attr;
5629  int index;
5630
5631  /* Before we resort to using `strcmp', see if the string address matches
5632     anywhere.  In most cases, it should have been canonicalized to do so.  */
5633  if (name == alternative_name)
5634    return NULL;
5635
5636  index = name[0] & (MAX_ATTRS_INDEX - 1);
5637  for (attr = attrs[index]; attr; attr = attr->next)
5638    if (name == attr->name)
5639      return attr;
5640
5641  /* Otherwise, do it the slow way.  */
5642  for (attr = attrs[index]; attr; attr = attr->next)
5643    if (name[0] == attr->name[0] && ! strcmp (name, attr->name))
5644      return attr;
5645
5646  if (! create)
5647    return NULL;
5648
5649  attr = (struct attr_desc *) oballoc (sizeof (struct attr_desc));
5650  attr->name = attr_string (name, strlen (name));
5651  attr->first_value = attr->default_val = NULL;
5652  attr->is_numeric = attr->negative_ok = attr->is_const = attr->is_special = 0;
5653  attr->next = attrs[index];
5654  attrs[index] = attr;
5655
5656  return attr;
5657}
5658
5659/* Create internal attribute with the given default value.  */
5660
5661static void
5662make_internal_attr (name, value, special)
5663     char *name;
5664     rtx value;
5665     int special;
5666{
5667  struct attr_desc *attr;
5668
5669  attr = find_attr (name, 1);
5670  if (attr->default_val)
5671    abort ();
5672
5673  attr->is_numeric = 1;
5674  attr->is_const = 0;
5675  attr->is_special = (special & 1) != 0;
5676  attr->negative_ok = (special & 2) != 0;
5677  attr->unsigned_p = (special & 4) != 0;
5678  attr->func_units_p = (special & 8) != 0;
5679  attr->blockage_p = (special & 16) != 0;
5680  attr->default_val = get_attr_value (value, attr, -2);
5681}
5682
5683/* Find the most used value of an attribute.  */
5684
5685static struct attr_value *
5686find_most_used (attr)
5687     struct attr_desc *attr;
5688{
5689  struct attr_value *av;
5690  struct attr_value *most_used;
5691  int nuses;
5692
5693  most_used = NULL;
5694  nuses = -1;
5695
5696  for (av = attr->first_value; av; av = av->next)
5697    if (av->num_insns > nuses)
5698      nuses = av->num_insns, most_used = av;
5699
5700  return most_used;
5701}
5702
5703/* If an attribute only has a single value used, return it.  Otherwise
5704   return NULL.  */
5705
5706static rtx
5707find_single_value (attr)
5708     struct attr_desc *attr;
5709{
5710  struct attr_value *av;
5711  rtx unique_value;
5712
5713  unique_value = NULL;
5714  for (av = attr->first_value; av; av = av->next)
5715    if (av->num_insns)
5716      {
5717	if (unique_value)
5718	  return NULL;
5719	else
5720	  unique_value = av->value;
5721      }
5722
5723  return unique_value;
5724}
5725
5726/* Return (attr_value "n") */
5727
5728static rtx
5729make_numeric_value (n)
5730     int n;
5731{
5732  static rtx int_values[20];
5733  rtx exp;
5734  char *p;
5735
5736  if (n < 0)
5737    abort ();
5738
5739  if (n < 20 && int_values[n])
5740    return int_values[n];
5741
5742  p = attr_printf (MAX_DIGITS, "%d", n);
5743  exp = attr_rtx (CONST_STRING, p);
5744
5745  if (n < 20)
5746    int_values[n] = exp;
5747
5748  return exp;
5749}
5750
5751static void
5752extend_range (range, min, max)
5753     struct range *range;
5754     int min;
5755     int max;
5756{
5757  if (range->min > min) range->min = min;
5758  if (range->max < max) range->max = max;
5759}
5760
5761char *
5762xrealloc (ptr, size)
5763     char *ptr;
5764     unsigned size;
5765{
5766  char *result = (char *) realloc (ptr, size);
5767  if (!result)
5768    fatal ("virtual memory exhausted");
5769  return result;
5770}
5771
5772char *
5773xmalloc (size)
5774     unsigned size;
5775{
5776  register char *val = (char *) malloc (size);
5777
5778  if (val == 0)
5779    fatal ("virtual memory exhausted");
5780  return val;
5781}
5782
5783static rtx
5784copy_rtx_unchanging (orig)
5785     register rtx orig;
5786{
5787#if 0
5788  register rtx copy;
5789  register RTX_CODE code;
5790#endif
5791
5792  if (RTX_UNCHANGING_P (orig) || MEM_IN_STRUCT_P (orig))
5793    return orig;
5794
5795  MEM_IN_STRUCT_P (orig) = 1;
5796  return orig;
5797
5798#if 0
5799  code = GET_CODE (orig);
5800  switch (code)
5801    {
5802    case CONST_INT:
5803    case CONST_DOUBLE:
5804    case SYMBOL_REF:
5805    case CODE_LABEL:
5806      return orig;
5807
5808    default:
5809      break;
5810    }
5811
5812  copy = rtx_alloc (code);
5813  PUT_MODE (copy, GET_MODE (orig));
5814  RTX_UNCHANGING_P (copy) = 1;
5815
5816  bcopy ((char *) &XEXP (orig, 0), (char *) &XEXP (copy, 0),
5817	 GET_RTX_LENGTH (GET_CODE (copy)) * sizeof (rtx));
5818  return copy;
5819#endif
5820}
5821
5822static void
5823fatal VPROTO ((char *format, ...))
5824{
5825#ifndef __STDC__
5826  char *format;
5827#endif
5828  va_list ap;
5829
5830  VA_START (ap, format);
5831
5832#ifndef __STDC__
5833  format = va_arg (ap, char *);
5834#endif
5835
5836  fprintf (stderr, "genattrtab: ");
5837  vfprintf (stderr, format, ap);
5838  va_end (ap);
5839  fprintf (stderr, "\n");
5840  exit (FATAL_EXIT_CODE);
5841}
5842
5843/* More 'friendly' abort that prints the line and file.
5844   config.h can #define abort fancy_abort if you like that sort of thing.  */
5845
5846void
5847fancy_abort ()
5848{
5849  fatal ("Internal gcc abort.");
5850}
5851
5852/* Determine if an insn has a constant number of delay slots, i.e., the
5853   number of delay slots is not a function of the length of the insn.  */
5854
5855void
5856write_const_num_delay_slots ()
5857{
5858  struct attr_desc *attr = find_attr ("*num_delay_slots", 0);
5859  struct attr_value *av;
5860  struct insn_ent *ie;
5861
5862  if (attr)
5863    {
5864      printf ("int\nconst_num_delay_slots (insn)\n");
5865      printf ("     rtx insn;\n");
5866      printf ("{\n");
5867      printf ("  switch (recog_memoized (insn))\n");
5868      printf ("    {\n");
5869
5870      for (av = attr->first_value; av; av = av->next)
5871	{
5872	  length_used = 0;
5873	  walk_attr_value (av->value);
5874	  if (length_used)
5875	    {
5876	      for (ie = av->first_insn; ie; ie = ie->next)
5877	      if (ie->insn_code != -1)
5878		printf ("    case %d:\n", ie->insn_code);
5879	      printf ("      return 0;\n");
5880	    }
5881	}
5882
5883      printf ("    default:\n");
5884      printf ("      return 1;\n");
5885      printf ("    }\n}\n\n");
5886    }
5887}
5888
5889
5890int
5891main (argc, argv)
5892     int argc;
5893     char **argv;
5894{
5895  rtx desc;
5896  FILE *infile;
5897  register int c;
5898  struct attr_desc *attr;
5899  struct insn_def *id;
5900  rtx tem;
5901  int i;
5902
5903#if defined (RLIMIT_STACK) && defined (HAVE_GETRLIMIT) && defined (HAVE_SETRLIMIT)
5904  /* Get rid of any avoidable limit on stack size.  */
5905  {
5906    struct rlimit rlim;
5907
5908    /* Set the stack limit huge so that alloca does not fail.  */
5909    getrlimit (RLIMIT_STACK, &rlim);
5910    rlim.rlim_cur = rlim.rlim_max;
5911    setrlimit (RLIMIT_STACK, &rlim);
5912  }
5913#endif
5914
5915  obstack_init (rtl_obstack);
5916  obstack_init (hash_obstack);
5917  obstack_init (temp_obstack);
5918
5919  if (argc <= 1)
5920    fatal ("No input file name.");
5921
5922  infile = fopen (argv[1], "r");
5923  if (infile == 0)
5924    {
5925      perror (argv[1]);
5926      exit (FATAL_EXIT_CODE);
5927    }
5928
5929  init_rtl ();
5930
5931  /* Set up true and false rtx's */
5932  true_rtx = rtx_alloc (CONST_INT);
5933  XWINT (true_rtx, 0) = 1;
5934  false_rtx = rtx_alloc (CONST_INT);
5935  XWINT (false_rtx, 0) = 0;
5936  RTX_UNCHANGING_P (true_rtx) = RTX_UNCHANGING_P (false_rtx) = 1;
5937  RTX_INTEGRATED_P (true_rtx) = RTX_INTEGRATED_P (false_rtx) = 1;
5938
5939  alternative_name = attr_string ("alternative", strlen ("alternative"));
5940
5941  printf ("/* Generated automatically by the program `genattrtab'\n\
5942from the machine description file `md'.  */\n\n");
5943
5944  /* Read the machine description.  */
5945
5946  while (1)
5947    {
5948      c = read_skip_spaces (infile);
5949      if (c == EOF)
5950	break;
5951      ungetc (c, infile);
5952
5953      desc = read_rtx (infile);
5954      if (GET_CODE (desc) == DEFINE_INSN
5955	  || GET_CODE (desc) == DEFINE_PEEPHOLE
5956	  || GET_CODE (desc) == DEFINE_ASM_ATTRIBUTES)
5957	gen_insn (desc);
5958
5959      else if (GET_CODE (desc) == DEFINE_EXPAND)
5960	insn_code_number++, insn_index_number++;
5961
5962      else if (GET_CODE (desc) == DEFINE_SPLIT)
5963	insn_code_number++, insn_index_number++;
5964
5965      else if (GET_CODE (desc) == DEFINE_ATTR)
5966	{
5967	  gen_attr (desc);
5968	  insn_index_number++;
5969	}
5970
5971      else if (GET_CODE (desc) == DEFINE_DELAY)
5972	{
5973	  gen_delay (desc);
5974	  insn_index_number++;
5975	}
5976
5977      else if (GET_CODE (desc) == DEFINE_FUNCTION_UNIT)
5978	{
5979	  gen_unit (desc);
5980	  insn_index_number++;
5981	}
5982    }
5983
5984  /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one.  */
5985  if (! got_define_asm_attributes)
5986    {
5987      tem = rtx_alloc (DEFINE_ASM_ATTRIBUTES);
5988      XVEC (tem, 0) = rtvec_alloc (0);
5989      gen_insn (tem);
5990    }
5991
5992  /* Expand DEFINE_DELAY information into new attribute.  */
5993  if (num_delays)
5994    expand_delays ();
5995
5996  /* Expand DEFINE_FUNCTION_UNIT information into new attributes.  */
5997  if (num_units)
5998    expand_units ();
5999
6000  printf ("#include \"config.h\"\n");
6001  printf ("#include \"system.h\"\n");
6002  printf ("#include \"rtl.h\"\n");
6003  printf ("#include \"insn-config.h\"\n");
6004  printf ("#include \"recog.h\"\n");
6005  printf ("#include \"regs.h\"\n");
6006  printf ("#include \"real.h\"\n");
6007  printf ("#include \"output.h\"\n");
6008  printf ("#include \"insn-attr.h\"\n");
6009  printf ("\n");
6010  printf ("#define operands recog_operand\n\n");
6011
6012  /* Make `insn_alternatives'.  */
6013  insn_alternatives = (int *) oballoc (insn_code_number * sizeof (int));
6014  for (id = defs; id; id = id->next)
6015    if (id->insn_code >= 0)
6016      insn_alternatives[id->insn_code] = (1 << id->num_alternatives) - 1;
6017
6018  /* Make `insn_n_alternatives'.  */
6019  insn_n_alternatives = (int *) oballoc (insn_code_number * sizeof (int));
6020  for (id = defs; id; id = id->next)
6021    if (id->insn_code >= 0)
6022      insn_n_alternatives[id->insn_code] = id->num_alternatives;
6023
6024  /* Prepare to write out attribute subroutines by checking everything stored
6025     away and building the attribute cases.  */
6026
6027  check_defs ();
6028  for (i = 0; i < MAX_ATTRS_INDEX; i++)
6029    for (attr = attrs[i]; attr; attr = attr->next)
6030      {
6031	attr->default_val->value
6032	  = check_attr_value (attr->default_val->value, attr);
6033	fill_attr (attr);
6034      }
6035
6036  /* Construct extra attributes for `length'.  */
6037  make_length_attrs ();
6038
6039  /* Perform any possible optimizations to speed up compilation.  */
6040  optimize_attrs ();
6041
6042  /* Now write out all the `gen_attr_...' routines.  Do these before the
6043     special routines (specifically before write_function_unit_info), so
6044     that they get defined before they are used.  */
6045
6046  for (i = 0; i < MAX_ATTRS_INDEX; i++)
6047    for (attr = attrs[i]; attr; attr = attr->next)
6048      {
6049	if (! attr->is_special && ! attr->is_const)
6050	  write_attr_get (attr);
6051      }
6052
6053  /* Write out delay eligibility information, if DEFINE_DELAY present.
6054     (The function to compute the number of delay slots will be written
6055     below.)  */
6056  if (num_delays)
6057    {
6058      write_eligible_delay ("delay");
6059      if (have_annul_true)
6060	write_eligible_delay ("annul_true");
6061      if (have_annul_false)
6062	write_eligible_delay ("annul_false");
6063    }
6064
6065  /* Write out information about function units.  */
6066  if (num_units)
6067    write_function_unit_info ();
6068
6069  /* Write out constant delay slot info */
6070  write_const_num_delay_slots ();
6071
6072  write_length_unit_log ();
6073
6074  fflush (stdout);
6075  exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
6076  /* NOTREACHED */
6077  return 0;
6078}
6079