OSDN Git Service

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