OSDN Git Service

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