OSDN Git Service

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