OSDN Git Service

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