OSDN Git Service

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