OSDN Git Service

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