OSDN Git Service

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