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