OSDN Git Service

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