OSDN Git Service

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