OSDN Git Service

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