genautomata.c revision 132718
1/* Pipeline hazard description translator.
2   Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
3
4   Written by Vladimir Makarov <vmakarov@redhat.com>
5
6This file is part of GCC.
7
8GCC is free software; you can redistribute it and/or modify it
9under the terms of the GNU General Public License as published by the
10Free Software Foundation; either version 2, or (at your option) any
11later version.
12
13GCC is distributed in the hope that it will be useful, but WITHOUT
14ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16for more details.
17
18You should have received a copy of the GNU General Public License
19along with GCC; see the file COPYING.  If not, write to the Free
20Software Foundation, 59 Temple Place - Suite 330, Boston, MA
2102111-1307, USA.  */
22
23/* References:
24
25   1. Detecting pipeline structural hazards quickly. T. Proebsting,
26      C. Fraser. Proceedings of ACM SIGPLAN-SIGACT Symposium on
27      Principles of Programming Languages, pages 280--286, 1994.
28
29      This article is a good start point to understand usage of finite
30      state automata for pipeline hazard recognizers.  But I'd
31      recommend the 2nd article for more deep understanding.
32
33   2. Efficient Instruction Scheduling Using Finite State Automata:
34      V. Bala and N. Rubin, Proceedings of MICRO-28.  This is the best
35      article about usage of finite state automata for pipeline hazard
36      recognizers.
37
38   The current implementation is different from the 2nd article in the
39   following:
40
41   1. New operator `|' (alternative) is permitted in functional unit
42      reservation which can be treated deterministically and
43      non-deterministically.
44
45   2. Possibility of usage of nondeterministic automata too.
46
47   3. Possibility to query functional unit reservations for given
48      automaton state.
49
50   4. Several constructions to describe impossible reservations
51      (`exclusion_set', `presence_set', `final_presence_set',
52      `absence_set', and `final_absence_set').
53
54   5. No reverse automata are generated.  Trace instruction scheduling
55      requires this.  It can be easily added in the future if we
56      really need this.
57
58   6. Union of automaton states are not generated yet.  It is planned
59      to be implemented.  Such feature is needed to make more accurate
60      interlock insn scheduling to get state describing functional
61      unit reservation in a joint CFG point.  */
62
63/* This file code processes constructions of machine description file
64   which describes automaton used for recognition of processor pipeline
65   hazards by insn scheduler and can be used for other tasks (such as
66   VLIW insn packing.
67
68   The translator functions `gen_cpu_unit', `gen_query_cpu_unit',
69   `gen_bypass', `gen_excl_set', `gen_presence_set',
70   `gen_final_presence_set', `gen_absence_set',
71   `gen_final_absence_set', `gen_automaton', `gen_automata_option',
72   `gen_reserv', `gen_insn_reserv' are called from file
73   `genattrtab.c'.  They transform RTL constructions describing
74   automata in .md file into internal representation convenient for
75   further processing.
76
77   The translator major function `expand_automata' processes the
78   description internal representation into finite state automaton.
79   It can be divided on:
80
81     o checking correctness of the automaton pipeline description
82       (major function is `check_all_description').
83
84     o generating automaton (automata) from the description (major
85       function is `make_automaton').
86
87     o optional transformation of nondeterministic finite state
88       automata into deterministic ones if the alternative operator
89       `|' is treated nondeterministically in the description (major
90       function is NDFA_to_DFA).
91
92     o optional minimization of the finite state automata by merging
93       equivalent automaton states (major function is `minimize_DFA').
94
95     o forming tables (some as comb vectors) and attributes
96       representing the automata (functions output_..._table).
97
98   Function `write_automata' outputs the created finite state
99   automaton as different tables and functions which works with the
100   automata to inquire automaton state and to change its state.  These
101   function are used by gcc instruction scheduler and may be some
102   other gcc code.  */
103
104#include "bconfig.h"
105#include "system.h"
106#include "coretypes.h"
107#include "tm.h"
108#include "rtl.h"
109#include "obstack.h"
110#include "errors.h"
111
112#include <math.h>
113#include "hashtab.h"
114#include "varray.h"
115
116#ifndef CHAR_BIT
117#define CHAR_BIT 8
118#endif
119
120#include "genattrtab.h"
121
122/* Positions in machine description file.  Now they are not used.  But
123   they could be used in the future for better diagnostic messages.  */
124typedef int pos_t;
125
126/* The following is element of vector of current (and planned in the
127   future) functional unit reservations.  */
128typedef unsigned HOST_WIDE_INT set_el_t;
129
130/* Reservations of function units are represented by value of the following
131   type.  */
132typedef set_el_t *reserv_sets_t;
133
134/* The following structure represents variable length array (vla) of
135   pointers and HOST WIDE INTs.  We could be use only varray.  But we
136   add new lay because we add elements very frequently and this could
137   stress OS allocator when varray is used only.  */
138typedef struct {
139  size_t length;      /* current size of vla.  */
140  varray_type varray; /* container for vla.  */
141} vla_ptr_t;
142
143typedef vla_ptr_t vla_hwint_t;
144
145/* The following structure describes a ticker.  */
146struct ticker
147{
148  /* The following member value is time of the ticker creation with
149     taking into account time when the ticker is off.  Active time of
150     the ticker is current time minus the value.  */
151  int modified_creation_time;
152  /* The following member value is time (incremented by one) when the
153     ticker was off.  Zero value means that now the ticker is on.  */
154  int incremented_off_time;
155};
156
157/* The ticker is represented by the following type.  */
158typedef struct ticker ticker_t;
159
160/* The following type describes elements of output vectors.  */
161typedef HOST_WIDE_INT vect_el_t;
162
163/* Forward declaration of structures of internal representation of
164   pipeline description based on NDFA.  */
165
166struct unit_decl;
167struct bypass_decl;
168struct result_decl;
169struct automaton_decl;
170struct unit_pattern_rel_decl;
171struct reserv_decl;
172struct insn_reserv_decl;
173struct decl;
174struct unit_regexp;
175struct result_regexp;
176struct reserv_regexp;
177struct nothing_regexp;
178struct sequence_regexp;
179struct repeat_regexp;
180struct allof_regexp;
181struct oneof_regexp;
182struct regexp;
183struct description;
184struct unit_set_el;
185struct pattern_set_el;
186struct pattern_reserv;
187struct state;
188struct alt_state;
189struct arc;
190struct ainsn;
191struct automaton;
192struct state_ainsn_table;
193
194/* The following typedefs are for brevity.  */
195typedef struct unit_decl *unit_decl_t;
196typedef struct decl *decl_t;
197typedef struct regexp *regexp_t;
198typedef struct unit_set_el *unit_set_el_t;
199typedef struct pattern_set_el *pattern_set_el_t;
200typedef struct pattern_reserv *pattern_reserv_t;
201typedef struct alt_state *alt_state_t;
202typedef struct state *state_t;
203typedef struct arc *arc_t;
204typedef struct ainsn *ainsn_t;
205typedef struct automaton *automaton_t;
206typedef struct automata_list_el *automata_list_el_t;
207typedef struct state_ainsn_table *state_ainsn_table_t;
208
209
210/* Prototypes of functions gen_cpu_unit, gen_query_cpu_unit,
211   gen_bypass, gen_excl_set, gen_presence_set, gen_final_presence_set,
212   gen_absence_set, gen_final_absence_set, gen_automaton,
213   gen_automata_option, gen_reserv, gen_insn_reserv,
214   initiate_automaton_gen, expand_automata, write_automata are
215   described on the file top because the functions are called from
216   function `main'.  */
217
218static void *create_node             (size_t);
219static void *copy_node               (const void *, size_t);
220static char *check_name              (char *, pos_t);
221static char *next_sep_el             (char **, int, int);
222static int n_sep_els                 (char *, int, int);
223static char **get_str_vect           (char *, int *, int, int);
224static void gen_presence_absence_set (rtx, int, int);
225static regexp_t gen_regexp_el        (char *);
226static regexp_t gen_regexp_repeat    (char *);
227static regexp_t gen_regexp_allof     (char *);
228static regexp_t gen_regexp_oneof     (char *);
229static regexp_t gen_regexp_sequence  (char *);
230static regexp_t gen_regexp           (char *);
231
232static unsigned string_hash          (const char *);
233static unsigned automaton_decl_hash  (const void *);
234static int automaton_decl_eq_p       (const void *,
235				      const void *);
236static decl_t insert_automaton_decl       (decl_t);
237static decl_t find_automaton_decl         (char *);
238static void initiate_automaton_decl_table (void);
239static void finish_automaton_decl_table   (void);
240
241static hashval_t insn_decl_hash           (const void *);
242static int insn_decl_eq_p                 (const void *,
243					   const void *);
244static decl_t insert_insn_decl            (decl_t);
245static decl_t find_insn_decl              (char *);
246static void initiate_insn_decl_table      (void);
247static void finish_insn_decl_table        (void);
248
249static hashval_t decl_hash                (const void *);
250static int decl_eq_p                      (const void *,
251					   const void *);
252static decl_t insert_decl                 (decl_t);
253static decl_t find_decl                   (char *);
254static void initiate_decl_table           (void);
255static void finish_decl_table             (void);
256
257static unit_set_el_t process_excls       (char **, int, pos_t);
258static void add_excls                    (unit_set_el_t, unit_set_el_t,
259					  pos_t);
260static unit_set_el_t process_presence_absence_names
261					 (char **, int, pos_t,
262					  int, int);
263static pattern_set_el_t process_presence_absence_patterns
264					 (char ***, int, pos_t,
265					  int, int);
266static void add_presence_absence	 (unit_set_el_t,
267					  pattern_set_el_t,
268					  pos_t, int, int);
269static void process_decls                (void);
270static struct bypass_decl *find_bypass   (struct bypass_decl *,
271					  struct insn_reserv_decl *);
272static void check_automaton_usage        (void);
273static regexp_t process_regexp           (regexp_t);
274static void process_regexp_decls         (void);
275static void check_usage                  (void);
276static int loop_in_regexp                (regexp_t, decl_t);
277static void check_loops_in_regexps       (void);
278static void process_regexp_cycles        (regexp_t, int, int,
279					  int *, int *);
280static void evaluate_max_reserv_cycles   (void);
281static void check_all_description        (void);
282
283static ticker_t create_ticker               (void);
284static void ticker_off                      (ticker_t *);
285static void ticker_on                       (ticker_t *);
286static int active_time                      (ticker_t);
287static void print_active_time               (FILE *, ticker_t);
288
289static void add_advance_cycle_insn_decl     (void);
290
291static alt_state_t get_free_alt_state (void);
292static void free_alt_state              (alt_state_t);
293static void free_alt_states             (alt_state_t);
294static int alt_state_cmp                (const void *alt_state_ptr_1,
295					 const void *alt_state_ptr_2);
296static alt_state_t uniq_sort_alt_states (alt_state_t);
297static int alt_states_eq                (alt_state_t, alt_state_t);
298static void initiate_alt_states         (void);
299static void finish_alt_states           (void);
300
301static reserv_sets_t alloc_empty_reserv_sets (void);
302static unsigned reserv_sets_hash_value (reserv_sets_t);
303static int reserv_sets_cmp             (reserv_sets_t, reserv_sets_t);
304static int reserv_sets_eq              (reserv_sets_t, reserv_sets_t);
305static void set_unit_reserv            (reserv_sets_t, int, int);
306static int test_unit_reserv            (reserv_sets_t, int, int);
307static int it_is_empty_reserv_sets     (reserv_sets_t)
308                                            ATTRIBUTE_UNUSED;
309static int reserv_sets_are_intersected (reserv_sets_t, reserv_sets_t);
310static void reserv_sets_shift          (reserv_sets_t, reserv_sets_t);
311static void reserv_sets_or             (reserv_sets_t, reserv_sets_t,
312					reserv_sets_t);
313static void reserv_sets_and            (reserv_sets_t, reserv_sets_t,
314					reserv_sets_t)
315                                            ATTRIBUTE_UNUSED;
316static void output_cycle_reservs       (FILE *, reserv_sets_t,
317					int, int);
318static void output_reserv_sets         (FILE *, reserv_sets_t);
319static state_t get_free_state          (int, automaton_t);
320static void free_state                 (state_t);
321static hashval_t state_hash            (const void *);
322static int state_eq_p                  (const void *, const void *);
323static state_t insert_state            (state_t);
324static void set_state_reserv           (state_t, int, int);
325static int intersected_state_reservs_p (state_t, state_t);
326static state_t states_union            (state_t, state_t, reserv_sets_t);
327static state_t state_shift             (state_t, reserv_sets_t);
328static void initiate_states            (void);
329static void finish_states              (void);
330
331static void free_arc           (arc_t);
332static void remove_arc         (state_t, arc_t);
333static arc_t find_arc          (state_t, state_t, ainsn_t);
334static arc_t add_arc           (state_t, state_t, ainsn_t, int);
335static arc_t first_out_arc     (state_t);
336static arc_t next_out_arc      (arc_t);
337static void initiate_arcs      (void);
338static void finish_arcs        (void);
339
340static automata_list_el_t get_free_automata_list_el (void);
341static void free_automata_list_el (automata_list_el_t);
342static void free_automata_list (automata_list_el_t);
343static hashval_t automata_list_hash (const void *);
344static int automata_list_eq_p (const void *, const void *);
345static void initiate_automata_lists (void);
346static void automata_list_start (void);
347static void automata_list_add (automaton_t);
348static automata_list_el_t automata_list_finish (void);
349static void finish_automata_lists (void);
350
351static void initiate_excl_sets             (void);
352static reserv_sets_t get_excl_set          (reserv_sets_t);
353
354static pattern_reserv_t form_reserv_sets_list (pattern_set_el_t);
355static void initiate_presence_absence_pattern_sets     (void);
356static int check_presence_pattern_sets     (reserv_sets_t,
357					    reserv_sets_t, int);
358static int check_absence_pattern_sets  (reserv_sets_t, reserv_sets_t,
359					int);
360
361static regexp_t copy_insn_regexp     (regexp_t);
362static regexp_t transform_1          (regexp_t);
363static regexp_t transform_2          (regexp_t);
364static regexp_t transform_3          (regexp_t);
365static regexp_t regexp_transform_func
366                       (regexp_t, regexp_t (*) (regexp_t));
367static regexp_t transform_regexp            (regexp_t);
368static void transform_insn_regexps          (void);
369
370static void store_alt_unit_usage (regexp_t, regexp_t, int, int);
371static void check_regexp_units_distribution   (const char *, regexp_t);
372static void check_unit_distributions_to_automata (void);
373
374static int process_seq_for_forming_states   (regexp_t, automaton_t,
375					     int);
376static void finish_forming_alt_state        (alt_state_t,
377					     automaton_t);
378static void process_alts_for_forming_states (regexp_t,
379					     automaton_t, int);
380static void create_alt_states               (automaton_t);
381
382static void form_ainsn_with_same_reservs    (automaton_t);
383
384static reserv_sets_t form_reservs_matter (automaton_t);
385static void make_automaton           (automaton_t);
386static void form_arcs_marked_by_insn (state_t);
387static int create_composed_state     (state_t, arc_t, vla_ptr_t *);
388static void NDFA_to_DFA              (automaton_t);
389static void pass_state_graph         (state_t, void (*) (state_t));
390static void pass_states              (automaton_t,
391				      void (*) (state_t));
392static void initiate_pass_states       (void);
393static void add_achieved_state         (state_t);
394static int set_out_arc_insns_equiv_num (state_t, int);
395static void clear_arc_insns_equiv_num  (state_t);
396static void copy_equiv_class           (vla_ptr_t *to,
397					const vla_ptr_t *from);
398static int first_cycle_unit_presence   (state_t, int);
399static int state_is_differed           (state_t, state_t, int, int);
400static state_t init_equiv_class        (state_t *states, int);
401static int partition_equiv_class       (state_t *, int,
402					vla_ptr_t *, int *);
403static void evaluate_equiv_classes     (automaton_t, vla_ptr_t *);
404static void merge_states               (automaton_t, vla_ptr_t *);
405static void set_new_cycle_flags        (state_t);
406static void minimize_DFA               (automaton_t);
407static void incr_states_and_arcs_nums  (state_t);
408static void count_states_and_arcs      (automaton_t, int *, int *);
409static void build_automaton            (automaton_t);
410
411static void set_order_state_num              (state_t);
412static void enumerate_states                 (automaton_t);
413
414static ainsn_t insert_ainsn_into_equiv_class       (ainsn_t, ainsn_t);
415static void delete_ainsn_from_equiv_class          (ainsn_t);
416static void process_insn_equiv_class               (ainsn_t, arc_t *);
417static void process_state_for_insn_equiv_partition (state_t);
418static void set_insn_equiv_classes                 (automaton_t);
419
420static double estimate_one_automaton_bound     (void);
421static int compare_max_occ_cycle_nums          (const void *,
422						const void *);
423static void units_to_automata_heuristic_distr  (void);
424static ainsn_t create_ainsns                   (void);
425static void units_to_automata_distr            (void);
426static void create_automata                    (void);
427
428static void form_regexp                      (regexp_t);
429static const char *regexp_representation     (regexp_t);
430static void finish_regexp_representation     (void);
431
432static void output_range_type            (FILE *, long int, long int);
433static int longest_path_length           (state_t);
434static void process_state_longest_path_length (state_t);
435static void output_dfa_max_issue_rate    (void);
436static void output_vect                  (vect_el_t *, int);
437static void output_chip_member_name      (FILE *, automaton_t);
438static void output_temp_chip_member_name (FILE *, automaton_t);
439static void output_translate_vect_name   (FILE *, automaton_t);
440static void output_trans_full_vect_name  (FILE *, automaton_t);
441static void output_trans_comb_vect_name  (FILE *, automaton_t);
442static void output_trans_check_vect_name (FILE *, automaton_t);
443static void output_trans_base_vect_name  (FILE *, automaton_t);
444static void output_state_alts_full_vect_name    (FILE *, automaton_t);
445static void output_state_alts_comb_vect_name    (FILE *, automaton_t);
446static void output_state_alts_check_vect_name   (FILE *, automaton_t);
447static void output_state_alts_base_vect_name    (FILE *, automaton_t);
448static void output_min_issue_delay_vect_name    (FILE *, automaton_t);
449static void output_dead_lock_vect_name   (FILE *, automaton_t);
450static void output_reserved_units_table_name    (FILE *, automaton_t);
451static void output_state_member_type     (FILE *, automaton_t);
452static void output_chip_definitions      (void);
453static void output_translate_vect        (automaton_t);
454static int comb_vect_p                   (state_ainsn_table_t);
455static state_ainsn_table_t create_state_ainsn_table (automaton_t);
456static void output_state_ainsn_table
457   (state_ainsn_table_t, char *, void (*) (FILE *, automaton_t),
458    void (*) (FILE *, automaton_t), void (*) (FILE *, automaton_t),
459    void (*) (FILE *, automaton_t));
460static void add_vect                     (state_ainsn_table_t,
461					  int, vect_el_t *, int);
462static int out_state_arcs_num            (state_t);
463static int compare_transition_els_num    (const void *, const void *);
464static void add_vect_el	         (vla_hwint_t *,
465					  ainsn_t, int);
466static void add_states_vect_el           (state_t);
467static void output_trans_table           (automaton_t);
468static void output_state_alts_table      (automaton_t);
469static int min_issue_delay_pass_states   (state_t, ainsn_t);
470static int min_issue_delay               (state_t, ainsn_t);
471static void initiate_min_issue_delay_pass_states (void);
472static void output_min_issue_delay_table (automaton_t);
473static void output_dead_lock_vect        (automaton_t);
474static void output_reserved_units_table  (automaton_t);
475static void output_tables                (void);
476static void output_max_insn_queue_index_def (void);
477static void output_insn_code_cases   (void (*) (automata_list_el_t));
478static void output_automata_list_min_issue_delay_code (automata_list_el_t);
479static void output_internal_min_issue_delay_func (void);
480static void output_automata_list_transition_code (automata_list_el_t);
481static void output_internal_trans_func   (void);
482static void output_internal_insn_code_evaluation (const char *,
483						  const char *, int);
484static void output_dfa_insn_code_func	        (void);
485static void output_trans_func                   (void);
486static void output_automata_list_state_alts_code (automata_list_el_t);
487static void output_internal_state_alts_func     (void);
488static void output_state_alts_func              (void);
489static void output_min_issue_delay_func         (void);
490static void output_internal_dead_lock_func      (void);
491static void output_dead_lock_func               (void);
492static void output_internal_reset_func          (void);
493static void output_size_func		        (void);
494static void output_reset_func                   (void);
495static void output_min_insn_conflict_delay_func (void);
496static void output_internal_insn_latency_func   (void);
497static void output_insn_latency_func            (void);
498static void output_print_reservation_func       (void);
499static int units_cmp			        (const void *,
500						 const void *);
501static void output_get_cpu_unit_code_func       (void);
502static void output_cpu_unit_reservation_p       (void);
503static void output_dfa_clean_insn_cache_func    (void);
504static void output_dfa_start_func	        (void);
505static void output_dfa_finish_func	        (void);
506
507static void output_regexp                  (regexp_t );
508static void output_unit_set_el_list	   (unit_set_el_t);
509static void output_pattern_set_el_list	   (pattern_set_el_t);
510static void output_description             (void);
511static void output_automaton_name          (FILE *, automaton_t);
512static void output_automaton_units         (automaton_t);
513static void add_state_reservs              (state_t);
514static void output_state_arcs              (state_t);
515static int state_reservs_cmp               (const void *,
516					    const void *);
517static void remove_state_duplicate_reservs (void);
518static void output_state                   (state_t);
519static void output_automaton_descriptions  (void);
520static void output_statistics              (FILE *);
521static void output_time_statistics         (FILE *);
522static void generate                       (void);
523
524static void make_insn_alts_attr                (void);
525static void make_internal_dfa_insn_code_attr   (void);
526static void make_default_insn_latency_attr     (void);
527static void make_bypass_attr                   (void);
528static const char *file_name_suffix            (const char *);
529static const char *base_file_name              (const char *);
530static void check_automata_insn_issues	       (void);
531static void add_automaton_state                (state_t);
532static void form_important_insn_automata_lists (void);
533
534/* Undefined position.  */
535static pos_t no_pos = 0;
536
537/* All IR is stored in the following obstack.  */
538static struct obstack irp;
539
540
541
542/* This page contains code for work with variable length array (vla)
543   of pointers.  We could be use only varray.  But we add new lay
544   because we add elements very frequently and this could stress OS
545   allocator when varray is used only.  */
546
547/* Start work with vla.  */
548#define VLA_PTR_CREATE(vla, allocated_length, name)	 \
549  do									 \
550    {	 \
551      vla_ptr_t *const _vla_ptr = &(vla);                                \
552	 \
553      VARRAY_GENERIC_PTR_INIT (_vla_ptr->varray, allocated_length, name);\
554      _vla_ptr->length = 0;                                              \
555    }									 \
556  while (0)
557
558/* Finish work with the vla.  */
559#define VLA_PTR_DELETE(vla) VARRAY_FREE ((vla).varray)
560
561/* Return start address of the vla.  */
562#define VLA_PTR_BEGIN(vla) ((void *) &VARRAY_GENERIC_PTR ((vla).varray, 0))
563
564/* Address of the last element of the vla.  Do not use side effects in
565   the macro argument.  */
566#define VLA_PTR_LAST(vla) (&VARRAY_GENERIC_PTR ((vla).varray,         \
567                                                (vla).length - 1))
568/* Nullify the vla.  */
569#define VLA_PTR_NULLIFY(vla)  ((vla).length = 0)
570
571/* Shorten the vla on given number bytes.  */
572#define VLA_PTR_SHORTEN(vla, n)  ((vla).length -= (n))
573
574/* Expand the vla on N elements.  The values of new elements are
575   undefined.  */
576#define VLA_PTR_EXPAND(vla, n)                                        \
577  do {                                                                \
578    vla_ptr_t *const _expand_vla_ptr = &(vla);                        \
579    const size_t _new_length = (n) + _expand_vla_ptr->length;         \
580                                                                      \
581    if (VARRAY_SIZE (_expand_vla_ptr->varray) < _new_length)          \
582      VARRAY_GROW (_expand_vla_ptr->varray,                           \
583                   (_new_length - _expand_vla_ptr->length < 128       \
584                    ? _expand_vla_ptr->length + 128 : _new_length));  \
585    _expand_vla_ptr->length = _new_length;                            \
586  } while (0)
587
588/* Add element to the end of the vla.  */
589#define VLA_PTR_ADD(vla, ptr)                                           \
590  do {                                                                  \
591    vla_ptr_t *const _vla_ptr = &(vla);                                 \
592                                                                        \
593    VLA_PTR_EXPAND (*_vla_ptr, 1);                                      \
594    VARRAY_GENERIC_PTR (_vla_ptr->varray, _vla_ptr->length - 1) = (ptr);\
595  } while (0)
596
597/* Length of the vla in elements.  */
598#define VLA_PTR_LENGTH(vla) ((vla).length)
599
600/* N-th element of the vla.  */
601#define VLA_PTR(vla, n) VARRAY_GENERIC_PTR ((vla).varray, n)
602
603
604/* The following macros are analogous to the previous ones but for
605   VLAs of HOST WIDE INTs.  */
606
607#define VLA_HWINT_CREATE(vla, allocated_length, name)                 \
608  do {                                                                \
609    vla_hwint_t *const _vla_ptr = &(vla);                             \
610                                                                      \
611    VARRAY_WIDE_INT_INIT (_vla_ptr->varray, allocated_length, name);  \
612    _vla_ptr->length = 0;                                             \
613  } while (0)
614
615#define VLA_HWINT_DELETE(vla) VARRAY_FREE ((vla).varray)
616
617#define VLA_HWINT_BEGIN(vla) (&VARRAY_WIDE_INT ((vla).varray, 0))
618
619#define VLA_HWINT_NULLIFY(vla)  ((vla).length = 0)
620
621#define VLA_HWINT_EXPAND(vla, n)                                      \
622  do {                                                                \
623    vla_hwint_t *const _expand_vla_ptr = &(vla);                      \
624    const size_t _new_length = (n) + _expand_vla_ptr->length;         \
625                                                                      \
626    if (VARRAY_SIZE (_expand_vla_ptr->varray) < _new_length)          \
627      VARRAY_GROW (_expand_vla_ptr->varray,                           \
628                   (_new_length - _expand_vla_ptr->length < 128       \
629                    ? _expand_vla_ptr->length + 128 : _new_length));  \
630    _expand_vla_ptr->length = _new_length;                            \
631  } while (0)
632
633#define VLA_HWINT_ADD(vla, ptr)                                       \
634  do {                                                                \
635    vla_hwint_t *const _vla_ptr = &(vla);                             \
636                                                                      \
637    VLA_HWINT_EXPAND (*_vla_ptr, 1);                                  \
638    VARRAY_WIDE_INT (_vla_ptr->varray, _vla_ptr->length - 1) = (ptr); \
639  } while (0)
640
641#define VLA_HWINT_LENGTH(vla) ((vla).length)
642
643#define VLA_HWINT(vla, n) VARRAY_WIDE_INT ((vla).varray, n)
644
645
646
647/* Options with the following names can be set up in automata_option
648   construction.  Because the strings occur more one time we use the
649   macros.  */
650
651#define NO_MINIMIZATION_OPTION "-no-minimization"
652
653#define TIME_OPTION "-time"
654
655#define V_OPTION "-v"
656
657#define W_OPTION "-w"
658
659#define NDFA_OPTION "-ndfa"
660
661#define PROGRESS_OPTION "-progress"
662
663/* The following flags are set up by function `initiate_automaton_gen'.  */
664
665/* Make automata with nondeterministic reservation by insns (`-ndfa').  */
666static int ndfa_flag;
667
668/* Do not make minimization of DFA (`-no-minimization').  */
669static int no_minimization_flag;
670
671/* Value of this variable is number of automata being generated.  The
672   actual number of automata may be less this value if there is not
673   sufficient number of units.  This value is defined by argument of
674   option `-split' or by constructions automaton if the value is zero
675   (it is default value of the argument).  */
676static int split_argument;
677
678/* Flag of output time statistics (`-time').  */
679static int time_flag;
680
681/* Flag of creation of description file which contains description of
682   result automaton and statistics information (`-v').  */
683static int v_flag;
684
685/* Flag of output of a progress bar showing how many states were
686   generated so far for automaton being processed (`-progress').  */
687static int progress_flag;
688
689/* Flag of generating warning instead of error for non-critical errors
690   (`-w').  */
691static int w_flag;
692
693
694/* Output file for pipeline hazard recognizer (PHR) being generated.
695   The value is NULL if the file is not defined.  */
696static FILE *output_file;
697
698/* Description file of PHR.  The value is NULL if the file is not
699   created.  */
700static FILE *output_description_file;
701
702/* PHR description file name.  */
703static char *output_description_file_name;
704
705/* Value of the following variable is node representing description
706   being processed.  This is start point of IR.  */
707static struct description *description;
708
709
710
711/* This page contains description of IR structure (nodes).  */
712
713enum decl_mode
714{
715  dm_unit,
716  dm_bypass,
717  dm_automaton,
718  dm_excl,
719  dm_presence,
720  dm_absence,
721  dm_reserv,
722  dm_insn_reserv
723};
724
725/* This describes define_cpu_unit and define_query_cpu_unit (see file
726   rtl.def).  */
727struct unit_decl
728{
729  char *name;
730  /* NULL if the automaton name is absent.  */
731  char *automaton_name;
732  /* If the following value is not zero, the cpu unit reservation is
733     described in define_query_cpu_unit.  */
734  char query_p;
735
736  /* The following fields are defined by checker.  */
737
738  /* The following field value is nonzero if the unit is used in an
739     regexp.  */
740  char unit_is_used;
741
742  /* The following field value is order number (0, 1, ...) of given
743     unit.  */
744  int unit_num;
745  /* The following field value is corresponding declaration of
746     automaton which was given in description.  If the field value is
747     NULL then automaton in the unit declaration was absent.  */
748  struct automaton_decl *automaton_decl;
749  /* The following field value is maximal cycle number (1, ...) on
750     which given unit occurs in insns.  Zero value means that given
751     unit is not used in insns.  */
752  int max_occ_cycle_num;
753  /* The following field value is minimal cycle number (0, ...) on
754     which given unit occurs in insns.  -1 value means that given
755     unit is not used in insns.  */
756  int min_occ_cycle_num;
757  /* The following list contains units which conflict with given
758     unit.  */
759  unit_set_el_t excl_list;
760  /* The following list contains patterns which are required to
761     reservation of given unit.  */
762  pattern_set_el_t presence_list;
763  pattern_set_el_t final_presence_list;
764  /* The following list contains patterns which should be not present
765     in reservation for given unit.  */
766  pattern_set_el_t absence_list;
767  pattern_set_el_t final_absence_list;
768  /* The following is used only when `query_p' has nonzero value.
769     This is query number for the unit.  */
770  int query_num;
771  /* The following is the last cycle on which the unit was checked for
772     correct distributions of units to automata in a regexp.  */
773  int last_distribution_check_cycle;
774
775  /* The following fields are defined by automaton generator.  */
776
777  /* The following field value is number of the automaton to which
778     given unit belongs.  */
779  int corresponding_automaton_num;
780  /* If the following value is not zero, the cpu unit is present in a
781     `exclusion_set' or in right part of a `presence_set',
782     `final_presence_set', `absence_set', and
783     `final_absence_set'define_query_cpu_unit.  */
784  char in_set_p;
785};
786
787/* This describes define_bypass (see file rtl.def).  */
788struct bypass_decl
789{
790  int latency;
791  char *out_insn_name;
792  char *in_insn_name;
793  char *bypass_guard_name;
794
795  /* The following fields are defined by checker.  */
796
797  /* output and input insns of given bypass.  */
798  struct insn_reserv_decl *out_insn_reserv;
799  struct insn_reserv_decl *in_insn_reserv;
800  /* The next bypass for given output insn.  */
801  struct bypass_decl *next;
802};
803
804/* This describes define_automaton (see file rtl.def).  */
805struct automaton_decl
806{
807  char *name;
808
809  /* The following fields are defined by automaton generator.  */
810
811  /* The following field value is nonzero if the automaton is used in
812     an regexp definition.  */
813  char automaton_is_used;
814
815  /* The following fields are defined by checker.  */
816
817  /* The following field value is the corresponding automaton.  This
818     field is not NULL only if the automaton is present in unit
819     declarations and the automatic partition on automata is not
820     used.  */
821  automaton_t corresponding_automaton;
822};
823
824/* This describes exclusion relations: exclusion_set (see file
825   rtl.def).  */
826struct excl_rel_decl
827{
828  int all_names_num;
829  int first_list_length;
830  char *names [1];
831};
832
833/* This describes unit relations: [final_]presence_set or
834   [final_]absence_set (see file rtl.def).  */
835struct unit_pattern_rel_decl
836{
837  int final_p;
838  int names_num;
839  int patterns_num;
840  char **names;
841  char ***patterns;
842};
843
844/* This describes define_reservation (see file rtl.def).  */
845struct reserv_decl
846{
847  char *name;
848  regexp_t regexp;
849
850  /* The following fields are defined by checker.  */
851
852  /* The following field value is nonzero if the unit is used in an
853     regexp.  */
854  char reserv_is_used;
855  /* The following field is used to check up cycle in expression
856     definition.  */
857  int loop_pass_num;
858};
859
860/* This describes define_insn_reservation (see file rtl.def).  */
861struct insn_reserv_decl
862{
863  rtx condexp;
864  int default_latency;
865  regexp_t regexp;
866  char *name;
867
868  /* The following fields are defined by checker.  */
869
870  /* The following field value is order number (0, 1, ...) of given
871     insn.  */
872  int insn_num;
873  /* The following field value is list of bypasses in which given insn
874     is output insn.  */
875  struct bypass_decl *bypass_list;
876
877  /* The following fields are defined by automaton generator.  */
878
879  /* The following field is the insn regexp transformed that
880     the regexp has not optional regexp, repetition regexp, and an
881     reservation name (i.e. reservation identifiers are changed by the
882     corresponding regexp) and all alternations are the topest level
883     of the regexp.  The value can be NULL only if it is special
884     insn `cycle advancing'.  */
885  regexp_t transformed_regexp;
886  /* The following field value is list of arcs marked given
887     insn.  The field is used in transformation NDFA -> DFA.  */
888  arc_t arcs_marked_by_insn;
889  /* The two following fields are used during minimization of a finite state
890     automaton.  */
891  /* The field value is number of equivalence class of state into
892     which arc marked by given insn enters from a state (fixed during
893     an automaton minimization).  */
894  int equiv_class_num;
895  /* The field value is state_alts of arc leaving a state (fixed
896     during an automaton minimization) and marked by given insn
897     enters.  */
898  int state_alts;
899  /* The following member value is the list to automata which can be
900     changed by the insn issue.  */
901  automata_list_el_t important_automata_list;
902  /* The following member is used to process insn once for output.  */
903  int processed_p;
904};
905
906/* This contains a declaration mentioned above.  */
907struct decl
908{
909  /* What node in the union? */
910  enum decl_mode mode;
911  pos_t pos;
912  union
913  {
914    struct unit_decl unit;
915    struct bypass_decl bypass;
916    struct automaton_decl automaton;
917    struct excl_rel_decl excl;
918    struct unit_pattern_rel_decl presence;
919    struct unit_pattern_rel_decl absence;
920    struct reserv_decl reserv;
921    struct insn_reserv_decl insn_reserv;
922  } decl;
923};
924
925/* The following structures represent parsed reservation strings.  */
926enum regexp_mode
927{
928  rm_unit,
929  rm_reserv,
930  rm_nothing,
931  rm_sequence,
932  rm_repeat,
933  rm_allof,
934  rm_oneof
935};
936
937/* Cpu unit in reservation.  */
938struct unit_regexp
939{
940  char *name;
941  unit_decl_t unit_decl;
942};
943
944/* Define_reservation in a reservation.  */
945struct reserv_regexp
946{
947  char *name;
948  struct reserv_decl *reserv_decl;
949};
950
951/* Absence of reservation (represented by string `nothing').  */
952struct nothing_regexp
953{
954  /* This used to be empty but ISO C doesn't allow that.  */
955  char unused;
956};
957
958/* Representation of reservations separated by ',' (see file
959   rtl.def).  */
960struct sequence_regexp
961{
962  int regexps_num;
963  regexp_t regexps [1];
964};
965
966/* Representation of construction `repeat' (see file rtl.def).  */
967struct repeat_regexp
968{
969  int repeat_num;
970  regexp_t regexp;
971};
972
973/* Representation of reservations separated by '+' (see file
974   rtl.def).  */
975struct allof_regexp
976{
977  int regexps_num;
978  regexp_t regexps [1];
979};
980
981/* Representation of reservations separated by '|' (see file
982   rtl.def).  */
983struct oneof_regexp
984{
985  int regexps_num;
986  regexp_t regexps [1];
987};
988
989/* Representation of a reservation string.  */
990struct regexp
991{
992  /* What node in the union? */
993  enum regexp_mode mode;
994  pos_t pos;
995  union
996  {
997    struct unit_regexp unit;
998    struct reserv_regexp reserv;
999    struct nothing_regexp nothing;
1000    struct sequence_regexp sequence;
1001    struct repeat_regexp repeat;
1002    struct allof_regexp allof;
1003    struct oneof_regexp oneof;
1004  } regexp;
1005};
1006
1007/* Represents description of pipeline hazard description based on
1008   NDFA.  */
1009struct description
1010{
1011  int decls_num;
1012
1013  /* The following fields are defined by checker.  */
1014
1015  /* The following fields values are correspondingly number of all
1016     units, query units, and insns in the description.  */
1017  int units_num;
1018  int query_units_num;
1019  int insns_num;
1020  /* The following field value is max length (in cycles) of
1021     reservations of insns.  The field value is defined only for
1022     correct programs.  */
1023  int max_insn_reserv_cycles;
1024
1025  /* The following fields are defined by automaton generator.  */
1026
1027  /* The following field value is the first automaton.  */
1028  automaton_t first_automaton;
1029
1030  /* The following field is created by pipeline hazard parser and
1031     contains all declarations.  We allocate additional entry for
1032     special insn "cycle advancing" which is added by the automaton
1033     generator.  */
1034  decl_t decls [1];
1035};
1036
1037
1038/* The following nodes are created in automaton checker.  */
1039
1040/* The following nodes represent exclusion set for cpu units.  Each
1041   element is accessed through only one excl_list.  */
1042struct unit_set_el
1043{
1044  unit_decl_t unit_decl;
1045  unit_set_el_t next_unit_set_el;
1046};
1047
1048/* The following nodes represent presence or absence pattern for cpu
1049   units.  Each element is accessed through only one presence_list or
1050   absence_list.  */
1051struct pattern_set_el
1052{
1053  /* The number of units in unit_decls.  */
1054  int units_num;
1055  /* The units forming the pattern.  */
1056  struct unit_decl **unit_decls;
1057  pattern_set_el_t next_pattern_set_el;
1058};
1059
1060
1061/* The following nodes are created in automaton generator.  */
1062
1063
1064/* The following nodes represent presence or absence pattern for cpu
1065   units.  Each element is accessed through only one element of
1066   unit_presence_set_table or unit_absence_set_table.  */
1067struct pattern_reserv
1068{
1069  reserv_sets_t reserv;
1070  pattern_reserv_t next_pattern_reserv;
1071};
1072
1073/* The following node type describes state automaton.  The state may
1074   be deterministic or non-deterministic.  Non-deterministic state has
1075   several component states which represent alternative cpu units
1076   reservations.  The state also is used for describing a
1077   deterministic reservation of automaton insn.  */
1078struct state
1079{
1080  /* The following member value is nonzero if there is a transition by
1081     cycle advancing.  */
1082  int new_cycle_p;
1083  /* The following field is list of processor unit reservations on
1084     each cycle.  */
1085  reserv_sets_t reservs;
1086  /* The following field is unique number of given state between other
1087     states.  */
1088  int unique_num;
1089  /* The following field value is automaton to which given state
1090     belongs.  */
1091  automaton_t automaton;
1092  /* The following field value is the first arc output from given
1093     state.  */
1094  arc_t first_out_arc;
1095  /* The following field is used to form NDFA.  */
1096  char it_was_placed_in_stack_for_NDFA_forming;
1097  /* The following field is used to form DFA.  */
1098  char it_was_placed_in_stack_for_DFA_forming;
1099  /* The following field is used to transform NDFA to DFA and DFA
1100     minimization.  The field value is not NULL if the state is a
1101     compound state.  In this case the value of field `unit_sets_list'
1102     is NULL.  All states in the list are in the hash table.  The list
1103     is formed through field `next_sorted_alt_state'.  We should
1104     support only one level of nesting state.  */
1105  alt_state_t component_states;
1106  /* The following field is used for passing graph of states.  */
1107  int pass_num;
1108  /* The list of states belonging to one equivalence class is formed
1109     with the aid of the following field.  */
1110  state_t next_equiv_class_state;
1111  /* The two following fields are used during minimization of a finite
1112     state automaton.  */
1113  int equiv_class_num_1, equiv_class_num_2;
1114  /* The following field is used during minimization of a finite state
1115     automaton.  The field value is state corresponding to equivalence
1116     class to which given state belongs.  */
1117  state_t equiv_class_state;
1118  /* The following field value is the order number of given state.
1119     The states in final DFA is enumerated with the aid of the
1120     following field.  */
1121  int order_state_num;
1122  /* This member is used for passing states for searching minimal
1123     delay time.  */
1124  int state_pass_num;
1125  /* The following member is used to evaluate min issue delay of insn
1126     for a state.  */
1127  int min_insn_issue_delay;
1128  /* The following member is used to evaluate max issue rate of the
1129     processor.  The value of the member is maximal length of the path
1130     from given state no containing arcs marked by special insn `cycle
1131     advancing'.  */
1132  int longest_path_length;
1133};
1134
1135/* The following macro is an initial value of member
1136   `longest_path_length' of a state.  */
1137#define UNDEFINED_LONGEST_PATH_LENGTH -1
1138
1139/* Automaton arc.  */
1140struct arc
1141{
1142  /* The following field refers for the state into which given arc
1143     enters.  */
1144  state_t to_state;
1145  /* The following field describes that the insn issue (with cycle
1146     advancing for special insn `cycle advancing' and without cycle
1147     advancing for others) makes transition from given state to
1148     another given state.  */
1149  ainsn_t insn;
1150  /* The following field value is the next arc output from the same
1151     state.  */
1152  arc_t next_out_arc;
1153  /* List of arcs marked given insn is formed with the following
1154     field.  The field is used in transformation NDFA -> DFA.  */
1155  arc_t next_arc_marked_by_insn;
1156  /* The following field is defined if NDFA_FLAG is zero.  The member
1157     value is number of alternative reservations which can be used for
1158     transition for given state by given insn.  */
1159  int state_alts;
1160};
1161
1162/* The following node type describes a deterministic alternative in
1163   non-deterministic state which characterizes cpu unit reservations
1164   of automaton insn or which is part of NDFA.  */
1165struct alt_state
1166{
1167  /* The following field is a deterministic state which characterizes
1168     unit reservations of the instruction.  */
1169  state_t state;
1170  /* The following field refers to the next state which characterizes
1171     unit reservations of the instruction.  */
1172  alt_state_t next_alt_state;
1173  /* The following field refers to the next state in sorted list.  */
1174  alt_state_t next_sorted_alt_state;
1175};
1176
1177/* The following node type describes insn of automaton.  They are
1178   labels of FA arcs.  */
1179struct ainsn
1180{
1181  /* The following field value is the corresponding insn declaration
1182     of description.  */
1183  struct insn_reserv_decl *insn_reserv_decl;
1184  /* The following field value is the next insn declaration for an
1185     automaton.  */
1186  ainsn_t next_ainsn;
1187  /* The following field is states which characterize automaton unit
1188     reservations of the instruction.  The value can be NULL only if it
1189     is special insn `cycle advancing'.  */
1190  alt_state_t alt_states;
1191  /* The following field is sorted list of states which characterize
1192     automaton unit reservations of the instruction.  The value can be
1193     NULL only if it is special insn `cycle advancing'.  */
1194  alt_state_t sorted_alt_states;
1195  /* The following field refers the next automaton insn with
1196     the same reservations.  */
1197  ainsn_t next_same_reservs_insn;
1198  /* The following field is flag of the first automaton insn with the
1199     same reservations in the declaration list.  Only arcs marked such
1200     insn is present in the automaton.  This significantly decreases
1201     memory requirements especially when several automata are
1202     formed.  */
1203  char first_insn_with_same_reservs;
1204  /* The following member has nonzero value if there is arc from state of
1205     the automaton marked by the ainsn.  */
1206  char arc_exists_p;
1207  /* Cyclic list of insns of an equivalence class is formed with the
1208     aid of the following field.  */
1209  ainsn_t next_equiv_class_insn;
1210  /* The following field value is nonzero if the insn declaration is
1211     the first insn declaration with given equivalence number.  */
1212  char first_ainsn_with_given_equialence_num;
1213  /* The following field is number of class of equivalence of insns.
1214     It is necessary because many insns may be equivalent with the
1215     point of view of pipeline hazards.  */
1216  int insn_equiv_class_num;
1217  /* The following member value is TRUE if there is an arc in the
1218     automaton marked by the insn into another state.  In other
1219     words, the insn can change the state of the automaton.  */
1220  int important_p;
1221};
1222
1223/* The following describes an automaton for PHR.  */
1224struct automaton
1225{
1226  /* The following field value is the list of insn declarations for
1227     given automaton.  */
1228  ainsn_t ainsn_list;
1229  /* The following field value is the corresponding automaton
1230     declaration.  This field is not NULL only if the automatic
1231     partition on automata is not used.  */
1232  struct automaton_decl *corresponding_automaton_decl;
1233  /* The following field value is the next automaton.  */
1234  automaton_t next_automaton;
1235  /* The following field is start state of FA.  There are not unit
1236     reservations in the state.  */
1237  state_t start_state;
1238  /* The following field value is number of equivalence classes of
1239     insns (see field `insn_equiv_class_num' in
1240     `insn_reserv_decl').  */
1241  int insn_equiv_classes_num;
1242  /* The following field value is number of states of final DFA.  */
1243  int achieved_states_num;
1244  /* The following field value is the order number (0, 1, ...) of
1245     given automaton.  */
1246  int automaton_order_num;
1247  /* The following fields contain statistics information about
1248     building automaton.  */
1249  int NDFA_states_num, DFA_states_num;
1250  /* The following field value is defined only if minimization of DFA
1251     is used.  */
1252  int minimal_DFA_states_num;
1253  int NDFA_arcs_num, DFA_arcs_num;
1254  /* The following field value is defined only if minimization of DFA
1255     is used.  */
1256  int minimal_DFA_arcs_num;
1257  /* The following two members refer for two table state x ainsn ->
1258     int.  */
1259  state_ainsn_table_t trans_table;
1260  state_ainsn_table_t state_alts_table;
1261  /* The following member value is maximal value of min issue delay
1262     for insns of the automaton.  */
1263  int max_min_delay;
1264  /* Usually min issue delay is small and we can place several (2, 4,
1265     8) elements in one vector element.  So the compression factor can
1266     be 1 (no compression), 2, 4, 8.  */
1267  int min_issue_delay_table_compression_factor;
1268};
1269
1270/* The following is the element of the list of automata.  */
1271struct automata_list_el
1272{
1273  /* The automaton itself.  */
1274  automaton_t automaton;
1275  /* The next automata set element.  */
1276  automata_list_el_t next_automata_list_el;
1277};
1278
1279/* The following structure describes a table state X ainsn -> int(>= 0).  */
1280struct state_ainsn_table
1281{
1282  /* Automaton to which given table belongs.  */
1283  automaton_t automaton;
1284  /* The following tree vectors for comb vector implementation of the
1285     table.  */
1286  vla_hwint_t comb_vect;
1287  vla_hwint_t check_vect;
1288  vla_hwint_t base_vect;
1289  /* This is simple implementation of the table.  */
1290  vla_hwint_t full_vect;
1291  /* Minimal and maximal values of the previous vectors.  */
1292  int min_comb_vect_el_value, max_comb_vect_el_value;
1293  int min_base_vect_el_value, max_base_vect_el_value;
1294};
1295
1296/* Macros to access members of unions.  Use only them for access to
1297   union members of declarations and regexps.  */
1298
1299#if defined ENABLE_CHECKING && (GCC_VERSION >= 2007)
1300
1301#define DECL_UNIT(d) __extension__					\
1302(({ struct decl *const _decl = (d);					\
1303     if (_decl->mode != dm_unit)					\
1304       decl_mode_check_failed (_decl->mode, "dm_unit",			\
1305			       __FILE__, __LINE__, __FUNCTION__);	\
1306     &(_decl)->decl.unit; }))
1307
1308#define DECL_BYPASS(d) __extension__					\
1309(({ struct decl *const _decl = (d);					\
1310     if (_decl->mode != dm_bypass)					\
1311       decl_mode_check_failed (_decl->mode, "dm_bypass",		\
1312			       __FILE__, __LINE__, __FUNCTION__);	\
1313     &(_decl)->decl.bypass; }))
1314
1315#define DECL_AUTOMATON(d) __extension__					\
1316(({ struct decl *const _decl = (d);					\
1317     if (_decl->mode != dm_automaton)					\
1318       decl_mode_check_failed (_decl->mode, "dm_automaton",		\
1319			       __FILE__, __LINE__, __FUNCTION__);	\
1320     &(_decl)->decl.automaton; }))
1321
1322#define DECL_EXCL(d) __extension__					\
1323(({ struct decl *const _decl = (d);					\
1324     if (_decl->mode != dm_excl)					\
1325       decl_mode_check_failed (_decl->mode, "dm_excl",			\
1326			       __FILE__, __LINE__, __FUNCTION__);	\
1327     &(_decl)->decl.excl; }))
1328
1329#define DECL_PRESENCE(d) __extension__					\
1330(({ struct decl *const _decl = (d);					\
1331     if (_decl->mode != dm_presence)					\
1332       decl_mode_check_failed (_decl->mode, "dm_presence",		\
1333			       __FILE__, __LINE__, __FUNCTION__);	\
1334     &(_decl)->decl.presence; }))
1335
1336#define DECL_ABSENCE(d) __extension__					\
1337(({ struct decl *const _decl = (d);					\
1338     if (_decl->mode != dm_absence)					\
1339       decl_mode_check_failed (_decl->mode, "dm_absence",		\
1340			       __FILE__, __LINE__, __FUNCTION__);	\
1341     &(_decl)->decl.absence; }))
1342
1343#define DECL_RESERV(d) __extension__					\
1344(({ struct decl *const _decl = (d);					\
1345     if (_decl->mode != dm_reserv)					\
1346       decl_mode_check_failed (_decl->mode, "dm_reserv",		\
1347			       __FILE__, __LINE__, __FUNCTION__);	\
1348     &(_decl)->decl.reserv; }))
1349
1350#define DECL_INSN_RESERV(d) __extension__				\
1351(({ struct decl *const _decl = (d);					\
1352     if (_decl->mode != dm_insn_reserv)					\
1353       decl_mode_check_failed (_decl->mode, "dm_insn_reserv",		\
1354			       __FILE__, __LINE__, __FUNCTION__);	\
1355     &(_decl)->decl.insn_reserv; }))
1356
1357static const char *decl_name (enum decl_mode);
1358static void decl_mode_check_failed (enum decl_mode, const char *,
1359				    const char *, int, const char *);
1360
1361/* Return string representation of declaration mode MODE.  */
1362static const char *
1363decl_name (enum decl_mode mode)
1364{
1365  static char str [100];
1366
1367  if (mode == dm_unit)
1368    return "dm_unit";
1369  else if (mode == dm_bypass)
1370    return "dm_bypass";
1371  else if (mode == dm_automaton)
1372    return "dm_automaton";
1373  else if (mode == dm_excl)
1374    return "dm_excl";
1375  else if (mode == dm_presence)
1376    return "dm_presence";
1377  else if (mode == dm_absence)
1378    return "dm_absence";
1379  else if (mode == dm_reserv)
1380    return "dm_reserv";
1381  else if (mode == dm_insn_reserv)
1382    return "dm_insn_reserv";
1383  else
1384    sprintf (str, "unknown (%d)", (int) mode);
1385  return str;
1386}
1387
1388/* The function prints message about unexpected declaration and finish
1389   the program.  */
1390static void
1391decl_mode_check_failed (enum decl_mode mode, const char *expected_mode_str,
1392			const char *file, int line, const char *func)
1393{
1394  fprintf
1395    (stderr,
1396     "\n%s: %d: error in %s: DECL check: expected decl %s, have %s\n",
1397     file, line, func, expected_mode_str, decl_name (mode));
1398  exit (1);
1399}
1400
1401
1402#define REGEXP_UNIT(r) __extension__					\
1403(({ struct regexp *const _regexp = (r);					\
1404     if (_regexp->mode != rm_unit)					\
1405       regexp_mode_check_failed (_regexp->mode, "rm_unit",		\
1406			       __FILE__, __LINE__, __FUNCTION__);	\
1407     &(_regexp)->regexp.unit; }))
1408
1409#define REGEXP_RESERV(r) __extension__					\
1410(({ struct regexp *const _regexp = (r);					\
1411     if (_regexp->mode != rm_reserv)					\
1412       regexp_mode_check_failed (_regexp->mode, "rm_reserv",		\
1413			       __FILE__, __LINE__, __FUNCTION__);	\
1414     &(_regexp)->regexp.reserv; }))
1415
1416#define REGEXP_SEQUENCE(r) __extension__				\
1417(({ struct regexp *const _regexp = (r);					\
1418     if (_regexp->mode != rm_sequence)					\
1419       regexp_mode_check_failed (_regexp->mode, "rm_sequence",		\
1420			       __FILE__, __LINE__, __FUNCTION__);	\
1421     &(_regexp)->regexp.sequence; }))
1422
1423#define REGEXP_REPEAT(r) __extension__					\
1424(({ struct regexp *const _regexp = (r);					\
1425     if (_regexp->mode != rm_repeat)					\
1426       regexp_mode_check_failed (_regexp->mode, "rm_repeat",		\
1427			       __FILE__, __LINE__, __FUNCTION__);	\
1428     &(_regexp)->regexp.repeat; }))
1429
1430#define REGEXP_ALLOF(r) __extension__					\
1431(({ struct regexp *const _regexp = (r);					\
1432     if (_regexp->mode != rm_allof)					\
1433       regexp_mode_check_failed (_regexp->mode, "rm_allof",		\
1434			       __FILE__, __LINE__, __FUNCTION__);	\
1435     &(_regexp)->regexp.allof; }))
1436
1437#define REGEXP_ONEOF(r) __extension__					\
1438(({ struct regexp *const _regexp = (r);					\
1439     if (_regexp->mode != rm_oneof)					\
1440       regexp_mode_check_failed (_regexp->mode, "rm_oneof",		\
1441			       __FILE__, __LINE__, __FUNCTION__);	\
1442     &(_regexp)->regexp.oneof; }))
1443
1444static const char *regexp_name (enum regexp_mode);
1445static void regexp_mode_check_failed (enum regexp_mode, const char *,
1446				      const char *, int,
1447				      const char *);
1448
1449
1450/* Return string representation of regexp mode MODE.  */
1451static const char *
1452regexp_name (enum regexp_mode mode)
1453{
1454  static char str [100];
1455
1456  if (mode == rm_unit)
1457    return "rm_unit";
1458  else if (mode == rm_reserv)
1459    return "rm_reserv";
1460  else if (mode == rm_nothing)
1461    return "rm_nothing";
1462  else if (mode == rm_sequence)
1463    return "rm_sequence";
1464  else if (mode == rm_repeat)
1465    return "rm_repeat";
1466  else if (mode == rm_allof)
1467    return "rm_allof";
1468  else if (mode == rm_oneof)
1469    return "rm_oneof";
1470  else
1471    sprintf (str, "unknown (%d)", (int) mode);
1472  return str;
1473}
1474
1475/* The function prints message about unexpected regexp and finish the
1476   program.  */
1477static void
1478regexp_mode_check_failed (enum regexp_mode mode,
1479			  const char *expected_mode_str,
1480			  const char *file, int line, const char *func)
1481{
1482  fprintf
1483    (stderr,
1484     "\n%s: %d: error in %s: REGEXP check: expected decl %s, have %s\n",
1485     file, line, func, expected_mode_str, regexp_name (mode));
1486  exit (1);
1487}
1488
1489#else /* #if defined ENABLE_RTL_CHECKING && (GCC_VERSION >= 2007) */
1490
1491#define DECL_UNIT(d) (&(d)->decl.unit)
1492#define DECL_BYPASS(d) (&(d)->decl.bypass)
1493#define DECL_AUTOMATON(d) (&(d)->decl.automaton)
1494#define DECL_EXCL(d) (&(d)->decl.excl)
1495#define DECL_PRESENCE(d) (&(d)->decl.presence)
1496#define DECL_ABSENCE(d) (&(d)->decl.absence)
1497#define DECL_RESERV(d) (&(d)->decl.reserv)
1498#define DECL_INSN_RESERV(d) (&(d)->decl.insn_reserv)
1499
1500#define REGEXP_UNIT(r) (&(r)->regexp.unit)
1501#define REGEXP_RESERV(r) (&(r)->regexp.reserv)
1502#define REGEXP_SEQUENCE(r) (&(r)->regexp.sequence)
1503#define REGEXP_REPEAT(r) (&(r)->regexp.repeat)
1504#define REGEXP_ALLOF(r) (&(r)->regexp.allof)
1505#define REGEXP_ONEOF(r) (&(r)->regexp.oneof)
1506
1507#endif /* #if defined ENABLE_RTL_CHECKING && (GCC_VERSION >= 2007) */
1508
1509/* Create IR structure (node).  */
1510static void *
1511create_node (size_t size)
1512{
1513  void *result;
1514
1515  obstack_blank (&irp, size);
1516  result = obstack_base (&irp);
1517  obstack_finish (&irp);
1518  /* Default values of members are NULL and zero.  */
1519  memset (result, 0, size);
1520  return result;
1521}
1522
1523/* Copy IR structure (node).  */
1524static void *
1525copy_node (const void *from, size_t size)
1526{
1527  void *const result = create_node (size);
1528  memcpy (result, from, size);
1529  return result;
1530}
1531
1532/* The function checks that NAME does not contain quotes (`"').  */
1533static char *
1534check_name (char * name, pos_t pos ATTRIBUTE_UNUSED)
1535{
1536  const char *str;
1537
1538  for (str = name; *str != '\0'; str++)
1539    if (*str == '\"')
1540      error ("Name `%s' contains quotes", name);
1541  return name;
1542}
1543
1544/* Pointers to all declarations during IR generation are stored in the
1545   following.  */
1546static vla_ptr_t decls;
1547
1548/* Given a pointer to a (char *) and a separator, return an alloc'ed
1549   string containing the next separated element, taking parentheses
1550   into account if PAR_FLAG has nonzero value.  Advance the pointer to
1551   after the string scanned, or the end-of-string.  Return NULL if at
1552   end of string.  */
1553static char *
1554next_sep_el (char **pstr, int sep, int par_flag)
1555{
1556  char *out_str;
1557  char *p;
1558  int pars_num;
1559  int n_spaces;
1560
1561  /* Remove leading whitespaces.  */
1562  while (ISSPACE ((int) **pstr))
1563    (*pstr)++;
1564
1565  if (**pstr == '\0')
1566    return NULL;
1567
1568  n_spaces = 0;
1569  for (pars_num = 0, p = *pstr; *p != '\0'; p++)
1570    {
1571      if (par_flag && *p == '(')
1572	pars_num++;
1573      else if (par_flag && *p == ')')
1574	pars_num--;
1575      else if (pars_num == 0 && *p == sep)
1576	break;
1577      if (pars_num == 0 && ISSPACE ((int) *p))
1578	n_spaces++;
1579      else
1580	{
1581	  for (; n_spaces != 0; n_spaces--)
1582	    obstack_1grow (&irp, p [-n_spaces]);
1583	  obstack_1grow (&irp, *p);
1584	}
1585    }
1586  obstack_1grow (&irp, '\0');
1587  out_str = obstack_base (&irp);
1588  obstack_finish (&irp);
1589
1590  *pstr = p;
1591  if (**pstr == sep)
1592    (*pstr)++;
1593
1594  return out_str;
1595}
1596
1597/* Given a string and a separator, return the number of separated
1598   elements in it, taking parentheses into account if PAR_FLAG has
1599   nonzero value.  Return 0 for the null string, -1 if parentheses is
1600   not balanced.  */
1601static int
1602n_sep_els (char *s, int sep, int par_flag)
1603{
1604  int n;
1605  int pars_num;
1606
1607  if (*s == '\0')
1608    return 0;
1609
1610  for (pars_num = 0, n = 1; *s; s++)
1611    if (par_flag && *s == '(')
1612      pars_num++;
1613    else if (par_flag && *s == ')')
1614      pars_num--;
1615    else if (pars_num == 0 && *s == sep)
1616      n++;
1617
1618  return (pars_num != 0 ? -1 : n);
1619}
1620
1621/* Given a string and a separator, return vector of strings which are
1622   elements in the string and number of elements through els_num.
1623   Take parentheses into account if PAREN_P has nonzero value.  The
1624   function also inserts the end marker NULL at the end of vector.
1625   Return 0 for the null string, -1 if parentheses are not balanced.  */
1626static char **
1627get_str_vect (char *str, int *els_num, int sep, int paren_p)
1628{
1629  int i;
1630  char **vect;
1631  char **pstr;
1632
1633  *els_num = n_sep_els (str, sep, paren_p);
1634  if (*els_num <= 0)
1635    return NULL;
1636  obstack_blank (&irp, sizeof (char *) * (*els_num + 1));
1637  vect = (char **) obstack_base (&irp);
1638  obstack_finish (&irp);
1639  pstr = &str;
1640  for (i = 0; i < *els_num; i++)
1641    vect [i] = next_sep_el (pstr, sep, paren_p);
1642  if (next_sep_el (pstr, sep, paren_p) != NULL)
1643    abort ();
1644  vect [i] = NULL;
1645  return vect;
1646}
1647
1648/* Process a DEFINE_CPU_UNIT.
1649
1650   This gives information about a unit contained in CPU.  We fill a
1651   struct unit_decl with information used later by `expand_automata'.  */
1652void
1653gen_cpu_unit (rtx def)
1654{
1655  decl_t decl;
1656  char **str_cpu_units;
1657  int vect_length;
1658  int i;
1659
1660  str_cpu_units = get_str_vect ((char *) XSTR (def, 0), &vect_length, ',',
1661				FALSE);
1662  if (str_cpu_units == NULL)
1663    fatal ("invalid string `%s' in define_cpu_unit", XSTR (def, 0));
1664  for (i = 0; i < vect_length; i++)
1665    {
1666      decl = create_node (sizeof (struct decl));
1667      decl->mode = dm_unit;
1668      decl->pos = 0;
1669      DECL_UNIT (decl)->name = check_name (str_cpu_units [i], decl->pos);
1670      DECL_UNIT (decl)->automaton_name = (char *) XSTR (def, 1);
1671      DECL_UNIT (decl)->query_p = 0;
1672      DECL_UNIT (decl)->min_occ_cycle_num = -1;
1673      DECL_UNIT (decl)->in_set_p = 0;
1674      VLA_PTR_ADD (decls, decl);
1675      num_dfa_decls++;
1676    }
1677}
1678
1679/* Process a DEFINE_QUERY_CPU_UNIT.
1680
1681   This gives information about a unit contained in CPU.  We fill a
1682   struct unit_decl with information used later by `expand_automata'.  */
1683void
1684gen_query_cpu_unit (rtx def)
1685{
1686  decl_t decl;
1687  char **str_cpu_units;
1688  int vect_length;
1689  int i;
1690
1691  str_cpu_units = get_str_vect ((char *) XSTR (def, 0), &vect_length, ',',
1692				FALSE);
1693  if (str_cpu_units == NULL)
1694    fatal ("invalid string `%s' in define_query_cpu_unit", XSTR (def, 0));
1695  for (i = 0; i < vect_length; i++)
1696    {
1697      decl = create_node (sizeof (struct decl));
1698      decl->mode = dm_unit;
1699      decl->pos = 0;
1700      DECL_UNIT (decl)->name = check_name (str_cpu_units [i], decl->pos);
1701      DECL_UNIT (decl)->automaton_name = (char *) XSTR (def, 1);
1702      DECL_UNIT (decl)->query_p = 1;
1703      VLA_PTR_ADD (decls, decl);
1704      num_dfa_decls++;
1705    }
1706}
1707
1708/* Process a DEFINE_BYPASS.
1709
1710   This gives information about a unit contained in the CPU.  We fill
1711   in a struct bypass_decl with information used later by
1712   `expand_automata'.  */
1713void
1714gen_bypass (rtx def)
1715{
1716  decl_t decl;
1717  char **out_insns;
1718  int out_length;
1719  char **in_insns;
1720  int in_length;
1721  int i, j;
1722
1723  out_insns = get_str_vect ((char *) XSTR (def, 1), &out_length, ',', FALSE);
1724  if (out_insns == NULL)
1725    fatal ("invalid string `%s' in define_bypass", XSTR (def, 1));
1726  in_insns = get_str_vect ((char *) XSTR (def, 2), &in_length, ',', FALSE);
1727  if (in_insns == NULL)
1728    fatal ("invalid string `%s' in define_bypass", XSTR (def, 2));
1729  for (i = 0; i < out_length; i++)
1730    for (j = 0; j < in_length; j++)
1731      {
1732	decl = create_node (sizeof (struct decl));
1733	decl->mode = dm_bypass;
1734	decl->pos = 0;
1735	DECL_BYPASS (decl)->latency = XINT (def, 0);
1736	DECL_BYPASS (decl)->out_insn_name = out_insns [i];
1737	DECL_BYPASS (decl)->in_insn_name = in_insns [j];
1738	DECL_BYPASS (decl)->bypass_guard_name = (char *) XSTR (def, 3);
1739	VLA_PTR_ADD (decls, decl);
1740	num_dfa_decls++;
1741      }
1742}
1743
1744/* Process an EXCLUSION_SET.
1745
1746   This gives information about a cpu unit conflicts.  We fill a
1747   struct excl_rel_decl (excl) with information used later by
1748   `expand_automata'.  */
1749void
1750gen_excl_set (rtx def)
1751{
1752  decl_t decl;
1753  char **first_str_cpu_units;
1754  char **second_str_cpu_units;
1755  int first_vect_length;
1756  int length;
1757  int i;
1758
1759  first_str_cpu_units
1760    = get_str_vect ((char *) XSTR (def, 0), &first_vect_length, ',', FALSE);
1761  if (first_str_cpu_units == NULL)
1762    fatal ("invalid first string `%s' in exclusion_set", XSTR (def, 0));
1763  second_str_cpu_units = get_str_vect ((char *) XSTR (def, 1), &length, ',',
1764				       FALSE);
1765  if (second_str_cpu_units == NULL)
1766    fatal ("invalid second string `%s' in exclusion_set", XSTR (def, 1));
1767  length += first_vect_length;
1768  decl = create_node (sizeof (struct decl) + (length - 1) * sizeof (char *));
1769  decl->mode = dm_excl;
1770  decl->pos = 0;
1771  DECL_EXCL (decl)->all_names_num = length;
1772  DECL_EXCL (decl)->first_list_length = first_vect_length;
1773  for (i = 0; i < length; i++)
1774    if (i < first_vect_length)
1775      DECL_EXCL (decl)->names [i] = first_str_cpu_units [i];
1776    else
1777      DECL_EXCL (decl)->names [i]
1778	= second_str_cpu_units [i - first_vect_length];
1779  VLA_PTR_ADD (decls, decl);
1780  num_dfa_decls++;
1781}
1782
1783/* Process a PRESENCE_SET, a FINAL_PRESENCE_SET, an ABSENCE_SET,
1784   FINAL_ABSENCE_SET (it is depended on PRESENCE_P and FINAL_P).
1785
1786   This gives information about a cpu unit reservation requirements.
1787   We fill a struct unit_pattern_rel_decl with information used later
1788   by `expand_automata'.  */
1789static void
1790gen_presence_absence_set (rtx def, int presence_p, int final_p)
1791{
1792  decl_t decl;
1793  char **str_cpu_units;
1794  char ***str_patterns;
1795  int cpu_units_length;
1796  int length;
1797  int patterns_length;
1798  int i;
1799
1800  str_cpu_units = get_str_vect ((char *) XSTR (def, 0), &cpu_units_length, ',',
1801				FALSE);
1802  if (str_cpu_units == NULL)
1803    fatal ((presence_p
1804	    ? (final_p
1805	       ? "invalid first string `%s' in final_presence_set"
1806	       : "invalid first string `%s' in presence_set")
1807	    : (final_p
1808	       ? "invalid first string `%s' in final_absence_set"
1809	       : "invalid first string `%s' in absence_set")),
1810	   XSTR (def, 0));
1811  str_patterns = (char ***) get_str_vect ((char *) XSTR (def, 1),
1812					  &patterns_length, ',', FALSE);
1813  if (str_patterns == NULL)
1814    fatal ((presence_p
1815	    ? (final_p
1816	       ? "invalid second string `%s' in final_presence_set"
1817	       : "invalid second string `%s' in presence_set")
1818	    : (final_p
1819	       ? "invalid second string `%s' in final_absence_set"
1820	       : "invalid second string `%s' in absence_set")), XSTR (def, 1));
1821  for (i = 0; i < patterns_length; i++)
1822    {
1823      str_patterns [i] = get_str_vect ((char *) str_patterns [i], &length, ' ',
1824				       FALSE);
1825      if (str_patterns [i] == NULL)
1826	abort ();
1827    }
1828  decl = create_node (sizeof (struct decl));
1829  decl->pos = 0;
1830  if (presence_p)
1831    {
1832      decl->mode = dm_presence;
1833      DECL_PRESENCE (decl)->names_num = cpu_units_length;
1834      DECL_PRESENCE (decl)->names = str_cpu_units;
1835      DECL_PRESENCE (decl)->patterns = str_patterns;
1836      DECL_PRESENCE (decl)->patterns_num = patterns_length;
1837      DECL_PRESENCE (decl)->final_p = final_p;
1838    }
1839  else
1840    {
1841      decl->mode = dm_absence;
1842      DECL_ABSENCE (decl)->names_num = cpu_units_length;
1843      DECL_ABSENCE (decl)->names = str_cpu_units;
1844      DECL_ABSENCE (decl)->patterns = str_patterns;
1845      DECL_ABSENCE (decl)->patterns_num = patterns_length;
1846      DECL_ABSENCE (decl)->final_p = final_p;
1847    }
1848  VLA_PTR_ADD (decls, decl);
1849  num_dfa_decls++;
1850}
1851
1852/* Process a PRESENCE_SET.
1853
1854    This gives information about a cpu unit reservation requirements.
1855   We fill a struct unit_pattern_rel_decl (presence) with information
1856   used later by `expand_automata'.  */
1857void
1858gen_presence_set (rtx def)
1859{
1860  gen_presence_absence_set (def, TRUE, FALSE);
1861}
1862
1863/* Process a FINAL_PRESENCE_SET.
1864
1865   This gives information about a cpu unit reservation requirements.
1866   We fill a struct unit_pattern_rel_decl (presence) with information
1867   used later by `expand_automata'.  */
1868void
1869gen_final_presence_set (rtx def)
1870{
1871  gen_presence_absence_set (def, TRUE, TRUE);
1872}
1873
1874/* Process an ABSENCE_SET.
1875
1876   This gives information about a cpu unit reservation requirements.
1877   We fill a struct unit_pattern_rel_decl (absence) with information
1878   used later by `expand_automata'.  */
1879void
1880gen_absence_set (rtx def)
1881{
1882  gen_presence_absence_set (def, FALSE, FALSE);
1883}
1884
1885/* Process a FINAL_ABSENCE_SET.
1886
1887   This gives information about a cpu unit reservation requirements.
1888   We fill a struct unit_pattern_rel_decl (absence) with information
1889   used later by `expand_automata'.  */
1890void
1891gen_final_absence_set (rtx def)
1892{
1893  gen_presence_absence_set (def, FALSE, TRUE);
1894}
1895
1896/* Process a DEFINE_AUTOMATON.
1897
1898   This gives information about a finite state automaton used for
1899   recognizing pipeline hazards.  We fill a struct automaton_decl
1900   with information used later by `expand_automata'.  */
1901void
1902gen_automaton (rtx def)
1903{
1904  decl_t decl;
1905  char **str_automata;
1906  int vect_length;
1907  int i;
1908
1909  str_automata = get_str_vect ((char *) XSTR (def, 0), &vect_length, ',',
1910			       FALSE);
1911  if (str_automata == NULL)
1912    fatal ("invalid string `%s' in define_automaton", XSTR (def, 0));
1913  for (i = 0; i < vect_length; i++)
1914    {
1915      decl = create_node (sizeof (struct decl));
1916      decl->mode = dm_automaton;
1917      decl->pos = 0;
1918      DECL_AUTOMATON (decl)->name = check_name (str_automata [i], decl->pos);
1919      VLA_PTR_ADD (decls, decl);
1920      num_dfa_decls++;
1921    }
1922}
1923
1924/* Process an AUTOMATA_OPTION.
1925
1926   This gives information how to generate finite state automaton used
1927   for recognizing pipeline hazards.  */
1928void
1929gen_automata_option (rtx def)
1930{
1931  if (strcmp (XSTR (def, 0), NO_MINIMIZATION_OPTION + 1) == 0)
1932    no_minimization_flag = 1;
1933  else if (strcmp (XSTR (def, 0), TIME_OPTION + 1) == 0)
1934    time_flag = 1;
1935  else if (strcmp (XSTR (def, 0), V_OPTION + 1) == 0)
1936    v_flag = 1;
1937  else if (strcmp (XSTR (def, 0), W_OPTION + 1) == 0)
1938    w_flag = 1;
1939  else if (strcmp (XSTR (def, 0), NDFA_OPTION + 1) == 0)
1940    ndfa_flag = 1;
1941  else if (strcmp (XSTR (def, 0), PROGRESS_OPTION + 1) == 0)
1942    progress_flag = 1;
1943  else
1944    fatal ("invalid option `%s' in automata_option", XSTR (def, 0));
1945}
1946
1947/* Name in reservation to denote absence reservation.  */
1948#define NOTHING_NAME "nothing"
1949
1950/* The following string contains original reservation string being
1951   parsed.  */
1952static char *reserv_str;
1953
1954/* Parse an element in STR.  */
1955static regexp_t
1956gen_regexp_el (char *str)
1957{
1958  regexp_t regexp;
1959  int len;
1960
1961  if (*str == '(')
1962    {
1963      len = strlen (str);
1964      if (str [len - 1] != ')')
1965	fatal ("garbage after ) in reservation `%s'", reserv_str);
1966      str [len - 1] = '\0';
1967      regexp = gen_regexp_sequence (str + 1);
1968    }
1969  else if (strcmp (str, NOTHING_NAME) == 0)
1970    {
1971      regexp = create_node (sizeof (struct decl));
1972      regexp->mode = rm_nothing;
1973    }
1974  else
1975    {
1976      regexp = create_node (sizeof (struct decl));
1977      regexp->mode = rm_unit;
1978      REGEXP_UNIT (regexp)->name = str;
1979    }
1980  return regexp;
1981}
1982
1983/* Parse construction `repeat' in STR.  */
1984static regexp_t
1985gen_regexp_repeat (char *str)
1986{
1987  regexp_t regexp;
1988  regexp_t repeat;
1989  char **repeat_vect;
1990  int els_num;
1991  int i;
1992
1993  repeat_vect = get_str_vect (str, &els_num, '*', TRUE);
1994  if (repeat_vect == NULL)
1995    fatal ("invalid `%s' in reservation `%s'", str, reserv_str);
1996  if (els_num > 1)
1997    {
1998      regexp = gen_regexp_el (repeat_vect [0]);
1999      for (i = 1; i < els_num; i++)
2000	{
2001	  repeat = create_node (sizeof (struct regexp));
2002	  repeat->mode = rm_repeat;
2003	  REGEXP_REPEAT (repeat)->regexp = regexp;
2004	  REGEXP_REPEAT (repeat)->repeat_num = atoi (repeat_vect [i]);
2005          if (REGEXP_REPEAT (repeat)->repeat_num <= 1)
2006            fatal ("repetition `%s' <= 1 in reservation `%s'",
2007                   str, reserv_str);
2008          regexp = repeat;
2009	}
2010      return regexp;
2011    }
2012  else
2013    return gen_regexp_el (str);
2014}
2015
2016/* Parse reservation STR which possibly contains separator '+'.  */
2017static regexp_t
2018gen_regexp_allof (char *str)
2019{
2020  regexp_t allof;
2021  char **allof_vect;
2022  int els_num;
2023  int i;
2024
2025  allof_vect = get_str_vect (str, &els_num, '+', TRUE);
2026  if (allof_vect == NULL)
2027    fatal ("invalid `%s' in reservation `%s'", str, reserv_str);
2028  if (els_num > 1)
2029    {
2030      allof = create_node (sizeof (struct regexp)
2031			   + sizeof (regexp_t) * (els_num - 1));
2032      allof->mode = rm_allof;
2033      REGEXP_ALLOF (allof)->regexps_num = els_num;
2034      for (i = 0; i < els_num; i++)
2035	REGEXP_ALLOF (allof)->regexps [i] = gen_regexp_repeat (allof_vect [i]);
2036      return allof;
2037    }
2038  else
2039    return gen_regexp_repeat (str);
2040}
2041
2042/* Parse reservation STR which possibly contains separator '|'.  */
2043static regexp_t
2044gen_regexp_oneof (char *str)
2045{
2046  regexp_t oneof;
2047  char **oneof_vect;
2048  int els_num;
2049  int i;
2050
2051  oneof_vect = get_str_vect (str, &els_num, '|', TRUE);
2052  if (oneof_vect == NULL)
2053    fatal ("invalid `%s' in reservation `%s'", str, reserv_str);
2054  if (els_num > 1)
2055    {
2056      oneof = create_node (sizeof (struct regexp)
2057			   + sizeof (regexp_t) * (els_num - 1));
2058      oneof->mode = rm_oneof;
2059      REGEXP_ONEOF (oneof)->regexps_num = els_num;
2060      for (i = 0; i < els_num; i++)
2061	REGEXP_ONEOF (oneof)->regexps [i] = gen_regexp_allof (oneof_vect [i]);
2062      return oneof;
2063    }
2064  else
2065    return gen_regexp_allof (str);
2066}
2067
2068/* Parse reservation STR which possibly contains separator ','.  */
2069static regexp_t
2070gen_regexp_sequence (char *str)
2071{
2072  regexp_t sequence;
2073  char **sequence_vect;
2074  int els_num;
2075  int i;
2076
2077  sequence_vect = get_str_vect (str, &els_num, ',', TRUE);
2078  if (els_num > 1)
2079    {
2080      sequence = create_node (sizeof (struct regexp)
2081			      + sizeof (regexp_t) * (els_num - 1));
2082      sequence->mode = rm_sequence;
2083      REGEXP_SEQUENCE (sequence)->regexps_num = els_num;
2084      for (i = 0; i < els_num; i++)
2085	REGEXP_SEQUENCE (sequence)->regexps [i]
2086          = gen_regexp_oneof (sequence_vect [i]);
2087      return sequence;
2088    }
2089  else
2090    return gen_regexp_oneof (str);
2091}
2092
2093/* Parse construction reservation STR.  */
2094static regexp_t
2095gen_regexp (char *str)
2096{
2097  reserv_str = str;
2098  return gen_regexp_sequence (str);;
2099}
2100
2101/* Process a DEFINE_RESERVATION.
2102
2103   This gives information about a reservation of cpu units.  We fill
2104   in a struct reserv_decl with information used later by
2105   `expand_automata'.  */
2106void
2107gen_reserv (rtx def)
2108{
2109  decl_t decl;
2110
2111  decl = create_node (sizeof (struct decl));
2112  decl->mode = dm_reserv;
2113  decl->pos = 0;
2114  DECL_RESERV (decl)->name = check_name ((char *) XSTR (def, 0), decl->pos);
2115  DECL_RESERV (decl)->regexp = gen_regexp ((char *) XSTR (def, 1));
2116  VLA_PTR_ADD (decls, decl);
2117  num_dfa_decls++;
2118}
2119
2120/* Process a DEFINE_INSN_RESERVATION.
2121
2122   This gives information about the reservation of cpu units by an
2123   insn.  We fill a struct insn_reserv_decl with information used
2124   later by `expand_automata'.  */
2125void
2126gen_insn_reserv (rtx def)
2127{
2128  decl_t decl;
2129
2130  decl = create_node (sizeof (struct decl));
2131  decl->mode = dm_insn_reserv;
2132  decl->pos = 0;
2133  DECL_INSN_RESERV (decl)->name
2134    = check_name ((char *) XSTR (def, 0), decl->pos);
2135  DECL_INSN_RESERV (decl)->default_latency = XINT (def, 1);
2136  DECL_INSN_RESERV (decl)->condexp = XEXP (def, 2);
2137  DECL_INSN_RESERV (decl)->regexp = gen_regexp ((char *) XSTR (def, 3));
2138  VLA_PTR_ADD (decls, decl);
2139  num_dfa_decls++;
2140}
2141
2142
2143
2144/* The function evaluates hash value (0..UINT_MAX) of string.  */
2145static unsigned
2146string_hash (const char *string)
2147{
2148  unsigned result, i;
2149
2150  for (result = i = 0;*string++ != '\0'; i++)
2151    result += ((unsigned char) *string << (i % CHAR_BIT));
2152  return result;
2153}
2154
2155
2156
2157/* This page contains abstract data `table of automaton declarations'.
2158   Elements of the table is nodes representing automaton declarations.
2159   Key of the table elements is name of given automaton.  Remember
2160   that automaton names have own space.  */
2161
2162/* The function evaluates hash value of an automaton declaration.  The
2163   function is used by abstract data `hashtab'.  The function returns
2164   hash value (0..UINT_MAX) of given automaton declaration.  */
2165static hashval_t
2166automaton_decl_hash (const void *automaton_decl)
2167{
2168  const decl_t decl = (decl_t) automaton_decl;
2169
2170  if (decl->mode == dm_automaton && DECL_AUTOMATON (decl)->name == NULL)
2171    abort ();
2172  return string_hash (DECL_AUTOMATON (decl)->name);
2173}
2174
2175/* The function tests automaton declarations on equality of their
2176   keys.  The function is used by abstract data `hashtab'.  The
2177   function returns 1 if the declarations have the same key, 0
2178   otherwise.  */
2179static int
2180automaton_decl_eq_p (const void* automaton_decl_1,
2181		     const void* automaton_decl_2)
2182{
2183  const decl_t decl1 = (decl_t) automaton_decl_1;
2184  const decl_t decl2 = (decl_t) automaton_decl_2;
2185
2186  if (decl1->mode != dm_automaton || DECL_AUTOMATON (decl1)->name == NULL
2187      || decl2->mode != dm_automaton || DECL_AUTOMATON (decl2)->name == NULL)
2188    abort ();
2189  return strcmp (DECL_AUTOMATON (decl1)->name,
2190		 DECL_AUTOMATON (decl2)->name) == 0;
2191}
2192
2193/* The automaton declaration table itself is represented by the
2194   following variable.  */
2195static htab_t automaton_decl_table;
2196
2197/* The function inserts automaton declaration into the table.  The
2198   function does nothing if an automaton declaration with the same key
2199   exists already in the table.  The function returns automaton
2200   declaration node in the table with the same key as given automaton
2201   declaration node.  */
2202static decl_t
2203insert_automaton_decl (decl_t automaton_decl)
2204{
2205  void **entry_ptr;
2206
2207  entry_ptr = htab_find_slot (automaton_decl_table, automaton_decl, 1);
2208  if (*entry_ptr == NULL)
2209    *entry_ptr = (void *) automaton_decl;
2210  return (decl_t) *entry_ptr;
2211}
2212
2213/* The following variable value is node representing automaton
2214   declaration.  The node used for searching automaton declaration
2215   with given name.  */
2216static struct decl work_automaton_decl;
2217
2218/* The function searches for automaton declaration in the table with
2219   the same key as node representing name of the automaton
2220   declaration.  The function returns node found in the table, NULL if
2221   such node does not exist in the table.  */
2222static decl_t
2223find_automaton_decl (char *name)
2224{
2225  void *entry;
2226
2227  work_automaton_decl.mode = dm_automaton;
2228  DECL_AUTOMATON (&work_automaton_decl)->name = name;
2229  entry = htab_find (automaton_decl_table, &work_automaton_decl);
2230  return (decl_t) entry;
2231}
2232
2233/* The function creates empty automaton declaration table and node
2234   representing automaton declaration and used for searching automaton
2235   declaration with given name.  The function must be called only once
2236   before any work with the automaton declaration table.  */
2237static void
2238initiate_automaton_decl_table (void)
2239{
2240  work_automaton_decl.mode = dm_automaton;
2241  automaton_decl_table = htab_create (10, automaton_decl_hash,
2242				      automaton_decl_eq_p, (htab_del) 0);
2243}
2244
2245/* The function deletes the automaton declaration table.  Only call of
2246   function `initiate_automaton_decl_table' is possible immediately
2247   after this function call.  */
2248static void
2249finish_automaton_decl_table (void)
2250{
2251  htab_delete (automaton_decl_table);
2252}
2253
2254
2255
2256/* This page contains abstract data `table of insn declarations'.
2257   Elements of the table is nodes representing insn declarations.  Key
2258   of the table elements is name of given insn (in corresponding
2259   define_insn_reservation).  Remember that insn names have own
2260   space.  */
2261
2262/* The function evaluates hash value of an insn declaration.  The
2263   function is used by abstract data `hashtab'.  The function returns
2264   hash value (0..UINT_MAX) of given insn declaration.  */
2265static hashval_t
2266insn_decl_hash (const void *insn_decl)
2267{
2268  const decl_t decl = (decl_t) insn_decl;
2269
2270  if (decl->mode != dm_insn_reserv || DECL_INSN_RESERV (decl)->name == NULL)
2271    abort ();
2272  return string_hash (DECL_INSN_RESERV (decl)->name);
2273}
2274
2275/* The function tests insn declarations on equality of their keys.
2276   The function is used by abstract data `hashtab'.  The function
2277   returns 1 if declarations have the same key, 0 otherwise.  */
2278static int
2279insn_decl_eq_p (const void *insn_decl_1, const void *insn_decl_2)
2280{
2281  const decl_t decl1 = (decl_t) insn_decl_1;
2282  const decl_t decl2 = (decl_t) insn_decl_2;
2283
2284  if (decl1->mode != dm_insn_reserv || DECL_INSN_RESERV (decl1)->name == NULL
2285      || decl2->mode != dm_insn_reserv
2286      || DECL_INSN_RESERV (decl2)->name == NULL)
2287    abort ();
2288  return strcmp (DECL_INSN_RESERV (decl1)->name,
2289                 DECL_INSN_RESERV (decl2)->name) == 0;
2290}
2291
2292/* The insn declaration table itself is represented by the following
2293   variable.  The table does not contain insn reservation
2294   declarations.  */
2295static htab_t insn_decl_table;
2296
2297/* The function inserts insn declaration into the table.  The function
2298   does nothing if an insn declaration with the same key exists
2299   already in the table.  The function returns insn declaration node
2300   in the table with the same key as given insn declaration node.  */
2301static decl_t
2302insert_insn_decl (decl_t insn_decl)
2303{
2304  void **entry_ptr;
2305
2306  entry_ptr = htab_find_slot (insn_decl_table, insn_decl, 1);
2307  if (*entry_ptr == NULL)
2308    *entry_ptr = (void *) insn_decl;
2309  return (decl_t) *entry_ptr;
2310}
2311
2312/* The following variable value is node representing insn reservation
2313   declaration.  The node used for searching insn reservation
2314   declaration with given name.  */
2315static struct decl work_insn_decl;
2316
2317/* The function searches for insn reservation declaration in the table
2318   with the same key as node representing name of the insn reservation
2319   declaration.  The function returns node found in the table, NULL if
2320   such node does not exist in the table.  */
2321static decl_t
2322find_insn_decl (char *name)
2323{
2324  void *entry;
2325
2326  work_insn_decl.mode = dm_insn_reserv;
2327  DECL_INSN_RESERV (&work_insn_decl)->name = name;
2328  entry = htab_find (insn_decl_table, &work_insn_decl);
2329  return (decl_t) entry;
2330}
2331
2332/* The function creates empty insn declaration table and node
2333   representing insn declaration and used for searching insn
2334   declaration with given name.  The function must be called only once
2335   before any work with the insn declaration table.  */
2336static void
2337initiate_insn_decl_table (void)
2338{
2339  work_insn_decl.mode = dm_insn_reserv;
2340  insn_decl_table = htab_create (10, insn_decl_hash, insn_decl_eq_p,
2341				 (htab_del) 0);
2342}
2343
2344/* The function deletes the insn declaration table.  Only call of
2345   function `initiate_insn_decl_table' is possible immediately after
2346   this function call.  */
2347static void
2348finish_insn_decl_table (void)
2349{
2350  htab_delete (insn_decl_table);
2351}
2352
2353
2354
2355/* This page contains abstract data `table of declarations'.  Elements
2356   of the table is nodes representing declarations (of units and
2357   reservations).  Key of the table elements is names of given
2358   declarations.  */
2359
2360/* The function evaluates hash value of a declaration.  The function
2361   is used by abstract data `hashtab'.  The function returns hash
2362   value (0..UINT_MAX) of given declaration.  */
2363static hashval_t
2364decl_hash (const void *decl)
2365{
2366  const decl_t d = (const decl_t) decl;
2367
2368  if ((d->mode != dm_unit || DECL_UNIT (d)->name == NULL)
2369      && (d->mode != dm_reserv || DECL_RESERV (d)->name == NULL))
2370    abort ();
2371  return string_hash (d->mode == dm_unit
2372		      ? DECL_UNIT (d)->name : DECL_RESERV (d)->name);
2373}
2374
2375/* The function tests declarations on equality of their keys.  The
2376   function is used by abstract data `hashtab'.  The function
2377   returns 1 if the declarations have the same key, 0 otherwise.  */
2378static int
2379decl_eq_p (const void *decl_1, const void *decl_2)
2380{
2381  const decl_t d1 = (const decl_t) decl_1;
2382  const decl_t d2 = (const decl_t) decl_2;
2383
2384  if (((d1->mode != dm_unit || DECL_UNIT (d1)->name == NULL)
2385       && (d1->mode != dm_reserv || DECL_RESERV (d1)->name == NULL))
2386      || ((d2->mode != dm_unit || DECL_UNIT (d2)->name == NULL)
2387	  && (d2->mode != dm_reserv || DECL_RESERV (d2)->name == NULL)))
2388    abort ();
2389  return strcmp ((d1->mode == dm_unit
2390                  ? DECL_UNIT (d1)->name : DECL_RESERV (d1)->name),
2391                 (d2->mode == dm_unit
2392                  ? DECL_UNIT (d2)->name : DECL_RESERV (d2)->name)) == 0;
2393}
2394
2395/* The declaration table itself is represented by the following
2396   variable.  */
2397static htab_t decl_table;
2398
2399/* The function inserts declaration into the table.  The function does
2400   nothing if a declaration with the same key exists already in the
2401   table.  The function returns declaration node in the table with the
2402   same key as given declaration node.  */
2403
2404static decl_t
2405insert_decl (decl_t decl)
2406{
2407  void **entry_ptr;
2408
2409  entry_ptr = htab_find_slot (decl_table, decl, 1);
2410  if (*entry_ptr == NULL)
2411    *entry_ptr = (void *) decl;
2412  return (decl_t) *entry_ptr;
2413}
2414
2415/* The following variable value is node representing declaration.  The
2416   node used for searching declaration with given name.  */
2417static struct decl work_decl;
2418
2419/* The function searches for declaration in the table with the same
2420   key as node representing name of the declaration.  The function
2421   returns node found in the table, NULL if such node does not exist
2422   in the table.  */
2423static decl_t
2424find_decl (char *name)
2425{
2426  void *entry;
2427
2428  work_decl.mode = dm_unit;
2429  DECL_UNIT (&work_decl)->name = name;
2430  entry = htab_find (decl_table, &work_decl);
2431  return (decl_t) entry;
2432}
2433
2434/* The function creates empty declaration table and node representing
2435   declaration and used for searching declaration with given name.
2436   The function must be called only once before any work with the
2437   declaration table.  */
2438static void
2439initiate_decl_table (void)
2440{
2441  work_decl.mode = dm_unit;
2442  decl_table = htab_create (10, decl_hash, decl_eq_p, (htab_del) 0);
2443}
2444
2445/* The function deletes the declaration table.  Only call of function
2446   `initiate_declaration_table' is possible immediately after this
2447   function call.  */
2448static void
2449finish_decl_table (void)
2450{
2451  htab_delete (decl_table);
2452}
2453
2454
2455
2456/* This page contains checker of pipeline hazard description.  */
2457
2458/* Checking NAMES in an exclusion clause vector and returning formed
2459   unit_set_el_list.  */
2460static unit_set_el_t
2461process_excls (char **names, int num, pos_t excl_pos ATTRIBUTE_UNUSED)
2462{
2463  unit_set_el_t el_list;
2464  unit_set_el_t last_el;
2465  unit_set_el_t new_el;
2466  decl_t decl_in_table;
2467  int i;
2468
2469  el_list = NULL;
2470  last_el = NULL;
2471  for (i = 0; i < num; i++)
2472    {
2473      decl_in_table = find_decl (names [i]);
2474      if (decl_in_table == NULL)
2475	error ("unit `%s' in exclusion is not declared", names [i]);
2476      else if (decl_in_table->mode != dm_unit)
2477	error ("`%s' in exclusion is not unit", names [i]);
2478      else
2479	{
2480	  new_el = create_node (sizeof (struct unit_set_el));
2481	  new_el->unit_decl = DECL_UNIT (decl_in_table);
2482	  new_el->next_unit_set_el = NULL;
2483	  if (last_el == NULL)
2484	    el_list = last_el = new_el;
2485	  else
2486	    {
2487	      last_el->next_unit_set_el = new_el;
2488	      last_el = last_el->next_unit_set_el;
2489	    }
2490	}
2491    }
2492  return el_list;
2493}
2494
2495/* The function adds each element from SOURCE_LIST to the exclusion
2496   list of the each element from DEST_LIST.  Checking situation "unit
2497   excludes itself".  */
2498static void
2499add_excls (unit_set_el_t dest_list, unit_set_el_t source_list,
2500	   pos_t excl_pos ATTRIBUTE_UNUSED)
2501{
2502  unit_set_el_t dst;
2503  unit_set_el_t src;
2504  unit_set_el_t curr_el;
2505  unit_set_el_t prev_el;
2506  unit_set_el_t copy;
2507
2508  for (dst = dest_list; dst != NULL; dst = dst->next_unit_set_el)
2509    for (src = source_list; src != NULL; src = src->next_unit_set_el)
2510      {
2511	if (dst->unit_decl == src->unit_decl)
2512	  {
2513	    error ("unit `%s' excludes itself", src->unit_decl->name);
2514	    continue;
2515	  }
2516	if (dst->unit_decl->automaton_name != NULL
2517	    && src->unit_decl->automaton_name != NULL
2518	    && strcmp (dst->unit_decl->automaton_name,
2519		       src->unit_decl->automaton_name) != 0)
2520	  {
2521	    error ("units `%s' and `%s' in exclusion set belong to different automata",
2522		   src->unit_decl->name, dst->unit_decl->name);
2523	    continue;
2524	  }
2525	for (curr_el = dst->unit_decl->excl_list, prev_el = NULL;
2526	     curr_el != NULL;
2527	     prev_el = curr_el, curr_el = curr_el->next_unit_set_el)
2528	  if (curr_el->unit_decl == src->unit_decl)
2529	    break;
2530	if (curr_el == NULL)
2531	  {
2532	    /* Element not found - insert.  */
2533	    copy = copy_node (src, sizeof (*src));
2534	    copy->next_unit_set_el = NULL;
2535	    if (prev_el == NULL)
2536	      dst->unit_decl->excl_list = copy;
2537	    else
2538	      prev_el->next_unit_set_el = copy;
2539	}
2540    }
2541}
2542
2543/* Checking NAMES in presence/absence clause and returning the
2544   formed unit_set_el_list.  The function is called only after
2545   processing all exclusion sets.  */
2546static unit_set_el_t
2547process_presence_absence_names (char **names, int num,
2548				pos_t req_pos ATTRIBUTE_UNUSED,
2549				int presence_p, int final_p)
2550{
2551  unit_set_el_t el_list;
2552  unit_set_el_t last_el;
2553  unit_set_el_t new_el;
2554  decl_t decl_in_table;
2555  int i;
2556
2557  el_list = NULL;
2558  last_el = NULL;
2559  for (i = 0; i < num; i++)
2560    {
2561      decl_in_table = find_decl (names [i]);
2562      if (decl_in_table == NULL)
2563	error ((presence_p
2564		? (final_p
2565		   ? "unit `%s' in final presence set is not declared"
2566		   : "unit `%s' in presence set is not declared")
2567		: (final_p
2568		   ? "unit `%s' in final absence set is not declared"
2569		   : "unit `%s' in absence set is not declared")), names [i]);
2570      else if (decl_in_table->mode != dm_unit)
2571	error ((presence_p
2572		? (final_p
2573		   ? "`%s' in final presence set is not unit"
2574		   : "`%s' in presence set is not unit")
2575		: (final_p
2576		   ? "`%s' in final absence set is not unit"
2577		   : "`%s' in absence set is not unit")), names [i]);
2578      else
2579	{
2580	  new_el = create_node (sizeof (struct unit_set_el));
2581	  new_el->unit_decl = DECL_UNIT (decl_in_table);
2582	  new_el->next_unit_set_el = NULL;
2583	  if (last_el == NULL)
2584	    el_list = last_el = new_el;
2585	  else
2586	    {
2587	      last_el->next_unit_set_el = new_el;
2588	      last_el = last_el->next_unit_set_el;
2589	    }
2590	}
2591    }
2592  return el_list;
2593}
2594
2595/* Checking NAMES in patterns of a presence/absence clause and
2596   returning the formed pattern_set_el_list.  The function is called
2597   only after processing all exclusion sets.  */
2598static pattern_set_el_t
2599process_presence_absence_patterns (char ***patterns, int num,
2600				   pos_t req_pos ATTRIBUTE_UNUSED,
2601				   int presence_p, int final_p)
2602{
2603  pattern_set_el_t el_list;
2604  pattern_set_el_t last_el;
2605  pattern_set_el_t new_el;
2606  decl_t decl_in_table;
2607  int i, j;
2608
2609  el_list = NULL;
2610  last_el = NULL;
2611  for (i = 0; i < num; i++)
2612    {
2613      for (j = 0; patterns [i] [j] != NULL; j++)
2614	;
2615      new_el = create_node (sizeof (struct pattern_set_el)
2616			    + sizeof (struct unit_decl *) * j);
2617      new_el->unit_decls
2618	= (struct unit_decl **) ((char *) new_el
2619				 + sizeof (struct pattern_set_el));
2620      new_el->next_pattern_set_el = NULL;
2621      if (last_el == NULL)
2622	el_list = last_el = new_el;
2623      else
2624	{
2625	  last_el->next_pattern_set_el = new_el;
2626	  last_el = last_el->next_pattern_set_el;
2627	}
2628      new_el->units_num = 0;
2629      for (j = 0; patterns [i] [j] != NULL; j++)
2630	{
2631	  decl_in_table = find_decl (patterns [i] [j]);
2632	  if (decl_in_table == NULL)
2633	    error ((presence_p
2634		    ? (final_p
2635		       ? "unit `%s' in final presence set is not declared"
2636		       : "unit `%s' in presence set is not declared")
2637		    : (final_p
2638		       ? "unit `%s' in final absence set is not declared"
2639		       : "unit `%s' in absence set is not declared")),
2640		   patterns [i] [j]);
2641	  else if (decl_in_table->mode != dm_unit)
2642	    error ((presence_p
2643		    ? (final_p
2644		       ? "`%s' in final presence set is not unit"
2645		       : "`%s' in presence set is not unit")
2646		    : (final_p
2647		       ? "`%s' in final absence set is not unit"
2648		       : "`%s' in absence set is not unit")),
2649		   patterns [i] [j]);
2650	  else
2651	    {
2652	      new_el->unit_decls [new_el->units_num]
2653		= DECL_UNIT (decl_in_table);
2654	      new_el->units_num++;
2655	    }
2656	}
2657    }
2658  return el_list;
2659}
2660
2661/* The function adds each element from PATTERN_LIST to presence (if
2662   PRESENCE_P) or absence list of the each element from DEST_LIST.
2663   Checking situations "unit requires own absence", and "unit excludes
2664   and requires presence of ...", "unit requires absence and presence
2665   of ...", "units in (final) presence set belong to different
2666   automata", and "units in (final) absence set belong to different
2667   automata".  Remember that we process absence sets only after all
2668   presence sets.  */
2669static void
2670add_presence_absence (unit_set_el_t dest_list,
2671		      pattern_set_el_t pattern_list,
2672		      pos_t req_pos ATTRIBUTE_UNUSED,
2673		      int presence_p, int final_p)
2674{
2675  unit_set_el_t dst;
2676  pattern_set_el_t pat;
2677  struct unit_decl *unit;
2678  unit_set_el_t curr_excl_el;
2679  pattern_set_el_t curr_pat_el;
2680  pattern_set_el_t prev_el;
2681  pattern_set_el_t copy;
2682  int i;
2683  int no_error_flag;
2684
2685  for (dst = dest_list; dst != NULL; dst = dst->next_unit_set_el)
2686    for (pat = pattern_list; pat != NULL; pat = pat->next_pattern_set_el)
2687      {
2688	for (i = 0; i < pat->units_num; i++)
2689	  {
2690	    unit = pat->unit_decls [i];
2691	    if (dst->unit_decl == unit && pat->units_num == 1 && !presence_p)
2692	      {
2693		error ("unit `%s' requires own absence", unit->name);
2694		continue;
2695	      }
2696	    if (dst->unit_decl->automaton_name != NULL
2697		&& unit->automaton_name != NULL
2698		&& strcmp (dst->unit_decl->automaton_name,
2699			   unit->automaton_name) != 0)
2700	      {
2701		error ((presence_p
2702			? (final_p
2703			   ? "units `%s' and `%s' in final presence set belong to different automata"
2704			   : "units `%s' and `%s' in presence set belong to different automata")
2705			: (final_p
2706			   ? "units `%s' and `%s' in final absence set belong to different automata"
2707			   : "units `%s' and `%s' in absence set belong to different automata")),
2708		       unit->name, dst->unit_decl->name);
2709		continue;
2710	      }
2711	    no_error_flag = 1;
2712	    if (presence_p)
2713	      for (curr_excl_el = dst->unit_decl->excl_list;
2714		   curr_excl_el != NULL;
2715		   curr_excl_el = curr_excl_el->next_unit_set_el)
2716		{
2717		  if (unit == curr_excl_el->unit_decl && pat->units_num == 1)
2718		    {
2719		      if (!w_flag)
2720			{
2721			  error ("unit `%s' excludes and requires presence of `%s'",
2722				 dst->unit_decl->name, unit->name);
2723			  no_error_flag = 0;
2724			}
2725		      else
2726			warning
2727			  ("unit `%s' excludes and requires presence of `%s'",
2728			   dst->unit_decl->name, unit->name);
2729		    }
2730		}
2731	    else if (pat->units_num == 1)
2732	      for (curr_pat_el = dst->unit_decl->presence_list;
2733		   curr_pat_el != NULL;
2734		   curr_pat_el = curr_pat_el->next_pattern_set_el)
2735		if (curr_pat_el->units_num == 1
2736		    && unit == curr_pat_el->unit_decls [0])
2737		  {
2738		    if (!w_flag)
2739		      {
2740			error
2741			  ("unit `%s' requires absence and presence of `%s'",
2742			   dst->unit_decl->name, unit->name);
2743			no_error_flag = 0;
2744		      }
2745		    else
2746		      warning
2747			("unit `%s' requires absence and presence of `%s'",
2748			 dst->unit_decl->name, unit->name);
2749		  }
2750	    if (no_error_flag)
2751	      {
2752		for (prev_el = (presence_p
2753				? (final_p
2754				   ? dst->unit_decl->final_presence_list
2755				   : dst->unit_decl->final_presence_list)
2756				: (final_p
2757				   ? dst->unit_decl->final_absence_list
2758				   : dst->unit_decl->absence_list));
2759		     prev_el != NULL && prev_el->next_pattern_set_el != NULL;
2760		     prev_el = prev_el->next_pattern_set_el)
2761		  ;
2762		copy = copy_node (pat, sizeof (*pat));
2763		copy->next_pattern_set_el = NULL;
2764		if (prev_el == NULL)
2765		  {
2766		    if (presence_p)
2767		      {
2768			if (final_p)
2769			  dst->unit_decl->final_presence_list = copy;
2770			else
2771			  dst->unit_decl->presence_list = copy;
2772		      }
2773		    else if (final_p)
2774		      dst->unit_decl->final_absence_list = copy;
2775		    else
2776		      dst->unit_decl->absence_list = copy;
2777		  }
2778		else
2779		  prev_el->next_pattern_set_el = copy;
2780	      }
2781	  }
2782      }
2783}
2784
2785
2786/* The function searches for bypass with given IN_INSN_RESERV in given
2787   BYPASS_LIST.  */
2788static struct bypass_decl *
2789find_bypass (struct bypass_decl *bypass_list,
2790	     struct insn_reserv_decl *in_insn_reserv)
2791{
2792  struct bypass_decl *bypass;
2793
2794  for (bypass = bypass_list; bypass != NULL; bypass = bypass->next)
2795    if (bypass->in_insn_reserv == in_insn_reserv)
2796      break;
2797  return bypass;
2798}
2799
2800/* The function processes pipeline description declarations, checks
2801   their correctness, and forms exclusion/presence/absence sets.  */
2802static void
2803process_decls (void)
2804{
2805  decl_t decl;
2806  decl_t automaton_decl;
2807  decl_t decl_in_table;
2808  decl_t out_insn_reserv;
2809  decl_t in_insn_reserv;
2810  struct bypass_decl *bypass;
2811  int automaton_presence;
2812  int i;
2813
2814  /* Checking repeated automata declarations.  */
2815  automaton_presence = 0;
2816  for (i = 0; i < description->decls_num; i++)
2817    {
2818      decl = description->decls [i];
2819      if (decl->mode == dm_automaton)
2820	{
2821	  automaton_presence = 1;
2822	  decl_in_table = insert_automaton_decl (decl);
2823	  if (decl_in_table != decl)
2824	    {
2825	      if (!w_flag)
2826		error ("repeated declaration of automaton `%s'",
2827		       DECL_AUTOMATON (decl)->name);
2828	      else
2829		warning ("repeated declaration of automaton `%s'",
2830			 DECL_AUTOMATON (decl)->name);
2831	    }
2832	}
2833    }
2834  /* Checking undeclared automata, repeated declarations (except for
2835     automata) and correctness of their attributes (insn latency times
2836     etc.).  */
2837  for (i = 0; i < description->decls_num; i++)
2838    {
2839      decl = description->decls [i];
2840      if (decl->mode == dm_insn_reserv)
2841	{
2842          DECL_INSN_RESERV (decl)->condexp
2843	    = check_attr_test (DECL_INSN_RESERV (decl)->condexp, 0, 0);
2844	  if (DECL_INSN_RESERV (decl)->default_latency < 0)
2845	    error ("define_insn_reservation `%s' has negative latency time",
2846		   DECL_INSN_RESERV (decl)->name);
2847	  DECL_INSN_RESERV (decl)->insn_num = description->insns_num;
2848	  description->insns_num++;
2849	  decl_in_table = insert_insn_decl (decl);
2850	  if (decl_in_table != decl)
2851	    error ("`%s' is already used as insn reservation name",
2852		   DECL_INSN_RESERV (decl)->name);
2853	}
2854      else if (decl->mode == dm_bypass)
2855	{
2856	  if (DECL_BYPASS (decl)->latency < 0)
2857	    error ("define_bypass `%s - %s' has negative latency time",
2858		   DECL_BYPASS (decl)->out_insn_name,
2859		   DECL_BYPASS (decl)->in_insn_name);
2860	}
2861      else if (decl->mode == dm_unit || decl->mode == dm_reserv)
2862	{
2863	  if (decl->mode == dm_unit)
2864	    {
2865	      DECL_UNIT (decl)->automaton_decl = NULL;
2866	      if (DECL_UNIT (decl)->automaton_name != NULL)
2867		{
2868		  automaton_decl
2869                    = find_automaton_decl (DECL_UNIT (decl)->automaton_name);
2870		  if (automaton_decl == NULL)
2871		    error ("automaton `%s' is not declared",
2872			   DECL_UNIT (decl)->automaton_name);
2873		  else
2874		    {
2875		      DECL_AUTOMATON (automaton_decl)->automaton_is_used = 1;
2876		      DECL_UNIT (decl)->automaton_decl
2877			= DECL_AUTOMATON (automaton_decl);
2878		    }
2879		}
2880	      else if (automaton_presence)
2881		error ("define_unit `%s' without automaton when one defined",
2882		       DECL_UNIT (decl)->name);
2883	      DECL_UNIT (decl)->unit_num = description->units_num;
2884	      description->units_num++;
2885	      if (strcmp (DECL_UNIT (decl)->name, NOTHING_NAME) == 0)
2886		{
2887		  error ("`%s' is declared as cpu unit", NOTHING_NAME);
2888		  continue;
2889		}
2890	      decl_in_table = find_decl (DECL_UNIT (decl)->name);
2891	    }
2892	  else
2893	    {
2894	      if (strcmp (DECL_RESERV (decl)->name, NOTHING_NAME) == 0)
2895		{
2896		  error ("`%s' is declared as cpu reservation", NOTHING_NAME);
2897		  continue;
2898		}
2899	      decl_in_table = find_decl (DECL_RESERV (decl)->name);
2900	    }
2901	  if (decl_in_table == NULL)
2902	    decl_in_table = insert_decl (decl);
2903	  else
2904	    {
2905	      if (decl->mode == dm_unit)
2906		error ("repeated declaration of unit `%s'",
2907		       DECL_UNIT (decl)->name);
2908	      else
2909		error ("repeated declaration of reservation `%s'",
2910		       DECL_RESERV (decl)->name);
2911	    }
2912	}
2913    }
2914  /* Check bypasses and form list of bypasses for each (output)
2915     insn.  */
2916  for (i = 0; i < description->decls_num; i++)
2917    {
2918      decl = description->decls [i];
2919      if (decl->mode == dm_bypass)
2920	{
2921	  out_insn_reserv = find_insn_decl (DECL_BYPASS (decl)->out_insn_name);
2922	  in_insn_reserv = find_insn_decl (DECL_BYPASS (decl)->in_insn_name);
2923	  if (out_insn_reserv == NULL)
2924	    error ("there is no insn reservation `%s'",
2925		   DECL_BYPASS (decl)->out_insn_name);
2926	  else if (in_insn_reserv == NULL)
2927	    error ("there is no insn reservation `%s'",
2928		   DECL_BYPASS (decl)->in_insn_name);
2929	  else
2930	    {
2931	      DECL_BYPASS (decl)->out_insn_reserv
2932		= DECL_INSN_RESERV (out_insn_reserv);
2933	      DECL_BYPASS (decl)->in_insn_reserv
2934		= DECL_INSN_RESERV (in_insn_reserv);
2935	      bypass
2936		= find_bypass (DECL_INSN_RESERV (out_insn_reserv)->bypass_list,
2937			       DECL_BYPASS (decl)->in_insn_reserv);
2938	      if (bypass != NULL)
2939		{
2940		  if (DECL_BYPASS (decl)->latency == bypass->latency)
2941		    {
2942		      if (!w_flag)
2943			error
2944			  ("the same bypass `%s - %s' is already defined",
2945			   DECL_BYPASS (decl)->out_insn_name,
2946			   DECL_BYPASS (decl)->in_insn_name);
2947		      else
2948			warning
2949			  ("the same bypass `%s - %s' is already defined",
2950			   DECL_BYPASS (decl)->out_insn_name,
2951			   DECL_BYPASS (decl)->in_insn_name);
2952		    }
2953		  else
2954		    error ("bypass `%s - %s' is already defined",
2955			   DECL_BYPASS (decl)->out_insn_name,
2956			   DECL_BYPASS (decl)->in_insn_name);
2957		}
2958	      else
2959		{
2960		  DECL_BYPASS (decl)->next
2961		    = DECL_INSN_RESERV (out_insn_reserv)->bypass_list;
2962		  DECL_INSN_RESERV (out_insn_reserv)->bypass_list
2963		    = DECL_BYPASS (decl);
2964		}
2965	    }
2966	}
2967    }
2968
2969  /* Check exclusion set declarations and form exclusion sets.  */
2970  for (i = 0; i < description->decls_num; i++)
2971    {
2972      decl = description->decls [i];
2973      if (decl->mode == dm_excl)
2974	{
2975	  unit_set_el_t unit_set_el_list;
2976	  unit_set_el_t unit_set_el_list_2;
2977
2978	  unit_set_el_list
2979            = process_excls (DECL_EXCL (decl)->names,
2980			     DECL_EXCL (decl)->first_list_length, decl->pos);
2981	  unit_set_el_list_2
2982	    = process_excls (&DECL_EXCL (decl)->names
2983			     [DECL_EXCL (decl)->first_list_length],
2984                             DECL_EXCL (decl)->all_names_num
2985                             - DECL_EXCL (decl)->first_list_length,
2986                             decl->pos);
2987	  add_excls (unit_set_el_list, unit_set_el_list_2, decl->pos);
2988	  add_excls (unit_set_el_list_2, unit_set_el_list, decl->pos);
2989	}
2990    }
2991
2992  /* Check presence set declarations and form presence sets.  */
2993  for (i = 0; i < description->decls_num; i++)
2994    {
2995      decl = description->decls [i];
2996      if (decl->mode == dm_presence)
2997	{
2998	  unit_set_el_t unit_set_el_list;
2999	  pattern_set_el_t pattern_set_el_list;
3000
3001	  unit_set_el_list
3002            = process_presence_absence_names
3003	      (DECL_PRESENCE (decl)->names, DECL_PRESENCE (decl)->names_num,
3004	       decl->pos, TRUE, DECL_PRESENCE (decl)->final_p);
3005	  pattern_set_el_list
3006	    = process_presence_absence_patterns
3007	      (DECL_PRESENCE (decl)->patterns,
3008	       DECL_PRESENCE (decl)->patterns_num,
3009	       decl->pos, TRUE, DECL_PRESENCE (decl)->final_p);
3010	  add_presence_absence (unit_set_el_list, pattern_set_el_list,
3011				decl->pos, TRUE,
3012				DECL_PRESENCE (decl)->final_p);
3013	}
3014    }
3015
3016  /* Check absence set declarations and form absence sets.  */
3017  for (i = 0; i < description->decls_num; i++)
3018    {
3019      decl = description->decls [i];
3020      if (decl->mode == dm_absence)
3021	{
3022	  unit_set_el_t unit_set_el_list;
3023	  pattern_set_el_t pattern_set_el_list;
3024
3025	  unit_set_el_list
3026            = process_presence_absence_names
3027	      (DECL_ABSENCE (decl)->names, DECL_ABSENCE (decl)->names_num,
3028	       decl->pos, FALSE, DECL_ABSENCE (decl)->final_p);
3029	  pattern_set_el_list
3030	    = process_presence_absence_patterns
3031	      (DECL_ABSENCE (decl)->patterns,
3032	       DECL_ABSENCE (decl)->patterns_num,
3033	       decl->pos, FALSE, DECL_ABSENCE (decl)->final_p);
3034	  add_presence_absence (unit_set_el_list, pattern_set_el_list,
3035				decl->pos, FALSE,
3036				DECL_ABSENCE (decl)->final_p);
3037	}
3038    }
3039}
3040
3041/* The following function checks that declared automaton is used.  If
3042   the automaton is not used, the function fixes error/warning.  The
3043   following function must be called only after `process_decls'.  */
3044static void
3045check_automaton_usage (void)
3046{
3047  decl_t decl;
3048  int i;
3049
3050  for (i = 0; i < description->decls_num; i++)
3051    {
3052      decl = description->decls [i];
3053      if (decl->mode == dm_automaton
3054	  && !DECL_AUTOMATON (decl)->automaton_is_used)
3055	{
3056	  if (!w_flag)
3057	    error ("automaton `%s' is not used", DECL_AUTOMATON (decl)->name);
3058	  else
3059	    warning ("automaton `%s' is not used",
3060		     DECL_AUTOMATON (decl)->name);
3061	}
3062    }
3063}
3064
3065/* The following recursive function processes all regexp in order to
3066   fix usage of units or reservations and to fix errors of undeclared
3067   name.  The function may change unit_regexp onto reserv_regexp.
3068   Remember that reserv_regexp does not exist before the function
3069   call.  */
3070static regexp_t
3071process_regexp (regexp_t regexp)
3072{
3073  decl_t decl_in_table;
3074  regexp_t new_regexp;
3075  int i;
3076
3077  if (regexp->mode == rm_unit)
3078    {
3079      decl_in_table = find_decl (REGEXP_UNIT (regexp)->name);
3080      if (decl_in_table == NULL)
3081        error ("undeclared unit or reservation `%s'",
3082	       REGEXP_UNIT (regexp)->name);
3083      else if (decl_in_table->mode == dm_unit)
3084	{
3085	  DECL_UNIT (decl_in_table)->unit_is_used = 1;
3086	  REGEXP_UNIT (regexp)->unit_decl = DECL_UNIT (decl_in_table);
3087	}
3088      else if (decl_in_table->mode == dm_reserv)
3089	{
3090	  DECL_RESERV (decl_in_table)->reserv_is_used = 1;
3091	  new_regexp = create_node (sizeof (struct regexp));
3092	  new_regexp->mode = rm_reserv;
3093	  new_regexp->pos = regexp->pos;
3094	  REGEXP_RESERV (new_regexp)->name = REGEXP_UNIT (regexp)->name;
3095	  REGEXP_RESERV (new_regexp)->reserv_decl
3096	    = DECL_RESERV (decl_in_table);
3097	  regexp = new_regexp;
3098	}
3099      else
3100	abort ();
3101    }
3102  else if (regexp->mode == rm_sequence)
3103    for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
3104     REGEXP_SEQUENCE (regexp)->regexps [i]
3105	= process_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
3106  else if (regexp->mode == rm_allof)
3107    for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
3108      REGEXP_ALLOF (regexp)->regexps [i]
3109        = process_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
3110  else if (regexp->mode == rm_oneof)
3111    for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
3112      REGEXP_ONEOF (regexp)->regexps [i]
3113	= process_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
3114  else if (regexp->mode == rm_repeat)
3115    REGEXP_REPEAT (regexp)->regexp
3116      = process_regexp (REGEXP_REPEAT (regexp)->regexp);
3117  else if (regexp->mode != rm_nothing)
3118    abort ();
3119  return regexp;
3120}
3121
3122/* The following function processes regexp of define_reservation and
3123   define_insn_reservation with the aid of function
3124   `process_regexp'.  */
3125static void
3126process_regexp_decls (void)
3127{
3128  decl_t decl;
3129  int i;
3130
3131  for (i = 0; i < description->decls_num; i++)
3132    {
3133      decl = description->decls [i];
3134      if (decl->mode == dm_reserv)
3135	DECL_RESERV (decl)->regexp
3136	  = process_regexp (DECL_RESERV (decl)->regexp);
3137      else if (decl->mode == dm_insn_reserv)
3138	DECL_INSN_RESERV (decl)->regexp
3139	  = process_regexp (DECL_INSN_RESERV (decl)->regexp);
3140    }
3141}
3142
3143/* The following function checks that declared unit is used.  If the
3144   unit is not used, the function fixes errors/warnings.  The
3145   following function must be called only after `process_decls',
3146   `process_regexp_decls'.  */
3147static void
3148check_usage (void)
3149{
3150  decl_t decl;
3151  int i;
3152
3153  for (i = 0; i < description->decls_num; i++)
3154    {
3155      decl = description->decls [i];
3156      if (decl->mode == dm_unit && !DECL_UNIT (decl)->unit_is_used)
3157	{
3158	  if (!w_flag)
3159	    error ("unit `%s' is not used", DECL_UNIT (decl)->name);
3160	  else
3161	    warning ("unit `%s' is not used", DECL_UNIT (decl)->name);
3162	}
3163      else if (decl->mode == dm_reserv && !DECL_RESERV (decl)->reserv_is_used)
3164	{
3165	  if (!w_flag)
3166	    error ("reservation `%s' is not used", DECL_RESERV (decl)->name);
3167	  else
3168	    warning ("reservation `%s' is not used", DECL_RESERV (decl)->name);
3169	}
3170    }
3171}
3172
3173/* The following variable value is number of reservation being
3174   processed on loop recognition.  */
3175static int curr_loop_pass_num;
3176
3177/* The following recursive function returns nonzero value if REGEXP
3178   contains given decl or reservations in given regexp refers for
3179   given decl.  */
3180static int
3181loop_in_regexp (regexp_t regexp, decl_t start_decl)
3182{
3183  int i;
3184
3185  if (regexp == NULL)
3186    return 0;
3187  if (regexp->mode == rm_unit)
3188    return 0;
3189  else if (regexp->mode == rm_reserv)
3190    {
3191      if (start_decl->mode == dm_reserv
3192          && REGEXP_RESERV (regexp)->reserv_decl == DECL_RESERV (start_decl))
3193        return 1;
3194      else if (REGEXP_RESERV (regexp)->reserv_decl->loop_pass_num
3195	       == curr_loop_pass_num)
3196        /* declaration has been processed.  */
3197        return 0;
3198      else
3199        {
3200	  REGEXP_RESERV (regexp)->reserv_decl->loop_pass_num
3201            = curr_loop_pass_num;
3202          return loop_in_regexp (REGEXP_RESERV (regexp)->reserv_decl->regexp,
3203                                 start_decl);
3204        }
3205    }
3206  else if (regexp->mode == rm_sequence)
3207    {
3208      for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
3209	if (loop_in_regexp (REGEXP_SEQUENCE (regexp)->regexps [i], start_decl))
3210	  return 1;
3211      return 0;
3212    }
3213  else if (regexp->mode == rm_allof)
3214    {
3215      for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
3216	if (loop_in_regexp (REGEXP_ALLOF (regexp)->regexps [i], start_decl))
3217	  return 1;
3218      return 0;
3219    }
3220  else if (regexp->mode == rm_oneof)
3221    {
3222      for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
3223	if (loop_in_regexp (REGEXP_ONEOF (regexp)->regexps [i], start_decl))
3224	  return 1;
3225      return 0;
3226    }
3227  else if (regexp->mode == rm_repeat)
3228    return loop_in_regexp (REGEXP_REPEAT (regexp)->regexp, start_decl);
3229  else
3230    {
3231      if (regexp->mode != rm_nothing)
3232	abort ();
3233      return 0;
3234    }
3235}
3236
3237/* The following function fixes errors "cycle in definition ...".  The
3238   function uses function `loop_in_regexp' for that.  */
3239static void
3240check_loops_in_regexps (void)
3241{
3242  decl_t decl;
3243  int i;
3244
3245  for (i = 0; i < description->decls_num; i++)
3246    {
3247      decl = description->decls [i];
3248      if (decl->mode == dm_reserv)
3249	DECL_RESERV (decl)->loop_pass_num = 0;
3250    }
3251  for (i = 0; i < description->decls_num; i++)
3252    {
3253      decl = description->decls [i];
3254      curr_loop_pass_num = i;
3255
3256      if (decl->mode == dm_reserv)
3257	  {
3258	    DECL_RESERV (decl)->loop_pass_num = curr_loop_pass_num;
3259	    if (loop_in_regexp (DECL_RESERV (decl)->regexp, decl))
3260	      {
3261		if (DECL_RESERV (decl)->regexp == NULL)
3262		  abort ();
3263		error ("cycle in definition of reservation `%s'",
3264		       DECL_RESERV (decl)->name);
3265	      }
3266	  }
3267    }
3268}
3269
3270/* The function recursively processes IR of reservation and defines
3271   max and min cycle for reservation of unit.  */
3272static void
3273process_regexp_cycles (regexp_t regexp, int max_start_cycle,
3274		       int min_start_cycle, int *max_finish_cycle,
3275		       int *min_finish_cycle)
3276{
3277  int i;
3278
3279  if (regexp->mode == rm_unit)
3280    {
3281      if (REGEXP_UNIT (regexp)->unit_decl->max_occ_cycle_num < max_start_cycle)
3282	REGEXP_UNIT (regexp)->unit_decl->max_occ_cycle_num = max_start_cycle;
3283      if (REGEXP_UNIT (regexp)->unit_decl->min_occ_cycle_num > min_start_cycle
3284	  || REGEXP_UNIT (regexp)->unit_decl->min_occ_cycle_num == -1)
3285	REGEXP_UNIT (regexp)->unit_decl->min_occ_cycle_num = min_start_cycle;
3286      *max_finish_cycle = max_start_cycle;
3287      *min_finish_cycle = min_start_cycle;
3288    }
3289  else if (regexp->mode == rm_reserv)
3290   process_regexp_cycles (REGEXP_RESERV (regexp)->reserv_decl->regexp,
3291			  max_start_cycle, min_start_cycle,
3292			  max_finish_cycle, min_finish_cycle);
3293  else if (regexp->mode == rm_repeat)
3294    {
3295      for (i = 0; i < REGEXP_REPEAT (regexp)->repeat_num; i++)
3296	{
3297	  process_regexp_cycles (REGEXP_REPEAT (regexp)->regexp,
3298				 max_start_cycle, min_start_cycle,
3299				 max_finish_cycle, min_finish_cycle);
3300	  max_start_cycle = *max_finish_cycle + 1;
3301	  min_start_cycle = *min_finish_cycle + 1;
3302	}
3303    }
3304  else if (regexp->mode == rm_sequence)
3305    {
3306      for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
3307	{
3308	  process_regexp_cycles (REGEXP_SEQUENCE (regexp)->regexps [i],
3309				 max_start_cycle, min_start_cycle,
3310				 max_finish_cycle, min_finish_cycle);
3311	  max_start_cycle = *max_finish_cycle + 1;
3312	  min_start_cycle = *min_finish_cycle + 1;
3313	}
3314    }
3315  else if (regexp->mode == rm_allof)
3316    {
3317      int max_cycle = 0;
3318      int min_cycle = 0;
3319
3320      for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
3321	{
3322	  process_regexp_cycles (REGEXP_ALLOF (regexp)->regexps [i],
3323				 max_start_cycle, min_start_cycle,
3324				 max_finish_cycle, min_finish_cycle);
3325	  if (max_cycle < *max_finish_cycle)
3326	    max_cycle = *max_finish_cycle;
3327	  if (i == 0 || min_cycle > *min_finish_cycle)
3328	    min_cycle = *min_finish_cycle;
3329	}
3330      *max_finish_cycle = max_cycle;
3331      *min_finish_cycle = min_cycle;
3332    }
3333  else if (regexp->mode == rm_oneof)
3334    {
3335      int max_cycle = 0;
3336      int min_cycle = 0;
3337
3338      for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
3339	{
3340	  process_regexp_cycles (REGEXP_ONEOF (regexp)->regexps [i],
3341				 max_start_cycle, min_start_cycle,
3342				 max_finish_cycle, min_finish_cycle);
3343	  if (max_cycle < *max_finish_cycle)
3344	    max_cycle = *max_finish_cycle;
3345	  if (i == 0 || min_cycle > *min_finish_cycle)
3346	    min_cycle = *min_finish_cycle;
3347	}
3348      *max_finish_cycle = max_cycle;
3349      *min_finish_cycle = min_cycle;
3350    }
3351  else
3352    {
3353      if (regexp->mode != rm_nothing)
3354	abort ();
3355      *max_finish_cycle = max_start_cycle;
3356      *min_finish_cycle = min_start_cycle;
3357    }
3358}
3359
3360/* The following function is called only for correct program.  The
3361   function defines max reservation of insns in cycles.  */
3362static void
3363evaluate_max_reserv_cycles (void)
3364{
3365  int max_insn_cycles_num;
3366  int min_insn_cycles_num;
3367  decl_t decl;
3368  int i;
3369
3370  description->max_insn_reserv_cycles = 0;
3371  for (i = 0; i < description->decls_num; i++)
3372    {
3373      decl = description->decls [i];
3374      if (decl->mode == dm_insn_reserv)
3375      {
3376        process_regexp_cycles (DECL_INSN_RESERV (decl)->regexp, 0, 0,
3377			       &max_insn_cycles_num, &min_insn_cycles_num);
3378        if (description->max_insn_reserv_cycles < max_insn_cycles_num)
3379	  description->max_insn_reserv_cycles = max_insn_cycles_num;
3380      }
3381    }
3382  description->max_insn_reserv_cycles++;
3383}
3384
3385/* The following function calls functions for checking all
3386   description.  */
3387static void
3388check_all_description (void)
3389{
3390  process_decls ();
3391  check_automaton_usage ();
3392  process_regexp_decls ();
3393  check_usage ();
3394  check_loops_in_regexps ();
3395  if (!have_error)
3396    evaluate_max_reserv_cycles ();
3397}
3398
3399
3400
3401/* The page contains abstract data `ticker'.  This data is used to
3402   report time of different phases of building automata.  It is
3403   possibly to write a description for which automata will be built
3404   during several minutes even on fast machine.  */
3405
3406/* The following function creates ticker and makes it active.  */
3407static ticker_t
3408create_ticker (void)
3409{
3410  ticker_t ticker;
3411
3412  ticker.modified_creation_time = get_run_time ();
3413  ticker.incremented_off_time = 0;
3414  return ticker;
3415}
3416
3417/* The following function switches off given ticker.  */
3418static void
3419ticker_off (ticker_t *ticker)
3420{
3421  if (ticker->incremented_off_time == 0)
3422    ticker->incremented_off_time = get_run_time () + 1;
3423}
3424
3425/* The following function switches on given ticker.  */
3426static void
3427ticker_on (ticker_t *ticker)
3428{
3429  if (ticker->incremented_off_time != 0)
3430    {
3431      ticker->modified_creation_time
3432        += get_run_time () - ticker->incremented_off_time + 1;
3433      ticker->incremented_off_time = 0;
3434    }
3435}
3436
3437/* The following function returns current time in milliseconds since
3438   the moment when given ticker was created.  */
3439static int
3440active_time (ticker_t ticker)
3441{
3442  if (ticker.incremented_off_time != 0)
3443    return ticker.incremented_off_time - 1 - ticker.modified_creation_time;
3444  else
3445    return get_run_time () - ticker.modified_creation_time;
3446}
3447
3448/* The following function returns string representation of active time
3449   of given ticker.  The result is string representation of seconds
3450   with accuracy of 1/100 second.  Only result of the last call of the
3451   function exists.  Therefore the following code is not correct
3452
3453      printf ("parser time: %s\ngeneration time: %s\n",
3454              active_time_string (parser_ticker),
3455              active_time_string (generation_ticker));
3456
3457   Correct code has to be the following
3458
3459      printf ("parser time: %s\n", active_time_string (parser_ticker));
3460      printf ("generation time: %s\n",
3461              active_time_string (generation_ticker));
3462
3463*/
3464static void
3465print_active_time (FILE *f, ticker_t ticker)
3466{
3467  int msecs;
3468
3469  msecs = active_time (ticker);
3470  fprintf (f, "%d.%06d", msecs / 1000000, msecs % 1000000);
3471}
3472
3473
3474
3475/* The following variable value is number of automaton which are
3476   really being created.  This value is defined on the base of
3477   argument of option `-split'.  If the variable has zero value the
3478   number of automata is defined by the constructions `%automaton'.
3479   This case occurs when option `-split' is absent or has zero
3480   argument.  If constructions `define_automaton' is absent only one
3481   automaton is created.  */
3482static int automata_num;
3483
3484/* The following variable values are times of
3485       o transformation of regular expressions
3486       o building NDFA (DFA if !ndfa_flag)
3487       o NDFA -> DFA   (simply the same automaton if !ndfa_flag)
3488       o DFA minimization
3489       o building insn equivalence classes
3490       o all previous ones
3491       o code output */
3492static ticker_t transform_time;
3493static ticker_t NDFA_time;
3494static ticker_t NDFA_to_DFA_time;
3495static ticker_t minimize_time;
3496static ticker_t equiv_time;
3497static ticker_t automaton_generation_time;
3498static ticker_t output_time;
3499
3500/* The following variable values are times of
3501       all checking
3502       all generation
3503       all pipeline hazard translator work */
3504static ticker_t check_time;
3505static ticker_t generation_time;
3506static ticker_t all_time;
3507
3508
3509
3510/* Pseudo insn decl which denotes advancing cycle.  */
3511static decl_t advance_cycle_insn_decl;
3512static void
3513add_advance_cycle_insn_decl (void)
3514{
3515  advance_cycle_insn_decl = create_node (sizeof (struct decl));
3516  advance_cycle_insn_decl->mode = dm_insn_reserv;
3517  advance_cycle_insn_decl->pos = no_pos;
3518  DECL_INSN_RESERV (advance_cycle_insn_decl)->regexp = NULL;
3519  DECL_INSN_RESERV (advance_cycle_insn_decl)->name = (char *) "$advance_cycle";
3520  DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num
3521    = description->insns_num;
3522  description->decls [description->decls_num] = advance_cycle_insn_decl;
3523  description->decls_num++;
3524  description->insns_num++;
3525  num_dfa_decls++;
3526}
3527
3528
3529/* Abstract data `alternative states' which represents
3530   nondeterministic nature of the description (see comments for
3531   structures alt_state and state).  */
3532
3533/* List of free states.  */
3534static alt_state_t first_free_alt_state;
3535
3536#ifndef NDEBUG
3537/* The following variables is maximal number of allocated nodes
3538   alt_state.  */
3539static int allocated_alt_states_num = 0;
3540#endif
3541
3542/* The following function returns free node alt_state.  It may be new
3543   allocated node or node freed earlier.  */
3544static alt_state_t
3545get_free_alt_state (void)
3546{
3547  alt_state_t result;
3548
3549  if (first_free_alt_state != NULL)
3550    {
3551      result = first_free_alt_state;
3552      first_free_alt_state = first_free_alt_state->next_alt_state;
3553    }
3554  else
3555    {
3556#ifndef NDEBUG
3557      allocated_alt_states_num++;
3558#endif
3559      result = create_node (sizeof (struct alt_state));
3560    }
3561  result->state = NULL;
3562  result->next_alt_state = NULL;
3563  result->next_sorted_alt_state = NULL;
3564  return result;
3565}
3566
3567/* The function frees node ALT_STATE.  */
3568static void
3569free_alt_state (alt_state_t alt_state)
3570{
3571  if (alt_state == NULL)
3572    return;
3573  alt_state->next_alt_state = first_free_alt_state;
3574  first_free_alt_state = alt_state;
3575}
3576
3577/* The function frees list started with node ALT_STATE_LIST.  */
3578static void
3579free_alt_states (alt_state_t alt_states_list)
3580{
3581  alt_state_t curr_alt_state;
3582  alt_state_t next_alt_state;
3583
3584  for (curr_alt_state = alt_states_list;
3585       curr_alt_state != NULL;
3586       curr_alt_state = next_alt_state)
3587    {
3588      next_alt_state = curr_alt_state->next_alt_state;
3589      free_alt_state (curr_alt_state);
3590    }
3591}
3592
3593/* The function compares unique numbers of alt states.  */
3594static int
3595alt_state_cmp (const void *alt_state_ptr_1, const void *alt_state_ptr_2)
3596{
3597  if ((*(alt_state_t *) alt_state_ptr_1)->state->unique_num
3598      == (*(alt_state_t *) alt_state_ptr_2)->state->unique_num)
3599    return 0;
3600  else if ((*(alt_state_t *) alt_state_ptr_1)->state->unique_num
3601	   < (*(alt_state_t *) alt_state_ptr_2)->state->unique_num)
3602    return -1;
3603  else
3604    return 1;
3605}
3606
3607/* The function sorts ALT_STATES_LIST and removes duplicated alt
3608   states from the list.  The comparison key is alt state unique
3609   number.  */
3610static alt_state_t
3611uniq_sort_alt_states (alt_state_t alt_states_list)
3612{
3613  alt_state_t curr_alt_state;
3614  vla_ptr_t alt_states;
3615  size_t i;
3616  size_t prev_unique_state_ind;
3617  alt_state_t result;
3618  alt_state_t *result_ptr;
3619
3620  VLA_PTR_CREATE (alt_states, 150, "alt_states");
3621  for (curr_alt_state = alt_states_list;
3622       curr_alt_state != NULL;
3623       curr_alt_state = curr_alt_state->next_alt_state)
3624    VLA_PTR_ADD (alt_states, curr_alt_state);
3625  qsort (VLA_PTR_BEGIN (alt_states), VLA_PTR_LENGTH (alt_states),
3626	 sizeof (alt_state_t), alt_state_cmp);
3627  if (VLA_PTR_LENGTH (alt_states) == 0)
3628    result = NULL;
3629  else
3630    {
3631      result_ptr = VLA_PTR_BEGIN (alt_states);
3632      prev_unique_state_ind = 0;
3633      for (i = 1; i < VLA_PTR_LENGTH (alt_states); i++)
3634        if (result_ptr [prev_unique_state_ind]->state != result_ptr [i]->state)
3635          {
3636            prev_unique_state_ind++;
3637            result_ptr [prev_unique_state_ind] = result_ptr [i];
3638          }
3639#if 0
3640      for (i = prev_unique_state_ind + 1; i < VLA_PTR_LENGTH (alt_states); i++)
3641        free_alt_state (result_ptr [i]);
3642#endif
3643      VLA_PTR_SHORTEN (alt_states, i - prev_unique_state_ind - 1);
3644      result_ptr = VLA_PTR_BEGIN (alt_states);
3645      for (i = 1; i < VLA_PTR_LENGTH (alt_states); i++)
3646        result_ptr [i - 1]->next_sorted_alt_state = result_ptr [i];
3647      result_ptr [i - 1]->next_sorted_alt_state = NULL;
3648      result = *result_ptr;
3649    }
3650  VLA_PTR_DELETE (alt_states);
3651  return result;
3652}
3653
3654/* The function checks equality of alt state lists.  Remember that the
3655   lists must be already sorted by the previous function.  */
3656static int
3657alt_states_eq (alt_state_t alt_states_1, alt_state_t alt_states_2)
3658{
3659  while (alt_states_1 != NULL && alt_states_2 != NULL
3660         && alt_state_cmp (&alt_states_1, &alt_states_2) == 0)
3661    {
3662      alt_states_1 = alt_states_1->next_sorted_alt_state;
3663      alt_states_2 = alt_states_2->next_sorted_alt_state;
3664    }
3665  return alt_states_1 == alt_states_2;
3666}
3667
3668/* Initialization of the abstract data.  */
3669static void
3670initiate_alt_states (void)
3671{
3672  first_free_alt_state = NULL;
3673}
3674
3675/* Finishing work with the abstract data.  */
3676static void
3677finish_alt_states (void)
3678{
3679}
3680
3681
3682
3683/* The page contains macros for work with bits strings.  We could use
3684   standard gcc bitmap or sbitmap but it would result in difficulties
3685   of building canadian cross.  */
3686
3687/* Set bit number bitno in the bit string.  The macro is not side
3688   effect proof.  */
3689#define SET_BIT(bitstring, bitno)					  \
3690  (((char *) (bitstring)) [(bitno) / CHAR_BIT] |= 1 << (bitno) % CHAR_BIT)
3691
3692#define CLEAR_BIT(bitstring, bitno)					  \
3693  (((char *) (bitstring)) [(bitno) / CHAR_BIT] &= ~(1 << (bitno) % CHAR_BIT))
3694
3695/* Test if bit number bitno in the bitstring is set.  The macro is not
3696   side effect proof.  */
3697#define TEST_BIT(bitstring, bitno)                                        \
3698  (((char *) (bitstring)) [(bitno) / CHAR_BIT] >> (bitno) % CHAR_BIT & 1)
3699
3700
3701
3702/* This page contains abstract data `state'.  */
3703
3704/* Maximal length of reservations in cycles (>= 1).  */
3705static int max_cycles_num;
3706
3707/* Number of set elements (see type set_el_t) needed for
3708   representation of one cycle reservation.  It is depended on units
3709   number.  */
3710static int els_in_cycle_reserv;
3711
3712/* Number of set elements (see type set_el_t) needed for
3713   representation of maximal length reservation.  Deterministic
3714   reservation is stored as set (bit string) of length equal to the
3715   variable value * number of bits in set_el_t.  */
3716static int els_in_reservs;
3717
3718/* VLA for representation of array of pointers to unit
3719   declarations.  */
3720static vla_ptr_t units_container;
3721
3722/* The start address of the array.  */
3723static unit_decl_t *units_array;
3724
3725/* Temporary reservation of maximal length.  */
3726static reserv_sets_t temp_reserv;
3727
3728/* The state table itself is represented by the following variable.  */
3729static htab_t state_table;
3730
3731/* VLA for representation of array of pointers to free nodes
3732   `state'.  */
3733static vla_ptr_t free_states;
3734
3735static int curr_unique_state_num;
3736
3737#ifndef NDEBUG
3738/* The following variables is maximal number of allocated nodes
3739   `state'.  */
3740static int allocated_states_num = 0;
3741#endif
3742
3743/* Allocate new reservation set.  */
3744static reserv_sets_t
3745alloc_empty_reserv_sets (void)
3746{
3747  reserv_sets_t result;
3748
3749  obstack_blank (&irp, els_in_reservs * sizeof (set_el_t));
3750  result = (reserv_sets_t) obstack_base (&irp);
3751  obstack_finish (&irp);
3752  memset (result, 0, els_in_reservs * sizeof (set_el_t));
3753  return result;
3754}
3755
3756/* Hash value of reservation set.  */
3757static unsigned
3758reserv_sets_hash_value (reserv_sets_t reservs)
3759{
3760  set_el_t hash_value;
3761  unsigned result;
3762  int reservs_num, i;
3763  set_el_t *reserv_ptr;
3764
3765  hash_value = 0;
3766  reservs_num = els_in_reservs;
3767  reserv_ptr = reservs;
3768  i = 0;
3769  while (reservs_num != 0)
3770    {
3771      reservs_num--;
3772      hash_value += ((*reserv_ptr >> i)
3773		     | (*reserv_ptr << (sizeof (set_el_t) * CHAR_BIT - i)));
3774      i++;
3775      if (i == sizeof (set_el_t) * CHAR_BIT)
3776	i = 0;
3777      reserv_ptr++;
3778    }
3779  if (sizeof (set_el_t) <= sizeof (unsigned))
3780    return hash_value;
3781  result = 0;
3782  for (i = sizeof (set_el_t); i > 0; i -= sizeof (unsigned) - 1)
3783    {
3784      result += (unsigned) hash_value;
3785      hash_value >>= (sizeof (unsigned) - 1) * CHAR_BIT;
3786    }
3787  return result;
3788}
3789
3790/* Comparison of given reservation sets.  */
3791static int
3792reserv_sets_cmp (reserv_sets_t reservs_1, reserv_sets_t reservs_2)
3793{
3794  int reservs_num;
3795  set_el_t *reserv_ptr_1;
3796  set_el_t *reserv_ptr_2;
3797
3798  if (reservs_1 == NULL || reservs_2 == NULL)
3799    abort ();
3800  reservs_num = els_in_reservs;
3801  reserv_ptr_1 = reservs_1;
3802  reserv_ptr_2 = reservs_2;
3803  while (reservs_num != 0 && *reserv_ptr_1 == *reserv_ptr_2)
3804    {
3805      reservs_num--;
3806      reserv_ptr_1++;
3807      reserv_ptr_2++;
3808    }
3809  if (reservs_num == 0)
3810    return 0;
3811  else if (*reserv_ptr_1 < *reserv_ptr_2)
3812    return -1;
3813  else
3814    return 1;
3815}
3816
3817/* The function checks equality of the reservation sets.  */
3818static int
3819reserv_sets_eq (reserv_sets_t reservs_1, reserv_sets_t reservs_2)
3820{
3821  return reserv_sets_cmp (reservs_1, reservs_2) == 0;
3822}
3823
3824/* Set up in the reservation set that unit with UNIT_NUM is used on
3825   CYCLE_NUM.  */
3826static void
3827set_unit_reserv (reserv_sets_t reservs, int cycle_num, int unit_num)
3828{
3829  if (cycle_num >= max_cycles_num)
3830    abort ();
3831  SET_BIT (reservs, cycle_num * els_in_cycle_reserv
3832           * sizeof (set_el_t) * CHAR_BIT + unit_num);
3833}
3834
3835/* Set up in the reservation set RESERVS that unit with UNIT_NUM is
3836   used on CYCLE_NUM.  */
3837static int
3838test_unit_reserv (reserv_sets_t reservs, int cycle_num, int unit_num)
3839{
3840  if (cycle_num >= max_cycles_num)
3841    abort ();
3842  return TEST_BIT (reservs, cycle_num * els_in_cycle_reserv
3843		   * sizeof (set_el_t) * CHAR_BIT + unit_num);
3844}
3845
3846/* The function checks that the reservation set represents no one unit
3847   reservation.  */
3848static int
3849it_is_empty_reserv_sets (reserv_sets_t operand)
3850{
3851  set_el_t *reserv_ptr;
3852  int reservs_num;
3853
3854  if (operand == NULL)
3855    abort ();
3856  for (reservs_num = els_in_reservs, reserv_ptr = operand;
3857       reservs_num != 0;
3858       reserv_ptr++, reservs_num--)
3859    if (*reserv_ptr != 0)
3860      return 0;
3861  return 1;
3862}
3863
3864/* The function checks that the reservation sets are intersected,
3865   i.e. there is a unit reservation on a cycle in both reservation
3866   sets.  */
3867static int
3868reserv_sets_are_intersected (reserv_sets_t operand_1,
3869			     reserv_sets_t operand_2)
3870{
3871  set_el_t *el_ptr_1;
3872  set_el_t *el_ptr_2;
3873  set_el_t *cycle_ptr_1;
3874  set_el_t *cycle_ptr_2;
3875
3876  if (operand_1 == NULL || operand_2 == NULL)
3877    abort ();
3878  for (el_ptr_1 = operand_1, el_ptr_2 = operand_2;
3879       el_ptr_1 < operand_1 + els_in_reservs;
3880       el_ptr_1++, el_ptr_2++)
3881    if (*el_ptr_1 & *el_ptr_2)
3882      return 1;
3883  reserv_sets_or (temp_reserv, operand_1, operand_2);
3884  for (cycle_ptr_1 = operand_1, cycle_ptr_2 = operand_2;
3885       cycle_ptr_1 < operand_1 + els_in_reservs;
3886       cycle_ptr_1 += els_in_cycle_reserv, cycle_ptr_2 += els_in_cycle_reserv)
3887    {
3888      for (el_ptr_1 = cycle_ptr_1, el_ptr_2 = get_excl_set (cycle_ptr_2);
3889	   el_ptr_1 < cycle_ptr_1 + els_in_cycle_reserv;
3890	   el_ptr_1++, el_ptr_2++)
3891	if (*el_ptr_1 & *el_ptr_2)
3892	  return 1;
3893      if (!check_presence_pattern_sets (cycle_ptr_1, cycle_ptr_2, FALSE))
3894	return 1;
3895      if (!check_presence_pattern_sets (temp_reserv + (cycle_ptr_2
3896						       - operand_2),
3897					cycle_ptr_2, TRUE))
3898	return 1;
3899      if (!check_absence_pattern_sets (cycle_ptr_1, cycle_ptr_2, FALSE))
3900	return 1;
3901      if (!check_absence_pattern_sets (temp_reserv + (cycle_ptr_2 - operand_2),
3902				       cycle_ptr_2, TRUE))
3903	return 1;
3904    }
3905  return 0;
3906}
3907
3908/* The function sets up RESULT bits by bits of OPERAND shifted on one
3909   cpu cycle.  The remaining bits of OPERAND (representing the last
3910   cycle unit reservations) are not changed.  */
3911static void
3912reserv_sets_shift (reserv_sets_t result, reserv_sets_t operand)
3913{
3914  int i;
3915
3916  if (result == NULL || operand == NULL || result == operand)
3917    abort ();
3918  for (i = els_in_cycle_reserv; i < els_in_reservs; i++)
3919    result [i - els_in_cycle_reserv] = operand [i];
3920}
3921
3922/* OR of the reservation sets.  */
3923static void
3924reserv_sets_or (reserv_sets_t result, reserv_sets_t operand_1,
3925		reserv_sets_t operand_2)
3926{
3927  set_el_t *el_ptr_1;
3928  set_el_t *el_ptr_2;
3929  set_el_t *result_set_el_ptr;
3930
3931  if (result == NULL || operand_1 == NULL || operand_2 == NULL)
3932    abort ();
3933  for (el_ptr_1 = operand_1, el_ptr_2 = operand_2, result_set_el_ptr = result;
3934       el_ptr_1 < operand_1 + els_in_reservs;
3935       el_ptr_1++, el_ptr_2++, result_set_el_ptr++)
3936    *result_set_el_ptr = *el_ptr_1 | *el_ptr_2;
3937}
3938
3939/* AND of the reservation sets.  */
3940static void
3941reserv_sets_and (reserv_sets_t result, reserv_sets_t operand_1,
3942		reserv_sets_t operand_2)
3943{
3944  set_el_t *el_ptr_1;
3945  set_el_t *el_ptr_2;
3946  set_el_t *result_set_el_ptr;
3947
3948  if (result == NULL || operand_1 == NULL || operand_2 == NULL)
3949    abort ();
3950  for (el_ptr_1 = operand_1, el_ptr_2 = operand_2, result_set_el_ptr = result;
3951       el_ptr_1 < operand_1 + els_in_reservs;
3952       el_ptr_1++, el_ptr_2++, result_set_el_ptr++)
3953    *result_set_el_ptr = *el_ptr_1 & *el_ptr_2;
3954}
3955
3956/* The function outputs string representation of units reservation on
3957   cycle START_CYCLE in the reservation set.  The function uses repeat
3958   construction if REPETITION_NUM > 1.  */
3959static void
3960output_cycle_reservs (FILE *f, reserv_sets_t reservs, int start_cycle,
3961		      int repetition_num)
3962{
3963  int unit_num;
3964  int reserved_units_num;
3965
3966  reserved_units_num = 0;
3967  for (unit_num = 0; unit_num < description->units_num; unit_num++)
3968    if (TEST_BIT (reservs, start_cycle * els_in_cycle_reserv
3969                  * sizeof (set_el_t) * CHAR_BIT + unit_num))
3970      reserved_units_num++;
3971  if (repetition_num <= 0)
3972    abort ();
3973  if (repetition_num != 1 && reserved_units_num > 1)
3974    fprintf (f, "(");
3975  reserved_units_num = 0;
3976  for (unit_num = 0;
3977       unit_num < description->units_num;
3978       unit_num++)
3979    if (TEST_BIT (reservs, start_cycle * els_in_cycle_reserv
3980		  * sizeof (set_el_t) * CHAR_BIT + unit_num))
3981      {
3982        if (reserved_units_num != 0)
3983          fprintf (f, "+");
3984        reserved_units_num++;
3985        fprintf (f, "%s", units_array [unit_num]->name);
3986      }
3987  if (reserved_units_num == 0)
3988    fprintf (f, NOTHING_NAME);
3989  if (repetition_num <= 0)
3990    abort ();
3991  if (repetition_num != 1 && reserved_units_num > 1)
3992    fprintf (f, ")");
3993  if (repetition_num != 1)
3994    fprintf (f, "*%d", repetition_num);
3995}
3996
3997/* The function outputs string representation of units reservation in
3998   the reservation set.  */
3999static void
4000output_reserv_sets (FILE *f, reserv_sets_t reservs)
4001{
4002  int start_cycle = 0;
4003  int cycle;
4004  int repetition_num;
4005
4006  repetition_num = 0;
4007  for (cycle = 0; cycle < max_cycles_num; cycle++)
4008    if (repetition_num == 0)
4009      {
4010        repetition_num++;
4011        start_cycle = cycle;
4012      }
4013    else if (memcmp
4014             ((char *) reservs + start_cycle * els_in_cycle_reserv
4015	      * sizeof (set_el_t),
4016              (char *) reservs + cycle * els_in_cycle_reserv
4017	      * sizeof (set_el_t),
4018	      els_in_cycle_reserv * sizeof (set_el_t)) == 0)
4019      repetition_num++;
4020    else
4021      {
4022        if (start_cycle != 0)
4023          fprintf (f, ", ");
4024        output_cycle_reservs (f, reservs, start_cycle, repetition_num);
4025        repetition_num = 1;
4026        start_cycle = cycle;
4027      }
4028  if (start_cycle < max_cycles_num)
4029    {
4030      if (start_cycle != 0)
4031        fprintf (f, ", ");
4032      output_cycle_reservs (f, reservs, start_cycle, repetition_num);
4033    }
4034}
4035
4036/* The following function returns free node state for AUTOMATON.  It
4037   may be new allocated node or node freed earlier.  The function also
4038   allocates reservation set if WITH_RESERVS has nonzero value.  */
4039static state_t
4040get_free_state (int with_reservs, automaton_t automaton)
4041{
4042  state_t result;
4043
4044  if (max_cycles_num <= 0 || automaton == NULL)
4045    abort ();
4046  if (VLA_PTR_LENGTH (free_states) != 0)
4047    {
4048      result = VLA_PTR (free_states, VLA_PTR_LENGTH (free_states) - 1);
4049      VLA_PTR_SHORTEN (free_states, 1);
4050      result->automaton = automaton;
4051      result->first_out_arc = NULL;
4052      result->it_was_placed_in_stack_for_NDFA_forming = 0;
4053      result->it_was_placed_in_stack_for_DFA_forming = 0;
4054      result->component_states = NULL;
4055      result->longest_path_length = UNDEFINED_LONGEST_PATH_LENGTH;
4056    }
4057  else
4058    {
4059#ifndef NDEBUG
4060      allocated_states_num++;
4061#endif
4062      result = create_node (sizeof (struct state));
4063      result->automaton = automaton;
4064      result->first_out_arc = NULL;
4065      result->unique_num = curr_unique_state_num;
4066      result->longest_path_length = UNDEFINED_LONGEST_PATH_LENGTH;
4067      curr_unique_state_num++;
4068    }
4069  if (with_reservs)
4070    {
4071      if (result->reservs == NULL)
4072        result->reservs = alloc_empty_reserv_sets ();
4073      else
4074        memset (result->reservs, 0, els_in_reservs * sizeof (set_el_t));
4075    }
4076  return result;
4077}
4078
4079/* The function frees node STATE.  */
4080static void
4081free_state (state_t state)
4082{
4083  free_alt_states (state->component_states);
4084  VLA_PTR_ADD (free_states, state);
4085}
4086
4087/* Hash value of STATE.  If STATE represents deterministic state it is
4088   simply hash value of the corresponding reservation set.  Otherwise
4089   it is formed from hash values of the component deterministic
4090   states.  One more key is order number of state automaton.  */
4091static hashval_t
4092state_hash (const void *state)
4093{
4094  unsigned int hash_value;
4095  alt_state_t alt_state;
4096
4097  if (((state_t) state)->component_states == NULL)
4098    hash_value = reserv_sets_hash_value (((state_t) state)->reservs);
4099  else
4100    {
4101      hash_value = 0;
4102      for (alt_state = ((state_t) state)->component_states;
4103           alt_state != NULL;
4104           alt_state = alt_state->next_sorted_alt_state)
4105        hash_value = (((hash_value >> (sizeof (unsigned) - 1) * CHAR_BIT)
4106                       | (hash_value << CHAR_BIT))
4107                      + alt_state->state->unique_num);
4108    }
4109  hash_value = (((hash_value >> (sizeof (unsigned) - 1) * CHAR_BIT)
4110                 | (hash_value << CHAR_BIT))
4111                + ((state_t) state)->automaton->automaton_order_num);
4112  return hash_value;
4113}
4114
4115/* Return nonzero value if the states are the same.  */
4116static int
4117state_eq_p (const void *state_1, const void *state_2)
4118{
4119  alt_state_t alt_state_1;
4120  alt_state_t alt_state_2;
4121
4122  if (((state_t) state_1)->automaton != ((state_t) state_2)->automaton)
4123    return 0;
4124  else if (((state_t) state_1)->component_states == NULL
4125           && ((state_t) state_2)->component_states == NULL)
4126    return reserv_sets_eq (((state_t) state_1)->reservs,
4127			   ((state_t) state_2)->reservs);
4128  else if (((state_t) state_1)->component_states != NULL
4129           && ((state_t) state_2)->component_states != NULL)
4130    {
4131      for (alt_state_1 = ((state_t) state_1)->component_states,
4132           alt_state_2 = ((state_t) state_2)->component_states;
4133           alt_state_1 != NULL && alt_state_2 != NULL;
4134           alt_state_1 = alt_state_1->next_sorted_alt_state,
4135	   alt_state_2 = alt_state_2->next_sorted_alt_state)
4136        /* All state in the list must be already in the hash table.
4137           Also the lists must be sorted.  */
4138        if (alt_state_1->state != alt_state_2->state)
4139          return 0;
4140      return alt_state_1 == alt_state_2;
4141    }
4142  else
4143    return 0;
4144}
4145
4146/* Insert STATE into the state table.  */
4147static state_t
4148insert_state (state_t state)
4149{
4150  void **entry_ptr;
4151
4152  entry_ptr = htab_find_slot (state_table, (void *) state, 1);
4153  if (*entry_ptr == NULL)
4154    *entry_ptr = (void *) state;
4155  return (state_t) *entry_ptr;
4156}
4157
4158/* Add reservation of unit with UNIT_NUM on cycle CYCLE_NUM to
4159   deterministic STATE.  */
4160static void
4161set_state_reserv (state_t state, int cycle_num, int unit_num)
4162{
4163  set_unit_reserv (state->reservs, cycle_num, unit_num);
4164}
4165
4166/* Return nonzero value if the deterministic states contains a
4167   reservation of the same cpu unit on the same cpu cycle.  */
4168static int
4169intersected_state_reservs_p (state_t state1, state_t state2)
4170{
4171  if (state1->automaton != state2->automaton)
4172    abort ();
4173  return reserv_sets_are_intersected (state1->reservs, state2->reservs);
4174}
4175
4176/* Return deterministic state (inserted into the table) which
4177   representing the automaton state which is union of reservations of
4178   the deterministic states masked by RESERVS.  */
4179static state_t
4180states_union (state_t state1, state_t state2, reserv_sets_t reservs)
4181{
4182  state_t result;
4183  state_t state_in_table;
4184
4185  if (state1->automaton != state2->automaton)
4186    abort ();
4187  result = get_free_state (1, state1->automaton);
4188  reserv_sets_or (result->reservs, state1->reservs, state2->reservs);
4189  reserv_sets_and (result->reservs, result->reservs, reservs);
4190  state_in_table = insert_state (result);
4191  if (result != state_in_table)
4192    {
4193      free_state (result);
4194      result = state_in_table;
4195    }
4196  return result;
4197}
4198
4199/* Return deterministic state (inserted into the table) which
4200   represent the automaton state is obtained from deterministic STATE
4201   by advancing cpu cycle and masking by RESERVS.  */
4202static state_t
4203state_shift (state_t state, reserv_sets_t reservs)
4204{
4205  state_t result;
4206  state_t state_in_table;
4207
4208  result = get_free_state (1, state->automaton);
4209  reserv_sets_shift (result->reservs, state->reservs);
4210  reserv_sets_and (result->reservs, result->reservs, reservs);
4211  state_in_table = insert_state (result);
4212  if (result != state_in_table)
4213    {
4214      free_state (result);
4215      result = state_in_table;
4216    }
4217  return result;
4218}
4219
4220/* Initialization of the abstract data.  */
4221static void
4222initiate_states (void)
4223{
4224  decl_t decl;
4225  int i;
4226
4227  VLA_PTR_CREATE (units_container, description->units_num, "units_container");
4228  units_array
4229    = (description->decls_num && description->units_num
4230       ? VLA_PTR_BEGIN (units_container) : NULL);
4231  for (i = 0; i < description->decls_num; i++)
4232    {
4233      decl = description->decls [i];
4234      if (decl->mode == dm_unit)
4235	units_array [DECL_UNIT (decl)->unit_num] = DECL_UNIT (decl);
4236    }
4237  max_cycles_num = description->max_insn_reserv_cycles;
4238  els_in_cycle_reserv
4239    = ((description->units_num + sizeof (set_el_t) * CHAR_BIT - 1)
4240       / (sizeof (set_el_t) * CHAR_BIT));
4241  els_in_reservs = els_in_cycle_reserv * max_cycles_num;
4242  curr_unique_state_num = 0;
4243  initiate_alt_states ();
4244  VLA_PTR_CREATE (free_states, 1500, "free states");
4245  state_table = htab_create (1500, state_hash, state_eq_p, (htab_del) 0);
4246  temp_reserv = alloc_empty_reserv_sets ();
4247}
4248
4249/* Finishing work with the abstract data.  */
4250static void
4251finish_states (void)
4252{
4253  VLA_PTR_DELETE (units_container);
4254  htab_delete (state_table);
4255  VLA_PTR_DELETE (free_states);
4256  finish_alt_states ();
4257}
4258
4259
4260
4261/* Abstract data `arcs'.  */
4262
4263/* List of free arcs.  */
4264static arc_t first_free_arc;
4265
4266#ifndef NDEBUG
4267/* The following variables is maximal number of allocated nodes
4268   `arc'.  */
4269static int allocated_arcs_num = 0;
4270#endif
4271
4272/* The function frees node ARC.  */
4273static void
4274free_arc (arc_t arc)
4275{
4276  arc->next_out_arc = first_free_arc;
4277  first_free_arc = arc;
4278}
4279
4280/* The function removes and frees ARC staring from FROM_STATE.  */
4281static void
4282remove_arc (state_t from_state, arc_t arc)
4283{
4284  arc_t prev_arc;
4285  arc_t curr_arc;
4286
4287  if (arc == NULL)
4288    abort ();
4289  for (prev_arc = NULL, curr_arc = from_state->first_out_arc;
4290       curr_arc != NULL;
4291       prev_arc = curr_arc, curr_arc = curr_arc->next_out_arc)
4292    if (curr_arc == arc)
4293      break;
4294  if (curr_arc == NULL)
4295    abort ();
4296  if (prev_arc == NULL)
4297    from_state->first_out_arc = arc->next_out_arc;
4298  else
4299    prev_arc->next_out_arc = arc->next_out_arc;
4300  free_arc (arc);
4301}
4302
4303/* The functions returns arc with given characteristics (or NULL if
4304   the arc does not exist).  */
4305static arc_t
4306find_arc (state_t from_state, state_t to_state, ainsn_t insn)
4307{
4308  arc_t arc;
4309
4310  for (arc = first_out_arc (from_state); arc != NULL; arc = next_out_arc (arc))
4311    if (arc->to_state == to_state && arc->insn == insn)
4312      return arc;
4313  return NULL;
4314}
4315
4316/* The function adds arc from FROM_STATE to TO_STATE marked by AINSN
4317   and with given STATE_ALTS.  The function returns added arc (or
4318   already existing arc).  */
4319static arc_t
4320add_arc (state_t from_state, state_t to_state, ainsn_t ainsn,
4321	 int state_alts)
4322{
4323  arc_t new_arc;
4324
4325  new_arc = find_arc (from_state, to_state, ainsn);
4326  if (new_arc != NULL)
4327    return new_arc;
4328  if (first_free_arc == NULL)
4329    {
4330#ifndef NDEBUG
4331      allocated_arcs_num++;
4332#endif
4333      new_arc = create_node (sizeof (struct arc));
4334      new_arc->to_state = NULL;
4335      new_arc->insn = NULL;
4336      new_arc->next_out_arc = NULL;
4337    }
4338  else
4339    {
4340      new_arc = first_free_arc;
4341      first_free_arc =  first_free_arc->next_out_arc;
4342    }
4343  new_arc->to_state = to_state;
4344  new_arc->insn = ainsn;
4345  ainsn->arc_exists_p = 1;
4346  new_arc->next_out_arc = from_state->first_out_arc;
4347  from_state->first_out_arc = new_arc;
4348  new_arc->next_arc_marked_by_insn = NULL;
4349  new_arc->state_alts = state_alts;
4350  return new_arc;
4351}
4352
4353/* The function returns the first arc starting from STATE.  */
4354static arc_t
4355first_out_arc (state_t state)
4356{
4357  return state->first_out_arc;
4358}
4359
4360/* The function returns next out arc after ARC.  */
4361static arc_t
4362next_out_arc (arc_t arc)
4363{
4364  return arc->next_out_arc;
4365}
4366
4367/* Initialization of the abstract data.  */
4368static void
4369initiate_arcs (void)
4370{
4371  first_free_arc = NULL;
4372}
4373
4374/* Finishing work with the abstract data.  */
4375static void
4376finish_arcs (void)
4377{
4378}
4379
4380
4381
4382/* Abstract data `automata lists'.  */
4383
4384/* List of free states.  */
4385static automata_list_el_t first_free_automata_list_el;
4386
4387/* The list being formed.  */
4388static automata_list_el_t current_automata_list;
4389
4390/* Hash table of automata lists.  */
4391static htab_t automata_list_table;
4392
4393/* The following function returns free automata list el.  It may be
4394   new allocated node or node freed earlier.  */
4395static automata_list_el_t
4396get_free_automata_list_el (void)
4397{
4398  automata_list_el_t result;
4399
4400  if (first_free_automata_list_el != NULL)
4401    {
4402      result = first_free_automata_list_el;
4403      first_free_automata_list_el
4404	= first_free_automata_list_el->next_automata_list_el;
4405    }
4406  else
4407    result = create_node (sizeof (struct automata_list_el));
4408  result->automaton = NULL;
4409  result->next_automata_list_el = NULL;
4410  return result;
4411}
4412
4413/* The function frees node AUTOMATA_LIST_EL.  */
4414static void
4415free_automata_list_el (automata_list_el_t automata_list_el)
4416{
4417  if (automata_list_el == NULL)
4418    return;
4419  automata_list_el->next_automata_list_el = first_free_automata_list_el;
4420  first_free_automata_list_el = automata_list_el;
4421}
4422
4423/* The function frees list AUTOMATA_LIST.  */
4424static void
4425free_automata_list (automata_list_el_t automata_list)
4426{
4427  automata_list_el_t curr_automata_list_el;
4428  automata_list_el_t next_automata_list_el;
4429
4430  for (curr_automata_list_el = automata_list;
4431       curr_automata_list_el != NULL;
4432       curr_automata_list_el = next_automata_list_el)
4433    {
4434      next_automata_list_el = curr_automata_list_el->next_automata_list_el;
4435      free_automata_list_el (curr_automata_list_el);
4436    }
4437}
4438
4439/* Hash value of AUTOMATA_LIST.  */
4440static hashval_t
4441automata_list_hash (const void *automata_list)
4442{
4443  unsigned int hash_value;
4444  automata_list_el_t curr_automata_list_el;
4445
4446  hash_value = 0;
4447  for (curr_automata_list_el = (automata_list_el_t) automata_list;
4448       curr_automata_list_el != NULL;
4449       curr_automata_list_el = curr_automata_list_el->next_automata_list_el)
4450    hash_value = (((hash_value >> (sizeof (unsigned) - 1) * CHAR_BIT)
4451		   | (hash_value << CHAR_BIT))
4452		  + curr_automata_list_el->automaton->automaton_order_num);
4453  return hash_value;
4454}
4455
4456/* Return nonzero value if the automata_lists are the same.  */
4457static int
4458automata_list_eq_p (const void *automata_list_1, const void *automata_list_2)
4459{
4460  automata_list_el_t automata_list_el_1;
4461  automata_list_el_t automata_list_el_2;
4462
4463  for (automata_list_el_1 = (automata_list_el_t) automata_list_1,
4464	 automata_list_el_2 = (automata_list_el_t) automata_list_2;
4465       automata_list_el_1 != NULL && automata_list_el_2 != NULL;
4466       automata_list_el_1 = automata_list_el_1->next_automata_list_el,
4467	 automata_list_el_2 = automata_list_el_2->next_automata_list_el)
4468    if (automata_list_el_1->automaton != automata_list_el_2->automaton)
4469      return 0;
4470  return automata_list_el_1 == automata_list_el_2;
4471}
4472
4473/* Initialization of the abstract data.  */
4474static void
4475initiate_automata_lists (void)
4476{
4477  first_free_automata_list_el = NULL;
4478  automata_list_table = htab_create (1500, automata_list_hash,
4479				     automata_list_eq_p, (htab_del) 0);
4480}
4481
4482/* The following function starts new automata list and makes it the
4483   current one.  */
4484static void
4485automata_list_start (void)
4486{
4487  current_automata_list = NULL;
4488}
4489
4490/* The following function adds AUTOMATON to the current list.  */
4491static void
4492automata_list_add (automaton_t automaton)
4493{
4494  automata_list_el_t el;
4495
4496  el = get_free_automata_list_el ();
4497  el->automaton = automaton;
4498  el->next_automata_list_el = current_automata_list;
4499  current_automata_list = el;
4500}
4501
4502/* The following function finishes forming the current list, inserts
4503   it into the table and returns it.  */
4504static automata_list_el_t
4505automata_list_finish (void)
4506{
4507  void **entry_ptr;
4508
4509  if (current_automata_list == NULL)
4510    return NULL;
4511  entry_ptr = htab_find_slot (automata_list_table,
4512			      (void *) current_automata_list, 1);
4513  if (*entry_ptr == NULL)
4514    *entry_ptr = (void *) current_automata_list;
4515  else
4516    free_automata_list (current_automata_list);
4517  current_automata_list = NULL;
4518  return (automata_list_el_t) *entry_ptr;
4519}
4520
4521/* Finishing work with the abstract data.  */
4522static void
4523finish_automata_lists (void)
4524{
4525  htab_delete (automata_list_table);
4526}
4527
4528
4529
4530/* The page contains abstract data for work with exclusion sets (see
4531   exclusion_set in file rtl.def).  */
4532
4533/* The following variable refers to an exclusion set returned by
4534   get_excl_set.  This is bit string of length equal to cpu units
4535   number.  If exclusion set for given unit contains 1 for a unit,
4536   then simultaneous reservation of the units is prohibited.  */
4537static reserv_sets_t excl_set;
4538
4539/* The array contains exclusion sets for each unit.  */
4540static reserv_sets_t *unit_excl_set_table;
4541
4542/* The following function forms the array containing exclusion sets
4543   for each unit.  */
4544static void
4545initiate_excl_sets (void)
4546{
4547  decl_t decl;
4548  reserv_sets_t unit_excl_set;
4549  unit_set_el_t el;
4550  int i;
4551
4552  obstack_blank (&irp, els_in_cycle_reserv * sizeof (set_el_t));
4553  excl_set = (reserv_sets_t) obstack_base (&irp);
4554  obstack_finish (&irp);
4555  obstack_blank (&irp, description->units_num * sizeof (reserv_sets_t));
4556  unit_excl_set_table = (reserv_sets_t *) obstack_base (&irp);
4557  obstack_finish (&irp);
4558  /* Evaluate unit exclusion sets.  */
4559  for (i = 0; i < description->decls_num; i++)
4560    {
4561      decl = description->decls [i];
4562      if (decl->mode == dm_unit)
4563	{
4564	  obstack_blank (&irp, els_in_cycle_reserv * sizeof (set_el_t));
4565	  unit_excl_set = (reserv_sets_t) obstack_base (&irp);
4566	  obstack_finish (&irp);
4567	  memset (unit_excl_set, 0, els_in_cycle_reserv * sizeof (set_el_t));
4568	  for (el = DECL_UNIT (decl)->excl_list;
4569	       el != NULL;
4570	       el = el->next_unit_set_el)
4571	    {
4572	      SET_BIT (unit_excl_set, el->unit_decl->unit_num);
4573	      el->unit_decl->in_set_p = TRUE;
4574	    }
4575          unit_excl_set_table [DECL_UNIT (decl)->unit_num] = unit_excl_set;
4576        }
4577    }
4578}
4579
4580/* The function sets up and return EXCL_SET which is union of
4581   exclusion sets for each unit in IN_SET.  */
4582static reserv_sets_t
4583get_excl_set (reserv_sets_t in_set)
4584{
4585  int excl_char_num;
4586  int chars_num;
4587  int i;
4588  int start_unit_num;
4589  int unit_num;
4590
4591  chars_num = els_in_cycle_reserv * sizeof (set_el_t);
4592  memset (excl_set, 0, chars_num);
4593  for (excl_char_num = 0; excl_char_num < chars_num; excl_char_num++)
4594    if (((unsigned char *) in_set) [excl_char_num])
4595      for (i = CHAR_BIT - 1; i >= 0; i--)
4596	if ((((unsigned char *) in_set) [excl_char_num] >> i) & 1)
4597	  {
4598	    start_unit_num = excl_char_num * CHAR_BIT + i;
4599	    if (start_unit_num >= description->units_num)
4600	      return excl_set;
4601	    for (unit_num = 0; unit_num < els_in_cycle_reserv; unit_num++)
4602	      {
4603		excl_set [unit_num]
4604		  |= unit_excl_set_table [start_unit_num] [unit_num];
4605	      }
4606	  }
4607  return excl_set;
4608}
4609
4610
4611
4612/* The page contains abstract data for work with presence/absence
4613   pattern sets (see presence_set/absence_set in file rtl.def).  */
4614
4615/* The following arrays contain correspondingly presence, final
4616   presence, absence, and final absence patterns for each unit.  */
4617static pattern_reserv_t *unit_presence_set_table;
4618static pattern_reserv_t *unit_final_presence_set_table;
4619static pattern_reserv_t *unit_absence_set_table;
4620static pattern_reserv_t *unit_final_absence_set_table;
4621
4622/* The following function forms list of reservation sets for given
4623   PATTERN_LIST.  */
4624static pattern_reserv_t
4625form_reserv_sets_list (pattern_set_el_t pattern_list)
4626{
4627  pattern_set_el_t el;
4628  pattern_reserv_t first, curr, prev;
4629  int i;
4630
4631  prev = first = NULL;
4632  for (el = pattern_list; el != NULL; el = el->next_pattern_set_el)
4633    {
4634      curr = create_node (sizeof (struct pattern_reserv));
4635      curr->reserv = alloc_empty_reserv_sets ();
4636      curr->next_pattern_reserv = NULL;
4637      for (i = 0; i < el->units_num; i++)
4638	{
4639	  SET_BIT (curr->reserv, el->unit_decls [i]->unit_num);
4640	  el->unit_decls [i]->in_set_p = TRUE;
4641	}
4642      if (prev != NULL)
4643	prev->next_pattern_reserv = curr;
4644      else
4645	first = curr;
4646      prev = curr;
4647    }
4648  return first;
4649}
4650
4651 /* The following function forms the array containing presence and
4652   absence pattern sets for each unit.  */
4653static void
4654initiate_presence_absence_pattern_sets (void)
4655{
4656  decl_t decl;
4657  int i;
4658
4659  obstack_blank (&irp, description->units_num * sizeof (pattern_reserv_t));
4660  unit_presence_set_table = (pattern_reserv_t *) obstack_base (&irp);
4661  obstack_finish (&irp);
4662  obstack_blank (&irp, description->units_num * sizeof (pattern_reserv_t));
4663  unit_final_presence_set_table = (pattern_reserv_t *) obstack_base (&irp);
4664  obstack_finish (&irp);
4665  obstack_blank (&irp, description->units_num * sizeof (pattern_reserv_t));
4666  unit_absence_set_table = (pattern_reserv_t *) obstack_base (&irp);
4667  obstack_finish (&irp);
4668  obstack_blank (&irp, description->units_num * sizeof (pattern_reserv_t));
4669  unit_final_absence_set_table = (pattern_reserv_t *) obstack_base (&irp);
4670  obstack_finish (&irp);
4671  /* Evaluate unit presence/absence sets.  */
4672  for (i = 0; i < description->decls_num; i++)
4673    {
4674      decl = description->decls [i];
4675      if (decl->mode == dm_unit)
4676	{
4677          unit_presence_set_table [DECL_UNIT (decl)->unit_num]
4678	    = form_reserv_sets_list (DECL_UNIT (decl)->presence_list);
4679          unit_final_presence_set_table [DECL_UNIT (decl)->unit_num]
4680	    = form_reserv_sets_list (DECL_UNIT (decl)->final_presence_list);
4681          unit_absence_set_table [DECL_UNIT (decl)->unit_num]
4682	    = form_reserv_sets_list (DECL_UNIT (decl)->absence_list);
4683          unit_final_absence_set_table [DECL_UNIT (decl)->unit_num]
4684	    = form_reserv_sets_list (DECL_UNIT (decl)->final_absence_list);
4685        }
4686    }
4687}
4688
4689/* The function checks that CHECKED_SET satisfies all presence pattern
4690   sets for units in ORIGIONAL_SET.  The function returns TRUE if it
4691   is ok.  */
4692static int
4693check_presence_pattern_sets (reserv_sets_t checked_set,
4694			     reserv_sets_t origional_set,
4695			     int final_p)
4696{
4697  int char_num;
4698  int chars_num;
4699  int i;
4700  int start_unit_num;
4701  int unit_num;
4702  int presence_p;
4703  pattern_reserv_t pat_reserv;
4704
4705  chars_num = els_in_cycle_reserv * sizeof (set_el_t);
4706  for (char_num = 0; char_num < chars_num; char_num++)
4707    if (((unsigned char *) origional_set) [char_num])
4708      for (i = CHAR_BIT - 1; i >= 0; i--)
4709	if ((((unsigned char *) origional_set) [char_num] >> i) & 1)
4710	  {
4711	    start_unit_num = char_num * CHAR_BIT + i;
4712	    if (start_unit_num >= description->units_num)
4713	      break;
4714	    if ((final_p
4715		 && unit_final_presence_set_table [start_unit_num] == NULL)
4716		|| (!final_p
4717		    && unit_presence_set_table [start_unit_num] == NULL))
4718	      continue;
4719	    presence_p = FALSE;
4720	    for (pat_reserv = (final_p
4721			       ? unit_final_presence_set_table [start_unit_num]
4722			       : unit_presence_set_table [start_unit_num]);
4723		 pat_reserv != NULL;
4724		 pat_reserv = pat_reserv->next_pattern_reserv)
4725	      {
4726		for (unit_num = 0; unit_num < els_in_cycle_reserv; unit_num++)
4727		  if ((checked_set [unit_num] & pat_reserv->reserv [unit_num])
4728		      != pat_reserv->reserv [unit_num])
4729		    break;
4730		presence_p = presence_p || unit_num >= els_in_cycle_reserv;
4731	      }
4732	    if (!presence_p)
4733	      return FALSE;
4734	  }
4735  return TRUE;
4736}
4737
4738/* The function checks that CHECKED_SET satisfies all absence pattern
4739   sets for units in ORIGIONAL_SET.  The function returns TRUE if it
4740   is ok.  */
4741static int
4742check_absence_pattern_sets (reserv_sets_t checked_set,
4743			    reserv_sets_t origional_set,
4744			    int final_p)
4745{
4746  int char_num;
4747  int chars_num;
4748  int i;
4749  int start_unit_num;
4750  int unit_num;
4751  pattern_reserv_t pat_reserv;
4752
4753  chars_num = els_in_cycle_reserv * sizeof (set_el_t);
4754  for (char_num = 0; char_num < chars_num; char_num++)
4755    if (((unsigned char *) origional_set) [char_num])
4756      for (i = CHAR_BIT - 1; i >= 0; i--)
4757	if ((((unsigned char *) origional_set) [char_num] >> i) & 1)
4758	  {
4759	    start_unit_num = char_num * CHAR_BIT + i;
4760	    if (start_unit_num >= description->units_num)
4761	      break;
4762	    for (pat_reserv = (final_p
4763			       ? unit_final_absence_set_table [start_unit_num]
4764			       : unit_absence_set_table [start_unit_num]);
4765		 pat_reserv != NULL;
4766		 pat_reserv = pat_reserv->next_pattern_reserv)
4767	      {
4768		for (unit_num = 0; unit_num < els_in_cycle_reserv; unit_num++)
4769		  if ((checked_set [unit_num] & pat_reserv->reserv [unit_num])
4770		      != pat_reserv->reserv [unit_num]
4771		      && pat_reserv->reserv [unit_num])
4772		    break;
4773		if (unit_num >= els_in_cycle_reserv)
4774		  return FALSE;
4775	      }
4776	  }
4777  return TRUE;
4778}
4779
4780
4781
4782/* This page contains code for transformation of original reservations
4783   described in .md file.  The main goal of transformations is
4784   simplifying reservation and lifting up all `|' on the top of IR
4785   reservation representation.  */
4786
4787
4788/* The following function makes copy of IR representation of
4789   reservation.  The function also substitutes all reservations
4790   defined by define_reservation by corresponding value during making
4791   the copy.  */
4792static regexp_t
4793copy_insn_regexp (regexp_t regexp)
4794{
4795  regexp_t  result;
4796  int i;
4797
4798  if (regexp->mode == rm_reserv)
4799    result = copy_insn_regexp (REGEXP_RESERV (regexp)->reserv_decl->regexp);
4800  else if (regexp->mode == rm_unit)
4801    result = copy_node (regexp, sizeof (struct regexp));
4802  else if (regexp->mode == rm_repeat)
4803    {
4804      result = copy_node (regexp, sizeof (struct regexp));
4805      REGEXP_REPEAT (result)->regexp
4806        = copy_insn_regexp (REGEXP_REPEAT (regexp)->regexp);
4807    }
4808  else if (regexp->mode == rm_sequence)
4809    {
4810      result = copy_node (regexp,
4811                          sizeof (struct regexp) + sizeof (regexp_t)
4812			  * (REGEXP_SEQUENCE (regexp)->regexps_num - 1));
4813      for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
4814	REGEXP_SEQUENCE (result)->regexps [i]
4815	  = copy_insn_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
4816    }
4817  else if (regexp->mode == rm_allof)
4818    {
4819      result = copy_node (regexp,
4820                          sizeof (struct regexp) + sizeof (regexp_t)
4821			  * (REGEXP_ALLOF (regexp)->regexps_num - 1));
4822      for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
4823	REGEXP_ALLOF (result)->regexps [i]
4824	  = copy_insn_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
4825    }
4826  else if (regexp->mode == rm_oneof)
4827    {
4828      result = copy_node (regexp,
4829                          sizeof (struct regexp) + sizeof (regexp_t)
4830			  * (REGEXP_ONEOF (regexp)->regexps_num - 1));
4831      for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
4832	REGEXP_ONEOF (result)->regexps [i]
4833	  = copy_insn_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
4834    }
4835  else
4836    {
4837      if (regexp->mode != rm_nothing)
4838	abort ();
4839      result = copy_node (regexp, sizeof (struct regexp));
4840    }
4841  return result;
4842}
4843
4844/* The following variable is set up 1 if a transformation has been
4845   applied.  */
4846static int regexp_transformed_p;
4847
4848/* The function makes transformation
4849   A*N -> A, A, ...  */
4850static regexp_t
4851transform_1 (regexp_t regexp)
4852{
4853  int i;
4854  int repeat_num;
4855  regexp_t operand;
4856  pos_t pos;
4857
4858  if (regexp->mode == rm_repeat)
4859    {
4860      repeat_num = REGEXP_REPEAT (regexp)->repeat_num;
4861      if (repeat_num <= 1)
4862	abort ();
4863      operand = REGEXP_REPEAT (regexp)->regexp;
4864      pos = regexp->mode;
4865      regexp = create_node (sizeof (struct regexp) + sizeof (regexp_t)
4866			    * (repeat_num - 1));
4867      regexp->mode = rm_sequence;
4868      regexp->pos = pos;
4869      REGEXP_SEQUENCE (regexp)->regexps_num = repeat_num;
4870      for (i = 0; i < repeat_num; i++)
4871	REGEXP_SEQUENCE (regexp)->regexps [i] = copy_insn_regexp (operand);
4872      regexp_transformed_p = 1;
4873    }
4874  return regexp;
4875}
4876
4877/* The function makes transformations
4878   ...,(A,B,...),C,... -> ...,A,B,...,C,...
4879   ...+(A+B+...)+C+... -> ...+A+B+...+C+...
4880   ...|(A|B|...)|C|... -> ...|A|B|...|C|...  */
4881static regexp_t
4882transform_2 (regexp_t regexp)
4883{
4884  if (regexp->mode == rm_sequence)
4885    {
4886      regexp_t sequence = NULL;
4887      regexp_t result;
4888      int sequence_index = 0;
4889      int i, j;
4890
4891      for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
4892	if (REGEXP_SEQUENCE (regexp)->regexps [i]->mode == rm_sequence)
4893	  {
4894	    sequence_index = i;
4895	    sequence = REGEXP_SEQUENCE (regexp)->regexps [i];
4896	    break;
4897	  }
4898      if (i < REGEXP_SEQUENCE (regexp)->regexps_num)
4899	{
4900	  if ( REGEXP_SEQUENCE (sequence)->regexps_num <= 1
4901	      || REGEXP_SEQUENCE (regexp)->regexps_num <= 1)
4902	    abort ();
4903	  result = create_node (sizeof (struct regexp)
4904                                + sizeof (regexp_t)
4905				* (REGEXP_SEQUENCE (regexp)->regexps_num
4906                                   + REGEXP_SEQUENCE (sequence)->regexps_num
4907                                   - 2));
4908	  result->mode = rm_sequence;
4909	  result->pos = regexp->pos;
4910	  REGEXP_SEQUENCE (result)->regexps_num
4911            = (REGEXP_SEQUENCE (regexp)->regexps_num
4912               + REGEXP_SEQUENCE (sequence)->regexps_num - 1);
4913	  for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
4914            if (i < sequence_index)
4915              REGEXP_SEQUENCE (result)->regexps [i]
4916                = copy_insn_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
4917            else if (i > sequence_index)
4918              REGEXP_SEQUENCE (result)->regexps
4919                [i + REGEXP_SEQUENCE (sequence)->regexps_num - 1]
4920                = copy_insn_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
4921            else
4922              for (j = 0; j < REGEXP_SEQUENCE (sequence)->regexps_num; j++)
4923                REGEXP_SEQUENCE (result)->regexps [i + j]
4924                  = copy_insn_regexp (REGEXP_SEQUENCE (sequence)->regexps [j]);
4925	  regexp_transformed_p = 1;
4926	  regexp = result;
4927	}
4928    }
4929  else if (regexp->mode == rm_allof)
4930    {
4931      regexp_t allof = NULL;
4932      regexp_t result;
4933      int allof_index = 0;
4934      int i, j;
4935
4936      for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
4937	if (REGEXP_ALLOF (regexp)->regexps [i]->mode == rm_allof)
4938	  {
4939	    allof_index = i;
4940	    allof = REGEXP_ALLOF (regexp)->regexps [i];
4941	    break;
4942	  }
4943      if (i < REGEXP_ALLOF (regexp)->regexps_num)
4944	{
4945	  if (REGEXP_ALLOF (allof)->regexps_num <= 1
4946	      || REGEXP_ALLOF (regexp)->regexps_num <= 1)
4947	    abort ();
4948	  result = create_node (sizeof (struct regexp)
4949                                + sizeof (regexp_t)
4950				* (REGEXP_ALLOF (regexp)->regexps_num
4951                                   + REGEXP_ALLOF (allof)->regexps_num - 2));
4952	  result->mode = rm_allof;
4953	  result->pos = regexp->pos;
4954	  REGEXP_ALLOF (result)->regexps_num
4955            = (REGEXP_ALLOF (regexp)->regexps_num
4956               + REGEXP_ALLOF (allof)->regexps_num - 1);
4957	  for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
4958            if (i < allof_index)
4959              REGEXP_ALLOF (result)->regexps [i]
4960                = copy_insn_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
4961            else if (i > allof_index)
4962              REGEXP_ALLOF (result)->regexps
4963                [i + REGEXP_ALLOF (allof)->regexps_num - 1]
4964                = copy_insn_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
4965            else
4966              for (j = 0; j < REGEXP_ALLOF (allof)->regexps_num; j++)
4967                REGEXP_ALLOF (result)->regexps [i + j]
4968                  = copy_insn_regexp (REGEXP_ALLOF (allof)->regexps [j]);
4969	  regexp_transformed_p = 1;
4970	  regexp = result;
4971	}
4972    }
4973  else if (regexp->mode == rm_oneof)
4974    {
4975      regexp_t oneof = NULL;
4976      regexp_t result;
4977      int oneof_index = 0;
4978      int i, j;
4979
4980      for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
4981	if (REGEXP_ONEOF (regexp)->regexps [i]->mode == rm_oneof)
4982	  {
4983	    oneof_index = i;
4984	    oneof = REGEXP_ONEOF (regexp)->regexps [i];
4985	    break;
4986	  }
4987      if (i < REGEXP_ONEOF (regexp)->regexps_num)
4988	{
4989	  if (REGEXP_ONEOF (oneof)->regexps_num <= 1
4990	      || REGEXP_ONEOF (regexp)->regexps_num <= 1)
4991	    abort ();
4992	  result = create_node (sizeof (struct regexp)
4993				+ sizeof (regexp_t)
4994				* (REGEXP_ONEOF (regexp)->regexps_num
4995                                   + REGEXP_ONEOF (oneof)->regexps_num - 2));
4996	  result->mode = rm_oneof;
4997	  result->pos = regexp->pos;
4998	  REGEXP_ONEOF (result)->regexps_num
4999	    = (REGEXP_ONEOF (regexp)->regexps_num
5000               + REGEXP_ONEOF (oneof)->regexps_num - 1);
5001	  for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
5002            if (i < oneof_index)
5003              REGEXP_ONEOF (result)->regexps [i]
5004                = copy_insn_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
5005            else if (i > oneof_index)
5006              REGEXP_ONEOF (result)->regexps
5007                [i + REGEXP_ONEOF (oneof)->regexps_num - 1]
5008                = copy_insn_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
5009            else
5010              for (j = 0; j < REGEXP_ONEOF (oneof)->regexps_num; j++)
5011                REGEXP_ONEOF (result)->regexps [i + j]
5012                  = copy_insn_regexp (REGEXP_ONEOF (oneof)->regexps [j]);
5013	  regexp_transformed_p = 1;
5014	  regexp = result;
5015	}
5016    }
5017  return regexp;
5018}
5019
5020/* The function makes transformations
5021   ...,A|B|...,C,... -> (...,A,C,...)|(...,B,C,...)|...
5022   ...+(A|B|...)+C+... -> (...+A+C+...)|(...+B+C+...)|...
5023   ...+(A,B,...)+C+... -> (...+A+C+...),B,...
5024   ...+(A,B,...)+(C,D,...) -> (A+C),(B+D),...  */
5025static regexp_t
5026transform_3 (regexp_t regexp)
5027{
5028  if (regexp->mode == rm_sequence)
5029    {
5030      regexp_t oneof = NULL;
5031      int oneof_index = 0;
5032      regexp_t result;
5033      regexp_t sequence;
5034      int i, j;
5035
5036      for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
5037	if (REGEXP_SEQUENCE (regexp)->regexps [i]->mode == rm_oneof)
5038	  {
5039	    oneof_index = i;
5040	    oneof = REGEXP_SEQUENCE (regexp)->regexps [i];
5041	    break;
5042	  }
5043      if (i < REGEXP_SEQUENCE (regexp)->regexps_num)
5044	{
5045	  if (REGEXP_ONEOF (oneof)->regexps_num <= 1
5046	      || REGEXP_SEQUENCE (regexp)->regexps_num <= 1)
5047	    abort ();
5048	  result = create_node (sizeof (struct regexp)
5049				+ sizeof (regexp_t)
5050				* (REGEXP_ONEOF (oneof)->regexps_num - 1));
5051	  result->mode = rm_oneof;
5052	  result->pos = regexp->pos;
5053	  REGEXP_ONEOF (result)->regexps_num
5054	    = REGEXP_ONEOF (oneof)->regexps_num;
5055	  for (i = 0; i < REGEXP_ONEOF (result)->regexps_num; i++)
5056	    {
5057	      sequence
5058                = create_node (sizeof (struct regexp)
5059                               + sizeof (regexp_t)
5060                               * (REGEXP_SEQUENCE (regexp)->regexps_num - 1));
5061	      sequence->mode = rm_sequence;
5062	      sequence->pos = regexp->pos;
5063	      REGEXP_SEQUENCE (sequence)->regexps_num
5064                = REGEXP_SEQUENCE (regexp)->regexps_num;
5065              REGEXP_ONEOF (result)->regexps [i] = sequence;
5066	      for (j = 0; j < REGEXP_SEQUENCE (sequence)->regexps_num; j++)
5067		if (j != oneof_index)
5068		  REGEXP_SEQUENCE (sequence)->regexps [j]
5069		    = copy_insn_regexp (REGEXP_SEQUENCE (regexp)->regexps [j]);
5070		else
5071		  REGEXP_SEQUENCE (sequence)->regexps [j]
5072		    = copy_insn_regexp (REGEXP_ONEOF (oneof)->regexps [i]);
5073	    }
5074	  regexp_transformed_p = 1;
5075	  regexp = result;
5076	}
5077    }
5078  else if (regexp->mode == rm_allof)
5079    {
5080      regexp_t oneof = NULL;
5081      regexp_t seq;
5082      int oneof_index = 0;
5083      int max_seq_length, allof_length;
5084      regexp_t result;
5085      regexp_t allof = NULL;
5086      regexp_t allof_op = NULL;
5087      int i, j;
5088
5089      for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
5090	if (REGEXP_ALLOF (regexp)->regexps [i]->mode == rm_oneof)
5091	  {
5092	    oneof_index = i;
5093	    oneof = REGEXP_ALLOF (regexp)->regexps [i];
5094	    break;
5095	  }
5096      if (i < REGEXP_ALLOF (regexp)->regexps_num)
5097	{
5098	  if (REGEXP_ONEOF (oneof)->regexps_num <= 1
5099	      || REGEXP_ALLOF (regexp)->regexps_num <= 1)
5100	    abort ();
5101	  result = create_node (sizeof (struct regexp)
5102				+ sizeof (regexp_t)
5103				* (REGEXP_ONEOF (oneof)->regexps_num - 1));
5104	  result->mode = rm_oneof;
5105	  result->pos = regexp->pos;
5106	  REGEXP_ONEOF (result)->regexps_num
5107	    = REGEXP_ONEOF (oneof)->regexps_num;
5108	  for (i = 0; i < REGEXP_ONEOF (result)->regexps_num; i++)
5109	    {
5110	      allof
5111		= create_node (sizeof (struct regexp)
5112                               + sizeof (regexp_t)
5113			       * (REGEXP_ALLOF (regexp)->regexps_num - 1));
5114	      allof->mode = rm_allof;
5115	      allof->pos = regexp->pos;
5116	      REGEXP_ALLOF (allof)->regexps_num
5117                = REGEXP_ALLOF (regexp)->regexps_num;
5118              REGEXP_ONEOF (result)->regexps [i] = allof;
5119	      for (j = 0; j < REGEXP_ALLOF (allof)->regexps_num; j++)
5120		if (j != oneof_index)
5121		  REGEXP_ALLOF (allof)->regexps [j]
5122		    = copy_insn_regexp (REGEXP_ALLOF (regexp)->regexps [j]);
5123		else
5124		  REGEXP_ALLOF (allof)->regexps [j]
5125		    = copy_insn_regexp (REGEXP_ONEOF (oneof)->regexps [i]);
5126	    }
5127	  regexp_transformed_p = 1;
5128	  regexp = result;
5129	}
5130      max_seq_length = 0;
5131      if (regexp->mode == rm_allof)
5132	for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
5133	  {
5134	    if (REGEXP_ALLOF (regexp)->regexps [i]->mode == rm_sequence)
5135	      {
5136		seq = REGEXP_ALLOF (regexp)->regexps [i];
5137		if (max_seq_length < REGEXP_SEQUENCE (seq)->regexps_num)
5138		  max_seq_length = REGEXP_SEQUENCE (seq)->regexps_num;
5139	      }
5140	    else if (REGEXP_ALLOF (regexp)->regexps [i]->mode != rm_unit
5141		     && REGEXP_ALLOF (regexp)->regexps [i]->mode != rm_nothing)
5142	      {
5143		max_seq_length = 0;
5144		break;
5145	      }
5146	  }
5147      if (max_seq_length != 0)
5148	{
5149	  if (max_seq_length == 1 || REGEXP_ALLOF (regexp)->regexps_num <= 1)
5150	    abort ();
5151	  result = create_node (sizeof (struct regexp)
5152				+ sizeof (regexp_t) * (max_seq_length - 1));
5153	  result->mode = rm_sequence;
5154	  result->pos = regexp->pos;
5155	  REGEXP_SEQUENCE (result)->regexps_num = max_seq_length;
5156	  for (i = 0; i < max_seq_length; i++)
5157	    {
5158	      allof_length = 0;
5159	      for (j = 0; j < REGEXP_ALLOF (regexp)->regexps_num; j++)
5160		if (REGEXP_ALLOF (regexp)->regexps [j]->mode == rm_sequence
5161		    && (i < (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp)
5162					      ->regexps [j])->regexps_num)))
5163		  {
5164		    allof_op
5165		      = (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp)->regexps [j])
5166			 ->regexps [i]);
5167		    allof_length++;
5168		  }
5169		else if (i == 0
5170			 && (REGEXP_ALLOF (regexp)->regexps [j]->mode
5171			     == rm_unit
5172			     || (REGEXP_ALLOF (regexp)->regexps [j]->mode
5173				 == rm_nothing)))
5174		  {
5175		    allof_op = REGEXP_ALLOF (regexp)->regexps [j];
5176		    allof_length++;
5177		  }
5178	      if (allof_length == 1)
5179		REGEXP_SEQUENCE (result)->regexps [i] = allof_op;
5180	      else
5181		{
5182		  allof = create_node (sizeof (struct regexp)
5183				       + sizeof (regexp_t)
5184				       * (allof_length - 1));
5185		  allof->mode = rm_allof;
5186		  allof->pos = regexp->pos;
5187		  REGEXP_ALLOF (allof)->regexps_num = allof_length;
5188		  REGEXP_SEQUENCE (result)->regexps [i] = allof;
5189		  allof_length = 0;
5190		  for (j = 0; j < REGEXP_ALLOF (regexp)->regexps_num; j++)
5191		    if (REGEXP_ALLOF (regexp)->regexps [j]->mode == rm_sequence
5192			&& (i <
5193			    (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp)
5194					      ->regexps [j])->regexps_num)))
5195		      {
5196			allof_op = (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp)
5197						     ->regexps [j])
5198				    ->regexps [i]);
5199			REGEXP_ALLOF (allof)->regexps [allof_length]
5200			  = allof_op;
5201			allof_length++;
5202		      }
5203		    else if (i == 0
5204			     && (REGEXP_ALLOF (regexp)->regexps [j]->mode
5205				 == rm_unit
5206				 || (REGEXP_ALLOF (regexp)->regexps [j]->mode
5207				     == rm_nothing)))
5208		      {
5209			allof_op = REGEXP_ALLOF (regexp)->regexps [j];
5210			REGEXP_ALLOF (allof)->regexps [allof_length]
5211			  = allof_op;
5212			allof_length++;
5213		      }
5214		}
5215	    }
5216	  regexp_transformed_p = 1;
5217	  regexp = result;
5218	}
5219    }
5220  return regexp;
5221}
5222
5223/* The function traverses IR of reservation and applies transformations
5224   implemented by FUNC.  */
5225static regexp_t
5226regexp_transform_func (regexp_t regexp, regexp_t (*func) (regexp_t regexp))
5227{
5228  int i;
5229
5230  if (regexp->mode == rm_sequence)
5231    for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
5232      REGEXP_SEQUENCE (regexp)->regexps [i]
5233	= regexp_transform_func (REGEXP_SEQUENCE (regexp)->regexps [i], func);
5234  else if (regexp->mode == rm_allof)
5235    for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
5236      REGEXP_ALLOF (regexp)->regexps [i]
5237	= regexp_transform_func (REGEXP_ALLOF (regexp)->regexps [i], func);
5238  else if (regexp->mode == rm_oneof)
5239    for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
5240      REGEXP_ONEOF (regexp)->regexps [i]
5241	= regexp_transform_func (REGEXP_ONEOF (regexp)->regexps [i], func);
5242  else if (regexp->mode == rm_repeat)
5243    REGEXP_REPEAT (regexp)->regexp
5244      = regexp_transform_func (REGEXP_REPEAT (regexp)->regexp, func);
5245  else if (regexp->mode != rm_nothing && regexp->mode != rm_unit)
5246    abort ();
5247  return (*func) (regexp);
5248}
5249
5250/* The function applies all transformations for IR representation of
5251   reservation REGEXP.  */
5252static regexp_t
5253transform_regexp (regexp_t regexp)
5254{
5255  regexp = regexp_transform_func (regexp, transform_1);
5256  do
5257    {
5258      regexp_transformed_p = 0;
5259      regexp = regexp_transform_func (regexp, transform_2);
5260      regexp = regexp_transform_func (regexp, transform_3);
5261    }
5262  while (regexp_transformed_p);
5263  return regexp;
5264}
5265
5266/* The function applies all transformations for reservations of all
5267   insn declarations.  */
5268static void
5269transform_insn_regexps (void)
5270{
5271  decl_t decl;
5272  int i;
5273
5274  transform_time = create_ticker ();
5275  add_advance_cycle_insn_decl ();
5276  if (progress_flag)
5277    fprintf (stderr, "Reservation transformation...");
5278  for (i = 0; i < description->decls_num; i++)
5279    {
5280      decl = description->decls [i];
5281      if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
5282	DECL_INSN_RESERV (decl)->transformed_regexp
5283	  = transform_regexp (copy_insn_regexp
5284			      (DECL_INSN_RESERV (decl)->regexp));
5285    }
5286  if (progress_flag)
5287    fprintf (stderr, "done\n");
5288  ticker_off (&transform_time);
5289}
5290
5291
5292
5293/* The following variable value is TRUE if the first annotated message
5294   about units to automata distribution has been output.  */
5295static int annotation_message_reported_p;
5296
5297/* The following structure describes usage of a unit in a reservation.  */
5298struct unit_usage
5299{
5300  unit_decl_t unit_decl;
5301  /* The following forms a list of units used on the same cycle in the
5302     same alternative.  */
5303  struct unit_usage *next;
5304};
5305
5306/* Obstack for unit_usage structures.  */
5307static struct obstack unit_usages;
5308
5309/* VLA for representation of array of pointers to unit usage
5310   structures.  There is an element for each combination of
5311   (alternative number, cycle).  Unit usages on given cycle in
5312   alternative with given number are referred through element with
5313   index equals to the cycle * number of all alternatives in the regexp
5314   + the alternative number.  */
5315static vla_ptr_t cycle_alt_unit_usages;
5316
5317/* The following function creates the structure unit_usage for UNIT on
5318   CYCLE in REGEXP alternative with ALT_NUM.  The structure is made
5319   accessed through cycle_alt_unit_usages.  */
5320static void
5321store_alt_unit_usage (regexp_t regexp, regexp_t unit, int cycle,
5322		      int alt_num)
5323{
5324  size_t i, length, old_length;
5325  unit_decl_t unit_decl;
5326  struct unit_usage *unit_usage_ptr;
5327  int index;
5328
5329  if (regexp == NULL || regexp->mode != rm_oneof
5330      || alt_num >= REGEXP_ONEOF (regexp)->regexps_num)
5331    abort ();
5332  unit_decl = REGEXP_UNIT (unit)->unit_decl;
5333  old_length = VLA_PTR_LENGTH (cycle_alt_unit_usages);
5334  length = (cycle + 1) * REGEXP_ONEOF (regexp)->regexps_num;
5335  if (old_length < length)
5336    {
5337      VLA_PTR_EXPAND (cycle_alt_unit_usages, length - old_length);
5338      for (i = old_length; i < length; i++)
5339	VLA_PTR (cycle_alt_unit_usages, i) = NULL;
5340    }
5341  obstack_blank (&unit_usages, sizeof (struct unit_usage));
5342  unit_usage_ptr = (struct unit_usage *) obstack_base (&unit_usages);
5343  obstack_finish (&unit_usages);
5344  unit_usage_ptr->unit_decl = unit_decl;
5345  index = cycle * REGEXP_ONEOF (regexp)->regexps_num + alt_num;
5346  unit_usage_ptr->next = VLA_PTR (cycle_alt_unit_usages, index);
5347  VLA_PTR (cycle_alt_unit_usages, index) = unit_usage_ptr;
5348  unit_decl->last_distribution_check_cycle = -1; /* undefined */
5349}
5350
5351/* The function processes given REGEXP to find units with the wrong
5352   distribution.  */
5353static void
5354check_regexp_units_distribution (const char *insn_reserv_name,
5355				 regexp_t regexp)
5356{
5357  int i, j, k, cycle;
5358  regexp_t seq, allof, unit;
5359  struct unit_usage *unit_usage_ptr, *other_unit_usage_ptr;
5360
5361  if (regexp == NULL || regexp->mode != rm_oneof)
5362    return;
5363  /* Store all unit usages in the regexp:  */
5364  obstack_init (&unit_usages);
5365  VLA_PTR_CREATE (cycle_alt_unit_usages, 100, "unit usages on cycles");
5366  for (i = REGEXP_ONEOF (regexp)->regexps_num - 1; i >= 0; i--)
5367    {
5368      seq = REGEXP_ONEOF (regexp)->regexps [i];
5369      if (seq->mode == rm_sequence)
5370	for (j = 0; j < REGEXP_SEQUENCE (seq)->regexps_num; j++)
5371	  {
5372	    allof = REGEXP_SEQUENCE (seq)->regexps [j];
5373	    if (allof->mode == rm_allof)
5374	      for (k = 0; k < REGEXP_ALLOF (allof)->regexps_num; k++)
5375		{
5376		  unit = REGEXP_ALLOF (allof)->regexps [k];
5377		  if (unit->mode == rm_unit)
5378		    store_alt_unit_usage (regexp, unit, j, i);
5379		  else if (unit->mode != rm_nothing)
5380		    abort ();
5381		}
5382	    else if (allof->mode == rm_unit)
5383	      store_alt_unit_usage (regexp, allof, j, i);
5384	    else if (allof->mode != rm_nothing)
5385	      abort ();
5386	  }
5387      else if (seq->mode == rm_allof)
5388	for (k = 0; k < REGEXP_ALLOF (seq)->regexps_num; k++)
5389	  {
5390	    unit = REGEXP_ALLOF (seq)->regexps [k];
5391	    if (unit->mode == rm_unit)
5392	      store_alt_unit_usage (regexp, unit, 0, i);
5393	    else if (unit->mode != rm_nothing)
5394	      abort ();
5395	  }
5396      else if (seq->mode == rm_unit)
5397	store_alt_unit_usage (regexp, seq, 0, i);
5398      else if (seq->mode != rm_nothing)
5399	abort ();
5400    }
5401  /* Check distribution:  */
5402  for (i = 0; i < (int) VLA_PTR_LENGTH (cycle_alt_unit_usages); i++)
5403    {
5404      cycle = i / REGEXP_ONEOF (regexp)->regexps_num;
5405      for (unit_usage_ptr = VLA_PTR (cycle_alt_unit_usages, i);
5406	   unit_usage_ptr != NULL;
5407	   unit_usage_ptr = unit_usage_ptr->next)
5408	if (cycle != unit_usage_ptr->unit_decl->last_distribution_check_cycle)
5409	  {
5410	    unit_usage_ptr->unit_decl->last_distribution_check_cycle = cycle;
5411	    for (k = cycle * REGEXP_ONEOF (regexp)->regexps_num;
5412		 k < (int) VLA_PTR_LENGTH (cycle_alt_unit_usages)
5413		   && k == cycle * REGEXP_ONEOF (regexp)->regexps_num;
5414		 k++)
5415	      {
5416		for (other_unit_usage_ptr = VLA_PTR (cycle_alt_unit_usages, k);
5417		     other_unit_usage_ptr != NULL;
5418		     other_unit_usage_ptr = other_unit_usage_ptr->next)
5419		  if (unit_usage_ptr->unit_decl->automaton_decl
5420		      == other_unit_usage_ptr->unit_decl->automaton_decl)
5421		    break;
5422		if (other_unit_usage_ptr == NULL
5423		    && VLA_PTR (cycle_alt_unit_usages, k) != NULL)
5424		  break;
5425	      }
5426	    if (k < (int) VLA_PTR_LENGTH (cycle_alt_unit_usages)
5427		&& k == cycle * REGEXP_ONEOF (regexp)->regexps_num)
5428	      {
5429		if (!annotation_message_reported_p)
5430		  {
5431		    fprintf (stderr, "\n");
5432		    error ("The following units do not satisfy units-automata distribution rule");
5433		    error (" (A unit of given unit automaton should be on each reserv. altern.)");
5434		    annotation_message_reported_p = TRUE;
5435		  }
5436		error ("Unit %s, reserv. %s, cycle %d",
5437		       unit_usage_ptr->unit_decl->name, insn_reserv_name,
5438		       cycle);
5439	      }
5440	  }
5441    }
5442  VLA_PTR_DELETE (cycle_alt_unit_usages);
5443  obstack_free (&unit_usages, NULL);
5444}
5445
5446/* The function finds units which violates units to automata
5447   distribution rule.  If the units exist, report about them.  */
5448static void
5449check_unit_distributions_to_automata (void)
5450{
5451  decl_t decl;
5452  int i;
5453
5454  if (progress_flag)
5455    fprintf (stderr, "Check unit distributions to automata...");
5456  annotation_message_reported_p = FALSE;
5457  for (i = 0; i < description->decls_num; i++)
5458    {
5459      decl = description->decls [i];
5460      if (decl->mode == dm_insn_reserv)
5461	check_regexp_units_distribution
5462	  (DECL_INSN_RESERV (decl)->name,
5463	   DECL_INSN_RESERV (decl)->transformed_regexp);
5464    }
5465  if (progress_flag)
5466    fprintf (stderr, "done\n");
5467}
5468
5469
5470
5471/* The page contains code for building alt_states (see comments for
5472   IR) describing all possible insns reservations of an automaton.  */
5473
5474/* Current state being formed for which the current alt_state
5475   refers.  */
5476static state_t state_being_formed;
5477
5478/* Current alt_state being formed.  */
5479static alt_state_t alt_state_being_formed;
5480
5481/* This recursive function processes `,' and units in reservation
5482   REGEXP for forming alt_states of AUTOMATON.  It is believed that
5483   CURR_CYCLE is start cycle of all reservation REGEXP.  */
5484static int
5485process_seq_for_forming_states (regexp_t regexp, automaton_t automaton,
5486				int curr_cycle)
5487{
5488  int i;
5489
5490  if (regexp == NULL)
5491    return curr_cycle;
5492  else if (regexp->mode == rm_unit)
5493    {
5494      if (REGEXP_UNIT (regexp)->unit_decl->corresponding_automaton_num
5495          == automaton->automaton_order_num)
5496        set_state_reserv (state_being_formed, curr_cycle,
5497                          REGEXP_UNIT (regexp)->unit_decl->unit_num);
5498      return curr_cycle;
5499    }
5500  else if (regexp->mode == rm_sequence)
5501    {
5502      for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
5503	curr_cycle
5504	  = process_seq_for_forming_states
5505	    (REGEXP_SEQUENCE (regexp)->regexps [i], automaton, curr_cycle) + 1;
5506      return curr_cycle;
5507    }
5508  else if (regexp->mode == rm_allof)
5509    {
5510      int finish_cycle = 0;
5511      int cycle;
5512
5513      for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
5514	{
5515	  cycle = process_seq_for_forming_states (REGEXP_ALLOF (regexp)
5516						  ->regexps [i],
5517						  automaton, curr_cycle);
5518	  if (finish_cycle < cycle)
5519	    finish_cycle = cycle;
5520	}
5521      return finish_cycle;
5522    }
5523  else
5524    {
5525      if (regexp->mode != rm_nothing)
5526	abort ();
5527      return curr_cycle;
5528    }
5529}
5530
5531/* This recursive function finishes forming ALT_STATE of AUTOMATON and
5532   inserts alt_state into the table.  */
5533static void
5534finish_forming_alt_state (alt_state_t alt_state,
5535			  automaton_t automaton ATTRIBUTE_UNUSED)
5536{
5537  state_t state_in_table;
5538  state_t corresponding_state;
5539
5540  corresponding_state = alt_state->state;
5541  state_in_table = insert_state (corresponding_state);
5542  if (state_in_table != corresponding_state)
5543    {
5544      free_state (corresponding_state);
5545      alt_state->state = state_in_table;
5546    }
5547}
5548
5549/* The following variable value is current automaton insn for whose
5550   reservation the alt states are created.  */
5551static ainsn_t curr_ainsn;
5552
5553/* This recursive function processes `|' in reservation REGEXP for
5554   forming alt_states of AUTOMATON.  List of the alt states should
5555   have the same order as in the description.  */
5556static void
5557process_alts_for_forming_states (regexp_t regexp, automaton_t automaton,
5558				 int inside_oneof_p)
5559{
5560  int i;
5561
5562  if (regexp->mode != rm_oneof)
5563    {
5564      alt_state_being_formed = get_free_alt_state ();
5565      state_being_formed = get_free_state (1, automaton);
5566      alt_state_being_formed->state = state_being_formed;
5567      /* We inserts in reverse order but we process alternatives also
5568         in reverse order.  So we have the same order of alternative
5569         as in the description.  */
5570      alt_state_being_formed->next_alt_state = curr_ainsn->alt_states;
5571      curr_ainsn->alt_states = alt_state_being_formed;
5572      (void) process_seq_for_forming_states (regexp, automaton, 0);
5573      finish_forming_alt_state (alt_state_being_formed, automaton);
5574    }
5575  else
5576    {
5577      if (inside_oneof_p)
5578	abort ();
5579      /* We processes it in reverse order to get list with the same
5580	 order as in the description.  See also the previous
5581	 commentary.  */
5582      for (i = REGEXP_ONEOF (regexp)->regexps_num - 1; i >= 0; i--)
5583	process_alts_for_forming_states (REGEXP_ONEOF (regexp)->regexps [i],
5584					 automaton, 1);
5585    }
5586}
5587
5588/* Create nodes alt_state for all AUTOMATON insns.  */
5589static void
5590create_alt_states (automaton_t automaton)
5591{
5592  struct insn_reserv_decl *reserv_decl;
5593
5594  for (curr_ainsn = automaton->ainsn_list;
5595       curr_ainsn != NULL;
5596       curr_ainsn = curr_ainsn->next_ainsn)
5597    {
5598      reserv_decl = curr_ainsn->insn_reserv_decl;
5599      if (reserv_decl != DECL_INSN_RESERV (advance_cycle_insn_decl))
5600        {
5601          curr_ainsn->alt_states = NULL;
5602          process_alts_for_forming_states (reserv_decl->transformed_regexp,
5603					   automaton, 0);
5604          curr_ainsn->sorted_alt_states
5605	    = uniq_sort_alt_states (curr_ainsn->alt_states);
5606        }
5607    }
5608}
5609
5610
5611
5612/* The page contains major code for building DFA(s) for fast pipeline
5613   hazards recognition.  */
5614
5615/* The function forms list of ainsns of AUTOMATON with the same
5616   reservation.  */
5617static void
5618form_ainsn_with_same_reservs (automaton_t automaton)
5619{
5620  ainsn_t curr_ainsn;
5621  size_t i;
5622  vla_ptr_t first_insns;
5623  vla_ptr_t last_insns;
5624
5625  VLA_PTR_CREATE (first_insns, 150, "first insns with the same reservs");
5626  VLA_PTR_CREATE (last_insns, 150, "last insns with the same reservs");
5627  for (curr_ainsn = automaton->ainsn_list;
5628       curr_ainsn != NULL;
5629       curr_ainsn = curr_ainsn->next_ainsn)
5630    if (curr_ainsn->insn_reserv_decl
5631	== DECL_INSN_RESERV (advance_cycle_insn_decl))
5632      {
5633        curr_ainsn->next_same_reservs_insn = NULL;
5634        curr_ainsn->first_insn_with_same_reservs = 1;
5635      }
5636    else
5637      {
5638        for (i = 0; i < VLA_PTR_LENGTH (first_insns); i++)
5639          if (alt_states_eq
5640              (curr_ainsn->sorted_alt_states,
5641               ((ainsn_t) VLA_PTR (first_insns, i))->sorted_alt_states))
5642            break;
5643        curr_ainsn->next_same_reservs_insn = NULL;
5644        if (i < VLA_PTR_LENGTH (first_insns))
5645          {
5646            curr_ainsn->first_insn_with_same_reservs = 0;
5647	    ((ainsn_t) VLA_PTR (last_insns, i))->next_same_reservs_insn
5648	      = curr_ainsn;
5649            VLA_PTR (last_insns, i) = curr_ainsn;
5650          }
5651        else
5652          {
5653            VLA_PTR_ADD (first_insns, curr_ainsn);
5654            VLA_PTR_ADD (last_insns, curr_ainsn);
5655            curr_ainsn->first_insn_with_same_reservs = 1;
5656          }
5657      }
5658  VLA_PTR_DELETE (first_insns);
5659  VLA_PTR_DELETE (last_insns);
5660}
5661
5662/* Forming unit reservations which can affect creating the automaton
5663   states achieved from a given state.  It permits to build smaller
5664   automata in many cases.  We would have the same automata after
5665   the minimization without such optimization, but the automaton
5666   right after the building could be huge.  So in other words, usage
5667   of reservs_matter means some minimization during building the
5668   automaton.  */
5669static reserv_sets_t
5670form_reservs_matter (automaton_t automaton)
5671{
5672  int cycle, unit;
5673  reserv_sets_t reservs_matter = alloc_empty_reserv_sets();
5674
5675  for (cycle = 0; cycle < max_cycles_num; cycle++)
5676    for (unit = 0; unit < description->units_num; unit++)
5677      if (units_array [unit]->automaton_decl
5678	  == automaton->corresponding_automaton_decl
5679	  && (cycle >= units_array [unit]->min_occ_cycle_num
5680	      /* We can not remove queried unit from reservations.  */
5681	      || units_array [unit]->query_p
5682	      /* We can not remove units which are used
5683		 `exclusion_set', `presence_set',
5684		 `final_presence_set', `absence_set', and
5685		 `final_absence_set'.  */
5686	      || units_array [unit]->in_set_p))
5687	set_unit_reserv (reservs_matter, cycle, unit);
5688  return reservs_matter;
5689}
5690
5691/* The following function creates all states of nondeterministic (if
5692   NDFA_FLAG has nonzero value) or deterministic AUTOMATON.  */
5693static void
5694make_automaton (automaton_t automaton)
5695{
5696  ainsn_t ainsn;
5697  struct insn_reserv_decl *insn_reserv_decl;
5698  alt_state_t alt_state;
5699  state_t state;
5700  state_t start_state;
5701  state_t state2;
5702  ainsn_t advance_cycle_ainsn;
5703  arc_t added_arc;
5704  vla_ptr_t state_stack;
5705  int states_n;
5706  reserv_sets_t reservs_matter = form_reservs_matter (automaton);
5707
5708  VLA_PTR_CREATE (state_stack, 150, "state stack");
5709  /* Create the start state (empty state).  */
5710  start_state = insert_state (get_free_state (1, automaton));
5711  automaton->start_state = start_state;
5712  start_state->it_was_placed_in_stack_for_NDFA_forming = 1;
5713  VLA_PTR_ADD (state_stack, start_state);
5714  states_n = 1;
5715  while (VLA_PTR_LENGTH (state_stack) != 0)
5716    {
5717      state = VLA_PTR (state_stack, VLA_PTR_LENGTH (state_stack) - 1);
5718      VLA_PTR_SHORTEN (state_stack, 1);
5719      advance_cycle_ainsn = NULL;
5720      for (ainsn = automaton->ainsn_list;
5721	   ainsn != NULL;
5722	   ainsn = ainsn->next_ainsn)
5723        if (ainsn->first_insn_with_same_reservs)
5724          {
5725            insn_reserv_decl = ainsn->insn_reserv_decl;
5726            if (insn_reserv_decl != DECL_INSN_RESERV (advance_cycle_insn_decl))
5727              {
5728		/* We process alt_states in the same order as they are
5729                   present in the description.  */
5730		added_arc = NULL;
5731                for (alt_state = ainsn->alt_states;
5732                     alt_state != NULL;
5733                     alt_state = alt_state->next_alt_state)
5734                  {
5735                    state2 = alt_state->state;
5736                    if (!intersected_state_reservs_p (state, state2))
5737                      {
5738                        state2 = states_union (state, state2, reservs_matter);
5739                        if (!state2->it_was_placed_in_stack_for_NDFA_forming)
5740                          {
5741                            state2->it_was_placed_in_stack_for_NDFA_forming
5742			      = 1;
5743                            VLA_PTR_ADD (state_stack, state2);
5744			    states_n++;
5745			    if (progress_flag && states_n % 100 == 0)
5746			      fprintf (stderr, ".");
5747                          }
5748			added_arc = add_arc (state, state2, ainsn, 1);
5749			if (!ndfa_flag)
5750			  break;
5751                      }
5752                  }
5753		if (!ndfa_flag && added_arc != NULL)
5754		  {
5755		    added_arc->state_alts = 0;
5756		    for (alt_state = ainsn->alt_states;
5757			 alt_state != NULL;
5758			 alt_state = alt_state->next_alt_state)
5759		      {
5760			state2 = alt_state->state;
5761			if (!intersected_state_reservs_p (state, state2))
5762			  added_arc->state_alts++;
5763		      }
5764		  }
5765              }
5766            else
5767              advance_cycle_ainsn = ainsn;
5768          }
5769      /* Add transition to advance cycle.  */
5770      state2 = state_shift (state, reservs_matter);
5771      if (!state2->it_was_placed_in_stack_for_NDFA_forming)
5772        {
5773          state2->it_was_placed_in_stack_for_NDFA_forming = 1;
5774          VLA_PTR_ADD (state_stack, state2);
5775	  states_n++;
5776	  if (progress_flag && states_n % 100 == 0)
5777	    fprintf (stderr, ".");
5778        }
5779      if (advance_cycle_ainsn == NULL)
5780	abort ();
5781      add_arc (state, state2, advance_cycle_ainsn, 1);
5782    }
5783  VLA_PTR_DELETE (state_stack);
5784}
5785
5786/* Foms lists of all arcs of STATE marked by the same ainsn.  */
5787static void
5788form_arcs_marked_by_insn (state_t state)
5789{
5790  decl_t decl;
5791  arc_t arc;
5792  int i;
5793
5794  for (i = 0; i < description->decls_num; i++)
5795    {
5796      decl = description->decls [i];
5797      if (decl->mode == dm_insn_reserv)
5798	DECL_INSN_RESERV (decl)->arcs_marked_by_insn = NULL;
5799    }
5800  for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
5801    {
5802      if (arc->insn == NULL)
5803	abort ();
5804      arc->next_arc_marked_by_insn
5805	= arc->insn->insn_reserv_decl->arcs_marked_by_insn;
5806      arc->insn->insn_reserv_decl->arcs_marked_by_insn = arc;
5807    }
5808}
5809
5810/* The function creates composed state (see comments for IR) from
5811   ORIGINAL_STATE and list of arcs ARCS_MARKED_BY_INSN marked by the
5812   same insn.  If the composed state is not in STATE_STACK yet, it is
5813   pushed into STATE_STACK.  */
5814static int
5815create_composed_state (state_t original_state, arc_t arcs_marked_by_insn,
5816		       vla_ptr_t *state_stack)
5817{
5818  state_t state;
5819  alt_state_t alt_state, curr_alt_state;
5820  alt_state_t new_alt_state;
5821  arc_t curr_arc;
5822  arc_t next_arc;
5823  state_t state_in_table;
5824  state_t temp_state;
5825  alt_state_t canonical_alt_states_list;
5826  int alts_number;
5827  int new_state_p = 0;
5828
5829  if (arcs_marked_by_insn == NULL)
5830    return new_state_p;
5831  if (arcs_marked_by_insn->next_arc_marked_by_insn == NULL)
5832    state = arcs_marked_by_insn->to_state;
5833  else
5834    {
5835      if (!ndfa_flag)
5836	abort ();
5837      /* Create composed state.  */
5838      state = get_free_state (0, arcs_marked_by_insn->to_state->automaton);
5839      curr_alt_state = NULL;
5840      for (curr_arc = arcs_marked_by_insn;
5841           curr_arc != NULL;
5842           curr_arc = curr_arc->next_arc_marked_by_insn)
5843	if (curr_arc->to_state->component_states == NULL)
5844	  {
5845	    new_alt_state = get_free_alt_state ();
5846	    new_alt_state->next_alt_state = curr_alt_state;
5847	    new_alt_state->state = curr_arc->to_state;
5848	    curr_alt_state = new_alt_state;
5849	  }
5850	else
5851	  for (alt_state = curr_arc->to_state->component_states;
5852	       alt_state != NULL;
5853	       alt_state = alt_state->next_sorted_alt_state)
5854	    {
5855	      new_alt_state = get_free_alt_state ();
5856	      new_alt_state->next_alt_state = curr_alt_state;
5857	      new_alt_state->state = alt_state->state;
5858	      if (alt_state->state->component_states != NULL)
5859		abort ();
5860	      curr_alt_state = new_alt_state;
5861	    }
5862      /* There are not identical sets in the alt state list.  */
5863      canonical_alt_states_list = uniq_sort_alt_states (curr_alt_state);
5864      if (canonical_alt_states_list->next_sorted_alt_state == NULL)
5865        {
5866          temp_state = state;
5867          state = canonical_alt_states_list->state;
5868          free_state (temp_state);
5869        }
5870      else
5871        {
5872          state->component_states = canonical_alt_states_list;
5873          state_in_table = insert_state (state);
5874          if (state_in_table != state)
5875            {
5876              if (!state_in_table->it_was_placed_in_stack_for_DFA_forming)
5877		abort ();
5878              free_state (state);
5879              state = state_in_table;
5880            }
5881          else
5882            {
5883              if (state->it_was_placed_in_stack_for_DFA_forming)
5884		abort ();
5885	      new_state_p = 1;
5886              for (curr_alt_state = state->component_states;
5887                   curr_alt_state != NULL;
5888                   curr_alt_state = curr_alt_state->next_sorted_alt_state)
5889                for (curr_arc = first_out_arc (curr_alt_state->state);
5890                     curr_arc != NULL;
5891                     curr_arc = next_out_arc (curr_arc))
5892		  add_arc (state, curr_arc->to_state, curr_arc->insn, 1);
5893            }
5894          arcs_marked_by_insn->to_state = state;
5895          for (alts_number = 0,
5896	       curr_arc = arcs_marked_by_insn->next_arc_marked_by_insn;
5897               curr_arc != NULL;
5898               curr_arc = next_arc)
5899            {
5900              next_arc = curr_arc->next_arc_marked_by_insn;
5901              remove_arc (original_state, curr_arc);
5902	      alts_number++;
5903            }
5904	  arcs_marked_by_insn->state_alts = alts_number;
5905        }
5906    }
5907  if (!state->it_was_placed_in_stack_for_DFA_forming)
5908    {
5909      state->it_was_placed_in_stack_for_DFA_forming = 1;
5910      VLA_PTR_ADD (*state_stack, state);
5911    }
5912  return new_state_p;
5913}
5914
5915/* The function transforms nondeterministic AUTOMATON into
5916   deterministic.  */
5917static void
5918NDFA_to_DFA (automaton_t automaton)
5919{
5920  state_t start_state;
5921  state_t state;
5922  decl_t decl;
5923  vla_ptr_t state_stack;
5924  int i;
5925  int states_n;
5926
5927  VLA_PTR_CREATE (state_stack, 150, "state stack");
5928  /* Create the start state (empty state).  */
5929  start_state = automaton->start_state;
5930  start_state->it_was_placed_in_stack_for_DFA_forming = 1;
5931  VLA_PTR_ADD (state_stack, start_state);
5932  states_n = 1;
5933  while (VLA_PTR_LENGTH (state_stack) != 0)
5934    {
5935      state = VLA_PTR (state_stack, VLA_PTR_LENGTH (state_stack) - 1);
5936      VLA_PTR_SHORTEN (state_stack, 1);
5937      form_arcs_marked_by_insn (state);
5938      for (i = 0; i < description->decls_num; i++)
5939	{
5940	  decl = description->decls [i];
5941	  if (decl->mode == dm_insn_reserv
5942	      && create_composed_state
5943	         (state, DECL_INSN_RESERV (decl)->arcs_marked_by_insn,
5944		  &state_stack))
5945	    {
5946	      states_n++;
5947	      if (progress_flag && states_n % 100 == 0)
5948		fprintf (stderr, ".");
5949	    }
5950	}
5951    }
5952  VLA_PTR_DELETE (state_stack);
5953}
5954
5955/* The following variable value is current number (1, 2, ...) of passing
5956   graph of states.  */
5957static int curr_state_graph_pass_num;
5958
5959/* This recursive function passes all states achieved from START_STATE
5960   and applies APPLIED_FUNC to them.  */
5961static void
5962pass_state_graph (state_t start_state, void (*applied_func) (state_t state))
5963{
5964  arc_t arc;
5965
5966  if (start_state->pass_num == curr_state_graph_pass_num)
5967    return;
5968  start_state->pass_num = curr_state_graph_pass_num;
5969  (*applied_func) (start_state);
5970  for (arc = first_out_arc (start_state);
5971       arc != NULL;
5972       arc = next_out_arc (arc))
5973    pass_state_graph (arc->to_state, applied_func);
5974}
5975
5976/* This recursive function passes all states of AUTOMATON and applies
5977   APPLIED_FUNC to them.  */
5978static void
5979pass_states (automaton_t automaton, void (*applied_func) (state_t state))
5980{
5981  curr_state_graph_pass_num++;
5982  pass_state_graph (automaton->start_state, applied_func);
5983}
5984
5985/* The function initializes code for passing of all states.  */
5986static void
5987initiate_pass_states (void)
5988{
5989  curr_state_graph_pass_num = 0;
5990}
5991
5992/* The following vla is used for storing pointers to all achieved
5993   states.  */
5994static vla_ptr_t all_achieved_states;
5995
5996/* This function is called by function pass_states to add an achieved
5997   STATE.  */
5998static void
5999add_achieved_state (state_t state)
6000{
6001  VLA_PTR_ADD (all_achieved_states, state);
6002}
6003
6004/* The function sets up equivalence numbers of insns which mark all
6005   out arcs of STATE by equiv_class_num_1 (if ODD_ITERATION_FLAG has
6006   nonzero value) or by equiv_class_num_2 of the destination state.
6007   The function returns number of out arcs of STATE.  */
6008static int
6009set_out_arc_insns_equiv_num (state_t state, int odd_iteration_flag)
6010{
6011  int state_out_arcs_num;
6012  arc_t arc;
6013
6014  state_out_arcs_num = 0;
6015  for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6016    {
6017      if (arc->insn->insn_reserv_decl->equiv_class_num != 0
6018	  || arc->insn->insn_reserv_decl->state_alts != 0)
6019	abort ();
6020      state_out_arcs_num++;
6021      arc->insn->insn_reserv_decl->equiv_class_num
6022	= (odd_iteration_flag
6023           ? arc->to_state->equiv_class_num_1
6024	   : arc->to_state->equiv_class_num_2);
6025      arc->insn->insn_reserv_decl->state_alts = arc->state_alts;
6026      if (arc->insn->insn_reserv_decl->equiv_class_num == 0
6027	  || arc->insn->insn_reserv_decl->state_alts <= 0)
6028	abort ();
6029    }
6030  return state_out_arcs_num;
6031}
6032
6033/* The function clears equivalence numbers and alt_states in all insns
6034   which mark all out arcs of STATE.  */
6035static void
6036clear_arc_insns_equiv_num (state_t state)
6037{
6038  arc_t arc;
6039
6040  for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6041    {
6042      arc->insn->insn_reserv_decl->equiv_class_num = 0;
6043      arc->insn->insn_reserv_decl->state_alts = 0;
6044    }
6045}
6046
6047/* The function copies pointers to equivalent states from vla FROM
6048   into vla TO.  */
6049static void
6050copy_equiv_class (vla_ptr_t *to, const vla_ptr_t *from)
6051{
6052  state_t *class_ptr;
6053
6054  VLA_PTR_NULLIFY (*to);
6055  for (class_ptr = VLA_PTR_BEGIN (*from);
6056       class_ptr <= (state_t *) VLA_PTR_LAST (*from);
6057       class_ptr++)
6058    VLA_PTR_ADD (*to, *class_ptr);
6059}
6060
6061/* The following function returns TRUE if STATE reserves the unit with
6062   UNIT_NUM on the first cycle.  */
6063static int
6064first_cycle_unit_presence (state_t state, int unit_num)
6065{
6066  int presence_p;
6067
6068  if (state->component_states == NULL)
6069    presence_p = test_unit_reserv (state->reservs, 0, unit_num);
6070  else
6071    presence_p
6072      = test_unit_reserv (state->component_states->state->reservs,
6073			  0, unit_num);
6074  return presence_p;
6075}
6076
6077/* The function returns nonzero value if STATE is not equivalent to
6078   ANOTHER_STATE from the same current partition on equivalence
6079   classes.  Another state has ANOTHER_STATE_OUT_ARCS_NUM number of
6080   output arcs.  Iteration of making equivalence partition is defined
6081   by ODD_ITERATION_FLAG.  */
6082static int
6083state_is_differed (state_t state, state_t another_state,
6084		   int another_state_out_arcs_num, int odd_iteration_flag)
6085{
6086  arc_t arc;
6087  int state_out_arcs_num;
6088  int i, presence1_p, presence2_p;
6089
6090  state_out_arcs_num = 0;
6091  for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6092    {
6093      state_out_arcs_num++;
6094      if ((odd_iteration_flag
6095           ? arc->to_state->equiv_class_num_1
6096	   : arc->to_state->equiv_class_num_2)
6097          != arc->insn->insn_reserv_decl->equiv_class_num
6098	  || (arc->insn->insn_reserv_decl->state_alts != arc->state_alts))
6099        return 1;
6100    }
6101  if (state_out_arcs_num != another_state_out_arcs_num)
6102    return 1;
6103  /* Now we are looking at the states with the point of view of query
6104     units.  */
6105  for (i = 0; i < description->units_num; i++)
6106    if (units_array [i]->query_p)
6107      {
6108	presence1_p = first_cycle_unit_presence (state, i);
6109	presence2_p = first_cycle_unit_presence (another_state, i);
6110	if ((presence1_p && !presence2_p) || (!presence1_p && presence2_p))
6111	  return 1;
6112      }
6113  return 0;
6114}
6115
6116/* The function makes initial partition of STATES on equivalent
6117   classes.  */
6118static state_t
6119init_equiv_class (state_t *states, int states_num)
6120{
6121  state_t *state_ptr;
6122  state_t result_equiv_class;
6123
6124  result_equiv_class = NULL;
6125  for (state_ptr = states; state_ptr < states + states_num; state_ptr++)
6126    {
6127      (*state_ptr)->equiv_class_num_1 = 1;
6128      (*state_ptr)->next_equiv_class_state = result_equiv_class;
6129      result_equiv_class = *state_ptr;
6130    }
6131  return result_equiv_class;
6132}
6133
6134/* The function processes equivalence class given by its pointer
6135   EQUIV_CLASS_PTR on odd iteration if ODD_ITERATION_FLAG.  If there
6136   are not equivalent states, the function partitions the class
6137   removing nonequivalent states and placing them in
6138   *NEXT_ITERATION_CLASSES, increments *NEW_EQUIV_CLASS_NUM_PTR ans
6139   assigns it to the state equivalence number.  If the class has been
6140   partitioned, the function returns nonzero value.  */
6141static int
6142partition_equiv_class (state_t *equiv_class_ptr, int odd_iteration_flag,
6143		       vla_ptr_t *next_iteration_classes,
6144		       int *new_equiv_class_num_ptr)
6145{
6146  state_t new_equiv_class;
6147  int partition_p;
6148  state_t first_state;
6149  state_t curr_state;
6150  state_t prev_state;
6151  state_t next_state;
6152  int out_arcs_num;
6153
6154  partition_p = 0;
6155  if (*equiv_class_ptr == NULL)
6156    abort ();
6157  for (first_state = *equiv_class_ptr;
6158       first_state != NULL;
6159       first_state = new_equiv_class)
6160    {
6161      new_equiv_class = NULL;
6162      if (first_state->next_equiv_class_state != NULL)
6163	{
6164	  /* There are more one states in the class equivalence.  */
6165	  out_arcs_num = set_out_arc_insns_equiv_num (first_state,
6166						      odd_iteration_flag);
6167	  for (prev_state = first_state,
6168		 curr_state = first_state->next_equiv_class_state;
6169	       curr_state != NULL;
6170	       curr_state = next_state)
6171	    {
6172	      next_state = curr_state->next_equiv_class_state;
6173	      if (state_is_differed (curr_state, first_state, out_arcs_num,
6174				     odd_iteration_flag))
6175		{
6176		  /* Remove curr state from the class equivalence.  */
6177		  prev_state->next_equiv_class_state = next_state;
6178		  /* Add curr state to the new class equivalence.  */
6179		  curr_state->next_equiv_class_state = new_equiv_class;
6180		  if (new_equiv_class == NULL)
6181		    (*new_equiv_class_num_ptr)++;
6182		  if (odd_iteration_flag)
6183		    curr_state->equiv_class_num_2 = *new_equiv_class_num_ptr;
6184		  else
6185		    curr_state->equiv_class_num_1 = *new_equiv_class_num_ptr;
6186		  new_equiv_class = curr_state;
6187		  partition_p = 1;
6188		}
6189	      else
6190		prev_state = curr_state;
6191	    }
6192	  clear_arc_insns_equiv_num (first_state);
6193	}
6194      if (new_equiv_class != NULL)
6195	VLA_PTR_ADD  (*next_iteration_classes, new_equiv_class);
6196    }
6197  return partition_p;
6198}
6199
6200/* The function finds equivalent states of AUTOMATON.  */
6201static void
6202evaluate_equiv_classes (automaton_t automaton, vla_ptr_t *equiv_classes)
6203{
6204  state_t new_equiv_class;
6205  int new_equiv_class_num;
6206  int odd_iteration_flag;
6207  int finish_flag;
6208  vla_ptr_t next_iteration_classes;
6209  state_t *equiv_class_ptr;
6210  state_t *state_ptr;
6211
6212  VLA_PTR_CREATE (all_achieved_states, 1500, "all achieved states");
6213  pass_states (automaton, add_achieved_state);
6214  new_equiv_class = init_equiv_class (VLA_PTR_BEGIN (all_achieved_states),
6215                                      VLA_PTR_LENGTH (all_achieved_states));
6216  odd_iteration_flag = 0;
6217  new_equiv_class_num = 1;
6218  VLA_PTR_CREATE (next_iteration_classes, 150, "next iteration classes");
6219  VLA_PTR_ADD (next_iteration_classes, new_equiv_class);
6220  do
6221    {
6222      odd_iteration_flag = !odd_iteration_flag;
6223      finish_flag = 1;
6224      copy_equiv_class (equiv_classes, &next_iteration_classes);
6225      /* Transfer equiv numbers for the next iteration.  */
6226      for (state_ptr = VLA_PTR_BEGIN (all_achieved_states);
6227	   state_ptr <= (state_t *) VLA_PTR_LAST (all_achieved_states);
6228           state_ptr++)
6229	if (odd_iteration_flag)
6230	  (*state_ptr)->equiv_class_num_2 = (*state_ptr)->equiv_class_num_1;
6231	else
6232	  (*state_ptr)->equiv_class_num_1 = (*state_ptr)->equiv_class_num_2;
6233      for (equiv_class_ptr = VLA_PTR_BEGIN (*equiv_classes);
6234           equiv_class_ptr <= (state_t *) VLA_PTR_LAST (*equiv_classes);
6235           equiv_class_ptr++)
6236	if (partition_equiv_class (equiv_class_ptr, odd_iteration_flag,
6237				   &next_iteration_classes,
6238				   &new_equiv_class_num))
6239	  finish_flag = 0;
6240    }
6241  while (!finish_flag);
6242  VLA_PTR_DELETE (next_iteration_classes);
6243  VLA_PTR_DELETE (all_achieved_states);
6244}
6245
6246/* The function merges equivalent states of AUTOMATON.  */
6247static void
6248merge_states (automaton_t automaton, vla_ptr_t *equiv_classes)
6249{
6250  state_t *equiv_class_ptr;
6251  state_t curr_state;
6252  state_t new_state;
6253  state_t first_class_state;
6254  alt_state_t alt_states;
6255  alt_state_t alt_state, new_alt_state;
6256  arc_t curr_arc;
6257  arc_t next_arc;
6258
6259  /* Create states corresponding to equivalence classes containing two
6260     or more states.  */
6261  for (equiv_class_ptr = VLA_PTR_BEGIN (*equiv_classes);
6262       equiv_class_ptr <= (state_t *) VLA_PTR_LAST (*equiv_classes);
6263       equiv_class_ptr++)
6264    if ((*equiv_class_ptr)->next_equiv_class_state != NULL)
6265      {
6266        /* There are more one states in the class equivalence.  */
6267        /* Create new compound state.  */
6268        new_state = get_free_state (0, automaton);
6269        alt_states = NULL;
6270        first_class_state = *equiv_class_ptr;
6271        for (curr_state = first_class_state;
6272             curr_state != NULL;
6273             curr_state = curr_state->next_equiv_class_state)
6274          {
6275            curr_state->equiv_class_state = new_state;
6276	    if (curr_state->component_states == NULL)
6277	      {
6278		new_alt_state = get_free_alt_state ();
6279		new_alt_state->state = curr_state;
6280		new_alt_state->next_alt_state = alt_states;
6281		alt_states = new_alt_state;
6282	      }
6283	    else
6284	      for (alt_state = curr_state->component_states;
6285		   alt_state != NULL;
6286		   alt_state = alt_state->next_sorted_alt_state)
6287		{
6288		  new_alt_state = get_free_alt_state ();
6289		  new_alt_state->state = alt_state->state;
6290		  new_alt_state->next_alt_state = alt_states;
6291		  alt_states = new_alt_state;
6292		}
6293          }
6294	/* Its is important that alt states were sorted before and
6295           after merging to have the same querying results.  */
6296        new_state->component_states = uniq_sort_alt_states (alt_states);
6297      }
6298    else
6299      (*equiv_class_ptr)->equiv_class_state = *equiv_class_ptr;
6300  for (equiv_class_ptr = VLA_PTR_BEGIN (*equiv_classes);
6301       equiv_class_ptr <= (state_t *) VLA_PTR_LAST (*equiv_classes);
6302       equiv_class_ptr++)
6303    if ((*equiv_class_ptr)->next_equiv_class_state != NULL)
6304      {
6305        first_class_state = *equiv_class_ptr;
6306        /* Create new arcs output from the state corresponding to
6307           equiv class.  */
6308        for (curr_arc = first_out_arc (first_class_state);
6309             curr_arc != NULL;
6310             curr_arc = next_out_arc (curr_arc))
6311          add_arc (first_class_state->equiv_class_state,
6312                   curr_arc->to_state->equiv_class_state,
6313		   curr_arc->insn, curr_arc->state_alts);
6314        /* Delete output arcs from states of given class equivalence.  */
6315        for (curr_state = first_class_state;
6316             curr_state != NULL;
6317             curr_state = curr_state->next_equiv_class_state)
6318          {
6319            if (automaton->start_state == curr_state)
6320              automaton->start_state = curr_state->equiv_class_state;
6321            /* Delete the state and its output arcs.  */
6322            for (curr_arc = first_out_arc (curr_state);
6323                 curr_arc != NULL;
6324                 curr_arc = next_arc)
6325              {
6326                next_arc = next_out_arc (curr_arc);
6327                free_arc (curr_arc);
6328              }
6329          }
6330      }
6331    else
6332      {
6333        /* Change `to_state' of arcs output from the state of given
6334           equivalence class.  */
6335        for (curr_arc = first_out_arc (*equiv_class_ptr);
6336             curr_arc != NULL;
6337             curr_arc = next_out_arc (curr_arc))
6338          curr_arc->to_state = curr_arc->to_state->equiv_class_state;
6339      }
6340}
6341
6342/* The function sets up new_cycle_p for states if there is arc to the
6343   state marked by advance_cycle_insn_decl.  */
6344static void
6345set_new_cycle_flags (state_t state)
6346{
6347  arc_t arc;
6348
6349  for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6350    if (arc->insn->insn_reserv_decl
6351	== DECL_INSN_RESERV (advance_cycle_insn_decl))
6352      arc->to_state->new_cycle_p = 1;
6353}
6354
6355/* The top level function for minimization of deterministic
6356   AUTOMATON.  */
6357static void
6358minimize_DFA (automaton_t automaton)
6359{
6360  vla_ptr_t equiv_classes;
6361
6362  VLA_PTR_CREATE (equiv_classes, 1500, "equivalence classes");
6363  evaluate_equiv_classes (automaton, &equiv_classes);
6364  merge_states (automaton, &equiv_classes);
6365  pass_states (automaton, set_new_cycle_flags);
6366  VLA_PTR_DELETE (equiv_classes);
6367}
6368
6369/* Values of two variables are counted number of states and arcs in an
6370   automaton.  */
6371static int curr_counted_states_num;
6372static int curr_counted_arcs_num;
6373
6374/* The function is called by function `pass_states' to count states
6375   and arcs of an automaton.  */
6376static void
6377incr_states_and_arcs_nums (state_t state)
6378{
6379  arc_t arc;
6380
6381  curr_counted_states_num++;
6382  for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6383    curr_counted_arcs_num++;
6384}
6385
6386/* The function counts states and arcs of AUTOMATON.  */
6387static void
6388count_states_and_arcs (automaton_t automaton, int *states_num,
6389		       int *arcs_num)
6390{
6391  curr_counted_states_num = 0;
6392  curr_counted_arcs_num = 0;
6393  pass_states (automaton, incr_states_and_arcs_nums);
6394  *states_num = curr_counted_states_num;
6395  *arcs_num = curr_counted_arcs_num;
6396}
6397
6398/* The function builds one DFA AUTOMATON for fast pipeline hazards
6399   recognition after checking and simplifying IR of the
6400   description.  */
6401static void
6402build_automaton (automaton_t automaton)
6403{
6404  int states_num;
6405  int arcs_num;
6406
6407  ticker_on (&NDFA_time);
6408  if (progress_flag)
6409    {
6410      if (automaton->corresponding_automaton_decl == NULL)
6411	fprintf (stderr, "Create anonymous automaton");
6412      else
6413	fprintf (stderr, "Create automaton `%s'",
6414		 automaton->corresponding_automaton_decl->name);
6415      fprintf (stderr, " (1 dot is 100 new states):");
6416    }
6417  make_automaton (automaton);
6418  if (progress_flag)
6419    fprintf (stderr, " done\n");
6420  ticker_off (&NDFA_time);
6421  count_states_and_arcs (automaton, &states_num, &arcs_num);
6422  automaton->NDFA_states_num = states_num;
6423  automaton->NDFA_arcs_num = arcs_num;
6424  ticker_on (&NDFA_to_DFA_time);
6425  if (progress_flag)
6426    {
6427      if (automaton->corresponding_automaton_decl == NULL)
6428	fprintf (stderr, "Make anonymous DFA");
6429      else
6430	fprintf (stderr, "Make DFA `%s'",
6431		 automaton->corresponding_automaton_decl->name);
6432      fprintf (stderr, " (1 dot is 100 new states):");
6433    }
6434  NDFA_to_DFA (automaton);
6435  if (progress_flag)
6436    fprintf (stderr, " done\n");
6437  ticker_off (&NDFA_to_DFA_time);
6438  count_states_and_arcs (automaton, &states_num, &arcs_num);
6439  automaton->DFA_states_num = states_num;
6440  automaton->DFA_arcs_num = arcs_num;
6441  if (!no_minimization_flag)
6442    {
6443      ticker_on (&minimize_time);
6444      if (progress_flag)
6445	{
6446	  if (automaton->corresponding_automaton_decl == NULL)
6447	    fprintf (stderr, "Minimize anonymous DFA...");
6448	  else
6449	    fprintf (stderr, "Minimize DFA `%s'...",
6450		     automaton->corresponding_automaton_decl->name);
6451	}
6452      minimize_DFA (automaton);
6453      if (progress_flag)
6454	fprintf (stderr, "done\n");
6455      ticker_off (&minimize_time);
6456      count_states_and_arcs (automaton, &states_num, &arcs_num);
6457      automaton->minimal_DFA_states_num = states_num;
6458      automaton->minimal_DFA_arcs_num = arcs_num;
6459    }
6460}
6461
6462
6463
6464/* The page contains code for enumeration  of all states of an automaton.  */
6465
6466/* Variable used for enumeration of all states of an automaton.  Its
6467   value is current number of automaton states.  */
6468static int curr_state_order_num;
6469
6470/* The function is called by function `pass_states' for enumerating
6471   states.  */
6472static void
6473set_order_state_num (state_t state)
6474{
6475  state->order_state_num = curr_state_order_num;
6476  curr_state_order_num++;
6477}
6478
6479/* The function enumerates all states of AUTOMATON.  */
6480static void
6481enumerate_states (automaton_t automaton)
6482{
6483  curr_state_order_num = 0;
6484  pass_states (automaton, set_order_state_num);
6485  automaton->achieved_states_num = curr_state_order_num;
6486}
6487
6488
6489
6490/* The page contains code for finding equivalent automaton insns
6491   (ainsns).  */
6492
6493/* The function inserts AINSN into cyclic list
6494   CYCLIC_EQUIV_CLASS_INSN_LIST of ainsns.  */
6495static ainsn_t
6496insert_ainsn_into_equiv_class (ainsn_t ainsn,
6497			       ainsn_t cyclic_equiv_class_insn_list)
6498{
6499  if (cyclic_equiv_class_insn_list == NULL)
6500    ainsn->next_equiv_class_insn = ainsn;
6501  else
6502    {
6503      ainsn->next_equiv_class_insn
6504        = cyclic_equiv_class_insn_list->next_equiv_class_insn;
6505      cyclic_equiv_class_insn_list->next_equiv_class_insn = ainsn;
6506    }
6507  return ainsn;
6508}
6509
6510/* The function deletes equiv_class_insn into cyclic list of
6511   equivalent ainsns.  */
6512static void
6513delete_ainsn_from_equiv_class (ainsn_t equiv_class_insn)
6514{
6515  ainsn_t curr_equiv_class_insn;
6516  ainsn_t prev_equiv_class_insn;
6517
6518  prev_equiv_class_insn = equiv_class_insn;
6519  for (curr_equiv_class_insn = equiv_class_insn->next_equiv_class_insn;
6520       curr_equiv_class_insn != equiv_class_insn;
6521       curr_equiv_class_insn = curr_equiv_class_insn->next_equiv_class_insn)
6522    prev_equiv_class_insn = curr_equiv_class_insn;
6523  if (prev_equiv_class_insn != equiv_class_insn)
6524    prev_equiv_class_insn->next_equiv_class_insn
6525      = equiv_class_insn->next_equiv_class_insn;
6526}
6527
6528/* The function processes AINSN of a state in order to find equivalent
6529   ainsns.  INSN_ARCS_ARRAY is table: code of insn -> out arc of the
6530   state.  */
6531static void
6532process_insn_equiv_class (ainsn_t ainsn, arc_t *insn_arcs_array)
6533{
6534  ainsn_t next_insn;
6535  ainsn_t curr_insn;
6536  ainsn_t cyclic_insn_list;
6537  arc_t arc;
6538
6539  if (insn_arcs_array [ainsn->insn_reserv_decl->insn_num] == NULL)
6540    abort ();
6541  curr_insn = ainsn;
6542  /* New class of ainsns which are not equivalent to given ainsn.  */
6543  cyclic_insn_list = NULL;
6544  do
6545    {
6546      next_insn = curr_insn->next_equiv_class_insn;
6547      arc = insn_arcs_array [curr_insn->insn_reserv_decl->insn_num];
6548      if (arc == NULL
6549          || (insn_arcs_array [ainsn->insn_reserv_decl->insn_num]->to_state
6550              != arc->to_state))
6551        {
6552          delete_ainsn_from_equiv_class (curr_insn);
6553          cyclic_insn_list = insert_ainsn_into_equiv_class (curr_insn,
6554							    cyclic_insn_list);
6555        }
6556      curr_insn = next_insn;
6557    }
6558  while (curr_insn != ainsn);
6559}
6560
6561/* The function processes STATE in order to find equivalent ainsns.  */
6562static void
6563process_state_for_insn_equiv_partition (state_t state)
6564{
6565  arc_t arc;
6566  arc_t *insn_arcs_array;
6567  int i;
6568  vla_ptr_t insn_arcs_vect;
6569
6570  VLA_PTR_CREATE (insn_arcs_vect, 500, "insn arcs vector");
6571  VLA_PTR_EXPAND (insn_arcs_vect, description->insns_num);
6572  insn_arcs_array = VLA_PTR_BEGIN (insn_arcs_vect);
6573  /* Process insns of the arcs.  */
6574  for (i = 0; i < description->insns_num; i++)
6575    insn_arcs_array [i] = NULL;
6576  for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6577    insn_arcs_array [arc->insn->insn_reserv_decl->insn_num] = arc;
6578  for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6579    process_insn_equiv_class (arc->insn, insn_arcs_array);
6580  VLA_PTR_DELETE (insn_arcs_vect);
6581}
6582
6583/* The function searches for equivalent ainsns of AUTOMATON.  */
6584static void
6585set_insn_equiv_classes (automaton_t automaton)
6586{
6587  ainsn_t ainsn;
6588  ainsn_t first_insn;
6589  ainsn_t curr_insn;
6590  ainsn_t cyclic_insn_list;
6591  ainsn_t insn_with_same_reservs;
6592  int equiv_classes_num;
6593
6594  /* All insns are included in one equivalence class.  */
6595  cyclic_insn_list = NULL;
6596  for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
6597    if (ainsn->first_insn_with_same_reservs)
6598      cyclic_insn_list = insert_ainsn_into_equiv_class (ainsn,
6599							cyclic_insn_list);
6600  /* Process insns in order to make equivalence partition.  */
6601  pass_states (automaton, process_state_for_insn_equiv_partition);
6602  /* Enumerate equiv classes.  */
6603  for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
6604    /* Set undefined value.  */
6605    ainsn->insn_equiv_class_num = -1;
6606  equiv_classes_num = 0;
6607  for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
6608    if (ainsn->insn_equiv_class_num < 0)
6609      {
6610        first_insn = ainsn;
6611        if (!first_insn->first_insn_with_same_reservs)
6612	  abort ();
6613        first_insn->first_ainsn_with_given_equialence_num = 1;
6614        curr_insn = first_insn;
6615        do
6616          {
6617            for (insn_with_same_reservs = curr_insn;
6618                 insn_with_same_reservs != NULL;
6619                 insn_with_same_reservs
6620		   = insn_with_same_reservs->next_same_reservs_insn)
6621              insn_with_same_reservs->insn_equiv_class_num = equiv_classes_num;
6622            curr_insn = curr_insn->next_equiv_class_insn;
6623          }
6624        while (curr_insn != first_insn);
6625        equiv_classes_num++;
6626      }
6627  automaton->insn_equiv_classes_num = equiv_classes_num;
6628}
6629
6630
6631
6632/* This page contains code for creating DFA(s) and calls functions
6633   building them.  */
6634
6635
6636/* The following value is used to prevent floating point overflow for
6637   estimating an automaton bound.  The value should be less DBL_MAX on
6638   the host machine.  We use here approximate minimum of maximal
6639   double floating point value required by ANSI C standard.  It
6640   will work for non ANSI sun compiler too.  */
6641
6642#define MAX_FLOATING_POINT_VALUE_FOR_AUTOMATON_BOUND  1.0E37
6643
6644/* The function estimate size of the single DFA used by PHR (pipeline
6645   hazards recognizer).  */
6646static double
6647estimate_one_automaton_bound (void)
6648{
6649  decl_t decl;
6650  double one_automaton_estimation_bound;
6651  double root_value;
6652  int i;
6653
6654  one_automaton_estimation_bound = 1.0;
6655  for (i = 0; i < description->decls_num; i++)
6656    {
6657      decl = description->decls [i];
6658      if (decl->mode == dm_unit)
6659	{
6660	  root_value = exp (log (DECL_UNIT (decl)->max_occ_cycle_num
6661				 - DECL_UNIT (decl)->min_occ_cycle_num + 1.0)
6662                            / automata_num);
6663	  if (MAX_FLOATING_POINT_VALUE_FOR_AUTOMATON_BOUND / root_value
6664	      > one_automaton_estimation_bound)
6665	    one_automaton_estimation_bound *= root_value;
6666	}
6667    }
6668  return one_automaton_estimation_bound;
6669}
6670
6671/* The function compares unit declarations according to their maximal
6672   cycle in reservations.  */
6673static int
6674compare_max_occ_cycle_nums (const void *unit_decl_1,
6675			    const void *unit_decl_2)
6676{
6677  if ((DECL_UNIT (*(decl_t *) unit_decl_1)->max_occ_cycle_num)
6678      < (DECL_UNIT (*(decl_t *) unit_decl_2)->max_occ_cycle_num))
6679    return 1;
6680  else if ((DECL_UNIT (*(decl_t *) unit_decl_1)->max_occ_cycle_num)
6681	   == (DECL_UNIT (*(decl_t *) unit_decl_2)->max_occ_cycle_num))
6682    return 0;
6683  else
6684    return -1;
6685}
6686
6687/* The function makes heuristic assigning automata to units.  Actually
6688   efficacy of the algorithm has been checked yet??? */
6689static void
6690units_to_automata_heuristic_distr (void)
6691{
6692  double estimation_bound;
6693  decl_t decl;
6694  decl_t *unit_decl_ptr;
6695  int automaton_num;
6696  int rest_units_num;
6697  double bound_value;
6698  vla_ptr_t unit_decls;
6699  int i;
6700
6701  if (description->units_num == 0)
6702    return;
6703  estimation_bound = estimate_one_automaton_bound ();
6704  VLA_PTR_CREATE (unit_decls, 150, "unit decls");
6705  for (i = 0; i < description->decls_num; i++)
6706    {
6707      decl = description->decls [i];
6708      if (decl->mode == dm_unit)
6709	VLA_PTR_ADD (unit_decls, decl);
6710    }
6711  qsort (VLA_PTR_BEGIN (unit_decls), VLA_PTR_LENGTH (unit_decls),
6712         sizeof (decl_t), compare_max_occ_cycle_nums);
6713  automaton_num = 0;
6714  unit_decl_ptr = VLA_PTR_BEGIN (unit_decls);
6715  bound_value = DECL_UNIT (*unit_decl_ptr)->max_occ_cycle_num;
6716  DECL_UNIT (*unit_decl_ptr)->corresponding_automaton_num = automaton_num;
6717  for (unit_decl_ptr++;
6718       unit_decl_ptr <= (decl_t *) VLA_PTR_LAST (unit_decls);
6719       unit_decl_ptr++)
6720    {
6721      rest_units_num
6722	= ((decl_t *) VLA_PTR_LAST (unit_decls) - unit_decl_ptr + 1);
6723      if (automata_num - automaton_num - 1 > rest_units_num)
6724	abort ();
6725      if (automaton_num < automata_num - 1
6726          && ((automata_num - automaton_num - 1 == rest_units_num)
6727              || (bound_value
6728                  > (estimation_bound
6729		     / (DECL_UNIT (*unit_decl_ptr)->max_occ_cycle_num)))))
6730        {
6731          bound_value = DECL_UNIT (*unit_decl_ptr)->max_occ_cycle_num;
6732          automaton_num++;
6733        }
6734      else
6735        bound_value *= DECL_UNIT (*unit_decl_ptr)->max_occ_cycle_num;
6736      DECL_UNIT (*unit_decl_ptr)->corresponding_automaton_num = automaton_num;
6737    }
6738  if (automaton_num != automata_num - 1)
6739    abort ();
6740  VLA_PTR_DELETE (unit_decls);
6741}
6742
6743/* The functions creates automaton insns for each automata.  Automaton
6744   insn is simply insn for given automaton which makes reservation
6745   only of units of the automaton.  */
6746static ainsn_t
6747create_ainsns (void)
6748{
6749  decl_t decl;
6750  ainsn_t first_ainsn;
6751  ainsn_t curr_ainsn;
6752  ainsn_t prev_ainsn;
6753  int i;
6754
6755  first_ainsn = NULL;
6756  prev_ainsn = NULL;
6757  for (i = 0; i < description->decls_num; i++)
6758    {
6759      decl = description->decls [i];
6760      if (decl->mode == dm_insn_reserv)
6761	{
6762	  curr_ainsn = create_node (sizeof (struct ainsn));
6763	  curr_ainsn->insn_reserv_decl = DECL_INSN_RESERV (decl);
6764	  curr_ainsn->important_p = FALSE;
6765	  curr_ainsn->next_ainsn = NULL;
6766	  if (prev_ainsn == NULL)
6767	    first_ainsn = curr_ainsn;
6768	  else
6769	    prev_ainsn->next_ainsn = curr_ainsn;
6770	  prev_ainsn = curr_ainsn;
6771	}
6772    }
6773  return first_ainsn;
6774}
6775
6776/* The function assigns automata to units according to constructions
6777   `define_automaton' in the description.  */
6778static void
6779units_to_automata_distr (void)
6780{
6781  decl_t decl;
6782  int i;
6783
6784  for (i = 0; i < description->decls_num; i++)
6785    {
6786      decl = description->decls [i];
6787      if (decl->mode == dm_unit)
6788	{
6789	  if (DECL_UNIT (decl)->automaton_decl == NULL
6790	      || (DECL_UNIT (decl)->automaton_decl->corresponding_automaton
6791		  == NULL))
6792	    /* Distribute to the first automaton.  */
6793	    DECL_UNIT (decl)->corresponding_automaton_num = 0;
6794	  else
6795	    DECL_UNIT (decl)->corresponding_automaton_num
6796	      = (DECL_UNIT (decl)->automaton_decl
6797                 ->corresponding_automaton->automaton_order_num);
6798	}
6799    }
6800}
6801
6802/* The function creates DFA(s) for fast pipeline hazards recognition
6803   after checking and simplifying IR of the description.  */
6804static void
6805create_automata (void)
6806{
6807  automaton_t curr_automaton;
6808  automaton_t prev_automaton;
6809  decl_t decl;
6810  int curr_automaton_num;
6811  int i;
6812
6813  if (automata_num != 0)
6814    {
6815      units_to_automata_heuristic_distr ();
6816      for (prev_automaton = NULL, curr_automaton_num = 0;
6817           curr_automaton_num < automata_num;
6818           curr_automaton_num++, prev_automaton = curr_automaton)
6819        {
6820	  curr_automaton = create_node (sizeof (struct automaton));
6821	  curr_automaton->ainsn_list = create_ainsns ();
6822	  curr_automaton->corresponding_automaton_decl = NULL;
6823	  curr_automaton->next_automaton = NULL;
6824          curr_automaton->automaton_order_num = curr_automaton_num;
6825          if (prev_automaton == NULL)
6826            description->first_automaton = curr_automaton;
6827          else
6828            prev_automaton->next_automaton = curr_automaton;
6829        }
6830    }
6831  else
6832    {
6833      curr_automaton_num = 0;
6834      prev_automaton = NULL;
6835      for (i = 0; i < description->decls_num; i++)
6836	{
6837	  decl = description->decls [i];
6838	  if (decl->mode == dm_automaton
6839	      && DECL_AUTOMATON (decl)->automaton_is_used)
6840	    {
6841	      curr_automaton = create_node (sizeof (struct automaton));
6842	      curr_automaton->ainsn_list = create_ainsns ();
6843	      curr_automaton->corresponding_automaton_decl
6844		= DECL_AUTOMATON (decl);
6845	      curr_automaton->next_automaton = NULL;
6846	      DECL_AUTOMATON (decl)->corresponding_automaton = curr_automaton;
6847	      curr_automaton->automaton_order_num = curr_automaton_num;
6848	      if (prev_automaton == NULL)
6849		description->first_automaton = curr_automaton;
6850	      else
6851		prev_automaton->next_automaton = curr_automaton;
6852	      curr_automaton_num++;
6853	      prev_automaton = curr_automaton;
6854	    }
6855	}
6856      if (curr_automaton_num == 0)
6857	{
6858	  curr_automaton = create_node (sizeof (struct automaton));
6859	  curr_automaton->ainsn_list = create_ainsns ();
6860	  curr_automaton->corresponding_automaton_decl = NULL;
6861	  curr_automaton->next_automaton = NULL;
6862	  description->first_automaton = curr_automaton;
6863	}
6864      units_to_automata_distr ();
6865    }
6866  NDFA_time = create_ticker ();
6867  ticker_off (&NDFA_time);
6868  NDFA_to_DFA_time = create_ticker ();
6869  ticker_off (&NDFA_to_DFA_time);
6870  minimize_time = create_ticker ();
6871  ticker_off (&minimize_time);
6872  equiv_time = create_ticker ();
6873  ticker_off (&equiv_time);
6874  for (curr_automaton = description->first_automaton;
6875       curr_automaton != NULL;
6876       curr_automaton = curr_automaton->next_automaton)
6877    {
6878      if (progress_flag)
6879	{
6880	  if (curr_automaton->corresponding_automaton_decl == NULL)
6881	    fprintf (stderr, "Prepare anonymous automaton creation ... ");
6882	  else
6883	    fprintf (stderr, "Prepare automaton `%s' creation...",
6884		     curr_automaton->corresponding_automaton_decl->name);
6885	}
6886      create_alt_states (curr_automaton);
6887      form_ainsn_with_same_reservs (curr_automaton);
6888      if (progress_flag)
6889	fprintf (stderr, "done\n");
6890      build_automaton (curr_automaton);
6891      enumerate_states (curr_automaton);
6892      ticker_on (&equiv_time);
6893      set_insn_equiv_classes (curr_automaton);
6894      ticker_off (&equiv_time);
6895    }
6896}
6897
6898
6899
6900/* This page contains code for forming string representation of
6901   regexp.  The representation is formed on IR obstack.  So you should
6902   not work with IR obstack between regexp_representation and
6903   finish_regexp_representation calls.  */
6904
6905/* This recursive function forms string representation of regexp
6906   (without tailing '\0').  */
6907static void
6908form_regexp (regexp_t regexp)
6909{
6910  int i;
6911
6912  if (regexp->mode == rm_unit || regexp->mode == rm_reserv)
6913    {
6914      const char *name = (regexp->mode == rm_unit
6915                          ? REGEXP_UNIT (regexp)->name
6916			  : REGEXP_RESERV (regexp)->name);
6917
6918      obstack_grow (&irp, name, strlen (name));
6919    }
6920  else if (regexp->mode == rm_sequence)
6921    for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
6922      {
6923	if (i != 0)
6924          obstack_1grow (&irp, ',');
6925	form_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
6926      }
6927  else if (regexp->mode == rm_allof)
6928    {
6929      obstack_1grow (&irp, '(');
6930      for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
6931	{
6932	  if (i != 0)
6933            obstack_1grow (&irp, '+');
6934	  if (REGEXP_ALLOF (regexp)->regexps[i]->mode == rm_sequence
6935              || REGEXP_ALLOF (regexp)->regexps[i]->mode == rm_oneof)
6936            obstack_1grow (&irp, '(');
6937	  form_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
6938	  if (REGEXP_ALLOF (regexp)->regexps[i]->mode == rm_sequence
6939              || REGEXP_ALLOF (regexp)->regexps[i]->mode == rm_oneof)
6940            obstack_1grow (&irp, ')');
6941        }
6942      obstack_1grow (&irp, ')');
6943    }
6944  else if (regexp->mode == rm_oneof)
6945    for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
6946      {
6947	if (i != 0)
6948          obstack_1grow (&irp, '|');
6949	if (REGEXP_ONEOF (regexp)->regexps[i]->mode == rm_sequence)
6950          obstack_1grow (&irp, '(');
6951        form_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
6952	if (REGEXP_ONEOF (regexp)->regexps[i]->mode == rm_sequence)
6953          obstack_1grow (&irp, ')');
6954      }
6955  else if (regexp->mode == rm_repeat)
6956    {
6957      char digits [30];
6958
6959      if (REGEXP_REPEAT (regexp)->regexp->mode == rm_sequence
6960	  || REGEXP_REPEAT (regexp)->regexp->mode == rm_allof
6961	  || REGEXP_REPEAT (regexp)->regexp->mode == rm_oneof)
6962        obstack_1grow (&irp, '(');
6963      form_regexp (REGEXP_REPEAT (regexp)->regexp);
6964      if (REGEXP_REPEAT (regexp)->regexp->mode == rm_sequence
6965	  || REGEXP_REPEAT (regexp)->regexp->mode == rm_allof
6966	  || REGEXP_REPEAT (regexp)->regexp->mode == rm_oneof)
6967        obstack_1grow (&irp, ')');
6968      sprintf (digits, "*%d", REGEXP_REPEAT (regexp)->repeat_num);
6969      obstack_grow (&irp, digits, strlen (digits));
6970    }
6971  else if (regexp->mode == rm_nothing)
6972    obstack_grow (&irp, NOTHING_NAME, strlen (NOTHING_NAME));
6973  else
6974    abort ();
6975}
6976
6977/* The function returns string representation of REGEXP on IR
6978   obstack.  */
6979static const char *
6980regexp_representation (regexp_t regexp)
6981{
6982  form_regexp (regexp);
6983  obstack_1grow (&irp, '\0');
6984  return obstack_base (&irp);
6985}
6986
6987/* The function frees memory allocated for last formed string
6988   representation of regexp.  */
6989static void
6990finish_regexp_representation (void)
6991{
6992  int length = obstack_object_size (&irp);
6993
6994  obstack_blank_fast (&irp, -length);
6995}
6996
6997
6998
6999/* This page contains code for output PHR (pipeline hazards recognizer).  */
7000
7001/* The function outputs minimal C type which is sufficient for
7002   representation numbers in range min_range_value and
7003   max_range_value.  Because host machine and build machine may be
7004   different, we use here minimal values required by ANSI C standard
7005   instead of UCHAR_MAX, SHRT_MAX, SHRT_MIN, etc.  This is a good
7006   approximation.  */
7007
7008static void
7009output_range_type (FILE *f, long int min_range_value,
7010		   long int max_range_value)
7011{
7012  if (min_range_value >= 0 && max_range_value <= 255)
7013    fprintf (f, "unsigned char");
7014  else if (min_range_value >= -127 && max_range_value <= 127)
7015    fprintf (f, "signed char");
7016  else if (min_range_value >= 0 && max_range_value <= 65535)
7017    fprintf (f, "unsigned short");
7018  else if (min_range_value >= -32767 && max_range_value <= 32767)
7019    fprintf (f, "short");
7020  else
7021    fprintf (f, "int");
7022}
7023
7024/* The following macro value is used as value of member
7025   `longest_path_length' of state when we are processing path and the
7026   state on the path.  */
7027
7028#define ON_THE_PATH -2
7029
7030/* The following recursive function searches for the length of the
7031   longest path starting from STATE which does not contain cycles and
7032   `cycle advance' arcs.  */
7033
7034static int
7035longest_path_length (state_t state)
7036{
7037  arc_t arc;
7038  int length, result;
7039
7040  if (state->longest_path_length == ON_THE_PATH)
7041    /* We don't expect the path cycle here.  Our graph may contain
7042       only cycles with one state on the path not containing `cycle
7043       advance' arcs -- see comment below.  */
7044    abort ();
7045  else if (state->longest_path_length != UNDEFINED_LONGEST_PATH_LENGTH)
7046    /* We already visited the state.  */
7047    return state->longest_path_length;
7048
7049  result = 0;
7050  for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
7051    /* Ignore cycles containing one state and `cycle advance' arcs.  */
7052    if (arc->to_state != state
7053	&& (arc->insn->insn_reserv_decl
7054	    != DECL_INSN_RESERV (advance_cycle_insn_decl)))
7055    {
7056      length = longest_path_length (arc->to_state);
7057      if (length > result)
7058	result = length;
7059    }
7060  state->longest_path_length = result + 1;
7061  return result;
7062}
7063
7064/* The following variable value is value of the corresponding global
7065   variable in the automaton based pipeline interface.  */
7066
7067static int max_dfa_issue_rate;
7068
7069/* The following function processes the longest path length staring
7070   from STATE to find MAX_DFA_ISSUE_RATE.  */
7071
7072static void
7073process_state_longest_path_length (state_t state)
7074{
7075  int value;
7076
7077  value = longest_path_length (state);
7078  if (value > max_dfa_issue_rate)
7079    max_dfa_issue_rate = value;
7080}
7081
7082/* The following macro value is name of the corresponding global
7083   variable in the automaton based pipeline interface.  */
7084
7085#define MAX_DFA_ISSUE_RATE_VAR_NAME "max_dfa_issue_rate"
7086
7087/* The following function calculates value of the corresponding
7088   global variable and outputs its declaration.  */
7089
7090static void
7091output_dfa_max_issue_rate (void)
7092{
7093  automaton_t automaton;
7094
7095  if (UNDEFINED_LONGEST_PATH_LENGTH == ON_THE_PATH || ON_THE_PATH >= 0)
7096    abort ();
7097  max_dfa_issue_rate = 0;
7098  for (automaton = description->first_automaton;
7099       automaton != NULL;
7100       automaton = automaton->next_automaton)
7101    pass_states (automaton, process_state_longest_path_length);
7102  fprintf (output_file, "\nint %s = %d;\n",
7103	   MAX_DFA_ISSUE_RATE_VAR_NAME, max_dfa_issue_rate);
7104}
7105
7106/* The function outputs all initialization values of VECT with length
7107   vect_length.  */
7108static void
7109output_vect (vect_el_t *vect, int vect_length)
7110{
7111  int els_on_line;
7112
7113  els_on_line = 1;
7114  if (vect_length == 0)
7115    fprintf (output_file,
7116             "0 /* This is dummy el because the vect is empty */");
7117  else
7118    {
7119      do
7120        {
7121          fprintf (output_file, "%5ld", (long) *vect);
7122          vect_length--;
7123          if (els_on_line == 10)
7124	    {
7125	      els_on_line = 0;
7126	      fprintf (output_file, ",\n");
7127	    }
7128          else if (vect_length != 0)
7129            fprintf (output_file, ", ");
7130          els_on_line++;
7131          vect++;
7132        }
7133      while (vect_length != 0);
7134    }
7135}
7136
7137/* The following is name of the structure which represents DFA(s) for
7138   PHR.  */
7139#define CHIP_NAME "DFA_chip"
7140
7141/* The following is name of member which represents state of a DFA for
7142   PHR.  */
7143static void
7144output_chip_member_name (FILE *f, automaton_t automaton)
7145{
7146  if (automaton->corresponding_automaton_decl == NULL)
7147    fprintf (f, "automaton_state_%d", automaton->automaton_order_num);
7148  else
7149    fprintf (f, "%s_automaton_state",
7150             automaton->corresponding_automaton_decl->name);
7151}
7152
7153/* The following is name of temporary variable which stores state of a
7154   DFA for PHR.  */
7155static void
7156output_temp_chip_member_name (FILE *f, automaton_t automaton)
7157{
7158  fprintf (f, "_");
7159  output_chip_member_name (f, automaton);
7160}
7161
7162/* This is name of macro value which is code of pseudo_insn
7163   representing advancing cpu cycle.  Its value is used as internal
7164   code unknown insn.  */
7165#define ADVANCE_CYCLE_VALUE_NAME "DFA__ADVANCE_CYCLE"
7166
7167/* Output name of translate vector for given automaton.  */
7168static void
7169output_translate_vect_name (FILE *f, automaton_t automaton)
7170{
7171  if (automaton->corresponding_automaton_decl == NULL)
7172    fprintf (f, "translate_%d", automaton->automaton_order_num);
7173  else
7174    fprintf (f, "%s_translate", automaton->corresponding_automaton_decl->name);
7175}
7176
7177/* Output name for simple transition table representation.  */
7178static void
7179output_trans_full_vect_name (FILE *f, automaton_t automaton)
7180{
7181  if (automaton->corresponding_automaton_decl == NULL)
7182    fprintf (f, "transitions_%d", automaton->automaton_order_num);
7183  else
7184    fprintf (f, "%s_transitions",
7185	     automaton->corresponding_automaton_decl->name);
7186}
7187
7188/* Output name of comb vector of the transition table for given
7189   automaton.  */
7190static void
7191output_trans_comb_vect_name (FILE *f, automaton_t automaton)
7192{
7193  if (automaton->corresponding_automaton_decl == NULL)
7194    fprintf (f, "transitions_%d", automaton->automaton_order_num);
7195  else
7196    fprintf (f, "%s_transitions",
7197             automaton->corresponding_automaton_decl->name);
7198}
7199
7200/* Output name of check vector of the transition table for given
7201   automaton.  */
7202static void
7203output_trans_check_vect_name (FILE *f, automaton_t automaton)
7204{
7205  if (automaton->corresponding_automaton_decl == NULL)
7206    fprintf (f, "check_%d", automaton->automaton_order_num);
7207  else
7208    fprintf (f, "%s_check", automaton->corresponding_automaton_decl->name);
7209}
7210
7211/* Output name of base vector of the transition table for given
7212   automaton.  */
7213static void
7214output_trans_base_vect_name (FILE *f, automaton_t automaton)
7215{
7216  if (automaton->corresponding_automaton_decl == NULL)
7217    fprintf (f, "base_%d", automaton->automaton_order_num);
7218  else
7219    fprintf (f, "%s_base", automaton->corresponding_automaton_decl->name);
7220}
7221
7222/* Output name for simple alternatives number representation.  */
7223static void
7224output_state_alts_full_vect_name (FILE *f, automaton_t automaton)
7225{
7226  if (automaton->corresponding_automaton_decl == NULL)
7227    fprintf (f, "state_alts_%d", automaton->automaton_order_num);
7228  else
7229    fprintf (f, "%s_state_alts",
7230             automaton->corresponding_automaton_decl->name);
7231}
7232
7233/* Output name of comb vector of the alternatives number table for given
7234   automaton.  */
7235static void
7236output_state_alts_comb_vect_name (FILE *f, automaton_t automaton)
7237{
7238  if (automaton->corresponding_automaton_decl == NULL)
7239    fprintf (f, "state_alts_%d", automaton->automaton_order_num);
7240  else
7241    fprintf (f, "%s_state_alts",
7242             automaton->corresponding_automaton_decl->name);
7243}
7244
7245/* Output name of check vector of the alternatives number table for given
7246   automaton.  */
7247static void
7248output_state_alts_check_vect_name (FILE *f, automaton_t automaton)
7249{
7250  if (automaton->corresponding_automaton_decl == NULL)
7251    fprintf (f, "check_state_alts_%d", automaton->automaton_order_num);
7252  else
7253    fprintf (f, "%s_check_state_alts",
7254	     automaton->corresponding_automaton_decl->name);
7255}
7256
7257/* Output name of base vector of the alternatives number table for given
7258   automaton.  */
7259static void
7260output_state_alts_base_vect_name (FILE *f, automaton_t automaton)
7261{
7262  if (automaton->corresponding_automaton_decl == NULL)
7263    fprintf (f, "base_state_alts_%d", automaton->automaton_order_num);
7264  else
7265    fprintf (f, "%s_base_state_alts",
7266	     automaton->corresponding_automaton_decl->name);
7267}
7268
7269/* Output name of simple min issue delay table representation.  */
7270static void
7271output_min_issue_delay_vect_name (FILE *f, automaton_t automaton)
7272{
7273  if (automaton->corresponding_automaton_decl == NULL)
7274    fprintf (f, "min_issue_delay_%d", automaton->automaton_order_num);
7275  else
7276    fprintf (f, "%s_min_issue_delay",
7277             automaton->corresponding_automaton_decl->name);
7278}
7279
7280/* Output name of deadlock vector for given automaton.  */
7281static void
7282output_dead_lock_vect_name (FILE *f, automaton_t automaton)
7283{
7284  if (automaton->corresponding_automaton_decl == NULL)
7285    fprintf (f, "dead_lock_%d", automaton->automaton_order_num);
7286  else
7287    fprintf (f, "%s_dead_lock", automaton->corresponding_automaton_decl->name);
7288}
7289
7290/* Output name of reserved units table for AUTOMATON into file F.  */
7291static void
7292output_reserved_units_table_name (FILE *f, automaton_t automaton)
7293{
7294  if (automaton->corresponding_automaton_decl == NULL)
7295    fprintf (f, "reserved_units_%d", automaton->automaton_order_num);
7296  else
7297    fprintf (f, "%s_reserved_units",
7298	     automaton->corresponding_automaton_decl->name);
7299}
7300
7301/* Name of the PHR interface macro.  */
7302#define AUTOMATON_STATE_ALTS_MACRO_NAME "AUTOMATON_STATE_ALTS"
7303
7304/* Name of the PHR interface macro.  */
7305#define CPU_UNITS_QUERY_MACRO_NAME "CPU_UNITS_QUERY"
7306
7307/* Names of an internal functions: */
7308#define INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME "internal_min_issue_delay"
7309
7310/* This is external type of DFA(s) state.  */
7311#define STATE_TYPE_NAME "state_t"
7312
7313#define INTERNAL_TRANSITION_FUNC_NAME "internal_state_transition"
7314
7315#define INTERNAL_STATE_ALTS_FUNC_NAME "internal_state_alts"
7316
7317#define INTERNAL_RESET_FUNC_NAME "internal_reset"
7318
7319#define INTERNAL_DEAD_LOCK_FUNC_NAME "internal_state_dead_lock_p"
7320
7321#define INTERNAL_INSN_LATENCY_FUNC_NAME "internal_insn_latency"
7322
7323/* Name of cache of insn dfa codes.  */
7324#define DFA_INSN_CODES_VARIABLE_NAME "dfa_insn_codes"
7325
7326/* Name of length of cache of insn dfa codes.  */
7327#define DFA_INSN_CODES_LENGTH_VARIABLE_NAME "dfa_insn_codes_length"
7328
7329/* Names of the PHR interface functions: */
7330#define SIZE_FUNC_NAME "state_size"
7331
7332#define TRANSITION_FUNC_NAME "state_transition"
7333
7334#define STATE_ALTS_FUNC_NAME "state_alts"
7335
7336#define MIN_ISSUE_DELAY_FUNC_NAME "min_issue_delay"
7337
7338#define MIN_INSN_CONFLICT_DELAY_FUNC_NAME "min_insn_conflict_delay"
7339
7340#define DEAD_LOCK_FUNC_NAME "state_dead_lock_p"
7341
7342#define RESET_FUNC_NAME "state_reset"
7343
7344#define INSN_LATENCY_FUNC_NAME "insn_latency"
7345
7346#define PRINT_RESERVATION_FUNC_NAME "print_reservation"
7347
7348#define GET_CPU_UNIT_CODE_FUNC_NAME "get_cpu_unit_code"
7349
7350#define CPU_UNIT_RESERVATION_P_FUNC_NAME "cpu_unit_reservation_p"
7351
7352#define DFA_CLEAN_INSN_CACHE_FUNC_NAME  "dfa_clean_insn_cache"
7353
7354#define DFA_START_FUNC_NAME  "dfa_start"
7355
7356#define DFA_FINISH_FUNC_NAME "dfa_finish"
7357
7358/* Names of parameters of the PHR interface functions.  */
7359#define STATE_NAME "state"
7360
7361#define INSN_PARAMETER_NAME "insn"
7362
7363#define INSN2_PARAMETER_NAME "insn2"
7364
7365#define CHIP_PARAMETER_NAME "chip"
7366
7367#define FILE_PARAMETER_NAME "f"
7368
7369#define CPU_UNIT_NAME_PARAMETER_NAME "cpu_unit_name"
7370
7371#define CPU_CODE_PARAMETER_NAME "cpu_unit_code"
7372
7373/* Names of the variables whose values are internal insn code of rtx
7374   insn.  */
7375#define INTERNAL_INSN_CODE_NAME "insn_code"
7376
7377#define INTERNAL_INSN2_CODE_NAME "insn2_code"
7378
7379/* Names of temporary variables in some functions.  */
7380#define TEMPORARY_VARIABLE_NAME "temp"
7381
7382#define I_VARIABLE_NAME "i"
7383
7384/* Name of result variable in some functions.  */
7385#define RESULT_VARIABLE_NAME "res"
7386
7387/* Name of function (attribute) to translate insn into internal insn
7388   code.  */
7389#define INTERNAL_DFA_INSN_CODE_FUNC_NAME "internal_dfa_insn_code"
7390
7391/* Name of function (attribute) to translate insn into internal insn
7392   code with caching.  */
7393#define DFA_INSN_CODE_FUNC_NAME "dfa_insn_code"
7394
7395/* Name of function (attribute) to translate insn into internal insn
7396   code.  */
7397#define INSN_DEFAULT_LATENCY_FUNC_NAME "insn_default_latency"
7398
7399/* Name of function (attribute) to translate insn into internal insn
7400   code.  */
7401#define BYPASS_P_FUNC_NAME "bypass_p"
7402
7403/* Output C type which is used for representation of codes of states
7404   of AUTOMATON.  */
7405static void
7406output_state_member_type (FILE *f, automaton_t automaton)
7407{
7408  output_range_type (f, 0, automaton->achieved_states_num);
7409}
7410
7411/* Output definition of the structure representing current DFA(s)
7412   state(s).  */
7413static void
7414output_chip_definitions (void)
7415{
7416  automaton_t automaton;
7417
7418  fprintf (output_file, "struct %s\n{\n", CHIP_NAME);
7419  for (automaton = description->first_automaton;
7420       automaton != NULL;
7421       automaton = automaton->next_automaton)
7422    {
7423      fprintf (output_file, "  ");
7424      output_state_member_type (output_file, automaton);
7425      fprintf (output_file, " ");
7426      output_chip_member_name (output_file, automaton);
7427      fprintf (output_file, ";\n");
7428    }
7429  fprintf (output_file, "};\n\n");
7430#if 0
7431  fprintf (output_file, "static struct %s %s;\n\n", CHIP_NAME, CHIP_NAME);
7432#endif
7433}
7434
7435
7436/* The function outputs translate vector of internal insn code into
7437   insn equivalence class number.  The equivalence class number is
7438   used to access to table and vectors representing DFA(s).  */
7439static void
7440output_translate_vect (automaton_t automaton)
7441{
7442  ainsn_t ainsn;
7443  int insn_value;
7444  vla_hwint_t translate_vect;
7445
7446  VLA_HWINT_CREATE (translate_vect, 250, "translate vector");
7447  VLA_HWINT_EXPAND (translate_vect, description->insns_num);
7448  for (insn_value = 0; insn_value < description->insns_num; insn_value++)
7449    /* Undefined value */
7450    VLA_HWINT (translate_vect, insn_value) = automaton->insn_equiv_classes_num;
7451  for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
7452    VLA_HWINT (translate_vect, ainsn->insn_reserv_decl->insn_num)
7453      = ainsn->insn_equiv_class_num;
7454  fprintf (output_file,
7455           "/* Vector translating external insn codes to internal ones.*/\n");
7456  fprintf (output_file, "static const ");
7457  output_range_type (output_file, 0, automaton->insn_equiv_classes_num);
7458  fprintf (output_file, " ");
7459  output_translate_vect_name (output_file, automaton);
7460  fprintf (output_file, "[] ATTRIBUTE_UNUSED = {\n");
7461  output_vect (VLA_HWINT_BEGIN (translate_vect),
7462	       VLA_HWINT_LENGTH (translate_vect));
7463  fprintf (output_file, "};\n\n");
7464  VLA_HWINT_DELETE (translate_vect);
7465}
7466
7467/* The value in a table state x ainsn -> something which represents
7468   undefined value.  */
7469static int undefined_vect_el_value;
7470
7471/* The following function returns nonzero value if the best
7472   representation of the table is comb vector.  */
7473static int
7474comb_vect_p (state_ainsn_table_t tab)
7475{
7476  return  (2 * VLA_HWINT_LENGTH (tab->full_vect)
7477           > 5 * VLA_HWINT_LENGTH (tab->comb_vect));
7478}
7479
7480/* The following function creates new table for AUTOMATON.  */
7481static state_ainsn_table_t
7482create_state_ainsn_table (automaton_t automaton)
7483{
7484  state_ainsn_table_t tab;
7485  int full_vect_length;
7486  int i;
7487
7488  tab = create_node (sizeof (struct state_ainsn_table));
7489  tab->automaton = automaton;
7490  VLA_HWINT_CREATE (tab->comb_vect, 10000, "comb vector");
7491  VLA_HWINT_CREATE (tab->check_vect, 10000, "check vector");
7492  VLA_HWINT_CREATE (tab->base_vect, 1000, "base vector");
7493  VLA_HWINT_EXPAND (tab->base_vect, automaton->achieved_states_num);
7494  VLA_HWINT_CREATE (tab->full_vect, 10000, "full vector");
7495  full_vect_length = (automaton->insn_equiv_classes_num
7496                      * automaton->achieved_states_num);
7497  VLA_HWINT_EXPAND (tab->full_vect, full_vect_length);
7498  for (i = 0; i < full_vect_length; i++)
7499    VLA_HWINT (tab->full_vect, i) = undefined_vect_el_value;
7500  tab->min_base_vect_el_value = 0;
7501  tab->max_base_vect_el_value = 0;
7502  tab->min_comb_vect_el_value = 0;
7503  tab->max_comb_vect_el_value = 0;
7504  return tab;
7505}
7506
7507/* The following function outputs the best C representation of the
7508   table TAB of given TABLE_NAME.  */
7509static void
7510output_state_ainsn_table (state_ainsn_table_t tab, char *table_name,
7511			  void (*output_full_vect_name_func) (FILE *, automaton_t),
7512			  void (*output_comb_vect_name_func) (FILE *, automaton_t),
7513			  void (*output_check_vect_name_func) (FILE *, automaton_t),
7514			  void (*output_base_vect_name_func) (FILE *, automaton_t))
7515{
7516  if (!comb_vect_p (tab))
7517    {
7518      fprintf (output_file, "/* Vector for %s.  */\n", table_name);
7519      fprintf (output_file, "static const ");
7520      output_range_type (output_file, tab->min_comb_vect_el_value,
7521                         tab->max_comb_vect_el_value);
7522      fprintf (output_file, " ");
7523      (*output_full_vect_name_func) (output_file, tab->automaton);
7524      fprintf (output_file, "[] ATTRIBUTE_UNUSED = {\n");
7525      output_vect (VLA_HWINT_BEGIN (tab->full_vect),
7526                   VLA_HWINT_LENGTH (tab->full_vect));
7527      fprintf (output_file, "};\n\n");
7528    }
7529  else
7530    {
7531      fprintf (output_file, "/* Comb vector for %s.  */\n", table_name);
7532      fprintf (output_file, "static const ");
7533      output_range_type (output_file, tab->min_comb_vect_el_value,
7534                         tab->max_comb_vect_el_value);
7535      fprintf (output_file, " ");
7536      (*output_comb_vect_name_func) (output_file, tab->automaton);
7537      fprintf (output_file, "[] ATTRIBUTE_UNUSED = {\n");
7538      output_vect (VLA_HWINT_BEGIN (tab->comb_vect),
7539                   VLA_HWINT_LENGTH (tab->comb_vect));
7540      fprintf (output_file, "};\n\n");
7541      fprintf (output_file, "/* Check vector for %s.  */\n", table_name);
7542      fprintf (output_file, "static const ");
7543      output_range_type (output_file, 0, tab->automaton->achieved_states_num);
7544      fprintf (output_file, " ");
7545      (*output_check_vect_name_func) (output_file, tab->automaton);
7546      fprintf (output_file, "[] = {\n");
7547      output_vect (VLA_HWINT_BEGIN (tab->check_vect),
7548                   VLA_HWINT_LENGTH (tab->check_vect));
7549      fprintf (output_file, "};\n\n");
7550      fprintf (output_file, "/* Base vector for %s.  */\n", table_name);
7551      fprintf (output_file, "static const ");
7552      output_range_type (output_file, tab->min_base_vect_el_value,
7553                         tab->max_base_vect_el_value);
7554      fprintf (output_file, " ");
7555      (*output_base_vect_name_func) (output_file, tab->automaton);
7556      fprintf (output_file, "[] = {\n");
7557      output_vect (VLA_HWINT_BEGIN (tab->base_vect),
7558                   VLA_HWINT_LENGTH (tab->base_vect));
7559      fprintf (output_file, "};\n\n");
7560    }
7561}
7562
7563/* The following function adds vector with length VECT_LENGTH and
7564   elements pointed by VECT to table TAB as its line with number
7565   VECT_NUM.  */
7566static void
7567add_vect (state_ainsn_table_t tab, int vect_num, vect_el_t *vect,
7568	  int vect_length)
7569{
7570  int real_vect_length;
7571  vect_el_t *comb_vect_start;
7572  vect_el_t *check_vect_start;
7573  int comb_vect_index;
7574  int comb_vect_els_num;
7575  int vect_index;
7576  int first_unempty_vect_index;
7577  int additional_els_num;
7578  int no_state_value;
7579  vect_el_t vect_el;
7580  int i;
7581
7582  if (vect_length == 0)
7583    abort ();
7584  real_vect_length = tab->automaton->insn_equiv_classes_num;
7585  if (vect [vect_length - 1] == undefined_vect_el_value)
7586    abort ();
7587  /* Form full vector in the table: */
7588  for (i = 0; i < vect_length; i++)
7589    VLA_HWINT (tab->full_vect,
7590               i + tab->automaton->insn_equiv_classes_num * vect_num)
7591      = vect [i];
7592  /* Form comb vector in the table: */
7593  if (VLA_HWINT_LENGTH (tab->comb_vect) != VLA_HWINT_LENGTH (tab->check_vect))
7594    abort ();
7595  comb_vect_start = VLA_HWINT_BEGIN (tab->comb_vect);
7596  comb_vect_els_num = VLA_HWINT_LENGTH (tab->comb_vect);
7597  for (first_unempty_vect_index = 0;
7598       first_unempty_vect_index < vect_length;
7599       first_unempty_vect_index++)
7600    if (vect [first_unempty_vect_index] != undefined_vect_el_value)
7601      break;
7602  /* Search for the place in comb vect for the inserted vect.  */
7603  for (comb_vect_index = 0;
7604       comb_vect_index < comb_vect_els_num;
7605       comb_vect_index++)
7606    {
7607      for (vect_index = first_unempty_vect_index;
7608           vect_index < vect_length
7609             && vect_index + comb_vect_index < comb_vect_els_num;
7610           vect_index++)
7611        if (vect [vect_index] != undefined_vect_el_value
7612            && (comb_vect_start [vect_index + comb_vect_index]
7613		!= undefined_vect_el_value))
7614          break;
7615      if (vect_index >= vect_length
7616          || vect_index + comb_vect_index >= comb_vect_els_num)
7617        break;
7618    }
7619  /* Slot was found.  */
7620  additional_els_num = comb_vect_index + real_vect_length - comb_vect_els_num;
7621  if (additional_els_num < 0)
7622    additional_els_num = 0;
7623  /* Expand comb and check vectors.  */
7624  vect_el = undefined_vect_el_value;
7625  no_state_value = tab->automaton->achieved_states_num;
7626  while (additional_els_num > 0)
7627    {
7628      VLA_HWINT_ADD (tab->comb_vect, vect_el);
7629      VLA_HWINT_ADD (tab->check_vect, no_state_value);
7630      additional_els_num--;
7631    }
7632  comb_vect_start = VLA_HWINT_BEGIN (tab->comb_vect);
7633  check_vect_start = VLA_HWINT_BEGIN (tab->check_vect);
7634  if (VLA_HWINT_LENGTH (tab->comb_vect)
7635      < (size_t) (comb_vect_index + real_vect_length))
7636    abort ();
7637  /* Fill comb and check vectors.  */
7638  for (vect_index = 0; vect_index < vect_length; vect_index++)
7639    if (vect [vect_index] != undefined_vect_el_value)
7640      {
7641        if (comb_vect_start [comb_vect_index + vect_index]
7642	    != undefined_vect_el_value)
7643	  abort ();
7644        comb_vect_start [comb_vect_index + vect_index] = vect [vect_index];
7645        if (vect [vect_index] < 0)
7646	  abort ();
7647        if (tab->max_comb_vect_el_value < vect [vect_index])
7648          tab->max_comb_vect_el_value = vect [vect_index];
7649        if (tab->min_comb_vect_el_value > vect [vect_index])
7650          tab->min_comb_vect_el_value = vect [vect_index];
7651        check_vect_start [comb_vect_index + vect_index] = vect_num;
7652      }
7653  if (tab->max_comb_vect_el_value < undefined_vect_el_value)
7654    tab->max_comb_vect_el_value = undefined_vect_el_value;
7655  if (tab->min_comb_vect_el_value > undefined_vect_el_value)
7656    tab->min_comb_vect_el_value = undefined_vect_el_value;
7657  if (tab->max_base_vect_el_value < comb_vect_index)
7658    tab->max_base_vect_el_value = comb_vect_index;
7659  if (tab->min_base_vect_el_value > comb_vect_index)
7660    tab->min_base_vect_el_value = comb_vect_index;
7661  VLA_HWINT (tab->base_vect, vect_num) = comb_vect_index;
7662}
7663
7664/* Return number of out arcs of STATE.  */
7665static int
7666out_state_arcs_num (state_t state)
7667{
7668  int result;
7669  arc_t arc;
7670
7671  result = 0;
7672  for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
7673    {
7674      if (arc->insn == NULL)
7675	abort ();
7676      if (arc->insn->first_ainsn_with_given_equialence_num)
7677        result++;
7678    }
7679  return result;
7680}
7681
7682/* Compare number of possible transitions from the states.  */
7683static int
7684compare_transition_els_num (const void *state_ptr_1,
7685			    const void *state_ptr_2)
7686{
7687  int transition_els_num_1;
7688  int transition_els_num_2;
7689
7690  transition_els_num_1 = out_state_arcs_num (*(state_t *) state_ptr_1);
7691  transition_els_num_2 = out_state_arcs_num (*(state_t *) state_ptr_2);
7692  if (transition_els_num_1 < transition_els_num_2)
7693    return 1;
7694  else if (transition_els_num_1 == transition_els_num_2)
7695    return 0;
7696  else
7697    return -1;
7698}
7699
7700/* The function adds element EL_VALUE to vector VECT for a table state
7701   x AINSN.  */
7702static void
7703add_vect_el (vla_hwint_t *vect, ainsn_t ainsn, int el_value)
7704{
7705  int equiv_class_num;
7706  int vect_index;
7707
7708  if (ainsn == NULL)
7709    abort ();
7710  equiv_class_num = ainsn->insn_equiv_class_num;
7711  for (vect_index = VLA_HWINT_LENGTH (*vect);
7712       vect_index <= equiv_class_num;
7713       vect_index++)
7714    VLA_HWINT_ADD (*vect, undefined_vect_el_value);
7715  VLA_HWINT (*vect, equiv_class_num) = el_value;
7716}
7717
7718/* This is for forming vector of states of an automaton.  */
7719static vla_ptr_t output_states_vect;
7720
7721/* The function is called by function pass_states.  The function adds
7722   STATE to `output_states_vect'.  */
7723static void
7724add_states_vect_el (state_t state)
7725{
7726  VLA_PTR_ADD (output_states_vect, state);
7727}
7728
7729/* Form and output vectors (comb, check, base or full vector)
7730   representing transition table of AUTOMATON.  */
7731static void
7732output_trans_table (automaton_t automaton)
7733{
7734  state_t *state_ptr;
7735  arc_t arc;
7736  vla_hwint_t transition_vect;
7737
7738  undefined_vect_el_value = automaton->achieved_states_num;
7739  automaton->trans_table = create_state_ainsn_table (automaton);
7740  /* Create vect of pointers to states ordered by num of transitions
7741     from the state (state with the maximum num is the first).  */
7742  VLA_PTR_CREATE (output_states_vect, 1500, "output states vector");
7743  pass_states (automaton, add_states_vect_el);
7744  qsort (VLA_PTR_BEGIN (output_states_vect),
7745         VLA_PTR_LENGTH (output_states_vect),
7746         sizeof (state_t), compare_transition_els_num);
7747  VLA_HWINT_CREATE (transition_vect, 500, "transition vector");
7748  for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
7749       state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
7750       state_ptr++)
7751    {
7752      VLA_HWINT_NULLIFY (transition_vect);
7753      for (arc = first_out_arc (*state_ptr);
7754	   arc != NULL;
7755	   arc = next_out_arc (arc))
7756        {
7757          if (arc->insn == NULL)
7758	    abort ();
7759          if (arc->insn->first_ainsn_with_given_equialence_num)
7760            add_vect_el (&transition_vect, arc->insn,
7761                         arc->to_state->order_state_num);
7762        }
7763      add_vect (automaton->trans_table, (*state_ptr)->order_state_num,
7764                VLA_HWINT_BEGIN (transition_vect),
7765                VLA_HWINT_LENGTH (transition_vect));
7766    }
7767  output_state_ainsn_table
7768    (automaton->trans_table, (char *) "state transitions",
7769     output_trans_full_vect_name, output_trans_comb_vect_name,
7770     output_trans_check_vect_name, output_trans_base_vect_name);
7771  VLA_PTR_DELETE (output_states_vect);
7772  VLA_HWINT_DELETE (transition_vect);
7773}
7774
7775/* Form and output vectors (comb, check, base or simple vect)
7776   representing alts number table of AUTOMATON.  The table is state x
7777   ainsn -> number of possible alternative reservations by the
7778   ainsn.  */
7779static void
7780output_state_alts_table (automaton_t automaton)
7781{
7782  state_t *state_ptr;
7783  arc_t arc;
7784  vla_hwint_t state_alts_vect;
7785
7786  undefined_vect_el_value = 0; /* no alts when transition is not possible */
7787  automaton->state_alts_table = create_state_ainsn_table (automaton);
7788  /* Create vect of pointers to states ordered by num of transitions
7789     from the state (state with the maximum num is the first).  */
7790  VLA_PTR_CREATE (output_states_vect, 1500, "output states vector");
7791  pass_states (automaton, add_states_vect_el);
7792  qsort (VLA_PTR_BEGIN (output_states_vect),
7793         VLA_PTR_LENGTH (output_states_vect),
7794         sizeof (state_t), compare_transition_els_num);
7795  /* Create base, comb, and check vectors.  */
7796  VLA_HWINT_CREATE (state_alts_vect, 500, "state alts vector");
7797  for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
7798       state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
7799       state_ptr++)
7800    {
7801      VLA_HWINT_NULLIFY (state_alts_vect);
7802      for (arc = first_out_arc (*state_ptr);
7803	   arc != NULL;
7804	   arc = next_out_arc (arc))
7805        {
7806          if (arc->insn == NULL)
7807	    abort ();
7808          if (arc->insn->first_ainsn_with_given_equialence_num)
7809            add_vect_el (&state_alts_vect, arc->insn, arc->state_alts);
7810        }
7811      add_vect (automaton->state_alts_table, (*state_ptr)->order_state_num,
7812                VLA_HWINT_BEGIN (state_alts_vect),
7813                VLA_HWINT_LENGTH (state_alts_vect));
7814    }
7815  output_state_ainsn_table
7816    (automaton->state_alts_table, (char *) "state insn alternatives",
7817     output_state_alts_full_vect_name, output_state_alts_comb_vect_name,
7818     output_state_alts_check_vect_name, output_state_alts_base_vect_name);
7819  VLA_PTR_DELETE (output_states_vect);
7820  VLA_HWINT_DELETE (state_alts_vect);
7821}
7822
7823/* The current number of passing states to find minimal issue delay
7824   value for an ainsn and state.  */
7825static int curr_state_pass_num;
7826
7827/* This recursive function passes states to find minimal issue delay
7828   value for AINSN.  The state being visited is STATE.  The function
7829   returns minimal issue delay value for AINSN in STATE or -1 if we
7830   enter into a loop.  */
7831static int
7832min_issue_delay_pass_states (state_t state, ainsn_t ainsn)
7833{
7834  arc_t arc;
7835  int min_insn_issue_delay, insn_issue_delay;
7836
7837  if (state->state_pass_num == curr_state_pass_num
7838      || state->min_insn_issue_delay != -1)
7839    /* We've entered into a loop or already have the correct value for
7840       given state and ainsn.  */
7841    return state->min_insn_issue_delay;
7842  state->state_pass_num = curr_state_pass_num;
7843  min_insn_issue_delay = -1;
7844  for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
7845    if (arc->insn == ainsn)
7846      {
7847	min_insn_issue_delay = 0;
7848	break;
7849      }
7850    else
7851      {
7852        insn_issue_delay = min_issue_delay_pass_states (arc->to_state, ainsn);
7853	if (insn_issue_delay != -1)
7854	  {
7855	    if (arc->insn->insn_reserv_decl
7856		== DECL_INSN_RESERV (advance_cycle_insn_decl))
7857	      insn_issue_delay++;
7858	    if (min_insn_issue_delay == -1
7859		|| min_insn_issue_delay > insn_issue_delay)
7860	      {
7861		min_insn_issue_delay = insn_issue_delay;
7862		if (insn_issue_delay == 0)
7863		  break;
7864	      }
7865	  }
7866      }
7867  return min_insn_issue_delay;
7868}
7869
7870/* The function searches minimal issue delay value for AINSN in STATE.
7871   The function can return negative value if we can not issue AINSN.  We
7872   will report about it later.  */
7873static int
7874min_issue_delay (state_t state, ainsn_t ainsn)
7875{
7876  curr_state_pass_num++;
7877  state->min_insn_issue_delay = min_issue_delay_pass_states (state, ainsn);
7878  return state->min_insn_issue_delay;
7879}
7880
7881/* The function initiates code for finding minimal issue delay values.
7882   It should be called only once.  */
7883static void
7884initiate_min_issue_delay_pass_states (void)
7885{
7886  curr_state_pass_num = 0;
7887}
7888
7889/* Form and output vectors representing minimal issue delay table of
7890   AUTOMATON.  The table is state x ainsn -> minimal issue delay of
7891   the ainsn.  */
7892static void
7893output_min_issue_delay_table (automaton_t automaton)
7894{
7895  vla_hwint_t min_issue_delay_vect;
7896  vla_hwint_t compressed_min_issue_delay_vect;
7897  vect_el_t min_delay;
7898  ainsn_t ainsn;
7899  state_t *state_ptr;
7900  int i;
7901
7902  /* Create vect of pointers to states ordered by num of transitions
7903     from the state (state with the maximum num is the first).  */
7904  VLA_PTR_CREATE (output_states_vect, 1500, "output states vector");
7905  pass_states (automaton, add_states_vect_el);
7906  VLA_HWINT_CREATE (min_issue_delay_vect, 1500, "min issue delay vector");
7907  VLA_HWINT_EXPAND (min_issue_delay_vect,
7908		    VLA_HWINT_LENGTH (output_states_vect)
7909		    * automaton->insn_equiv_classes_num);
7910  for (i = 0;
7911       i < ((int) VLA_HWINT_LENGTH (output_states_vect)
7912	    * automaton->insn_equiv_classes_num);
7913       i++)
7914    VLA_HWINT (min_issue_delay_vect, i) = 0;
7915  automaton->max_min_delay = 0;
7916  for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
7917    if (ainsn->first_ainsn_with_given_equialence_num)
7918      {
7919	for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
7920	     state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
7921	     state_ptr++)
7922	  (*state_ptr)->min_insn_issue_delay = -1;
7923	for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
7924	     state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
7925	     state_ptr++)
7926	  {
7927            min_delay = min_issue_delay (*state_ptr, ainsn);
7928	    if (automaton->max_min_delay < min_delay)
7929	      automaton->max_min_delay = min_delay;
7930	    VLA_HWINT (min_issue_delay_vect,
7931		       (*state_ptr)->order_state_num
7932		       * automaton->insn_equiv_classes_num
7933		       + ainsn->insn_equiv_class_num) = min_delay;
7934	  }
7935      }
7936  fprintf (output_file, "/* Vector of min issue delay of insns.  */\n");
7937  fprintf (output_file, "static const ");
7938  output_range_type (output_file, 0, automaton->max_min_delay);
7939  fprintf (output_file, " ");
7940  output_min_issue_delay_vect_name (output_file, automaton);
7941  fprintf (output_file, "[] ATTRIBUTE_UNUSED = {\n");
7942  /* Compress the vector.  */
7943  if (automaton->max_min_delay < 2)
7944    automaton->min_issue_delay_table_compression_factor = 8;
7945  else if (automaton->max_min_delay < 4)
7946    automaton->min_issue_delay_table_compression_factor = 4;
7947  else if (automaton->max_min_delay < 16)
7948    automaton->min_issue_delay_table_compression_factor = 2;
7949  else
7950    automaton->min_issue_delay_table_compression_factor = 1;
7951  VLA_HWINT_CREATE (compressed_min_issue_delay_vect, 1500,
7952		    "compressed min issue delay vector");
7953  VLA_HWINT_EXPAND (compressed_min_issue_delay_vect,
7954		    (VLA_HWINT_LENGTH (min_issue_delay_vect)
7955		     + automaton->min_issue_delay_table_compression_factor
7956		     - 1)
7957		    / automaton->min_issue_delay_table_compression_factor);
7958  for (i = 0;
7959       i < (int) VLA_HWINT_LENGTH (compressed_min_issue_delay_vect);
7960       i++)
7961    VLA_HWINT (compressed_min_issue_delay_vect, i) = 0;
7962  for (i = 0; i < (int) VLA_HWINT_LENGTH (min_issue_delay_vect); i++)
7963    VLA_HWINT (compressed_min_issue_delay_vect,
7964	       i / automaton->min_issue_delay_table_compression_factor)
7965      |= (VLA_HWINT (min_issue_delay_vect, i)
7966	  << (8 - (i % automaton->min_issue_delay_table_compression_factor
7967		   + 1)
7968	      * (8 / automaton->min_issue_delay_table_compression_factor)));
7969  output_vect (VLA_HWINT_BEGIN (compressed_min_issue_delay_vect),
7970               VLA_HWINT_LENGTH (compressed_min_issue_delay_vect));
7971  fprintf (output_file, "};\n\n");
7972  VLA_PTR_DELETE (output_states_vect);
7973  VLA_HWINT_DELETE (min_issue_delay_vect);
7974  VLA_HWINT_DELETE (compressed_min_issue_delay_vect);
7975}
7976
7977#ifndef NDEBUG
7978/* Number of states which contains transition only by advancing cpu
7979   cycle.  */
7980static int locked_states_num;
7981#endif
7982
7983/* Form and output vector representing the locked states of
7984   AUTOMATON.  */
7985static void
7986output_dead_lock_vect (automaton_t automaton)
7987{
7988  state_t *state_ptr;
7989  arc_t arc;
7990  vla_hwint_t dead_lock_vect;
7991
7992  /* Create vect of pointers to states ordered by num of
7993     transitions from the state (state with the maximum num is the
7994     first).  */
7995  VLA_PTR_CREATE (output_states_vect, 1500, "output states vector");
7996  pass_states (automaton, add_states_vect_el);
7997  VLA_HWINT_CREATE (dead_lock_vect, 1500, "is dead locked vector");
7998  VLA_HWINT_EXPAND (dead_lock_vect, VLA_HWINT_LENGTH (output_states_vect));
7999  for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
8000       state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
8001       state_ptr++)
8002    {
8003      arc = first_out_arc (*state_ptr);
8004      if (arc == NULL)
8005	abort ();
8006      VLA_HWINT (dead_lock_vect, (*state_ptr)->order_state_num)
8007        = (next_out_arc (arc) == NULL
8008           && (arc->insn->insn_reserv_decl
8009               == DECL_INSN_RESERV (advance_cycle_insn_decl)) ? 1 : 0);
8010#ifndef NDEBUG
8011      if (VLA_HWINT (dead_lock_vect, (*state_ptr)->order_state_num))
8012        locked_states_num++;
8013#endif
8014    }
8015  fprintf (output_file, "/* Vector for locked state flags.  */\n");
8016  fprintf (output_file, "static const ");
8017  output_range_type (output_file, 0, 1);
8018  fprintf (output_file, " ");
8019  output_dead_lock_vect_name (output_file, automaton);
8020  fprintf (output_file, "[] = {\n");
8021  output_vect (VLA_HWINT_BEGIN (dead_lock_vect),
8022	       VLA_HWINT_LENGTH (dead_lock_vect));
8023  fprintf (output_file, "};\n\n");
8024  VLA_HWINT_DELETE (dead_lock_vect);
8025  VLA_PTR_DELETE (output_states_vect);
8026}
8027
8028/* Form and output vector representing reserved units of the states of
8029   AUTOMATON.  */
8030static void
8031output_reserved_units_table (automaton_t automaton)
8032{
8033  state_t *curr_state_ptr;
8034  vla_hwint_t reserved_units_table;
8035  size_t state_byte_size;
8036  int i;
8037
8038  /* Create vect of pointers to states.  */
8039  VLA_PTR_CREATE (output_states_vect, 1500, "output states vector");
8040  pass_states (automaton, add_states_vect_el);
8041  /* Create vector.  */
8042  VLA_HWINT_CREATE (reserved_units_table, 1500, "reserved units vector");
8043  state_byte_size = (description->query_units_num + 7) / 8;
8044  VLA_HWINT_EXPAND (reserved_units_table,
8045		    VLA_HWINT_LENGTH (output_states_vect) * state_byte_size);
8046  for (i = 0;
8047       i < (int) (VLA_HWINT_LENGTH (output_states_vect) * state_byte_size);
8048       i++)
8049    VLA_HWINT (reserved_units_table, i) = 0;
8050  for (curr_state_ptr = VLA_PTR_BEGIN (output_states_vect);
8051       curr_state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
8052       curr_state_ptr++)
8053    {
8054      for (i = 0; i < description->units_num; i++)
8055	if (units_array [i]->query_p
8056	    && first_cycle_unit_presence (*curr_state_ptr, i))
8057	  VLA_HWINT (reserved_units_table,
8058		     (*curr_state_ptr)->order_state_num * state_byte_size
8059		     + units_array [i]->query_num / 8)
8060	    += (1 << (units_array [i]->query_num % 8));
8061    }
8062  fprintf (output_file, "/* Vector for reserved units of states.  */\n");
8063  fprintf (output_file, "static const ");
8064  output_range_type (output_file, 0, 255);
8065  fprintf (output_file, " ");
8066  output_reserved_units_table_name (output_file, automaton);
8067  fprintf (output_file, "[] = {\n");
8068  output_vect (VLA_HWINT_BEGIN (reserved_units_table),
8069               VLA_HWINT_LENGTH (reserved_units_table));
8070  fprintf (output_file, "};\n\n");
8071  VLA_HWINT_DELETE (reserved_units_table);
8072  VLA_PTR_DELETE (output_states_vect);
8073}
8074
8075/* The function outputs all tables representing DFA(s) used for fast
8076   pipeline hazards recognition.  */
8077static void
8078output_tables (void)
8079{
8080  automaton_t automaton;
8081
8082#ifndef NDEBUG
8083  locked_states_num = 0;
8084#endif
8085  initiate_min_issue_delay_pass_states ();
8086  for (automaton = description->first_automaton;
8087       automaton != NULL;
8088       automaton = automaton->next_automaton)
8089    {
8090      output_translate_vect (automaton);
8091      output_trans_table (automaton);
8092      fprintf (output_file, "\n#if %s\n", AUTOMATON_STATE_ALTS_MACRO_NAME);
8093      output_state_alts_table (automaton);
8094      fprintf (output_file, "\n#endif /* #if %s */\n\n",
8095	       AUTOMATON_STATE_ALTS_MACRO_NAME);
8096      output_min_issue_delay_table (automaton);
8097      output_dead_lock_vect (automaton);
8098      fprintf (output_file, "\n#if %s\n\n", CPU_UNITS_QUERY_MACRO_NAME);
8099      output_reserved_units_table (automaton);
8100      fprintf (output_file, "\n#endif /* #if %s */\n\n",
8101	       CPU_UNITS_QUERY_MACRO_NAME);
8102    }
8103  fprintf (output_file, "\n#define %s %d\n\n", ADVANCE_CYCLE_VALUE_NAME,
8104           DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num);
8105}
8106
8107/* The function outputs definition and value of PHR interface variable
8108   `max_insn_queue_index'.  Its value is not less than maximal queue
8109   length needed for the insn scheduler.  */
8110static void
8111output_max_insn_queue_index_def (void)
8112{
8113  int i, max, latency;
8114  decl_t decl;
8115
8116  max = description->max_insn_reserv_cycles;
8117  for (i = 0; i < description->decls_num; i++)
8118    {
8119      decl = description->decls [i];
8120      if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
8121	{
8122	  latency = DECL_INSN_RESERV (decl)->default_latency;
8123	  if (latency > max)
8124	    max = latency;
8125	}
8126      else if (decl->mode == dm_bypass)
8127	{
8128	  latency = DECL_BYPASS (decl)->latency;
8129	  if (latency > max)
8130	    max = latency;
8131	}
8132    }
8133  for (i = 0; (1 << i) <= max; i++)
8134    ;
8135  if (i < 0)
8136    abort ();
8137  fprintf (output_file, "\nint max_insn_queue_index = %d;\n\n", (1 << i) - 1);
8138}
8139
8140
8141/* The function outputs switch cases for insn reservations using
8142   function *output_automata_list_code.  */
8143static void
8144output_insn_code_cases (void (*output_automata_list_code)
8145			(automata_list_el_t))
8146{
8147  decl_t decl, decl2;
8148  int i, j;
8149
8150  for (i = 0; i < description->decls_num; i++)
8151    {
8152      decl = description->decls [i];
8153      if (decl->mode == dm_insn_reserv)
8154	DECL_INSN_RESERV (decl)->processed_p = FALSE;
8155    }
8156  for (i = 0; i < description->decls_num; i++)
8157    {
8158      decl = description->decls [i];
8159      if (decl->mode == dm_insn_reserv
8160	  && !DECL_INSN_RESERV (decl)->processed_p)
8161	{
8162	  for (j = i; j < description->decls_num; j++)
8163	    {
8164	      decl2 = description->decls [j];
8165	      if (decl2->mode == dm_insn_reserv
8166		  && (DECL_INSN_RESERV (decl2)->important_automata_list
8167		      == DECL_INSN_RESERV (decl)->important_automata_list))
8168		{
8169		  DECL_INSN_RESERV (decl2)->processed_p = TRUE;
8170		  fprintf (output_file, "    case %d: /* %s */\n",
8171			   DECL_INSN_RESERV (decl2)->insn_num,
8172			   DECL_INSN_RESERV (decl2)->name);
8173		}
8174	    }
8175	  (*output_automata_list_code)
8176	    (DECL_INSN_RESERV (decl)->important_automata_list);
8177	}
8178    }
8179}
8180
8181
8182/* The function outputs a code for evaluation of a minimal delay of
8183   issue of insns which have reservations in given AUTOMATA_LIST.  */
8184static void
8185output_automata_list_min_issue_delay_code (automata_list_el_t automata_list)
8186{
8187  automata_list_el_t el;
8188  automaton_t automaton;
8189
8190  for (el = automata_list; el != NULL; el = el->next_automata_list_el)
8191    {
8192      automaton = el->automaton;
8193      fprintf (output_file, "\n      %s = ", TEMPORARY_VARIABLE_NAME);
8194      output_min_issue_delay_vect_name (output_file, automaton);
8195      fprintf (output_file,
8196	       (automaton->min_issue_delay_table_compression_factor != 1
8197		? " [(" : " ["));
8198      output_translate_vect_name (output_file, automaton);
8199      fprintf (output_file, " [%s] + ", INTERNAL_INSN_CODE_NAME);
8200      fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
8201      output_chip_member_name (output_file, automaton);
8202      fprintf (output_file, " * %d", automaton->insn_equiv_classes_num);
8203      if (automaton->min_issue_delay_table_compression_factor == 1)
8204	fprintf (output_file, "];\n");
8205      else
8206	{
8207	  fprintf (output_file, ") / %d];\n",
8208		   automaton->min_issue_delay_table_compression_factor);
8209	  fprintf (output_file, "      %s = (%s >> (8 - (",
8210		   TEMPORARY_VARIABLE_NAME, TEMPORARY_VARIABLE_NAME);
8211	  output_translate_vect_name (output_file, automaton);
8212	  fprintf
8213	    (output_file, " [%s] %% %d + 1) * %d)) & %d;\n",
8214	     INTERNAL_INSN_CODE_NAME,
8215	     automaton->min_issue_delay_table_compression_factor,
8216	     8 / automaton->min_issue_delay_table_compression_factor,
8217	     (1 << (8 / automaton->min_issue_delay_table_compression_factor))
8218	     - 1);
8219	}
8220      if (el == automata_list)
8221	fprintf (output_file, "      %s = %s;\n",
8222		 RESULT_VARIABLE_NAME, TEMPORARY_VARIABLE_NAME);
8223      else
8224	{
8225	  fprintf (output_file, "      if (%s > %s)\n",
8226		   TEMPORARY_VARIABLE_NAME, RESULT_VARIABLE_NAME);
8227	  fprintf (output_file, "        %s = %s;\n",
8228		   RESULT_VARIABLE_NAME, TEMPORARY_VARIABLE_NAME);
8229	}
8230    }
8231  fprintf (output_file, "      break;\n\n");
8232}
8233
8234/* Output function `internal_min_issue_delay'.  */
8235static void
8236output_internal_min_issue_delay_func (void)
8237{
8238  fprintf (output_file,
8239	   "static int\n%s (int %s, struct %s *%s ATTRIBUTE_UNUSED)\n",
8240	   INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8241	   CHIP_NAME, CHIP_PARAMETER_NAME);
8242  fprintf (output_file, "{\n  int %s ATTRIBUTE_UNUSED;\n  int %s = -1;\n",
8243	   TEMPORARY_VARIABLE_NAME, RESULT_VARIABLE_NAME);
8244  fprintf (output_file, "\n  switch (%s)\n    {\n", INTERNAL_INSN_CODE_NAME);
8245  output_insn_code_cases (output_automata_list_min_issue_delay_code);
8246  fprintf (output_file,
8247	   "\n    default:\n      %s = -1;\n      break;\n    }\n",
8248	   RESULT_VARIABLE_NAME);
8249  fprintf (output_file, "  return %s;\n", RESULT_VARIABLE_NAME);
8250  fprintf (output_file, "}\n\n");
8251}
8252
8253/* The function outputs a code changing state after issue of insns
8254   which have reservations in given AUTOMATA_LIST.  */
8255static void
8256output_automata_list_transition_code (automata_list_el_t automata_list)
8257{
8258  automata_list_el_t el, next_el;
8259
8260  fprintf (output_file, "      {\n");
8261  if (automata_list != NULL && automata_list->next_automata_list_el != NULL)
8262    for (el = automata_list;; el = next_el)
8263      {
8264        next_el = el->next_automata_list_el;
8265        if (next_el == NULL)
8266          break;
8267        fprintf (output_file, "        ");
8268        output_state_member_type (output_file, el->automaton);
8269	fprintf (output_file, " ");
8270        output_temp_chip_member_name (output_file, el->automaton);
8271        fprintf (output_file, ";\n");
8272      }
8273  for (el = automata_list; el != NULL; el = el->next_automata_list_el)
8274    if (comb_vect_p (el->automaton->trans_table))
8275      {
8276	fprintf (output_file, "\n        %s = ", TEMPORARY_VARIABLE_NAME);
8277	output_trans_base_vect_name (output_file, el->automaton);
8278	fprintf (output_file, " [%s->", CHIP_PARAMETER_NAME);
8279	output_chip_member_name (output_file, el->automaton);
8280	fprintf (output_file, "] + ");
8281	output_translate_vect_name (output_file, el->automaton);
8282	fprintf (output_file, " [%s];\n", INTERNAL_INSN_CODE_NAME);
8283	fprintf (output_file, "        if (");
8284	output_trans_check_vect_name (output_file, el->automaton);
8285	fprintf (output_file, " [%s] != %s->",
8286		 TEMPORARY_VARIABLE_NAME, CHIP_PARAMETER_NAME);
8287	output_chip_member_name (output_file, el->automaton);
8288	fprintf (output_file, ")\n");
8289	fprintf (output_file, "          return %s (%s, %s);\n",
8290		 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8291		 CHIP_PARAMETER_NAME);
8292	fprintf (output_file, "        else\n");
8293	fprintf (output_file, "          ");
8294	if (el->next_automata_list_el != NULL)
8295	  output_temp_chip_member_name (output_file, el->automaton);
8296	else
8297	  {
8298	    fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
8299	    output_chip_member_name (output_file, el->automaton);
8300	  }
8301	fprintf (output_file, " = ");
8302	output_trans_comb_vect_name (output_file, el->automaton);
8303	fprintf (output_file, " [%s];\n", TEMPORARY_VARIABLE_NAME);
8304      }
8305    else
8306      {
8307	fprintf (output_file, "\n        %s = ", TEMPORARY_VARIABLE_NAME);
8308	output_trans_full_vect_name (output_file, el->automaton);
8309	fprintf (output_file, " [");
8310	output_translate_vect_name (output_file, el->automaton);
8311	fprintf (output_file, " [%s] + ", INTERNAL_INSN_CODE_NAME);
8312	fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
8313	output_chip_member_name (output_file, el->automaton);
8314	fprintf (output_file, " * %d];\n",
8315		 el->automaton->insn_equiv_classes_num);
8316	fprintf (output_file, "        if (%s >= %d)\n",
8317		 TEMPORARY_VARIABLE_NAME, el->automaton->achieved_states_num);
8318	fprintf (output_file, "          return %s (%s, %s);\n",
8319		 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8320		 CHIP_PARAMETER_NAME);
8321	fprintf (output_file, "        else\n          ");
8322	if (el->next_automata_list_el != NULL)
8323	  output_temp_chip_member_name (output_file, el->automaton);
8324	else
8325	  {
8326	    fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
8327	    output_chip_member_name (output_file, el->automaton);
8328	  }
8329	fprintf (output_file, " = %s;\n", TEMPORARY_VARIABLE_NAME);
8330      }
8331  if (automata_list != NULL && automata_list->next_automata_list_el != NULL)
8332    for (el = automata_list;; el = next_el)
8333      {
8334        next_el = el->next_automata_list_el;
8335        if (next_el == NULL)
8336          break;
8337        fprintf (output_file, "        %s->", CHIP_PARAMETER_NAME);
8338        output_chip_member_name (output_file, el->automaton);
8339        fprintf (output_file, " = ");
8340        output_temp_chip_member_name (output_file, el->automaton);
8341        fprintf (output_file, ";\n");
8342      }
8343  fprintf (output_file, "        return -1;\n");
8344  fprintf (output_file, "      }\n");
8345}
8346
8347/* Output function `internal_state_transition'.  */
8348static void
8349output_internal_trans_func (void)
8350{
8351  fprintf (output_file,
8352	   "static int\n%s (int %s, struct %s *%s ATTRIBUTE_UNUSED)\n",
8353	   INTERNAL_TRANSITION_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8354	   CHIP_NAME, CHIP_PARAMETER_NAME);
8355  fprintf (output_file, "{\n  int %s ATTRIBUTE_UNUSED;\n", TEMPORARY_VARIABLE_NAME);
8356  fprintf (output_file, "\n  switch (%s)\n    {\n", INTERNAL_INSN_CODE_NAME);
8357  output_insn_code_cases (output_automata_list_transition_code);
8358  fprintf (output_file, "\n    default:\n      return -1;\n    }\n");
8359  fprintf (output_file, "}\n\n");
8360}
8361
8362/* Output code
8363
8364  if (insn != 0)
8365    {
8366      insn_code = dfa_insn_code (insn);
8367      if (insn_code > DFA__ADVANCE_CYCLE)
8368        return code;
8369    }
8370  else
8371    insn_code = DFA__ADVANCE_CYCLE;
8372
8373  where insn denotes INSN_NAME, insn_code denotes INSN_CODE_NAME, and
8374  code denotes CODE.  */
8375static void
8376output_internal_insn_code_evaluation (const char *insn_name,
8377				      const char *insn_code_name,
8378				      int code)
8379{
8380  fprintf (output_file, "\n  if (%s != 0)\n    {\n", insn_name);
8381  fprintf (output_file, "      %s = %s (%s);\n", insn_code_name,
8382	   DFA_INSN_CODE_FUNC_NAME, insn_name);
8383  fprintf (output_file, "      if (%s > %s)\n        return %d;\n",
8384	   insn_code_name, ADVANCE_CYCLE_VALUE_NAME, code);
8385  fprintf (output_file, "    }\n  else\n    %s = %s;\n\n",
8386	   insn_code_name, ADVANCE_CYCLE_VALUE_NAME);
8387}
8388
8389
8390/* This function outputs `dfa_insn_code' and its helper function
8391   `dfa_insn_code_enlarge'.  */
8392static void
8393output_dfa_insn_code_func (void)
8394{
8395  /* Emacs c-mode gets really confused if there's a { or } in column 0
8396     inside a string, so don't do that.  */
8397  fprintf (output_file, "\
8398static void\n\
8399dfa_insn_code_enlarge (int uid)\n\
8400{\n\
8401  int i = %s;\n\
8402  %s = 2 * uid;\n\
8403  %s = xrealloc (%s,\n\
8404                 %s * sizeof(int));\n\
8405  for (; i < %s; i++)\n\
8406    %s[i] = -1;\n}\n\n",
8407	   DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
8408	   DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
8409	   DFA_INSN_CODES_VARIABLE_NAME, DFA_INSN_CODES_VARIABLE_NAME,
8410	   DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
8411	   DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
8412	   DFA_INSN_CODES_VARIABLE_NAME);
8413  fprintf (output_file, "\
8414static inline int\n%s (rtx %s)\n\
8415{\n\
8416  int uid = INSN_UID (%s);\n\
8417  int %s;\n\n",
8418	   DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME,
8419	   INSN_PARAMETER_NAME, INTERNAL_INSN_CODE_NAME);
8420
8421  fprintf (output_file,
8422	   "  if (uid >= %s)\n    dfa_insn_code_enlarge (uid);\n\n",
8423	   DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
8424  fprintf (output_file, "  %s = %s[uid];\n",
8425	   INTERNAL_INSN_CODE_NAME, DFA_INSN_CODES_VARIABLE_NAME);
8426  fprintf (output_file, "\
8427  if (%s < 0)\n\
8428    {\n\
8429      %s = %s (%s);\n\
8430      %s[uid] = %s;\n\
8431    }\n",
8432	   INTERNAL_INSN_CODE_NAME,
8433	   INTERNAL_INSN_CODE_NAME,
8434	   INTERNAL_DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME,
8435	   DFA_INSN_CODES_VARIABLE_NAME, INTERNAL_INSN_CODE_NAME);
8436  fprintf (output_file, "  return %s;\n}\n\n", INTERNAL_INSN_CODE_NAME);
8437}
8438
8439/* The function outputs PHR interface function `state_transition'.  */
8440static void
8441output_trans_func (void)
8442{
8443  fprintf (output_file, "int\n%s (%s %s, rtx %s)\n",
8444	   TRANSITION_FUNC_NAME, STATE_TYPE_NAME, STATE_NAME,
8445	   INSN_PARAMETER_NAME);
8446  fprintf (output_file, "{\n  int %s;\n", INTERNAL_INSN_CODE_NAME);
8447  output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
8448					INTERNAL_INSN_CODE_NAME, -1);
8449  fprintf (output_file, "  return %s (%s, %s);\n}\n\n",
8450	   INTERNAL_TRANSITION_FUNC_NAME, INTERNAL_INSN_CODE_NAME, STATE_NAME);
8451}
8452
8453/* The function outputs a code for evaluation of alternative states
8454   number for insns which have reservations in given AUTOMATA_LIST.  */
8455static void
8456output_automata_list_state_alts_code (automata_list_el_t automata_list)
8457{
8458  automata_list_el_t el;
8459  automaton_t automaton;
8460
8461  fprintf (output_file, "      {\n");
8462  for (el = automata_list; el != NULL; el = el->next_automata_list_el)
8463    if (comb_vect_p (el->automaton->state_alts_table))
8464      {
8465	fprintf (output_file, "        int %s;\n", TEMPORARY_VARIABLE_NAME);
8466	break;
8467      }
8468  for (el = automata_list; el != NULL; el = el->next_automata_list_el)
8469    {
8470      automaton = el->automaton;
8471      if (comb_vect_p (automaton->state_alts_table))
8472	{
8473	  fprintf (output_file, "\n        %s = ", TEMPORARY_VARIABLE_NAME);
8474	  output_state_alts_base_vect_name (output_file, automaton);
8475	  fprintf (output_file, " [%s->", CHIP_PARAMETER_NAME);
8476	  output_chip_member_name (output_file, automaton);
8477	  fprintf (output_file, "] + ");
8478	  output_translate_vect_name (output_file, automaton);
8479	  fprintf (output_file, " [%s];\n", INTERNAL_INSN_CODE_NAME);
8480	  fprintf (output_file, "        if (");
8481	  output_state_alts_check_vect_name (output_file, automaton);
8482	  fprintf (output_file, " [%s] != %s->",
8483		   TEMPORARY_VARIABLE_NAME, CHIP_PARAMETER_NAME);
8484	  output_chip_member_name (output_file, automaton);
8485	  fprintf (output_file, ")\n");
8486	  fprintf (output_file, "          return 0;\n");
8487	  fprintf (output_file, "        else\n");
8488	  fprintf (output_file,
8489		   (el == automata_list
8490		    ? "          %s = " : "          %s += "),
8491		   RESULT_VARIABLE_NAME);
8492	  output_state_alts_comb_vect_name (output_file, automaton);
8493	  fprintf (output_file, " [%s];\n", TEMPORARY_VARIABLE_NAME);
8494	}
8495      else
8496	{
8497	  fprintf (output_file,
8498		   (el == automata_list
8499		    ? "\n        %s = " : "        %s += "),
8500		   RESULT_VARIABLE_NAME);
8501	  output_state_alts_full_vect_name (output_file, automaton);
8502	  fprintf (output_file, " [");
8503	  output_translate_vect_name (output_file, automaton);
8504	  fprintf (output_file, " [%s] + ", INTERNAL_INSN_CODE_NAME);
8505	  fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
8506	  output_chip_member_name (output_file, automaton);
8507	  fprintf (output_file, " * %d];\n",
8508		   automaton->insn_equiv_classes_num);
8509	}
8510    }
8511  fprintf (output_file, "        break;\n      }\n\n");
8512}
8513
8514/* Output function `internal_state_alts'.  */
8515static void
8516output_internal_state_alts_func (void)
8517{
8518  fprintf (output_file,
8519	   "static int\n%s (int %s, struct %s *%s)\n",
8520	   INTERNAL_STATE_ALTS_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8521	   CHIP_NAME, CHIP_PARAMETER_NAME);
8522  fprintf (output_file, "{\n  int %s;\n", RESULT_VARIABLE_NAME);
8523  fprintf (output_file, "\n  switch (%s)\n    {\n", INTERNAL_INSN_CODE_NAME);
8524  output_insn_code_cases (output_automata_list_state_alts_code);
8525  fprintf (output_file,
8526	   "\n    default:\n      %s = 0;\n      break;\n    }\n",
8527	   RESULT_VARIABLE_NAME);
8528  fprintf (output_file, "  return %s;\n", RESULT_VARIABLE_NAME);
8529  fprintf (output_file, "}\n\n");
8530}
8531
8532/* The function outputs PHR interface function `state_alts'.  */
8533static void
8534output_state_alts_func (void)
8535{
8536  fprintf (output_file, "int\n%s (%s, %s)\n\t%s %s;\n\trtx %s;\n",
8537	   STATE_ALTS_FUNC_NAME, STATE_NAME, INSN_PARAMETER_NAME,
8538	   STATE_TYPE_NAME, STATE_NAME, INSN_PARAMETER_NAME);
8539  fprintf (output_file, "{\n  int %s;\n", INTERNAL_INSN_CODE_NAME);
8540  output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
8541					INTERNAL_INSN_CODE_NAME, 0);
8542  fprintf (output_file, "  return %s (%s, %s);\n}\n\n",
8543	   INTERNAL_STATE_ALTS_FUNC_NAME, INTERNAL_INSN_CODE_NAME, STATE_NAME);
8544}
8545
8546/* Output function `min_issue_delay'.  */
8547static void
8548output_min_issue_delay_func (void)
8549{
8550  fprintf (output_file, "int\n%s (%s %s, rtx %s)\n",
8551	   MIN_ISSUE_DELAY_FUNC_NAME, STATE_TYPE_NAME, STATE_NAME,
8552	   INSN_PARAMETER_NAME);
8553  fprintf (output_file, "{\n  int %s;\n", INTERNAL_INSN_CODE_NAME);
8554  fprintf (output_file, "\n  if (%s != 0)\n    {\n", INSN_PARAMETER_NAME);
8555  fprintf (output_file, "      %s = %s (%s);\n", INTERNAL_INSN_CODE_NAME,
8556	   DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME);
8557  fprintf (output_file, "      if (%s > %s)\n        return 0;\n",
8558	   INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8559  fprintf (output_file, "    }\n  else\n    %s = %s;\n",
8560	   INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8561  fprintf (output_file, "\n  return %s (%s, %s);\n",
8562	   INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8563	   STATE_NAME);
8564  fprintf (output_file, "}\n\n");
8565}
8566
8567/* Output function `internal_dead_lock'.  */
8568static void
8569output_internal_dead_lock_func (void)
8570{
8571  automaton_t automaton;
8572
8573  fprintf (output_file, "static int\n%s (struct %s *%s)\n",
8574	   INTERNAL_DEAD_LOCK_FUNC_NAME, CHIP_NAME, CHIP_PARAMETER_NAME);
8575  fprintf (output_file, "{\n");
8576  for (automaton = description->first_automaton;
8577       automaton != NULL;
8578       automaton = automaton->next_automaton)
8579    {
8580      fprintf (output_file, "  if (");
8581      output_dead_lock_vect_name (output_file, automaton);
8582      fprintf (output_file, " [%s->", CHIP_PARAMETER_NAME);
8583      output_chip_member_name (output_file, automaton);
8584      fprintf (output_file, "])\n    return 1/* TRUE */;\n");
8585    }
8586  fprintf (output_file, "  return 0/* FALSE */;\n}\n\n");
8587}
8588
8589/* The function outputs PHR interface function `state_dead_lock_p'.  */
8590static void
8591output_dead_lock_func (void)
8592{
8593  fprintf (output_file, "int\n%s (%s %s)\n",
8594	   DEAD_LOCK_FUNC_NAME, STATE_TYPE_NAME, STATE_NAME);
8595  fprintf (output_file, "{\n  return %s (%s);\n}\n\n",
8596	   INTERNAL_DEAD_LOCK_FUNC_NAME, STATE_NAME);
8597}
8598
8599/* Output function `internal_reset'.  */
8600static void
8601output_internal_reset_func (void)
8602{
8603  fprintf (output_file, "static inline void\n%s (struct %s *%s)\n",
8604	   INTERNAL_RESET_FUNC_NAME, CHIP_NAME, CHIP_PARAMETER_NAME);
8605  fprintf (output_file, "{\n  memset (%s, 0, sizeof (struct %s));\n}\n\n",
8606	   CHIP_PARAMETER_NAME, CHIP_NAME);
8607}
8608
8609/* The function outputs PHR interface function `state_size'.  */
8610static void
8611output_size_func (void)
8612{
8613  fprintf (output_file, "int\n%s (void)\n", SIZE_FUNC_NAME);
8614  fprintf (output_file, "{\n  return sizeof (struct %s);\n}\n\n", CHIP_NAME);
8615}
8616
8617/* The function outputs PHR interface function `state_reset'.  */
8618static void
8619output_reset_func (void)
8620{
8621  fprintf (output_file, "void\n%s (%s %s)\n",
8622	   RESET_FUNC_NAME, STATE_TYPE_NAME, STATE_NAME);
8623  fprintf (output_file, "{\n  %s (%s);\n}\n\n", INTERNAL_RESET_FUNC_NAME,
8624	   STATE_NAME);
8625}
8626
8627/* Output function `min_insn_conflict_delay'.  */
8628static void
8629output_min_insn_conflict_delay_func (void)
8630{
8631  fprintf (output_file,
8632	   "int\n%s (%s %s, rtx %s, rtx %s)\n",
8633	   MIN_INSN_CONFLICT_DELAY_FUNC_NAME, STATE_TYPE_NAME,
8634	   STATE_NAME, INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
8635  fprintf (output_file, "{\n  struct %s %s;\n  int %s, %s;\n",
8636	   CHIP_NAME, CHIP_NAME, INTERNAL_INSN_CODE_NAME,
8637	   INTERNAL_INSN2_CODE_NAME);
8638  output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
8639					INTERNAL_INSN_CODE_NAME, 0);
8640  output_internal_insn_code_evaluation (INSN2_PARAMETER_NAME,
8641					INTERNAL_INSN2_CODE_NAME, 0);
8642  fprintf (output_file, "  memcpy (&%s, %s, sizeof (%s));\n",
8643	   CHIP_NAME, STATE_NAME, CHIP_NAME);
8644  fprintf (output_file, "  %s (&%s);\n", INTERNAL_RESET_FUNC_NAME, CHIP_NAME);
8645  fprintf (output_file, "  if (%s (%s, &%s) > 0)\n    abort ();\n",
8646	   INTERNAL_TRANSITION_FUNC_NAME, INTERNAL_INSN_CODE_NAME, CHIP_NAME);
8647  fprintf (output_file, "  return %s (%s, &%s);\n",
8648	   INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN2_CODE_NAME,
8649	   CHIP_NAME);
8650  fprintf (output_file, "}\n\n");
8651}
8652
8653/* Output function `internal_insn_latency'.  */
8654static void
8655output_internal_insn_latency_func (void)
8656{
8657  decl_t decl;
8658  struct bypass_decl *bypass;
8659  int i, j, col;
8660  const char *tabletype = "unsigned char";
8661
8662  /* Find the smallest integer type that can hold all the default
8663     latency values.  */
8664  for (i = 0; i < description->decls_num; i++)
8665    if (description->decls[i]->mode == dm_insn_reserv)
8666      {
8667	decl = description->decls[i];
8668	if (DECL_INSN_RESERV (decl)->default_latency > UCHAR_MAX
8669	    && tabletype[0] != 'i')  /* Don't shrink it.  */
8670	  tabletype = "unsigned short";
8671	if (DECL_INSN_RESERV (decl)->default_latency > USHRT_MAX)
8672	  tabletype = "int";
8673      }
8674
8675  fprintf (output_file, "static int\n%s (int %s ATTRIBUTE_UNUSED,\n\tint %s ATTRIBUTE_UNUSED,\n\trtx %s ATTRIBUTE_UNUSED,\n\trtx %s ATTRIBUTE_UNUSED)\n",
8676	   INTERNAL_INSN_LATENCY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8677	   INTERNAL_INSN2_CODE_NAME, INSN_PARAMETER_NAME,
8678	   INSN2_PARAMETER_NAME);
8679  fprintf (output_file, "{\n");
8680
8681  if (DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num == 0)
8682    {
8683      fputs ("  return 0;\n}\n\n", output_file);
8684      return;
8685    }
8686
8687  fprintf (output_file, "  static const %s default_latencies[] =\n    {",
8688	   tabletype);
8689
8690  for (i = 0, j = 0, col = 7; i < description->decls_num; i++)
8691    if (description->decls[i]->mode == dm_insn_reserv
8692	&& description->decls[i] != advance_cycle_insn_decl)
8693      {
8694	if ((col = (col+1) % 8) == 0)
8695	  fputs ("\n     ", output_file);
8696	decl = description->decls[i];
8697	if (j++ != DECL_INSN_RESERV (decl)->insn_num)
8698	  abort ();
8699	fprintf (output_file, "% 4d,",
8700		 DECL_INSN_RESERV (decl)->default_latency);
8701      }
8702  if (j != DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num)
8703    abort ();
8704  fputs ("\n    };\n", output_file);
8705
8706  fprintf (output_file, "  if (%s >= %s || %s >= %s)\n    return 0;\n",
8707	   INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME,
8708	   INTERNAL_INSN2_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8709
8710  fprintf (output_file, "  switch (%s)\n    {\n", INTERNAL_INSN_CODE_NAME);
8711  for (i = 0; i < description->decls_num; i++)
8712    if (description->decls[i]->mode == dm_insn_reserv
8713	&& DECL_INSN_RESERV (description->decls[i])->bypass_list)
8714      {
8715	decl = description->decls [i];
8716	fprintf (output_file,
8717		 "    case %d:\n      switch (%s)\n        {\n",
8718		 DECL_INSN_RESERV (decl)->insn_num,
8719		 INTERNAL_INSN2_CODE_NAME);
8720	for (bypass = DECL_INSN_RESERV (decl)->bypass_list;
8721	     bypass != NULL;
8722	     bypass = bypass->next)
8723	  {
8724	    if (bypass->in_insn_reserv->insn_num
8725		== DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num)
8726	      abort ();
8727	    fprintf (output_file, "        case %d:\n",
8728		     bypass->in_insn_reserv->insn_num);
8729	    if (bypass->bypass_guard_name == NULL)
8730	      fprintf (output_file, "          return %d;\n",
8731		       bypass->latency);
8732	    else
8733	      {
8734		fprintf (output_file,
8735			 "          if (%s (%s, %s))\n",
8736			 bypass->bypass_guard_name, INSN_PARAMETER_NAME,
8737			 INSN2_PARAMETER_NAME);
8738		fprintf (output_file,
8739			 "            return %d;\n          break;\n",
8740			 bypass->latency);
8741	      }
8742	  }
8743	fputs ("        }\n      break;\n", output_file);
8744      }
8745
8746  fprintf (output_file, "    }\n  return default_latencies[%s];\n}\n\n",
8747	   INTERNAL_INSN_CODE_NAME);
8748}
8749
8750/* The function outputs PHR interface function `insn_latency'.  */
8751static void
8752output_insn_latency_func (void)
8753{
8754  fprintf (output_file, "int\n%s (rtx %s, rtx %s)\n",
8755	   INSN_LATENCY_FUNC_NAME, INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
8756  fprintf (output_file, "{\n  int %s, %s;\n",
8757	   INTERNAL_INSN_CODE_NAME, INTERNAL_INSN2_CODE_NAME);
8758  output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
8759					INTERNAL_INSN_CODE_NAME, 0);
8760  output_internal_insn_code_evaluation (INSN2_PARAMETER_NAME,
8761					INTERNAL_INSN2_CODE_NAME, 0);
8762  fprintf (output_file, "  return %s (%s, %s, %s, %s);\n}\n\n",
8763	   INTERNAL_INSN_LATENCY_FUNC_NAME,
8764	   INTERNAL_INSN_CODE_NAME, INTERNAL_INSN2_CODE_NAME,
8765	   INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
8766}
8767
8768/* The function outputs PHR interface function `print_reservation'.  */
8769static void
8770output_print_reservation_func (void)
8771{
8772  decl_t decl;
8773  int i, j;
8774
8775  fprintf (output_file,
8776	   "void\n%s (FILE *%s, rtx %s ATTRIBUTE_UNUSED)\n{\n",
8777           PRINT_RESERVATION_FUNC_NAME, FILE_PARAMETER_NAME,
8778           INSN_PARAMETER_NAME);
8779
8780  if (DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num == 0)
8781    {
8782      fprintf (output_file, "  fputs (\"%s\", %s);\n}\n\n",
8783	       NOTHING_NAME, FILE_PARAMETER_NAME);
8784      return;
8785    }
8786
8787
8788  fputs ("  static const char *const reservation_names[] =\n    {",
8789	 output_file);
8790
8791  for (i = 0, j = 0; i < description->decls_num; i++)
8792    {
8793      decl = description->decls [i];
8794      if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
8795	{
8796	  if (j++ != DECL_INSN_RESERV (decl)->insn_num)
8797	    abort ();
8798	  fprintf (output_file, "\n      \"%s\",",
8799		   regexp_representation (DECL_INSN_RESERV (decl)->regexp));
8800	  finish_regexp_representation ();
8801	}
8802    }
8803  if (j != DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num)
8804    abort ();
8805
8806  fprintf (output_file, "\n      \"%s\"\n    };\n  int %s;\n\n",
8807	   NOTHING_NAME, INTERNAL_INSN_CODE_NAME);
8808
8809  fprintf (output_file, "  if (%s == 0)\n    %s = %s;\n",
8810	   INSN_PARAMETER_NAME,
8811	   INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8812  fprintf (output_file, "  else\n\
8813    {\n\
8814      %s = %s (%s);\n\
8815      if (%s > %s)\n\
8816        %s = %s;\n\
8817    }\n",
8818	   INTERNAL_INSN_CODE_NAME, DFA_INSN_CODE_FUNC_NAME,
8819	       INSN_PARAMETER_NAME,
8820	   INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME,
8821	   INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8822
8823  fprintf (output_file, "  fputs (reservation_names[%s], %s);\n}\n\n",
8824	   INTERNAL_INSN_CODE_NAME, FILE_PARAMETER_NAME);
8825}
8826
8827/* The following function is used to sort unit declaration by their
8828   names.  */
8829static int
8830units_cmp (const void *unit1, const void *unit2)
8831{
8832  const unit_decl_t u1 = *(unit_decl_t *) unit1;
8833  const unit_decl_t u2 = *(unit_decl_t *) unit2;
8834
8835  return strcmp (u1->name, u2->name);
8836}
8837
8838/* The following macro value is name of struct containing unit name
8839   and unit code.  */
8840#define NAME_CODE_STRUCT_NAME  "name_code"
8841
8842/* The following macro value is name of table of struct name_code.  */
8843#define NAME_CODE_TABLE_NAME   "name_code_table"
8844
8845/* The following macro values are member names for struct name_code.  */
8846#define NAME_MEMBER_NAME       "name"
8847#define CODE_MEMBER_NAME       "code"
8848
8849/* The following macro values are local variable names for function
8850   `get_cpu_unit_code'.  */
8851#define CMP_VARIABLE_NAME      "cmp"
8852#define LOW_VARIABLE_NAME      "l"
8853#define MIDDLE_VARIABLE_NAME   "m"
8854#define HIGH_VARIABLE_NAME     "h"
8855
8856/* The following function outputs function to obtain internal cpu unit
8857   code by the cpu unit name.  */
8858static void
8859output_get_cpu_unit_code_func (void)
8860{
8861  int i;
8862  unit_decl_t *units;
8863
8864  fprintf (output_file, "int\n%s (%s)\n\tconst char *%s;\n",
8865	   GET_CPU_UNIT_CODE_FUNC_NAME, CPU_UNIT_NAME_PARAMETER_NAME,
8866	   CPU_UNIT_NAME_PARAMETER_NAME);
8867  fprintf (output_file, "{\n  struct %s {const char *%s; int %s;};\n",
8868	   NAME_CODE_STRUCT_NAME, NAME_MEMBER_NAME, CODE_MEMBER_NAME);
8869  fprintf (output_file, "  int %s, %s, %s, %s;\n", CMP_VARIABLE_NAME,
8870	   LOW_VARIABLE_NAME, MIDDLE_VARIABLE_NAME, HIGH_VARIABLE_NAME);
8871  fprintf (output_file, "  static struct %s %s [] =\n    {\n",
8872	   NAME_CODE_STRUCT_NAME, NAME_CODE_TABLE_NAME);
8873  units = xmalloc (sizeof (unit_decl_t) * description->units_num);
8874  memcpy (units, units_array, sizeof (unit_decl_t) * description->units_num);
8875  qsort (units, description->units_num, sizeof (unit_decl_t), units_cmp);
8876  for (i = 0; i < description->units_num; i++)
8877    if (units [i]->query_p)
8878      fprintf (output_file, "      {\"%s\", %d},\n",
8879	       units[i]->name, units[i]->query_num);
8880  fprintf (output_file, "    };\n\n");
8881  fprintf (output_file, "  /* The following is binary search: */\n");
8882  fprintf (output_file, "  %s = 0;\n", LOW_VARIABLE_NAME);
8883  fprintf (output_file, "  %s = sizeof (%s) / sizeof (struct %s) - 1;\n",
8884	   HIGH_VARIABLE_NAME, NAME_CODE_TABLE_NAME, NAME_CODE_STRUCT_NAME);
8885  fprintf (output_file, "  while (%s <= %s)\n    {\n",
8886	   LOW_VARIABLE_NAME, HIGH_VARIABLE_NAME);
8887  fprintf (output_file, "      %s = (%s + %s) / 2;\n",
8888	   MIDDLE_VARIABLE_NAME, LOW_VARIABLE_NAME, HIGH_VARIABLE_NAME);
8889  fprintf (output_file, "      %s = strcmp (%s, %s [%s].%s);\n",
8890	   CMP_VARIABLE_NAME, CPU_UNIT_NAME_PARAMETER_NAME,
8891	   NAME_CODE_TABLE_NAME, MIDDLE_VARIABLE_NAME, NAME_MEMBER_NAME);
8892  fprintf (output_file, "      if (%s < 0)\n", CMP_VARIABLE_NAME);
8893  fprintf (output_file, "        %s = %s - 1;\n",
8894	   HIGH_VARIABLE_NAME, MIDDLE_VARIABLE_NAME);
8895  fprintf (output_file, "      else if (%s > 0)\n", CMP_VARIABLE_NAME);
8896  fprintf (output_file, "        %s = %s + 1;\n",
8897	   LOW_VARIABLE_NAME, MIDDLE_VARIABLE_NAME);
8898  fprintf (output_file, "      else\n");
8899  fprintf (output_file, "        return %s [%s].%s;\n    }\n",
8900	   NAME_CODE_TABLE_NAME, MIDDLE_VARIABLE_NAME, CODE_MEMBER_NAME);
8901  fprintf (output_file, "  return -1;\n}\n\n");
8902  free (units);
8903}
8904
8905/* The following function outputs function to check reservation of cpu
8906   unit (its internal code will be passed as the function argument) in
8907   given cpu state.  */
8908static void
8909output_cpu_unit_reservation_p (void)
8910{
8911  automaton_t automaton;
8912
8913  fprintf (output_file, "int\n%s (%s, %s)\n\t%s %s;\n\tint %s;\n",
8914	   CPU_UNIT_RESERVATION_P_FUNC_NAME, STATE_NAME,
8915	   CPU_CODE_PARAMETER_NAME, STATE_TYPE_NAME, STATE_NAME,
8916	   CPU_CODE_PARAMETER_NAME);
8917  fprintf (output_file, "{\n  if (%s < 0 || %s >= %d)\n    abort ();\n",
8918	   CPU_CODE_PARAMETER_NAME, CPU_CODE_PARAMETER_NAME,
8919	   description->query_units_num);
8920  for (automaton = description->first_automaton;
8921       automaton != NULL;
8922       automaton = automaton->next_automaton)
8923    {
8924      fprintf (output_file, "  if ((");
8925      output_reserved_units_table_name (output_file, automaton);
8926      fprintf (output_file, " [((struct %s *) %s)->", CHIP_NAME, STATE_NAME);
8927      output_chip_member_name (output_file, automaton);
8928      fprintf (output_file, " * %d + %s / 8] >> (%s %% 8)) & 1)\n",
8929	       (description->query_units_num + 7) / 8,
8930	       CPU_CODE_PARAMETER_NAME, CPU_CODE_PARAMETER_NAME);
8931      fprintf (output_file, "    return 1;\n");
8932    }
8933  fprintf (output_file, "  return 0;\n}\n\n");
8934}
8935
8936/* The function outputs PHR interface function `dfa_clean_insn_cache'.  */
8937static void
8938output_dfa_clean_insn_cache_func (void)
8939{
8940  fprintf (output_file,
8941	   "void\n%s (void)\n{\n  int %s;\n\n",
8942	   DFA_CLEAN_INSN_CACHE_FUNC_NAME, I_VARIABLE_NAME);
8943  fprintf (output_file,
8944	   "  for (%s = 0; %s < %s; %s++)\n    %s [%s] = -1;\n}\n\n",
8945	   I_VARIABLE_NAME, I_VARIABLE_NAME,
8946	   DFA_INSN_CODES_LENGTH_VARIABLE_NAME, I_VARIABLE_NAME,
8947	   DFA_INSN_CODES_VARIABLE_NAME, I_VARIABLE_NAME);
8948}
8949
8950/* The function outputs PHR interface function `dfa_start'.  */
8951static void
8952output_dfa_start_func (void)
8953{
8954  fprintf (output_file,
8955	   "void\n%s (void)\n{\n  %s = get_max_uid ();\n",
8956	   DFA_START_FUNC_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
8957  fprintf (output_file, "  %s = xmalloc (%s * sizeof (int));\n",
8958	   DFA_INSN_CODES_VARIABLE_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
8959  fprintf (output_file, "  %s ();\n}\n\n", DFA_CLEAN_INSN_CACHE_FUNC_NAME);
8960}
8961
8962/* The function outputs PHR interface function `dfa_finish'.  */
8963static void
8964output_dfa_finish_func (void)
8965{
8966  fprintf (output_file, "void\n%s (void)\n{\n  free (%s);\n}\n\n",
8967	   DFA_FINISH_FUNC_NAME, DFA_INSN_CODES_VARIABLE_NAME);
8968}
8969
8970
8971
8972/* The page contains code for output description file (readable
8973   representation of original description and generated DFA(s).  */
8974
8975/* The function outputs string representation of IR reservation.  */
8976static void
8977output_regexp (regexp_t regexp)
8978{
8979  fprintf (output_description_file, "%s", regexp_representation (regexp));
8980  finish_regexp_representation ();
8981}
8982
8983/* Output names of units in LIST separated by comma.  */
8984static void
8985output_unit_set_el_list (unit_set_el_t list)
8986{
8987  unit_set_el_t el;
8988
8989  for (el = list; el != NULL; el = el->next_unit_set_el)
8990    {
8991      if (el != list)
8992	fprintf (output_description_file, ", ");
8993      fprintf (output_description_file, "%s", el->unit_decl->name);
8994    }
8995}
8996
8997/* Output patterns in LIST separated by comma.  */
8998static void
8999output_pattern_set_el_list (pattern_set_el_t list)
9000{
9001  pattern_set_el_t el;
9002  int i;
9003
9004  for (el = list; el != NULL; el = el->next_pattern_set_el)
9005    {
9006      if (el != list)
9007	fprintf (output_description_file, ", ");
9008      for (i = 0; i < el->units_num; i++)
9009	fprintf (output_description_file, (i == 0 ? "%s" : " %s"),
9010		 el->unit_decls [i]->name);
9011    }
9012}
9013
9014/* The function outputs string representation of IR define_reservation
9015   and define_insn_reservation.  */
9016static void
9017output_description (void)
9018{
9019  decl_t decl;
9020  int i;
9021
9022  for (i = 0; i < description->decls_num; i++)
9023    {
9024      decl = description->decls [i];
9025      if (decl->mode == dm_unit)
9026	{
9027	  if (DECL_UNIT (decl)->excl_list != NULL)
9028	    {
9029	      fprintf (output_description_file, "unit %s exlusion_set: ",
9030		       DECL_UNIT (decl)->name);
9031	      output_unit_set_el_list (DECL_UNIT (decl)->excl_list);
9032	      fprintf (output_description_file, "\n");
9033	    }
9034	  if (DECL_UNIT (decl)->presence_list != NULL)
9035	    {
9036	      fprintf (output_description_file, "unit %s presence_set: ",
9037		       DECL_UNIT (decl)->name);
9038	      output_pattern_set_el_list (DECL_UNIT (decl)->presence_list);
9039	      fprintf (output_description_file, "\n");
9040	    }
9041	  if (DECL_UNIT (decl)->final_presence_list != NULL)
9042	    {
9043	      fprintf (output_description_file, "unit %s final_presence_set: ",
9044		       DECL_UNIT (decl)->name);
9045	      output_pattern_set_el_list
9046		(DECL_UNIT (decl)->final_presence_list);
9047	      fprintf (output_description_file, "\n");
9048	    }
9049	  if (DECL_UNIT (decl)->absence_list != NULL)
9050	    {
9051	      fprintf (output_description_file, "unit %s absence_set: ",
9052		       DECL_UNIT (decl)->name);
9053	      output_pattern_set_el_list (DECL_UNIT (decl)->absence_list);
9054	      fprintf (output_description_file, "\n");
9055	    }
9056	  if (DECL_UNIT (decl)->final_absence_list != NULL)
9057	    {
9058	      fprintf (output_description_file, "unit %s final_absence_set: ",
9059		       DECL_UNIT (decl)->name);
9060	      output_pattern_set_el_list
9061		(DECL_UNIT (decl)->final_absence_list);
9062	      fprintf (output_description_file, "\n");
9063	    }
9064	}
9065    }
9066  fprintf (output_description_file, "\n");
9067  for (i = 0; i < description->decls_num; i++)
9068    {
9069      decl = description->decls [i];
9070      if (decl->mode == dm_reserv)
9071	{
9072          fprintf (output_description_file, "reservation %s: ",
9073		   DECL_RESERV (decl)->name);
9074          output_regexp (DECL_RESERV (decl)->regexp);
9075          fprintf (output_description_file, "\n");
9076        }
9077      else if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
9078        {
9079          fprintf (output_description_file, "insn reservation %s ",
9080		   DECL_INSN_RESERV (decl)->name);
9081          print_rtl (output_description_file,
9082		     DECL_INSN_RESERV (decl)->condexp);
9083          fprintf (output_description_file, ": ");
9084          output_regexp (DECL_INSN_RESERV (decl)->regexp);
9085          fprintf (output_description_file, "\n");
9086        }
9087      else if (decl->mode == dm_bypass)
9088	fprintf (output_description_file, "bypass %d %s %s\n",
9089		 DECL_BYPASS (decl)->latency,
9090		 DECL_BYPASS (decl)->out_insn_name,
9091		 DECL_BYPASS (decl)->in_insn_name);
9092    }
9093  fprintf (output_description_file, "\n\f\n");
9094}
9095
9096/* The function outputs name of AUTOMATON.  */
9097static void
9098output_automaton_name (FILE *f, automaton_t automaton)
9099{
9100  if (automaton->corresponding_automaton_decl == NULL)
9101    fprintf (f, "#%d", automaton->automaton_order_num);
9102  else
9103    fprintf (f, "`%s'", automaton->corresponding_automaton_decl->name);
9104}
9105
9106/* Maximal length of line for pretty printing into description
9107   file.  */
9108#define MAX_LINE_LENGTH 70
9109
9110/* The function outputs units name belonging to AUTOMATON.  */
9111static void
9112output_automaton_units (automaton_t automaton)
9113{
9114  decl_t decl;
9115  char *name;
9116  int curr_line_length;
9117  int there_is_an_automaton_unit;
9118  int i;
9119
9120  fprintf (output_description_file, "\n  Coresponding units:\n");
9121  fprintf (output_description_file, "    ");
9122  curr_line_length = 4;
9123  there_is_an_automaton_unit = 0;
9124  for (i = 0; i < description->decls_num; i++)
9125    {
9126      decl = description->decls [i];
9127      if (decl->mode == dm_unit
9128          && (DECL_UNIT (decl)->corresponding_automaton_num
9129	      == automaton->automaton_order_num))
9130	{
9131	  there_is_an_automaton_unit = 1;
9132	  name = DECL_UNIT (decl)->name;
9133	  if (curr_line_length + strlen (name) + 1 > MAX_LINE_LENGTH )
9134	    {
9135	      curr_line_length = strlen (name) + 4;
9136	      fprintf (output_description_file, "\n    ");
9137	    }
9138	  else
9139	    {
9140	      curr_line_length += strlen (name) + 1;
9141	      fprintf (output_description_file, " ");
9142	    }
9143	  fprintf (output_description_file, "%s", name);
9144	}
9145    }
9146  if (!there_is_an_automaton_unit)
9147    fprintf (output_description_file, "<None>");
9148  fprintf (output_description_file, "\n\n");
9149}
9150
9151/* The following variable is used for forming array of all possible cpu unit
9152   reservations described by the current DFA state.  */
9153static vla_ptr_t state_reservs;
9154
9155/* The function forms `state_reservs' for STATE.  */
9156static void
9157add_state_reservs (state_t state)
9158{
9159  alt_state_t curr_alt_state;
9160  reserv_sets_t reservs;
9161
9162  if (state->component_states != NULL)
9163    for (curr_alt_state = state->component_states;
9164         curr_alt_state != NULL;
9165         curr_alt_state = curr_alt_state->next_sorted_alt_state)
9166      add_state_reservs (curr_alt_state->state);
9167  else
9168    {
9169      reservs = state->reservs;
9170      VLA_PTR_ADD (state_reservs, reservs);
9171    }
9172}
9173
9174/* The function outputs readable representation of all out arcs of
9175   STATE.  */
9176static void
9177output_state_arcs (state_t state)
9178{
9179  arc_t arc;
9180  ainsn_t ainsn;
9181  char *insn_name;
9182  int curr_line_length;
9183
9184  for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
9185    {
9186      ainsn = arc->insn;
9187      if (!ainsn->first_insn_with_same_reservs)
9188	abort ();
9189      fprintf (output_description_file, "    ");
9190      curr_line_length = 7;
9191      fprintf (output_description_file, "%2d: ", ainsn->insn_equiv_class_num);
9192      do
9193        {
9194          insn_name = ainsn->insn_reserv_decl->name;
9195          if (curr_line_length + strlen (insn_name) > MAX_LINE_LENGTH)
9196            {
9197              if (ainsn != arc->insn)
9198                {
9199                  fprintf (output_description_file, ",\n      ");
9200                  curr_line_length = strlen (insn_name) + 6;
9201                }
9202              else
9203                curr_line_length += strlen (insn_name);
9204            }
9205          else
9206            {
9207              curr_line_length += strlen (insn_name);
9208              if (ainsn != arc->insn)
9209                {
9210                  curr_line_length += 2;
9211                  fprintf (output_description_file, ", ");
9212                }
9213            }
9214          fprintf (output_description_file, "%s", insn_name);
9215          ainsn = ainsn->next_same_reservs_insn;
9216        }
9217      while (ainsn != NULL);
9218      fprintf (output_description_file, "    %d (%d)\n",
9219	       arc->to_state->order_state_num, arc->state_alts);
9220    }
9221  fprintf (output_description_file, "\n");
9222}
9223
9224/* The following function is used for sorting possible cpu unit
9225   reservation of a DFA state.  */
9226static int
9227state_reservs_cmp (const void *reservs_ptr_1, const void *reservs_ptr_2)
9228{
9229  return reserv_sets_cmp (*(reserv_sets_t *) reservs_ptr_1,
9230                          *(reserv_sets_t *) reservs_ptr_2);
9231}
9232
9233/* The following function is used for sorting possible cpu unit
9234   reservation of a DFA state.  */
9235static void
9236remove_state_duplicate_reservs (void)
9237{
9238  reserv_sets_t *reservs_ptr;
9239  reserv_sets_t *last_formed_reservs_ptr;
9240
9241  last_formed_reservs_ptr = NULL;
9242  for (reservs_ptr = VLA_PTR_BEGIN (state_reservs);
9243       reservs_ptr <= (reserv_sets_t *) VLA_PTR_LAST (state_reservs);
9244       reservs_ptr++)
9245    if (last_formed_reservs_ptr == NULL)
9246      last_formed_reservs_ptr = reservs_ptr;
9247    else if (reserv_sets_cmp (*last_formed_reservs_ptr, *reservs_ptr) != 0)
9248      {
9249        ++last_formed_reservs_ptr;
9250        *last_formed_reservs_ptr = *reservs_ptr;
9251      }
9252  VLA_PTR_SHORTEN (state_reservs, reservs_ptr - last_formed_reservs_ptr - 1);
9253}
9254
9255/* The following function output readable representation of DFA(s)
9256   state used for fast recognition of pipeline hazards.  State is
9257   described by possible (current and scheduled) cpu unit
9258   reservations.  */
9259static void
9260output_state (state_t state)
9261{
9262  reserv_sets_t *reservs_ptr;
9263
9264  VLA_PTR_CREATE (state_reservs, 150, "state reservations");
9265  fprintf (output_description_file, "  State #%d", state->order_state_num);
9266  fprintf (output_description_file,
9267	   state->new_cycle_p ? " (new cycle)\n" : "\n");
9268  add_state_reservs (state);
9269  qsort (VLA_PTR_BEGIN (state_reservs), VLA_PTR_LENGTH (state_reservs),
9270         sizeof (reserv_sets_t), state_reservs_cmp);
9271  remove_state_duplicate_reservs ();
9272  for (reservs_ptr = VLA_PTR_BEGIN (state_reservs);
9273       reservs_ptr <= (reserv_sets_t *) VLA_PTR_LAST (state_reservs);
9274       reservs_ptr++)
9275    {
9276      fprintf (output_description_file, "    ");
9277      output_reserv_sets (output_description_file, *reservs_ptr);
9278      fprintf (output_description_file, "\n");
9279    }
9280  fprintf (output_description_file, "\n");
9281  output_state_arcs (state);
9282  VLA_PTR_DELETE (state_reservs);
9283}
9284
9285/* The following function output readable representation of
9286   DFAs used for fast recognition of pipeline hazards.  */
9287static void
9288output_automaton_descriptions (void)
9289{
9290  automaton_t automaton;
9291
9292  for (automaton = description->first_automaton;
9293       automaton != NULL;
9294       automaton = automaton->next_automaton)
9295    {
9296      fprintf (output_description_file, "\nAutomaton ");
9297      output_automaton_name (output_description_file, automaton);
9298      fprintf (output_description_file, "\n");
9299      output_automaton_units (automaton);
9300      pass_states (automaton, output_state);
9301    }
9302}
9303
9304
9305
9306/* The page contains top level function for generation DFA(s) used for
9307   PHR.  */
9308
9309/* The function outputs statistics about work of different phases of
9310   DFA generator.  */
9311static void
9312output_statistics (FILE *f)
9313{
9314  automaton_t automaton;
9315  int states_num;
9316#ifndef NDEBUG
9317  int transition_comb_vect_els = 0;
9318  int transition_full_vect_els = 0;
9319  int state_alts_comb_vect_els = 0;
9320  int state_alts_full_vect_els = 0;
9321  int min_issue_delay_vect_els = 0;
9322#endif
9323
9324  for (automaton = description->first_automaton;
9325       automaton != NULL;
9326       automaton = automaton->next_automaton)
9327    {
9328      fprintf (f, "\nAutomaton ");
9329      output_automaton_name (f, automaton);
9330      fprintf (f, "\n    %5d NDFA states,          %5d NDFA arcs\n",
9331	       automaton->NDFA_states_num, automaton->NDFA_arcs_num);
9332      fprintf (f, "    %5d DFA states,           %5d DFA arcs\n",
9333	       automaton->DFA_states_num, automaton->DFA_arcs_num);
9334      states_num = automaton->DFA_states_num;
9335      if (!no_minimization_flag)
9336	{
9337	  fprintf (f, "    %5d minimal DFA states,   %5d minimal DFA arcs\n",
9338		   automaton->minimal_DFA_states_num,
9339		   automaton->minimal_DFA_arcs_num);
9340	  states_num = automaton->minimal_DFA_states_num;
9341	}
9342      fprintf (f, "    %5d all insns      %5d insn equivalence classes\n",
9343	       description->insns_num, automaton->insn_equiv_classes_num);
9344#ifndef NDEBUG
9345      fprintf
9346	(f, "%5ld transition comb vector els, %5ld trans table els: %s\n",
9347	 (long) VLA_HWINT_LENGTH (automaton->trans_table->comb_vect),
9348	 (long) VLA_HWINT_LENGTH (automaton->trans_table->full_vect),
9349	 (comb_vect_p (automaton->trans_table)
9350	  ? "use comb vect" : "use simple vect"));
9351      fprintf
9352        (f, "%5ld state alts comb vector els, %5ld state alts table els: %s\n",
9353         (long) VLA_HWINT_LENGTH (automaton->state_alts_table->comb_vect),
9354         (long) VLA_HWINT_LENGTH (automaton->state_alts_table->full_vect),
9355         (comb_vect_p (automaton->state_alts_table)
9356          ? "use comb vect" : "use simple vect"));
9357      fprintf
9358        (f, "%5ld min delay table els, compression factor %d\n",
9359         (long) states_num * automaton->insn_equiv_classes_num,
9360	 automaton->min_issue_delay_table_compression_factor);
9361      transition_comb_vect_els
9362	+= VLA_HWINT_LENGTH (automaton->trans_table->comb_vect);
9363      transition_full_vect_els
9364        += VLA_HWINT_LENGTH (automaton->trans_table->full_vect);
9365      state_alts_comb_vect_els
9366        += VLA_HWINT_LENGTH (automaton->state_alts_table->comb_vect);
9367      state_alts_full_vect_els
9368        += VLA_HWINT_LENGTH (automaton->state_alts_table->full_vect);
9369      min_issue_delay_vect_els
9370	+= states_num * automaton->insn_equiv_classes_num;
9371#endif
9372    }
9373#ifndef NDEBUG
9374  fprintf (f, "\n%5d all allocated states,     %5d all allocated arcs\n",
9375	   allocated_states_num, allocated_arcs_num);
9376  fprintf (f, "%5d all allocated alternative states\n",
9377	   allocated_alt_states_num);
9378  fprintf (f, "%5d all transition comb vector els, %5d all trans table els\n",
9379	   transition_comb_vect_els, transition_full_vect_els);
9380  fprintf
9381    (f, "%5d all state alts comb vector els, %5d all state alts table els\n",
9382     state_alts_comb_vect_els, state_alts_full_vect_els);
9383  fprintf (f, "%5d all min delay table els\n", min_issue_delay_vect_els);
9384  fprintf (f, "%5d locked states num\n", locked_states_num);
9385#endif
9386}
9387
9388/* The function output times of work of different phases of DFA
9389   generator.  */
9390static void
9391output_time_statistics (FILE *f)
9392{
9393  fprintf (f, "\n  transformation: ");
9394  print_active_time (f, transform_time);
9395  fprintf (f, (!ndfa_flag ? ", building DFA: " : ", building NDFA: "));
9396  print_active_time (f, NDFA_time);
9397  if (ndfa_flag)
9398    {
9399      fprintf (f, ", NDFA -> DFA: ");
9400      print_active_time (f, NDFA_to_DFA_time);
9401    }
9402  fprintf (f, "\n  DFA minimization: ");
9403  print_active_time (f, minimize_time);
9404  fprintf (f, ", making insn equivalence: ");
9405  print_active_time (f, equiv_time);
9406  fprintf (f, "\n all automaton generation: ");
9407  print_active_time (f, automaton_generation_time);
9408  fprintf (f, ", output: ");
9409  print_active_time (f, output_time);
9410  fprintf (f, "\n");
9411}
9412
9413/* The function generates DFA (deterministic finite state automaton)
9414   for fast recognition of pipeline hazards.  No errors during
9415   checking must be fixed before this function call.  */
9416static void
9417generate (void)
9418{
9419  automata_num = split_argument;
9420  if (description->units_num < automata_num)
9421    automata_num = description->units_num;
9422  initiate_states ();
9423  initiate_arcs ();
9424  initiate_automata_lists ();
9425  initiate_pass_states ();
9426  initiate_excl_sets ();
9427  initiate_presence_absence_pattern_sets ();
9428  automaton_generation_time = create_ticker ();
9429  create_automata ();
9430  ticker_off (&automaton_generation_time);
9431}
9432
9433
9434
9435/* The following function creates insn attribute whose values are
9436   number alternatives in insn reservations.  */
9437static void
9438make_insn_alts_attr (void)
9439{
9440  int i, insn_num;
9441  decl_t decl;
9442  rtx condexp;
9443
9444  condexp = rtx_alloc (COND);
9445  XVEC (condexp, 0) = rtvec_alloc ((description->insns_num - 1) * 2);
9446  XEXP (condexp, 1) = make_numeric_value (0);
9447  for (i = insn_num = 0; i < description->decls_num; i++)
9448    {
9449      decl = description->decls [i];
9450      if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
9451	{
9452          XVECEXP (condexp, 0, 2 * insn_num)
9453	    = DECL_INSN_RESERV (decl)->condexp;
9454          XVECEXP (condexp, 0, 2 * insn_num + 1)
9455            = make_numeric_value
9456	      (DECL_INSN_RESERV (decl)->transformed_regexp->mode != rm_oneof
9457	       ? 1 : REGEXP_ONEOF (DECL_INSN_RESERV (decl)
9458				   ->transformed_regexp)->regexps_num);
9459          insn_num++;
9460        }
9461    }
9462  if (description->insns_num != insn_num + 1)
9463    abort ();
9464  make_internal_attr (attr_printf (sizeof ("*")
9465				   + strlen (INSN_ALTS_FUNC_NAME) + 1,
9466				   "*%s", INSN_ALTS_FUNC_NAME),
9467		      condexp, ATTR_NONE);
9468}
9469
9470
9471
9472/* The following function creates attribute which is order number of
9473   insn in pipeline hazard description translator.  */
9474static void
9475make_internal_dfa_insn_code_attr (void)
9476{
9477  int i, insn_num;
9478  decl_t decl;
9479  rtx condexp;
9480
9481  condexp = rtx_alloc (COND);
9482  XVEC (condexp, 0) = rtvec_alloc ((description->insns_num - 1) * 2);
9483  XEXP (condexp, 1)
9484    = make_numeric_value (DECL_INSN_RESERV (advance_cycle_insn_decl)
9485			  ->insn_num + 1);
9486  for (i = insn_num = 0; i < description->decls_num; i++)
9487    {
9488      decl = description->decls [i];
9489      if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
9490	{
9491          XVECEXP (condexp, 0, 2 * insn_num)
9492	    = DECL_INSN_RESERV (decl)->condexp;
9493          XVECEXP (condexp, 0, 2 * insn_num + 1)
9494            = make_numeric_value (DECL_INSN_RESERV (decl)->insn_num);
9495          insn_num++;
9496        }
9497    }
9498  if (description->insns_num != insn_num + 1)
9499    abort ();
9500  make_internal_attr
9501    (attr_printf (sizeof ("*")
9502		  + strlen (INTERNAL_DFA_INSN_CODE_FUNC_NAME) + 1,
9503		  "*%s", INTERNAL_DFA_INSN_CODE_FUNC_NAME),
9504     condexp, ATTR_STATIC);
9505}
9506
9507
9508
9509/* The following function creates attribute which order number of insn
9510   in pipeline hazard description translator.  */
9511static void
9512make_default_insn_latency_attr (void)
9513{
9514  int i, insn_num;
9515  decl_t decl;
9516  rtx condexp;
9517
9518  condexp = rtx_alloc (COND);
9519  XVEC (condexp, 0) = rtvec_alloc ((description->insns_num - 1) * 2);
9520  XEXP (condexp, 1) = make_numeric_value (0);
9521  for (i = insn_num = 0; i < description->decls_num; i++)
9522    {
9523      decl = description->decls [i];
9524      if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
9525	{
9526          XVECEXP (condexp, 0, 2 * insn_num)
9527	    = DECL_INSN_RESERV (decl)->condexp;
9528          XVECEXP (condexp, 0, 2 * insn_num + 1)
9529            = make_numeric_value (DECL_INSN_RESERV (decl)->default_latency);
9530          insn_num++;
9531        }
9532    }
9533  if (description->insns_num != insn_num + 1)
9534    abort ();
9535  make_internal_attr (attr_printf (sizeof ("*")
9536				   + strlen (INSN_DEFAULT_LATENCY_FUNC_NAME)
9537				   + 1, "*%s", INSN_DEFAULT_LATENCY_FUNC_NAME),
9538		      condexp, ATTR_NONE);
9539}
9540
9541
9542
9543/* The following function creates attribute which returns 1 if given
9544   output insn has bypassing and 0 otherwise.  */
9545static void
9546make_bypass_attr (void)
9547{
9548  int i, bypass_insn;
9549  int bypass_insns_num = 0;
9550  decl_t decl;
9551  rtx result_rtx;
9552
9553  for (i = 0; i < description->decls_num; i++)
9554    {
9555      decl = description->decls [i];
9556      if (decl->mode == dm_insn_reserv
9557	  && DECL_INSN_RESERV (decl)->condexp != NULL
9558	  && DECL_INSN_RESERV (decl)->bypass_list != NULL)
9559	bypass_insns_num++;
9560    }
9561  if (bypass_insns_num == 0)
9562    result_rtx = make_numeric_value (0);
9563  else
9564    {
9565      result_rtx = rtx_alloc (COND);
9566      XVEC (result_rtx, 0) = rtvec_alloc (bypass_insns_num * 2);
9567      XEXP (result_rtx, 1) = make_numeric_value (0);
9568
9569      for (i = bypass_insn = 0; i < description->decls_num; i++)
9570        {
9571          decl = description->decls [i];
9572          if (decl->mode == dm_insn_reserv
9573	      && DECL_INSN_RESERV (decl)->condexp != NULL
9574	      && DECL_INSN_RESERV (decl)->bypass_list != NULL)
9575	    {
9576              XVECEXP (result_rtx, 0, 2 * bypass_insn)
9577		= DECL_INSN_RESERV (decl)->condexp;
9578              XVECEXP (result_rtx, 0, 2 * bypass_insn + 1)
9579	        = make_numeric_value (1);
9580              bypass_insn++;
9581            }
9582        }
9583    }
9584  make_internal_attr (attr_printf (sizeof ("*")
9585				   + strlen (BYPASS_P_FUNC_NAME) + 1,
9586				   "*%s", BYPASS_P_FUNC_NAME),
9587		      result_rtx, ATTR_NONE);
9588}
9589
9590
9591
9592/* This page mainly contains top level functions of pipeline hazards
9593   description translator.  */
9594
9595/* The following macro value is suffix of name of description file of
9596   pipeline hazards description translator.  */
9597#define STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX ".dfa"
9598
9599/* The function returns suffix of given file name.  The returned
9600   string can not be changed.  */
9601static const char *
9602file_name_suffix (const char *file_name)
9603{
9604  const char *last_period;
9605
9606  for (last_period = NULL; *file_name != '\0'; file_name++)
9607    if (*file_name == '.')
9608      last_period = file_name;
9609  return (last_period == NULL ? file_name : last_period);
9610}
9611
9612/* The function returns base name of given file name, i.e. pointer to
9613   first char after last `/' (or `\' for WIN32) in given file name,
9614   given file name itself if the directory name is absent.  The
9615   returned string can not be changed.  */
9616static const char *
9617base_file_name (const char *file_name)
9618{
9619  int directory_name_length;
9620
9621  directory_name_length = strlen (file_name);
9622#ifdef WIN32
9623  while (directory_name_length >= 0 && file_name[directory_name_length] != '/'
9624         && file_name[directory_name_length] != '\\')
9625#else
9626  while (directory_name_length >= 0 && file_name[directory_name_length] != '/')
9627#endif
9628    directory_name_length--;
9629  return file_name + directory_name_length + 1;
9630}
9631
9632/* The following is top level function to initialize the work of
9633   pipeline hazards description translator.  */
9634void
9635initiate_automaton_gen (int argc, char **argv)
9636{
9637  const char *base_name;
9638  int i;
9639
9640  ndfa_flag = 0;
9641  split_argument = 0;  /* default value */
9642  no_minimization_flag = 0;
9643  time_flag = 0;
9644  v_flag = 0;
9645  w_flag = 0;
9646  progress_flag = 0;
9647  for (i = 2; i < argc; i++)
9648    if (strcmp (argv [i], NO_MINIMIZATION_OPTION) == 0)
9649      no_minimization_flag = 1;
9650    else if (strcmp (argv [i], TIME_OPTION) == 0)
9651      time_flag = 1;
9652    else if (strcmp (argv [i], V_OPTION) == 0)
9653      v_flag = 1;
9654    else if (strcmp (argv [i], W_OPTION) == 0)
9655      w_flag = 1;
9656    else if (strcmp (argv [i], NDFA_OPTION) == 0)
9657      ndfa_flag = 1;
9658    else if (strcmp (argv [i], PROGRESS_OPTION) == 0)
9659      progress_flag = 1;
9660    else if (strcmp (argv [i], "-split") == 0)
9661      {
9662	if (i + 1 >= argc)
9663	  fatal ("-split has no argument.");
9664	fatal ("option `-split' has not been implemented yet\n");
9665	/* split_argument = atoi (argument_vect [i + 1]); */
9666      }
9667  VLA_PTR_CREATE (decls, 150, "decls");
9668  /* Initialize IR storage.  */
9669  obstack_init (&irp);
9670  initiate_automaton_decl_table ();
9671  initiate_insn_decl_table ();
9672  initiate_decl_table ();
9673  output_file = stdout;
9674  output_description_file = NULL;
9675  base_name = base_file_name (argv[1]);
9676  obstack_grow (&irp, base_name,
9677		strlen (base_name) - strlen (file_name_suffix (base_name)));
9678  obstack_grow (&irp, STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX,
9679		strlen (STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX) + 1);
9680  obstack_1grow (&irp, '\0');
9681  output_description_file_name = obstack_base (&irp);
9682  obstack_finish (&irp);
9683}
9684
9685/* The following function checks existence at least one arc marked by
9686   each insn.  */
9687static void
9688check_automata_insn_issues (void)
9689{
9690  automaton_t automaton;
9691  ainsn_t ainsn, reserv_ainsn;
9692
9693  for (automaton = description->first_automaton;
9694       automaton != NULL;
9695       automaton = automaton->next_automaton)
9696    {
9697      for (ainsn = automaton->ainsn_list;
9698	   ainsn != NULL;
9699	   ainsn = ainsn->next_ainsn)
9700	if (ainsn->first_insn_with_same_reservs && !ainsn->arc_exists_p)
9701	  {
9702	    for (reserv_ainsn = ainsn;
9703		 reserv_ainsn != NULL;
9704		 reserv_ainsn = reserv_ainsn->next_same_reservs_insn)
9705	      if (automaton->corresponding_automaton_decl != NULL)
9706		{
9707		  if (!w_flag)
9708		    error ("Automaton `%s': Insn `%s' will never be issued",
9709			   automaton->corresponding_automaton_decl->name,
9710			   reserv_ainsn->insn_reserv_decl->name);
9711		  else
9712		    warning
9713		      ("Automaton `%s': Insn `%s' will never be issued",
9714		       automaton->corresponding_automaton_decl->name,
9715		       reserv_ainsn->insn_reserv_decl->name);
9716		}
9717	      else
9718		{
9719		  if (!w_flag)
9720		    error ("Insn `%s' will never be issued",
9721			   reserv_ainsn->insn_reserv_decl->name);
9722		  else
9723		    warning ("Insn `%s' will never be issued",
9724			     reserv_ainsn->insn_reserv_decl->name);
9725		}
9726	  }
9727    }
9728}
9729
9730/* The following vla is used for storing pointers to all achieved
9731   states.  */
9732static vla_ptr_t automaton_states;
9733
9734/* This function is called by function pass_states to add an achieved
9735   STATE.  */
9736static void
9737add_automaton_state (state_t state)
9738{
9739  VLA_PTR_ADD (automaton_states, state);
9740}
9741
9742/* The following function forms list of important automata (whose
9743   states may be changed after the insn issue) for each insn.  */
9744static void
9745form_important_insn_automata_lists (void)
9746{
9747  automaton_t automaton;
9748  state_t *state_ptr;
9749  decl_t decl;
9750  ainsn_t ainsn;
9751  arc_t arc;
9752  int i;
9753
9754  VLA_PTR_CREATE (automaton_states, 1500,
9755		  "automaton states for forming important insn automata sets");
9756  /* Mark important ainsns.  */
9757  for (automaton = description->first_automaton;
9758       automaton != NULL;
9759       automaton = automaton->next_automaton)
9760    {
9761      VLA_PTR_NULLIFY (automaton_states);
9762      pass_states (automaton, add_automaton_state);
9763      for (state_ptr = VLA_PTR_BEGIN (automaton_states);
9764	   state_ptr <= (state_t *) VLA_PTR_LAST (automaton_states);
9765	   state_ptr++)
9766	{
9767	  for (arc = first_out_arc (*state_ptr);
9768	       arc != NULL;
9769	       arc = next_out_arc (arc))
9770	    if (arc->to_state != *state_ptr)
9771	      {
9772		if (!arc->insn->first_insn_with_same_reservs)
9773		  abort ();
9774		for (ainsn = arc->insn;
9775		     ainsn != NULL;
9776		     ainsn = ainsn->next_same_reservs_insn)
9777		  ainsn->important_p = TRUE;
9778	      }
9779	}
9780    }
9781  VLA_PTR_DELETE (automaton_states);
9782  /* Create automata sets for the insns.  */
9783  for (i = 0; i < description->decls_num; i++)
9784    {
9785      decl = description->decls [i];
9786      if (decl->mode == dm_insn_reserv)
9787	{
9788	  automata_list_start ();
9789	  for (automaton = description->first_automaton;
9790	       automaton != NULL;
9791	       automaton = automaton->next_automaton)
9792	    for (ainsn = automaton->ainsn_list;
9793		 ainsn != NULL;
9794		 ainsn = ainsn->next_ainsn)
9795	      if (ainsn->important_p
9796		  && ainsn->insn_reserv_decl == DECL_INSN_RESERV (decl))
9797		{
9798		  automata_list_add (automaton);
9799		  break;
9800		}
9801	  DECL_INSN_RESERV (decl)->important_automata_list
9802	    = automata_list_finish ();
9803	}
9804    }
9805}
9806
9807
9808/* The following is top level function to generate automat(a,on) for
9809   fast recognition of pipeline hazards.  */
9810void
9811expand_automata (void)
9812{
9813  int i;
9814
9815  description = create_node (sizeof (struct description)
9816			     /* One entry for cycle advancing insn.  */
9817			     + sizeof (decl_t) * VLA_PTR_LENGTH (decls));
9818  description->decls_num = VLA_PTR_LENGTH (decls);
9819  description->query_units_num = 0;
9820  for (i = 0; i < description->decls_num; i++)
9821    {
9822      description->decls [i] = VLA_PTR (decls, i);
9823      if (description->decls [i]->mode == dm_unit
9824	  && DECL_UNIT (description->decls [i])->query_p)
9825        DECL_UNIT (description->decls [i])->query_num
9826	  = description->query_units_num++;
9827    }
9828  all_time = create_ticker ();
9829  check_time = create_ticker ();
9830  if (progress_flag)
9831    fprintf (stderr, "Check description...");
9832  check_all_description ();
9833  if (progress_flag)
9834    fprintf (stderr, "done\n");
9835  ticker_off (&check_time);
9836  generation_time = create_ticker ();
9837  if (!have_error)
9838    {
9839      transform_insn_regexps ();
9840      check_unit_distributions_to_automata ();
9841    }
9842  if (!have_error)
9843    {
9844      generate ();
9845      check_automata_insn_issues ();
9846    }
9847  if (!have_error)
9848    {
9849      form_important_insn_automata_lists ();
9850      if (progress_flag)
9851	fprintf (stderr, "Generation of attributes...");
9852      make_internal_dfa_insn_code_attr ();
9853      make_insn_alts_attr ();
9854      make_default_insn_latency_attr ();
9855      make_bypass_attr ();
9856      if (progress_flag)
9857	fprintf (stderr, "done\n");
9858    }
9859  ticker_off (&generation_time);
9860  ticker_off (&all_time);
9861  if (progress_flag)
9862    fprintf (stderr, "All other genattrtab stuff...");
9863}
9864
9865/* The following is top level function to output PHR and to finish
9866   work with pipeline description translator.  */
9867void
9868write_automata (void)
9869{
9870  if (progress_flag)
9871    fprintf (stderr, "done\n");
9872  if (have_error)
9873    fatal ("Errors in DFA description");
9874  ticker_on (&all_time);
9875  output_time = create_ticker ();
9876  if (progress_flag)
9877    fprintf (stderr, "Forming and outputting automata tables...");
9878  output_dfa_max_issue_rate ();
9879  output_tables ();
9880  if (progress_flag)
9881    {
9882      fprintf (stderr, "done\n");
9883      fprintf (stderr, "Output functions to work with automata...");
9884    }
9885  output_chip_definitions ();
9886  output_max_insn_queue_index_def ();
9887  output_internal_min_issue_delay_func ();
9888  output_internal_trans_func ();
9889  /* Cache of insn dfa codes: */
9890  fprintf (output_file, "\nstatic int *%s;\n", DFA_INSN_CODES_VARIABLE_NAME);
9891  fprintf (output_file, "\nstatic int %s;\n\n",
9892	   DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
9893  output_dfa_insn_code_func ();
9894  output_trans_func ();
9895  fprintf (output_file, "\n#if %s\n\n", AUTOMATON_STATE_ALTS_MACRO_NAME);
9896  output_internal_state_alts_func ();
9897  output_state_alts_func ();
9898  fprintf (output_file, "\n#endif /* #if %s */\n\n",
9899	   AUTOMATON_STATE_ALTS_MACRO_NAME);
9900  output_min_issue_delay_func ();
9901  output_internal_dead_lock_func ();
9902  output_dead_lock_func ();
9903  output_size_func ();
9904  output_internal_reset_func ();
9905  output_reset_func ();
9906  output_min_insn_conflict_delay_func ();
9907  output_internal_insn_latency_func ();
9908  output_insn_latency_func ();
9909  output_print_reservation_func ();
9910  /* Output function get_cpu_unit_code.  */
9911  fprintf (output_file, "\n#if %s\n\n", CPU_UNITS_QUERY_MACRO_NAME);
9912  output_get_cpu_unit_code_func ();
9913  output_cpu_unit_reservation_p ();
9914  fprintf (output_file, "\n#endif /* #if %s */\n\n",
9915	   CPU_UNITS_QUERY_MACRO_NAME);
9916  output_dfa_clean_insn_cache_func ();
9917  output_dfa_start_func ();
9918  output_dfa_finish_func ();
9919  if (progress_flag)
9920    fprintf (stderr, "done\n");
9921  if (v_flag)
9922    {
9923      output_description_file = fopen (output_description_file_name, "w");
9924      if (output_description_file == NULL)
9925	{
9926	  perror (output_description_file_name);
9927	  exit (FATAL_EXIT_CODE);
9928	}
9929      if (progress_flag)
9930	fprintf (stderr, "Output automata description...");
9931      output_description ();
9932      output_automaton_descriptions ();
9933      if (progress_flag)
9934	fprintf (stderr, "done\n");
9935      output_statistics (output_description_file);
9936    }
9937  output_statistics (stderr);
9938  ticker_off (&output_time);
9939  output_time_statistics (stderr);
9940  finish_states ();
9941  finish_arcs ();
9942  finish_automata_lists ();
9943  if (time_flag)
9944    {
9945      fprintf (stderr, "Summary:\n");
9946      fprintf (stderr, "  check time ");
9947      print_active_time (stderr, check_time);
9948      fprintf (stderr, ", generation time ");
9949      print_active_time (stderr, generation_time);
9950      fprintf (stderr, ", all time ");
9951      print_active_time (stderr, all_time);
9952      fprintf (stderr, "\n");
9953    }
9954  /* Finish all work.  */
9955  if (output_description_file != NULL)
9956    {
9957      fflush (output_description_file);
9958      if (ferror (stdout) != 0)
9959	fatal ("Error in writing DFA description file %s",
9960               output_description_file_name);
9961      fclose (output_description_file);
9962    }
9963  finish_automaton_decl_table ();
9964  finish_insn_decl_table ();
9965  finish_decl_table ();
9966  obstack_free (&irp, NULL);
9967  if (have_error && output_description_file != NULL)
9968    remove (output_description_file_name);
9969}
9970