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