OSDN Git Service

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