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