OSDN Git Service

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