OSDN Git Service

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