OSDN Git Service

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