OSDN Git Service

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