OSDN Git Service

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