OSDN Git Service

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