OSDN Git Service

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