OSDN Git Service

* fixinc/inclhack.def (thread_keyword): Match __thread as last arg.
[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   set_el_t hash_value;
3395   unsigned result;
3396   int reservs_num, i;
3397   set_el_t *reserv_ptr;
3398
3399   hash_value = 0;
3400   reservs_num = els_in_reservs;
3401   reserv_ptr = reservs;
3402   i = 0;
3403   while (reservs_num != 0)
3404     {
3405       reservs_num--;
3406       hash_value += ((*reserv_ptr >> i)
3407                      | (*reserv_ptr << (sizeof (set_el_t) * CHAR_BIT - i)));
3408       i++;
3409       if (i == sizeof (set_el_t) * CHAR_BIT)
3410         i = 0;
3411       reserv_ptr++;
3412     }
3413   if (sizeof (set_el_t) <= sizeof (unsigned))
3414     return hash_value;
3415   result = 0;
3416   for (i = sizeof (set_el_t); i > 0; i -= sizeof (unsigned))
3417     {
3418       result += (unsigned) hash_value;
3419       hash_value >>= sizeof (unsigned) * CHAR_BIT;
3420     }
3421   return result;
3422 }
3423
3424 /* Comparison of given reservation sets.  */
3425 static int
3426 reserv_sets_cmp (reservs_1, reservs_2)
3427      reserv_sets_t reservs_1;
3428      reserv_sets_t reservs_2;
3429 {
3430   int reservs_num;
3431   set_el_t *reserv_ptr_1;
3432   set_el_t *reserv_ptr_2;
3433
3434   if (reservs_1 == NULL || reservs_2 == NULL)
3435     abort ();
3436   reservs_num = els_in_reservs;
3437   reserv_ptr_1 = reservs_1;
3438   reserv_ptr_2 = reservs_2;
3439   while (reservs_num != 0 && *reserv_ptr_1 == *reserv_ptr_2)
3440     {
3441       reservs_num--;
3442       reserv_ptr_1++;
3443       reserv_ptr_2++;
3444     }
3445   if (reservs_num == 0)
3446     return 0;
3447   else if (*reserv_ptr_1 < *reserv_ptr_2)
3448     return -1;
3449   else
3450     return 1;
3451 }
3452
3453 /* The function checks equality of the reservation sets.  */
3454 static int
3455 reserv_sets_eq (reservs_1, reservs_2)
3456      reserv_sets_t reservs_1;
3457      reserv_sets_t reservs_2;
3458 {
3459   return reserv_sets_cmp (reservs_1, reservs_2) == 0;
3460 }
3461
3462 /* Set up in the reservation set that unit with UNIT_NUM is used on
3463    CYCLE_NUM.  */
3464 static void
3465 set_unit_reserv (reservs, cycle_num, unit_num)
3466      reserv_sets_t reservs;
3467      int cycle_num;
3468      int unit_num;
3469 {
3470   if (cycle_num >= max_cycles_num)
3471     abort ();
3472   SET_BIT (reservs, cycle_num * els_in_cycle_reserv
3473            * sizeof (set_el_t) * CHAR_BIT + unit_num);
3474 }
3475
3476 /* Set up in the reservation set RESERVS that unit with UNIT_NUM is
3477    used on CYCLE_NUM.  */
3478 static int
3479 test_unit_reserv (reservs, cycle_num, unit_num)
3480      reserv_sets_t reservs;
3481      int cycle_num;
3482      int unit_num;
3483 {
3484   if (cycle_num >= max_cycles_num)
3485     abort ();
3486   return TEST_BIT (reservs, cycle_num * els_in_cycle_reserv
3487                    * sizeof (set_el_t) * CHAR_BIT + unit_num);
3488 }
3489
3490 /* The function checks that the reservation set represents no one unit
3491    reservation.  */
3492 static int
3493 it_is_empty_reserv_sets (operand)
3494      reserv_sets_t operand;
3495 {
3496   set_el_t *reserv_ptr;
3497   int reservs_num;
3498
3499   if (operand == NULL)
3500     abort ();
3501   for (reservs_num = els_in_reservs, reserv_ptr = operand;
3502        reservs_num != 0;
3503        reserv_ptr++, reservs_num--)
3504     if (*reserv_ptr != 0)
3505       return 0;
3506   return 1;
3507 }
3508
3509 /* The function checks that the reservation sets are intersected,
3510    i.e. there is a unit reservation on a cycle in both reservation
3511    sets.  */
3512 static int
3513 reserv_sets_are_intersected (operand_1, operand_2)
3514      reserv_sets_t operand_1;
3515      reserv_sets_t operand_2;
3516 {
3517   set_el_t *el_ptr_1;
3518   set_el_t *el_ptr_2;
3519   set_el_t *cycle_ptr_1;
3520   set_el_t *cycle_ptr_2;
3521   int nonzero_p;
3522
3523   if (operand_1 == NULL || operand_2 == NULL)
3524     abort ();
3525   for (el_ptr_1 = operand_1, el_ptr_2 = operand_2;
3526        el_ptr_1 < operand_1 + els_in_reservs;
3527        el_ptr_1++, el_ptr_2++)
3528     if (*el_ptr_1 & *el_ptr_2)
3529       return 1;
3530   for (cycle_ptr_1 = operand_1, cycle_ptr_2 = operand_2;
3531        cycle_ptr_1 < operand_1 + els_in_reservs;
3532        cycle_ptr_1 += els_in_cycle_reserv, cycle_ptr_2 += els_in_cycle_reserv)
3533     {
3534       for (el_ptr_1 = cycle_ptr_1, el_ptr_2 = get_excl_set (cycle_ptr_2);
3535            el_ptr_1 < cycle_ptr_1 + els_in_cycle_reserv;
3536            el_ptr_1++, el_ptr_2++)
3537         if (*el_ptr_1 & *el_ptr_2)
3538           return 1;
3539       nonzero_p = 0;
3540       for (el_ptr_1 = cycle_ptr_1,
3541              el_ptr_2 = get_presence_absence_set (cycle_ptr_2, 1);
3542            el_ptr_1 < cycle_ptr_1 + els_in_cycle_reserv;
3543            el_ptr_1++, el_ptr_2++)
3544         if (*el_ptr_1 & *el_ptr_2)
3545           break;
3546         else if (*el_ptr_2 != 0)
3547           nonzero_p = 1;
3548       if (nonzero_p && el_ptr_1 >= cycle_ptr_1 + els_in_cycle_reserv)
3549         return 1;
3550       for (el_ptr_1 = cycle_ptr_1,
3551              el_ptr_2 = get_presence_absence_set (cycle_ptr_2, 0);
3552            el_ptr_1 < cycle_ptr_1 + els_in_cycle_reserv;
3553            el_ptr_1++, el_ptr_2++)
3554         /* It looks like code for exclusion but exclusion set is
3555            made as symmetric relation preliminary.  */
3556         if (*el_ptr_1 & *el_ptr_2)
3557           return 1;
3558     }
3559   return 0;
3560 }
3561
3562 /* The function sets up RESULT bits by bits of OPERAND shifted on one
3563    cpu cycle.  The remaining bits of OPERAND (representing the last
3564    cycle unit reservations) are not chenged.  */
3565 static void
3566 reserv_sets_shift (result, operand)
3567      reserv_sets_t result;
3568      reserv_sets_t operand;
3569 {
3570   int i;
3571
3572   if (result == NULL || operand == NULL || result == operand)
3573     abort ();
3574   for (i = els_in_cycle_reserv; i < els_in_reservs; i++)
3575     result [i - els_in_cycle_reserv] = operand [i];
3576 }
3577
3578 /* OR of the reservation sets.  */
3579 static void
3580 reserv_sets_or (result, operand_1, operand_2)
3581      reserv_sets_t result;
3582      reserv_sets_t operand_1;
3583      reserv_sets_t operand_2;
3584 {
3585   set_el_t *el_ptr_1;
3586   set_el_t *el_ptr_2;
3587   set_el_t *result_set_el_ptr;
3588
3589   if (result == NULL || operand_1 == NULL || operand_2 == NULL)
3590     abort ();
3591   for (el_ptr_1 = operand_1, el_ptr_2 = operand_2, result_set_el_ptr = result;
3592        el_ptr_1 < operand_1 + els_in_reservs;
3593        el_ptr_1++, el_ptr_2++, result_set_el_ptr++)
3594     *result_set_el_ptr = *el_ptr_1 | *el_ptr_2;
3595 }
3596
3597 /* AND of the reservation sets.  */
3598 static void
3599 reserv_sets_and (result, operand_1, operand_2)
3600      reserv_sets_t result;
3601      reserv_sets_t operand_1;
3602      reserv_sets_t operand_2;
3603 {
3604   set_el_t *el_ptr_1;
3605   set_el_t *el_ptr_2;
3606   set_el_t *result_set_el_ptr;
3607
3608   if (result == NULL || operand_1 == NULL || operand_2 == NULL)
3609     abort ();
3610   for (el_ptr_1 = operand_1, el_ptr_2 = operand_2, result_set_el_ptr = result;
3611        el_ptr_1 < operand_1 + els_in_reservs;
3612        el_ptr_1++, el_ptr_2++, result_set_el_ptr++)
3613     *result_set_el_ptr = *el_ptr_1 & *el_ptr_2;
3614 }
3615
3616 /* The function outputs string representation of units reservation on
3617    cycle START_CYCLE in the reservation set.  The function uses repeat
3618    construction if REPETITION_NUM > 1.  */
3619 static void
3620 output_cycle_reservs (f, reservs, start_cycle, repetition_num)
3621      FILE *f;
3622      reserv_sets_t reservs;
3623      int start_cycle;
3624      int repetition_num;
3625 {
3626   int unit_num;
3627   int reserved_units_num;
3628
3629   reserved_units_num = 0;
3630   for (unit_num = 0; unit_num < description->units_num; unit_num++)
3631     if (TEST_BIT (reservs, start_cycle * els_in_cycle_reserv
3632                   * sizeof (set_el_t) * CHAR_BIT + unit_num))
3633       reserved_units_num++;
3634   if (repetition_num <= 0)
3635     abort ();
3636   if (repetition_num != 1 && reserved_units_num > 1)
3637     fprintf (f, "(");
3638   reserved_units_num = 0;
3639   for (unit_num = 0;
3640        unit_num < description->units_num;
3641        unit_num++)
3642     if (TEST_BIT (reservs, start_cycle * els_in_cycle_reserv
3643                   * sizeof (set_el_t) * CHAR_BIT + unit_num))
3644       {
3645         if (reserved_units_num != 0)
3646           fprintf (f, "+");
3647         reserved_units_num++;
3648         fprintf (f, "%s", units_array [unit_num]->name);
3649       }
3650   if (reserved_units_num == 0)
3651     fprintf (f, NOTHING_NAME);
3652   if (repetition_num <= 0)
3653     abort ();
3654   if (reserved_units_num > 1)
3655     fprintf (f, ")");
3656   if (repetition_num != 1)
3657     fprintf (f, "*%d", repetition_num);
3658 }
3659
3660 /* The function outputs string representation of units reservation in
3661    the reservation set.  */
3662 static void
3663 output_reserv_sets (f, reservs)
3664      FILE *f;
3665      reserv_sets_t reservs;
3666 {
3667   int start_cycle = 0;
3668   int cycle;
3669   int repetition_num;
3670
3671   repetition_num = 0;
3672   for (cycle = 0; cycle < max_cycles_num; cycle++)
3673     if (repetition_num == 0)
3674       {
3675         repetition_num++;
3676         start_cycle = cycle;
3677       }
3678     else if (memcmp
3679              ((char *) reservs + start_cycle * els_in_cycle_reserv
3680               * sizeof (set_el_t),
3681               (char *) reservs + cycle * els_in_cycle_reserv
3682               * sizeof (set_el_t),
3683               els_in_cycle_reserv * sizeof (set_el_t)) == 0)
3684       repetition_num++;
3685     else
3686       {
3687         if (start_cycle != 0)
3688           fprintf (f, ", ");
3689         output_cycle_reservs (f, reservs, start_cycle, repetition_num);
3690         repetition_num = 1;
3691         start_cycle = cycle;
3692       }
3693   if (start_cycle < max_cycles_num)
3694     {
3695       if (start_cycle != 0)
3696         fprintf (f, ", ");
3697       output_cycle_reservs (f, reservs, start_cycle, repetition_num);
3698     }
3699 }
3700
3701 /* The following function returns free node state for AUTOMATON.  It
3702    may be new allocated node or node freed eralier.  The function also
3703    allocates reservation set if WITH_RESERVS has nonzero value.  */
3704 static state_t
3705 get_free_state (with_reservs, automaton)
3706      int with_reservs;
3707      automaton_t automaton;
3708 {
3709   state_t result;
3710
3711   if (max_cycles_num <= 0 || automaton == NULL)
3712     abort ();
3713   if (VLA_PTR_LENGTH (free_states) != 0)
3714     {
3715       result = VLA_PTR (free_states, VLA_PTR_LENGTH (free_states) - 1);
3716       VLA_PTR_SHORTEN (free_states, 1);
3717       result->automaton = automaton;
3718       result->first_out_arc = NULL;
3719       result->it_was_placed_in_stack_for_NDFA_forming = 0;
3720       result->it_was_placed_in_stack_for_DFA_forming = 0;
3721       result->component_states = NULL;
3722       result->longest_path_length = UNDEFINED_LONGEST_PATH_LENGTH;
3723     }
3724   else
3725     {
3726 #ifndef NDEBUG
3727       allocated_states_num++;
3728 #endif
3729       result = create_node (sizeof (struct state));
3730       result->automaton = automaton;
3731       result->first_out_arc = NULL;
3732       result->unique_num = curr_unique_state_num;
3733       result->longest_path_length = UNDEFINED_LONGEST_PATH_LENGTH;
3734       curr_unique_state_num++;
3735     }
3736   if (with_reservs)
3737     {
3738       if (result->reservs == NULL)
3739         result->reservs = alloc_empty_reserv_sets ();
3740       else
3741         memset (result->reservs, 0, els_in_reservs * sizeof (set_el_t));
3742     }
3743   return result;
3744 }
3745
3746 /* The function frees node STATE.  */
3747 static void
3748 free_state (state)
3749      state_t state;
3750 {
3751   free_alt_states (state->component_states);
3752   VLA_PTR_ADD (free_states, state);
3753 }
3754
3755 /* Hash value of STATE.  If STATE represents deterministic state it is
3756    simply hash value of the corresponding reservation set.  Otherwise
3757    it is formed from hash values of the component deterministic
3758    states.  One more key is order number of state automaton.  */
3759 static unsigned
3760 state_hash (state)
3761      const void *state;
3762 {
3763   unsigned int hash_value;
3764   alt_state_t alt_state;
3765
3766   if (((state_t) state)->component_states == NULL)
3767     hash_value = reserv_sets_hash_value (((state_t) state)->reservs);
3768   else
3769     {
3770       hash_value = 0;
3771       for (alt_state = ((state_t) state)->component_states;
3772            alt_state != NULL;
3773            alt_state = alt_state->next_sorted_alt_state)
3774         hash_value = (((hash_value >> (sizeof (unsigned) - 1) * CHAR_BIT)
3775                        | (hash_value << CHAR_BIT))
3776                       + alt_state->state->unique_num);
3777     }
3778   hash_value = (((hash_value >> (sizeof (unsigned) - 1) * CHAR_BIT)
3779                  | (hash_value << CHAR_BIT))
3780                 + ((state_t) state)->automaton->automaton_order_num);
3781   return hash_value;
3782 }
3783
3784 /* Return nonzero value if the states are the same.  */
3785 static int
3786 state_eq_p (state_1, state_2)
3787      const void *state_1;
3788      const void *state_2;
3789 {
3790   alt_state_t alt_state_1;
3791   alt_state_t alt_state_2;
3792
3793   if (((state_t) state_1)->automaton != ((state_t) state_2)->automaton)
3794     return 0;
3795   else if (((state_t) state_1)->component_states == NULL
3796            && ((state_t) state_2)->component_states == NULL)
3797     return reserv_sets_eq (((state_t) state_1)->reservs,
3798                            ((state_t) state_2)->reservs);
3799   else if (((state_t) state_1)->component_states != NULL
3800            && ((state_t) state_2)->component_states != NULL)
3801     {
3802       for (alt_state_1 = ((state_t) state_1)->component_states,
3803            alt_state_2 = ((state_t) state_2)->component_states;
3804            alt_state_1 != NULL && alt_state_2 != NULL;
3805            alt_state_1 = alt_state_1->next_sorted_alt_state,
3806            alt_state_2 = alt_state_2->next_sorted_alt_state)
3807         /* All state in the list must be already in the hash table.
3808            Also the lists must be sorted.  */
3809         if (alt_state_1->state != alt_state_2->state)
3810           return 0;
3811       return alt_state_1 == alt_state_2;
3812     }
3813   else
3814     return 0;
3815 }
3816
3817 /* Insert STATE into the state table.  */
3818 static state_t
3819 insert_state (state)
3820      state_t state;
3821 {
3822   void **entry_ptr;
3823
3824   entry_ptr = htab_find_slot (state_table, (void *) state, 1);
3825   if (*entry_ptr == NULL)
3826     *entry_ptr = (void *) state;
3827   return (state_t) *entry_ptr;
3828 }
3829
3830 /* Add reservation of unit with UNIT_NUM on cycle CYCLE_NUM to
3831    deterministic STATE.  */
3832 static void
3833 set_state_reserv (state, cycle_num, unit_num)
3834      state_t state;
3835      int cycle_num;
3836      int unit_num;
3837 {
3838   set_unit_reserv (state->reservs, cycle_num, unit_num);
3839 }
3840
3841 /* Return nonzero value if the deterministic states contains a
3842    reservation of the same cpu unit on the same cpu cycle.  */
3843 static int
3844 intersected_state_reservs_p (state1, state2)
3845      state_t state1;
3846      state_t state2;
3847 {
3848   if (state1->automaton != state2->automaton)
3849     abort ();
3850   return reserv_sets_are_intersected (state1->reservs, state2->reservs);
3851 }
3852
3853 /* Return deterministic state (inserted into the table) which
3854    representing the automaton state whic is union of reservations of
3855    deterministic states.  */
3856 static state_t
3857 states_union (state1, state2)
3858      state_t state1;
3859      state_t state2;
3860 {
3861   state_t result;
3862   state_t state_in_table;
3863
3864   if (state1->automaton != state2->automaton)
3865     abort ();
3866   result = get_free_state (1, state1->automaton);
3867   reserv_sets_or (result->reservs, state1->reservs, state2->reservs);
3868   state_in_table = insert_state (result);
3869   if (result != state_in_table)
3870     {
3871       free_state (result);
3872       result = state_in_table;
3873     }
3874   return result;
3875 }
3876
3877 /* Return deterministic state (inserted into the table) which
3878    represent the automaton state is obtained from deterministic STATE
3879    by advancing cpu cycle.  */
3880 static state_t
3881 state_shift (state)
3882      state_t state;
3883 {
3884   state_t result;
3885   state_t state_in_table;
3886
3887   result = get_free_state (1, state->automaton);
3888   reserv_sets_shift (result->reservs, state->reservs);
3889   state_in_table = insert_state (result);
3890   if (result != state_in_table)
3891     {
3892       free_state (result);
3893       result = state_in_table;
3894     }
3895   return result;
3896 }
3897
3898 /* Initialization of the abstract data.  */
3899 static void
3900 initiate_states ()
3901 {
3902   decl_t decl;
3903   int i;
3904
3905   VLA_PTR_CREATE (units_container, description->units_num, "units_container");
3906   units_array
3907     = (description->decls_num && description->units_num
3908        ? VLA_PTR_BEGIN (units_container) : NULL);
3909   for (i = 0; i < description->decls_num; i++)
3910     {
3911       decl = description->decls [i];
3912       if (decl->mode == dm_unit)
3913         units_array [decl->decl.unit.unit_num] = &decl->decl.unit;
3914     }
3915   max_cycles_num = description->max_insn_reserv_cycles;
3916   els_in_cycle_reserv
3917     = ((description->units_num + sizeof (set_el_t) * CHAR_BIT - 1)
3918        / (sizeof (set_el_t) * CHAR_BIT));
3919   els_in_reservs = els_in_cycle_reserv * max_cycles_num;
3920   curr_unique_state_num = 0;
3921   initiate_alt_states ();
3922   VLA_PTR_CREATE (free_states, 1500, "free states");
3923   state_table = htab_create (1500, state_hash, state_eq_p, (htab_del) 0);
3924   empty_reserv = alloc_empty_reserv_sets ();
3925 }
3926
3927 /* Finisging work with the abstract data.  */
3928 static void
3929 finish_states ()
3930 {
3931   VLA_PTR_DELETE (units_container);
3932   htab_delete (state_table);
3933   VLA_PTR_DELETE (free_states);
3934   finish_alt_states ();
3935 }
3936
3937 \f
3938
3939 /* Abstract data `arcs'.  */
3940
3941 /* List of free arcs.  */
3942 static arc_t first_free_arc;
3943
3944 #ifndef NDEBUG
3945 /* The following variables is maximal number of allocated nodes
3946    `arc'.  */
3947 static int allocated_arcs_num = 0;
3948 #endif
3949
3950 /* The function frees node ARC.  */
3951 static void
3952 free_arc (arc)
3953      arc_t arc;
3954 {
3955   arc->next_out_arc = first_free_arc;
3956   first_free_arc = arc;
3957 }
3958
3959 /* The function removes and frees ARC staring from FROM_STATE.  */
3960 static void
3961 remove_arc (from_state, arc)
3962      state_t from_state;
3963      arc_t arc;
3964 {
3965   arc_t prev_arc;
3966   arc_t curr_arc;
3967
3968   if (arc == NULL)
3969     abort ();
3970   for (prev_arc = NULL, curr_arc = from_state->first_out_arc;
3971        curr_arc != NULL;
3972        prev_arc = curr_arc, curr_arc = curr_arc->next_out_arc)
3973     if (curr_arc == arc)
3974       break;
3975   if (curr_arc == NULL)
3976     abort ();
3977   if (prev_arc == NULL)
3978     from_state->first_out_arc = arc->next_out_arc;
3979   else
3980     prev_arc->next_out_arc = arc->next_out_arc;
3981   free_arc (arc);
3982 }
3983
3984 /* The functions returns arc with given characteristics (or NULL if
3985    the arc does not exist).  */
3986 static arc_t
3987 find_arc (from_state, to_state, insn)
3988      state_t from_state;
3989      state_t to_state;
3990      ainsn_t insn;
3991 {
3992   arc_t arc;
3993
3994   for (arc = first_out_arc (from_state); arc != NULL; arc = next_out_arc (arc))
3995     if (arc->to_state == to_state && arc->insn == insn)
3996       return arc;
3997   return NULL;
3998 }
3999
4000 /* The function adds arc from FROM_STATE to TO_STATE marked by AINSN
4001    and with given STATE_ALTS.  The function returns added arc (or
4002    already existing arc).  */
4003 static arc_t
4004 add_arc (from_state, to_state, ainsn, state_alts)
4005      state_t from_state;
4006      state_t to_state;
4007      ainsn_t ainsn;
4008      int state_alts;
4009 {
4010   arc_t new_arc;
4011
4012   new_arc = find_arc (from_state, to_state, ainsn);
4013   if (new_arc != NULL)
4014     return new_arc;
4015   if (first_free_arc == NULL)
4016     {
4017 #ifndef NDEBUG
4018       allocated_arcs_num++;
4019 #endif
4020       new_arc = create_node (sizeof (struct arc));
4021       new_arc->to_state = NULL;
4022       new_arc->insn = NULL;
4023       new_arc->next_out_arc = NULL;
4024     }
4025   else
4026     {
4027       new_arc = first_free_arc;
4028       first_free_arc =  first_free_arc->next_out_arc;
4029     }
4030   new_arc->to_state = to_state;
4031   new_arc->insn = ainsn;
4032   ainsn->arc_exists_p = 1;
4033   new_arc->next_out_arc = from_state->first_out_arc;
4034   from_state->first_out_arc = new_arc;
4035   new_arc->next_arc_marked_by_insn = NULL;
4036   new_arc->state_alts = state_alts;
4037   return new_arc;
4038 }
4039
4040 /* The function returns the first arc starting from STATE.  */
4041 static arc_t
4042 first_out_arc (state)
4043      state_t state;
4044 {
4045   return state->first_out_arc;
4046 }
4047
4048 /* The function returns next out arc after ARC.  */
4049 static arc_t
4050 next_out_arc (arc)
4051      arc_t arc;
4052 {
4053   return arc->next_out_arc;
4054 }
4055
4056 /* Initialization of the abstract data.  */
4057 static void
4058 initiate_arcs ()
4059 {
4060   first_free_arc = NULL;
4061 }
4062
4063 /* Finishing work with the abstract data.  */
4064 static void
4065 finish_arcs ()
4066 {
4067 }
4068
4069 \f
4070
4071 /* Abstract data `automata lists'.  */
4072
4073 /* List of free states.  */
4074 static automata_list_el_t first_free_automata_list_el;
4075
4076 /* The list being formed.  */
4077 static automata_list_el_t current_automata_list;
4078
4079 /* Hash table of automata lists.  */
4080 static htab_t automata_list_table;
4081
4082 /* The following function returns free automata list el.  It may be
4083    new allocated node or node freed earlier.  */
4084 static automata_list_el_t 
4085 get_free_automata_list_el ()
4086 {
4087   automata_list_el_t result;
4088
4089   if (first_free_automata_list_el != NULL)
4090     {
4091       result = first_free_automata_list_el;
4092       first_free_automata_list_el
4093         = first_free_automata_list_el->next_automata_list_el;
4094     }
4095   else
4096     result = create_node (sizeof (struct automata_list_el));
4097   result->automaton = NULL;
4098   result->next_automata_list_el = NULL;
4099   return result;
4100 }
4101
4102 /* The function frees node AUTOMATA_LIST_EL.  */
4103 static void
4104 free_automata_list_el (automata_list_el)
4105      automata_list_el_t automata_list_el;
4106 {
4107   if (automata_list_el == NULL)
4108     return;
4109   automata_list_el->next_automata_list_el = first_free_automata_list_el;
4110   first_free_automata_list_el = automata_list_el;
4111 }
4112
4113 /* The function frees list AUTOMATA_LIST.  */
4114 static void
4115 free_automata_list (automata_list)
4116      automata_list_el_t automata_list;
4117 {
4118   automata_list_el_t curr_automata_list_el;
4119   automata_list_el_t next_automata_list_el;
4120
4121   for (curr_automata_list_el = automata_list;
4122        curr_automata_list_el != NULL;
4123        curr_automata_list_el = next_automata_list_el)
4124     {
4125       next_automata_list_el = curr_automata_list_el->next_automata_list_el;
4126       free_automata_list_el (curr_automata_list_el);
4127     }
4128 }
4129
4130 /* Hash value of AUTOMATA_LIST.  */
4131 static unsigned
4132 automata_list_hash (automata_list)
4133      const void *automata_list;
4134 {
4135   unsigned int hash_value;
4136   automata_list_el_t curr_automata_list_el;
4137
4138   hash_value = 0;
4139   for (curr_automata_list_el = (automata_list_el_t) automata_list;
4140        curr_automata_list_el != NULL;
4141        curr_automata_list_el = curr_automata_list_el->next_automata_list_el)
4142     hash_value = (((hash_value >> (sizeof (unsigned) - 1) * CHAR_BIT)
4143                    | (hash_value << CHAR_BIT))
4144                   + curr_automata_list_el->automaton->automaton_order_num);
4145   return hash_value;
4146 }
4147
4148 /* Return nonzero value if the automata_lists are the same.  */
4149 static int
4150 automata_list_eq_p (automata_list_1, automata_list_2)
4151      const void *automata_list_1;
4152      const void *automata_list_2;
4153 {
4154   automata_list_el_t automata_list_el_1;
4155   automata_list_el_t automata_list_el_2;
4156
4157   for (automata_list_el_1 = (automata_list_el_t) automata_list_1,
4158          automata_list_el_2 = (automata_list_el_t) automata_list_2;
4159        automata_list_el_1 != NULL && automata_list_el_2 != NULL;
4160        automata_list_el_1 = automata_list_el_1->next_automata_list_el,
4161          automata_list_el_2 = automata_list_el_2->next_automata_list_el)
4162     if (automata_list_el_1->automaton != automata_list_el_2->automaton)
4163       return 0;
4164   return automata_list_el_1 == automata_list_el_2;
4165 }
4166
4167 /* Initialization of the abstract data.  */
4168 static void
4169 initiate_automata_lists ()
4170 {
4171   first_free_automata_list_el = NULL;
4172   automata_list_table = htab_create (1500, automata_list_hash,
4173                                      automata_list_eq_p, (htab_del) 0);
4174 }
4175
4176 /* The following function starts new automata list and makes it the
4177    current one.  */
4178 static void
4179 automata_list_start ()
4180 {
4181   current_automata_list = NULL;
4182 }
4183
4184 /* The following function adds AUTOMATON to the current list.  */
4185 static void
4186 automata_list_add (automaton)
4187      automaton_t automaton;
4188 {
4189   automata_list_el_t el;
4190
4191   el = get_free_automata_list_el ();
4192   el->automaton = automaton;
4193   el->next_automata_list_el = current_automata_list;
4194   current_automata_list = el;
4195 }
4196
4197 /* The following function finishes forming the current list, inserts
4198    it into the table and returns it.  */
4199 static automata_list_el_t
4200 automata_list_finish ()
4201 {
4202   void **entry_ptr;
4203
4204   if (current_automata_list == NULL)
4205     return NULL;
4206   entry_ptr = htab_find_slot (automata_list_table,
4207                               (void *) current_automata_list, 1);
4208   if (*entry_ptr == NULL)
4209     *entry_ptr = (void *) current_automata_list;
4210   else
4211     free_automata_list (current_automata_list);
4212   current_automata_list = NULL;
4213   return (automata_list_el_t) *entry_ptr;
4214 }
4215
4216 /* Finishing work with the abstract data.  */
4217 static void
4218 finish_automata_lists ()
4219 {
4220   htab_delete (automata_list_table);
4221 }
4222
4223 \f
4224
4225 /* The page contains abstract data for work with exclusion sets (see
4226    exclusion_set in file rtl.def).  */
4227
4228 /* The following variable refers to an exclusion set returned by
4229    get_excl_set.  This is bit string of length equal to cpu units
4230    number.  If exclusion set for given unit contains 1 for a unit,
4231    then simultaneous reservation of the units is prohibited.  */
4232 static reserv_sets_t excl_set;
4233
4234 /* The array contains exclusion sets for each unit.  */
4235 static reserv_sets_t *unit_excl_set_table;
4236
4237 /* The following function forms the array containing exclusion sets
4238    for each unit.  */
4239 static void
4240 initiate_excl_sets ()
4241 {
4242   decl_t decl;
4243   reserv_sets_t unit_excl_set;
4244   unit_set_el_t el;
4245   int i;
4246
4247   obstack_blank (&irp, els_in_cycle_reserv * sizeof (set_el_t));
4248   excl_set = (reserv_sets_t) obstack_base (&irp);
4249   obstack_finish (&irp);
4250   obstack_blank (&irp, description->units_num * sizeof (reserv_sets_t));
4251   unit_excl_set_table = (reserv_sets_t *) obstack_base (&irp);
4252   obstack_finish (&irp);
4253   /* Evaluate unit exclusion sets.  */
4254   for (i = 0; i < description->decls_num; i++)
4255     {
4256       decl = description->decls [i];
4257       if (decl->mode == dm_unit)
4258         {
4259           obstack_blank (&irp, els_in_cycle_reserv * sizeof (set_el_t));
4260           unit_excl_set = (reserv_sets_t) obstack_base (&irp);
4261           obstack_finish (&irp);
4262           memset (unit_excl_set, 0, els_in_cycle_reserv * sizeof (set_el_t));
4263           for (el = decl->decl.unit.excl_list;
4264                el != NULL;
4265                el = el->next_unit_set_el)
4266             SET_BIT (unit_excl_set, el->unit_decl->unit_num);
4267           unit_excl_set_table [decl->decl.unit.unit_num] = unit_excl_set;
4268         }
4269     }
4270 }
4271
4272 /* The function sets up and return EXCL_SET which is union of
4273    exclusion sets for each unit in IN_SET.  */
4274 static reserv_sets_t
4275 get_excl_set (in_set)
4276      reserv_sets_t in_set;
4277 {
4278   int excl_char_num;
4279   int chars_num;
4280   int i;
4281   int start_unit_num;
4282   int unit_num;
4283
4284   chars_num = els_in_cycle_reserv * sizeof (set_el_t);
4285   memset (excl_set, 0, chars_num);
4286   for (excl_char_num = 0; excl_char_num < chars_num; excl_char_num++)
4287     if (((unsigned char *) in_set) [excl_char_num])
4288       for (i = CHAR_BIT - 1; i >= 0; i--)
4289         if ((((unsigned char *) in_set) [excl_char_num] >> i) & 1)
4290           {
4291             start_unit_num = excl_char_num * CHAR_BIT + i;
4292             if (start_unit_num >= description->units_num)
4293               return excl_set;
4294             for (unit_num = 0; unit_num < els_in_cycle_reserv; unit_num++)
4295               {
4296                 excl_set [unit_num]
4297                   |= unit_excl_set_table [start_unit_num] [unit_num];
4298               }
4299           }
4300   return excl_set;
4301 }
4302
4303 \f
4304
4305 /* The page contains abstract data for work with presence/absence sets
4306    (see presence_set/absence_set in file rtl.def).  */
4307
4308 /* The following variables refer to correspondingly an presence and an
4309    absence set returned by get_presence_absence_set.  This is bit
4310    string of length equal to cpu units number.  */
4311 static reserv_sets_t presence_set, absence_set;
4312
4313 /* The following arrays contain correspondingly presence and absence
4314    sets for each unit.  */
4315 static reserv_sets_t *unit_presence_set_table, *unit_absence_set_table;
4316
4317 /* The following function forms the array containing presence and
4318    absence sets for each unit */
4319 static void
4320 initiate_presence_absence_sets ()
4321 {
4322   decl_t decl;
4323   reserv_sets_t unit_set;
4324   unit_set_el_t el;
4325   int i;
4326
4327   obstack_blank (&irp, els_in_cycle_reserv * sizeof (set_el_t));
4328   presence_set = (reserv_sets_t) obstack_base (&irp);
4329   obstack_finish (&irp);
4330   obstack_blank (&irp, description->units_num * sizeof (reserv_sets_t));
4331   unit_presence_set_table = (reserv_sets_t *) obstack_base (&irp);
4332   obstack_finish (&irp);
4333   obstack_blank (&irp, els_in_cycle_reserv * sizeof (set_el_t));
4334   absence_set = (reserv_sets_t) obstack_base (&irp);
4335   obstack_finish (&irp);
4336   obstack_blank (&irp, description->units_num * sizeof (reserv_sets_t));
4337   unit_absence_set_table = (reserv_sets_t *) obstack_base (&irp);
4338   obstack_finish (&irp);
4339   /* Evaluate unit presence/absence sets.  */
4340   for (i = 0; i < description->decls_num; i++)
4341     {
4342       decl = description->decls [i];
4343       if (decl->mode == dm_unit)
4344         {
4345           obstack_blank (&irp, els_in_cycle_reserv * sizeof (set_el_t));
4346           unit_set = (reserv_sets_t) obstack_base (&irp);
4347           obstack_finish (&irp);
4348           memset (unit_set, 0, els_in_cycle_reserv * sizeof (set_el_t));
4349           for (el = decl->decl.unit.presence_list;
4350                el != NULL;
4351                el = el->next_unit_set_el)
4352             SET_BIT (unit_set, el->unit_decl->unit_num);
4353           unit_presence_set_table [decl->decl.unit.unit_num] = unit_set;
4354
4355           obstack_blank (&irp, els_in_cycle_reserv * sizeof (set_el_t));
4356           unit_set = (reserv_sets_t) obstack_base (&irp);
4357           obstack_finish (&irp);
4358           memset (unit_set, 0, els_in_cycle_reserv * sizeof (set_el_t));
4359           for (el = decl->decl.unit.absence_list;
4360                el != NULL;
4361                el = el->next_unit_set_el)
4362             SET_BIT (unit_set, el->unit_decl->unit_num);
4363           unit_absence_set_table [decl->decl.unit.unit_num] = unit_set;
4364         }
4365     }
4366 }
4367
4368 /* The function sets up and return PRESENCE_SET (if PRESENCE_P) or
4369    ABSENCE_SET which is union of corresponding sets for each unit in
4370    IN_SET.  */
4371 static reserv_sets_t
4372 get_presence_absence_set (in_set, presence_p)
4373      reserv_sets_t in_set;
4374      int presence_p;
4375 {
4376   int char_num;
4377   int chars_num;
4378   int i;
4379   int start_unit_num;
4380   int unit_num;
4381
4382   chars_num = els_in_cycle_reserv * sizeof (set_el_t);
4383   if (presence_p)
4384     memset (presence_set, 0, chars_num);
4385   else
4386     memset (absence_set, 0, chars_num);
4387   for (char_num = 0; char_num < chars_num; char_num++)
4388     if (((unsigned char *) in_set) [char_num])
4389       for (i = CHAR_BIT - 1; i >= 0; i--)
4390         if ((((unsigned char *) in_set) [char_num] >> i) & 1)
4391           {
4392             start_unit_num = char_num * CHAR_BIT + i;
4393             if (start_unit_num >= description->units_num)
4394               return (presence_p ? presence_set : absence_set);
4395             for (unit_num = 0; unit_num < els_in_cycle_reserv; unit_num++)
4396               if (presence_p)
4397                 presence_set [unit_num]
4398                   |= unit_presence_set_table [start_unit_num] [unit_num];
4399               else
4400                 absence_set [unit_num]
4401                   |= unit_absence_set_table [start_unit_num] [unit_num];
4402           }
4403   return (presence_p ? presence_set : absence_set);
4404 }
4405
4406 \f
4407
4408 /* This page contains code for transformation of original reservations
4409    described in .md file.  The main goal of transformations is
4410    simplifying reservation and lifting up all `|' on the top of IR
4411    reservation representation.  */
4412
4413
4414 /* The following function makes copy of IR representation of
4415    reservation.  The function also substitutes all reservations
4416    defined by define_reservation by corresponding value during making
4417    the copy.  */
4418 static regexp_t
4419 copy_insn_regexp (regexp)
4420      regexp_t regexp;
4421 {
4422   regexp_t  result;
4423   int i;
4424
4425   if (regexp->mode == rm_reserv)
4426     result = copy_insn_regexp (regexp->regexp.reserv.reserv_decl->regexp);
4427   else if (regexp->mode == rm_unit)
4428     result = copy_node (regexp, sizeof (struct regexp));
4429   else if (regexp->mode == rm_repeat)
4430     {
4431       result = copy_node (regexp, sizeof (struct regexp));
4432       result->regexp.repeat.regexp
4433         = copy_insn_regexp (regexp->regexp.repeat.regexp);
4434     }
4435   else if (regexp->mode == rm_sequence)
4436     {
4437       result = copy_node (regexp,
4438                           sizeof (struct regexp) + sizeof (regexp_t)
4439                           * (regexp->regexp.sequence.regexps_num - 1));
4440       for (i = 0; i < regexp->regexp.sequence.regexps_num; i++)
4441         result->regexp.sequence.regexps [i]
4442           = copy_insn_regexp (regexp->regexp.sequence.regexps [i]);
4443     }
4444   else if (regexp->mode == rm_allof)
4445     {
4446       result = copy_node (regexp,
4447                           sizeof (struct regexp) + sizeof (regexp_t)
4448                           * (regexp->regexp.allof.regexps_num - 1));
4449       for (i = 0; i < regexp->regexp.allof.regexps_num; i++)
4450         result->regexp.allof.regexps [i]
4451           = copy_insn_regexp (regexp->regexp.allof.regexps [i]);
4452     }
4453   else if (regexp->mode == rm_oneof)
4454     {
4455       result = copy_node (regexp,
4456                           sizeof (struct regexp) + sizeof (regexp_t)
4457                           * (regexp->regexp.oneof.regexps_num - 1));
4458       for (i = 0; i < regexp->regexp.oneof.regexps_num; i++)
4459         result->regexp.oneof.regexps [i]
4460           = copy_insn_regexp (regexp->regexp.oneof.regexps [i]);
4461     }
4462   else
4463     {
4464       if (regexp->mode != rm_nothing)
4465         abort ();
4466       result = copy_node (regexp, sizeof (struct regexp));
4467     }
4468   return result;
4469 }
4470
4471 /* The following variable is set up 1 if a transformation has been
4472    applied.  */
4473 static int regexp_transformed_p;
4474
4475 /* The function makes transformation
4476    A*N -> A, A, ...  */
4477 static regexp_t
4478 transform_1 (regexp)
4479      regexp_t regexp;
4480 {
4481   int i;
4482   int repeat_num;
4483   regexp_t operand;
4484   pos_t pos;
4485
4486   if (regexp->mode == rm_repeat)
4487     {
4488       repeat_num = regexp->regexp.repeat.repeat_num;
4489       if (repeat_num <= 1)
4490         abort ();
4491       operand = regexp->regexp.repeat.regexp;
4492       pos = regexp->mode;
4493       regexp = create_node (sizeof (struct regexp) + sizeof (regexp_t)
4494                             * (repeat_num - 1));
4495       regexp->mode = rm_sequence;
4496       regexp->pos = pos;
4497       regexp->regexp.sequence.regexps_num = repeat_num;
4498       for (i = 0; i < repeat_num; i++)
4499         regexp->regexp.sequence.regexps [i] = copy_insn_regexp (operand);
4500       regexp_transformed_p = 1;
4501     }
4502   return regexp;
4503 }
4504
4505 /* The function makes transformations
4506    ...,(A,B,...),C,... -> ...,A,B,...,C,...
4507    ...+(A+B+...)+C+... -> ...+A+B+...+C+...
4508    ...|(A|B|...)|C|... -> ...|A|B|...|C|...  */
4509 static regexp_t
4510 transform_2 (regexp)
4511      regexp_t regexp;
4512 {
4513   if (regexp->mode == rm_sequence)
4514     {
4515       regexp_t sequence;
4516       regexp_t result;
4517       int sequence_index;
4518       int i, j;
4519
4520       for (i = 0; i < regexp->regexp.sequence.regexps_num; i++)
4521         if (regexp->regexp.sequence.regexps [i]->mode == rm_sequence)
4522           {
4523             sequence_index = i;
4524             sequence = regexp->regexp.sequence.regexps [i];
4525             break;
4526           }
4527       if (i < regexp->regexp.sequence.regexps_num)
4528         {
4529           if (sequence->regexp.sequence.regexps_num <= 1
4530               || regexp->regexp.sequence.regexps_num <= 1)
4531             abort ();
4532           result = create_node (sizeof (struct regexp)
4533                                 + sizeof (regexp_t)
4534                                 * (regexp->regexp.sequence.regexps_num
4535                                    + sequence->regexp.sequence.regexps_num
4536                                    - 2));
4537           result->mode = rm_sequence;
4538           result->pos = regexp->pos;
4539           result->regexp.sequence.regexps_num
4540             = (regexp->regexp.sequence.regexps_num
4541                + sequence->regexp.sequence.regexps_num - 1);
4542           for (i = 0; i < regexp->regexp.sequence.regexps_num; i++)
4543             if (i < sequence_index)
4544               result->regexp.sequence.regexps [i]
4545                 = copy_insn_regexp (regexp->regexp.sequence.regexps [i]);
4546             else if (i > sequence_index)
4547               result->regexp.sequence.regexps
4548                 [i + sequence->regexp.sequence.regexps_num - 1]
4549                 = copy_insn_regexp (regexp->regexp.sequence.regexps [i]);
4550             else
4551               for (j = 0; j < sequence->regexp.sequence.regexps_num; j++)
4552                 result->regexp.sequence.regexps [i + j]
4553                   = copy_insn_regexp (sequence->regexp.sequence.regexps [j]);
4554           regexp_transformed_p = 1;
4555           regexp = result;
4556         }
4557     }
4558   else if (regexp->mode == rm_allof)
4559     {
4560       regexp_t allof;
4561       regexp_t result;
4562       int allof_index;
4563       int i, j;
4564
4565       for (i = 0; i < regexp->regexp.allof.regexps_num; i++)
4566         if (regexp->regexp.allof.regexps [i]->mode == rm_allof)
4567           {
4568             allof_index = i;
4569             allof = regexp->regexp.allof.regexps [i];
4570             break;
4571           }
4572       if (i < regexp->regexp.allof.regexps_num)
4573         {
4574           if (allof->regexp.allof.regexps_num <= 1
4575               || regexp->regexp.allof.regexps_num <= 1)
4576             abort ();
4577           result = create_node (sizeof (struct regexp)
4578                                 + sizeof (regexp_t)
4579                                 * (regexp->regexp.allof.regexps_num
4580                                    + allof->regexp.allof.regexps_num - 2));
4581           result->mode = rm_allof;
4582           result->pos = regexp->pos;
4583           result->regexp.allof.regexps_num
4584             = (regexp->regexp.allof.regexps_num
4585                + allof->regexp.allof.regexps_num - 1);
4586           for (i = 0; i < regexp->regexp.allof.regexps_num; i++)
4587             if (i < allof_index)
4588               result->regexp.allof.regexps [i]
4589                 = copy_insn_regexp (regexp->regexp.allof.regexps [i]);
4590             else if (i > allof_index)
4591               result->regexp.allof.regexps
4592                 [i + allof->regexp.allof.regexps_num - 1]
4593                 = copy_insn_regexp (regexp->regexp.allof.regexps [i]);
4594             else
4595               for (j = 0; j < allof->regexp.allof.regexps_num; j++)
4596                 result->regexp.allof.regexps [i + j]
4597                   = copy_insn_regexp (allof->regexp.allof.regexps [j]);
4598           regexp_transformed_p = 1;
4599           regexp = result;
4600         }
4601     }
4602   else if (regexp->mode == rm_oneof)
4603     {
4604       regexp_t oneof;
4605       regexp_t result;
4606       int oneof_index;
4607       int i, j;
4608
4609       for (i = 0; i < regexp->regexp.oneof.regexps_num; i++)
4610         if (regexp->regexp.oneof.regexps [i]->mode == rm_oneof)
4611           {
4612             oneof_index = i;
4613             oneof = regexp->regexp.oneof.regexps [i];
4614             break;
4615           }
4616       if (i < regexp->regexp.oneof.regexps_num)
4617         {
4618           if (oneof->regexp.oneof.regexps_num <= 1
4619               || regexp->regexp.oneof.regexps_num <= 1)
4620             abort ();
4621           result = create_node (sizeof (struct regexp)
4622                                 + sizeof (regexp_t)
4623                                 * (regexp->regexp.oneof.regexps_num
4624                                    + oneof->regexp.oneof.regexps_num - 2));
4625           result->mode = rm_oneof;
4626           result->pos = regexp->pos;
4627           result->regexp.oneof.regexps_num
4628             = (regexp->regexp.oneof.regexps_num
4629                + oneof->regexp.oneof.regexps_num - 1);
4630           for (i = 0; i < regexp->regexp.oneof.regexps_num; i++)
4631             if (i < oneof_index)
4632               result->regexp.oneof.regexps [i]
4633                 = copy_insn_regexp (regexp->regexp.oneof.regexps [i]);
4634             else if (i > oneof_index)
4635               result->regexp.oneof.regexps
4636                 [i + oneof->regexp.oneof.regexps_num - 1]
4637                 = copy_insn_regexp (regexp->regexp.oneof.regexps [i]);
4638             else
4639               for (j = 0; j < oneof->regexp.oneof.regexps_num; j++)
4640                 result->regexp.oneof.regexps [i + j]
4641                   = copy_insn_regexp (oneof->regexp.oneof.regexps [j]);
4642           regexp_transformed_p = 1;
4643           regexp = result;
4644         }
4645     }
4646   return regexp;
4647 }
4648
4649 /* The function makes transformations
4650    ...,A|B|...,C,... -> (...,A,C,...)|(...,B,C,...)|...
4651    ...+(A|B|...)+C+... -> (...+A+C+...)|(...+B+C+...)|...
4652    ...+(A,B,...)+C+... -> (...+A+C+...),B,...
4653    ...+(A,B,...)+(C,D,...) -> (A+C),(B+D),...  */
4654 static regexp_t
4655 transform_3 (regexp)
4656      regexp_t regexp;
4657 {
4658   if (regexp->mode == rm_sequence)
4659     {
4660       regexp_t oneof;
4661       int oneof_index;
4662       regexp_t result;
4663       regexp_t sequence;
4664       int i, j;
4665
4666       for (i = 0; i < regexp->regexp.sequence.regexps_num; i++)
4667         if (regexp->regexp.sequence.regexps [i]->mode == rm_oneof)
4668           {
4669             oneof_index = i;
4670             oneof = regexp->regexp.sequence.regexps [i];
4671             break;
4672           }
4673       if (i < regexp->regexp.sequence.regexps_num)
4674         {
4675           if (oneof->regexp.oneof.regexps_num <= 1
4676               || regexp->regexp.sequence.regexps_num <= 1)
4677             abort ();
4678           result = create_node (sizeof (struct regexp)
4679                                 + sizeof (regexp_t)
4680                                 * (oneof->regexp.oneof.regexps_num - 1));
4681           result->mode = rm_oneof;
4682           result->pos = regexp->pos;
4683           result->regexp.oneof.regexps_num = oneof->regexp.oneof.regexps_num;
4684           for (i = 0; i < result->regexp.oneof.regexps_num; i++)
4685             {
4686               sequence
4687                 = create_node (sizeof (struct regexp)
4688                                + sizeof (regexp_t)
4689                                * (regexp->regexp.sequence.regexps_num - 1));
4690               sequence->mode = rm_sequence;
4691               sequence->pos = regexp->pos;
4692               sequence->regexp.sequence.regexps_num
4693                 = regexp->regexp.sequence.regexps_num;
4694               result->regexp.oneof.regexps [i] = sequence;
4695               for (j = 0; j < sequence->regexp.sequence.regexps_num; j++)
4696                 if (j != oneof_index)
4697                   sequence->regexp.sequence.regexps [j]
4698                     = copy_insn_regexp (regexp->regexp.sequence.regexps [j]);
4699                 else
4700                   sequence->regexp.sequence.regexps [j]
4701                     = copy_insn_regexp (oneof->regexp.oneof.regexps [i]);
4702             }
4703           regexp_transformed_p = 1;
4704           regexp = result;
4705         }
4706     }
4707   else if (regexp->mode == rm_allof)
4708     {
4709       regexp_t oneof, seq;
4710       int oneof_index, max_seq_length, allof_length;
4711       regexp_t result;
4712       regexp_t allof, allof_op;
4713       int i, j;
4714
4715       for (i = 0; i < regexp->regexp.allof.regexps_num; i++)
4716         if (regexp->regexp.allof.regexps [i]->mode == rm_oneof)
4717           {
4718             oneof_index = i;
4719             oneof = regexp->regexp.allof.regexps [i];
4720             break;
4721           }
4722       if (i < regexp->regexp.allof.regexps_num)
4723         {
4724           if (oneof->regexp.oneof.regexps_num <= 1
4725               || regexp->regexp.allof.regexps_num <= 1)
4726             abort ();
4727           result = create_node (sizeof (struct regexp)
4728                                 + sizeof (regexp_t)
4729                                 * (oneof->regexp.oneof.regexps_num - 1));
4730           result->mode = rm_oneof;
4731           result->pos = regexp->pos;
4732           result->regexp.oneof.regexps_num = oneof->regexp.oneof.regexps_num;
4733           for (i = 0; i < result->regexp.oneof.regexps_num; i++)
4734             {
4735               allof
4736                 = create_node (sizeof (struct regexp)
4737                                + sizeof (regexp_t)
4738                                * (regexp->regexp.allof.regexps_num - 1));
4739               allof->mode = rm_allof;
4740               allof->pos = regexp->pos;
4741               allof->regexp.allof.regexps_num
4742                 = regexp->regexp.allof.regexps_num;
4743               result->regexp.oneof.regexps [i] = allof;
4744               for (j = 0; j < allof->regexp.allof.regexps_num; j++)
4745                 if (j != oneof_index)
4746                   allof->regexp.allof.regexps [j]
4747                     = copy_insn_regexp (regexp->regexp.allof.regexps [j]);
4748                 else
4749                   allof->regexp.allof.regexps [j]
4750                     = copy_insn_regexp (oneof->regexp.oneof.regexps [i]);
4751             }
4752           regexp_transformed_p = 1;
4753           regexp = result;
4754         }
4755       max_seq_length = 0;
4756       for (i = 0; i < regexp->regexp.allof.regexps_num; i++)
4757         if (regexp->regexp.allof.regexps [i]->mode == rm_sequence)
4758           {
4759             seq = regexp->regexp.allof.regexps [i];
4760             if (max_seq_length < seq->regexp.sequence.regexps_num)
4761               max_seq_length = seq->regexp.sequence.regexps_num;
4762           }
4763         else if (regexp->regexp.allof.regexps [i]->mode != rm_unit)
4764           {
4765             max_seq_length = 0;
4766             break;
4767           }
4768       if (max_seq_length != 0)
4769         {
4770           if (max_seq_length == 1 || regexp->regexp.allof.regexps_num <= 1)
4771             abort ();
4772           result = create_node (sizeof (struct regexp)
4773                                 + sizeof (regexp_t) * (max_seq_length - 1));
4774           result->mode = rm_sequence;
4775           result->pos = regexp->pos;
4776           result->regexp.sequence.regexps_num = max_seq_length;
4777           for (i = 0; i < max_seq_length; i++)
4778             {
4779               allof_length = 0;
4780               for (j = 0; j < regexp->regexp.allof.regexps_num; j++)
4781                 if (regexp->regexp.allof.regexps [j]->mode == rm_sequence
4782                     && (i < (regexp->regexp.allof.regexps [j]
4783                              ->regexp.sequence.regexps_num)))
4784                   {
4785                     allof_op = (regexp->regexp.allof.regexps [j]
4786                                 ->regexp.sequence.regexps [i]);
4787                     allof_length++;
4788                   }
4789                 else if (i == 0
4790                          && regexp->regexp.allof.regexps [j]->mode == rm_unit)
4791                   {
4792                     allof_op = regexp->regexp.allof.regexps [j];
4793                     allof_length++;
4794                   }
4795               if (allof_length == 1)
4796                 result->regexp.sequence.regexps [i] = allof_op;
4797               else
4798                 {
4799                   allof = create_node (sizeof (struct regexp)
4800                                        + sizeof (regexp_t)
4801                                        * (allof_length - 1));
4802                   allof->mode = rm_allof;
4803                   allof->pos = regexp->pos;
4804                   allof->regexp.allof.regexps_num = allof_length;
4805                   result->regexp.sequence.regexps [i] = allof;
4806                   allof_length = 0;
4807                   for (j = 0; j < regexp->regexp.allof.regexps_num; j++)
4808                     if (regexp->regexp.allof.regexps [j]->mode == rm_sequence
4809                         && (i < (regexp->regexp.allof.regexps [j]
4810                                  ->regexp.sequence.regexps_num)))
4811                       {
4812                         allof_op = (regexp->regexp.allof.regexps [j]
4813                                     ->regexp.sequence.regexps [i]);
4814                         allof->regexp.allof.regexps [allof_length] = allof_op;
4815                         
4816                         allof_length++;
4817                       }
4818                     else if (i == 0
4819                              && (regexp->regexp.allof.regexps [j]->mode
4820                                  == rm_unit))
4821                       {
4822                         allof_op = regexp->regexp.allof.regexps [j];
4823                         allof->regexp.allof.regexps [allof_length] = allof_op;
4824                         allof_length++;
4825                       }
4826                 }
4827             }
4828           regexp_transformed_p = 1;
4829           regexp = result;
4830         }
4831     }
4832   return regexp;
4833 }
4834
4835 /* The function traverses IR of reservation and applies transformations
4836    implemented by FUNC.  */
4837 static regexp_t
4838 regexp_transform_func (regexp, func)
4839      regexp_t regexp;
4840      regexp_t (*func) PARAMS ((regexp_t regexp));
4841 {
4842   int i;
4843
4844   if (regexp->mode == rm_sequence)
4845     for (i = 0; i < regexp->regexp.sequence.regexps_num; i++)
4846       regexp->regexp.sequence.regexps [i]
4847         = regexp_transform_func (regexp->regexp.sequence.regexps [i], func);
4848   else if (regexp->mode == rm_allof)
4849     for (i = 0; i < regexp->regexp.allof.regexps_num; i++)
4850       regexp->regexp.allof.regexps [i]
4851         = regexp_transform_func (regexp->regexp.allof.regexps [i], func);
4852   else if (regexp->mode == rm_oneof)
4853     for (i = 0; i < regexp->regexp.oneof.regexps_num; i++)
4854       regexp->regexp.oneof.regexps [i]
4855         = regexp_transform_func (regexp->regexp.oneof.regexps [i], func);
4856   else if (regexp->mode == rm_repeat)
4857     regexp->regexp.repeat.regexp
4858       = regexp_transform_func (regexp->regexp.repeat.regexp, func);
4859   else if (regexp->mode != rm_nothing && regexp->mode != rm_unit)
4860     abort ();
4861   return (*func) (regexp);
4862 }
4863
4864 /* The function applies all transformations for IR representation of
4865    reservation REGEXP.  */
4866 static regexp_t
4867 transform_regexp (regexp)
4868      regexp_t regexp;
4869 {
4870   regexp = regexp_transform_func (regexp, transform_1);  
4871   do
4872     {
4873       regexp_transformed_p = 0;
4874       regexp = regexp_transform_func (regexp, transform_2);
4875       regexp = regexp_transform_func (regexp, transform_3);
4876     }
4877   while (regexp_transformed_p);
4878   return regexp;
4879 }
4880
4881 /* The function applys all transformations for reservations of all
4882    insn declarations.  */
4883 static void
4884 transform_insn_regexps ()
4885 {
4886   decl_t decl;
4887   int i;
4888
4889   transform_time = create_ticker ();
4890   add_advance_cycle_insn_decl ();
4891   fprintf (stderr, "Reservation transformation...");
4892   fflush (stderr);
4893   for (i = 0; i < description->decls_num; i++)
4894     {
4895       decl = description->decls [i];
4896       if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
4897         decl->decl.insn_reserv.transformed_regexp
4898           = transform_regexp (copy_insn_regexp
4899                               (decl->decl.insn_reserv.regexp));
4900     }
4901   fprintf (stderr, "done\n");
4902   ticker_off (&transform_time);
4903   fflush (stderr);
4904 }
4905
4906 \f
4907
4908 /* The following variable is an array indexed by cycle.  Each element
4909    contains cyclic list of units which should be in the same cycle.  */
4910 static unit_decl_t *the_same_automaton_lists;
4911
4912 /* The function processes all alternative reservations on CYCLE in
4913    given REGEXP to check the UNIT is not reserved on the all
4914    alternatives.  If it is true, the unit should be in the same
4915    automaton with other analogous units reserved on CYCLE in given
4916    REGEXP.  */
4917 static void
4918 process_unit_to_form_the_same_automaton_unit_lists (unit, regexp, cycle)
4919      regexp_t unit;
4920      regexp_t regexp;
4921      int cycle;
4922 {
4923   int i, k;
4924   regexp_t seq, allof;
4925   unit_decl_t unit_decl, last;
4926
4927   if (regexp == NULL || regexp->mode != rm_oneof)
4928     abort ();
4929   unit_decl = unit->regexp.unit.unit_decl;
4930   for (i = regexp->regexp.oneof.regexps_num - 1; i >= 0; i--)
4931     {
4932       seq = regexp->regexp.oneof.regexps [i];
4933       if (seq->mode == rm_sequence)
4934         {
4935           if (cycle >= seq->regexp.sequence.regexps_num)
4936             break;
4937           allof = seq->regexp.sequence.regexps [cycle];
4938           if (allof->mode == rm_allof)
4939             {
4940               for (k = 0; k < allof->regexp.allof.regexps_num; k++)
4941                 if (allof->regexp.allof.regexps [k]->mode == rm_unit
4942                     && (allof->regexp.allof.regexps [k]->regexp.unit.unit_decl
4943                         == unit_decl))
4944                   break;
4945               if (k >= allof->regexp.allof.regexps_num)
4946                 break;
4947             }
4948           else if (allof->mode == rm_unit
4949                    && allof->regexp.unit.unit_decl != unit_decl)
4950             break;
4951         }
4952       else if (cycle != 0)
4953         break;
4954       else if (seq->mode == rm_allof)
4955         {
4956           for (k = 0; k < seq->regexp.allof.regexps_num; k++)
4957             if (seq->regexp.allof.regexps [k]->mode == rm_unit
4958                 && (seq->regexp.allof.regexps [k]->regexp.unit.unit_decl
4959                     == unit_decl))
4960               break;
4961           if (k >= seq->regexp.allof.regexps_num)
4962             break;
4963         }
4964       else if (seq->mode == rm_unit && seq->regexp.unit.unit_decl != unit_decl)
4965         break;
4966     }
4967   if (i >= 0)
4968     {
4969       if (the_same_automaton_lists [cycle] == NULL)
4970         the_same_automaton_lists [cycle] = unit_decl;
4971       else
4972         {
4973           for (last = the_same_automaton_lists [cycle];;)
4974             {
4975               if (last == unit_decl)
4976                 return;
4977               if (last->the_same_automaton_unit
4978                   == the_same_automaton_lists [cycle])
4979                 break;
4980               last = last->the_same_automaton_unit;
4981             }
4982           last->the_same_automaton_unit = unit_decl->the_same_automaton_unit;
4983           unit_decl->the_same_automaton_unit
4984             = the_same_automaton_lists [cycle];
4985         }
4986     }
4987 }
4988
4989 /* The function processes given REGEXP to find units which should be
4990    in the same automaton.  */
4991 static void
4992 form_the_same_automaton_unit_lists_from_regexp (regexp)
4993      regexp_t regexp;
4994 {
4995   int i, j, k;
4996   regexp_t seq, allof, unit;
4997
4998   if (regexp == NULL || regexp->mode != rm_oneof)
4999     return;
5000   for (i = 0; i < description->max_insn_reserv_cycles; i++)
5001     the_same_automaton_lists [i] = NULL;
5002   for (i = regexp->regexp.oneof.regexps_num - 1; i >= 0; i--)
5003     {
5004       seq = regexp->regexp.oneof.regexps [i];
5005       if (seq->mode == rm_sequence)
5006         for (j = 0; j < seq->regexp.sequence.regexps_num; j++)
5007           {
5008             allof = seq->regexp.sequence.regexps [j];
5009             if (allof->mode == rm_allof)
5010               for (k = 0; k < allof->regexp.allof.regexps_num; k++)
5011                 {
5012                   unit = allof->regexp.allof.regexps [k];
5013                   if (unit->mode == rm_unit)
5014                     process_unit_to_form_the_same_automaton_unit_lists
5015                       (unit, regexp, j);
5016                   else if (unit->mode != rm_nothing)
5017                     abort ();
5018                 }
5019             else if (allof->mode == rm_unit)
5020               process_unit_to_form_the_same_automaton_unit_lists
5021                 (allof, regexp, j);
5022             else if (allof->mode != rm_nothing)
5023               abort ();
5024           }
5025       else if (seq->mode == rm_allof)
5026         for (k = 0; k < seq->regexp.allof.regexps_num; k++)
5027           {
5028             unit = seq->regexp.allof.regexps [k];
5029             if (unit->mode == rm_unit)
5030               process_unit_to_form_the_same_automaton_unit_lists
5031                 (unit, regexp, 0);
5032             else if (unit->mode != rm_nothing)
5033               abort ();
5034           }
5035       else if (seq->mode == rm_unit)
5036         process_unit_to_form_the_same_automaton_unit_lists (seq, regexp, 0);
5037       else if (seq->mode != rm_nothing)
5038         abort ();
5039     }
5040 }
5041
5042 /* The function initializes data to search for units which should be
5043    in the same automaton and call function
5044    `form_the_same_automaton_unit_lists_from_regexp' for each insn
5045    reservation regexp.  */
5046 static void
5047 form_the_same_automaton_unit_lists ()
5048 {
5049   decl_t decl;
5050   int i;
5051
5052   the_same_automaton_lists
5053     = (unit_decl_t *) xmalloc (description->max_insn_reserv_cycles
5054                                * sizeof (unit_decl_t));
5055   for (i = 0; i < description->decls_num; i++)
5056     {
5057       decl = description->decls [i];
5058       if (decl->mode == dm_unit)
5059         {
5060           decl->decl.unit.the_same_automaton_message_reported_p = FALSE;
5061           decl->decl.unit.the_same_automaton_unit = &decl->decl.unit;
5062         }
5063     }
5064   for (i = 0; i < description->decls_num; i++)
5065     {
5066       decl = description->decls [i];
5067       if (decl->mode == dm_insn_reserv)
5068         form_the_same_automaton_unit_lists_from_regexp
5069           (decl->decl.insn_reserv.transformed_regexp);
5070     }
5071   free (the_same_automaton_lists);
5072 }
5073
5074 /* The function finds units which should be in the same automaton and,
5075    if they are not, reports about it.  */
5076 static void
5077 check_unit_distributions_to_automata ()
5078 {
5079   decl_t decl;
5080   unit_decl_t start_unit_decl, unit_decl;
5081   int i;
5082
5083   form_the_same_automaton_unit_lists ();
5084   for (i = 0; i < description->decls_num; i++)
5085     {
5086       decl = description->decls [i];
5087       if (decl->mode == dm_unit)
5088         {
5089           start_unit_decl = &decl->decl.unit;
5090           if (!start_unit_decl->the_same_automaton_message_reported_p)
5091             for (unit_decl = start_unit_decl->the_same_automaton_unit;
5092                  unit_decl != start_unit_decl;
5093                  unit_decl = unit_decl->the_same_automaton_unit)
5094               if (start_unit_decl->automaton_decl != unit_decl->automaton_decl)
5095                 {
5096                   error ("Units `%s' and `%s' should be in the same automaton",
5097                          start_unit_decl->name, unit_decl->name);
5098                   unit_decl->the_same_automaton_message_reported_p = TRUE;
5099                 }
5100         }
5101     }
5102 }
5103
5104 \f
5105
5106 /* The page contains code for building alt_states (see comments for
5107    IR) describing all possible insns reservations of an automaton.  */
5108
5109 /* Current state being formed for which the current alt_state
5110    refers.  */
5111 static state_t state_being_formed;
5112
5113 /* Current alt_state being formed.  */
5114 static alt_state_t alt_state_being_formed;
5115  
5116 /* This recursive function processes `,' and units in reservation
5117    REGEXP for forming alt_states of AUTOMATON.  It is believed that
5118    CURR_CYCLE is start cycle of all reservation REGEXP.  */
5119 static int
5120 process_seq_for_forming_states (regexp, automaton, curr_cycle)
5121      regexp_t regexp;
5122      automaton_t automaton;
5123      int curr_cycle;
5124 {
5125   int i;
5126
5127   if (regexp == NULL)
5128     return curr_cycle;
5129   else if (regexp->mode == rm_unit)
5130     {
5131       if (regexp->regexp.unit.unit_decl->corresponding_automaton_num
5132           == automaton->automaton_order_num)
5133         set_state_reserv (state_being_formed, curr_cycle,
5134                           regexp->regexp.unit.unit_decl->unit_num);
5135       return curr_cycle;
5136     }
5137   else if (regexp->mode == rm_sequence)
5138     {
5139       for (i = 0; i < regexp->regexp.sequence.regexps_num; i++)
5140         curr_cycle
5141           = process_seq_for_forming_states
5142             (regexp->regexp.sequence.regexps [i], automaton, curr_cycle) + 1;
5143       return curr_cycle;
5144     }
5145   else if (regexp->mode == rm_allof)
5146     {
5147       int finish_cycle = 0;
5148       int cycle;
5149
5150       for (i = 0; i < regexp->regexp.allof.regexps_num; i++)
5151         {
5152           cycle
5153             = process_seq_for_forming_states (regexp->regexp.allof.regexps [i],
5154                                               automaton, curr_cycle);
5155           if (finish_cycle < cycle)
5156             finish_cycle = cycle;
5157         }
5158       return finish_cycle;
5159     }
5160   else
5161     {
5162       if (regexp->mode != rm_nothing)
5163         abort ();
5164       return curr_cycle;
5165     }
5166 }
5167
5168 /* This recursive function finishes forming ALT_STATE of AUTOMATON and
5169    inserts alt_state into the table.  */
5170 static void
5171 finish_forming_alt_state (alt_state, automaton)
5172      alt_state_t alt_state;
5173      automaton_t automaton ATTRIBUTE_UNUSED;
5174 {
5175   state_t state_in_table;
5176   state_t corresponding_state;
5177
5178   corresponding_state = alt_state->state;
5179   state_in_table = insert_state (corresponding_state);
5180   if (state_in_table != corresponding_state)
5181     {
5182       free_state (corresponding_state);
5183       alt_state->state = state_in_table;
5184     }
5185 }
5186
5187 /* The following variable value is current automaton insn for whose
5188    reservation the alt states are created.  */
5189 static ainsn_t curr_ainsn;
5190
5191 /* This recursive function processes `|' in reservation REGEXP for
5192    forming alt_states of AUTOMATON.  List of the alt states should
5193    have the same order as in the description.  */
5194 static void
5195 process_alts_for_forming_states (regexp, automaton, inside_oneof_p)
5196      regexp_t regexp;
5197      automaton_t automaton;
5198      int inside_oneof_p;
5199 {
5200   int i;
5201
5202   if (regexp->mode != rm_oneof)
5203     {
5204       alt_state_being_formed = get_free_alt_state ();
5205       state_being_formed = get_free_state (1, automaton);
5206       alt_state_being_formed->state = state_being_formed;
5207       /* We inserts in reverse order but we process alternatives also
5208          in reverse order.  So we have the same order of alternative
5209          as in the description.  */
5210       alt_state_being_formed->next_alt_state = curr_ainsn->alt_states;
5211       curr_ainsn->alt_states = alt_state_being_formed;
5212       (void) process_seq_for_forming_states (regexp, automaton, 0);
5213       finish_forming_alt_state (alt_state_being_formed, automaton);
5214     }
5215   else
5216     {
5217       if (inside_oneof_p)
5218         abort ();
5219       /* We processes it in reverse order to get list with the same
5220          order as in the description.  See also the previous
5221          commentary.  */
5222       for (i = regexp->regexp.oneof.regexps_num - 1; i >= 0; i--)
5223         process_alts_for_forming_states (regexp->regexp.oneof.regexps [i],
5224                                          automaton, 1);
5225     }
5226 }
5227
5228 /* Create nodes alt_state for all AUTOMATON insns.  */
5229 static void
5230 create_alt_states (automaton)
5231      automaton_t automaton;
5232 {
5233   struct insn_reserv_decl *reserv_decl;
5234
5235   for (curr_ainsn = automaton->ainsn_list;
5236        curr_ainsn != NULL;
5237        curr_ainsn = curr_ainsn->next_ainsn)
5238     {
5239       reserv_decl = curr_ainsn->insn_reserv_decl;
5240       if (reserv_decl != &advance_cycle_insn_decl->decl.insn_reserv)
5241         {
5242           curr_ainsn->alt_states = NULL;
5243           process_alts_for_forming_states (reserv_decl->transformed_regexp,
5244                                            automaton, 0);
5245           curr_ainsn->sorted_alt_states
5246             = uniq_sort_alt_states (curr_ainsn->alt_states);
5247         }
5248     }
5249 }
5250
5251 \f
5252
5253 /* The page contains major code for building DFA(s) for fast pipeline
5254    hazards recognition.  */
5255
5256 /* The function forms list of ainsns of AUTOMATON with the same
5257    reservation.  */
5258 static void
5259 form_ainsn_with_same_reservs (automaton)
5260      automaton_t automaton;
5261 {
5262   ainsn_t curr_ainsn;
5263   size_t i;
5264   vla_ptr_t first_insns;
5265   vla_ptr_t last_insns;
5266
5267   VLA_PTR_CREATE (first_insns, 150, "first insns with the same reservs");
5268   VLA_PTR_CREATE (last_insns, 150, "last insns with the same reservs");
5269   for (curr_ainsn = automaton->ainsn_list;
5270        curr_ainsn != NULL;
5271        curr_ainsn = curr_ainsn->next_ainsn)
5272     if (curr_ainsn->insn_reserv_decl
5273         == &advance_cycle_insn_decl->decl.insn_reserv)
5274       {
5275         curr_ainsn->next_same_reservs_insn = NULL;
5276         curr_ainsn->first_insn_with_same_reservs = 1;
5277       }
5278     else
5279       {
5280         for (i = 0; i < VLA_PTR_LENGTH (first_insns); i++)
5281           if (alt_states_eq
5282               (curr_ainsn->sorted_alt_states,
5283                ((ainsn_t) VLA_PTR (first_insns, i))->sorted_alt_states))
5284             break;
5285         curr_ainsn->next_same_reservs_insn = NULL;
5286         if (i < VLA_PTR_LENGTH (first_insns))
5287           {
5288             curr_ainsn->first_insn_with_same_reservs = 0;
5289             ((ainsn_t) VLA_PTR (last_insns, i))->next_same_reservs_insn
5290               = curr_ainsn;
5291             VLA_PTR (last_insns, i) = curr_ainsn;
5292           }
5293         else
5294           {
5295             VLA_PTR_ADD (first_insns, curr_ainsn);
5296             VLA_PTR_ADD (last_insns, curr_ainsn);
5297             curr_ainsn->first_insn_with_same_reservs = 1;
5298           }
5299       }
5300   VLA_PTR_DELETE (first_insns);
5301   VLA_PTR_DELETE (last_insns);
5302 }
5303
5304 /* The following function creates all states of nondeterministic (if
5305    NDFA_FLAG has nonzero value) or deterministic AUTOMATON.  */
5306 static void
5307 make_automaton (automaton)
5308      automaton_t automaton;
5309 {
5310   ainsn_t ainsn;
5311   struct insn_reserv_decl *insn_reserv_decl;
5312   alt_state_t alt_state;
5313   state_t state;
5314   state_t start_state;
5315   state_t state2;
5316   ainsn_t advance_cycle_ainsn;
5317   arc_t added_arc;
5318   vla_ptr_t state_stack;
5319
5320   VLA_PTR_CREATE (state_stack, 150, "state stack");
5321   /* Create the start state (empty state).  */
5322   start_state = insert_state (get_free_state (1, automaton));
5323   automaton->start_state = start_state;
5324   start_state->it_was_placed_in_stack_for_NDFA_forming = 1;
5325   VLA_PTR_ADD (state_stack, start_state);
5326   while (VLA_PTR_LENGTH (state_stack) != 0)
5327     {
5328       state = VLA_PTR (state_stack, VLA_PTR_LENGTH (state_stack) - 1);
5329       VLA_PTR_SHORTEN (state_stack, 1);
5330       advance_cycle_ainsn = NULL;
5331       for (ainsn = automaton->ainsn_list;
5332            ainsn != NULL;
5333            ainsn = ainsn->next_ainsn)
5334         if (ainsn->first_insn_with_same_reservs)
5335           {
5336             insn_reserv_decl = ainsn->insn_reserv_decl;
5337             if (insn_reserv_decl != &advance_cycle_insn_decl->decl.insn_reserv)
5338               {
5339                 /* We process alt_states in the same order as they are
5340                    present in the description.  */
5341                 added_arc = NULL;
5342                 for (alt_state = ainsn->alt_states;
5343                      alt_state != NULL;
5344                      alt_state = alt_state->next_alt_state)
5345                   {
5346                     state2 = alt_state->state;
5347                     if (!intersected_state_reservs_p (state, state2))
5348                       {
5349                         state2 = states_union (state, state2);
5350                         if (!state2->it_was_placed_in_stack_for_NDFA_forming)
5351                           {
5352                             state2->it_was_placed_in_stack_for_NDFA_forming
5353                               = 1;
5354                             VLA_PTR_ADD (state_stack, state2);
5355                           }
5356                         added_arc = add_arc (state, state2, ainsn, 1);
5357                         if (!ndfa_flag)
5358                           break;
5359                       }
5360                   }
5361                 if (!ndfa_flag && added_arc != NULL)
5362                   {
5363                     added_arc->state_alts = 0;
5364                     for (alt_state = ainsn->alt_states;
5365                          alt_state != NULL;
5366                          alt_state = alt_state->next_alt_state)
5367                       {
5368                         state2 = alt_state->state;
5369                         if (!intersected_state_reservs_p (state, state2))
5370                           added_arc->state_alts++;
5371                       }
5372                   }
5373               }
5374             else
5375               advance_cycle_ainsn = ainsn;
5376           }
5377       /* Add transition to advance cycle.  */
5378       state2 = state_shift (state);
5379       if (!state2->it_was_placed_in_stack_for_NDFA_forming)
5380         {
5381           state2->it_was_placed_in_stack_for_NDFA_forming = 1;
5382           VLA_PTR_ADD (state_stack, state2);
5383         }
5384       if (advance_cycle_ainsn == NULL)
5385         abort ();
5386       add_arc (state, state2, advance_cycle_ainsn, 1);
5387     }
5388   VLA_PTR_DELETE (state_stack);
5389 }
5390
5391 /* Foms lists of all arcs of STATE marked by the same ainsn.  */
5392 static void
5393 form_arcs_marked_by_insn (state)
5394      state_t state;
5395 {
5396   decl_t decl;
5397   arc_t arc;
5398   int i;
5399
5400   for (i = 0; i < description->decls_num; i++)
5401     {
5402       decl = description->decls [i];
5403       if (decl->mode == dm_insn_reserv)
5404         decl->decl.insn_reserv.arcs_marked_by_insn = NULL;
5405     }
5406   for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
5407     {
5408       if (arc->insn == NULL)
5409         abort ();
5410       arc->next_arc_marked_by_insn
5411         = arc->insn->insn_reserv_decl->arcs_marked_by_insn;
5412       arc->insn->insn_reserv_decl->arcs_marked_by_insn = arc;
5413     }
5414 }
5415
5416 /* The function creates composed state (see comments for IR) from
5417    ORIGINAL_STATE and list of arcs ARCS_MARKED_BY_INSN marked by the
5418    same insn.  If the composed state is not in STATE_STACK yet, it is
5419    popped to STATE_STACK.  */
5420 static void
5421 create_composed_state (original_state, arcs_marked_by_insn, state_stack)
5422      state_t original_state;
5423      arc_t arcs_marked_by_insn;
5424      vla_ptr_t *state_stack;
5425 {
5426   state_t state;
5427   alt_state_t curr_alt_state;
5428   alt_state_t new_alt_state;
5429   arc_t curr_arc;
5430   arc_t next_arc;
5431   state_t state_in_table;
5432   state_t temp_state;
5433   alt_state_t canonical_alt_states_list;
5434   int alts_number;
5435
5436   if (arcs_marked_by_insn == NULL)
5437     return;
5438   if (arcs_marked_by_insn->next_arc_marked_by_insn == NULL)
5439     state = arcs_marked_by_insn->to_state;
5440   else
5441     {
5442       if (!ndfa_flag)
5443         abort ();
5444       /* Create composed state.  */
5445       state = get_free_state (0, arcs_marked_by_insn->to_state->automaton);
5446       curr_alt_state = NULL;
5447       for (curr_arc = arcs_marked_by_insn;
5448            curr_arc != NULL;
5449            curr_arc = curr_arc->next_arc_marked_by_insn)
5450         {
5451           new_alt_state = get_free_alt_state ();
5452           new_alt_state->next_alt_state = curr_alt_state;
5453           new_alt_state->state = curr_arc->to_state;
5454           if (curr_arc->to_state->component_states != NULL)
5455             abort ();
5456           curr_alt_state = new_alt_state;
5457         }
5458       /* There are not identical sets in the alt state list.  */
5459       canonical_alt_states_list = uniq_sort_alt_states (curr_alt_state);
5460       if (canonical_alt_states_list->next_sorted_alt_state == NULL)
5461         {
5462           temp_state = state;
5463           state = canonical_alt_states_list->state;
5464           free_state (temp_state);
5465         }
5466       else
5467         {
5468           state->component_states = canonical_alt_states_list;
5469           state_in_table = insert_state (state);
5470           if (state_in_table != state)
5471             {
5472               if (!state_in_table->it_was_placed_in_stack_for_DFA_forming)
5473                 abort ();
5474               free_state (state);
5475               state = state_in_table;
5476             }
5477           else
5478             {
5479               if (state->it_was_placed_in_stack_for_DFA_forming)
5480                 abort ();
5481               for (curr_alt_state = state->component_states;
5482                    curr_alt_state != NULL;
5483                    curr_alt_state = curr_alt_state->next_sorted_alt_state)
5484                 for (curr_arc = first_out_arc (curr_alt_state->state);
5485                      curr_arc != NULL;
5486                      curr_arc = next_out_arc (curr_arc))
5487                   add_arc (state, curr_arc->to_state, curr_arc->insn, 1);
5488             }
5489           arcs_marked_by_insn->to_state = state;
5490           for (alts_number = 0,
5491                curr_arc = arcs_marked_by_insn->next_arc_marked_by_insn;
5492                curr_arc != NULL;
5493                curr_arc = next_arc)
5494             {
5495               next_arc = curr_arc->next_arc_marked_by_insn;
5496               remove_arc (original_state, curr_arc);
5497               alts_number++;
5498             }
5499           arcs_marked_by_insn->state_alts = alts_number;
5500         }
5501     }
5502   if (!state->it_was_placed_in_stack_for_DFA_forming)
5503     {
5504       state->it_was_placed_in_stack_for_DFA_forming = 1;
5505       VLA_PTR_ADD (*state_stack, state);
5506     }
5507 }
5508
5509 /* The function transformes nondeterminstic AUTOMATON into
5510    deterministic.  */
5511 static void
5512 NDFA_to_DFA (automaton)
5513      automaton_t automaton;
5514 {
5515   state_t start_state;
5516   state_t state;
5517   decl_t decl;
5518   vla_ptr_t state_stack;
5519   int i;
5520
5521   VLA_PTR_CREATE (state_stack, 150, "state stack");
5522   /* Create the start state (empty state).  */
5523   start_state = automaton->start_state;
5524   start_state->it_was_placed_in_stack_for_DFA_forming = 1;
5525   VLA_PTR_ADD (state_stack, start_state);
5526   while (VLA_PTR_LENGTH (state_stack) != 0)
5527     {
5528       state = VLA_PTR (state_stack, VLA_PTR_LENGTH (state_stack) - 1);
5529       VLA_PTR_SHORTEN (state_stack, 1);
5530       form_arcs_marked_by_insn (state);
5531       for (i = 0; i < description->decls_num; i++)
5532         {
5533           decl = description->decls [i];
5534           if (decl->mode == dm_insn_reserv)
5535             create_composed_state
5536               (state, decl->decl.insn_reserv.arcs_marked_by_insn,
5537                &state_stack);
5538         }
5539     }
5540   VLA_PTR_DELETE (state_stack);
5541 }
5542
5543 /* The following variable value is current number (1, 2, ...) of passing
5544    graph of states.  */
5545 static int curr_state_graph_pass_num;
5546
5547 /* This recursive function passes all states achieved from START_STATE
5548    and applies APPLIED_FUNC to them.  */
5549 static void
5550 pass_state_graph (start_state, applied_func)
5551      state_t start_state;
5552      void (*applied_func) PARAMS ((state_t state));
5553 {
5554   arc_t arc;
5555
5556   if (start_state->pass_num == curr_state_graph_pass_num)
5557     return;
5558   start_state->pass_num = curr_state_graph_pass_num;
5559   (*applied_func) (start_state);
5560   for (arc = first_out_arc (start_state);
5561        arc != NULL;
5562        arc = next_out_arc (arc))
5563     pass_state_graph (arc->to_state, applied_func);
5564 }
5565
5566 /* This recursive function passes all states of AUTOMATON and applies
5567    APPLIED_FUNC to them.  */
5568 static void
5569 pass_states (automaton, applied_func)
5570      automaton_t automaton;
5571      void (*applied_func) PARAMS ((state_t state));
5572 {
5573   curr_state_graph_pass_num++;
5574   pass_state_graph (automaton->start_state, applied_func);
5575 }
5576
5577 /* The function initializes code for passing of all states.  */
5578 static void
5579 initiate_pass_states ()
5580 {
5581   curr_state_graph_pass_num = 0;
5582 }
5583
5584 /* The following vla is used for storing pointers to all achieved
5585    states.  */
5586 static vla_ptr_t all_achieved_states;
5587
5588 /* This function is called by function pass_states to add an achieved
5589    STATE.  */
5590 static void
5591 add_achieved_state (state)
5592      state_t state;
5593 {
5594   VLA_PTR_ADD (all_achieved_states, state);
5595 }
5596
5597 /* The function sets up equivalence numbers of insns which mark all
5598    out arcs of STATE by equiv_class_num_1 (if ODD_ITERATION_FLAG has
5599    nonzero value) or by equiv_class_num_2 of the destination state.
5600    The function returns number of out arcs of STATE.  */
5601 static int
5602 set_out_arc_insns_equiv_num (state, odd_iteration_flag)
5603      state_t state;
5604      int odd_iteration_flag;
5605 {
5606   int state_out_arcs_num;
5607   arc_t arc;
5608
5609   state_out_arcs_num = 0;
5610   for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
5611     {
5612       if (arc->insn->insn_reserv_decl->equiv_class_num != 0
5613           || arc->insn->insn_reserv_decl->state_alts != 0)
5614         abort ();
5615       state_out_arcs_num++;
5616       arc->insn->insn_reserv_decl->equiv_class_num
5617         = (odd_iteration_flag
5618            ? arc->to_state->equiv_class_num_1
5619            : arc->to_state->equiv_class_num_2);
5620       arc->insn->insn_reserv_decl->state_alts = arc->state_alts;
5621       if (arc->insn->insn_reserv_decl->equiv_class_num == 0
5622           || arc->insn->insn_reserv_decl->state_alts <= 0)
5623         abort ();
5624     }
5625   return state_out_arcs_num;
5626 }
5627
5628 /* The function clears equivalence numbers and alt_states in all insns
5629    which mark all out arcs of STATE.  */
5630 static void
5631 clear_arc_insns_equiv_num (state)
5632      state_t state;
5633 {
5634   arc_t arc;
5635
5636   for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
5637     {
5638       arc->insn->insn_reserv_decl->equiv_class_num = 0;
5639       arc->insn->insn_reserv_decl->state_alts = 0;
5640     }
5641 }
5642
5643 /* The function copies pointers to equivalent states from vla FROM
5644    into vla TO.  */
5645 static void
5646 copy_equiv_class (to, from)
5647      vla_ptr_t *to;
5648      const vla_ptr_t *from;
5649 {
5650   state_t *class_ptr;
5651
5652   VLA_PTR_NULLIFY (*to);
5653   for (class_ptr = VLA_PTR_BEGIN (*from);
5654        class_ptr <= (state_t *) VLA_PTR_LAST (*from);
5655        class_ptr++)
5656     VLA_PTR_ADD (*to, *class_ptr);
5657 }
5658
5659 /* The function returns nonzero value if STATE is not equivalent to
5660    another state from the same current partition on equivalence
5661    classes Another state has ORIGINAL_STATE_OUT_ARCS_NUM number of
5662    output arcs.  Iteration of making equivalence partition is defined
5663    by ODD_ITERATION_FLAG.  */
5664 static int
5665 state_is_differed (state, original_state_out_arcs_num, odd_iteration_flag)
5666      state_t state;
5667      int original_state_out_arcs_num;
5668      int odd_iteration_flag;
5669 {
5670   arc_t arc;
5671   int state_out_arcs_num;
5672
5673   state_out_arcs_num = 0;
5674   for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
5675     {
5676       state_out_arcs_num++;
5677       if ((odd_iteration_flag
5678            ? arc->to_state->equiv_class_num_1
5679            : arc->to_state->equiv_class_num_2)
5680           != arc->insn->insn_reserv_decl->equiv_class_num
5681           || (arc->insn->insn_reserv_decl->state_alts != arc->state_alts))
5682         return 1;
5683     }
5684   return state_out_arcs_num != original_state_out_arcs_num;
5685 }
5686
5687 /* The function makes initial partition of STATES on equivalent
5688    classes.  */
5689 static state_t
5690 init_equiv_class (states, states_num)
5691      state_t *states;
5692      int states_num;
5693 {
5694   state_t *state_ptr;
5695   state_t result_equiv_class;
5696
5697   result_equiv_class = NULL;
5698   for (state_ptr = states; state_ptr < states + states_num; state_ptr++)
5699     {
5700       (*state_ptr)->equiv_class_num_1 = 1;
5701       (*state_ptr)->next_equiv_class_state = result_equiv_class;
5702       result_equiv_class = *state_ptr;
5703     }
5704   return result_equiv_class;
5705 }
5706
5707 /* The function processes equivalence class given by its pointer
5708    EQUIV_CLASS_PTR on odd iteration if ODD_ITERATION_FLAG.  If there
5709    are not equvalent states, the function partitions the class
5710    removing nonequivalent states and placing them in
5711    *NEXT_ITERATION_CLASSES, increments *NEW_EQUIV_CLASS_NUM_PTR ans
5712    assigns it to the state equivalence number.  If the class has been
5713    partitioned, the function returns nonzero value.  */
5714 static int
5715 partition_equiv_class (equiv_class_ptr, odd_iteration_flag,
5716                        next_iteration_classes, new_equiv_class_num_ptr)
5717      state_t *equiv_class_ptr;
5718      int odd_iteration_flag;
5719      vla_ptr_t *next_iteration_classes;
5720      int *new_equiv_class_num_ptr;
5721 {
5722   state_t new_equiv_class;
5723   int partition_p;
5724   state_t first_state;
5725   state_t curr_state;
5726   state_t prev_state;
5727   state_t next_state;
5728   int out_arcs_num;
5729
5730   partition_p = 0;
5731   if (*equiv_class_ptr == NULL)
5732     abort ();
5733   for (first_state = *equiv_class_ptr;
5734        first_state != NULL;
5735        first_state = new_equiv_class)
5736     {
5737       new_equiv_class = NULL;
5738       if (first_state->next_equiv_class_state != NULL)
5739         {
5740           /* There are more one states in the class equivalence.  */
5741           out_arcs_num = set_out_arc_insns_equiv_num (first_state,
5742                                                       odd_iteration_flag);
5743           for (prev_state = first_state,
5744                  curr_state = first_state->next_equiv_class_state;
5745                curr_state != NULL;
5746                curr_state = next_state)
5747             {
5748               next_state = curr_state->next_equiv_class_state;
5749               if (state_is_differed (curr_state, out_arcs_num,
5750                                      odd_iteration_flag))
5751                 {
5752                   /* Remove curr state from the class equivalence.  */
5753                   prev_state->next_equiv_class_state = next_state;
5754                   /* Add curr state to the new class equivalence.  */
5755                   curr_state->next_equiv_class_state = new_equiv_class;
5756                   if (new_equiv_class == NULL)
5757                     (*new_equiv_class_num_ptr)++;
5758                   if (odd_iteration_flag)
5759                     curr_state->equiv_class_num_2 = *new_equiv_class_num_ptr;
5760                   else
5761                     curr_state->equiv_class_num_1 = *new_equiv_class_num_ptr;
5762                   new_equiv_class = curr_state;
5763                   partition_p = 1;
5764                 }
5765               else
5766                 prev_state = curr_state;
5767             }
5768           clear_arc_insns_equiv_num (first_state);
5769         }
5770       if (new_equiv_class != NULL)
5771         VLA_PTR_ADD  (*next_iteration_classes, new_equiv_class);
5772     }
5773   return partition_p;
5774 }
5775
5776 /* The function finds equivalent states of AUTOMATON.  */
5777 static void
5778 evaluate_equiv_classes (automaton, equiv_classes)
5779      automaton_t automaton;
5780      vla_ptr_t *equiv_classes;
5781 {
5782   state_t new_equiv_class;
5783   int new_equiv_class_num;
5784   int odd_iteration_flag;
5785   int finish_flag;
5786   vla_ptr_t next_iteration_classes;
5787   state_t *equiv_class_ptr;
5788   state_t *state_ptr;
5789   
5790   VLA_PTR_CREATE (all_achieved_states, 1500, "all achieved states");
5791   pass_states (automaton, add_achieved_state);
5792   new_equiv_class = init_equiv_class (VLA_PTR_BEGIN (all_achieved_states),
5793                                       VLA_PTR_LENGTH (all_achieved_states));
5794   odd_iteration_flag = 0;
5795   new_equiv_class_num = 1;
5796   VLA_PTR_CREATE (next_iteration_classes, 150, "next iteration classes");
5797   VLA_PTR_ADD (next_iteration_classes, new_equiv_class);
5798   do
5799     {
5800       odd_iteration_flag = !odd_iteration_flag;
5801       finish_flag = 1;
5802       copy_equiv_class (equiv_classes, &next_iteration_classes);
5803       /* Transfer equiv numbers for the next iteration.  */
5804       for (state_ptr = VLA_PTR_BEGIN (all_achieved_states);
5805            state_ptr <= (state_t *) VLA_PTR_LAST (all_achieved_states);
5806            state_ptr++)
5807         if (odd_iteration_flag)
5808           (*state_ptr)->equiv_class_num_2 = (*state_ptr)->equiv_class_num_1;
5809         else
5810           (*state_ptr)->equiv_class_num_1 = (*state_ptr)->equiv_class_num_2;
5811       for (equiv_class_ptr = VLA_PTR_BEGIN (*equiv_classes);
5812            equiv_class_ptr <= (state_t *) VLA_PTR_LAST (*equiv_classes);
5813            equiv_class_ptr++)
5814         if (partition_equiv_class (equiv_class_ptr, odd_iteration_flag,
5815                                    &next_iteration_classes,
5816                                    &new_equiv_class_num))
5817           finish_flag = 0;
5818     }
5819   while (!finish_flag);
5820   VLA_PTR_DELETE (next_iteration_classes);
5821   VLA_PTR_DELETE (all_achieved_states);
5822 }
5823
5824 /* The function merges equivalent states of AUTOMATON.  */
5825 static void
5826 merge_states (automaton, equiv_classes)
5827      automaton_t automaton;
5828      vla_ptr_t *equiv_classes;
5829 {
5830   state_t *equiv_class_ptr;
5831   state_t curr_state;
5832   state_t new_state;
5833   state_t first_class_state;
5834   alt_state_t alt_states;
5835   alt_state_t new_alt_state;
5836   arc_t curr_arc;
5837   arc_t next_arc;
5838
5839   /* Create states corresponding to equivalence classes containing two
5840      or more states.  */
5841   for (equiv_class_ptr = VLA_PTR_BEGIN (*equiv_classes);
5842        equiv_class_ptr <= (state_t *) VLA_PTR_LAST (*equiv_classes);
5843        equiv_class_ptr++)
5844     if ((*equiv_class_ptr)->next_equiv_class_state != NULL)
5845       {
5846         /* There are more one states in the class equivalence.  */
5847         /* Create new compound state.  */
5848         new_state = get_free_state (0, automaton);
5849         alt_states = NULL;
5850         first_class_state = *equiv_class_ptr;
5851         for (curr_state = first_class_state;
5852              curr_state != NULL;
5853              curr_state = curr_state->next_equiv_class_state)
5854           {
5855             curr_state->equiv_class_state = new_state;
5856             new_alt_state = get_free_alt_state ();
5857             new_alt_state->state = curr_state;
5858             new_alt_state->next_sorted_alt_state = alt_states;
5859             alt_states = new_alt_state;
5860           }
5861         new_state->component_states = alt_states;
5862       }
5863     else
5864       (*equiv_class_ptr)->equiv_class_state = *equiv_class_ptr;
5865   for (equiv_class_ptr = VLA_PTR_BEGIN (*equiv_classes);
5866        equiv_class_ptr <= (state_t *) VLA_PTR_LAST (*equiv_classes);
5867        equiv_class_ptr++)
5868     if ((*equiv_class_ptr)->next_equiv_class_state != NULL)
5869       {
5870         first_class_state = *equiv_class_ptr;
5871         /* Create new arcs output from the state corresponding to
5872            equiv class.  */
5873         for (curr_arc = first_out_arc (first_class_state);
5874              curr_arc != NULL;
5875              curr_arc = next_out_arc (curr_arc))
5876           add_arc (first_class_state->equiv_class_state,
5877                    curr_arc->to_state->equiv_class_state,
5878                    curr_arc->insn, curr_arc->state_alts);
5879         /* Delete output arcs from states of given class equivalence.  */
5880         for (curr_state = first_class_state;
5881              curr_state != NULL;
5882              curr_state = curr_state->next_equiv_class_state)
5883           {
5884             if (automaton->start_state == curr_state)
5885               automaton->start_state = curr_state->equiv_class_state;
5886             /* Delete the state and its output arcs.  */
5887             for (curr_arc = first_out_arc (curr_state);
5888                  curr_arc != NULL;
5889                  curr_arc = next_arc)
5890               {
5891                 next_arc = next_out_arc (curr_arc);
5892                 free_arc (curr_arc);
5893               }
5894           }
5895       }
5896     else
5897       {
5898         /* Change `to_state' of arcs output from the state of given
5899            equivalence class.  */
5900         for (curr_arc = first_out_arc (*equiv_class_ptr);
5901              curr_arc != NULL;
5902              curr_arc = next_out_arc (curr_arc))
5903           curr_arc->to_state = curr_arc->to_state->equiv_class_state;
5904       }
5905 }
5906
5907 /* The function sets up new_cycle_p for states if there is arc to the
5908    state marked by advance_cycle_insn_decl.  */
5909 static void
5910 set_new_cycle_flags (state)
5911      state_t state;
5912 {
5913   arc_t arc;
5914
5915   for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
5916     if (arc->insn->insn_reserv_decl
5917         == &advance_cycle_insn_decl->decl.insn_reserv)
5918       arc->to_state->new_cycle_p = 1;
5919 }
5920
5921 /* The top level function for minimization of deterministic
5922    AUTOMATON.  */
5923 static void
5924 minimize_DFA (automaton)
5925      automaton_t automaton;
5926 {
5927   vla_ptr_t equiv_classes;
5928
5929   VLA_PTR_CREATE (equiv_classes, 1500, "equivalence classes");
5930   evaluate_equiv_classes (automaton, &equiv_classes);
5931   merge_states (automaton, &equiv_classes);
5932   pass_states (automaton, set_new_cycle_flags);
5933   VLA_PTR_DELETE (equiv_classes);
5934 }
5935
5936 /* Values of two variables are counted number of states and arcs in an
5937    automaton.  */
5938 static int curr_counted_states_num;
5939 static int curr_counted_arcs_num;
5940
5941 /* The function is called by function `pass_states' to count states
5942    and arcs of an automaton.  */
5943 static void
5944 incr_states_and_arcs_nums (state)
5945      state_t state;
5946 {
5947   arc_t arc;
5948
5949   curr_counted_states_num++;
5950   for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
5951     curr_counted_arcs_num++;
5952 }
5953
5954 /* The function counts states and arcs of AUTOMATON.  */
5955 static void
5956 count_states_and_arcs (automaton, states_num, arcs_num)
5957      automaton_t automaton;
5958      int *states_num;
5959      int *arcs_num;
5960 {
5961   curr_counted_states_num = 0;
5962   curr_counted_arcs_num = 0;
5963   pass_states (automaton, incr_states_and_arcs_nums);
5964   *states_num = curr_counted_states_num;
5965   *arcs_num = curr_counted_arcs_num;
5966 }
5967
5968 /* The function builds one DFA AUTOMATON for fast pipeline hazards
5969    recognition after checking and simplifying IR of the
5970    description.  */
5971 static void
5972 build_automaton (automaton)
5973      automaton_t automaton;
5974 {
5975   int states_num;
5976   int arcs_num;
5977
5978   ticker_on (&NDFA_time);
5979   make_automaton (automaton);
5980   ticker_off (&NDFA_time);
5981   count_states_and_arcs (automaton, &states_num, &arcs_num);
5982   automaton->NDFA_states_num = states_num;
5983   automaton->NDFA_arcs_num = arcs_num;
5984   ticker_on (&NDFA_to_DFA_time);
5985   NDFA_to_DFA (automaton);
5986   ticker_off (&NDFA_to_DFA_time);
5987   count_states_and_arcs (automaton, &states_num, &arcs_num);
5988   automaton->DFA_states_num = states_num;
5989   automaton->DFA_arcs_num = arcs_num;
5990   if (!no_minimization_flag)
5991     {
5992       ticker_on (&minimize_time);
5993       minimize_DFA (automaton);
5994       ticker_off (&minimize_time);
5995       count_states_and_arcs (automaton, &states_num, &arcs_num);
5996       automaton->minimal_DFA_states_num = states_num;
5997       automaton->minimal_DFA_arcs_num = arcs_num;
5998     }
5999 }
6000
6001 \f
6002
6003 /* The page contains code for enumeration  of all states of an automaton.  */
6004
6005 /* Variable used for enumeration of all states of an automaton.  Its
6006    value is current number of automaton states.  */
6007 static int curr_state_order_num;
6008
6009 /* The function is called by function `pass_states' for enumerating
6010    states.  */
6011 static void
6012 set_order_state_num (state)
6013      state_t state;
6014 {
6015   state->order_state_num = curr_state_order_num;
6016   curr_state_order_num++;
6017 }
6018
6019 /* The function enumerates all states of AUTOMATON.  */
6020 static void
6021 enumerate_states (automaton)
6022      automaton_t automaton;
6023 {
6024   curr_state_order_num = 0;
6025   pass_states (automaton, set_order_state_num);
6026   automaton->achieved_states_num = curr_state_order_num;
6027 }
6028
6029 \f
6030
6031 /* The page contains code for finding equivalent automaton insns
6032    (ainsns).  */
6033
6034 /* The function inserts AINSN into cyclic list
6035    CYCLIC_EQUIV_CLASS_INSN_LIST of ainsns.  */
6036 static ainsn_t
6037 insert_ainsn_into_equiv_class (ainsn, cyclic_equiv_class_insn_list)
6038      ainsn_t ainsn;
6039      ainsn_t cyclic_equiv_class_insn_list;
6040 {
6041   if (cyclic_equiv_class_insn_list == NULL)
6042     ainsn->next_equiv_class_insn = ainsn;
6043   else
6044     {
6045       ainsn->next_equiv_class_insn
6046         = cyclic_equiv_class_insn_list->next_equiv_class_insn;
6047       cyclic_equiv_class_insn_list->next_equiv_class_insn = ainsn;
6048     }
6049   return ainsn;
6050 }
6051
6052 /* The function deletes equiv_class_insn into cyclic list of
6053    equivalent ainsns.  */
6054 static void
6055 delete_ainsn_from_equiv_class (equiv_class_insn)
6056      ainsn_t equiv_class_insn;
6057 {
6058   ainsn_t curr_equiv_class_insn;
6059   ainsn_t prev_equiv_class_insn;
6060
6061   prev_equiv_class_insn = equiv_class_insn;
6062   for (curr_equiv_class_insn = equiv_class_insn->next_equiv_class_insn;
6063        curr_equiv_class_insn != equiv_class_insn;
6064        curr_equiv_class_insn = curr_equiv_class_insn->next_equiv_class_insn)
6065     prev_equiv_class_insn = curr_equiv_class_insn;
6066   if (prev_equiv_class_insn != equiv_class_insn)
6067     prev_equiv_class_insn->next_equiv_class_insn
6068       = equiv_class_insn->next_equiv_class_insn;
6069 }
6070
6071 /* The function processes AINSN of a state in order to find equivalent
6072    ainsns.  INSN_ARCS_ARRAY is table: code of insn -> out arc of the
6073    state.  */
6074 static void
6075 process_insn_equiv_class (ainsn, insn_arcs_array)
6076      ainsn_t ainsn;
6077      arc_t *insn_arcs_array;
6078 {
6079   ainsn_t next_insn;
6080   ainsn_t curr_insn;
6081   ainsn_t cyclic_insn_list;
6082   arc_t arc;
6083
6084   if (insn_arcs_array [ainsn->insn_reserv_decl->insn_num] == NULL)
6085     abort ();
6086   curr_insn = ainsn;
6087   /* New class of ainsns which are not equivalent to given ainsn.  */
6088   cyclic_insn_list = NULL;
6089   do
6090     {
6091       next_insn = curr_insn->next_equiv_class_insn;
6092       arc = insn_arcs_array [curr_insn->insn_reserv_decl->insn_num];
6093       if (arc == NULL
6094           || (insn_arcs_array [ainsn->insn_reserv_decl->insn_num]->to_state
6095               != arc->to_state))
6096         {
6097           delete_ainsn_from_equiv_class (curr_insn);
6098           cyclic_insn_list = insert_ainsn_into_equiv_class (curr_insn,
6099                                                             cyclic_insn_list);
6100         }
6101       curr_insn = next_insn;
6102     }
6103   while (curr_insn != ainsn);
6104 }
6105
6106 /* The function processes STATE in order to find equivalent ainsns.  */
6107 static void
6108 process_state_for_insn_equiv_partition (state)
6109      state_t state;
6110 {
6111   arc_t arc;
6112   arc_t *insn_arcs_array;
6113   int i;
6114   vla_ptr_t insn_arcs_vect;
6115
6116   VLA_PTR_CREATE (insn_arcs_vect, 500, "insn arcs vector");
6117   VLA_PTR_EXPAND (insn_arcs_vect, description->insns_num);
6118   insn_arcs_array = VLA_PTR_BEGIN (insn_arcs_vect);
6119   /* Process insns of the arcs.  */
6120   for (i = 0; i < description->insns_num; i++)
6121     insn_arcs_array [i] = NULL;
6122   for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6123     insn_arcs_array [arc->insn->insn_reserv_decl->insn_num] = arc;
6124   for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6125     process_insn_equiv_class (arc->insn, insn_arcs_array);
6126   VLA_PTR_DELETE (insn_arcs_vect);
6127 }
6128
6129 /* The function searches for equivalent ainsns of AUTOMATON.  */
6130 static void
6131 set_insn_equiv_classes (automaton)
6132      automaton_t automaton;
6133 {
6134   ainsn_t ainsn;
6135   ainsn_t first_insn;
6136   ainsn_t curr_insn;
6137   ainsn_t cyclic_insn_list;
6138   ainsn_t insn_with_same_reservs;
6139   int equiv_classes_num;
6140
6141   /* All insns are included in one equivalence class.  */
6142   cyclic_insn_list = NULL;
6143   for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
6144     if (ainsn->first_insn_with_same_reservs)
6145       cyclic_insn_list = insert_ainsn_into_equiv_class (ainsn,
6146                                                         cyclic_insn_list);
6147   /* Process insns in order to make equivalence partition.  */
6148   pass_states (automaton, process_state_for_insn_equiv_partition);
6149   /* Enumerate equiv classes.  */
6150   for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
6151     /* Set undefined value.  */
6152     ainsn->insn_equiv_class_num = -1;
6153   equiv_classes_num = 0;
6154   for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
6155     if (ainsn->insn_equiv_class_num < 0)
6156       {
6157         first_insn = ainsn;
6158         if (!first_insn->first_insn_with_same_reservs)
6159           abort ();
6160         first_insn->first_ainsn_with_given_equialence_num = 1;
6161         curr_insn = first_insn;
6162         do
6163           {
6164             for (insn_with_same_reservs = curr_insn;
6165                  insn_with_same_reservs != NULL;
6166                  insn_with_same_reservs
6167                    = insn_with_same_reservs->next_same_reservs_insn)
6168               insn_with_same_reservs->insn_equiv_class_num = equiv_classes_num;
6169             curr_insn = curr_insn->next_equiv_class_insn;
6170           }
6171         while (curr_insn != first_insn);
6172         equiv_classes_num++;
6173       }
6174   automaton->insn_equiv_classes_num = equiv_classes_num;
6175 }
6176
6177 \f
6178
6179 /* This page contains code for creating DFA(s) and calls functions
6180    building them.  */
6181
6182
6183 /* The following value is used to prevent floating point overflow for
6184    estimating an automaton bound.  The value should be less DBL_MAX on
6185    the host machine.  We use here approximate minimum of maximal
6186    double floating point value required by ANSI C standard.  It
6187    will work for non ANSI sun compiler too.  */
6188
6189 #define MAX_FLOATING_POINT_VALUE_FOR_AUTOMATON_BOUND  1.0E37
6190
6191 /* The function estimate size of the single DFA used by PHR (pipeline
6192    hazards recognizer).  */
6193 static double
6194 estimate_one_automaton_bound ()
6195 {
6196   decl_t decl;
6197   double one_automaton_estimation_bound;
6198   double root_value;
6199   int i;
6200
6201   one_automaton_estimation_bound = 1.0;
6202   for (i = 0; i < description->decls_num; i++)
6203     {
6204       decl = description->decls [i];
6205       if (decl->mode == dm_unit)
6206         {
6207           root_value = exp (log (decl->decl.unit.max_occ_cycle_num + 1.0)
6208                             / automata_num);
6209           if (MAX_FLOATING_POINT_VALUE_FOR_AUTOMATON_BOUND / root_value
6210               > one_automaton_estimation_bound)
6211             one_automaton_estimation_bound *= root_value;
6212         }
6213     }
6214   return one_automaton_estimation_bound;
6215 }
6216
6217 /* The function compares unit declarations acoording to their maximal
6218    cycle in reservations.  */
6219 static int
6220 compare_max_occ_cycle_nums (unit_decl_1, unit_decl_2)
6221      const void *unit_decl_1;
6222      const void *unit_decl_2;
6223 {
6224   if (((*(decl_t *) unit_decl_1)->decl.unit.max_occ_cycle_num)
6225       < ((*(decl_t *) unit_decl_2)->decl.unit.max_occ_cycle_num))
6226     return 1;
6227   else if (((*(decl_t *) unit_decl_1)->decl.unit.max_occ_cycle_num)
6228            == ((*(decl_t *) unit_decl_2)->decl.unit.max_occ_cycle_num))
6229     return 0;
6230   else
6231     return -1;
6232 }
6233
6234 /* The function makes heuristic assigning automata to units.  Actually
6235    efficacy of the algorithm has been checked yet??? */
6236 static void
6237 units_to_automata_heuristic_distr ()
6238 {
6239   double estimation_bound;
6240   decl_t decl;
6241   decl_t *unit_decl_ptr;
6242   int automaton_num;
6243   int rest_units_num;
6244   double bound_value;
6245   vla_ptr_t unit_decls;
6246   int i;
6247
6248   if (description->units_num == 0)
6249     return;
6250   estimation_bound = estimate_one_automaton_bound ();
6251   VLA_PTR_CREATE (unit_decls, 150, "unit decls");
6252   for (i = 0; i < description->decls_num; i++)
6253     {
6254       decl = description->decls [i];
6255       if (decl->mode == dm_unit)
6256         VLA_PTR_ADD (unit_decls, decl);
6257     }
6258   qsort (VLA_PTR_BEGIN (unit_decls), VLA_PTR_LENGTH (unit_decls),
6259          sizeof (decl_t), compare_max_occ_cycle_nums);
6260   automaton_num = 0;
6261   unit_decl_ptr = VLA_PTR_BEGIN (unit_decls);
6262   bound_value = (*unit_decl_ptr)->decl.unit.max_occ_cycle_num;
6263   (*unit_decl_ptr)->decl.unit.corresponding_automaton_num = automaton_num;
6264   for (unit_decl_ptr++;
6265        unit_decl_ptr <= (decl_t *) VLA_PTR_LAST (unit_decls);
6266        unit_decl_ptr++)
6267     {
6268       rest_units_num
6269         = ((decl_t *) VLA_PTR_LAST (unit_decls) - unit_decl_ptr + 1);
6270       if (automata_num - automaton_num - 1 > rest_units_num)
6271         abort ();
6272       if (automaton_num < automata_num - 1
6273           && ((automata_num - automaton_num - 1 == rest_units_num)
6274               || (bound_value
6275                   > (estimation_bound
6276                      / ((*unit_decl_ptr)->decl.unit.max_occ_cycle_num)))))
6277         {
6278           bound_value = (*unit_decl_ptr)->decl.unit.max_occ_cycle_num;
6279           automaton_num++;
6280         }
6281       else
6282         bound_value *= (*unit_decl_ptr)->decl.unit.max_occ_cycle_num;
6283       (*unit_decl_ptr)->decl.unit.corresponding_automaton_num = automaton_num;
6284     }
6285   if (automaton_num != automata_num - 1)
6286     abort ();
6287   VLA_PTR_DELETE (unit_decls);
6288 }
6289
6290 /* The functions creates automaton insns for each automata.  Automaton
6291    insn is simply insn for given automaton which makes reservation
6292    only of units of the automaton.  */
6293 static ainsn_t
6294 create_ainsns ()
6295 {
6296   decl_t decl;
6297   ainsn_t first_ainsn;
6298   ainsn_t curr_ainsn;
6299   ainsn_t prev_ainsn;
6300   int i;
6301
6302   first_ainsn = NULL;
6303   prev_ainsn = NULL;
6304   for (i = 0; i < description->decls_num; i++)
6305     {
6306       decl = description->decls [i];
6307       if (decl->mode == dm_insn_reserv)
6308         {
6309           curr_ainsn = create_node (sizeof (struct ainsn));
6310           curr_ainsn->insn_reserv_decl = &decl->decl.insn_reserv;
6311           curr_ainsn->important_p = FALSE;
6312           curr_ainsn->next_ainsn = NULL;
6313           if (prev_ainsn == NULL)
6314             first_ainsn = curr_ainsn;
6315           else
6316             prev_ainsn->next_ainsn = curr_ainsn;
6317           prev_ainsn = curr_ainsn;
6318         }
6319     }
6320   return first_ainsn;
6321 }
6322
6323 /* The function assigns automata to units according to constructions
6324    `define_automaton' in the description.  */
6325 static void
6326 units_to_automata_distr ()
6327 {
6328   decl_t decl;
6329   int i;
6330   
6331   for (i = 0; i < description->decls_num; i++)
6332     {
6333       decl = description->decls [i];
6334       if (decl->mode == dm_unit)
6335         {
6336           if (decl->decl.unit.automaton_decl == NULL
6337               || (decl->decl.unit.automaton_decl->corresponding_automaton
6338                   == NULL))
6339             /* Distribute to the first automaton.  */
6340             decl->decl.unit.corresponding_automaton_num = 0;
6341           else
6342             decl->decl.unit.corresponding_automaton_num
6343               = (decl->decl.unit.automaton_decl
6344                  ->corresponding_automaton->automaton_order_num);
6345         }
6346     }
6347 }
6348
6349 /* The function creates DFA(s) for fast pipeline hazards recognition
6350    after checking and simplifying IR of the description.  */
6351 static void
6352 create_automata ()
6353 {
6354   automaton_t curr_automaton;
6355   automaton_t prev_automaton;
6356   decl_t decl;
6357   int curr_automaton_num;
6358   int i;
6359
6360   if (automata_num != 0)
6361     {
6362       units_to_automata_heuristic_distr ();
6363       for (prev_automaton = NULL, curr_automaton_num = 0;
6364            curr_automaton_num < automata_num;
6365            curr_automaton_num++, prev_automaton = curr_automaton)
6366         {
6367           curr_automaton = create_node (sizeof (struct automaton));
6368           curr_automaton->ainsn_list = create_ainsns ();
6369           curr_automaton->corresponding_automaton_decl = NULL;
6370           curr_automaton->next_automaton = NULL;
6371           curr_automaton->automaton_order_num = curr_automaton_num;
6372           if (prev_automaton == NULL)
6373             description->first_automaton = curr_automaton;
6374           else
6375             prev_automaton->next_automaton = curr_automaton;
6376         }
6377     }
6378   else
6379     {
6380       curr_automaton_num = 0;
6381       prev_automaton = NULL;
6382       for (i = 0; i < description->decls_num; i++)
6383         {
6384           decl = description->decls [i];
6385           if (decl->mode == dm_automaton
6386               && decl->decl.automaton.automaton_is_used)
6387             {
6388               curr_automaton = create_node (sizeof (struct automaton));
6389               curr_automaton->ainsn_list = create_ainsns ();
6390               curr_automaton->corresponding_automaton_decl
6391                 = &decl->decl.automaton;
6392               curr_automaton->next_automaton = NULL;
6393               decl->decl.automaton.corresponding_automaton = curr_automaton;
6394               curr_automaton->automaton_order_num = curr_automaton_num;
6395               if (prev_automaton == NULL)
6396                 description->first_automaton = curr_automaton;
6397               else
6398                 prev_automaton->next_automaton = curr_automaton;
6399               curr_automaton_num++;
6400               prev_automaton = curr_automaton;
6401             }
6402         }
6403       if (curr_automaton_num == 0)
6404         {
6405           curr_automaton = create_node (sizeof (struct automaton));
6406           curr_automaton->ainsn_list = create_ainsns ();
6407           curr_automaton->corresponding_automaton_decl = NULL;
6408           curr_automaton->next_automaton = NULL;
6409           description->first_automaton = curr_automaton;
6410         }
6411       units_to_automata_distr ();
6412     }
6413   NDFA_time = create_ticker ();
6414   ticker_off (&NDFA_time);
6415   NDFA_to_DFA_time = create_ticker ();
6416   ticker_off (&NDFA_to_DFA_time);
6417   minimize_time = create_ticker ();
6418   ticker_off (&minimize_time);
6419   equiv_time = create_ticker ();
6420   ticker_off (&equiv_time);
6421   for (curr_automaton = description->first_automaton;
6422        curr_automaton != NULL;
6423        curr_automaton = curr_automaton->next_automaton)
6424     {
6425       if (curr_automaton->corresponding_automaton_decl == NULL)
6426         fprintf (stderr, "Create anonymous automaton ...");
6427       else
6428         fprintf (stderr, "Create automaton `%s'...",
6429                  curr_automaton->corresponding_automaton_decl->name);
6430       create_alt_states (curr_automaton);
6431       form_ainsn_with_same_reservs (curr_automaton);
6432       build_automaton (curr_automaton);
6433       enumerate_states (curr_automaton);
6434       ticker_on (&equiv_time);
6435       set_insn_equiv_classes (curr_automaton);
6436       ticker_off (&equiv_time);
6437       fprintf (stderr, "done\n");
6438     }
6439 }
6440
6441 \f
6442
6443 /* This page contains code for forming string representation of
6444    regexp.  The representation is formed on IR obstack.  So you should
6445    not work with IR obstack between regexp_representation and
6446    finish_regexp_representation calls.  */
6447
6448 /* This recursive function forms string representation of regexp
6449    (without tailing '\0').  */
6450 static void
6451 form_regexp (regexp)
6452      regexp_t regexp;
6453 {
6454   int i;
6455     
6456   if (regexp->mode == rm_unit || regexp->mode == rm_reserv)
6457     {
6458       const char *name = (regexp->mode == rm_unit
6459                           ? regexp->regexp.unit.name
6460                           : regexp->regexp.reserv.name);
6461
6462       obstack_grow (&irp, name, strlen (name));
6463     }
6464   else if (regexp->mode == rm_sequence)
6465     for (i = 0; i < regexp->regexp.sequence.regexps_num; i++)
6466       {
6467         if (i != 0)
6468           obstack_1grow (&irp, ',');
6469         form_regexp (regexp->regexp.sequence.regexps [i]);
6470       }
6471   else if (regexp->mode == rm_allof)
6472     {
6473       obstack_1grow (&irp, '(');
6474       for (i = 0; i < regexp->regexp.allof.regexps_num; i++)
6475         {
6476           if (i != 0)
6477             obstack_1grow (&irp, '+');
6478           if (regexp->regexp.allof.regexps[i]->mode == rm_sequence
6479               || regexp->regexp.oneof.regexps[i]->mode == rm_oneof)
6480             obstack_1grow (&irp, '(');
6481           form_regexp (regexp->regexp.allof.regexps [i]);
6482           if (regexp->regexp.allof.regexps[i]->mode == rm_sequence
6483               || regexp->regexp.oneof.regexps[i]->mode == rm_oneof)
6484             obstack_1grow (&irp, ')');
6485         }
6486       obstack_1grow (&irp, ')');
6487     }
6488   else if (regexp->mode == rm_oneof)
6489     for (i = 0; i < regexp->regexp.oneof.regexps_num; i++)
6490       {
6491         if (i != 0)
6492           obstack_1grow (&irp, '|');
6493         if (regexp->regexp.oneof.regexps[i]->mode == rm_sequence)
6494           obstack_1grow (&irp, '(');
6495         form_regexp (regexp->regexp.oneof.regexps [i]);
6496         if (regexp->regexp.oneof.regexps[i]->mode == rm_sequence)
6497           obstack_1grow (&irp, ')');
6498       }
6499   else if (regexp->mode == rm_repeat)
6500     {
6501       char digits [30];
6502
6503       if (regexp->regexp.repeat.regexp->mode == rm_sequence
6504           || regexp->regexp.repeat.regexp->mode == rm_allof
6505           || regexp->regexp.repeat.regexp->mode == rm_oneof)
6506         obstack_1grow (&irp, '(');
6507       form_regexp (regexp->regexp.repeat.regexp);
6508       if (regexp->regexp.repeat.regexp->mode == rm_sequence
6509           || regexp->regexp.repeat.regexp->mode == rm_allof
6510           || regexp->regexp.repeat.regexp->mode == rm_oneof)
6511         obstack_1grow (&irp, ')');
6512       sprintf (digits, "*%d", regexp->regexp.repeat.repeat_num);
6513       obstack_grow (&irp, digits, strlen (digits));
6514     }
6515   else if (regexp->mode == rm_nothing)
6516     obstack_grow (&irp, NOTHING_NAME, strlen (NOTHING_NAME));
6517   else
6518     abort ();
6519 }
6520
6521 /* The function returns string representation of REGEXP on IR
6522    obstack.  */
6523 static const char *
6524 regexp_representation (regexp)
6525      regexp_t regexp;
6526 {
6527   form_regexp (regexp);
6528   obstack_1grow (&irp, '\0');
6529   return obstack_base (&irp);
6530 }
6531
6532 /* The function frees memory allocated for last formed string
6533    representation of regexp.  */
6534 static void
6535 finish_regexp_representation ()
6536 {
6537   int length = obstack_object_size (&irp);
6538   
6539   obstack_blank_fast (&irp, -length);
6540 }
6541
6542 \f
6543
6544 /* This page contains code for output PHR (pipeline hazards recognizer).  */
6545
6546 /* The function outputs minimal C type which is sufficient for
6547    representation numbers in range min_range_value and
6548    max_range_value.  Because host machine and build machine may be
6549    different, we use here minimal values required by ANSI C standard
6550    instead of UCHAR_MAX, SHRT_MAX, SHRT_MIN, etc.  This is a good
6551    approximation.  */
6552
6553 static void
6554 output_range_type (f, min_range_value, max_range_value)
6555      FILE *f;
6556      long int min_range_value;
6557      long int max_range_value;
6558 {
6559   if (min_range_value >= 0 && max_range_value <= 255)
6560     fprintf (f, "unsigned char");
6561   else if (min_range_value >= -127 && max_range_value <= 127)
6562     fprintf (f, "signed char");
6563   else if (min_range_value >= 0 && max_range_value <= 65535)
6564     fprintf (f, "unsigned short");
6565   else if (min_range_value >= -32767 && max_range_value <= 32767)
6566     fprintf (f, "short");
6567   else
6568     fprintf (f, "int");
6569 }
6570
6571 /* The following macro value is used as value of member
6572    `longest_path_length' of state when we are processing path and the
6573    state on the path.  */
6574
6575 #define ON_THE_PATH -2
6576
6577 /* The following recursive function searches for the length of the
6578    longest path starting from STATE which does not contain cycles and
6579    `cycle advance' arcs.  */
6580
6581 static int
6582 longest_path_length (state)
6583      state_t state;
6584 {
6585   arc_t arc;
6586   int length, result;
6587   
6588   if (state->longest_path_length == ON_THE_PATH)
6589     /* We don't expect the path cycle here.  Our graph may contain
6590        only cycles with one state on the path not containing `cycle
6591        advance' arcs -- see comment below.  */
6592     abort ();
6593   else if (state->longest_path_length != UNDEFINED_LONGEST_PATH_LENGTH)
6594     /* We alreday visited the state.  */
6595     return state->longest_path_length;
6596
6597   result = 0;
6598   for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6599     /* Ignore cycles containing one state and `cycle advance' arcs.  */
6600     if (arc->to_state != state
6601         && (arc->insn->insn_reserv_decl
6602             != &advance_cycle_insn_decl->decl.insn_reserv))
6603     {
6604       length = longest_path_length (arc->to_state);
6605       if (length > result)
6606         result = length;
6607     }
6608   state->longest_path_length = result + 1;
6609   return result;
6610 }
6611
6612 /* The following variable value is value of the corresponding global
6613    variable in the automaton based pipeline interface.  */
6614
6615 static int max_dfa_issue_rate;
6616
6617 /* The following function processes the longest path length staring
6618    from STATE to find MAX_DFA_ISSUE_RATE.  */
6619
6620 static void
6621 process_state_longest_path_length (state)
6622      state_t state;
6623 {
6624   int value;
6625
6626   value = longest_path_length (state);
6627   if (value > max_dfa_issue_rate)
6628     max_dfa_issue_rate = value;
6629 }
6630
6631 /* The following nacro value is name of the corresponding global
6632    variable in the automaton based pipeline interface.  */
6633
6634 #define MAX_DFA_ISSUE_RATE_VAR_NAME "max_dfa_issue_rate"
6635
6636 /* The following function calculates value of the the corresponding
6637    global variable and outputs its declaration.  */
6638
6639 static void
6640 output_dfa_max_issue_rate ()
6641 {
6642   automaton_t automaton;
6643
6644   if (UNDEFINED_LONGEST_PATH_LENGTH == ON_THE_PATH || ON_THE_PATH >= 0)
6645     abort ();
6646   max_dfa_issue_rate = 0;
6647   for (automaton = description->first_automaton;
6648        automaton != NULL;
6649        automaton = automaton->next_automaton)
6650     pass_states (automaton, process_state_longest_path_length);
6651   fprintf (output_file, "\nint %s = %d;\n",
6652            MAX_DFA_ISSUE_RATE_VAR_NAME, max_dfa_issue_rate);
6653 }
6654
6655 /* The function outputs all initialization values of VECT with length
6656    vect_length.  */
6657 static void
6658 output_vect (vect, vect_length)
6659      vect_el_t *vect;
6660      int vect_length;
6661 {
6662   int els_on_line;
6663
6664   els_on_line = 1;
6665   if (vect_length == 0)
6666     fprintf (output_file,
6667              "0 /* This is dummy el because the vect is empty */");
6668   else
6669     {
6670       do
6671         {
6672           fprintf (output_file, "%5ld", (long) *vect);
6673           vect_length--;
6674           if (els_on_line == 10)
6675             {
6676               els_on_line = 0;
6677               fprintf (output_file, ",\n");
6678             }
6679           else if (vect_length != 0)
6680             fprintf (output_file, ", ");
6681           els_on_line++;
6682           vect++;
6683         }
6684       while (vect_length != 0);
6685     }
6686 }
6687
6688 /* The following is name of the structure which represents DFA(s) for
6689    PHR.  */
6690 #define CHIP_NAME "DFA_chip"
6691
6692 /* The following is name of member which represents state of a DFA for
6693    PHR.  */
6694 static void
6695 output_chip_member_name (f, automaton)
6696      FILE *f;
6697      automaton_t automaton;
6698 {
6699   if (automaton->corresponding_automaton_decl == NULL)
6700     fprintf (f, "automaton_state_%d", automaton->automaton_order_num);
6701   else
6702     fprintf (f, "%s_automaton_state",
6703              automaton->corresponding_automaton_decl->name);
6704 }
6705
6706 /* The following is name of temporary variable which stores state of a
6707    DFA for PHR.  */
6708 static void
6709 output_temp_chip_member_name (f, automaton)
6710      FILE *f;
6711      automaton_t automaton;
6712 {
6713   fprintf (f, "_");
6714   output_chip_member_name (f, automaton);
6715 }
6716
6717 /* This is name of macro value which is code of pseudo_insn
6718    representing advancing cpu cycle.  Its value is used as internal
6719    code unknown insn.  */
6720 #define ADVANCE_CYCLE_VALUE_NAME "DFA__ADVANCE_CYCLE"
6721
6722 /* Output name of translate vector for given automaton.  */
6723 static void
6724 output_translate_vect_name (f, automaton)
6725      FILE *f;
6726      automaton_t automaton;
6727 {
6728   if (automaton->corresponding_automaton_decl == NULL)
6729     fprintf (f, "translate_%d", automaton->automaton_order_num);
6730   else
6731     fprintf (f, "%s_translate", automaton->corresponding_automaton_decl->name);
6732 }
6733
6734 /* Output name for simple transition table representation.  */
6735 static void
6736 output_trans_full_vect_name (f, automaton)
6737      FILE *f;
6738      automaton_t automaton;
6739 {
6740   if (automaton->corresponding_automaton_decl == NULL)
6741     fprintf (f, "transitions_%d", automaton->automaton_order_num);
6742   else
6743     fprintf (f, "%s_transitions",
6744              automaton->corresponding_automaton_decl->name);
6745 }
6746
6747 /* Output name of comb vector of the transition table for given
6748    automaton.  */
6749 static void
6750 output_trans_comb_vect_name (f, automaton)
6751      FILE *f;
6752      automaton_t automaton;
6753 {
6754   if (automaton->corresponding_automaton_decl == NULL)
6755     fprintf (f, "transitions_%d", automaton->automaton_order_num);
6756   else
6757     fprintf (f, "%s_transitions",
6758              automaton->corresponding_automaton_decl->name);
6759 }
6760
6761 /* Output name of check vector of the transition table for given
6762    automaton.  */
6763 static void
6764 output_trans_check_vect_name (f, automaton)
6765      FILE *f;
6766      automaton_t automaton;
6767 {
6768   if (automaton->corresponding_automaton_decl == NULL)
6769     fprintf (f, "check_%d", automaton->automaton_order_num);
6770   else
6771     fprintf (f, "%s_check", automaton->corresponding_automaton_decl->name);
6772 }
6773
6774 /* Output name of base vector of the transition table for given
6775    automaton.  */
6776 static void
6777 output_trans_base_vect_name (f, automaton)
6778      FILE *f;
6779      automaton_t automaton;
6780 {
6781   if (automaton->corresponding_automaton_decl == NULL)
6782     fprintf (f, "base_%d", automaton->automaton_order_num);
6783   else
6784     fprintf (f, "%s_base", automaton->corresponding_automaton_decl->name);
6785 }
6786
6787 /* Output name for simple alternatives number representation.  */
6788 static void
6789 output_state_alts_full_vect_name (f, automaton)
6790      FILE *f;
6791      automaton_t automaton;
6792 {
6793   if (automaton->corresponding_automaton_decl == NULL)
6794     fprintf (f, "state_alts_%d", automaton->automaton_order_num);
6795   else
6796     fprintf (f, "%s_state_alts",
6797              automaton->corresponding_automaton_decl->name);
6798 }
6799
6800 /* Output name of comb vector of the alternatives number table for given
6801    automaton.  */
6802 static void
6803 output_state_alts_comb_vect_name (f, automaton)
6804      FILE *f;
6805      automaton_t automaton;
6806 {
6807   if (automaton->corresponding_automaton_decl == NULL)
6808     fprintf (f, "state_alts_%d", automaton->automaton_order_num);
6809   else
6810     fprintf (f, "%s_state_alts",
6811              automaton->corresponding_automaton_decl->name);
6812 }
6813
6814 /* Output name of check vector of the alternatives number table for given
6815    automaton.  */
6816 static void
6817 output_state_alts_check_vect_name (f, automaton)
6818      FILE *f;
6819      automaton_t automaton;
6820 {
6821   if (automaton->corresponding_automaton_decl == NULL)
6822     fprintf (f, "check_state_alts_%d", automaton->automaton_order_num);
6823   else
6824     fprintf (f, "%s_check_state_alts",
6825              automaton->corresponding_automaton_decl->name);
6826 }
6827
6828 /* Output name of base vector of the alternatives number table for given
6829    automaton.  */
6830 static void
6831 output_state_alts_base_vect_name (f, automaton)
6832      FILE *f;
6833      automaton_t automaton;
6834 {
6835   if (automaton->corresponding_automaton_decl == NULL)
6836     fprintf (f, "base_state_alts_%d", automaton->automaton_order_num);
6837   else
6838     fprintf (f, "%s_base_state_alts",
6839              automaton->corresponding_automaton_decl->name);
6840 }
6841
6842 /* Output name of simple min issue delay table representation.  */
6843 static void
6844 output_min_issue_delay_vect_name (f, automaton)
6845      FILE *f;
6846      automaton_t automaton;
6847 {
6848   if (automaton->corresponding_automaton_decl == NULL)
6849     fprintf (f, "min_issue_delay_%d", automaton->automaton_order_num);
6850   else
6851     fprintf (f, "%s_min_issue_delay",
6852              automaton->corresponding_automaton_decl->name);
6853 }
6854
6855 /* Output name of deadlock vector for given automaton.  */
6856 static void
6857 output_dead_lock_vect_name (f, automaton)
6858      FILE *f;
6859      automaton_t automaton;
6860 {
6861   if (automaton->corresponding_automaton_decl == NULL)
6862     fprintf (f, "dead_lock_%d", automaton->automaton_order_num);
6863   else
6864     fprintf (f, "%s_dead_lock", automaton->corresponding_automaton_decl->name);
6865 }
6866
6867 /* Output name of reserved units table for AUTOMATON into file F.  */
6868 static void
6869 output_reserved_units_table_name (f, automaton)
6870      FILE *f;
6871      automaton_t automaton;
6872 {
6873   if (automaton->corresponding_automaton_decl == NULL)
6874     fprintf (f, "reserved_units_%d", automaton->automaton_order_num);
6875   else
6876     fprintf (f, "%s_reserved_units",
6877              automaton->corresponding_automaton_decl->name);
6878 }
6879
6880 /* Name of the PHR interface macro.  */
6881 #define AUTOMATON_STATE_ALTS_MACRO_NAME "AUTOMATON_STATE_ALTS"
6882
6883 /* Name of the PHR interface macro.  */
6884 #define CPU_UNITS_QUERY_MACRO_NAME "CPU_UNITS_QUERY"
6885
6886 /* Names of an internal functions: */
6887 #define INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME "internal_min_issue_delay"
6888
6889 /* This is external type of DFA(s) state.  */
6890 #define STATE_TYPE_NAME "state_t"
6891
6892 #define INTERNAL_TRANSITION_FUNC_NAME "internal_state_transition"
6893
6894 #define INTERNAL_STATE_ALTS_FUNC_NAME "internal_state_alts"
6895
6896 #define INTERNAL_RESET_FUNC_NAME "internal_reset"
6897
6898 #define INTERNAL_DEAD_LOCK_FUNC_NAME "internal_state_dead_lock_p"
6899
6900 #define INTERNAL_INSN_LATENCY_FUNC_NAME "internal_insn_latency"
6901
6902 /* Name of cache of insn dfa codes.  */
6903 #define DFA_INSN_CODES_VARIABLE_NAME "dfa_insn_codes"
6904
6905 /* Name of length of cache of insn dfa codes.  */
6906 #define DFA_INSN_CODES_LENGTH_VARIABLE_NAME "dfa_insn_codes_length"
6907
6908 /* Names of the PHR interface functions: */
6909 #define SIZE_FUNC_NAME "state_size"
6910
6911 #define TRANSITION_FUNC_NAME "state_transition"
6912
6913 #define STATE_ALTS_FUNC_NAME "state_alts"
6914
6915 #define MIN_ISSUE_DELAY_FUNC_NAME "min_issue_delay"
6916
6917 #define MIN_INSN_CONFLICT_DELAY_FUNC_NAME "min_insn_conflict_delay"
6918
6919 #define DEAD_LOCK_FUNC_NAME "state_dead_lock_p"
6920
6921 #define RESET_FUNC_NAME "state_reset"
6922
6923 #define INSN_LATENCY_FUNC_NAME "insn_latency"
6924
6925 #define PRINT_RESERVATION_FUNC_NAME "print_reservation"
6926
6927 #define GET_CPU_UNIT_CODE_FUNC_NAME "get_cpu_unit_code"
6928
6929 #define CPU_UNIT_RESERVATION_P_FUNC_NAME "cpu_unit_reservation_p"
6930
6931 #define DFA_START_FUNC_NAME  "dfa_start"
6932
6933 #define DFA_FINISH_FUNC_NAME "dfa_finish"
6934
6935 /* Names of parameters of the PHR interface functions.  */
6936 #define STATE_NAME "state"
6937
6938 #define INSN_PARAMETER_NAME "insn"
6939
6940 #define INSN2_PARAMETER_NAME "insn2"
6941
6942 #define CHIP_PARAMETER_NAME "chip"
6943
6944 #define FILE_PARAMETER_NAME "f"
6945
6946 #define CPU_UNIT_NAME_PARAMETER_NAME "cpu_unit_name"
6947
6948 #define CPU_CODE_PARAMETER_NAME "cpu_unit_code"
6949
6950 /* Names of the variables whose values are internal insn code of rtx
6951    insn.  */
6952 #define INTERNAL_INSN_CODE_NAME "insn_code"
6953
6954 #define INTERNAL_INSN2_CODE_NAME "insn2_code"
6955
6956 /* Names of temporary variables in some functions.  */
6957 #define TEMPORARY_VARIABLE_NAME "temp"
6958
6959 #define I_VARIABLE_NAME "i"
6960
6961 /* Name of result variable in some functions.  */
6962 #define RESULT_VARIABLE_NAME "res"
6963
6964 /* Name of function (attribute) to translate insn into number of insn
6965    alternatives reservation.  */
6966 #define INSN_ALTS_FUNC_NAME "insn_alts"
6967
6968 /* Name of function (attribute) to translate insn into internal insn
6969    code.  */
6970 #define INTERNAL_DFA_INSN_CODE_FUNC_NAME "internal_dfa_insn_code"
6971
6972 /* Name of function (attribute) to translate insn into internal insn
6973    code with caching.  */
6974 #define DFA_INSN_CODE_FUNC_NAME "dfa_insn_code"
6975
6976 /* Name of function (attribute) to translate insn into internal insn
6977    code.  */
6978 #define INSN_DEFAULT_LATENCY_FUNC_NAME "insn_default_latency"
6979
6980 /* Name of function (attribute) to translate insn into internal insn
6981    code.  */
6982 #define BYPASS_P_FUNC_NAME "bypass_p"
6983
6984 /* Output C type which is used for representation of codes of states
6985    of AUTOMATON.  */
6986 static void
6987 output_state_member_type (f, automaton)
6988      FILE *f;
6989      automaton_t automaton;
6990 {
6991   output_range_type (f, 0, automaton->achieved_states_num);
6992 }
6993
6994 /* Output definition of the structure representing current DFA(s)
6995    state(s).  */
6996 static void
6997 output_chip_definitions ()
6998 {
6999   automaton_t automaton;
7000
7001   fprintf (output_file, "struct %s\n{\n", CHIP_NAME);
7002   for (automaton = description->first_automaton;
7003        automaton != NULL;
7004        automaton = automaton->next_automaton)
7005     {
7006       fprintf (output_file, "  ");
7007       output_state_member_type (output_file, automaton);
7008       fprintf (output_file, " ");
7009       output_chip_member_name (output_file, automaton);
7010       fprintf (output_file, ";\n");
7011     }
7012   fprintf (output_file, "};\n\n");
7013 #if 0
7014   fprintf (output_file, "static struct %s %s;\n\n", CHIP_NAME, CHIP_NAME);
7015 #endif
7016 }
7017
7018
7019 /* The function outputs translate vector of internal insn code into
7020    insn equivalence class number.  The equivalence class number is
7021    used to access to table and vectors reprewsenting DFA(s).  */
7022 static void
7023 output_translate_vect (automaton)
7024      automaton_t automaton;
7025 {
7026   ainsn_t ainsn;
7027   int insn_value;
7028   vla_hwint_t translate_vect;
7029
7030   VLA_HWINT_CREATE (translate_vect, 250, "translate vector");
7031   VLA_HWINT_EXPAND (translate_vect, description->insns_num);
7032   for (insn_value = 0; insn_value <= description->insns_num; insn_value++)
7033     /* Undefined value */
7034     VLA_HWINT (translate_vect, insn_value) = automaton->insn_equiv_classes_num;
7035   for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
7036     VLA_HWINT (translate_vect, ainsn->insn_reserv_decl->insn_num)
7037       = ainsn->insn_equiv_class_num;
7038   fprintf (output_file,
7039            "/* Vector translating external insn codes to internal ones.*/\n");
7040   fprintf (output_file, "static const ");
7041   output_range_type (output_file, 0, automaton->insn_equiv_classes_num);
7042   fprintf (output_file, " ");
7043   output_translate_vect_name (output_file, automaton);
7044   fprintf (output_file, "[] = {\n");
7045   output_vect (VLA_HWINT_BEGIN (translate_vect),
7046                VLA_HWINT_LENGTH (translate_vect));
7047   fprintf (output_file, "};\n\n");
7048   VLA_HWINT_DELETE (translate_vect);
7049 }
7050
7051 /* The value in a table state x ainsn -> something which represents
7052    undefined value.  */
7053 static int undefined_vect_el_value;
7054
7055 /* The following function returns nonzero value if the best
7056    representation of the table is comb vector.  */
7057 static int
7058 comb_vect_p (tab)
7059      state_ainsn_table_t tab;
7060 {
7061   return  (2 * VLA_HWINT_LENGTH (tab->full_vect)
7062            > 5 * VLA_HWINT_LENGTH (tab->comb_vect));
7063 }
7064
7065 /* The following function creates new table for AUTOMATON.  */
7066 static state_ainsn_table_t
7067 create_state_ainsn_table (automaton)
7068      automaton_t automaton;
7069 {
7070   state_ainsn_table_t tab;
7071   int full_vect_length;
7072   int i;
7073
7074   tab = create_node (sizeof (struct state_ainsn_table));
7075   tab->automaton = automaton;
7076   VLA_HWINT_CREATE (tab->comb_vect, 10000, "comb vector");
7077   VLA_HWINT_CREATE (tab->check_vect, 10000, "check vector");
7078   VLA_HWINT_CREATE (tab->base_vect, 1000, "base vector");
7079   VLA_HWINT_EXPAND (tab->base_vect, automaton->achieved_states_num);
7080   VLA_HWINT_CREATE (tab->full_vect, 10000, "full vector");
7081   full_vect_length = (automaton->insn_equiv_classes_num
7082                       * automaton->achieved_states_num);
7083   VLA_HWINT_EXPAND (tab->full_vect, full_vect_length);
7084   for (i = 0; i < full_vect_length; i++)
7085     VLA_HWINT (tab->full_vect, i) = undefined_vect_el_value;
7086   tab->min_base_vect_el_value = 0;
7087   tab->max_base_vect_el_value = 0;
7088   tab->min_comb_vect_el_value = 0;
7089   tab->max_comb_vect_el_value = 0;
7090   return tab;
7091 }
7092
7093 /* The following function outputs the best C representation of the
7094    table TAB of given TABLE_NAME.  */
7095 static void
7096 output_state_ainsn_table (tab, table_name, output_full_vect_name_func,
7097                           output_comb_vect_name_func,
7098                           output_check_vect_name_func,
7099                           output_base_vect_name_func)
7100      state_ainsn_table_t tab;
7101      char *table_name;
7102      void (*output_full_vect_name_func) PARAMS ((FILE *, automaton_t));
7103      void (*output_comb_vect_name_func) PARAMS ((FILE *, automaton_t));
7104      void (*output_check_vect_name_func) PARAMS ((FILE *, automaton_t));
7105      void (*output_base_vect_name_func) PARAMS ((FILE *, automaton_t));
7106 {
7107   if (!comb_vect_p (tab))
7108     {
7109       fprintf (output_file, "/* Vector for %s.  */\n", table_name);
7110       fprintf (output_file, "static const ");
7111       output_range_type (output_file, tab->min_comb_vect_el_value,
7112                          tab->max_comb_vect_el_value);
7113       fprintf (output_file, " ");
7114       (*output_full_vect_name_func) (output_file, tab->automaton);
7115       fprintf (output_file, "[] = {\n");
7116       output_vect (VLA_HWINT_BEGIN (tab->full_vect),
7117                    VLA_HWINT_LENGTH (tab->full_vect));
7118       fprintf (output_file, "};\n\n");
7119     }
7120   else
7121     {
7122       fprintf (output_file, "/* Comb vector for %s.  */\n", table_name);
7123       fprintf (output_file, "static const ");
7124       output_range_type (output_file, tab->min_comb_vect_el_value,
7125                          tab->max_comb_vect_el_value);
7126       fprintf (output_file, " ");
7127       (*output_comb_vect_name_func) (output_file, tab->automaton);
7128       fprintf (output_file, "[] = {\n");
7129       output_vect (VLA_HWINT_BEGIN (tab->comb_vect),
7130                    VLA_HWINT_LENGTH (tab->comb_vect));
7131       fprintf (output_file, "};\n\n");
7132       fprintf (output_file, "/* Check vector for %s.  */\n", table_name);
7133       fprintf (output_file, "static const ");
7134       output_range_type (output_file, 0, tab->automaton->achieved_states_num);
7135       fprintf (output_file, " ");
7136       (*output_check_vect_name_func) (output_file, tab->automaton);
7137       fprintf (output_file, "[] = {\n");
7138       output_vect (VLA_HWINT_BEGIN (tab->check_vect),
7139                    VLA_HWINT_LENGTH (tab->check_vect));
7140       fprintf (output_file, "};\n\n");
7141       fprintf (output_file, "/* Base vector for %s.  */\n", table_name);
7142       fprintf (output_file, "static const ");
7143       output_range_type (output_file, tab->min_base_vect_el_value,
7144                          tab->max_base_vect_el_value);
7145       fprintf (output_file, " ");
7146       (*output_base_vect_name_func) (output_file, tab->automaton);
7147       fprintf (output_file, "[] = {\n");
7148       output_vect (VLA_HWINT_BEGIN (tab->base_vect),
7149                    VLA_HWINT_LENGTH (tab->base_vect));
7150       fprintf (output_file, "};\n\n");
7151     }
7152 }
7153
7154 /* The following function adds vector with length VECT_LENGTH and
7155    elements pointed by VECT to table TAB as its line with number
7156    VECT_NUM.  */
7157 static void
7158 add_vect (tab, vect_num, vect, vect_length)
7159      state_ainsn_table_t tab;
7160      int vect_num;
7161      vect_el_t *vect;
7162      int vect_length;
7163 {
7164   int real_vect_length;
7165   vect_el_t *comb_vect_start;
7166   vect_el_t *check_vect_start;
7167   int comb_vect_index;
7168   int comb_vect_els_num;
7169   int vect_index;
7170   int first_unempty_vect_index;
7171   int additional_els_num;
7172   int no_state_value;
7173   vect_el_t vect_el;
7174   int i;
7175
7176   if (vect_length == 0)
7177     abort ();
7178   real_vect_length = tab->automaton->insn_equiv_classes_num;
7179   if (vect [vect_length - 1] == undefined_vect_el_value)
7180     abort ();
7181   /* Form full vector in the table: */
7182   for (i = 0; i < vect_length; i++)
7183     VLA_HWINT (tab->full_vect,
7184                i + tab->automaton->insn_equiv_classes_num * vect_num)
7185       = vect [i];
7186   /* Form comb vector in the table: */
7187   if (VLA_HWINT_LENGTH (tab->comb_vect) != VLA_HWINT_LENGTH (tab->check_vect))
7188     abort ();
7189   comb_vect_start = VLA_HWINT_BEGIN (tab->comb_vect);
7190   comb_vect_els_num = VLA_HWINT_LENGTH (tab->comb_vect);
7191   for (first_unempty_vect_index = 0;
7192        first_unempty_vect_index < vect_length;
7193        first_unempty_vect_index++)
7194     if (vect [first_unempty_vect_index] != undefined_vect_el_value)
7195       break;
7196   /* Search for the place in comb vect for the inserted vect.  */
7197   for (comb_vect_index = 0;
7198        comb_vect_index < comb_vect_els_num;
7199        comb_vect_index++)
7200     {
7201       for (vect_index = first_unempty_vect_index;
7202            vect_index < vect_length
7203              && vect_index + comb_vect_index < comb_vect_els_num;
7204            vect_index++)
7205         if (vect [vect_index] != undefined_vect_el_value
7206             && (comb_vect_start [vect_index + comb_vect_index]
7207                 != undefined_vect_el_value))
7208           break;
7209       if (vect_index >= vect_length
7210           || vect_index + comb_vect_index >= comb_vect_els_num)
7211         break;
7212     }
7213   /* Slot was found.  */
7214   additional_els_num = comb_vect_index + real_vect_length - comb_vect_els_num;
7215   if (additional_els_num < 0)
7216     additional_els_num = 0;
7217   /* Expand comb and check vectors.  */
7218   vect_el = undefined_vect_el_value;
7219   no_state_value = tab->automaton->achieved_states_num;
7220   while (additional_els_num > 0)
7221     {
7222       VLA_HWINT_ADD (tab->comb_vect, vect_el);
7223       VLA_HWINT_ADD (tab->check_vect, no_state_value);
7224       additional_els_num--;
7225     }
7226   comb_vect_start = VLA_HWINT_BEGIN (tab->comb_vect);
7227   check_vect_start = VLA_HWINT_BEGIN (tab->check_vect);
7228   if (VLA_HWINT_LENGTH (tab->comb_vect)
7229       < (size_t) (comb_vect_index + real_vect_length))
7230     abort ();
7231   /* Fill comb and check vectors.  */
7232   for (vect_index = 0; vect_index < vect_length; vect_index++)
7233     if (vect [vect_index] != undefined_vect_el_value)
7234       {
7235         if (comb_vect_start [comb_vect_index + vect_index]
7236             != undefined_vect_el_value)
7237           abort ();
7238         comb_vect_start [comb_vect_index + vect_index] = vect [vect_index];
7239         if (vect [vect_index] < 0)
7240           abort ();
7241         if (tab->max_comb_vect_el_value < vect [vect_index])
7242           tab->max_comb_vect_el_value = vect [vect_index];
7243         if (tab->min_comb_vect_el_value > vect [vect_index])
7244           tab->min_comb_vect_el_value = vect [vect_index];
7245         check_vect_start [comb_vect_index + vect_index] = vect_num;
7246       }
7247   if (tab->max_base_vect_el_value < comb_vect_index)
7248     tab->max_base_vect_el_value = comb_vect_index;
7249   if (tab->min_base_vect_el_value > comb_vect_index)
7250     tab->min_base_vect_el_value = comb_vect_index;
7251   VLA_HWINT (tab->base_vect, vect_num) = comb_vect_index;
7252 }
7253
7254 /* Return number of out arcs of STATE.  */
7255 static int
7256 out_state_arcs_num (state)
7257      state_t state;
7258 {
7259   int result;
7260   arc_t arc;
7261
7262   result = 0;
7263   for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
7264     {
7265       if (arc->insn == NULL)
7266         abort ();
7267       if (arc->insn->first_ainsn_with_given_equialence_num)
7268         result++;
7269     }
7270   return result;
7271 }
7272
7273 /* Compare number of possible transitions from the states.  */
7274 static int
7275 compare_transition_els_num (state_ptr_1, state_ptr_2)
7276      const void *state_ptr_1;
7277      const void *state_ptr_2;
7278 {
7279   int transition_els_num_1;
7280   int transition_els_num_2;
7281
7282   transition_els_num_1 = out_state_arcs_num (*(state_t *) state_ptr_1);
7283   transition_els_num_2 = out_state_arcs_num (*(state_t *) state_ptr_2);
7284   if (transition_els_num_1 < transition_els_num_2)
7285     return 1;
7286   else if (transition_els_num_1 == transition_els_num_2)
7287     return 0;
7288   else
7289     return -1;
7290 }
7291
7292 /* The function adds element EL_VALUE to vector VECT for a table state
7293    x AINSN.  */
7294 static void
7295 add_vect_el (vect, ainsn, el_value)
7296      vla_hwint_t *vect;
7297      ainsn_t ainsn;
7298      int el_value;
7299 {
7300   int equiv_class_num;
7301   int vect_index;
7302
7303   if (ainsn == NULL)
7304     abort ();
7305   equiv_class_num = ainsn->insn_equiv_class_num;
7306   for (vect_index = VLA_HWINT_LENGTH (*vect);
7307        vect_index <= equiv_class_num;
7308        vect_index++)
7309     VLA_HWINT_ADD (*vect, undefined_vect_el_value);
7310   VLA_HWINT (*vect, equiv_class_num) = el_value;
7311 }
7312
7313 /* This is for forming vector of states of an automaton.  */
7314 static vla_ptr_t output_states_vect;
7315
7316 /* The function is called by function pass_states.  The function adds
7317    STATE to `output_states_vect'.  */
7318 static void
7319 add_states_vect_el (state)
7320      state_t state;
7321 {
7322   VLA_PTR_ADD (output_states_vect, state);
7323 }
7324
7325 /* Form and output vectors (comb, check, base or full vector)
7326    representing transition table of AUTOMATON.  */
7327 static void
7328 output_trans_table (automaton)
7329      automaton_t automaton;
7330 {
7331   state_t *state_ptr;
7332   arc_t arc;
7333   vla_hwint_t transition_vect;
7334
7335   undefined_vect_el_value = automaton->achieved_states_num;
7336   automaton->trans_table = create_state_ainsn_table (automaton);
7337   /* Create vect of pointers to states ordered by num of transitions
7338      from the state (state with the maximum num is the first).  */
7339   VLA_PTR_CREATE (output_states_vect, 1500, "output states vector");
7340   pass_states (automaton, add_states_vect_el);
7341   qsort (VLA_PTR_BEGIN (output_states_vect),
7342          VLA_PTR_LENGTH (output_states_vect),
7343          sizeof (state_t), compare_transition_els_num);
7344   VLA_HWINT_CREATE (transition_vect, 500, "transition vector");
7345   for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
7346        state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
7347        state_ptr++)
7348     {
7349       VLA_HWINT_NULLIFY (transition_vect);
7350       for (arc = first_out_arc (*state_ptr);
7351            arc != NULL;
7352            arc = next_out_arc (arc))
7353         {
7354           if (arc->insn == NULL)
7355             abort ();
7356           if (arc->insn->first_ainsn_with_given_equialence_num)
7357             add_vect_el (&transition_vect, arc->insn,
7358                          arc->to_state->order_state_num);
7359         }
7360       add_vect (automaton->trans_table, (*state_ptr)->order_state_num,
7361                 VLA_HWINT_BEGIN (transition_vect),
7362                 VLA_HWINT_LENGTH (transition_vect));
7363     }
7364   output_state_ainsn_table
7365     (automaton->trans_table, (char *) "state transitions",
7366      output_trans_full_vect_name, output_trans_comb_vect_name,
7367      output_trans_check_vect_name, output_trans_base_vect_name);
7368   VLA_PTR_DELETE (output_states_vect);
7369   VLA_HWINT_DELETE (transition_vect);
7370 }
7371
7372 /* Form and output vectors (comb, check, base or simple vect)
7373    representing alts number table of AUTOMATON.  The table is state x
7374    ainsn -> number of possible alternative reservations by the
7375    ainsn.  */
7376 static void
7377 output_state_alts_table (automaton)
7378      automaton_t automaton;
7379 {
7380   state_t *state_ptr;
7381   arc_t arc;
7382   vla_hwint_t state_alts_vect;
7383
7384   undefined_vect_el_value = 0; /* no alts when transition is not possible */
7385   automaton->state_alts_table = create_state_ainsn_table (automaton);
7386   /* Create vect of pointers to states ordered by num of transitions
7387      from the state (state with the maximum num is the first).  */
7388   VLA_PTR_CREATE (output_states_vect, 1500, "output states vector");
7389   pass_states (automaton, add_states_vect_el);
7390   qsort (VLA_PTR_BEGIN (output_states_vect),
7391          VLA_PTR_LENGTH (output_states_vect),
7392          sizeof (state_t), compare_transition_els_num);
7393   /* Create base, comb, and check vectors.  */
7394   VLA_HWINT_CREATE (state_alts_vect, 500, "state alts vector");
7395   for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
7396        state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
7397        state_ptr++)
7398     {
7399       VLA_HWINT_NULLIFY (state_alts_vect);
7400       for (arc = first_out_arc (*state_ptr);
7401            arc != NULL;
7402            arc = next_out_arc (arc))
7403         {
7404           if (arc->insn == NULL)
7405             abort ();
7406           if (arc->insn->first_ainsn_with_given_equialence_num)
7407             add_vect_el (&state_alts_vect, arc->insn, arc->state_alts);
7408         }
7409       add_vect (automaton->state_alts_table, (*state_ptr)->order_state_num,
7410                 VLA_HWINT_BEGIN (state_alts_vect),
7411                 VLA_HWINT_LENGTH (state_alts_vect));
7412     }
7413   output_state_ainsn_table
7414     (automaton->state_alts_table, (char *) "state insn alternatives",
7415      output_state_alts_full_vect_name, output_state_alts_comb_vect_name,
7416      output_state_alts_check_vect_name, output_state_alts_base_vect_name);
7417   VLA_PTR_DELETE (output_states_vect);
7418   VLA_HWINT_DELETE (state_alts_vect);
7419 }
7420
7421 /* The current number of passing states to find minimal issue delay
7422    value for an ainsn and state.  */
7423 static int curr_state_pass_num;
7424
7425
7426 /* This recursive function passes states to find minimal issue delay
7427    value for AINSN.  The state being visited is STATE.  The function
7428    returns minimal issue delay value for AINSN in STATE or -1 if we
7429    enter into a loop.  */
7430 static int
7431 min_issue_delay_pass_states (state, ainsn)
7432      state_t state;
7433      ainsn_t ainsn;
7434 {
7435   arc_t arc;
7436   int min_insn_issue_delay, insn_issue_delay;
7437
7438   if (state->state_pass_num == curr_state_pass_num
7439       || state->min_insn_issue_delay != -1)
7440     /* We've entered into a loop or already have the correct value for
7441        given state and ainsn.  */
7442     return state->min_insn_issue_delay;
7443   state->state_pass_num = curr_state_pass_num;
7444   min_insn_issue_delay = -1;
7445   for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
7446     if (arc->insn == ainsn)
7447       {
7448         min_insn_issue_delay = 0;
7449         break;
7450       }
7451     else
7452       {
7453         insn_issue_delay = min_issue_delay_pass_states (arc->to_state, ainsn);
7454         if (insn_issue_delay != -1)
7455           {
7456             if (arc->insn->insn_reserv_decl
7457                 == &advance_cycle_insn_decl->decl.insn_reserv)
7458               insn_issue_delay++;
7459             if (min_insn_issue_delay == -1
7460                 || min_insn_issue_delay > insn_issue_delay)
7461               {
7462                 min_insn_issue_delay = insn_issue_delay;
7463                 if (insn_issue_delay == 0)
7464                   break;
7465               }
7466           }
7467       }
7468   return min_insn_issue_delay;
7469 }
7470
7471 /* The function searches minimal issue delay value for AINSN in STATE.
7472    The function can return negative value if we can not issue AINSN.  We
7473    will report about it later.  */
7474 static int
7475 min_issue_delay (state, ainsn)
7476      state_t state;
7477      ainsn_t ainsn;
7478 {
7479   curr_state_pass_num++;
7480   state->min_insn_issue_delay = min_issue_delay_pass_states (state, ainsn);
7481   return state->min_insn_issue_delay;
7482 }
7483
7484 /* The function initiates code for finding minimal issue delay values.
7485    It should be called only once.  */
7486 static void
7487 initiate_min_issue_delay_pass_states ()
7488 {
7489   curr_state_pass_num = 0;
7490 }
7491
7492 /* Form and output vectors representing minimal issue delay table of
7493    AUTOMATON.  The table is state x ainsn -> minimal issue delay of
7494    the ainsn.  */
7495 static void
7496 output_min_issue_delay_table (automaton)
7497      automaton_t automaton;
7498 {
7499   vla_hwint_t min_issue_delay_vect;
7500   vla_hwint_t compressed_min_issue_delay_vect;
7501   vect_el_t min_delay;
7502   ainsn_t ainsn;
7503   state_t *state_ptr;
7504   int i;
7505
7506   /* Create vect of pointers to states ordered by num of transitions
7507      from the state (state with the maximum num is the first).  */
7508   VLA_PTR_CREATE (output_states_vect, 1500, "output states vector");
7509   pass_states (automaton, add_states_vect_el);
7510   VLA_HWINT_CREATE (min_issue_delay_vect, 1500, "min issue delay vector");
7511   VLA_HWINT_EXPAND (min_issue_delay_vect,
7512                     VLA_HWINT_LENGTH (output_states_vect)
7513                     * automaton->insn_equiv_classes_num);
7514   for (i = 0;
7515        i < ((int) VLA_HWINT_LENGTH (output_states_vect)
7516             * automaton->insn_equiv_classes_num);
7517        i++)
7518     VLA_HWINT (min_issue_delay_vect, i) = 0;
7519   automaton->max_min_delay = 0;
7520   for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
7521     if (ainsn->first_ainsn_with_given_equialence_num)
7522       {
7523         for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
7524              state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
7525              state_ptr++)
7526           (*state_ptr)->min_insn_issue_delay = -1;
7527         for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
7528              state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
7529              state_ptr++)
7530           {
7531             min_delay = min_issue_delay (*state_ptr, ainsn);
7532             if (automaton->max_min_delay < min_delay)
7533               automaton->max_min_delay = min_delay;
7534             VLA_HWINT (min_issue_delay_vect,
7535                        (*state_ptr)->order_state_num
7536                        * automaton->insn_equiv_classes_num
7537                        + ainsn->insn_equiv_class_num) = min_delay;
7538           }
7539       }
7540   fprintf (output_file, "/* Vector of min issue delay of insns.*/\n");
7541   fprintf (output_file, "static const ");
7542   output_range_type (output_file, 0, automaton->max_min_delay);
7543   fprintf (output_file, " ");
7544   output_min_issue_delay_vect_name (output_file, automaton);
7545   fprintf (output_file, "[] = {\n");
7546   /* Compress the vector */
7547   if (automaton->max_min_delay < 2)
7548     automaton->min_issue_delay_table_compression_factor = 8;
7549   else if (automaton->max_min_delay < 4)
7550     automaton->min_issue_delay_table_compression_factor = 4;
7551   else if (automaton->max_min_delay < 16)
7552     automaton->min_issue_delay_table_compression_factor = 2;
7553   else
7554     automaton->min_issue_delay_table_compression_factor = 1;
7555   VLA_HWINT_CREATE (compressed_min_issue_delay_vect, 1500,
7556                     "compressed min issue delay vector");
7557   VLA_HWINT_EXPAND (compressed_min_issue_delay_vect,
7558                     (VLA_HWINT_LENGTH (min_issue_delay_vect)
7559                      + automaton->min_issue_delay_table_compression_factor
7560                      - 1)
7561                     / automaton->min_issue_delay_table_compression_factor);
7562   for (i = 0;
7563        i < (int) VLA_HWINT_LENGTH (compressed_min_issue_delay_vect);
7564        i++)
7565     VLA_HWINT (compressed_min_issue_delay_vect, i) = 0;
7566   for (i = 0; i < (int) VLA_HWINT_LENGTH (min_issue_delay_vect); i++)
7567     VLA_HWINT (compressed_min_issue_delay_vect,
7568                i / automaton->min_issue_delay_table_compression_factor)
7569       |= (VLA_HWINT (min_issue_delay_vect, i)
7570           << (8 - (i % automaton->min_issue_delay_table_compression_factor
7571                    + 1)
7572               * (8 / automaton->min_issue_delay_table_compression_factor)));
7573   output_vect (VLA_HWINT_BEGIN (compressed_min_issue_delay_vect),
7574                VLA_HWINT_LENGTH (compressed_min_issue_delay_vect));
7575   fprintf (output_file, "};\n\n");
7576   VLA_PTR_DELETE (output_states_vect);
7577   VLA_HWINT_DELETE (min_issue_delay_vect);
7578   VLA_HWINT_DELETE (compressed_min_issue_delay_vect);
7579 }
7580
7581 #ifndef NDEBUG
7582 /* Number of states which contains transition only by advancing cpu
7583    cycle.  */
7584 static int locked_states_num;
7585 #endif
7586
7587 /* Form and output vector representing the locked states of
7588    AUTOMATON.  */
7589 static void
7590 output_dead_lock_vect (automaton)
7591      automaton_t automaton;
7592 {
7593   state_t *state_ptr;
7594   arc_t arc;
7595   vla_hwint_t dead_lock_vect;
7596
7597   /* Create vect of pointers to states ordered by num of
7598      transitions from the state (state with the maximum num is the
7599      first).  */
7600   VLA_PTR_CREATE (output_states_vect, 1500, "output states vector");
7601   pass_states (automaton, add_states_vect_el);
7602   VLA_HWINT_CREATE (dead_lock_vect, 1500, "is dead locked vector");
7603   VLA_HWINT_EXPAND (dead_lock_vect, VLA_HWINT_LENGTH (output_states_vect));
7604   for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
7605        state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
7606        state_ptr++)
7607     {
7608       arc = first_out_arc (*state_ptr);
7609       if (arc == NULL)
7610         abort ();
7611       VLA_HWINT (dead_lock_vect, (*state_ptr)->order_state_num)
7612         = (next_out_arc (arc) == NULL
7613            && (arc->insn->insn_reserv_decl
7614                == &advance_cycle_insn_decl->decl.insn_reserv) ? 1 : 0);
7615 #ifndef NDEBUG
7616       if (VLA_HWINT (dead_lock_vect, (*state_ptr)->order_state_num))
7617         locked_states_num++;
7618 #endif
7619     }
7620   fprintf (output_file, "/* Vector for locked state flags.  */\n");
7621   fprintf (output_file, "static const ");
7622   output_range_type (output_file, 0, 1);
7623   fprintf (output_file, " ");
7624   output_dead_lock_vect_name (output_file, automaton);
7625   fprintf (output_file, "[] = {\n");
7626   output_vect (VLA_HWINT_BEGIN (dead_lock_vect),
7627                VLA_HWINT_LENGTH (dead_lock_vect));
7628   fprintf (output_file, "};\n\n");
7629   VLA_HWINT_DELETE (dead_lock_vect);
7630   VLA_PTR_DELETE (output_states_vect);
7631 }
7632
7633 /* Form and output vector representing reserved units of the states of
7634    AUTOMATON.  */
7635 static void
7636 output_reserved_units_table (automaton)
7637      automaton_t automaton;
7638 {
7639   state_t *curr_state_ptr;
7640   vla_hwint_t reserved_units_table;
7641   size_t state_byte_size;
7642   int i;
7643
7644   /* Create vect of pointers to states.  */
7645   VLA_PTR_CREATE (output_states_vect, 1500, "output states vector");
7646   pass_states (automaton, add_states_vect_el);
7647   /* Create vector.  */
7648   VLA_HWINT_CREATE (reserved_units_table, 1500, "reserved units vector");
7649   state_byte_size = (description->query_units_num + 7) / 8;
7650   VLA_HWINT_EXPAND (reserved_units_table,
7651                     VLA_HWINT_LENGTH (output_states_vect) * state_byte_size);
7652   for (i = 0;
7653        i < (int) (VLA_HWINT_LENGTH (output_states_vect) * state_byte_size);
7654        i++)
7655     VLA_HWINT (reserved_units_table, i) = 0;
7656   for (curr_state_ptr = VLA_PTR_BEGIN (output_states_vect);
7657        curr_state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
7658        curr_state_ptr++)
7659     {
7660       for (i = 0; i < description->units_num; i++)
7661         if (units_array [i]->query_p)
7662           {
7663             if (test_unit_reserv ((*curr_state_ptr)->reservs, 0, i))
7664               VLA_HWINT (reserved_units_table,
7665                          (*curr_state_ptr)->order_state_num * state_byte_size
7666                          + units_array [i]->query_num / 8)
7667                 += (1 << (units_array [i]->query_num % 8));
7668           }
7669     }
7670   fprintf (output_file, "/* Vector for reserved units of states.  */\n");
7671   fprintf (output_file, "static const ");
7672   output_range_type (output_file, 0, 255);
7673   fprintf (output_file, " ");
7674   output_reserved_units_table_name (output_file, automaton);
7675   fprintf (output_file, "[] = {\n");
7676   output_vect (VLA_HWINT_BEGIN (reserved_units_table),
7677                VLA_HWINT_LENGTH (reserved_units_table));
7678   fprintf (output_file, "};\n\n");
7679   VLA_HWINT_DELETE (reserved_units_table);
7680   VLA_PTR_DELETE (output_states_vect);
7681 }
7682
7683 /* The function outputs all tables representing DFA(s) used for fast
7684    pipeline hazards recognition.  */
7685 static void
7686 output_tables ()
7687 {
7688   automaton_t automaton;
7689
7690 #ifndef NDEBUG
7691   locked_states_num = 0;
7692 #endif
7693   initiate_min_issue_delay_pass_states ();
7694   for (automaton = description->first_automaton;
7695        automaton != NULL;
7696        automaton = automaton->next_automaton)
7697     {
7698       output_translate_vect (automaton);
7699       output_trans_table (automaton);
7700       fprintf (output_file, "\n#if %s\n", AUTOMATON_STATE_ALTS_MACRO_NAME);
7701       output_state_alts_table (automaton);
7702       fprintf (output_file, "\n#endif /* #if %s */\n\n",
7703                AUTOMATON_STATE_ALTS_MACRO_NAME);
7704       output_min_issue_delay_table (automaton);
7705       output_dead_lock_vect (automaton);
7706       if (no_minimization_flag)
7707         {
7708           fprintf (output_file, "\n#if %s\n\n", CPU_UNITS_QUERY_MACRO_NAME);
7709           output_reserved_units_table (automaton);
7710           fprintf (output_file, "\n#endif /* #if %s */\n\n",
7711                    CPU_UNITS_QUERY_MACRO_NAME);
7712         }
7713     }
7714   fprintf (output_file, "\n#define %s %d\n\n", ADVANCE_CYCLE_VALUE_NAME,
7715            advance_cycle_insn_decl->decl.insn_reserv.insn_num);
7716 }
7717
7718 /* The function outputs definition and value of PHR interface variable
7719    `max_insn_queue_index' */
7720 static void
7721 output_max_insn_queue_index_def ()
7722 {
7723   int i;
7724
7725   for (i = 0; (1 << i) <= description->max_insn_reserv_cycles; i++)
7726     ;
7727   if (i < 0)
7728     abort ();
7729   fprintf (output_file, "\nint max_insn_queue_index = %d;\n\n", (1 << i) - 1);
7730 }
7731
7732
7733 /* The function outputs switch cases for insn reseravtions using
7734    function *output_automata_list_code.  */
7735 static void
7736 output_insn_code_cases (output_automata_list_code)
7737      void (*output_automata_list_code) (automata_list_el_t);
7738 {
7739   decl_t decl, decl_2;
7740   int i, j;
7741
7742   for (i = 0; i < description->decls_num; i++)
7743     {
7744       decl = description->decls [i];
7745       if (decl->mode == dm_insn_reserv)
7746         decl->decl.insn_reserv.processed_p = FALSE;
7747     }
7748   for (i = 0; i < description->decls_num; i++)
7749     {
7750       decl = description->decls [i];
7751       if (decl->mode == dm_insn_reserv && !decl->decl.insn_reserv.processed_p)
7752         {
7753           for (j = i; j < description->decls_num; j++)
7754             {
7755               decl_2 = description->decls [j];
7756               if (decl_2->mode == dm_insn_reserv
7757                   && (decl_2->decl.insn_reserv.important_automata_list
7758                       == decl->decl.insn_reserv.important_automata_list))
7759                 {
7760                   decl_2->decl.insn_reserv.processed_p = TRUE;
7761                   fprintf (output_file, "    case %d: /* %s */\n",
7762                            decl_2->decl.insn_reserv.insn_num,
7763                            decl_2->decl.insn_reserv.name);
7764                 }
7765             }
7766           (*output_automata_list_code)
7767             (decl->decl.insn_reserv.important_automata_list);
7768         }
7769     }
7770 }
7771
7772
7773 /* The function outputs a code for evaluation of a minimal delay of
7774    issue of insns which have reservations in given AUTOMATA_LIST.  */
7775 static void
7776 output_automata_list_min_issue_delay_code (automata_list)
7777      automata_list_el_t automata_list;
7778 {
7779   automata_list_el_t el;
7780   automaton_t automaton;
7781
7782   for (el = automata_list; el != NULL; el = el->next_automata_list_el)
7783     {
7784       automaton = el->automaton;
7785       fprintf (output_file, "\n      %s = ", TEMPORARY_VARIABLE_NAME);
7786       output_min_issue_delay_vect_name (output_file, automaton);
7787       fprintf (output_file,
7788                (automaton->min_issue_delay_table_compression_factor != 1
7789                 ? " [(" : " ["));
7790       output_translate_vect_name (output_file, automaton);
7791       fprintf (output_file, " [%s] + ", INTERNAL_INSN_CODE_NAME);
7792       fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
7793       output_chip_member_name (output_file, automaton);
7794       fprintf (output_file, " * %d", automaton->insn_equiv_classes_num);
7795       if (automaton->min_issue_delay_table_compression_factor == 1)
7796         fprintf (output_file, "];\n");
7797       else
7798         {
7799           fprintf (output_file, ") / %d];\n",
7800                    automaton->min_issue_delay_table_compression_factor);
7801           fprintf (output_file, "      %s = (%s >> (8 - (",
7802                    TEMPORARY_VARIABLE_NAME, TEMPORARY_VARIABLE_NAME);
7803           output_translate_vect_name (output_file, automaton);
7804           fprintf
7805             (output_file, " [%s] %% %d + 1) * %d)) & %d;\n",
7806              INTERNAL_INSN_CODE_NAME,
7807              automaton->min_issue_delay_table_compression_factor,
7808              8 / automaton->min_issue_delay_table_compression_factor,
7809              (1 << (8 / automaton->min_issue_delay_table_compression_factor))
7810              - 1);
7811         }
7812       if (el == automata_list)
7813         fprintf (output_file, "      %s = %s;\n",
7814                  RESULT_VARIABLE_NAME, TEMPORARY_VARIABLE_NAME);
7815       else
7816         {
7817           fprintf (output_file, "      if (%s > %s)\n",
7818                    TEMPORARY_VARIABLE_NAME, RESULT_VARIABLE_NAME);
7819           fprintf (output_file, "        %s = %s;\n",
7820                    RESULT_VARIABLE_NAME, TEMPORARY_VARIABLE_NAME);
7821         }
7822     }
7823   fprintf (output_file, "      break;\n\n");
7824 }
7825
7826 /* Output function `internal_min_issue_delay'.  */
7827 static void
7828 output_internal_min_issue_delay_func ()
7829 {
7830   fprintf (output_file, "static int %s PARAMS ((int, struct %s *));\n",
7831            INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, CHIP_NAME);
7832   fprintf (output_file,
7833            "static int\n%s (%s, %s)\n\tint %s;\n\tstruct %s *%s  ATTRIBUTE_UNUSED;\n",
7834            INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
7835            CHIP_PARAMETER_NAME, INTERNAL_INSN_CODE_NAME, CHIP_NAME,
7836            CHIP_PARAMETER_NAME);
7837   fprintf (output_file, "{\n  int %s ATTRIBUTE_UNUSED;\n  int %s;\n",
7838            TEMPORARY_VARIABLE_NAME, RESULT_VARIABLE_NAME);
7839   fprintf (output_file, "\n  switch (%s)\n    {\n", INTERNAL_INSN_CODE_NAME);
7840   output_insn_code_cases (output_automata_list_min_issue_delay_code);
7841   fprintf (output_file,
7842            "\n    default:\n      %s = -1;\n      break;\n    }\n",
7843            RESULT_VARIABLE_NAME);
7844   fprintf (output_file, "  return %s;\n", RESULT_VARIABLE_NAME);
7845   fprintf (output_file, "}\n\n");
7846 }
7847
7848 /* The function outputs a code changing state after issue of insns
7849    which have reservations in given AUTOMATA_LIST.  */
7850 static void
7851 output_automata_list_transition_code (automata_list)
7852      automata_list_el_t automata_list;
7853 {
7854   automata_list_el_t el, next_el;
7855
7856   fprintf (output_file, "      {\n");
7857   if (automata_list != NULL && automata_list->next_automata_list_el != NULL)
7858     for (el = automata_list;; el = next_el)
7859       {
7860         next_el = el->next_automata_list_el;
7861         if (next_el == NULL)
7862           break;
7863         fprintf (output_file, "        ");
7864         output_state_member_type (output_file, el->automaton);
7865         fprintf (output_file, " ");
7866         output_temp_chip_member_name (output_file, el->automaton);
7867         fprintf (output_file, ";\n");
7868       }
7869   for (el = automata_list; el != NULL; el = el->next_automata_list_el)
7870     if (comb_vect_p (el->automaton->trans_table))
7871       {
7872         fprintf (output_file, "\n        %s = ", TEMPORARY_VARIABLE_NAME);
7873         output_trans_base_vect_name (output_file, el->automaton);
7874         fprintf (output_file, " [%s->", CHIP_PARAMETER_NAME);
7875         output_chip_member_name (output_file, el->automaton);
7876         fprintf (output_file, "] + ");
7877         output_translate_vect_name (output_file, el->automaton);
7878         fprintf (output_file, " [%s];\n", INTERNAL_INSN_CODE_NAME);
7879         fprintf (output_file, "        if (");
7880         output_trans_check_vect_name (output_file, el->automaton);
7881         fprintf (output_file, " [%s] != %s->",
7882                  TEMPORARY_VARIABLE_NAME, CHIP_PARAMETER_NAME);
7883         output_chip_member_name (output_file, el->automaton);
7884         fprintf (output_file, ")\n");
7885         fprintf (output_file, "          return %s (%s, %s);\n",
7886                  INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
7887                  CHIP_PARAMETER_NAME);
7888         fprintf (output_file, "        else\n");
7889         fprintf (output_file, "          ");
7890         if (el->next_automata_list_el != NULL)
7891           output_temp_chip_member_name (output_file, el->automaton);
7892         else
7893           {
7894             fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
7895             output_chip_member_name (output_file, el->automaton);
7896           }
7897         fprintf (output_file, " = ");
7898         output_trans_comb_vect_name (output_file, el->automaton);
7899         fprintf (output_file, " [%s];\n", TEMPORARY_VARIABLE_NAME);
7900       }
7901     else
7902       {
7903         fprintf (output_file, "\n        %s = ", TEMPORARY_VARIABLE_NAME);
7904         output_trans_full_vect_name (output_file, el->automaton);
7905         fprintf (output_file, " [");
7906         output_translate_vect_name (output_file, el->automaton);
7907         fprintf (output_file, " [%s] + ", INTERNAL_INSN_CODE_NAME);
7908         fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
7909         output_chip_member_name (output_file, el->automaton);
7910         fprintf (output_file, " * %d];\n",
7911                  el->automaton->insn_equiv_classes_num);
7912         fprintf (output_file, "        if (%s >= %d)\n",
7913                  TEMPORARY_VARIABLE_NAME, el->automaton->achieved_states_num);
7914         fprintf (output_file, "          return %s (%s, %s);\n",
7915                  INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
7916                  CHIP_PARAMETER_NAME);
7917         fprintf (output_file, "        else\n          ");
7918         if (el->next_automata_list_el != NULL)
7919           output_temp_chip_member_name (output_file, el->automaton);
7920         else
7921           {
7922             fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
7923             output_chip_member_name (output_file, el->automaton);
7924           }
7925         fprintf (output_file, " = %s;\n", TEMPORARY_VARIABLE_NAME);
7926       }
7927   if (automata_list != NULL && automata_list->next_automata_list_el != NULL)
7928     for (el = automata_list;; el = next_el)
7929       {
7930         next_el = el->next_automata_list_el;
7931         if (next_el == NULL)
7932           break;
7933         fprintf (output_file, "        %s->", CHIP_PARAMETER_NAME);
7934         output_chip_member_name (output_file, el->automaton);
7935         fprintf (output_file, " = ");
7936         output_temp_chip_member_name (output_file, el->automaton);
7937         fprintf (output_file, ";\n");
7938       }
7939   fprintf (output_file, "        return -1;\n");
7940   fprintf (output_file, "      }\n");
7941 }
7942
7943 /* Output function `internal_state_transition'.  */
7944 static void
7945 output_internal_trans_func ()
7946 {
7947   fprintf (output_file, "static int %s PARAMS ((int, struct %s *));\n",
7948            INTERNAL_TRANSITION_FUNC_NAME, CHIP_NAME);
7949   fprintf (output_file,
7950            "static int\n%s (%s, %s)\n\tint %s;\n\tstruct %s *%s  ATTRIBUTE_UNUSED;\n",
7951            INTERNAL_TRANSITION_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
7952            CHIP_PARAMETER_NAME, INTERNAL_INSN_CODE_NAME,
7953            CHIP_NAME, CHIP_PARAMETER_NAME);
7954   fprintf (output_file, "{\n  int %s ATTRIBUTE_UNUSED;\n", TEMPORARY_VARIABLE_NAME);
7955   fprintf (output_file, "\n  switch (%s)\n    {\n", INTERNAL_INSN_CODE_NAME);
7956   output_insn_code_cases (output_automata_list_transition_code);
7957   fprintf (output_file, "\n    default:\n      return -1;\n    }\n");
7958   fprintf (output_file, "}\n\n");
7959 }
7960
7961 /* Output code
7962
7963   if (insn != 0)
7964     {
7965       insn_code = dfa_insn_code (insn);
7966       if (insn_code > DFA__ADVANCE_CYCLE)
7967         return code;
7968     }
7969   else
7970     insn_code = DFA__ADVANCE_CYCLE;
7971
7972   where insn denotes INSN_NAME, insn_code denotes INSN_CODE_NAME, and
7973   code denotes CODE.  */
7974 static void
7975 output_internal_insn_code_evaluation (insn_name, insn_code_name, code)
7976      const char *insn_name;
7977      const char *insn_code_name;
7978      int code;
7979 {
7980   fprintf (output_file, "\n  if (%s != 0)\n    {\n", insn_name);
7981   fprintf (output_file, "      %s = %s (%s);\n", insn_code_name,
7982            DFA_INSN_CODE_FUNC_NAME, insn_name);
7983   fprintf (output_file, "      if (%s > %s)\n        return %d;\n",
7984            insn_code_name, ADVANCE_CYCLE_VALUE_NAME, code);
7985   fprintf (output_file, "    }\n  else\n    %s = %s;\n\n",
7986            insn_code_name, ADVANCE_CYCLE_VALUE_NAME);
7987 }
7988
7989
7990 /* The function outputs function `dfa_insn_code'.  */
7991 static void
7992 output_dfa_insn_code_func ()
7993 {
7994   fprintf (output_file, "#ifdef __GNUC__\n__inline__\n#endif\n");
7995   fprintf (output_file, "static int %s PARAMS ((rtx));\n",
7996            DFA_INSN_CODE_FUNC_NAME);
7997   fprintf (output_file, "static int\n%s (%s)\n\trtx %s;\n",
7998            DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME, INSN_PARAMETER_NAME);
7999   fprintf (output_file, "{\n  int %s;\n  int %s;\n\n",
8000            INTERNAL_INSN_CODE_NAME, TEMPORARY_VARIABLE_NAME);
8001   fprintf (output_file, "  if (INSN_UID (%s) >= %s)\n    {\n",
8002            INSN_PARAMETER_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
8003   fprintf (output_file, "      %s = %s;\n      %s = 2 * INSN_UID (%s);\n",
8004            TEMPORARY_VARIABLE_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
8005            DFA_INSN_CODES_LENGTH_VARIABLE_NAME, INSN_PARAMETER_NAME);
8006   fprintf (output_file, "      %s = xrealloc (%s, %s * sizeof (int));\n",
8007            DFA_INSN_CODES_VARIABLE_NAME, DFA_INSN_CODES_VARIABLE_NAME,
8008            DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
8009   fprintf (output_file,
8010            "      for (; %s < %s; %s++)\n        %s [%s] = -1;\n    }\n",
8011            TEMPORARY_VARIABLE_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
8012            TEMPORARY_VARIABLE_NAME, DFA_INSN_CODES_VARIABLE_NAME,
8013            TEMPORARY_VARIABLE_NAME);
8014   fprintf (output_file, "  if ((%s = %s [INSN_UID (%s)]) < 0)\n    {\n",
8015            INTERNAL_INSN_CODE_NAME, DFA_INSN_CODES_VARIABLE_NAME,
8016            INSN_PARAMETER_NAME);
8017   fprintf (output_file, "      %s = %s (%s);\n", INTERNAL_INSN_CODE_NAME,
8018            INTERNAL_DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME);
8019   fprintf (output_file, "      %s [INSN_UID (%s)] = %s;\n",
8020            DFA_INSN_CODES_VARIABLE_NAME, INSN_PARAMETER_NAME,
8021            INTERNAL_INSN_CODE_NAME);
8022   fprintf (output_file, "    }\n  return %s;\n}\n\n",
8023            INTERNAL_INSN_CODE_NAME);
8024 }
8025
8026 /* The function outputs PHR interface function `state_transition'.  */
8027 static void
8028 output_trans_func ()
8029 {
8030   fprintf (output_file, "int\n%s (%s, %s)\n\t%s %s;\n\trtx %s;\n",
8031            TRANSITION_FUNC_NAME, STATE_NAME, INSN_PARAMETER_NAME,
8032            STATE_TYPE_NAME, STATE_NAME, INSN_PARAMETER_NAME);
8033   fprintf (output_file, "{\n  int %s;\n", INTERNAL_INSN_CODE_NAME);
8034   output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
8035                                         INTERNAL_INSN_CODE_NAME, -1);
8036   fprintf (output_file, "  return %s (%s, %s);\n}\n\n",
8037            INTERNAL_TRANSITION_FUNC_NAME, INTERNAL_INSN_CODE_NAME, STATE_NAME);
8038 }
8039
8040 /* The function outputs a code for evaluation of alternative states
8041    number for insns which have reservations in given AUTOMATA_LIST.  */
8042 static void
8043 output_automata_list_state_alts_code (automata_list)
8044      automata_list_el_t automata_list;
8045 {
8046   automata_list_el_t el;
8047   automaton_t automaton;
8048
8049   fprintf (output_file, "      {\n");
8050   for (el = automata_list; el != NULL; el = el->next_automata_list_el)
8051     if (comb_vect_p (el->automaton->state_alts_table))
8052       {
8053         fprintf (output_file, "        int %s;\n", TEMPORARY_VARIABLE_NAME);
8054         break;
8055       }
8056   for (el = automata_list; el != NULL; el = el->next_automata_list_el)
8057     {
8058       automaton = el->automaton;
8059       if (comb_vect_p (automaton->state_alts_table))
8060         {
8061           fprintf (output_file, "\n        %s = ", TEMPORARY_VARIABLE_NAME);
8062           output_state_alts_base_vect_name (output_file, automaton);
8063           fprintf (output_file, " [%s->", CHIP_PARAMETER_NAME);
8064           output_chip_member_name (output_file, automaton);
8065           fprintf (output_file, "] + ");
8066           output_translate_vect_name (output_file, automaton);
8067           fprintf (output_file, " [%s];\n", INTERNAL_INSN_CODE_NAME);
8068           fprintf (output_file, "        if (");
8069           output_state_alts_check_vect_name (output_file, automaton);
8070           fprintf (output_file, " [%s] != %s->",
8071                    TEMPORARY_VARIABLE_NAME, CHIP_PARAMETER_NAME);
8072           output_chip_member_name (output_file, automaton);
8073           fprintf (output_file, ")\n");
8074           fprintf (output_file, "          return 0;\n");
8075           fprintf (output_file, "        else\n");
8076           fprintf (output_file,
8077                    (el == automata_list
8078                     ? "          %s = " : "          %s += "),
8079                    RESULT_VARIABLE_NAME);
8080           output_state_alts_comb_vect_name (output_file, automaton);
8081           fprintf (output_file, " [%s];\n", TEMPORARY_VARIABLE_NAME);
8082         }
8083       else
8084         {
8085           fprintf (output_file,
8086                    (el == automata_list
8087                     ? "\n        %s = " : "        %s += "),
8088                    RESULT_VARIABLE_NAME);
8089           output_state_alts_full_vect_name (output_file, automaton);
8090           fprintf (output_file, " [");
8091           output_translate_vect_name (output_file, automaton);
8092           fprintf (output_file, " [%s] + ", INTERNAL_INSN_CODE_NAME);
8093           fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
8094           output_chip_member_name (output_file, automaton);
8095           fprintf (output_file, " * %d];\n",
8096                    automaton->insn_equiv_classes_num);
8097         }
8098     }
8099   fprintf (output_file, "        break;\n      }\n\n");
8100 }
8101
8102 /* Output function `internal_state_alts'.  */
8103 static void
8104 output_internal_state_alts_func ()
8105 {
8106   fprintf (output_file, "static int %s PARAMS ((int, struct %s *));\n",
8107            INTERNAL_STATE_ALTS_FUNC_NAME, CHIP_NAME);
8108   fprintf (output_file,
8109            "static int\n%s (%s, %s)\n\tint %s;\n\tstruct %s *%s;\n",
8110            INTERNAL_STATE_ALTS_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8111            CHIP_PARAMETER_NAME, INTERNAL_INSN_CODE_NAME, CHIP_NAME,
8112            CHIP_PARAMETER_NAME);
8113   fprintf (output_file, "{\n  int %s;\n", RESULT_VARIABLE_NAME);
8114   fprintf (output_file, "\n  switch (%s)\n    {\n", INTERNAL_INSN_CODE_NAME);
8115   output_insn_code_cases (output_automata_list_state_alts_code);
8116   fprintf (output_file,
8117            "\n    default:\n      %s = 0;\n      break;\n    }\n",
8118            RESULT_VARIABLE_NAME);
8119   fprintf (output_file, "  return %s;\n", RESULT_VARIABLE_NAME);
8120   fprintf (output_file, "}\n\n");
8121 }
8122
8123 /* The function outputs PHR interface function `state_alts'.  */
8124 static void
8125 output_state_alts_func ()
8126 {
8127   fprintf (output_file, "int\n%s (%s, %s)\n\t%s %s;\n\trtx %s;\n",
8128            STATE_ALTS_FUNC_NAME, STATE_NAME, INSN_PARAMETER_NAME,
8129            STATE_TYPE_NAME, STATE_NAME, INSN_PARAMETER_NAME);
8130   fprintf (output_file, "{\n  int %s;\n", INTERNAL_INSN_CODE_NAME);
8131   output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
8132                                         INTERNAL_INSN_CODE_NAME, 0);
8133   fprintf (output_file, "  return %s (%s, %s);\n}\n\n",
8134            INTERNAL_STATE_ALTS_FUNC_NAME, INTERNAL_INSN_CODE_NAME, STATE_NAME);
8135 }
8136
8137 /* Output function `min_issue_delay'.  */
8138 static void
8139 output_min_issue_delay_func ()
8140 {
8141   fprintf (output_file, "int\n%s (%s, %s)\n\t%s %s;\n\trtx %s;\n",
8142            MIN_ISSUE_DELAY_FUNC_NAME, STATE_NAME, INSN_PARAMETER_NAME,
8143            STATE_TYPE_NAME, STATE_NAME, INSN_PARAMETER_NAME);
8144   fprintf (output_file, "{\n  int %s;\n", INTERNAL_INSN_CODE_NAME);
8145   fprintf (output_file, "\n  if (%s != 0)\n    {\n", INSN_PARAMETER_NAME);
8146   fprintf (output_file, "      %s = %s (%s);\n", INTERNAL_INSN_CODE_NAME,
8147            DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME);
8148   fprintf (output_file, "      if (%s > %s)\n        return 0;\n",
8149            INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8150   fprintf (output_file, "    }\n  else\n    %s = %s;\n",
8151            INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8152   fprintf (output_file, "\n  return %s (%s, %s);\n",
8153            INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8154            STATE_NAME);
8155   fprintf (output_file, "}\n\n");
8156 }
8157
8158 /* Output function `internal_dead_lock'.  */
8159 static void
8160 output_internal_dead_lock_func ()
8161 {
8162   automaton_t automaton;
8163
8164   fprintf (output_file, "static int %s PARAMS ((struct %s *));\n",
8165            INTERNAL_DEAD_LOCK_FUNC_NAME, CHIP_NAME);
8166   fprintf (output_file, "static int\n%s (%s)\n\tstruct %s *%s;\n",
8167            INTERNAL_DEAD_LOCK_FUNC_NAME, CHIP_PARAMETER_NAME, CHIP_NAME,
8168            CHIP_PARAMETER_NAME);
8169   fprintf (output_file, "{\n");
8170   for (automaton = description->first_automaton;
8171        automaton != NULL;
8172        automaton = automaton->next_automaton)
8173     {
8174       fprintf (output_file, "  if (");
8175       output_dead_lock_vect_name (output_file, automaton);
8176       fprintf (output_file, " [%s->", CHIP_PARAMETER_NAME);
8177       output_chip_member_name (output_file, automaton);
8178       fprintf (output_file, "])\n    return 1/* TRUE */;\n");
8179     }
8180   fprintf (output_file, "  return 0/* FALSE */;\n}\n\n");
8181 }
8182
8183 /* The function outputs PHR interface function `state_dead_lock_p'.  */
8184 static void
8185 output_dead_lock_func ()
8186 {
8187   fprintf (output_file, "int\n%s (%s)\n\t%s %s;\n",
8188            DEAD_LOCK_FUNC_NAME, STATE_NAME, STATE_TYPE_NAME, STATE_NAME);
8189   fprintf (output_file, "{\n  return %s (%s);\n}\n\n",
8190            INTERNAL_DEAD_LOCK_FUNC_NAME, STATE_NAME);
8191 }
8192
8193 /* Output function `internal_reset'.  */
8194 static void
8195 output_internal_reset_func ()
8196 {
8197   fprintf (output_file, "static void %s PARAMS ((struct %s *));\n",
8198            INTERNAL_RESET_FUNC_NAME, CHIP_NAME);
8199   fprintf (output_file, "static void\n%s (%s)\n\tstruct %s *%s;\n",
8200            INTERNAL_RESET_FUNC_NAME, CHIP_PARAMETER_NAME,
8201            CHIP_NAME, CHIP_PARAMETER_NAME);
8202   fprintf (output_file, "{\n  memset (%s, 0, sizeof (struct %s));\n}\n\n",
8203            CHIP_PARAMETER_NAME, CHIP_NAME);
8204 }
8205
8206 /* The function outputs PHR interface function `state_size'.  */
8207 static void
8208 output_size_func ()
8209 {
8210   fprintf (output_file, "int\n%s ()\n", SIZE_FUNC_NAME);
8211   fprintf (output_file, "{\n  return sizeof (struct %s);\n}\n\n", CHIP_NAME);
8212 }
8213
8214 /* The function outputs PHR interface function `state_reset'.  */
8215 static void
8216 output_reset_func ()
8217 {
8218   fprintf (output_file, "void\n%s (%s)\n\t %s %s;\n",
8219            RESET_FUNC_NAME, STATE_NAME, STATE_TYPE_NAME, STATE_NAME);
8220   fprintf (output_file, "{\n  %s (%s);\n}\n\n", INTERNAL_RESET_FUNC_NAME,
8221            STATE_NAME);
8222 }
8223
8224 /* Output function `min_insn_conflict_delay'.  */
8225 static void
8226 output_min_insn_conflict_delay_func ()
8227 {
8228   fprintf (output_file,
8229            "int\n%s (%s, %s, %s)\n\t%s %s;\n\trtx %s;\n\trtx %s;\n",
8230            MIN_INSN_CONFLICT_DELAY_FUNC_NAME,
8231            STATE_NAME, INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME,
8232            STATE_TYPE_NAME, STATE_NAME,
8233            INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
8234   fprintf (output_file, "{\n  struct %s %s;\n  int %s, %s;\n",
8235            CHIP_NAME, CHIP_NAME, INTERNAL_INSN_CODE_NAME,
8236            INTERNAL_INSN2_CODE_NAME);
8237   output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
8238                                         INTERNAL_INSN_CODE_NAME, 0);
8239   output_internal_insn_code_evaluation (INSN2_PARAMETER_NAME,
8240                                         INTERNAL_INSN2_CODE_NAME, 0);
8241   fprintf (output_file, "  memcpy (&%s, %s, sizeof (%s));\n",
8242            CHIP_NAME, STATE_NAME, CHIP_NAME);
8243   fprintf (output_file, "  %s (&%s);\n", INTERNAL_RESET_FUNC_NAME, CHIP_NAME);
8244   fprintf (output_file, "  if (%s (%s, &%s) > 0)\n    abort ();\n",
8245            INTERNAL_TRANSITION_FUNC_NAME, INTERNAL_INSN_CODE_NAME, CHIP_NAME);
8246   fprintf (output_file, "  return %s (%s, &%s);\n",
8247            INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN2_CODE_NAME,
8248            CHIP_NAME);
8249   fprintf (output_file, "}\n\n");
8250 }
8251
8252 /* Output function `internal_insn_latency'.  */
8253 static void
8254 output_internal_insn_latency_func ()
8255 {
8256   decl_t decl;
8257   struct bypass_decl *bypass;
8258   int i;
8259
8260   fprintf (output_file, "static int %s PARAMS ((int, int, rtx, rtx));\n",
8261            INTERNAL_INSN_LATENCY_FUNC_NAME);
8262   fprintf (output_file, "static int\n%s (%s, %s, %s, %s)",
8263            INTERNAL_INSN_LATENCY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8264            INTERNAL_INSN2_CODE_NAME, INSN_PARAMETER_NAME,
8265            INSN2_PARAMETER_NAME);
8266   fprintf (output_file, "\n\tint %s;\n\tint %s;\n",
8267            INTERNAL_INSN_CODE_NAME, INTERNAL_INSN2_CODE_NAME);
8268   fprintf (output_file,
8269            "\trtx %s ATTRIBUTE_UNUSED;\n\trtx %s ATTRIBUTE_UNUSED;\n",
8270            INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
8271   fprintf (output_file, "{\n  switch (%s)\n    {\n", INTERNAL_INSN_CODE_NAME);
8272   for (i = 0; i < description->decls_num; i++)
8273     {
8274       decl = description->decls [i];
8275       if (decl->mode == dm_insn_reserv)
8276         {
8277           fprintf (output_file, "    case %d:\n",
8278                    decl->decl.insn_reserv.insn_num);
8279           if (decl->decl.insn_reserv.bypass_list == NULL)
8280             fprintf (output_file, "      return (%s != %s ? %d : 0);\n",
8281                      INTERNAL_INSN2_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME,
8282                      decl->decl.insn_reserv.default_latency);
8283           else
8284             {
8285               fprintf (output_file, "      switch (%s)\n        {\n",
8286                        INTERNAL_INSN2_CODE_NAME);
8287               for (bypass = decl->decl.insn_reserv.bypass_list;
8288                    bypass != NULL;
8289                    bypass = bypass->next)
8290                 {
8291                   fprintf (output_file, "        case %d:\n",
8292                            bypass->in_insn_reserv->insn_num);
8293                   if (bypass->bypass_guard_name == NULL)
8294                     fprintf (output_file, "          return %d;\n",
8295                              bypass->latency);
8296                   else
8297                     fprintf (output_file,
8298                              "          return (%s (%s, %s) ? %d : %d);\n",
8299                              bypass->bypass_guard_name, INSN_PARAMETER_NAME,
8300                              INSN2_PARAMETER_NAME, bypass->latency,
8301                              decl->decl.insn_reserv.default_latency);
8302                 }
8303               fprintf (output_file, "        default:\n");
8304               fprintf (output_file,
8305                        "          return (%s != %s ? %d : 0);\n        }\n",
8306                        INTERNAL_INSN2_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME,
8307                        decl->decl.insn_reserv.default_latency);
8308               
8309             }
8310         }
8311     }
8312   fprintf (output_file, "    default:\n      return 0;\n    }\n}\n\n");
8313 }
8314
8315 /* The function outputs PHR interface function `insn_latency'.  */
8316 static void
8317 output_insn_latency_func ()
8318 {
8319   fprintf (output_file, "int\n%s (%s, %s)\n\trtx %s;\n\trtx %s;\n",
8320            INSN_LATENCY_FUNC_NAME, INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME,
8321            INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
8322   fprintf (output_file, "{\n  int %s, %s;\n",
8323            INTERNAL_INSN_CODE_NAME, INTERNAL_INSN2_CODE_NAME);
8324   output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
8325                                         INTERNAL_INSN_CODE_NAME, 0);
8326   output_internal_insn_code_evaluation (INSN2_PARAMETER_NAME,
8327                                         INTERNAL_INSN2_CODE_NAME, 0);
8328   fprintf (output_file, "  return %s (%s, %s, %s, %s);\n}\n\n",
8329            INTERNAL_INSN_LATENCY_FUNC_NAME,
8330            INTERNAL_INSN_CODE_NAME, INTERNAL_INSN2_CODE_NAME,
8331            INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
8332 }
8333
8334 /* The function outputs PHR interface function `print_reservation'.  */
8335 static void
8336 output_print_reservation_func ()
8337 {
8338   decl_t decl;
8339   int i;
8340
8341   fprintf (output_file, "void\n%s (%s, %s)\n\tFILE *%s;\n\trtx %s;\n",
8342            PRINT_RESERVATION_FUNC_NAME, FILE_PARAMETER_NAME,
8343            INSN_PARAMETER_NAME, FILE_PARAMETER_NAME,
8344            INSN_PARAMETER_NAME);
8345   fprintf (output_file, "{\n  int %s;\n", INTERNAL_INSN_CODE_NAME);
8346   fprintf (output_file, "\n  if (%s != 0)\n    {\n", INSN_PARAMETER_NAME);
8347   fprintf (output_file, "      %s = %s (%s);\n",
8348            INTERNAL_INSN_CODE_NAME, DFA_INSN_CODE_FUNC_NAME,
8349            INSN_PARAMETER_NAME);
8350   fprintf (output_file, "      if (%s > %s)\n",
8351            INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8352   fprintf (output_file, "        {\n          fprintf (%s, \"%s\");\n",
8353            FILE_PARAMETER_NAME, NOTHING_NAME);
8354   fprintf (output_file, "          return;\n        }\n");
8355   fprintf (output_file, "    }\n  else\n");
8356   fprintf (output_file,
8357            "    {\n      fprintf (%s, \"%s\");\n      return;\n    }\n",
8358            FILE_PARAMETER_NAME, NOTHING_NAME);
8359   fprintf (output_file, "  switch (%s)\n    {\n", INTERNAL_INSN_CODE_NAME);
8360   for (i = 0; i < description->decls_num; i++)
8361     {
8362       decl = description->decls [i];
8363       if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
8364         {
8365           fprintf (output_file,
8366                    "    case %d:\n", decl->decl.insn_reserv.insn_num);
8367           fprintf (output_file,
8368                    "      fprintf (%s, \"%s\");\n      break;\n",
8369                    FILE_PARAMETER_NAME,
8370                    regexp_representation (decl->decl.insn_reserv.regexp));
8371           finish_regexp_representation ();
8372         }
8373     }
8374   fprintf (output_file, "    default:\n      fprintf (%s, \"%s\");\n    }\n",
8375            FILE_PARAMETER_NAME, NOTHING_NAME);
8376   fprintf (output_file, "}\n\n");
8377 }
8378
8379 /* The following function is used to sort unit declaration by their
8380    names.  */
8381 static int
8382 units_cmp (unit1, unit2)
8383      const void *unit1, *unit2;
8384 {
8385   const unit_decl_t u1 = *(unit_decl_t *) unit1;
8386   const unit_decl_t u2 = *(unit_decl_t *) unit2;
8387
8388   return strcmp (u1->name, u2->name);
8389 }
8390
8391 /* The following macro value is name of struct containing unit name
8392    and unit code.  */
8393 #define NAME_CODE_STRUCT_NAME  "name_code"
8394
8395 /* The following macro value is name of table of struct name_code.  */
8396 #define NAME_CODE_TABLE_NAME   "name_code_table"
8397
8398 /* The following macro values are member names for struct name_code.  */
8399 #define NAME_MEMBER_NAME       "name"
8400 #define CODE_MEMBER_NAME       "code"
8401
8402 /* The following macro values are local variable names for function
8403    `get_cpu_unit_code'.  */
8404 #define CMP_VARIABLE_NAME      "cmp"
8405 #define LOW_VARIABLE_NAME      "l"
8406 #define MIDDLE_VARIABLE_NAME   "m"
8407 #define HIGH_VARIABLE_NAME     "h"
8408
8409 /* The following function outputs function to obtain internal cpu unit
8410    code by the cpu unit name.  */
8411 static void
8412 output_get_cpu_unit_code_func ()
8413 {
8414   int i;
8415   unit_decl_t *units;
8416   
8417   fprintf (output_file, "int\n%s (%s)\n\tconst char *%s;\n",
8418            GET_CPU_UNIT_CODE_FUNC_NAME, CPU_UNIT_NAME_PARAMETER_NAME,
8419            CPU_UNIT_NAME_PARAMETER_NAME);
8420   fprintf (output_file, "{\n  struct %s {const char *%s; int %s;};\n",
8421            NAME_CODE_STRUCT_NAME, NAME_MEMBER_NAME, CODE_MEMBER_NAME);
8422   fprintf (output_file, "  int %s, %s, %s, %s;\n", CMP_VARIABLE_NAME,
8423            LOW_VARIABLE_NAME, MIDDLE_VARIABLE_NAME, HIGH_VARIABLE_NAME);
8424   fprintf (output_file, "  static struct %s %s [] =\n    {\n",
8425            NAME_CODE_STRUCT_NAME, NAME_CODE_TABLE_NAME);
8426   units = (unit_decl_t *) xmalloc (sizeof (unit_decl_t)
8427                                    * description->units_num);
8428   memcpy (units, units_array, sizeof (unit_decl_t) * description->units_num);
8429   qsort (units, description->units_num, sizeof (unit_decl_t), units_cmp);
8430   for (i = 0; i < description->units_num; i++)
8431     if (units [i]->query_p)
8432       fprintf (output_file, "      {\"%s\", %d},\n",
8433                units[i]->name, units[i]->query_num);
8434   fprintf (output_file, "    };\n\n");
8435   fprintf (output_file, "  /* The following is binary search: */\n");
8436   fprintf (output_file, "  %s = 0;\n", LOW_VARIABLE_NAME);
8437   fprintf (output_file, "  %s = sizeof (%s) / sizeof (struct %s) - 1;\n",
8438            HIGH_VARIABLE_NAME, NAME_CODE_TABLE_NAME, NAME_CODE_STRUCT_NAME);
8439   fprintf (output_file, "  while (%s <= %s)\n    {\n",
8440            LOW_VARIABLE_NAME, HIGH_VARIABLE_NAME);
8441   fprintf (output_file, "      %s = (%s + %s) / 2;\n",
8442            MIDDLE_VARIABLE_NAME, LOW_VARIABLE_NAME, HIGH_VARIABLE_NAME);
8443   fprintf (output_file, "      %s = strcmp (%s, %s [%s].%s);\n",
8444            CMP_VARIABLE_NAME, CPU_UNIT_NAME_PARAMETER_NAME,
8445            NAME_CODE_TABLE_NAME, MIDDLE_VARIABLE_NAME, NAME_MEMBER_NAME);
8446   fprintf (output_file, "      if (%s < 0)\n", CMP_VARIABLE_NAME);
8447   fprintf (output_file, "        %s = %s - 1;\n",
8448            HIGH_VARIABLE_NAME, MIDDLE_VARIABLE_NAME);
8449   fprintf (output_file, "      else if (%s > 0)\n", CMP_VARIABLE_NAME);
8450   fprintf (output_file, "        %s = %s + 1;\n",
8451            LOW_VARIABLE_NAME, MIDDLE_VARIABLE_NAME);
8452   fprintf (output_file, "      else\n");
8453   fprintf (output_file, "        return %s [%s].%s;\n    }\n",
8454            NAME_CODE_TABLE_NAME, MIDDLE_VARIABLE_NAME, CODE_MEMBER_NAME);
8455   fprintf (output_file, "  return -1;\n}\n\n");
8456   free (units);
8457 }
8458
8459 /* The following function outputs function to check reservation of cpu
8460    unit (its internal code will be passed as the function argument) in
8461    given cpu state.  */
8462 static void
8463 output_cpu_unit_reservation_p ()
8464 {
8465   automaton_t automaton;
8466
8467   fprintf (output_file, "int\n%s (%s, %s)\n\t%s %s;\n\tint %s;\n",
8468            CPU_UNIT_RESERVATION_P_FUNC_NAME, STATE_NAME,
8469            CPU_CODE_PARAMETER_NAME, STATE_TYPE_NAME, STATE_NAME,
8470            CPU_CODE_PARAMETER_NAME);
8471   fprintf (output_file, "{\n  if (%s < 0 || %s >= %d)\n    abort ();\n",
8472            CPU_CODE_PARAMETER_NAME, CPU_CODE_PARAMETER_NAME,
8473            description->query_units_num);
8474   for (automaton = description->first_automaton;
8475        automaton != NULL;
8476        automaton = automaton->next_automaton)
8477     {
8478       fprintf (output_file, "  if ((");
8479       output_reserved_units_table_name (output_file, automaton);
8480       fprintf (output_file, " [((struct %s *) %s)->", CHIP_NAME, STATE_NAME);
8481       output_chip_member_name (output_file, automaton);
8482       fprintf (output_file, " * %d + %s / 8] >> (%s %% 8)) & 1)\n",
8483                (description->query_units_num + 7) / 8,
8484                CPU_CODE_PARAMETER_NAME, CPU_CODE_PARAMETER_NAME);
8485       fprintf (output_file, "    return 1;\n");
8486     }
8487   fprintf (output_file, "  return 0;\n}\n\n");
8488 }
8489
8490 /* The function outputs PHR interface function `dfa_start'.  */
8491 static void
8492 output_dfa_start_func ()
8493 {
8494   fprintf (output_file,
8495            "void\n%s ()\n{\n  int %s;\n\n  %s = get_max_uid ();\n",
8496            DFA_START_FUNC_NAME, I_VARIABLE_NAME,
8497            DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
8498   fprintf (output_file, "  %s = (int *) xmalloc (%s * sizeof (int));\n",
8499            DFA_INSN_CODES_VARIABLE_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
8500   fprintf (output_file,
8501            "  for (%s = 0; %s < %s; %s++)\n    %s [%s] = -1;\n}\n\n",
8502            I_VARIABLE_NAME, I_VARIABLE_NAME,
8503            DFA_INSN_CODES_LENGTH_VARIABLE_NAME, I_VARIABLE_NAME,
8504            DFA_INSN_CODES_VARIABLE_NAME, I_VARIABLE_NAME);
8505 }
8506
8507 /* The function outputs PHR interface function `dfa_finish'.  */
8508 static void
8509 output_dfa_finish_func ()
8510 {
8511   fprintf (output_file, "void\n%s ()\n{\n  free (%s);\n}\n\n",
8512            DFA_FINISH_FUNC_NAME, DFA_INSN_CODES_VARIABLE_NAME);
8513 }
8514
8515 \f
8516
8517 /* The page contains code for output description file (readable
8518    representation of original description and generated DFA(s).  */
8519
8520 /* The function outputs string representation of IR reservation.  */
8521 static void
8522 output_regexp (regexp)
8523      regexp_t regexp;
8524 {
8525   fprintf (output_description_file, "%s", regexp_representation (regexp));
8526   finish_regexp_representation ();
8527 }
8528
8529 /* Output names of units in LIST separated by comma.  */
8530 static void
8531 output_unit_set_el_list (list)
8532      unit_set_el_t list;
8533 {
8534   unit_set_el_t el;
8535
8536   for (el = list; el != NULL; el = el->next_unit_set_el)
8537     {
8538       if (el != list)
8539         fprintf (output_description_file, ",");
8540       fprintf (output_description_file, "%s", el->unit_decl->name);
8541     }
8542 }
8543
8544 /* The function outputs string representation of IR define_reservation
8545    and define_insn_reservation.  */
8546 static void
8547 output_description ()
8548 {
8549   decl_t decl;
8550   int i;
8551
8552   for (i = 0; i < description->decls_num; i++)
8553     {
8554       decl = description->decls [i];
8555       if (decl->mode == dm_unit)
8556         {
8557           if (decl->decl.unit.excl_list != NULL)
8558             {
8559               fprintf (output_description_file, "unit %s exlusion_set: ",
8560                        decl->decl.unit.name);
8561               output_unit_set_el_list (decl->decl.unit.excl_list);
8562               fprintf (output_description_file, "\n");
8563             }
8564           if (decl->decl.unit.presence_list != NULL)
8565             {
8566               fprintf (output_description_file, "unit %s presence_set: ",
8567                        decl->decl.unit.name);
8568               output_unit_set_el_list (decl->decl.unit.presence_list);
8569               fprintf (output_description_file, "\n");
8570             }
8571           if (decl->decl.unit.absence_list != NULL)
8572             {
8573               fprintf (output_description_file, "unit %s absence_set: ",
8574                        decl->decl.unit.name);
8575               output_unit_set_el_list (decl->decl.unit.absence_list);
8576               fprintf (output_description_file, "\n");
8577             }
8578         }
8579     }
8580   fprintf (output_description_file, "\n");
8581   for (i = 0; i < description->decls_num; i++)
8582     {
8583       decl = description->decls [i];
8584       if (decl->mode == dm_reserv)
8585         {
8586           fprintf (output_description_file, "reservation ");
8587           fprintf (output_description_file, decl->decl.reserv.name);
8588           fprintf (output_description_file, ": ");
8589           output_regexp (decl->decl.reserv.regexp);
8590           fprintf (output_description_file, "\n");
8591         }
8592       else if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
8593         {
8594           fprintf (output_description_file, "insn reservation %s ",
8595                    decl->decl.insn_reserv.name);
8596           print_rtl (output_description_file, decl->decl.insn_reserv.condexp);
8597           fprintf (output_description_file, ": ");
8598           output_regexp (decl->decl.insn_reserv.regexp);
8599           fprintf (output_description_file, "\n");
8600         }
8601       else if (decl->mode == dm_bypass)
8602         fprintf (output_description_file, "bypass %d %s %s\n",
8603                  decl->decl.bypass.latency, decl->decl.bypass.out_insn_name,
8604                  decl->decl.bypass.in_insn_name);
8605     }
8606   fprintf (output_description_file, "\n\f\n");
8607 }
8608
8609 /* The function outputs name of AUTOMATON.  */
8610 static void
8611 output_automaton_name (f, automaton)
8612      FILE *f;
8613      automaton_t automaton;
8614 {
8615   if (automaton->corresponding_automaton_decl == NULL)
8616     fprintf (f, "#%d", automaton->automaton_order_num);
8617   else
8618     fprintf (f, "`%s'", automaton->corresponding_automaton_decl->name);
8619 }
8620
8621 /* Maximal length of line for pretty printing into description
8622    file.  */
8623 #define MAX_LINE_LENGTH 70
8624
8625 /* The function outputs units name belonging to AUTOMATON.  */
8626 static void
8627 output_automaton_units (automaton)
8628      automaton_t automaton;
8629 {
8630   decl_t decl;
8631   char *name;
8632   int curr_line_length;
8633   int there_is_an_automaton_unit;
8634   int i;
8635
8636   fprintf (output_description_file, "\n  Coresponding units:\n");
8637   fprintf (output_description_file, "    ");
8638   curr_line_length = 4;
8639   there_is_an_automaton_unit = 0;
8640   for (i = 0; i < description->decls_num; i++)
8641     {
8642       decl = description->decls [i];
8643       if (decl->mode == dm_unit
8644           && (decl->decl.unit.corresponding_automaton_num
8645               == automaton->automaton_order_num))
8646         {
8647           there_is_an_automaton_unit = 1;
8648           name = decl->decl.unit.name;
8649           if (curr_line_length + strlen (name) + 1 > MAX_LINE_LENGTH )
8650             {
8651               curr_line_length = strlen (name) + 4;
8652               fprintf (output_description_file, "\n    ");
8653             }
8654           else
8655             {
8656               curr_line_length += strlen (name) + 1;
8657               fprintf (output_description_file, " ");
8658             }
8659           fprintf (output_description_file, name);
8660         }
8661     }
8662   if (!there_is_an_automaton_unit)
8663     fprintf (output_description_file, "<None>");
8664   fprintf (output_description_file, "\n\n");
8665 }
8666
8667 /* The following variable is used for forming array of all possible cpu unit
8668    reservations described by the current DFA state.  */
8669 static vla_ptr_t state_reservs;
8670
8671 /* The function forms `state_reservs' for STATE.  */
8672 static void
8673 add_state_reservs (state)
8674      state_t state;
8675 {
8676   alt_state_t curr_alt_state;
8677   reserv_sets_t reservs;
8678
8679   if (state->component_states != NULL)
8680     for (curr_alt_state = state->component_states;
8681          curr_alt_state != NULL;
8682          curr_alt_state = curr_alt_state->next_sorted_alt_state)
8683       add_state_reservs (curr_alt_state->state);
8684   else
8685     {
8686       reservs = state->reservs;
8687       VLA_PTR_ADD (state_reservs, reservs);
8688     }
8689 }
8690
8691 /* The function outputs readable represenatation of all out arcs of
8692    STATE.  */
8693 static void
8694 output_state_arcs (state)
8695      state_t state;
8696 {
8697   arc_t arc;
8698   ainsn_t ainsn;
8699   char *insn_name;
8700   int curr_line_length;
8701
8702   for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
8703     {
8704       ainsn = arc->insn;
8705       if (!ainsn->first_insn_with_same_reservs)
8706         abort ();
8707       fprintf (output_description_file, "    ");
8708       curr_line_length = 7;
8709       fprintf (output_description_file, "%2d: ", ainsn->insn_equiv_class_num);
8710       do
8711         {
8712           insn_name = ainsn->insn_reserv_decl->name;
8713           if (curr_line_length + strlen (insn_name) > MAX_LINE_LENGTH)
8714             {
8715               if (ainsn != arc->insn)
8716                 {
8717                   fprintf (output_description_file, ",\n      ");
8718                   curr_line_length = strlen (insn_name) + 6;
8719                 }
8720               else
8721                 curr_line_length += strlen (insn_name);
8722             }
8723           else
8724             {
8725               curr_line_length += strlen (insn_name);
8726               if (ainsn != arc->insn)
8727                 {
8728                   curr_line_length += 2;
8729                   fprintf (output_description_file, ", ");
8730                 }
8731             }
8732           fprintf (output_description_file, insn_name);
8733           ainsn = ainsn->next_same_reservs_insn;
8734         }
8735       while (ainsn != NULL);
8736       fprintf (output_description_file, "    %d (%d)\n",
8737                arc->to_state->order_state_num, arc->state_alts);
8738     }
8739   fprintf (output_description_file, "\n");
8740 }
8741
8742 /* The following function is used for sorting possible cpu unit
8743    reservation of a DFA state.  */
8744 static int
8745 state_reservs_cmp (reservs_ptr_1, reservs_ptr_2)
8746      const void *reservs_ptr_1;
8747      const void *reservs_ptr_2;
8748 {
8749   return reserv_sets_cmp (*(reserv_sets_t *) reservs_ptr_1,
8750                           *(reserv_sets_t *) reservs_ptr_2);
8751 }
8752
8753 /* The following function is used for sorting possible cpu unit
8754    reservation of a DFA state.  */
8755 static void
8756 remove_state_duplicate_reservs ()
8757 {
8758   reserv_sets_t *reservs_ptr;
8759   reserv_sets_t *last_formed_reservs_ptr;
8760
8761   last_formed_reservs_ptr = NULL;
8762   for (reservs_ptr = VLA_PTR_BEGIN (state_reservs);
8763        reservs_ptr <= (reserv_sets_t *) VLA_PTR_LAST (state_reservs);
8764        reservs_ptr++)
8765     if (last_formed_reservs_ptr == NULL)
8766       last_formed_reservs_ptr = reservs_ptr;
8767     else if (reserv_sets_cmp (*last_formed_reservs_ptr, *reservs_ptr) != 0)
8768       {
8769         ++last_formed_reservs_ptr;
8770         *last_formed_reservs_ptr = *reservs_ptr;
8771       }
8772   VLA_PTR_SHORTEN (state_reservs, reservs_ptr - last_formed_reservs_ptr - 1);
8773 }
8774
8775 /* The following function output readable representation of DFA(s)
8776    state used for fast recognition of pipeline hazards.  State is
8777    described by possible (current and scehduled) cpu unit
8778    reservations.  */
8779 static void
8780 output_state (state)
8781      state_t state;
8782 {
8783   reserv_sets_t *reservs_ptr;
8784
8785   VLA_PTR_CREATE (state_reservs, 150, "state reservations");
8786   fprintf (output_description_file, "  State #%d", state->order_state_num);
8787   fprintf (output_description_file,
8788            state->new_cycle_p ? " (new cycle)\n" : "\n");
8789   add_state_reservs (state);
8790   qsort (VLA_PTR_BEGIN (state_reservs), VLA_PTR_LENGTH (state_reservs),
8791          sizeof (reserv_sets_t), state_reservs_cmp);
8792   remove_state_duplicate_reservs ();
8793   for (reservs_ptr = VLA_PTR_BEGIN (state_reservs);
8794        reservs_ptr <= (reserv_sets_t *) VLA_PTR_LAST (state_reservs);
8795        reservs_ptr++)
8796     {
8797       fprintf (output_description_file, "    ");
8798       output_reserv_sets (output_description_file, *reservs_ptr);
8799       fprintf (output_description_file, "\n");
8800     }
8801   fprintf (output_description_file, "\n");
8802   output_state_arcs (state);
8803   VLA_PTR_DELETE (state_reservs);
8804 }
8805
8806 /* The following function output readable representation of
8807    DFAs used for fast recognition of pipeline hazards.  */
8808 static void
8809 output_automaton_descriptions ()
8810 {
8811   automaton_t automaton;
8812
8813   for (automaton = description->first_automaton;
8814        automaton != NULL;
8815        automaton = automaton->next_automaton)
8816     {
8817       fprintf (output_description_file, "\nAutomaton ");
8818       output_automaton_name (output_description_file, automaton);
8819       fprintf (output_description_file, "\n");
8820       output_automaton_units (automaton);
8821       pass_states (automaton, output_state);
8822     }
8823 }
8824
8825 \f
8826
8827 /* The page contains top level function for generation DFA(s) used for
8828    PHR.  */
8829
8830 /* The function outputs statistics about work of different phases of
8831    DFA generator.  */
8832 static void
8833 output_statistics (f)
8834      FILE *f;
8835 {
8836   automaton_t automaton;
8837 #ifndef NDEBUG
8838   int transition_comb_vect_els = 0;
8839   int transition_full_vect_els = 0;
8840   int state_alts_comb_vect_els = 0;
8841   int state_alts_full_vect_els = 0;
8842   int min_issue_delay_vect_els = 0;
8843 #endif
8844
8845   for (automaton = description->first_automaton;
8846        automaton != NULL;
8847        automaton = automaton->next_automaton)
8848     {
8849       fprintf (f, "\nAutomaton ");
8850       output_automaton_name (f, automaton);
8851       fprintf (f, "\n    %5d NDFA states,          %5d NDFA arcs\n",
8852                automaton->NDFA_states_num, automaton->NDFA_arcs_num);
8853       fprintf (f, "    %5d DFA states,           %5d DFA arcs\n",
8854                automaton->DFA_states_num, automaton->DFA_arcs_num);
8855       if (!no_minimization_flag)
8856         fprintf (f, "    %5d minimal DFA states,   %5d minimal DFA arcs\n",
8857                  automaton->minimal_DFA_states_num,
8858                  automaton->minimal_DFA_arcs_num);
8859       fprintf (f, "    %5d all insns      %5d insn equivalence classes\n",
8860                description->insns_num, automaton->insn_equiv_classes_num);
8861 #ifndef NDEBUG
8862       fprintf
8863         (f, "%5ld transition comb vector els, %5ld trans table els: %s\n",
8864          (long) VLA_HWINT_LENGTH (automaton->trans_table->comb_vect),
8865          (long) VLA_HWINT_LENGTH (automaton->trans_table->full_vect),
8866          (comb_vect_p (automaton->trans_table)
8867           ? "use comb vect" : "use simple vect"));
8868       fprintf
8869         (f, "%5ld state alts comb vector els, %5ld state alts table els: %s\n",
8870          (long) VLA_HWINT_LENGTH (automaton->state_alts_table->comb_vect),
8871          (long) VLA_HWINT_LENGTH (automaton->state_alts_table->full_vect),
8872          (comb_vect_p (automaton->state_alts_table)
8873           ? "use comb vect" : "use simple vect"));
8874       fprintf
8875         (f, "%5ld min delay table els, compression factor %d\n",
8876          (long) automaton->DFA_states_num * automaton->insn_equiv_classes_num,
8877          automaton->min_issue_delay_table_compression_factor);
8878       transition_comb_vect_els
8879         += VLA_HWINT_LENGTH (automaton->trans_table->comb_vect);
8880       transition_full_vect_els 
8881         += VLA_HWINT_LENGTH (automaton->trans_table->full_vect);
8882       state_alts_comb_vect_els
8883         += VLA_HWINT_LENGTH (automaton->state_alts_table->comb_vect);
8884       state_alts_full_vect_els
8885         += VLA_HWINT_LENGTH (automaton->state_alts_table->full_vect);
8886       min_issue_delay_vect_els
8887         += automaton->DFA_states_num * automaton->insn_equiv_classes_num;
8888 #endif
8889     }
8890 #ifndef NDEBUG
8891   fprintf (f, "\n%5d all allocated states,     %5d all allocated arcs\n",
8892            allocated_states_num, allocated_arcs_num);
8893   fprintf (f, "%5d all allocated alternative states\n",
8894            allocated_alt_states_num);
8895   fprintf (f, "%5d all transition comb vector els, %5d all trans table els\n",
8896            transition_comb_vect_els, transition_full_vect_els);
8897   fprintf
8898     (f, "%5d all state alts comb vector els, %5d all state alts table els\n",
8899      state_alts_comb_vect_els, state_alts_full_vect_els);
8900   fprintf (f, "%5d all min delay table els\n", min_issue_delay_vect_els);
8901   fprintf (f, "%5d locked states num\n", locked_states_num);
8902 #endif
8903 }
8904
8905 /* The function output times of work of different phases of DFA
8906    generator.  */
8907 static void
8908 output_time_statistics (f)
8909      FILE *f;
8910 {
8911   fprintf (f, "\n  transformation: ");
8912   print_active_time (f, transform_time);
8913   fprintf (f, (!ndfa_flag ? ", building DFA: " : ", building NDFA: "));
8914   print_active_time (f, NDFA_time);
8915   if (ndfa_flag)
8916     {
8917       fprintf (f, ", NDFA -> DFA: ");
8918       print_active_time (f, NDFA_to_DFA_time);
8919     }
8920   fprintf (f, "\n  DFA minimization: ");
8921   print_active_time (f, minimize_time);
8922   fprintf (f, ", making insn equivalence: ");
8923   print_active_time (f, equiv_time);
8924   fprintf (f, "\n all automaton generation: ");
8925   print_active_time (f, automaton_generation_time);
8926   fprintf (f, ", output: ");
8927   print_active_time (f, output_time);
8928   fprintf (f, "\n");
8929 }
8930
8931 /* The function generates DFA (deterministic finate state automaton)
8932    for fast recognition of pipeline hazards.  No errors during
8933    checking must be fixed before this function call.  */
8934 static void
8935 generate ()
8936 {
8937   automata_num = split_argument;
8938   if (description->units_num < automata_num)
8939     automata_num = description->units_num;
8940   initiate_states ();
8941   initiate_arcs ();
8942   initiate_automata_lists ();
8943   initiate_pass_states ();
8944   initiate_excl_sets ();
8945   initiate_presence_absence_sets ();
8946   automaton_generation_time = create_ticker ();
8947   create_automata ();
8948   ticker_off (&automaton_generation_time);
8949 }
8950
8951 \f
8952
8953 /* The following function creates attribute which order number of insn
8954    in pipeline hazard description translator.  */
8955 static void
8956 make_insn_alts_attr ()
8957 {
8958   int i, insn_num;
8959   decl_t decl;
8960   rtx condexp;
8961
8962   condexp = rtx_alloc (COND);
8963   XVEC (condexp, 0) = rtvec_alloc ((description->insns_num - 1) * 2);
8964   XEXP (condexp, 1) = make_numeric_value (0);
8965   for (i = insn_num = 0; i < description->decls_num; i++)
8966     {
8967       decl = description->decls [i];
8968       if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
8969         {
8970           XVECEXP (condexp, 0, 2 * insn_num) = decl->decl.insn_reserv.condexp;
8971           XVECEXP (condexp, 0, 2 * insn_num + 1)
8972             = make_numeric_value (decl->decl.insn_reserv.transformed_regexp
8973                                   ->regexp.oneof.regexps_num);
8974           insn_num++;
8975         }
8976     }
8977   if (description->insns_num != insn_num + 1)
8978     abort ();
8979   make_internal_attr (attr_printf (sizeof ("*")
8980                                    + strlen (INSN_ALTS_FUNC_NAME) + 1,
8981                                    "*%s", INSN_ALTS_FUNC_NAME),
8982                       condexp, 0);
8983 }
8984
8985 \f
8986
8987 /* The following function creates attribute which is order number of
8988    insn in pipeline hazard description translator.  */
8989 static void
8990 make_internal_dfa_insn_code_attr ()
8991 {
8992   int i, insn_num;
8993   decl_t decl;
8994   rtx condexp;
8995
8996   condexp = rtx_alloc (COND);
8997   XVEC (condexp, 0) = rtvec_alloc ((description->insns_num - 1) * 2);
8998   XEXP (condexp, 1) = make_numeric_value (advance_cycle_insn_decl
8999                                           ->decl.insn_reserv.insn_num + 1);
9000   for (i = insn_num = 0; i < description->decls_num; i++)
9001     {
9002       decl = description->decls [i];
9003       if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
9004         {
9005           XVECEXP (condexp, 0, 2 * insn_num) = decl->decl.insn_reserv.condexp;
9006           XVECEXP (condexp, 0, 2 * insn_num + 1)
9007             = make_numeric_value (decl->decl.insn_reserv.insn_num);
9008           insn_num++;
9009         }
9010     }
9011   if (description->insns_num != insn_num + 1)
9012     abort ();
9013   make_internal_attr
9014     (attr_printf (sizeof ("*")
9015                   + strlen (INTERNAL_DFA_INSN_CODE_FUNC_NAME) + 1,
9016                   "*%s", INTERNAL_DFA_INSN_CODE_FUNC_NAME),
9017      condexp, 0);
9018 }
9019
9020 \f
9021
9022 /* The following function creates attribute which order number of insn
9023    in pipeline hazard description translator.  */
9024 static void
9025 make_default_insn_latency_attr ()
9026 {
9027   int i, insn_num;
9028   decl_t decl;
9029   rtx condexp;
9030
9031   condexp = rtx_alloc (COND);
9032   XVEC (condexp, 0) = rtvec_alloc ((description->insns_num - 1) * 2);
9033   XEXP (condexp, 1) = make_numeric_value (0);
9034   for (i = insn_num = 0; i < description->decls_num; i++)
9035     {
9036       decl = description->decls [i];
9037       if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
9038         {
9039           XVECEXP (condexp, 0, 2 * insn_num) = decl->decl.insn_reserv.condexp;
9040           XVECEXP (condexp, 0, 2 * insn_num + 1)
9041             = make_numeric_value (decl->decl.insn_reserv.default_latency);
9042           insn_num++;
9043         }
9044     }
9045   if (description->insns_num != insn_num + 1)
9046     abort ();
9047   make_internal_attr (attr_printf (sizeof ("*")
9048                                    + strlen (INSN_DEFAULT_LATENCY_FUNC_NAME)
9049                                    + 1, "*%s", INSN_DEFAULT_LATENCY_FUNC_NAME),
9050                       condexp, 0);
9051 }
9052
9053 \f
9054
9055 /* The following function creates attribute which returns 1 if given
9056    output insn has bypassing and 0 otherwise.  */
9057 static void
9058 make_bypass_attr ()
9059 {
9060   int i, bypass_insn;
9061   int bypass_insns_num = 0;
9062   decl_t decl;
9063   rtx result_rtx;
9064   
9065   for (i = 0; i < description->decls_num; i++)
9066     {
9067       decl = description->decls [i];
9068       if (decl->mode == dm_insn_reserv
9069           && decl->decl.insn_reserv.condexp != NULL
9070           && decl->decl.insn_reserv.bypass_list != NULL)
9071         bypass_insns_num++;
9072     }
9073   if (bypass_insns_num == 0)
9074     result_rtx = make_numeric_value (0);
9075   else
9076     {
9077       result_rtx = rtx_alloc (COND);
9078       XVEC (result_rtx, 0) = rtvec_alloc (bypass_insns_num * 2);
9079       XEXP (result_rtx, 1) = make_numeric_value (0);
9080
9081       for (i = bypass_insn = 0; i < description->decls_num; i++)
9082         {
9083           decl = description->decls [i];
9084           if (decl->mode == dm_insn_reserv
9085               && decl->decl.insn_reserv.condexp != NULL
9086               && decl->decl.insn_reserv.bypass_list != NULL)
9087             {
9088               XVECEXP (result_rtx, 0, 2 * bypass_insn)
9089                 = decl->decl.insn_reserv.condexp;
9090               XVECEXP (result_rtx, 0, 2 * bypass_insn + 1)
9091                 = make_numeric_value (1);
9092               bypass_insn++;
9093             }
9094         }
9095     }
9096   make_internal_attr (attr_printf (sizeof ("*")
9097                                    + strlen (BYPASS_P_FUNC_NAME) + 1,
9098                                    "*%s", BYPASS_P_FUNC_NAME),
9099                       result_rtx, 0);
9100 }
9101
9102 \f
9103
9104 /* This page mainly contains top level functions of pipeline hazards
9105    description translator.  */
9106
9107 /* The following macro value is suffix of name of description file of
9108    pipeline hazards description translator.  */
9109 #define STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX ".dfa"
9110
9111 /* The function returns suffix of given file name.  The returned
9112    string can not be changed.  */
9113 static const char *
9114 file_name_suffix (file_name)
9115      const char *file_name;
9116 {
9117   const char *last_period;
9118
9119   for (last_period = NULL; *file_name != '\0'; file_name++)
9120     if (*file_name == '.')
9121       last_period = file_name;
9122   return (last_period == NULL ? file_name : last_period);
9123 }
9124
9125 /* The function returns base name of given file name, i.e. pointer to
9126    first char after last `/' (or `\' for WIN32) in given file name,
9127    given file name itself if the directory name is absent.  The
9128    returned string can not be changed.  */
9129 static const char *
9130 base_file_name (file_name)
9131      const char *file_name;
9132 {
9133   int directory_name_length;
9134
9135   directory_name_length = strlen (file_name);
9136 #ifdef WIN32
9137   while (directory_name_length >= 0 && file_name[directory_name_length] != '/'
9138          && file_name[directory_name_length] != '\\')
9139 #else
9140   while (directory_name_length >= 0 && file_name[directory_name_length] != '/')
9141 #endif
9142     directory_name_length--;
9143   return file_name + directory_name_length + 1;
9144 }
9145
9146 /* The following is top level function to initialize the work of
9147    pipeline hazards description translator.  */
9148 void
9149 initiate_automaton_gen (argc, argv)
9150      int argc;
9151      char **argv;
9152 {
9153   const char *base_name;
9154   int i;
9155
9156   ndfa_flag = 0;
9157   split_argument = 0;  /* default value */
9158   no_minimization_flag = 0;
9159   time_flag = 0;
9160   v_flag = 0;
9161   w_flag = 0;
9162   for (i = 2; i < argc; i++)
9163     if (strcmp (argv [i], NO_MINIMIZATION_OPTION) == 0)
9164       no_minimization_flag = 1;
9165     else if (strcmp (argv [i], "-time") == 0)
9166       time_flag = 1;
9167     else if (strcmp (argv [i], "-v") == 0)
9168       v_flag = 1;
9169     else if (strcmp (argv [i], W_OPTION) == 0)
9170       w_flag = 1;
9171     else if (strcmp (argv [i], NDFA_OPTION) == 0)
9172       ndfa_flag = 1;
9173     else if (strcmp (argv [i], "-split") == 0)
9174       {
9175         if (i + 1 >= argc)
9176           fatal ("-split has no argument.");
9177         fatal ("option `-split' has not been implemented yet\n");
9178         /* split_argument = atoi (argument_vect [i + 1]); */
9179       }
9180   VLA_PTR_CREATE (decls, 150, "decls");
9181   /* Initialize IR storage.  */
9182   obstack_init (&irp);
9183   initiate_automaton_decl_table ();
9184   initiate_insn_decl_table ();
9185   initiate_decl_table ();
9186   output_file = stdout;
9187   output_description_file = NULL;
9188   base_name = base_file_name (argv[1]);
9189   obstack_grow (&irp, base_name,
9190                 strlen (base_name) - strlen (file_name_suffix (base_name)));
9191   obstack_grow (&irp, STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX,
9192                 strlen (STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX) + 1);
9193   obstack_1grow (&irp, '\0');
9194   output_description_file_name = obstack_base (&irp);
9195   obstack_finish (&irp);
9196 }
9197
9198 /* The following function checks existence at least one arc marked by
9199    each insn.  */
9200 static void
9201 check_automata_insn_issues ()
9202 {
9203   automaton_t automaton;
9204   ainsn_t ainsn, reserv_ainsn;
9205
9206   for (automaton = description->first_automaton;
9207        automaton != NULL;
9208        automaton = automaton->next_automaton)
9209     {
9210       for (ainsn = automaton->ainsn_list;
9211            ainsn != NULL;
9212            ainsn = ainsn->next_ainsn)
9213         if (ainsn->first_insn_with_same_reservs && !ainsn->arc_exists_p)
9214           {
9215             for (reserv_ainsn = ainsn;
9216                  reserv_ainsn != NULL;
9217                  reserv_ainsn = reserv_ainsn->next_same_reservs_insn)
9218               if (automaton->corresponding_automaton_decl != NULL)
9219                 {
9220                   if (!w_flag)
9221                     error ("Automaton `%s': Insn `%s' will never be issued",
9222                            automaton->corresponding_automaton_decl->name,
9223                            reserv_ainsn->insn_reserv_decl->name);
9224                   else
9225                     warning
9226                       ("Automaton `%s': Insn `%s' will never be issued",
9227                        automaton->corresponding_automaton_decl->name,
9228                        reserv_ainsn->insn_reserv_decl->name);
9229                 }
9230               else
9231                 {
9232                   if (!w_flag)
9233                     error ("Insn `%s' will never be issued",
9234                            reserv_ainsn->insn_reserv_decl->name);
9235                   else
9236                     warning ("Insn `%s' will never be issued",
9237                              reserv_ainsn->insn_reserv_decl->name);
9238                 }
9239           }
9240     }
9241 }
9242
9243 /* The following vla is used for storing pointers to all achieved
9244    states.  */
9245 static vla_ptr_t automaton_states;
9246
9247 /* This function is called by function pass_states to add an achieved
9248    STATE.  */
9249 static void
9250 add_automaton_state (state)
9251      state_t state;
9252 {
9253   VLA_PTR_ADD (automaton_states, state);
9254 }
9255
9256 /* The following function forms list of important automata (whose
9257    states may be changed after the insn issue) for each insn.  */
9258 static void
9259 form_important_insn_automata_lists ()
9260 {
9261   automaton_t automaton;
9262   state_t *state_ptr;
9263   decl_t decl;
9264   ainsn_t ainsn;
9265   arc_t arc;
9266   int i;
9267
9268   VLA_PTR_CREATE (automaton_states, 1500,
9269                   "automaton states for forming important insn automata sets");
9270   /* Mark important ainsns.  */
9271   for (automaton = description->first_automaton;
9272        automaton != NULL;
9273        automaton = automaton->next_automaton)
9274     {
9275       VLA_PTR_NULLIFY (automaton_states);
9276       pass_states (automaton, add_automaton_state);
9277       for (state_ptr = VLA_PTR_BEGIN (automaton_states);
9278            state_ptr <= (state_t *) VLA_PTR_LAST (automaton_states);
9279            state_ptr++)
9280         {
9281           for (arc = first_out_arc (*state_ptr);
9282                arc != NULL;
9283                arc = next_out_arc (arc))
9284             if (arc->to_state != *state_ptr)
9285               {
9286                 if (!arc->insn->first_insn_with_same_reservs)
9287                   abort ();
9288                 for (ainsn = arc->insn;
9289                      ainsn != NULL;
9290                      ainsn = ainsn->next_same_reservs_insn)
9291                   ainsn->important_p = TRUE;
9292               }
9293         }
9294     }
9295   VLA_PTR_DELETE (automaton_states);
9296   /* Create automata sets for the insns.  */
9297   for (i = 0; i < description->decls_num; i++)
9298     {
9299       decl = description->decls [i];
9300       if (decl->mode == dm_insn_reserv)
9301         {
9302           automata_list_start ();
9303           for (automaton = description->first_automaton;
9304                automaton != NULL;
9305                automaton = automaton->next_automaton)
9306             for (ainsn = automaton->ainsn_list;
9307                  ainsn != NULL;
9308                  ainsn = ainsn->next_ainsn)
9309               if (ainsn->important_p
9310                   && ainsn->insn_reserv_decl == &decl->decl.insn_reserv)
9311                 {
9312                   automata_list_add (automaton);
9313                   break;
9314                 }
9315           decl->decl.insn_reserv.important_automata_list
9316             = automata_list_finish ();
9317         }
9318     }
9319 }
9320
9321
9322 /* The following is top level function to generate automat(a,on) for
9323    fast recognition of pipeline hazards.  */
9324 void
9325 expand_automata ()
9326 {
9327   int i;
9328
9329   description = create_node (sizeof (struct description)
9330                              /* One entry for cycle advancing insn.  */
9331                              + sizeof (decl_t) * VLA_PTR_LENGTH (decls));
9332   description->decls_num = VLA_PTR_LENGTH (decls);
9333   description->query_units_num = 0;
9334   for (i = 0; i < description->decls_num; i++)
9335     {
9336       description->decls [i] = VLA_PTR (decls, i);
9337       if (description->decls [i]->mode == dm_unit
9338           && description->decls [i]->decl.unit.query_p)
9339         description->decls [i]->decl.unit.query_num
9340           = description->query_units_num++;
9341     }
9342   all_time = create_ticker ();
9343   check_time = create_ticker ();
9344   fprintf (stderr, "Check description...");
9345   fflush (stderr);
9346   check_all_description ();
9347   fprintf (stderr, "done\n");
9348   ticker_off (&check_time);
9349   generation_time = create_ticker ();
9350   if (!have_error)
9351     {
9352       transform_insn_regexps ();
9353       check_unit_distributions_to_automata ();
9354     }
9355   if (!have_error)
9356     {
9357       generate ();
9358       check_automata_insn_issues ();
9359     }
9360   if (!have_error)
9361     {
9362       form_important_insn_automata_lists ();
9363       fprintf (stderr, "Generation of attributes...");
9364       fflush (stderr);
9365       make_internal_dfa_insn_code_attr ();
9366       make_insn_alts_attr ();
9367       make_default_insn_latency_attr ();
9368       make_bypass_attr ();
9369       fprintf (stderr, "done\n");
9370     }
9371   ticker_off (&generation_time);
9372   ticker_off (&all_time);
9373   fprintf (stderr, "All other genattrtab stuff...");
9374   fflush (stderr);
9375 }
9376
9377 /* The following is top level function to output PHR and to finish
9378    work with pipeline description translator.  */
9379 void
9380 write_automata ()
9381 {
9382   fprintf (stderr, "done\n");
9383   if (have_error)
9384     fatal ("Errors in DFA description");
9385   ticker_on (&all_time);
9386   output_time = create_ticker ();
9387   fprintf (stderr, "Forming and outputing automata tables...");
9388   fflush (stderr);
9389   output_dfa_max_issue_rate ();
9390   output_tables ();
9391   fprintf (stderr, "done\n");
9392   fprintf (stderr, "Output functions to work with automata...");
9393   fflush (stderr);
9394   output_chip_definitions ();
9395   output_max_insn_queue_index_def ();
9396   output_internal_min_issue_delay_func ();
9397   output_internal_trans_func ();
9398   /* Cache of insn dfa codes: */
9399   fprintf (output_file, "\nstatic int *%s;\n", DFA_INSN_CODES_VARIABLE_NAME);
9400   fprintf (output_file, "\nstatic int %s;\n\n",
9401            DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
9402   output_dfa_insn_code_func ();
9403   output_trans_func ();
9404   fprintf (output_file, "\n#if %s\n\n", AUTOMATON_STATE_ALTS_MACRO_NAME);
9405   output_internal_state_alts_func ();
9406   output_state_alts_func ();
9407   fprintf (output_file, "\n#endif /* #if %s */\n\n",
9408            AUTOMATON_STATE_ALTS_MACRO_NAME);
9409   output_min_issue_delay_func ();
9410   output_internal_dead_lock_func ();
9411   output_dead_lock_func ();
9412   output_size_func ();
9413   output_internal_reset_func ();
9414   output_reset_func ();
9415   output_min_insn_conflict_delay_func ();
9416   output_internal_insn_latency_func ();
9417   output_insn_latency_func ();
9418   output_print_reservation_func ();
9419   if (no_minimization_flag)
9420     {
9421       fprintf (output_file, "\n#if %s\n\n", CPU_UNITS_QUERY_MACRO_NAME);
9422       output_get_cpu_unit_code_func ();
9423       output_cpu_unit_reservation_p ();
9424       fprintf (output_file, "\n#endif /* #if %s */\n\n",
9425                CPU_UNITS_QUERY_MACRO_NAME);
9426     }
9427   output_dfa_start_func ();
9428   output_dfa_finish_func ();
9429   fprintf (stderr, "done\n");
9430   if (v_flag)
9431     {
9432       output_description_file = fopen (output_description_file_name, "w");
9433       if (output_description_file == NULL)
9434         {
9435           perror (output_description_file_name);
9436           exit (FATAL_EXIT_CODE);
9437         }
9438       fprintf (stderr, "Output automata description...");
9439       fflush (stderr);
9440       output_description ();
9441       output_automaton_descriptions ();
9442       fprintf (stderr, "done\n");
9443       output_statistics (output_description_file);
9444     }
9445   output_statistics (stderr);
9446   ticker_off (&output_time);
9447   output_time_statistics (stderr);
9448   finish_states ();
9449   finish_arcs ();
9450   finish_automata_lists ();
9451   if (time_flag)
9452     {
9453       fprintf (stderr, "Summary:\n");
9454       fprintf (stderr, "  check time ");
9455       print_active_time (stderr, check_time);
9456       fprintf (stderr, ", generation time ");
9457       print_active_time (stderr, generation_time);
9458       fprintf (stderr, ", all time ");
9459       print_active_time (stderr, all_time);
9460       fprintf (stderr, "\n");
9461     }
9462   /* Finish all work.  */
9463   if (output_description_file != NULL)
9464     {
9465       fflush (output_description_file);
9466       if (ferror (stdout) != 0)
9467         fatal ("Error in writing DFA description file %s",
9468                output_description_file_name);
9469       fclose (output_description_file);
9470     }
9471   finish_automaton_decl_table ();
9472   finish_insn_decl_table ();
9473   finish_decl_table ();
9474   obstack_free (&irp, NULL);
9475   if (have_error && output_description_file != NULL)
9476     remove (output_description_file_name);
9477 }