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