OSDN Git Service

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