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