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