OSDN Git Service

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