OSDN Git Service

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