OSDN Git Service

* emit-rtl.c (emit_jump_insn_before, emit_call_insn_before,
[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           {
4987             if (REGEXP_ALLOF (regexp)->regexps [i]->mode == rm_sequence)
4988               {
4989                 seq = REGEXP_ALLOF (regexp)->regexps [i];
4990                 if (max_seq_length < REGEXP_SEQUENCE (seq)->regexps_num)
4991                   max_seq_length = REGEXP_SEQUENCE (seq)->regexps_num;
4992               }
4993             else if (REGEXP_ALLOF (regexp)->regexps [i]->mode != rm_unit)
4994               {
4995                 max_seq_length = 0;
4996                 break;
4997               }
4998           }
4999       if (max_seq_length != 0)
5000         {
5001           if (max_seq_length == 1 || REGEXP_ALLOF (regexp)->regexps_num <= 1)
5002             abort ();
5003           result = create_node (sizeof (struct regexp)
5004                                 + sizeof (regexp_t) * (max_seq_length - 1));
5005           result->mode = rm_sequence;
5006           result->pos = regexp->pos;
5007           REGEXP_SEQUENCE (result)->regexps_num = max_seq_length;
5008           for (i = 0; i < max_seq_length; i++)
5009             {
5010               allof_length = 0;
5011               for (j = 0; j < REGEXP_ALLOF (regexp)->regexps_num; j++)
5012                 if (REGEXP_ALLOF (regexp)->regexps [j]->mode == rm_sequence
5013                     && (i < (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp)
5014                                               ->regexps [j])->regexps_num)))
5015                   {
5016                     allof_op
5017                       = (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp)->regexps [j])
5018                          ->regexps [i]);
5019                     allof_length++;
5020                   }
5021                 else if (i == 0
5022                          && (REGEXP_ALLOF (regexp)->regexps [j]->mode
5023                              == rm_unit))
5024                   {
5025                     allof_op = REGEXP_ALLOF (regexp)->regexps [j];
5026                     allof_length++;
5027                   }
5028               if (allof_length == 1)
5029                 REGEXP_SEQUENCE (result)->regexps [i] = allof_op;
5030               else
5031                 {
5032                   allof = create_node (sizeof (struct regexp)
5033                                        + sizeof (regexp_t)
5034                                        * (allof_length - 1));
5035                   allof->mode = rm_allof;
5036                   allof->pos = regexp->pos;
5037                   REGEXP_ALLOF (allof)->regexps_num = allof_length;
5038                   REGEXP_SEQUENCE (result)->regexps [i] = allof;
5039                   allof_length = 0;
5040                   for (j = 0; j < REGEXP_ALLOF (regexp)->regexps_num; j++)
5041                     if (REGEXP_ALLOF (regexp)->regexps [j]->mode == rm_sequence
5042                         && (i <
5043                             (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp)
5044                                               ->regexps [j])->regexps_num)))
5045                       {
5046                         allof_op = (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp)
5047                                                      ->regexps [j])
5048                                     ->regexps [i]);
5049                         REGEXP_ALLOF (allof)->regexps [allof_length]
5050                           = allof_op;
5051                         allof_length++;
5052                       }
5053                     else if (i == 0
5054                              && (REGEXP_ALLOF (regexp)->regexps [j]->mode
5055                                  == rm_unit))
5056                       {
5057                         allof_op = REGEXP_ALLOF (regexp)->regexps [j];
5058                         REGEXP_ALLOF (allof)->regexps [allof_length]
5059                           = allof_op;
5060                         allof_length++;
5061                       }
5062                 }
5063             }
5064           regexp_transformed_p = 1;
5065           regexp = result;
5066         }
5067     }
5068   return regexp;
5069 }
5070
5071 /* The function traverses IR of reservation and applies transformations
5072    implemented by FUNC.  */
5073 static regexp_t
5074 regexp_transform_func (regexp, func)
5075      regexp_t regexp;
5076      regexp_t (*func) PARAMS ((regexp_t regexp));
5077 {
5078   int i;
5079
5080   if (regexp->mode == rm_sequence)
5081     for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
5082       REGEXP_SEQUENCE (regexp)->regexps [i]
5083         = regexp_transform_func (REGEXP_SEQUENCE (regexp)->regexps [i], func);
5084   else if (regexp->mode == rm_allof)
5085     for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
5086       REGEXP_ALLOF (regexp)->regexps [i]
5087         = regexp_transform_func (REGEXP_ALLOF (regexp)->regexps [i], func);
5088   else if (regexp->mode == rm_oneof)
5089     for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
5090       REGEXP_ONEOF (regexp)->regexps [i]
5091         = regexp_transform_func (REGEXP_ONEOF (regexp)->regexps [i], func);
5092   else if (regexp->mode == rm_repeat)
5093     REGEXP_REPEAT (regexp)->regexp
5094       = regexp_transform_func (REGEXP_REPEAT (regexp)->regexp, func);
5095   else if (regexp->mode != rm_nothing && regexp->mode != rm_unit)
5096     abort ();
5097   return (*func) (regexp);
5098 }
5099
5100 /* The function applies all transformations for IR representation of
5101    reservation REGEXP.  */
5102 static regexp_t
5103 transform_regexp (regexp)
5104      regexp_t regexp;
5105 {
5106   regexp = regexp_transform_func (regexp, transform_1);  
5107   do
5108     {
5109       regexp_transformed_p = 0;
5110       regexp = regexp_transform_func (regexp, transform_2);
5111       regexp = regexp_transform_func (regexp, transform_3);
5112     }
5113   while (regexp_transformed_p);
5114   return regexp;
5115 }
5116
5117 /* The function applys all transformations for reservations of all
5118    insn declarations.  */
5119 static void
5120 transform_insn_regexps ()
5121 {
5122   decl_t decl;
5123   int i;
5124
5125   transform_time = create_ticker ();
5126   add_advance_cycle_insn_decl ();
5127   fprintf (stderr, "Reservation transformation...");
5128   fflush (stderr);
5129   for (i = 0; i < description->decls_num; i++)
5130     {
5131       decl = description->decls [i];
5132       if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
5133         DECL_INSN_RESERV (decl)->transformed_regexp
5134           = transform_regexp (copy_insn_regexp
5135                               (DECL_INSN_RESERV (decl)->regexp));
5136     }
5137   fprintf (stderr, "done\n");
5138   ticker_off (&transform_time);
5139   fflush (stderr);
5140 }
5141
5142 \f
5143
5144 /* The following variable is an array indexed by cycle.  Each element
5145    contains cyclic list of units which should be in the same cycle.  */
5146 static unit_decl_t *the_same_automaton_lists;
5147
5148 /* The function processes all alternative reservations on CYCLE in
5149    given REGEXP to check the UNIT is not reserved on the all
5150    alternatives.  If it is true, the unit should be in the same
5151    automaton with other analogous units reserved on CYCLE in given
5152    REGEXP.  */
5153 static void
5154 process_unit_to_form_the_same_automaton_unit_lists (unit, regexp, cycle)
5155      regexp_t unit;
5156      regexp_t regexp;
5157      int cycle;
5158 {
5159   int i, k;
5160   regexp_t seq, allof;
5161   unit_decl_t unit_decl, last;
5162
5163   if (regexp == NULL || regexp->mode != rm_oneof)
5164     abort ();
5165   unit_decl = REGEXP_UNIT (unit)->unit_decl;
5166   for (i = REGEXP_ONEOF (regexp)->regexps_num - 1; i >= 0; i--)
5167     {
5168       seq = REGEXP_ONEOF (regexp)->regexps [i];
5169       if (seq->mode == rm_sequence)
5170         {
5171           if (cycle >= REGEXP_SEQUENCE (seq)->regexps_num)
5172             break;
5173           allof = REGEXP_SEQUENCE (seq)->regexps [cycle];
5174           if (allof->mode == rm_allof)
5175             {
5176               for (k = 0; k < REGEXP_ALLOF (allof)->regexps_num; k++)
5177                 if (REGEXP_ALLOF (allof)->regexps [k]->mode == rm_unit
5178                     && (REGEXP_UNIT (REGEXP_ALLOF (allof)->regexps [k])
5179                         ->unit_decl == unit_decl))
5180                   break;
5181               if (k >= REGEXP_ALLOF (allof)->regexps_num)
5182                 break;
5183             }
5184           else if (allof->mode == rm_unit
5185                    && REGEXP_UNIT (allof)->unit_decl != unit_decl)
5186             break;
5187         }
5188       else if (cycle != 0)
5189         break;
5190       else if (seq->mode == rm_allof)
5191         {
5192           for (k = 0; k < REGEXP_ALLOF (seq)->regexps_num; k++)
5193             if (REGEXP_ALLOF (seq)->regexps [k]->mode == rm_unit
5194                 && (REGEXP_UNIT (REGEXP_ALLOF (seq)->regexps [k])->unit_decl
5195                     == unit_decl))
5196               break;
5197           if (k >= REGEXP_ALLOF (seq)->regexps_num)
5198             break;
5199         }
5200       else if (seq->mode == rm_unit
5201                && REGEXP_UNIT (seq)->unit_decl != unit_decl)
5202         break;
5203     }
5204   if (i >= 0)
5205     {
5206       if (the_same_automaton_lists [cycle] == NULL)
5207         the_same_automaton_lists [cycle] = unit_decl;
5208       else
5209         {
5210           for (last = the_same_automaton_lists [cycle];;)
5211             {
5212               if (last == unit_decl)
5213                 return;
5214               if (last->the_same_automaton_unit
5215                   == the_same_automaton_lists [cycle])
5216                 break;
5217               last = last->the_same_automaton_unit;
5218             }
5219           last->the_same_automaton_unit = unit_decl->the_same_automaton_unit;
5220           unit_decl->the_same_automaton_unit
5221             = the_same_automaton_lists [cycle];
5222         }
5223     }
5224 }
5225
5226 /* The function processes given REGEXP to find units which should be
5227    in the same automaton.  */
5228 static void
5229 form_the_same_automaton_unit_lists_from_regexp (regexp)
5230      regexp_t regexp;
5231 {
5232   int i, j, k;
5233   regexp_t seq, allof, unit;
5234
5235   if (regexp == NULL || regexp->mode != rm_oneof)
5236     return;
5237   for (i = 0; i < description->max_insn_reserv_cycles; i++)
5238     the_same_automaton_lists [i] = NULL;
5239   for (i = REGEXP_ONEOF (regexp)->regexps_num - 1; i >= 0; i--)
5240     {
5241       seq = REGEXP_ONEOF (regexp)->regexps [i];
5242       if (seq->mode == rm_sequence)
5243         for (j = 0; j < REGEXP_SEQUENCE (seq)->regexps_num; j++)
5244           {
5245             allof = REGEXP_SEQUENCE (seq)->regexps [j];
5246             if (allof->mode == rm_allof)
5247               for (k = 0; k < REGEXP_ALLOF (allof)->regexps_num; k++)
5248                 {
5249                   unit = REGEXP_ALLOF (allof)->regexps [k];
5250                   if (unit->mode == rm_unit)
5251                     process_unit_to_form_the_same_automaton_unit_lists
5252                       (unit, regexp, j);
5253                   else if (unit->mode != rm_nothing)
5254                     abort ();
5255                 }
5256             else if (allof->mode == rm_unit)
5257               process_unit_to_form_the_same_automaton_unit_lists
5258                 (allof, regexp, j);
5259             else if (allof->mode != rm_nothing)
5260               abort ();
5261           }
5262       else if (seq->mode == rm_allof)
5263         for (k = 0; k < REGEXP_ALLOF (seq)->regexps_num; k++)
5264           {
5265             unit = REGEXP_ALLOF (seq)->regexps [k];
5266             if (unit->mode == rm_unit)
5267               process_unit_to_form_the_same_automaton_unit_lists
5268                 (unit, regexp, 0);
5269             else if (unit->mode != rm_nothing)
5270               abort ();
5271           }
5272       else if (seq->mode == rm_unit)
5273         process_unit_to_form_the_same_automaton_unit_lists (seq, regexp, 0);
5274       else if (seq->mode != rm_nothing)
5275         abort ();
5276     }
5277 }
5278
5279 /* The function initializes data to search for units which should be
5280    in the same automaton and call function
5281    `form_the_same_automaton_unit_lists_from_regexp' for each insn
5282    reservation regexp.  */
5283 static void
5284 form_the_same_automaton_unit_lists ()
5285 {
5286   decl_t decl;
5287   int i;
5288
5289   the_same_automaton_lists
5290     = (unit_decl_t *) xmalloc (description->max_insn_reserv_cycles
5291                                * sizeof (unit_decl_t));
5292   for (i = 0; i < description->decls_num; i++)
5293     {
5294       decl = description->decls [i];
5295       if (decl->mode == dm_unit)
5296         {
5297           DECL_UNIT (decl)->the_same_automaton_message_reported_p = FALSE;
5298           DECL_UNIT (decl)->the_same_automaton_unit = DECL_UNIT (decl);
5299         }
5300     }
5301   for (i = 0; i < description->decls_num; i++)
5302     {
5303       decl = description->decls [i];
5304       if (decl->mode == dm_insn_reserv)
5305         form_the_same_automaton_unit_lists_from_regexp
5306           (DECL_INSN_RESERV (decl)->transformed_regexp);
5307     }
5308   free (the_same_automaton_lists);
5309 }
5310
5311 /* The function finds units which should be in the same automaton and,
5312    if they are not, reports about it.  */
5313 static void
5314 check_unit_distributions_to_automata ()
5315 {
5316   decl_t decl;
5317   unit_decl_t start_unit_decl, unit_decl;
5318   int i;
5319
5320   form_the_same_automaton_unit_lists ();
5321   for (i = 0; i < description->decls_num; i++)
5322     {
5323       decl = description->decls [i];
5324       if (decl->mode == dm_unit)
5325         {
5326           start_unit_decl = DECL_UNIT (decl);
5327           if (!start_unit_decl->the_same_automaton_message_reported_p)
5328             for (unit_decl = start_unit_decl->the_same_automaton_unit;
5329                  unit_decl != start_unit_decl;
5330                  unit_decl = unit_decl->the_same_automaton_unit)
5331               if (start_unit_decl->automaton_decl != unit_decl->automaton_decl)
5332                 {
5333                   error ("Units `%s' and `%s' should be in the same automaton",
5334                          start_unit_decl->name, unit_decl->name);
5335                   unit_decl->the_same_automaton_message_reported_p = TRUE;
5336                 }
5337         }
5338     }
5339 }
5340
5341 \f
5342
5343 /* The page contains code for building alt_states (see comments for
5344    IR) describing all possible insns reservations of an automaton.  */
5345
5346 /* Current state being formed for which the current alt_state
5347    refers.  */
5348 static state_t state_being_formed;
5349
5350 /* Current alt_state being formed.  */
5351 static alt_state_t alt_state_being_formed;
5352  
5353 /* This recursive function processes `,' and units in reservation
5354    REGEXP for forming alt_states of AUTOMATON.  It is believed that
5355    CURR_CYCLE is start cycle of all reservation REGEXP.  */
5356 static int
5357 process_seq_for_forming_states (regexp, automaton, curr_cycle)
5358      regexp_t regexp;
5359      automaton_t automaton;
5360      int curr_cycle;
5361 {
5362   int i;
5363
5364   if (regexp == NULL)
5365     return curr_cycle;
5366   else if (regexp->mode == rm_unit)
5367     {
5368       if (REGEXP_UNIT (regexp)->unit_decl->corresponding_automaton_num
5369           == automaton->automaton_order_num)
5370         set_state_reserv (state_being_formed, curr_cycle,
5371                           REGEXP_UNIT (regexp)->unit_decl->unit_num);
5372       return curr_cycle;
5373     }
5374   else if (regexp->mode == rm_sequence)
5375     {
5376       for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
5377         curr_cycle
5378           = process_seq_for_forming_states
5379             (REGEXP_SEQUENCE (regexp)->regexps [i], automaton, curr_cycle) + 1;
5380       return curr_cycle;
5381     }
5382   else if (regexp->mode == rm_allof)
5383     {
5384       int finish_cycle = 0;
5385       int cycle;
5386
5387       for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
5388         {
5389           cycle = process_seq_for_forming_states (REGEXP_ALLOF (regexp)
5390                                                   ->regexps [i],
5391                                                   automaton, curr_cycle);
5392           if (finish_cycle < cycle)
5393             finish_cycle = cycle;
5394         }
5395       return finish_cycle;
5396     }
5397   else
5398     {
5399       if (regexp->mode != rm_nothing)
5400         abort ();
5401       return curr_cycle;
5402     }
5403 }
5404
5405 /* This recursive function finishes forming ALT_STATE of AUTOMATON and
5406    inserts alt_state into the table.  */
5407 static void
5408 finish_forming_alt_state (alt_state, automaton)
5409      alt_state_t alt_state;
5410      automaton_t automaton ATTRIBUTE_UNUSED;
5411 {
5412   state_t state_in_table;
5413   state_t corresponding_state;
5414
5415   corresponding_state = alt_state->state;
5416   state_in_table = insert_state (corresponding_state);
5417   if (state_in_table != corresponding_state)
5418     {
5419       free_state (corresponding_state);
5420       alt_state->state = state_in_table;
5421     }
5422 }
5423
5424 /* The following variable value is current automaton insn for whose
5425    reservation the alt states are created.  */
5426 static ainsn_t curr_ainsn;
5427
5428 /* This recursive function processes `|' in reservation REGEXP for
5429    forming alt_states of AUTOMATON.  List of the alt states should
5430    have the same order as in the description.  */
5431 static void
5432 process_alts_for_forming_states (regexp, automaton, inside_oneof_p)
5433      regexp_t regexp;
5434      automaton_t automaton;
5435      int inside_oneof_p;
5436 {
5437   int i;
5438
5439   if (regexp->mode != rm_oneof)
5440     {
5441       alt_state_being_formed = get_free_alt_state ();
5442       state_being_formed = get_free_state (1, automaton);
5443       alt_state_being_formed->state = state_being_formed;
5444       /* We inserts in reverse order but we process alternatives also
5445          in reverse order.  So we have the same order of alternative
5446          as in the description.  */
5447       alt_state_being_formed->next_alt_state = curr_ainsn->alt_states;
5448       curr_ainsn->alt_states = alt_state_being_formed;
5449       (void) process_seq_for_forming_states (regexp, automaton, 0);
5450       finish_forming_alt_state (alt_state_being_formed, automaton);
5451     }
5452   else
5453     {
5454       if (inside_oneof_p)
5455         abort ();
5456       /* We processes it in reverse order to get list with the same
5457          order as in the description.  See also the previous
5458          commentary.  */
5459       for (i = REGEXP_ONEOF (regexp)->regexps_num - 1; i >= 0; i--)
5460         process_alts_for_forming_states (REGEXP_ONEOF (regexp)->regexps [i],
5461                                          automaton, 1);
5462     }
5463 }
5464
5465 /* Create nodes alt_state for all AUTOMATON insns.  */
5466 static void
5467 create_alt_states (automaton)
5468      automaton_t automaton;
5469 {
5470   struct insn_reserv_decl *reserv_decl;
5471
5472   for (curr_ainsn = automaton->ainsn_list;
5473        curr_ainsn != NULL;
5474        curr_ainsn = curr_ainsn->next_ainsn)
5475     {
5476       reserv_decl = curr_ainsn->insn_reserv_decl;
5477       if (reserv_decl != DECL_INSN_RESERV (advance_cycle_insn_decl))
5478         {
5479           curr_ainsn->alt_states = NULL;
5480           process_alts_for_forming_states (reserv_decl->transformed_regexp,
5481                                            automaton, 0);
5482           curr_ainsn->sorted_alt_states
5483             = uniq_sort_alt_states (curr_ainsn->alt_states);
5484         }
5485     }
5486 }
5487
5488 \f
5489
5490 /* The page contains major code for building DFA(s) for fast pipeline
5491    hazards recognition.  */
5492
5493 /* The function forms list of ainsns of AUTOMATON with the same
5494    reservation.  */
5495 static void
5496 form_ainsn_with_same_reservs (automaton)
5497      automaton_t automaton;
5498 {
5499   ainsn_t curr_ainsn;
5500   size_t i;
5501   vla_ptr_t first_insns;
5502   vla_ptr_t last_insns;
5503
5504   VLA_PTR_CREATE (first_insns, 150, "first insns with the same reservs");
5505   VLA_PTR_CREATE (last_insns, 150, "last insns with the same reservs");
5506   for (curr_ainsn = automaton->ainsn_list;
5507        curr_ainsn != NULL;
5508        curr_ainsn = curr_ainsn->next_ainsn)
5509     if (curr_ainsn->insn_reserv_decl
5510         == DECL_INSN_RESERV (advance_cycle_insn_decl))
5511       {
5512         curr_ainsn->next_same_reservs_insn = NULL;
5513         curr_ainsn->first_insn_with_same_reservs = 1;
5514       }
5515     else
5516       {
5517         for (i = 0; i < VLA_PTR_LENGTH (first_insns); i++)
5518           if (alt_states_eq
5519               (curr_ainsn->sorted_alt_states,
5520                ((ainsn_t) VLA_PTR (first_insns, i))->sorted_alt_states))
5521             break;
5522         curr_ainsn->next_same_reservs_insn = NULL;
5523         if (i < VLA_PTR_LENGTH (first_insns))
5524           {
5525             curr_ainsn->first_insn_with_same_reservs = 0;
5526             ((ainsn_t) VLA_PTR (last_insns, i))->next_same_reservs_insn
5527               = curr_ainsn;
5528             VLA_PTR (last_insns, i) = curr_ainsn;
5529           }
5530         else
5531           {
5532             VLA_PTR_ADD (first_insns, curr_ainsn);
5533             VLA_PTR_ADD (last_insns, curr_ainsn);
5534             curr_ainsn->first_insn_with_same_reservs = 1;
5535           }
5536       }
5537   VLA_PTR_DELETE (first_insns);
5538   VLA_PTR_DELETE (last_insns);
5539 }
5540
5541 /* The following function creates all states of nondeterministic (if
5542    NDFA_FLAG has nonzero value) or deterministic AUTOMATON.  */
5543 static void
5544 make_automaton (automaton)
5545      automaton_t automaton;
5546 {
5547   ainsn_t ainsn;
5548   struct insn_reserv_decl *insn_reserv_decl;
5549   alt_state_t alt_state;
5550   state_t state;
5551   state_t start_state;
5552   state_t state2;
5553   ainsn_t advance_cycle_ainsn;
5554   arc_t added_arc;
5555   vla_ptr_t state_stack;
5556
5557   VLA_PTR_CREATE (state_stack, 150, "state stack");
5558   /* Create the start state (empty state).  */
5559   start_state = insert_state (get_free_state (1, automaton));
5560   automaton->start_state = start_state;
5561   start_state->it_was_placed_in_stack_for_NDFA_forming = 1;
5562   VLA_PTR_ADD (state_stack, start_state);
5563   while (VLA_PTR_LENGTH (state_stack) != 0)
5564     {
5565       state = VLA_PTR (state_stack, VLA_PTR_LENGTH (state_stack) - 1);
5566       VLA_PTR_SHORTEN (state_stack, 1);
5567       advance_cycle_ainsn = NULL;
5568       for (ainsn = automaton->ainsn_list;
5569            ainsn != NULL;
5570            ainsn = ainsn->next_ainsn)
5571         if (ainsn->first_insn_with_same_reservs)
5572           {
5573             insn_reserv_decl = ainsn->insn_reserv_decl;
5574             if (insn_reserv_decl != DECL_INSN_RESERV (advance_cycle_insn_decl))
5575               {
5576                 /* We process alt_states in the same order as they are
5577                    present in the description.  */
5578                 added_arc = NULL;
5579                 for (alt_state = ainsn->alt_states;
5580                      alt_state != NULL;
5581                      alt_state = alt_state->next_alt_state)
5582                   {
5583                     state2 = alt_state->state;
5584                     if (!intersected_state_reservs_p (state, state2))
5585                       {
5586                         state2 = states_union (state, state2);
5587                         if (!state2->it_was_placed_in_stack_for_NDFA_forming)
5588                           {
5589                             state2->it_was_placed_in_stack_for_NDFA_forming
5590                               = 1;
5591                             VLA_PTR_ADD (state_stack, state2);
5592                           }
5593                         added_arc = add_arc (state, state2, ainsn, 1);
5594                         if (!ndfa_flag)
5595                           break;
5596                       }
5597                   }
5598                 if (!ndfa_flag && added_arc != NULL)
5599                   {
5600                     added_arc->state_alts = 0;
5601                     for (alt_state = ainsn->alt_states;
5602                          alt_state != NULL;
5603                          alt_state = alt_state->next_alt_state)
5604                       {
5605                         state2 = alt_state->state;
5606                         if (!intersected_state_reservs_p (state, state2))
5607                           added_arc->state_alts++;
5608                       }
5609                   }
5610               }
5611             else
5612               advance_cycle_ainsn = ainsn;
5613           }
5614       /* Add transition to advance cycle.  */
5615       state2 = state_shift (state);
5616       if (!state2->it_was_placed_in_stack_for_NDFA_forming)
5617         {
5618           state2->it_was_placed_in_stack_for_NDFA_forming = 1;
5619           VLA_PTR_ADD (state_stack, state2);
5620         }
5621       if (advance_cycle_ainsn == NULL)
5622         abort ();
5623       add_arc (state, state2, advance_cycle_ainsn, 1);
5624     }
5625   VLA_PTR_DELETE (state_stack);
5626 }
5627
5628 /* Foms lists of all arcs of STATE marked by the same ainsn.  */
5629 static void
5630 form_arcs_marked_by_insn (state)
5631      state_t state;
5632 {
5633   decl_t decl;
5634   arc_t arc;
5635   int i;
5636
5637   for (i = 0; i < description->decls_num; i++)
5638     {
5639       decl = description->decls [i];
5640       if (decl->mode == dm_insn_reserv)
5641         DECL_INSN_RESERV (decl)->arcs_marked_by_insn = NULL;
5642     }
5643   for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
5644     {
5645       if (arc->insn == NULL)
5646         abort ();
5647       arc->next_arc_marked_by_insn
5648         = arc->insn->insn_reserv_decl->arcs_marked_by_insn;
5649       arc->insn->insn_reserv_decl->arcs_marked_by_insn = arc;
5650     }
5651 }
5652
5653 /* The function creates composed state (see comments for IR) from
5654    ORIGINAL_STATE and list of arcs ARCS_MARKED_BY_INSN marked by the
5655    same insn.  If the composed state is not in STATE_STACK yet, it is
5656    popped to STATE_STACK.  */
5657 static void
5658 create_composed_state (original_state, arcs_marked_by_insn, state_stack)
5659      state_t original_state;
5660      arc_t arcs_marked_by_insn;
5661      vla_ptr_t *state_stack;
5662 {
5663   state_t state;
5664   alt_state_t curr_alt_state;
5665   alt_state_t new_alt_state;
5666   arc_t curr_arc;
5667   arc_t next_arc;
5668   state_t state_in_table;
5669   state_t temp_state;
5670   alt_state_t canonical_alt_states_list;
5671   int alts_number;
5672
5673   if (arcs_marked_by_insn == NULL)
5674     return;
5675   if (arcs_marked_by_insn->next_arc_marked_by_insn == NULL)
5676     state = arcs_marked_by_insn->to_state;
5677   else
5678     {
5679       if (!ndfa_flag)
5680         abort ();
5681       /* Create composed state.  */
5682       state = get_free_state (0, arcs_marked_by_insn->to_state->automaton);
5683       curr_alt_state = NULL;
5684       for (curr_arc = arcs_marked_by_insn;
5685            curr_arc != NULL;
5686            curr_arc = curr_arc->next_arc_marked_by_insn)
5687         {
5688           new_alt_state = get_free_alt_state ();
5689           new_alt_state->next_alt_state = curr_alt_state;
5690           new_alt_state->state = curr_arc->to_state;
5691           if (curr_arc->to_state->component_states != NULL)
5692             abort ();
5693           curr_alt_state = new_alt_state;
5694         }
5695       /* There are not identical sets in the alt state list.  */
5696       canonical_alt_states_list = uniq_sort_alt_states (curr_alt_state);
5697       if (canonical_alt_states_list->next_sorted_alt_state == NULL)
5698         {
5699           temp_state = state;
5700           state = canonical_alt_states_list->state;
5701           free_state (temp_state);
5702         }
5703       else
5704         {
5705           state->component_states = canonical_alt_states_list;
5706           state_in_table = insert_state (state);
5707           if (state_in_table != state)
5708             {
5709               if (!state_in_table->it_was_placed_in_stack_for_DFA_forming)
5710                 abort ();
5711               free_state (state);
5712               state = state_in_table;
5713             }
5714           else
5715             {
5716               if (state->it_was_placed_in_stack_for_DFA_forming)
5717                 abort ();
5718               for (curr_alt_state = state->component_states;
5719                    curr_alt_state != NULL;
5720                    curr_alt_state = curr_alt_state->next_sorted_alt_state)
5721                 for (curr_arc = first_out_arc (curr_alt_state->state);
5722                      curr_arc != NULL;
5723                      curr_arc = next_out_arc (curr_arc))
5724                   add_arc (state, curr_arc->to_state, curr_arc->insn, 1);
5725             }
5726           arcs_marked_by_insn->to_state = state;
5727           for (alts_number = 0,
5728                curr_arc = arcs_marked_by_insn->next_arc_marked_by_insn;
5729                curr_arc != NULL;
5730                curr_arc = next_arc)
5731             {
5732               next_arc = curr_arc->next_arc_marked_by_insn;
5733               remove_arc (original_state, curr_arc);
5734               alts_number++;
5735             }
5736           arcs_marked_by_insn->state_alts = alts_number;
5737         }
5738     }
5739   if (!state->it_was_placed_in_stack_for_DFA_forming)
5740     {
5741       state->it_was_placed_in_stack_for_DFA_forming = 1;
5742       VLA_PTR_ADD (*state_stack, state);
5743     }
5744 }
5745
5746 /* The function transformes nondeterminstic AUTOMATON into
5747    deterministic.  */
5748 static void
5749 NDFA_to_DFA (automaton)
5750      automaton_t automaton;
5751 {
5752   state_t start_state;
5753   state_t state;
5754   decl_t decl;
5755   vla_ptr_t state_stack;
5756   int i;
5757
5758   VLA_PTR_CREATE (state_stack, 150, "state stack");
5759   /* Create the start state (empty state).  */
5760   start_state = automaton->start_state;
5761   start_state->it_was_placed_in_stack_for_DFA_forming = 1;
5762   VLA_PTR_ADD (state_stack, start_state);
5763   while (VLA_PTR_LENGTH (state_stack) != 0)
5764     {
5765       state = VLA_PTR (state_stack, VLA_PTR_LENGTH (state_stack) - 1);
5766       VLA_PTR_SHORTEN (state_stack, 1);
5767       form_arcs_marked_by_insn (state);
5768       for (i = 0; i < description->decls_num; i++)
5769         {
5770           decl = description->decls [i];
5771           if (decl->mode == dm_insn_reserv)
5772             create_composed_state
5773               (state, DECL_INSN_RESERV (decl)->arcs_marked_by_insn,
5774                &state_stack);
5775         }
5776     }
5777   VLA_PTR_DELETE (state_stack);
5778 }
5779
5780 /* The following variable value is current number (1, 2, ...) of passing
5781    graph of states.  */
5782 static int curr_state_graph_pass_num;
5783
5784 /* This recursive function passes all states achieved from START_STATE
5785    and applies APPLIED_FUNC to them.  */
5786 static void
5787 pass_state_graph (start_state, applied_func)
5788      state_t start_state;
5789      void (*applied_func) PARAMS ((state_t state));
5790 {
5791   arc_t arc;
5792
5793   if (start_state->pass_num == curr_state_graph_pass_num)
5794     return;
5795   start_state->pass_num = curr_state_graph_pass_num;
5796   (*applied_func) (start_state);
5797   for (arc = first_out_arc (start_state);
5798        arc != NULL;
5799        arc = next_out_arc (arc))
5800     pass_state_graph (arc->to_state, applied_func);
5801 }
5802
5803 /* This recursive function passes all states of AUTOMATON and applies
5804    APPLIED_FUNC to them.  */
5805 static void
5806 pass_states (automaton, applied_func)
5807      automaton_t automaton;
5808      void (*applied_func) PARAMS ((state_t state));
5809 {
5810   curr_state_graph_pass_num++;
5811   pass_state_graph (automaton->start_state, applied_func);
5812 }
5813
5814 /* The function initializes code for passing of all states.  */
5815 static void
5816 initiate_pass_states ()
5817 {
5818   curr_state_graph_pass_num = 0;
5819 }
5820
5821 /* The following vla is used for storing pointers to all achieved
5822    states.  */
5823 static vla_ptr_t all_achieved_states;
5824
5825 /* This function is called by function pass_states to add an achieved
5826    STATE.  */
5827 static void
5828 add_achieved_state (state)
5829      state_t state;
5830 {
5831   VLA_PTR_ADD (all_achieved_states, state);
5832 }
5833
5834 /* The function sets up equivalence numbers of insns which mark all
5835    out arcs of STATE by equiv_class_num_1 (if ODD_ITERATION_FLAG has
5836    nonzero value) or by equiv_class_num_2 of the destination state.
5837    The function returns number of out arcs of STATE.  */
5838 static int
5839 set_out_arc_insns_equiv_num (state, odd_iteration_flag)
5840      state_t state;
5841      int odd_iteration_flag;
5842 {
5843   int state_out_arcs_num;
5844   arc_t arc;
5845
5846   state_out_arcs_num = 0;
5847   for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
5848     {
5849       if (arc->insn->insn_reserv_decl->equiv_class_num != 0
5850           || arc->insn->insn_reserv_decl->state_alts != 0)
5851         abort ();
5852       state_out_arcs_num++;
5853       arc->insn->insn_reserv_decl->equiv_class_num
5854         = (odd_iteration_flag
5855            ? arc->to_state->equiv_class_num_1
5856            : arc->to_state->equiv_class_num_2);
5857       arc->insn->insn_reserv_decl->state_alts = arc->state_alts;
5858       if (arc->insn->insn_reserv_decl->equiv_class_num == 0
5859           || arc->insn->insn_reserv_decl->state_alts <= 0)
5860         abort ();
5861     }
5862   return state_out_arcs_num;
5863 }
5864
5865 /* The function clears equivalence numbers and alt_states in all insns
5866    which mark all out arcs of STATE.  */
5867 static void
5868 clear_arc_insns_equiv_num (state)
5869      state_t state;
5870 {
5871   arc_t arc;
5872
5873   for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
5874     {
5875       arc->insn->insn_reserv_decl->equiv_class_num = 0;
5876       arc->insn->insn_reserv_decl->state_alts = 0;
5877     }
5878 }
5879
5880 /* The function copies pointers to equivalent states from vla FROM
5881    into vla TO.  */
5882 static void
5883 copy_equiv_class (to, from)
5884      vla_ptr_t *to;
5885      const vla_ptr_t *from;
5886 {
5887   state_t *class_ptr;
5888
5889   VLA_PTR_NULLIFY (*to);
5890   for (class_ptr = VLA_PTR_BEGIN (*from);
5891        class_ptr <= (state_t *) VLA_PTR_LAST (*from);
5892        class_ptr++)
5893     VLA_PTR_ADD (*to, *class_ptr);
5894 }
5895
5896 /* The function returns nonzero value if STATE is not equivalent to
5897    another state from the same current partition on equivalence
5898    classes Another state has ORIGINAL_STATE_OUT_ARCS_NUM number of
5899    output arcs.  Iteration of making equivalence partition is defined
5900    by ODD_ITERATION_FLAG.  */
5901 static int
5902 state_is_differed (state, original_state_out_arcs_num, odd_iteration_flag)
5903      state_t state;
5904      int original_state_out_arcs_num;
5905      int odd_iteration_flag;
5906 {
5907   arc_t arc;
5908   int state_out_arcs_num;
5909
5910   state_out_arcs_num = 0;
5911   for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
5912     {
5913       state_out_arcs_num++;
5914       if ((odd_iteration_flag
5915            ? arc->to_state->equiv_class_num_1
5916            : arc->to_state->equiv_class_num_2)
5917           != arc->insn->insn_reserv_decl->equiv_class_num
5918           || (arc->insn->insn_reserv_decl->state_alts != arc->state_alts))
5919         return 1;
5920     }
5921   return state_out_arcs_num != original_state_out_arcs_num;
5922 }
5923
5924 /* The function makes initial partition of STATES on equivalent
5925    classes.  */
5926 static state_t
5927 init_equiv_class (states, states_num)
5928      state_t *states;
5929      int states_num;
5930 {
5931   state_t *state_ptr;
5932   state_t result_equiv_class;
5933
5934   result_equiv_class = NULL;
5935   for (state_ptr = states; state_ptr < states + states_num; state_ptr++)
5936     {
5937       (*state_ptr)->equiv_class_num_1 = 1;
5938       (*state_ptr)->next_equiv_class_state = result_equiv_class;
5939       result_equiv_class = *state_ptr;
5940     }
5941   return result_equiv_class;
5942 }
5943
5944 /* The function processes equivalence class given by its pointer
5945    EQUIV_CLASS_PTR on odd iteration if ODD_ITERATION_FLAG.  If there
5946    are not equvalent states, the function partitions the class
5947    removing nonequivalent states and placing them in
5948    *NEXT_ITERATION_CLASSES, increments *NEW_EQUIV_CLASS_NUM_PTR ans
5949    assigns it to the state equivalence number.  If the class has been
5950    partitioned, the function returns nonzero value.  */
5951 static int
5952 partition_equiv_class (equiv_class_ptr, odd_iteration_flag,
5953                        next_iteration_classes, new_equiv_class_num_ptr)
5954      state_t *equiv_class_ptr;
5955      int odd_iteration_flag;
5956      vla_ptr_t *next_iteration_classes;
5957      int *new_equiv_class_num_ptr;
5958 {
5959   state_t new_equiv_class;
5960   int partition_p;
5961   state_t first_state;
5962   state_t curr_state;
5963   state_t prev_state;
5964   state_t next_state;
5965   int out_arcs_num;
5966
5967   partition_p = 0;
5968   if (*equiv_class_ptr == NULL)
5969     abort ();
5970   for (first_state = *equiv_class_ptr;
5971        first_state != NULL;
5972        first_state = new_equiv_class)
5973     {
5974       new_equiv_class = NULL;
5975       if (first_state->next_equiv_class_state != NULL)
5976         {
5977           /* There are more one states in the class equivalence.  */
5978           out_arcs_num = set_out_arc_insns_equiv_num (first_state,
5979                                                       odd_iteration_flag);
5980           for (prev_state = first_state,
5981                  curr_state = first_state->next_equiv_class_state;
5982                curr_state != NULL;
5983                curr_state = next_state)
5984             {
5985               next_state = curr_state->next_equiv_class_state;
5986               if (state_is_differed (curr_state, out_arcs_num,
5987                                      odd_iteration_flag))
5988                 {
5989                   /* Remove curr state from the class equivalence.  */
5990                   prev_state->next_equiv_class_state = next_state;
5991                   /* Add curr state to the new class equivalence.  */
5992                   curr_state->next_equiv_class_state = new_equiv_class;
5993                   if (new_equiv_class == NULL)
5994                     (*new_equiv_class_num_ptr)++;
5995                   if (odd_iteration_flag)
5996                     curr_state->equiv_class_num_2 = *new_equiv_class_num_ptr;
5997                   else
5998                     curr_state->equiv_class_num_1 = *new_equiv_class_num_ptr;
5999                   new_equiv_class = curr_state;
6000                   partition_p = 1;
6001                 }
6002               else
6003                 prev_state = curr_state;
6004             }
6005           clear_arc_insns_equiv_num (first_state);
6006         }
6007       if (new_equiv_class != NULL)
6008         VLA_PTR_ADD  (*next_iteration_classes, new_equiv_class);
6009     }
6010   return partition_p;
6011 }
6012
6013 /* The function finds equivalent states of AUTOMATON.  */
6014 static void
6015 evaluate_equiv_classes (automaton, equiv_classes)
6016      automaton_t automaton;
6017      vla_ptr_t *equiv_classes;
6018 {
6019   state_t new_equiv_class;
6020   int new_equiv_class_num;
6021   int odd_iteration_flag;
6022   int finish_flag;
6023   vla_ptr_t next_iteration_classes;
6024   state_t *equiv_class_ptr;
6025   state_t *state_ptr;
6026   
6027   VLA_PTR_CREATE (all_achieved_states, 1500, "all achieved states");
6028   pass_states (automaton, add_achieved_state);
6029   new_equiv_class = init_equiv_class (VLA_PTR_BEGIN (all_achieved_states),
6030                                       VLA_PTR_LENGTH (all_achieved_states));
6031   odd_iteration_flag = 0;
6032   new_equiv_class_num = 1;
6033   VLA_PTR_CREATE (next_iteration_classes, 150, "next iteration classes");
6034   VLA_PTR_ADD (next_iteration_classes, new_equiv_class);
6035   do
6036     {
6037       odd_iteration_flag = !odd_iteration_flag;
6038       finish_flag = 1;
6039       copy_equiv_class (equiv_classes, &next_iteration_classes);
6040       /* Transfer equiv numbers for the next iteration.  */
6041       for (state_ptr = VLA_PTR_BEGIN (all_achieved_states);
6042            state_ptr <= (state_t *) VLA_PTR_LAST (all_achieved_states);
6043            state_ptr++)
6044         if (odd_iteration_flag)
6045           (*state_ptr)->equiv_class_num_2 = (*state_ptr)->equiv_class_num_1;
6046         else
6047           (*state_ptr)->equiv_class_num_1 = (*state_ptr)->equiv_class_num_2;
6048       for (equiv_class_ptr = VLA_PTR_BEGIN (*equiv_classes);
6049            equiv_class_ptr <= (state_t *) VLA_PTR_LAST (*equiv_classes);
6050            equiv_class_ptr++)
6051         if (partition_equiv_class (equiv_class_ptr, odd_iteration_flag,
6052                                    &next_iteration_classes,
6053                                    &new_equiv_class_num))
6054           finish_flag = 0;
6055     }
6056   while (!finish_flag);
6057   VLA_PTR_DELETE (next_iteration_classes);
6058   VLA_PTR_DELETE (all_achieved_states);
6059 }
6060
6061 /* The function merges equivalent states of AUTOMATON.  */
6062 static void
6063 merge_states (automaton, equiv_classes)
6064      automaton_t automaton;
6065      vla_ptr_t *equiv_classes;
6066 {
6067   state_t *equiv_class_ptr;
6068   state_t curr_state;
6069   state_t new_state;
6070   state_t first_class_state;
6071   alt_state_t alt_states;
6072   alt_state_t new_alt_state;
6073   arc_t curr_arc;
6074   arc_t next_arc;
6075
6076   /* Create states corresponding to equivalence classes containing two
6077      or more states.  */
6078   for (equiv_class_ptr = VLA_PTR_BEGIN (*equiv_classes);
6079        equiv_class_ptr <= (state_t *) VLA_PTR_LAST (*equiv_classes);
6080        equiv_class_ptr++)
6081     if ((*equiv_class_ptr)->next_equiv_class_state != NULL)
6082       {
6083         /* There are more one states in the class equivalence.  */
6084         /* Create new compound state.  */
6085         new_state = get_free_state (0, automaton);
6086         alt_states = NULL;
6087         first_class_state = *equiv_class_ptr;
6088         for (curr_state = first_class_state;
6089              curr_state != NULL;
6090              curr_state = curr_state->next_equiv_class_state)
6091           {
6092             curr_state->equiv_class_state = new_state;
6093             new_alt_state = get_free_alt_state ();
6094             new_alt_state->state = curr_state;
6095             new_alt_state->next_sorted_alt_state = alt_states;
6096             alt_states = new_alt_state;
6097           }
6098         new_state->component_states = alt_states;
6099       }
6100     else
6101       (*equiv_class_ptr)->equiv_class_state = *equiv_class_ptr;
6102   for (equiv_class_ptr = VLA_PTR_BEGIN (*equiv_classes);
6103        equiv_class_ptr <= (state_t *) VLA_PTR_LAST (*equiv_classes);
6104        equiv_class_ptr++)
6105     if ((*equiv_class_ptr)->next_equiv_class_state != NULL)
6106       {
6107         first_class_state = *equiv_class_ptr;
6108         /* Create new arcs output from the state corresponding to
6109            equiv class.  */
6110         for (curr_arc = first_out_arc (first_class_state);
6111              curr_arc != NULL;
6112              curr_arc = next_out_arc (curr_arc))
6113           add_arc (first_class_state->equiv_class_state,
6114                    curr_arc->to_state->equiv_class_state,
6115                    curr_arc->insn, curr_arc->state_alts);
6116         /* Delete output arcs from states of given class equivalence.  */
6117         for (curr_state = first_class_state;
6118              curr_state != NULL;
6119              curr_state = curr_state->next_equiv_class_state)
6120           {
6121             if (automaton->start_state == curr_state)
6122               automaton->start_state = curr_state->equiv_class_state;
6123             /* Delete the state and its output arcs.  */
6124             for (curr_arc = first_out_arc (curr_state);
6125                  curr_arc != NULL;
6126                  curr_arc = next_arc)
6127               {
6128                 next_arc = next_out_arc (curr_arc);
6129                 free_arc (curr_arc);
6130               }
6131           }
6132       }
6133     else
6134       {
6135         /* Change `to_state' of arcs output from the state of given
6136            equivalence class.  */
6137         for (curr_arc = first_out_arc (*equiv_class_ptr);
6138              curr_arc != NULL;
6139              curr_arc = next_out_arc (curr_arc))
6140           curr_arc->to_state = curr_arc->to_state->equiv_class_state;
6141       }
6142 }
6143
6144 /* The function sets up new_cycle_p for states if there is arc to the
6145    state marked by advance_cycle_insn_decl.  */
6146 static void
6147 set_new_cycle_flags (state)
6148      state_t state;
6149 {
6150   arc_t arc;
6151
6152   for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6153     if (arc->insn->insn_reserv_decl
6154         == DECL_INSN_RESERV (advance_cycle_insn_decl))
6155       arc->to_state->new_cycle_p = 1;
6156 }
6157
6158 /* The top level function for minimization of deterministic
6159    AUTOMATON.  */
6160 static void
6161 minimize_DFA (automaton)
6162      automaton_t automaton;
6163 {
6164   vla_ptr_t equiv_classes;
6165
6166   VLA_PTR_CREATE (equiv_classes, 1500, "equivalence classes");
6167   evaluate_equiv_classes (automaton, &equiv_classes);
6168   merge_states (automaton, &equiv_classes);
6169   pass_states (automaton, set_new_cycle_flags);
6170   VLA_PTR_DELETE (equiv_classes);
6171 }
6172
6173 /* Values of two variables are counted number of states and arcs in an
6174    automaton.  */
6175 static int curr_counted_states_num;
6176 static int curr_counted_arcs_num;
6177
6178 /* The function is called by function `pass_states' to count states
6179    and arcs of an automaton.  */
6180 static void
6181 incr_states_and_arcs_nums (state)
6182      state_t state;
6183 {
6184   arc_t arc;
6185
6186   curr_counted_states_num++;
6187   for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6188     curr_counted_arcs_num++;
6189 }
6190
6191 /* The function counts states and arcs of AUTOMATON.  */
6192 static void
6193 count_states_and_arcs (automaton, states_num, arcs_num)
6194      automaton_t automaton;
6195      int *states_num;
6196      int *arcs_num;
6197 {
6198   curr_counted_states_num = 0;
6199   curr_counted_arcs_num = 0;
6200   pass_states (automaton, incr_states_and_arcs_nums);
6201   *states_num = curr_counted_states_num;
6202   *arcs_num = curr_counted_arcs_num;
6203 }
6204
6205 /* The function builds one DFA AUTOMATON for fast pipeline hazards
6206    recognition after checking and simplifying IR of the
6207    description.  */
6208 static void
6209 build_automaton (automaton)
6210      automaton_t automaton;
6211 {
6212   int states_num;
6213   int arcs_num;
6214
6215   ticker_on (&NDFA_time);
6216   make_automaton (automaton);
6217   ticker_off (&NDFA_time);
6218   count_states_and_arcs (automaton, &states_num, &arcs_num);
6219   automaton->NDFA_states_num = states_num;
6220   automaton->NDFA_arcs_num = arcs_num;
6221   ticker_on (&NDFA_to_DFA_time);
6222   NDFA_to_DFA (automaton);
6223   ticker_off (&NDFA_to_DFA_time);
6224   count_states_and_arcs (automaton, &states_num, &arcs_num);
6225   automaton->DFA_states_num = states_num;
6226   automaton->DFA_arcs_num = arcs_num;
6227   if (!no_minimization_flag)
6228     {
6229       ticker_on (&minimize_time);
6230       minimize_DFA (automaton);
6231       ticker_off (&minimize_time);
6232       count_states_and_arcs (automaton, &states_num, &arcs_num);
6233       automaton->minimal_DFA_states_num = states_num;
6234       automaton->minimal_DFA_arcs_num = arcs_num;
6235     }
6236 }
6237
6238 \f
6239
6240 /* The page contains code for enumeration  of all states of an automaton.  */
6241
6242 /* Variable used for enumeration of all states of an automaton.  Its
6243    value is current number of automaton states.  */
6244 static int curr_state_order_num;
6245
6246 /* The function is called by function `pass_states' for enumerating
6247    states.  */
6248 static void
6249 set_order_state_num (state)
6250      state_t state;
6251 {
6252   state->order_state_num = curr_state_order_num;
6253   curr_state_order_num++;
6254 }
6255
6256 /* The function enumerates all states of AUTOMATON.  */
6257 static void
6258 enumerate_states (automaton)
6259      automaton_t automaton;
6260 {
6261   curr_state_order_num = 0;
6262   pass_states (automaton, set_order_state_num);
6263   automaton->achieved_states_num = curr_state_order_num;
6264 }
6265
6266 \f
6267
6268 /* The page contains code for finding equivalent automaton insns
6269    (ainsns).  */
6270
6271 /* The function inserts AINSN into cyclic list
6272    CYCLIC_EQUIV_CLASS_INSN_LIST of ainsns.  */
6273 static ainsn_t
6274 insert_ainsn_into_equiv_class (ainsn, cyclic_equiv_class_insn_list)
6275      ainsn_t ainsn;
6276      ainsn_t cyclic_equiv_class_insn_list;
6277 {
6278   if (cyclic_equiv_class_insn_list == NULL)
6279     ainsn->next_equiv_class_insn = ainsn;
6280   else
6281     {
6282       ainsn->next_equiv_class_insn
6283         = cyclic_equiv_class_insn_list->next_equiv_class_insn;
6284       cyclic_equiv_class_insn_list->next_equiv_class_insn = ainsn;
6285     }
6286   return ainsn;
6287 }
6288
6289 /* The function deletes equiv_class_insn into cyclic list of
6290    equivalent ainsns.  */
6291 static void
6292 delete_ainsn_from_equiv_class (equiv_class_insn)
6293      ainsn_t equiv_class_insn;
6294 {
6295   ainsn_t curr_equiv_class_insn;
6296   ainsn_t prev_equiv_class_insn;
6297
6298   prev_equiv_class_insn = equiv_class_insn;
6299   for (curr_equiv_class_insn = equiv_class_insn->next_equiv_class_insn;
6300        curr_equiv_class_insn != equiv_class_insn;
6301        curr_equiv_class_insn = curr_equiv_class_insn->next_equiv_class_insn)
6302     prev_equiv_class_insn = curr_equiv_class_insn;
6303   if (prev_equiv_class_insn != equiv_class_insn)
6304     prev_equiv_class_insn->next_equiv_class_insn
6305       = equiv_class_insn->next_equiv_class_insn;
6306 }
6307
6308 /* The function processes AINSN of a state in order to find equivalent
6309    ainsns.  INSN_ARCS_ARRAY is table: code of insn -> out arc of the
6310    state.  */
6311 static void
6312 process_insn_equiv_class (ainsn, insn_arcs_array)
6313      ainsn_t ainsn;
6314      arc_t *insn_arcs_array;
6315 {
6316   ainsn_t next_insn;
6317   ainsn_t curr_insn;
6318   ainsn_t cyclic_insn_list;
6319   arc_t arc;
6320
6321   if (insn_arcs_array [ainsn->insn_reserv_decl->insn_num] == NULL)
6322     abort ();
6323   curr_insn = ainsn;
6324   /* New class of ainsns which are not equivalent to given ainsn.  */
6325   cyclic_insn_list = NULL;
6326   do
6327     {
6328       next_insn = curr_insn->next_equiv_class_insn;
6329       arc = insn_arcs_array [curr_insn->insn_reserv_decl->insn_num];
6330       if (arc == NULL
6331           || (insn_arcs_array [ainsn->insn_reserv_decl->insn_num]->to_state
6332               != arc->to_state))
6333         {
6334           delete_ainsn_from_equiv_class (curr_insn);
6335           cyclic_insn_list = insert_ainsn_into_equiv_class (curr_insn,
6336                                                             cyclic_insn_list);
6337         }
6338       curr_insn = next_insn;
6339     }
6340   while (curr_insn != ainsn);
6341 }
6342
6343 /* The function processes STATE in order to find equivalent ainsns.  */
6344 static void
6345 process_state_for_insn_equiv_partition (state)
6346      state_t state;
6347 {
6348   arc_t arc;
6349   arc_t *insn_arcs_array;
6350   int i;
6351   vla_ptr_t insn_arcs_vect;
6352
6353   VLA_PTR_CREATE (insn_arcs_vect, 500, "insn arcs vector");
6354   VLA_PTR_EXPAND (insn_arcs_vect, description->insns_num);
6355   insn_arcs_array = VLA_PTR_BEGIN (insn_arcs_vect);
6356   /* Process insns of the arcs.  */
6357   for (i = 0; i < description->insns_num; i++)
6358     insn_arcs_array [i] = NULL;
6359   for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6360     insn_arcs_array [arc->insn->insn_reserv_decl->insn_num] = arc;
6361   for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6362     process_insn_equiv_class (arc->insn, insn_arcs_array);
6363   VLA_PTR_DELETE (insn_arcs_vect);
6364 }
6365
6366 /* The function searches for equivalent ainsns of AUTOMATON.  */
6367 static void
6368 set_insn_equiv_classes (automaton)
6369      automaton_t automaton;
6370 {
6371   ainsn_t ainsn;
6372   ainsn_t first_insn;
6373   ainsn_t curr_insn;
6374   ainsn_t cyclic_insn_list;
6375   ainsn_t insn_with_same_reservs;
6376   int equiv_classes_num;
6377
6378   /* All insns are included in one equivalence class.  */
6379   cyclic_insn_list = NULL;
6380   for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
6381     if (ainsn->first_insn_with_same_reservs)
6382       cyclic_insn_list = insert_ainsn_into_equiv_class (ainsn,
6383                                                         cyclic_insn_list);
6384   /* Process insns in order to make equivalence partition.  */
6385   pass_states (automaton, process_state_for_insn_equiv_partition);
6386   /* Enumerate equiv classes.  */
6387   for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
6388     /* Set undefined value.  */
6389     ainsn->insn_equiv_class_num = -1;
6390   equiv_classes_num = 0;
6391   for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
6392     if (ainsn->insn_equiv_class_num < 0)
6393       {
6394         first_insn = ainsn;
6395         if (!first_insn->first_insn_with_same_reservs)
6396           abort ();
6397         first_insn->first_ainsn_with_given_equialence_num = 1;
6398         curr_insn = first_insn;
6399         do
6400           {
6401             for (insn_with_same_reservs = curr_insn;
6402                  insn_with_same_reservs != NULL;
6403                  insn_with_same_reservs
6404                    = insn_with_same_reservs->next_same_reservs_insn)
6405               insn_with_same_reservs->insn_equiv_class_num = equiv_classes_num;
6406             curr_insn = curr_insn->next_equiv_class_insn;
6407           }
6408         while (curr_insn != first_insn);
6409         equiv_classes_num++;
6410       }
6411   automaton->insn_equiv_classes_num = equiv_classes_num;
6412 }
6413
6414 \f
6415
6416 /* This page contains code for creating DFA(s) and calls functions
6417    building them.  */
6418
6419
6420 /* The following value is used to prevent floating point overflow for
6421    estimating an automaton bound.  The value should be less DBL_MAX on
6422    the host machine.  We use here approximate minimum of maximal
6423    double floating point value required by ANSI C standard.  It
6424    will work for non ANSI sun compiler too.  */
6425
6426 #define MAX_FLOATING_POINT_VALUE_FOR_AUTOMATON_BOUND  1.0E37
6427
6428 /* The function estimate size of the single DFA used by PHR (pipeline
6429    hazards recognizer).  */
6430 static double
6431 estimate_one_automaton_bound ()
6432 {
6433   decl_t decl;
6434   double one_automaton_estimation_bound;
6435   double root_value;
6436   int i;
6437
6438   one_automaton_estimation_bound = 1.0;
6439   for (i = 0; i < description->decls_num; i++)
6440     {
6441       decl = description->decls [i];
6442       if (decl->mode == dm_unit)
6443         {
6444           root_value = exp (log (DECL_UNIT (decl)->max_occ_cycle_num + 1.0)
6445                             / automata_num);
6446           if (MAX_FLOATING_POINT_VALUE_FOR_AUTOMATON_BOUND / root_value
6447               > one_automaton_estimation_bound)
6448             one_automaton_estimation_bound *= root_value;
6449         }
6450     }
6451   return one_automaton_estimation_bound;
6452 }
6453
6454 /* The function compares unit declarations acoording to their maximal
6455    cycle in reservations.  */
6456 static int
6457 compare_max_occ_cycle_nums (unit_decl_1, unit_decl_2)
6458      const void *unit_decl_1;
6459      const void *unit_decl_2;
6460 {
6461   if ((DECL_UNIT (*(decl_t *) unit_decl_1)->max_occ_cycle_num)
6462       < (DECL_UNIT (*(decl_t *) unit_decl_2)->max_occ_cycle_num))
6463     return 1;
6464   else if ((DECL_UNIT (*(decl_t *) unit_decl_1)->max_occ_cycle_num)
6465            == (DECL_UNIT (*(decl_t *) unit_decl_2)->max_occ_cycle_num))
6466     return 0;
6467   else
6468     return -1;
6469 }
6470
6471 /* The function makes heuristic assigning automata to units.  Actually
6472    efficacy of the algorithm has been checked yet??? */
6473 static void
6474 units_to_automata_heuristic_distr ()
6475 {
6476   double estimation_bound;
6477   decl_t decl;
6478   decl_t *unit_decl_ptr;
6479   int automaton_num;
6480   int rest_units_num;
6481   double bound_value;
6482   vla_ptr_t unit_decls;
6483   int i;
6484
6485   if (description->units_num == 0)
6486     return;
6487   estimation_bound = estimate_one_automaton_bound ();
6488   VLA_PTR_CREATE (unit_decls, 150, "unit decls");
6489   for (i = 0; i < description->decls_num; i++)
6490     {
6491       decl = description->decls [i];
6492       if (decl->mode == dm_unit)
6493         VLA_PTR_ADD (unit_decls, decl);
6494     }
6495   qsort (VLA_PTR_BEGIN (unit_decls), VLA_PTR_LENGTH (unit_decls),
6496          sizeof (decl_t), compare_max_occ_cycle_nums);
6497   automaton_num = 0;
6498   unit_decl_ptr = VLA_PTR_BEGIN (unit_decls);
6499   bound_value = DECL_UNIT (*unit_decl_ptr)->max_occ_cycle_num;
6500   DECL_UNIT (*unit_decl_ptr)->corresponding_automaton_num = automaton_num;
6501   for (unit_decl_ptr++;
6502        unit_decl_ptr <= (decl_t *) VLA_PTR_LAST (unit_decls);
6503        unit_decl_ptr++)
6504     {
6505       rest_units_num
6506         = ((decl_t *) VLA_PTR_LAST (unit_decls) - unit_decl_ptr + 1);
6507       if (automata_num - automaton_num - 1 > rest_units_num)
6508         abort ();
6509       if (automaton_num < automata_num - 1
6510           && ((automata_num - automaton_num - 1 == rest_units_num)
6511               || (bound_value
6512                   > (estimation_bound
6513                      / (DECL_UNIT (*unit_decl_ptr)->max_occ_cycle_num)))))
6514         {
6515           bound_value = DECL_UNIT (*unit_decl_ptr)->max_occ_cycle_num;
6516           automaton_num++;
6517         }
6518       else
6519         bound_value *= DECL_UNIT (*unit_decl_ptr)->max_occ_cycle_num;
6520       DECL_UNIT (*unit_decl_ptr)->corresponding_automaton_num = automaton_num;
6521     }
6522   if (automaton_num != automata_num - 1)
6523     abort ();
6524   VLA_PTR_DELETE (unit_decls);
6525 }
6526
6527 /* The functions creates automaton insns for each automata.  Automaton
6528    insn is simply insn for given automaton which makes reservation
6529    only of units of the automaton.  */
6530 static ainsn_t
6531 create_ainsns ()
6532 {
6533   decl_t decl;
6534   ainsn_t first_ainsn;
6535   ainsn_t curr_ainsn;
6536   ainsn_t prev_ainsn;
6537   int i;
6538
6539   first_ainsn = NULL;
6540   prev_ainsn = NULL;
6541   for (i = 0; i < description->decls_num; i++)
6542     {
6543       decl = description->decls [i];
6544       if (decl->mode == dm_insn_reserv)
6545         {
6546           curr_ainsn = create_node (sizeof (struct ainsn));
6547           curr_ainsn->insn_reserv_decl = DECL_INSN_RESERV (decl);
6548           curr_ainsn->important_p = FALSE;
6549           curr_ainsn->next_ainsn = NULL;
6550           if (prev_ainsn == NULL)
6551             first_ainsn = curr_ainsn;
6552           else
6553             prev_ainsn->next_ainsn = curr_ainsn;
6554           prev_ainsn = curr_ainsn;
6555         }
6556     }
6557   return first_ainsn;
6558 }
6559
6560 /* The function assigns automata to units according to constructions
6561    `define_automaton' in the description.  */
6562 static void
6563 units_to_automata_distr ()
6564 {
6565   decl_t decl;
6566   int i;
6567   
6568   for (i = 0; i < description->decls_num; i++)
6569     {
6570       decl = description->decls [i];
6571       if (decl->mode == dm_unit)
6572         {
6573           if (DECL_UNIT (decl)->automaton_decl == NULL
6574               || (DECL_UNIT (decl)->automaton_decl->corresponding_automaton
6575                   == NULL))
6576             /* Distribute to the first automaton.  */
6577             DECL_UNIT (decl)->corresponding_automaton_num = 0;
6578           else
6579             DECL_UNIT (decl)->corresponding_automaton_num
6580               = (DECL_UNIT (decl)->automaton_decl
6581                  ->corresponding_automaton->automaton_order_num);
6582         }
6583     }
6584 }
6585
6586 /* The function creates DFA(s) for fast pipeline hazards recognition
6587    after checking and simplifying IR of the description.  */
6588 static void
6589 create_automata ()
6590 {
6591   automaton_t curr_automaton;
6592   automaton_t prev_automaton;
6593   decl_t decl;
6594   int curr_automaton_num;
6595   int i;
6596
6597   if (automata_num != 0)
6598     {
6599       units_to_automata_heuristic_distr ();
6600       for (prev_automaton = NULL, curr_automaton_num = 0;
6601            curr_automaton_num < automata_num;
6602            curr_automaton_num++, prev_automaton = curr_automaton)
6603         {
6604           curr_automaton = create_node (sizeof (struct automaton));
6605           curr_automaton->ainsn_list = create_ainsns ();
6606           curr_automaton->corresponding_automaton_decl = NULL;
6607           curr_automaton->next_automaton = NULL;
6608           curr_automaton->automaton_order_num = curr_automaton_num;
6609           if (prev_automaton == NULL)
6610             description->first_automaton = curr_automaton;
6611           else
6612             prev_automaton->next_automaton = curr_automaton;
6613         }
6614     }
6615   else
6616     {
6617       curr_automaton_num = 0;
6618       prev_automaton = NULL;
6619       for (i = 0; i < description->decls_num; i++)
6620         {
6621           decl = description->decls [i];
6622           if (decl->mode == dm_automaton
6623               && DECL_AUTOMATON (decl)->automaton_is_used)
6624             {
6625               curr_automaton = create_node (sizeof (struct automaton));
6626               curr_automaton->ainsn_list = create_ainsns ();
6627               curr_automaton->corresponding_automaton_decl
6628                 = DECL_AUTOMATON (decl);
6629               curr_automaton->next_automaton = NULL;
6630               DECL_AUTOMATON (decl)->corresponding_automaton = curr_automaton;
6631               curr_automaton->automaton_order_num = curr_automaton_num;
6632               if (prev_automaton == NULL)
6633                 description->first_automaton = curr_automaton;
6634               else
6635                 prev_automaton->next_automaton = curr_automaton;
6636               curr_automaton_num++;
6637               prev_automaton = curr_automaton;
6638             }
6639         }
6640       if (curr_automaton_num == 0)
6641         {
6642           curr_automaton = create_node (sizeof (struct automaton));
6643           curr_automaton->ainsn_list = create_ainsns ();
6644           curr_automaton->corresponding_automaton_decl = NULL;
6645           curr_automaton->next_automaton = NULL;
6646           description->first_automaton = curr_automaton;
6647         }
6648       units_to_automata_distr ();
6649     }
6650   NDFA_time = create_ticker ();
6651   ticker_off (&NDFA_time);
6652   NDFA_to_DFA_time = create_ticker ();
6653   ticker_off (&NDFA_to_DFA_time);
6654   minimize_time = create_ticker ();
6655   ticker_off (&minimize_time);
6656   equiv_time = create_ticker ();
6657   ticker_off (&equiv_time);
6658   for (curr_automaton = description->first_automaton;
6659        curr_automaton != NULL;
6660        curr_automaton = curr_automaton->next_automaton)
6661     {
6662       if (curr_automaton->corresponding_automaton_decl == NULL)
6663         fprintf (stderr, "Create anonymous automaton ...");
6664       else
6665         fprintf (stderr, "Create automaton `%s'...",
6666                  curr_automaton->corresponding_automaton_decl->name);
6667       create_alt_states (curr_automaton);
6668       form_ainsn_with_same_reservs (curr_automaton);
6669       build_automaton (curr_automaton);
6670       enumerate_states (curr_automaton);
6671       ticker_on (&equiv_time);
6672       set_insn_equiv_classes (curr_automaton);
6673       ticker_off (&equiv_time);
6674       fprintf (stderr, "done\n");
6675     }
6676 }
6677
6678 \f
6679
6680 /* This page contains code for forming string representation of
6681    regexp.  The representation is formed on IR obstack.  So you should
6682    not work with IR obstack between regexp_representation and
6683    finish_regexp_representation calls.  */
6684
6685 /* This recursive function forms string representation of regexp
6686    (without tailing '\0').  */
6687 static void
6688 form_regexp (regexp)
6689      regexp_t regexp;
6690 {
6691   int i;
6692     
6693   if (regexp->mode == rm_unit || regexp->mode == rm_reserv)
6694     {
6695       const char *name = (regexp->mode == rm_unit
6696                           ? REGEXP_UNIT (regexp)->name
6697                           : REGEXP_RESERV (regexp)->name);
6698
6699       obstack_grow (&irp, name, strlen (name));
6700     }
6701   else if (regexp->mode == rm_sequence)
6702     for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
6703       {
6704         if (i != 0)
6705           obstack_1grow (&irp, ',');
6706         form_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
6707       }
6708   else if (regexp->mode == rm_allof)
6709     {
6710       obstack_1grow (&irp, '(');
6711       for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
6712         {
6713           if (i != 0)
6714             obstack_1grow (&irp, '+');
6715           if (REGEXP_ALLOF (regexp)->regexps[i]->mode == rm_sequence
6716               || REGEXP_ALLOF (regexp)->regexps[i]->mode == rm_oneof)
6717             obstack_1grow (&irp, '(');
6718           form_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
6719           if (REGEXP_ALLOF (regexp)->regexps[i]->mode == rm_sequence
6720               || REGEXP_ALLOF (regexp)->regexps[i]->mode == rm_oneof)
6721             obstack_1grow (&irp, ')');
6722         }
6723       obstack_1grow (&irp, ')');
6724     }
6725   else if (regexp->mode == rm_oneof)
6726     for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
6727       {
6728         if (i != 0)
6729           obstack_1grow (&irp, '|');
6730         if (REGEXP_ONEOF (regexp)->regexps[i]->mode == rm_sequence)
6731           obstack_1grow (&irp, '(');
6732         form_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
6733         if (REGEXP_ONEOF (regexp)->regexps[i]->mode == rm_sequence)
6734           obstack_1grow (&irp, ')');
6735       }
6736   else if (regexp->mode == rm_repeat)
6737     {
6738       char digits [30];
6739
6740       if (REGEXP_REPEAT (regexp)->regexp->mode == rm_sequence
6741           || REGEXP_REPEAT (regexp)->regexp->mode == rm_allof
6742           || REGEXP_REPEAT (regexp)->regexp->mode == rm_oneof)
6743         obstack_1grow (&irp, '(');
6744       form_regexp (REGEXP_REPEAT (regexp)->regexp);
6745       if (REGEXP_REPEAT (regexp)->regexp->mode == rm_sequence
6746           || REGEXP_REPEAT (regexp)->regexp->mode == rm_allof
6747           || REGEXP_REPEAT (regexp)->regexp->mode == rm_oneof)
6748         obstack_1grow (&irp, ')');
6749       sprintf (digits, "*%d", REGEXP_REPEAT (regexp)->repeat_num);
6750       obstack_grow (&irp, digits, strlen (digits));
6751     }
6752   else if (regexp->mode == rm_nothing)
6753     obstack_grow (&irp, NOTHING_NAME, strlen (NOTHING_NAME));
6754   else
6755     abort ();
6756 }
6757
6758 /* The function returns string representation of REGEXP on IR
6759    obstack.  */
6760 static const char *
6761 regexp_representation (regexp)
6762      regexp_t regexp;
6763 {
6764   form_regexp (regexp);
6765   obstack_1grow (&irp, '\0');
6766   return obstack_base (&irp);
6767 }
6768
6769 /* The function frees memory allocated for last formed string
6770    representation of regexp.  */
6771 static void
6772 finish_regexp_representation ()
6773 {
6774   int length = obstack_object_size (&irp);
6775   
6776   obstack_blank_fast (&irp, -length);
6777 }
6778
6779 \f
6780
6781 /* This page contains code for output PHR (pipeline hazards recognizer).  */
6782
6783 /* The function outputs minimal C type which is sufficient for
6784    representation numbers in range min_range_value and
6785    max_range_value.  Because host machine and build machine may be
6786    different, we use here minimal values required by ANSI C standard
6787    instead of UCHAR_MAX, SHRT_MAX, SHRT_MIN, etc.  This is a good
6788    approximation.  */
6789
6790 static void
6791 output_range_type (f, min_range_value, max_range_value)
6792      FILE *f;
6793      long int min_range_value;
6794      long int max_range_value;
6795 {
6796   if (min_range_value >= 0 && max_range_value <= 255)
6797     fprintf (f, "unsigned char");
6798   else if (min_range_value >= -127 && max_range_value <= 127)
6799     fprintf (f, "signed char");
6800   else if (min_range_value >= 0 && max_range_value <= 65535)
6801     fprintf (f, "unsigned short");
6802   else if (min_range_value >= -32767 && max_range_value <= 32767)
6803     fprintf (f, "short");
6804   else
6805     fprintf (f, "int");
6806 }
6807
6808 /* The following macro value is used as value of member
6809    `longest_path_length' of state when we are processing path and the
6810    state on the path.  */
6811
6812 #define ON_THE_PATH -2
6813
6814 /* The following recursive function searches for the length of the
6815    longest path starting from STATE which does not contain cycles and
6816    `cycle advance' arcs.  */
6817
6818 static int
6819 longest_path_length (state)
6820      state_t state;
6821 {
6822   arc_t arc;
6823   int length, result;
6824   
6825   if (state->longest_path_length == ON_THE_PATH)
6826     /* We don't expect the path cycle here.  Our graph may contain
6827        only cycles with one state on the path not containing `cycle
6828        advance' arcs -- see comment below.  */
6829     abort ();
6830   else if (state->longest_path_length != UNDEFINED_LONGEST_PATH_LENGTH)
6831     /* We alreday visited the state.  */
6832     return state->longest_path_length;
6833
6834   result = 0;
6835   for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6836     /* Ignore cycles containing one state and `cycle advance' arcs.  */
6837     if (arc->to_state != state
6838         && (arc->insn->insn_reserv_decl
6839             != DECL_INSN_RESERV (advance_cycle_insn_decl)))
6840     {
6841       length = longest_path_length (arc->to_state);
6842       if (length > result)
6843         result = length;
6844     }
6845   state->longest_path_length = result + 1;
6846   return result;
6847 }
6848
6849 /* The following variable value is value of the corresponding global
6850    variable in the automaton based pipeline interface.  */
6851
6852 static int max_dfa_issue_rate;
6853
6854 /* The following function processes the longest path length staring
6855    from STATE to find MAX_DFA_ISSUE_RATE.  */
6856
6857 static void
6858 process_state_longest_path_length (state)
6859      state_t state;
6860 {
6861   int value;
6862
6863   value = longest_path_length (state);
6864   if (value > max_dfa_issue_rate)
6865     max_dfa_issue_rate = value;
6866 }
6867
6868 /* The following macro value is name of the corresponding global
6869    variable in the automaton based pipeline interface.  */
6870
6871 #define MAX_DFA_ISSUE_RATE_VAR_NAME "max_dfa_issue_rate"
6872
6873 /* The following function calculates value of the the corresponding
6874    global variable and outputs its declaration.  */
6875
6876 static void
6877 output_dfa_max_issue_rate ()
6878 {
6879   automaton_t automaton;
6880
6881   if (UNDEFINED_LONGEST_PATH_LENGTH == ON_THE_PATH || ON_THE_PATH >= 0)
6882     abort ();
6883   max_dfa_issue_rate = 0;
6884   for (automaton = description->first_automaton;
6885        automaton != NULL;
6886        automaton = automaton->next_automaton)
6887     pass_states (automaton, process_state_longest_path_length);
6888   fprintf (output_file, "\nint %s = %d;\n",
6889            MAX_DFA_ISSUE_RATE_VAR_NAME, max_dfa_issue_rate);
6890 }
6891
6892 /* The function outputs all initialization values of VECT with length
6893    vect_length.  */
6894 static void
6895 output_vect (vect, vect_length)
6896      vect_el_t *vect;
6897      int vect_length;
6898 {
6899   int els_on_line;
6900
6901   els_on_line = 1;
6902   if (vect_length == 0)
6903     fprintf (output_file,
6904              "0 /* This is dummy el because the vect is empty */");
6905   else
6906     {
6907       do
6908         {
6909           fprintf (output_file, "%5ld", (long) *vect);
6910           vect_length--;
6911           if (els_on_line == 10)
6912             {
6913               els_on_line = 0;
6914               fprintf (output_file, ",\n");
6915             }
6916           else if (vect_length != 0)
6917             fprintf (output_file, ", ");
6918           els_on_line++;
6919           vect++;
6920         }
6921       while (vect_length != 0);
6922     }
6923 }
6924
6925 /* The following is name of the structure which represents DFA(s) for
6926    PHR.  */
6927 #define CHIP_NAME "DFA_chip"
6928
6929 /* The following is name of member which represents state of a DFA for
6930    PHR.  */
6931 static void
6932 output_chip_member_name (f, automaton)
6933      FILE *f;
6934      automaton_t automaton;
6935 {
6936   if (automaton->corresponding_automaton_decl == NULL)
6937     fprintf (f, "automaton_state_%d", automaton->automaton_order_num);
6938   else
6939     fprintf (f, "%s_automaton_state",
6940              automaton->corresponding_automaton_decl->name);
6941 }
6942
6943 /* The following is name of temporary variable which stores state of a
6944    DFA for PHR.  */
6945 static void
6946 output_temp_chip_member_name (f, automaton)
6947      FILE *f;
6948      automaton_t automaton;
6949 {
6950   fprintf (f, "_");
6951   output_chip_member_name (f, automaton);
6952 }
6953
6954 /* This is name of macro value which is code of pseudo_insn
6955    representing advancing cpu cycle.  Its value is used as internal
6956    code unknown insn.  */
6957 #define ADVANCE_CYCLE_VALUE_NAME "DFA__ADVANCE_CYCLE"
6958
6959 /* Output name of translate vector for given automaton.  */
6960 static void
6961 output_translate_vect_name (f, automaton)
6962      FILE *f;
6963      automaton_t automaton;
6964 {
6965   if (automaton->corresponding_automaton_decl == NULL)
6966     fprintf (f, "translate_%d", automaton->automaton_order_num);
6967   else
6968     fprintf (f, "%s_translate", automaton->corresponding_automaton_decl->name);
6969 }
6970
6971 /* Output name for simple transition table representation.  */
6972 static void
6973 output_trans_full_vect_name (f, automaton)
6974      FILE *f;
6975      automaton_t automaton;
6976 {
6977   if (automaton->corresponding_automaton_decl == NULL)
6978     fprintf (f, "transitions_%d", automaton->automaton_order_num);
6979   else
6980     fprintf (f, "%s_transitions",
6981              automaton->corresponding_automaton_decl->name);
6982 }
6983
6984 /* Output name of comb vector of the transition table for given
6985    automaton.  */
6986 static void
6987 output_trans_comb_vect_name (f, automaton)
6988      FILE *f;
6989      automaton_t automaton;
6990 {
6991   if (automaton->corresponding_automaton_decl == NULL)
6992     fprintf (f, "transitions_%d", automaton->automaton_order_num);
6993   else
6994     fprintf (f, "%s_transitions",
6995              automaton->corresponding_automaton_decl->name);
6996 }
6997
6998 /* Output name of check vector of the transition table for given
6999    automaton.  */
7000 static void
7001 output_trans_check_vect_name (f, automaton)
7002      FILE *f;
7003      automaton_t automaton;
7004 {
7005   if (automaton->corresponding_automaton_decl == NULL)
7006     fprintf (f, "check_%d", automaton->automaton_order_num);
7007   else
7008     fprintf (f, "%s_check", automaton->corresponding_automaton_decl->name);
7009 }
7010
7011 /* Output name of base vector of the transition table for given
7012    automaton.  */
7013 static void
7014 output_trans_base_vect_name (f, automaton)
7015      FILE *f;
7016      automaton_t automaton;
7017 {
7018   if (automaton->corresponding_automaton_decl == NULL)
7019     fprintf (f, "base_%d", automaton->automaton_order_num);
7020   else
7021     fprintf (f, "%s_base", automaton->corresponding_automaton_decl->name);
7022 }
7023
7024 /* Output name for simple alternatives number representation.  */
7025 static void
7026 output_state_alts_full_vect_name (f, automaton)
7027      FILE *f;
7028      automaton_t automaton;
7029 {
7030   if (automaton->corresponding_automaton_decl == NULL)
7031     fprintf (f, "state_alts_%d", automaton->automaton_order_num);
7032   else
7033     fprintf (f, "%s_state_alts",
7034              automaton->corresponding_automaton_decl->name);
7035 }
7036
7037 /* Output name of comb vector of the alternatives number table for given
7038    automaton.  */
7039 static void
7040 output_state_alts_comb_vect_name (f, automaton)
7041      FILE *f;
7042      automaton_t automaton;
7043 {
7044   if (automaton->corresponding_automaton_decl == NULL)
7045     fprintf (f, "state_alts_%d", automaton->automaton_order_num);
7046   else
7047     fprintf (f, "%s_state_alts",
7048              automaton->corresponding_automaton_decl->name);
7049 }
7050
7051 /* Output name of check vector of the alternatives number table for given
7052    automaton.  */
7053 static void
7054 output_state_alts_check_vect_name (f, automaton)
7055      FILE *f;
7056      automaton_t automaton;
7057 {
7058   if (automaton->corresponding_automaton_decl == NULL)
7059     fprintf (f, "check_state_alts_%d", automaton->automaton_order_num);
7060   else
7061     fprintf (f, "%s_check_state_alts",
7062              automaton->corresponding_automaton_decl->name);
7063 }
7064
7065 /* Output name of base vector of the alternatives number table for given
7066    automaton.  */
7067 static void
7068 output_state_alts_base_vect_name (f, automaton)
7069      FILE *f;
7070      automaton_t automaton;
7071 {
7072   if (automaton->corresponding_automaton_decl == NULL)
7073     fprintf (f, "base_state_alts_%d", automaton->automaton_order_num);
7074   else
7075     fprintf (f, "%s_base_state_alts",
7076              automaton->corresponding_automaton_decl->name);
7077 }
7078
7079 /* Output name of simple min issue delay table representation.  */
7080 static void
7081 output_min_issue_delay_vect_name (f, automaton)
7082      FILE *f;
7083      automaton_t automaton;
7084 {
7085   if (automaton->corresponding_automaton_decl == NULL)
7086     fprintf (f, "min_issue_delay_%d", automaton->automaton_order_num);
7087   else
7088     fprintf (f, "%s_min_issue_delay",
7089              automaton->corresponding_automaton_decl->name);
7090 }
7091
7092 /* Output name of deadlock vector for given automaton.  */
7093 static void
7094 output_dead_lock_vect_name (f, automaton)
7095      FILE *f;
7096      automaton_t automaton;
7097 {
7098   if (automaton->corresponding_automaton_decl == NULL)
7099     fprintf (f, "dead_lock_%d", automaton->automaton_order_num);
7100   else
7101     fprintf (f, "%s_dead_lock", automaton->corresponding_automaton_decl->name);
7102 }
7103
7104 /* Output name of reserved units table for AUTOMATON into file F.  */
7105 static void
7106 output_reserved_units_table_name (f, automaton)
7107      FILE *f;
7108      automaton_t automaton;
7109 {
7110   if (automaton->corresponding_automaton_decl == NULL)
7111     fprintf (f, "reserved_units_%d", automaton->automaton_order_num);
7112   else
7113     fprintf (f, "%s_reserved_units",
7114              automaton->corresponding_automaton_decl->name);
7115 }
7116
7117 /* Name of the PHR interface macro.  */
7118 #define AUTOMATON_STATE_ALTS_MACRO_NAME "AUTOMATON_STATE_ALTS"
7119
7120 /* Name of the PHR interface macro.  */
7121 #define CPU_UNITS_QUERY_MACRO_NAME "CPU_UNITS_QUERY"
7122
7123 /* Names of an internal functions: */
7124 #define INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME "internal_min_issue_delay"
7125
7126 /* This is external type of DFA(s) state.  */
7127 #define STATE_TYPE_NAME "state_t"
7128
7129 #define INTERNAL_TRANSITION_FUNC_NAME "internal_state_transition"
7130
7131 #define INTERNAL_STATE_ALTS_FUNC_NAME "internal_state_alts"
7132
7133 #define INTERNAL_RESET_FUNC_NAME "internal_reset"
7134
7135 #define INTERNAL_DEAD_LOCK_FUNC_NAME "internal_state_dead_lock_p"
7136
7137 #define INTERNAL_INSN_LATENCY_FUNC_NAME "internal_insn_latency"
7138
7139 /* Name of cache of insn dfa codes.  */
7140 #define DFA_INSN_CODES_VARIABLE_NAME "dfa_insn_codes"
7141
7142 /* Name of length of cache of insn dfa codes.  */
7143 #define DFA_INSN_CODES_LENGTH_VARIABLE_NAME "dfa_insn_codes_length"
7144
7145 /* Names of the PHR interface functions: */
7146 #define SIZE_FUNC_NAME "state_size"
7147
7148 #define TRANSITION_FUNC_NAME "state_transition"
7149
7150 #define STATE_ALTS_FUNC_NAME "state_alts"
7151
7152 #define MIN_ISSUE_DELAY_FUNC_NAME "min_issue_delay"
7153
7154 #define MIN_INSN_CONFLICT_DELAY_FUNC_NAME "min_insn_conflict_delay"
7155
7156 #define DEAD_LOCK_FUNC_NAME "state_dead_lock_p"
7157
7158 #define RESET_FUNC_NAME "state_reset"
7159
7160 #define INSN_LATENCY_FUNC_NAME "insn_latency"
7161
7162 #define PRINT_RESERVATION_FUNC_NAME "print_reservation"
7163
7164 #define GET_CPU_UNIT_CODE_FUNC_NAME "get_cpu_unit_code"
7165
7166 #define CPU_UNIT_RESERVATION_P_FUNC_NAME "cpu_unit_reservation_p"
7167
7168 #define DFA_START_FUNC_NAME  "dfa_start"
7169
7170 #define DFA_FINISH_FUNC_NAME "dfa_finish"
7171
7172 /* Names of parameters of the PHR interface functions.  */
7173 #define STATE_NAME "state"
7174
7175 #define INSN_PARAMETER_NAME "insn"
7176
7177 #define INSN2_PARAMETER_NAME "insn2"
7178
7179 #define CHIP_PARAMETER_NAME "chip"
7180
7181 #define FILE_PARAMETER_NAME "f"
7182
7183 #define CPU_UNIT_NAME_PARAMETER_NAME "cpu_unit_name"
7184
7185 #define CPU_CODE_PARAMETER_NAME "cpu_unit_code"
7186
7187 /* Names of the variables whose values are internal insn code of rtx
7188    insn.  */
7189 #define INTERNAL_INSN_CODE_NAME "insn_code"
7190
7191 #define INTERNAL_INSN2_CODE_NAME "insn2_code"
7192
7193 /* Names of temporary variables in some functions.  */
7194 #define TEMPORARY_VARIABLE_NAME "temp"
7195
7196 #define I_VARIABLE_NAME "i"
7197
7198 /* Name of result variable in some functions.  */
7199 #define RESULT_VARIABLE_NAME "res"
7200
7201 /* Name of function (attribute) to translate insn into number of insn
7202    alternatives reservation.  */
7203 #define INSN_ALTS_FUNC_NAME "insn_alts"
7204
7205 /* Name of function (attribute) to translate insn into internal insn
7206    code.  */
7207 #define INTERNAL_DFA_INSN_CODE_FUNC_NAME "internal_dfa_insn_code"
7208
7209 /* Name of function (attribute) to translate insn into internal insn
7210    code with caching.  */
7211 #define DFA_INSN_CODE_FUNC_NAME "dfa_insn_code"
7212
7213 /* Name of function (attribute) to translate insn into internal insn
7214    code.  */
7215 #define INSN_DEFAULT_LATENCY_FUNC_NAME "insn_default_latency"
7216
7217 /* Name of function (attribute) to translate insn into internal insn
7218    code.  */
7219 #define BYPASS_P_FUNC_NAME "bypass_p"
7220
7221 /* Output C type which is used for representation of codes of states
7222    of AUTOMATON.  */
7223 static void
7224 output_state_member_type (f, automaton)
7225      FILE *f;
7226      automaton_t automaton;
7227 {
7228   output_range_type (f, 0, automaton->achieved_states_num);
7229 }
7230
7231 /* Output definition of the structure representing current DFA(s)
7232    state(s).  */
7233 static void
7234 output_chip_definitions ()
7235 {
7236   automaton_t automaton;
7237
7238   fprintf (output_file, "struct %s\n{\n", CHIP_NAME);
7239   for (automaton = description->first_automaton;
7240        automaton != NULL;
7241        automaton = automaton->next_automaton)
7242     {
7243       fprintf (output_file, "  ");
7244       output_state_member_type (output_file, automaton);
7245       fprintf (output_file, " ");
7246       output_chip_member_name (output_file, automaton);
7247       fprintf (output_file, ";\n");
7248     }
7249   fprintf (output_file, "};\n\n");
7250 #if 0
7251   fprintf (output_file, "static struct %s %s;\n\n", CHIP_NAME, CHIP_NAME);
7252 #endif
7253 }
7254
7255
7256 /* The function outputs translate vector of internal insn code into
7257    insn equivalence class number.  The equivalence class number is
7258    used to access to table and vectors reprewsenting DFA(s).  */
7259 static void
7260 output_translate_vect (automaton)
7261      automaton_t automaton;
7262 {
7263   ainsn_t ainsn;
7264   int insn_value;
7265   vla_hwint_t translate_vect;
7266
7267   VLA_HWINT_CREATE (translate_vect, 250, "translate vector");
7268   VLA_HWINT_EXPAND (translate_vect, description->insns_num);
7269   for (insn_value = 0; insn_value <= description->insns_num; insn_value++)
7270     /* Undefined value */
7271     VLA_HWINT (translate_vect, insn_value) = automaton->insn_equiv_classes_num;
7272   for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
7273     VLA_HWINT (translate_vect, ainsn->insn_reserv_decl->insn_num)
7274       = ainsn->insn_equiv_class_num;
7275   fprintf (output_file,
7276            "/* Vector translating external insn codes to internal ones.*/\n");
7277   fprintf (output_file, "static const ");
7278   output_range_type (output_file, 0, automaton->insn_equiv_classes_num);
7279   fprintf (output_file, " ");
7280   output_translate_vect_name (output_file, automaton);
7281   fprintf (output_file, "[] = {\n");
7282   output_vect (VLA_HWINT_BEGIN (translate_vect),
7283                VLA_HWINT_LENGTH (translate_vect));
7284   fprintf (output_file, "};\n\n");
7285   VLA_HWINT_DELETE (translate_vect);
7286 }
7287
7288 /* The value in a table state x ainsn -> something which represents
7289    undefined value.  */
7290 static int undefined_vect_el_value;
7291
7292 /* The following function returns nonzero value if the best
7293    representation of the table is comb vector.  */
7294 static int
7295 comb_vect_p (tab)
7296      state_ainsn_table_t tab;
7297 {
7298   return  (2 * VLA_HWINT_LENGTH (tab->full_vect)
7299            > 5 * VLA_HWINT_LENGTH (tab->comb_vect));
7300 }
7301
7302 /* The following function creates new table for AUTOMATON.  */
7303 static state_ainsn_table_t
7304 create_state_ainsn_table (automaton)
7305      automaton_t automaton;
7306 {
7307   state_ainsn_table_t tab;
7308   int full_vect_length;
7309   int i;
7310
7311   tab = create_node (sizeof (struct state_ainsn_table));
7312   tab->automaton = automaton;
7313   VLA_HWINT_CREATE (tab->comb_vect, 10000, "comb vector");
7314   VLA_HWINT_CREATE (tab->check_vect, 10000, "check vector");
7315   VLA_HWINT_CREATE (tab->base_vect, 1000, "base vector");
7316   VLA_HWINT_EXPAND (tab->base_vect, automaton->achieved_states_num);
7317   VLA_HWINT_CREATE (tab->full_vect, 10000, "full vector");
7318   full_vect_length = (automaton->insn_equiv_classes_num
7319                       * automaton->achieved_states_num);
7320   VLA_HWINT_EXPAND (tab->full_vect, full_vect_length);
7321   for (i = 0; i < full_vect_length; i++)
7322     VLA_HWINT (tab->full_vect, i) = undefined_vect_el_value;
7323   tab->min_base_vect_el_value = 0;
7324   tab->max_base_vect_el_value = 0;
7325   tab->min_comb_vect_el_value = 0;
7326   tab->max_comb_vect_el_value = 0;
7327   return tab;
7328 }
7329
7330 /* The following function outputs the best C representation of the
7331    table TAB of given TABLE_NAME.  */
7332 static void
7333 output_state_ainsn_table (tab, table_name, output_full_vect_name_func,
7334                           output_comb_vect_name_func,
7335                           output_check_vect_name_func,
7336                           output_base_vect_name_func)
7337      state_ainsn_table_t tab;
7338      char *table_name;
7339      void (*output_full_vect_name_func) PARAMS ((FILE *, automaton_t));
7340      void (*output_comb_vect_name_func) PARAMS ((FILE *, automaton_t));
7341      void (*output_check_vect_name_func) PARAMS ((FILE *, automaton_t));
7342      void (*output_base_vect_name_func) PARAMS ((FILE *, automaton_t));
7343 {
7344   if (!comb_vect_p (tab))
7345     {
7346       fprintf (output_file, "/* Vector for %s.  */\n", table_name);
7347       fprintf (output_file, "static const ");
7348       output_range_type (output_file, tab->min_comb_vect_el_value,
7349                          tab->max_comb_vect_el_value);
7350       fprintf (output_file, " ");
7351       (*output_full_vect_name_func) (output_file, tab->automaton);
7352       fprintf (output_file, "[] = {\n");
7353       output_vect (VLA_HWINT_BEGIN (tab->full_vect),
7354                    VLA_HWINT_LENGTH (tab->full_vect));
7355       fprintf (output_file, "};\n\n");
7356     }
7357   else
7358     {
7359       fprintf (output_file, "/* Comb vector for %s.  */\n", table_name);
7360       fprintf (output_file, "static const ");
7361       output_range_type (output_file, tab->min_comb_vect_el_value,
7362                          tab->max_comb_vect_el_value);
7363       fprintf (output_file, " ");
7364       (*output_comb_vect_name_func) (output_file, tab->automaton);
7365       fprintf (output_file, "[] = {\n");
7366       output_vect (VLA_HWINT_BEGIN (tab->comb_vect),
7367                    VLA_HWINT_LENGTH (tab->comb_vect));
7368       fprintf (output_file, "};\n\n");
7369       fprintf (output_file, "/* Check vector for %s.  */\n", table_name);
7370       fprintf (output_file, "static const ");
7371       output_range_type (output_file, 0, tab->automaton->achieved_states_num);
7372       fprintf (output_file, " ");
7373       (*output_check_vect_name_func) (output_file, tab->automaton);
7374       fprintf (output_file, "[] = {\n");
7375       output_vect (VLA_HWINT_BEGIN (tab->check_vect),
7376                    VLA_HWINT_LENGTH (tab->check_vect));
7377       fprintf (output_file, "};\n\n");
7378       fprintf (output_file, "/* Base vector for %s.  */\n", table_name);
7379       fprintf (output_file, "static const ");
7380       output_range_type (output_file, tab->min_base_vect_el_value,
7381                          tab->max_base_vect_el_value);
7382       fprintf (output_file, " ");
7383       (*output_base_vect_name_func) (output_file, tab->automaton);
7384       fprintf (output_file, "[] = {\n");
7385       output_vect (VLA_HWINT_BEGIN (tab->base_vect),
7386                    VLA_HWINT_LENGTH (tab->base_vect));
7387       fprintf (output_file, "};\n\n");
7388     }
7389 }
7390
7391 /* The following function adds vector with length VECT_LENGTH and
7392    elements pointed by VECT to table TAB as its line with number
7393    VECT_NUM.  */
7394 static void
7395 add_vect (tab, vect_num, vect, vect_length)
7396      state_ainsn_table_t tab;
7397      int vect_num;
7398      vect_el_t *vect;
7399      int vect_length;
7400 {
7401   int real_vect_length;
7402   vect_el_t *comb_vect_start;
7403   vect_el_t *check_vect_start;
7404   int comb_vect_index;
7405   int comb_vect_els_num;
7406   int vect_index;
7407   int first_unempty_vect_index;
7408   int additional_els_num;
7409   int no_state_value;
7410   vect_el_t vect_el;
7411   int i;
7412
7413   if (vect_length == 0)
7414     abort ();
7415   real_vect_length = tab->automaton->insn_equiv_classes_num;
7416   if (vect [vect_length - 1] == undefined_vect_el_value)
7417     abort ();
7418   /* Form full vector in the table: */
7419   for (i = 0; i < vect_length; i++)
7420     VLA_HWINT (tab->full_vect,
7421                i + tab->automaton->insn_equiv_classes_num * vect_num)
7422       = vect [i];
7423   /* Form comb vector in the table: */
7424   if (VLA_HWINT_LENGTH (tab->comb_vect) != VLA_HWINT_LENGTH (tab->check_vect))
7425     abort ();
7426   comb_vect_start = VLA_HWINT_BEGIN (tab->comb_vect);
7427   comb_vect_els_num = VLA_HWINT_LENGTH (tab->comb_vect);
7428   for (first_unempty_vect_index = 0;
7429        first_unempty_vect_index < vect_length;
7430        first_unempty_vect_index++)
7431     if (vect [first_unempty_vect_index] != undefined_vect_el_value)
7432       break;
7433   /* Search for the place in comb vect for the inserted vect.  */
7434   for (comb_vect_index = 0;
7435        comb_vect_index < comb_vect_els_num;
7436        comb_vect_index++)
7437     {
7438       for (vect_index = first_unempty_vect_index;
7439            vect_index < vect_length
7440              && vect_index + comb_vect_index < comb_vect_els_num;
7441            vect_index++)
7442         if (vect [vect_index] != undefined_vect_el_value
7443             && (comb_vect_start [vect_index + comb_vect_index]
7444                 != undefined_vect_el_value))
7445           break;
7446       if (vect_index >= vect_length
7447           || vect_index + comb_vect_index >= comb_vect_els_num)
7448         break;
7449     }
7450   /* Slot was found.  */
7451   additional_els_num = comb_vect_index + real_vect_length - comb_vect_els_num;
7452   if (additional_els_num < 0)
7453     additional_els_num = 0;
7454   /* Expand comb and check vectors.  */
7455   vect_el = undefined_vect_el_value;
7456   no_state_value = tab->automaton->achieved_states_num;
7457   while (additional_els_num > 0)
7458     {
7459       VLA_HWINT_ADD (tab->comb_vect, vect_el);
7460       VLA_HWINT_ADD (tab->check_vect, no_state_value);
7461       additional_els_num--;
7462     }
7463   comb_vect_start = VLA_HWINT_BEGIN (tab->comb_vect);
7464   check_vect_start = VLA_HWINT_BEGIN (tab->check_vect);
7465   if (VLA_HWINT_LENGTH (tab->comb_vect)
7466       < (size_t) (comb_vect_index + real_vect_length))
7467     abort ();
7468   /* Fill comb and check vectors.  */
7469   for (vect_index = 0; vect_index < vect_length; vect_index++)
7470     if (vect [vect_index] != undefined_vect_el_value)
7471       {
7472         if (comb_vect_start [comb_vect_index + vect_index]
7473             != undefined_vect_el_value)
7474           abort ();
7475         comb_vect_start [comb_vect_index + vect_index] = vect [vect_index];
7476         if (vect [vect_index] < 0)
7477           abort ();
7478         if (tab->max_comb_vect_el_value < vect [vect_index])
7479           tab->max_comb_vect_el_value = vect [vect_index];
7480         if (tab->min_comb_vect_el_value > vect [vect_index])
7481           tab->min_comb_vect_el_value = vect [vect_index];
7482         check_vect_start [comb_vect_index + vect_index] = vect_num;
7483       }
7484   if (tab->max_base_vect_el_value < comb_vect_index)
7485     tab->max_base_vect_el_value = comb_vect_index;
7486   if (tab->min_base_vect_el_value > comb_vect_index)
7487     tab->min_base_vect_el_value = comb_vect_index;
7488   VLA_HWINT (tab->base_vect, vect_num) = comb_vect_index;
7489 }
7490
7491 /* Return number of out arcs of STATE.  */
7492 static int
7493 out_state_arcs_num (state)
7494      state_t state;
7495 {
7496   int result;
7497   arc_t arc;
7498
7499   result = 0;
7500   for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
7501     {
7502       if (arc->insn == NULL)
7503         abort ();
7504       if (arc->insn->first_ainsn_with_given_equialence_num)
7505         result++;
7506     }
7507   return result;
7508 }
7509
7510 /* Compare number of possible transitions from the states.  */
7511 static int
7512 compare_transition_els_num (state_ptr_1, state_ptr_2)
7513      const void *state_ptr_1;
7514      const void *state_ptr_2;
7515 {
7516   int transition_els_num_1;
7517   int transition_els_num_2;
7518
7519   transition_els_num_1 = out_state_arcs_num (*(state_t *) state_ptr_1);
7520   transition_els_num_2 = out_state_arcs_num (*(state_t *) state_ptr_2);
7521   if (transition_els_num_1 < transition_els_num_2)
7522     return 1;
7523   else if (transition_els_num_1 == transition_els_num_2)
7524     return 0;
7525   else
7526     return -1;
7527 }
7528
7529 /* The function adds element EL_VALUE to vector VECT for a table state
7530    x AINSN.  */
7531 static void
7532 add_vect_el (vect, ainsn, el_value)
7533      vla_hwint_t *vect;
7534      ainsn_t ainsn;
7535      int el_value;
7536 {
7537   int equiv_class_num;
7538   int vect_index;
7539
7540   if (ainsn == NULL)
7541     abort ();
7542   equiv_class_num = ainsn->insn_equiv_class_num;
7543   for (vect_index = VLA_HWINT_LENGTH (*vect);
7544        vect_index <= equiv_class_num;
7545        vect_index++)
7546     VLA_HWINT_ADD (*vect, undefined_vect_el_value);
7547   VLA_HWINT (*vect, equiv_class_num) = el_value;
7548 }
7549
7550 /* This is for forming vector of states of an automaton.  */
7551 static vla_ptr_t output_states_vect;
7552
7553 /* The function is called by function pass_states.  The function adds
7554    STATE to `output_states_vect'.  */
7555 static void
7556 add_states_vect_el (state)
7557      state_t state;
7558 {
7559   VLA_PTR_ADD (output_states_vect, state);
7560 }
7561
7562 /* Form and output vectors (comb, check, base or full vector)
7563    representing transition table of AUTOMATON.  */
7564 static void
7565 output_trans_table (automaton)
7566      automaton_t automaton;
7567 {
7568   state_t *state_ptr;
7569   arc_t arc;
7570   vla_hwint_t transition_vect;
7571
7572   undefined_vect_el_value = automaton->achieved_states_num;
7573   automaton->trans_table = create_state_ainsn_table (automaton);
7574   /* Create vect of pointers to states ordered by num of transitions
7575      from the state (state with the maximum num is the first).  */
7576   VLA_PTR_CREATE (output_states_vect, 1500, "output states vector");
7577   pass_states (automaton, add_states_vect_el);
7578   qsort (VLA_PTR_BEGIN (output_states_vect),
7579          VLA_PTR_LENGTH (output_states_vect),
7580          sizeof (state_t), compare_transition_els_num);
7581   VLA_HWINT_CREATE (transition_vect, 500, "transition vector");
7582   for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
7583        state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
7584        state_ptr++)
7585     {
7586       VLA_HWINT_NULLIFY (transition_vect);
7587       for (arc = first_out_arc (*state_ptr);
7588            arc != NULL;
7589            arc = next_out_arc (arc))
7590         {
7591           if (arc->insn == NULL)
7592             abort ();
7593           if (arc->insn->first_ainsn_with_given_equialence_num)
7594             add_vect_el (&transition_vect, arc->insn,
7595                          arc->to_state->order_state_num);
7596         }
7597       add_vect (automaton->trans_table, (*state_ptr)->order_state_num,
7598                 VLA_HWINT_BEGIN (transition_vect),
7599                 VLA_HWINT_LENGTH (transition_vect));
7600     }
7601   output_state_ainsn_table
7602     (automaton->trans_table, (char *) "state transitions",
7603      output_trans_full_vect_name, output_trans_comb_vect_name,
7604      output_trans_check_vect_name, output_trans_base_vect_name);
7605   VLA_PTR_DELETE (output_states_vect);
7606   VLA_HWINT_DELETE (transition_vect);
7607 }
7608
7609 /* Form and output vectors (comb, check, base or simple vect)
7610    representing alts number table of AUTOMATON.  The table is state x
7611    ainsn -> number of possible alternative reservations by the
7612    ainsn.  */
7613 static void
7614 output_state_alts_table (automaton)
7615      automaton_t automaton;
7616 {
7617   state_t *state_ptr;
7618   arc_t arc;
7619   vla_hwint_t state_alts_vect;
7620
7621   undefined_vect_el_value = 0; /* no alts when transition is not possible */
7622   automaton->state_alts_table = create_state_ainsn_table (automaton);
7623   /* Create vect of pointers to states ordered by num of transitions
7624      from the state (state with the maximum num is the first).  */
7625   VLA_PTR_CREATE (output_states_vect, 1500, "output states vector");
7626   pass_states (automaton, add_states_vect_el);
7627   qsort (VLA_PTR_BEGIN (output_states_vect),
7628          VLA_PTR_LENGTH (output_states_vect),
7629          sizeof (state_t), compare_transition_els_num);
7630   /* Create base, comb, and check vectors.  */
7631   VLA_HWINT_CREATE (state_alts_vect, 500, "state alts vector");
7632   for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
7633        state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
7634        state_ptr++)
7635     {
7636       VLA_HWINT_NULLIFY (state_alts_vect);
7637       for (arc = first_out_arc (*state_ptr);
7638            arc != NULL;
7639            arc = next_out_arc (arc))
7640         {
7641           if (arc->insn == NULL)
7642             abort ();
7643           if (arc->insn->first_ainsn_with_given_equialence_num)
7644             add_vect_el (&state_alts_vect, arc->insn, arc->state_alts);
7645         }
7646       add_vect (automaton->state_alts_table, (*state_ptr)->order_state_num,
7647                 VLA_HWINT_BEGIN (state_alts_vect),
7648                 VLA_HWINT_LENGTH (state_alts_vect));
7649     }
7650   output_state_ainsn_table
7651     (automaton->state_alts_table, (char *) "state insn alternatives",
7652      output_state_alts_full_vect_name, output_state_alts_comb_vect_name,
7653      output_state_alts_check_vect_name, output_state_alts_base_vect_name);
7654   VLA_PTR_DELETE (output_states_vect);
7655   VLA_HWINT_DELETE (state_alts_vect);
7656 }
7657
7658 /* The current number of passing states to find minimal issue delay
7659    value for an ainsn and state.  */
7660 static int curr_state_pass_num;
7661
7662
7663 /* This recursive function passes states to find minimal issue delay
7664    value for AINSN.  The state being visited is STATE.  The function
7665    returns minimal issue delay value for AINSN in STATE or -1 if we
7666    enter into a loop.  */
7667 static int
7668 min_issue_delay_pass_states (state, ainsn)
7669      state_t state;
7670      ainsn_t ainsn;
7671 {
7672   arc_t arc;
7673   int min_insn_issue_delay, insn_issue_delay;
7674
7675   if (state->state_pass_num == curr_state_pass_num
7676       || state->min_insn_issue_delay != -1)
7677     /* We've entered into a loop or already have the correct value for
7678        given state and ainsn.  */
7679     return state->min_insn_issue_delay;
7680   state->state_pass_num = curr_state_pass_num;
7681   min_insn_issue_delay = -1;
7682   for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
7683     if (arc->insn == ainsn)
7684       {
7685         min_insn_issue_delay = 0;
7686         break;
7687       }
7688     else
7689       {
7690         insn_issue_delay = min_issue_delay_pass_states (arc->to_state, ainsn);
7691         if (insn_issue_delay != -1)
7692           {
7693             if (arc->insn->insn_reserv_decl
7694                 == DECL_INSN_RESERV (advance_cycle_insn_decl))
7695               insn_issue_delay++;
7696             if (min_insn_issue_delay == -1
7697                 || min_insn_issue_delay > insn_issue_delay)
7698               {
7699                 min_insn_issue_delay = insn_issue_delay;
7700                 if (insn_issue_delay == 0)
7701                   break;
7702               }
7703           }
7704       }
7705   return min_insn_issue_delay;
7706 }
7707
7708 /* The function searches minimal issue delay value for AINSN in STATE.
7709    The function can return negative value if we can not issue AINSN.  We
7710    will report about it later.  */
7711 static int
7712 min_issue_delay (state, ainsn)
7713      state_t state;
7714      ainsn_t ainsn;
7715 {
7716   curr_state_pass_num++;
7717   state->min_insn_issue_delay = min_issue_delay_pass_states (state, ainsn);
7718   return state->min_insn_issue_delay;
7719 }
7720
7721 /* The function initiates code for finding minimal issue delay values.
7722    It should be called only once.  */
7723 static void
7724 initiate_min_issue_delay_pass_states ()
7725 {
7726   curr_state_pass_num = 0;
7727 }
7728
7729 /* Form and output vectors representing minimal issue delay table of
7730    AUTOMATON.  The table is state x ainsn -> minimal issue delay of
7731    the ainsn.  */
7732 static void
7733 output_min_issue_delay_table (automaton)
7734      automaton_t automaton;
7735 {
7736   vla_hwint_t min_issue_delay_vect;
7737   vla_hwint_t compressed_min_issue_delay_vect;
7738   vect_el_t min_delay;
7739   ainsn_t ainsn;
7740   state_t *state_ptr;
7741   int i;
7742
7743   /* Create vect of pointers to states ordered by num of transitions
7744      from the state (state with the maximum num is the first).  */
7745   VLA_PTR_CREATE (output_states_vect, 1500, "output states vector");
7746   pass_states (automaton, add_states_vect_el);
7747   VLA_HWINT_CREATE (min_issue_delay_vect, 1500, "min issue delay vector");
7748   VLA_HWINT_EXPAND (min_issue_delay_vect,
7749                     VLA_HWINT_LENGTH (output_states_vect)
7750                     * automaton->insn_equiv_classes_num);
7751   for (i = 0;
7752        i < ((int) VLA_HWINT_LENGTH (output_states_vect)
7753             * automaton->insn_equiv_classes_num);
7754        i++)
7755     VLA_HWINT (min_issue_delay_vect, i) = 0;
7756   automaton->max_min_delay = 0;
7757   for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
7758     if (ainsn->first_ainsn_with_given_equialence_num)
7759       {
7760         for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
7761              state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
7762              state_ptr++)
7763           (*state_ptr)->min_insn_issue_delay = -1;
7764         for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
7765              state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
7766              state_ptr++)
7767           {
7768             min_delay = min_issue_delay (*state_ptr, ainsn);
7769             if (automaton->max_min_delay < min_delay)
7770               automaton->max_min_delay = min_delay;
7771             VLA_HWINT (min_issue_delay_vect,
7772                        (*state_ptr)->order_state_num
7773                        * automaton->insn_equiv_classes_num
7774                        + ainsn->insn_equiv_class_num) = min_delay;
7775           }
7776       }
7777   fprintf (output_file, "/* Vector of min issue delay of insns.*/\n");
7778   fprintf (output_file, "static const ");
7779   output_range_type (output_file, 0, automaton->max_min_delay);
7780   fprintf (output_file, " ");
7781   output_min_issue_delay_vect_name (output_file, automaton);
7782   fprintf (output_file, "[] = {\n");
7783   /* Compress the vector */
7784   if (automaton->max_min_delay < 2)
7785     automaton->min_issue_delay_table_compression_factor = 8;
7786   else if (automaton->max_min_delay < 4)
7787     automaton->min_issue_delay_table_compression_factor = 4;
7788   else if (automaton->max_min_delay < 16)
7789     automaton->min_issue_delay_table_compression_factor = 2;
7790   else
7791     automaton->min_issue_delay_table_compression_factor = 1;
7792   VLA_HWINT_CREATE (compressed_min_issue_delay_vect, 1500,
7793                     "compressed min issue delay vector");
7794   VLA_HWINT_EXPAND (compressed_min_issue_delay_vect,
7795                     (VLA_HWINT_LENGTH (min_issue_delay_vect)
7796                      + automaton->min_issue_delay_table_compression_factor
7797                      - 1)
7798                     / automaton->min_issue_delay_table_compression_factor);
7799   for (i = 0;
7800        i < (int) VLA_HWINT_LENGTH (compressed_min_issue_delay_vect);
7801        i++)
7802     VLA_HWINT (compressed_min_issue_delay_vect, i) = 0;
7803   for (i = 0; i < (int) VLA_HWINT_LENGTH (min_issue_delay_vect); i++)
7804     VLA_HWINT (compressed_min_issue_delay_vect,
7805                i / automaton->min_issue_delay_table_compression_factor)
7806       |= (VLA_HWINT (min_issue_delay_vect, i)
7807           << (8 - (i % automaton->min_issue_delay_table_compression_factor
7808                    + 1)
7809               * (8 / automaton->min_issue_delay_table_compression_factor)));
7810   output_vect (VLA_HWINT_BEGIN (compressed_min_issue_delay_vect),
7811                VLA_HWINT_LENGTH (compressed_min_issue_delay_vect));
7812   fprintf (output_file, "};\n\n");
7813   VLA_PTR_DELETE (output_states_vect);
7814   VLA_HWINT_DELETE (min_issue_delay_vect);
7815   VLA_HWINT_DELETE (compressed_min_issue_delay_vect);
7816 }
7817
7818 #ifndef NDEBUG
7819 /* Number of states which contains transition only by advancing cpu
7820    cycle.  */
7821 static int locked_states_num;
7822 #endif
7823
7824 /* Form and output vector representing the locked states of
7825    AUTOMATON.  */
7826 static void
7827 output_dead_lock_vect (automaton)
7828      automaton_t automaton;
7829 {
7830   state_t *state_ptr;
7831   arc_t arc;
7832   vla_hwint_t dead_lock_vect;
7833
7834   /* Create vect of pointers to states ordered by num of
7835      transitions from the state (state with the maximum num is the
7836      first).  */
7837   VLA_PTR_CREATE (output_states_vect, 1500, "output states vector");
7838   pass_states (automaton, add_states_vect_el);
7839   VLA_HWINT_CREATE (dead_lock_vect, 1500, "is dead locked vector");
7840   VLA_HWINT_EXPAND (dead_lock_vect, VLA_HWINT_LENGTH (output_states_vect));
7841   for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
7842        state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
7843        state_ptr++)
7844     {
7845       arc = first_out_arc (*state_ptr);
7846       if (arc == NULL)
7847         abort ();
7848       VLA_HWINT (dead_lock_vect, (*state_ptr)->order_state_num)
7849         = (next_out_arc (arc) == NULL
7850            && (arc->insn->insn_reserv_decl
7851                == DECL_INSN_RESERV (advance_cycle_insn_decl)) ? 1 : 0);
7852 #ifndef NDEBUG
7853       if (VLA_HWINT (dead_lock_vect, (*state_ptr)->order_state_num))
7854         locked_states_num++;
7855 #endif
7856     }
7857   fprintf (output_file, "/* Vector for locked state flags.  */\n");
7858   fprintf (output_file, "static const ");
7859   output_range_type (output_file, 0, 1);
7860   fprintf (output_file, " ");
7861   output_dead_lock_vect_name (output_file, automaton);
7862   fprintf (output_file, "[] = {\n");
7863   output_vect (VLA_HWINT_BEGIN (dead_lock_vect),
7864                VLA_HWINT_LENGTH (dead_lock_vect));
7865   fprintf (output_file, "};\n\n");
7866   VLA_HWINT_DELETE (dead_lock_vect);
7867   VLA_PTR_DELETE (output_states_vect);
7868 }
7869
7870 /* Form and output vector representing reserved units of the states of
7871    AUTOMATON.  */
7872 static void
7873 output_reserved_units_table (automaton)
7874      automaton_t automaton;
7875 {
7876   state_t *curr_state_ptr;
7877   vla_hwint_t reserved_units_table;
7878   size_t state_byte_size;
7879   int i;
7880
7881   /* Create vect of pointers to states.  */
7882   VLA_PTR_CREATE (output_states_vect, 1500, "output states vector");
7883   pass_states (automaton, add_states_vect_el);
7884   /* Create vector.  */
7885   VLA_HWINT_CREATE (reserved_units_table, 1500, "reserved units vector");
7886   state_byte_size = (description->query_units_num + 7) / 8;
7887   VLA_HWINT_EXPAND (reserved_units_table,
7888                     VLA_HWINT_LENGTH (output_states_vect) * state_byte_size);
7889   for (i = 0;
7890        i < (int) (VLA_HWINT_LENGTH (output_states_vect) * state_byte_size);
7891        i++)
7892     VLA_HWINT (reserved_units_table, i) = 0;
7893   for (curr_state_ptr = VLA_PTR_BEGIN (output_states_vect);
7894        curr_state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
7895        curr_state_ptr++)
7896     {
7897       for (i = 0; i < description->units_num; i++)
7898         if (units_array [i]->query_p)
7899           {
7900             if (test_unit_reserv ((*curr_state_ptr)->reservs, 0, i))
7901               VLA_HWINT (reserved_units_table,
7902                          (*curr_state_ptr)->order_state_num * state_byte_size
7903                          + units_array [i]->query_num / 8)
7904                 += (1 << (units_array [i]->query_num % 8));
7905           }
7906     }
7907   fprintf (output_file, "/* Vector for reserved units of states.  */\n");
7908   fprintf (output_file, "static const ");
7909   output_range_type (output_file, 0, 255);
7910   fprintf (output_file, " ");
7911   output_reserved_units_table_name (output_file, automaton);
7912   fprintf (output_file, "[] = {\n");
7913   output_vect (VLA_HWINT_BEGIN (reserved_units_table),
7914                VLA_HWINT_LENGTH (reserved_units_table));
7915   fprintf (output_file, "};\n\n");
7916   VLA_HWINT_DELETE (reserved_units_table);
7917   VLA_PTR_DELETE (output_states_vect);
7918 }
7919
7920 /* The function outputs all tables representing DFA(s) used for fast
7921    pipeline hazards recognition.  */
7922 static void
7923 output_tables ()
7924 {
7925   automaton_t automaton;
7926
7927 #ifndef NDEBUG
7928   locked_states_num = 0;
7929 #endif
7930   initiate_min_issue_delay_pass_states ();
7931   for (automaton = description->first_automaton;
7932        automaton != NULL;
7933        automaton = automaton->next_automaton)
7934     {
7935       output_translate_vect (automaton);
7936       output_trans_table (automaton);
7937       fprintf (output_file, "\n#if %s\n", AUTOMATON_STATE_ALTS_MACRO_NAME);
7938       output_state_alts_table (automaton);
7939       fprintf (output_file, "\n#endif /* #if %s */\n\n",
7940                AUTOMATON_STATE_ALTS_MACRO_NAME);
7941       output_min_issue_delay_table (automaton);
7942       output_dead_lock_vect (automaton);
7943       if (no_minimization_flag)
7944         {
7945           fprintf (output_file, "\n#if %s\n\n", CPU_UNITS_QUERY_MACRO_NAME);
7946           output_reserved_units_table (automaton);
7947           fprintf (output_file, "\n#endif /* #if %s */\n\n",
7948                    CPU_UNITS_QUERY_MACRO_NAME);
7949         }
7950     }
7951   fprintf (output_file, "\n#define %s %d\n\n", ADVANCE_CYCLE_VALUE_NAME,
7952            DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num);
7953 }
7954
7955 /* The function outputs definition and value of PHR interface variable
7956    `max_insn_queue_index'.  Its value is not less than maximal queue
7957    length needed for the insn scheduler.  */
7958 static void
7959 output_max_insn_queue_index_def ()
7960 {
7961   int i, max, latency;
7962   decl_t decl;
7963
7964   max = description->max_insn_reserv_cycles;
7965   for (i = 0; i < description->decls_num; i++)
7966     {
7967       decl = description->decls [i];
7968       if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
7969         {
7970           latency = DECL_INSN_RESERV (decl)->default_latency;
7971           if (latency > max)
7972             max = latency;
7973         }
7974       else if (decl->mode == dm_bypass)
7975         {
7976           latency = DECL_BYPASS (decl)->latency;
7977           if (latency > max)
7978             max = latency;
7979         }
7980     }
7981   for (i = 0; (1 << i) <= max; i++)
7982     ;
7983   if (i < 0)
7984     abort ();
7985   fprintf (output_file, "\nint max_insn_queue_index = %d;\n\n", (1 << i) - 1);
7986 }
7987
7988
7989 /* The function outputs switch cases for insn reseravtions using
7990    function *output_automata_list_code.  */
7991 static void
7992 output_insn_code_cases (output_automata_list_code)
7993      void (*output_automata_list_code) (automata_list_el_t);
7994 {
7995   decl_t decl, decl2;
7996   int i, j;
7997
7998   for (i = 0; i < description->decls_num; i++)
7999     {
8000       decl = description->decls [i];
8001       if (decl->mode == dm_insn_reserv)
8002         DECL_INSN_RESERV (decl)->processed_p = FALSE;
8003     }
8004   for (i = 0; i < description->decls_num; i++)
8005     {
8006       decl = description->decls [i];
8007       if (decl->mode == dm_insn_reserv
8008           && !DECL_INSN_RESERV (decl)->processed_p)
8009         {
8010           for (j = i; j < description->decls_num; j++)
8011             {
8012               decl2 = description->decls [j];
8013               if (decl2->mode == dm_insn_reserv
8014                   && (DECL_INSN_RESERV (decl2)->important_automata_list
8015                       == DECL_INSN_RESERV (decl)->important_automata_list))
8016                 {
8017                   DECL_INSN_RESERV (decl2)->processed_p = TRUE;
8018                   fprintf (output_file, "    case %d: /* %s */\n",
8019                            DECL_INSN_RESERV (decl2)->insn_num,
8020                            DECL_INSN_RESERV (decl2)->name);
8021                 }
8022             }
8023           (*output_automata_list_code)
8024             (DECL_INSN_RESERV (decl)->important_automata_list);
8025         }
8026     }
8027 }
8028
8029
8030 /* The function outputs a code for evaluation of a minimal delay of
8031    issue of insns which have reservations in given AUTOMATA_LIST.  */
8032 static void
8033 output_automata_list_min_issue_delay_code (automata_list)
8034      automata_list_el_t automata_list;
8035 {
8036   automata_list_el_t el;
8037   automaton_t automaton;
8038
8039   for (el = automata_list; el != NULL; el = el->next_automata_list_el)
8040     {
8041       automaton = el->automaton;
8042       fprintf (output_file, "\n      %s = ", TEMPORARY_VARIABLE_NAME);
8043       output_min_issue_delay_vect_name (output_file, automaton);
8044       fprintf (output_file,
8045                (automaton->min_issue_delay_table_compression_factor != 1
8046                 ? " [(" : " ["));
8047       output_translate_vect_name (output_file, automaton);
8048       fprintf (output_file, " [%s] + ", INTERNAL_INSN_CODE_NAME);
8049       fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
8050       output_chip_member_name (output_file, automaton);
8051       fprintf (output_file, " * %d", automaton->insn_equiv_classes_num);
8052       if (automaton->min_issue_delay_table_compression_factor == 1)
8053         fprintf (output_file, "];\n");
8054       else
8055         {
8056           fprintf (output_file, ") / %d];\n",
8057                    automaton->min_issue_delay_table_compression_factor);
8058           fprintf (output_file, "      %s = (%s >> (8 - (",
8059                    TEMPORARY_VARIABLE_NAME, TEMPORARY_VARIABLE_NAME);
8060           output_translate_vect_name (output_file, automaton);
8061           fprintf
8062             (output_file, " [%s] %% %d + 1) * %d)) & %d;\n",
8063              INTERNAL_INSN_CODE_NAME,
8064              automaton->min_issue_delay_table_compression_factor,
8065              8 / automaton->min_issue_delay_table_compression_factor,
8066              (1 << (8 / automaton->min_issue_delay_table_compression_factor))
8067              - 1);
8068         }
8069       if (el == automata_list)
8070         fprintf (output_file, "      %s = %s;\n",
8071                  RESULT_VARIABLE_NAME, TEMPORARY_VARIABLE_NAME);
8072       else
8073         {
8074           fprintf (output_file, "      if (%s > %s)\n",
8075                    TEMPORARY_VARIABLE_NAME, RESULT_VARIABLE_NAME);
8076           fprintf (output_file, "        %s = %s;\n",
8077                    RESULT_VARIABLE_NAME, TEMPORARY_VARIABLE_NAME);
8078         }
8079     }
8080   fprintf (output_file, "      break;\n\n");
8081 }
8082
8083 /* Output function `internal_min_issue_delay'.  */
8084 static void
8085 output_internal_min_issue_delay_func ()
8086 {
8087   fprintf (output_file, "static int %s PARAMS ((int, struct %s *));\n",
8088            INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, CHIP_NAME);
8089   fprintf (output_file,
8090            "static int\n%s (%s, %s)\n\tint %s;\n\tstruct %s *%s  ATTRIBUTE_UNUSED;\n",
8091            INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8092            CHIP_PARAMETER_NAME, INTERNAL_INSN_CODE_NAME, CHIP_NAME,
8093            CHIP_PARAMETER_NAME);
8094   fprintf (output_file, "{\n  int %s ATTRIBUTE_UNUSED;\n  int %s;\n",
8095            TEMPORARY_VARIABLE_NAME, RESULT_VARIABLE_NAME);
8096   fprintf (output_file, "\n  switch (%s)\n    {\n", INTERNAL_INSN_CODE_NAME);
8097   output_insn_code_cases (output_automata_list_min_issue_delay_code);
8098   fprintf (output_file,
8099            "\n    default:\n      %s = -1;\n      break;\n    }\n",
8100            RESULT_VARIABLE_NAME);
8101   fprintf (output_file, "  return %s;\n", RESULT_VARIABLE_NAME);
8102   fprintf (output_file, "}\n\n");
8103 }
8104
8105 /* The function outputs a code changing state after issue of insns
8106    which have reservations in given AUTOMATA_LIST.  */
8107 static void
8108 output_automata_list_transition_code (automata_list)
8109      automata_list_el_t automata_list;
8110 {
8111   automata_list_el_t el, next_el;
8112
8113   fprintf (output_file, "      {\n");
8114   if (automata_list != NULL && automata_list->next_automata_list_el != NULL)
8115     for (el = automata_list;; el = next_el)
8116       {
8117         next_el = el->next_automata_list_el;
8118         if (next_el == NULL)
8119           break;
8120         fprintf (output_file, "        ");
8121         output_state_member_type (output_file, el->automaton);
8122         fprintf (output_file, " ");
8123         output_temp_chip_member_name (output_file, el->automaton);
8124         fprintf (output_file, ";\n");
8125       }
8126   for (el = automata_list; el != NULL; el = el->next_automata_list_el)
8127     if (comb_vect_p (el->automaton->trans_table))
8128       {
8129         fprintf (output_file, "\n        %s = ", TEMPORARY_VARIABLE_NAME);
8130         output_trans_base_vect_name (output_file, el->automaton);
8131         fprintf (output_file, " [%s->", CHIP_PARAMETER_NAME);
8132         output_chip_member_name (output_file, el->automaton);
8133         fprintf (output_file, "] + ");
8134         output_translate_vect_name (output_file, el->automaton);
8135         fprintf (output_file, " [%s];\n", INTERNAL_INSN_CODE_NAME);
8136         fprintf (output_file, "        if (");
8137         output_trans_check_vect_name (output_file, el->automaton);
8138         fprintf (output_file, " [%s] != %s->",
8139                  TEMPORARY_VARIABLE_NAME, CHIP_PARAMETER_NAME);
8140         output_chip_member_name (output_file, el->automaton);
8141         fprintf (output_file, ")\n");
8142         fprintf (output_file, "          return %s (%s, %s);\n",
8143                  INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8144                  CHIP_PARAMETER_NAME);
8145         fprintf (output_file, "        else\n");
8146         fprintf (output_file, "          ");
8147         if (el->next_automata_list_el != NULL)
8148           output_temp_chip_member_name (output_file, el->automaton);
8149         else
8150           {
8151             fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
8152             output_chip_member_name (output_file, el->automaton);
8153           }
8154         fprintf (output_file, " = ");
8155         output_trans_comb_vect_name (output_file, el->automaton);
8156         fprintf (output_file, " [%s];\n", TEMPORARY_VARIABLE_NAME);
8157       }
8158     else
8159       {
8160         fprintf (output_file, "\n        %s = ", TEMPORARY_VARIABLE_NAME);
8161         output_trans_full_vect_name (output_file, el->automaton);
8162         fprintf (output_file, " [");
8163         output_translate_vect_name (output_file, el->automaton);
8164         fprintf (output_file, " [%s] + ", INTERNAL_INSN_CODE_NAME);
8165         fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
8166         output_chip_member_name (output_file, el->automaton);
8167         fprintf (output_file, " * %d];\n",
8168                  el->automaton->insn_equiv_classes_num);
8169         fprintf (output_file, "        if (%s >= %d)\n",
8170                  TEMPORARY_VARIABLE_NAME, el->automaton->achieved_states_num);
8171         fprintf (output_file, "          return %s (%s, %s);\n",
8172                  INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8173                  CHIP_PARAMETER_NAME);
8174         fprintf (output_file, "        else\n          ");
8175         if (el->next_automata_list_el != NULL)
8176           output_temp_chip_member_name (output_file, el->automaton);
8177         else
8178           {
8179             fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
8180             output_chip_member_name (output_file, el->automaton);
8181           }
8182         fprintf (output_file, " = %s;\n", TEMPORARY_VARIABLE_NAME);
8183       }
8184   if (automata_list != NULL && automata_list->next_automata_list_el != NULL)
8185     for (el = automata_list;; el = next_el)
8186       {
8187         next_el = el->next_automata_list_el;
8188         if (next_el == NULL)
8189           break;
8190         fprintf (output_file, "        %s->", CHIP_PARAMETER_NAME);
8191         output_chip_member_name (output_file, el->automaton);
8192         fprintf (output_file, " = ");
8193         output_temp_chip_member_name (output_file, el->automaton);
8194         fprintf (output_file, ";\n");
8195       }
8196   fprintf (output_file, "        return -1;\n");
8197   fprintf (output_file, "      }\n");
8198 }
8199
8200 /* Output function `internal_state_transition'.  */
8201 static void
8202 output_internal_trans_func ()
8203 {
8204   fprintf (output_file, "static int %s PARAMS ((int, struct %s *));\n",
8205            INTERNAL_TRANSITION_FUNC_NAME, CHIP_NAME);
8206   fprintf (output_file,
8207            "static int\n%s (%s, %s)\n\tint %s;\n\tstruct %s *%s  ATTRIBUTE_UNUSED;\n",
8208            INTERNAL_TRANSITION_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8209            CHIP_PARAMETER_NAME, INTERNAL_INSN_CODE_NAME,
8210            CHIP_NAME, CHIP_PARAMETER_NAME);
8211   fprintf (output_file, "{\n  int %s ATTRIBUTE_UNUSED;\n", TEMPORARY_VARIABLE_NAME);
8212   fprintf (output_file, "\n  switch (%s)\n    {\n", INTERNAL_INSN_CODE_NAME);
8213   output_insn_code_cases (output_automata_list_transition_code);
8214   fprintf (output_file, "\n    default:\n      return -1;\n    }\n");
8215   fprintf (output_file, "}\n\n");
8216 }
8217
8218 /* Output code
8219
8220   if (insn != 0)
8221     {
8222       insn_code = dfa_insn_code (insn);
8223       if (insn_code > DFA__ADVANCE_CYCLE)
8224         return code;
8225     }
8226   else
8227     insn_code = DFA__ADVANCE_CYCLE;
8228
8229   where insn denotes INSN_NAME, insn_code denotes INSN_CODE_NAME, and
8230   code denotes CODE.  */
8231 static void
8232 output_internal_insn_code_evaluation (insn_name, insn_code_name, code)
8233      const char *insn_name;
8234      const char *insn_code_name;
8235      int code;
8236 {
8237   fprintf (output_file, "\n  if (%s != 0)\n    {\n", insn_name);
8238   fprintf (output_file, "      %s = %s (%s);\n", insn_code_name,
8239            DFA_INSN_CODE_FUNC_NAME, insn_name);
8240   fprintf (output_file, "      if (%s > %s)\n        return %d;\n",
8241            insn_code_name, ADVANCE_CYCLE_VALUE_NAME, code);
8242   fprintf (output_file, "    }\n  else\n    %s = %s;\n\n",
8243            insn_code_name, ADVANCE_CYCLE_VALUE_NAME);
8244 }
8245
8246
8247 /* The function outputs function `dfa_insn_code'.  */
8248 static void
8249 output_dfa_insn_code_func ()
8250 {
8251   fprintf (output_file, "#ifdef __GNUC__\n__inline__\n#endif\n");
8252   fprintf (output_file, "static int %s PARAMS ((rtx));\n",
8253            DFA_INSN_CODE_FUNC_NAME);
8254   fprintf (output_file, "static int\n%s (%s)\n\trtx %s;\n",
8255            DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME, INSN_PARAMETER_NAME);
8256   fprintf (output_file, "{\n  int %s;\n  int %s;\n\n",
8257            INTERNAL_INSN_CODE_NAME, TEMPORARY_VARIABLE_NAME);
8258   fprintf (output_file, "  if (INSN_UID (%s) >= %s)\n    {\n",
8259            INSN_PARAMETER_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
8260   fprintf (output_file, "      %s = %s;\n      %s = 2 * INSN_UID (%s);\n",
8261            TEMPORARY_VARIABLE_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
8262            DFA_INSN_CODES_LENGTH_VARIABLE_NAME, INSN_PARAMETER_NAME);
8263   fprintf (output_file, "      %s = xrealloc (%s, %s * sizeof (int));\n",
8264            DFA_INSN_CODES_VARIABLE_NAME, DFA_INSN_CODES_VARIABLE_NAME,
8265            DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
8266   fprintf (output_file,
8267            "      for (; %s < %s; %s++)\n        %s [%s] = -1;\n    }\n",
8268            TEMPORARY_VARIABLE_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
8269            TEMPORARY_VARIABLE_NAME, DFA_INSN_CODES_VARIABLE_NAME,
8270            TEMPORARY_VARIABLE_NAME);
8271   fprintf (output_file, "  if ((%s = %s [INSN_UID (%s)]) < 0)\n    {\n",
8272            INTERNAL_INSN_CODE_NAME, DFA_INSN_CODES_VARIABLE_NAME,
8273            INSN_PARAMETER_NAME);
8274   fprintf (output_file, "      %s = %s (%s);\n", INTERNAL_INSN_CODE_NAME,
8275            INTERNAL_DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME);
8276   fprintf (output_file, "      %s [INSN_UID (%s)] = %s;\n",
8277            DFA_INSN_CODES_VARIABLE_NAME, INSN_PARAMETER_NAME,
8278            INTERNAL_INSN_CODE_NAME);
8279   fprintf (output_file, "    }\n  return %s;\n}\n\n",
8280            INTERNAL_INSN_CODE_NAME);
8281 }
8282
8283 /* The function outputs PHR interface function `state_transition'.  */
8284 static void
8285 output_trans_func ()
8286 {
8287   fprintf (output_file, "int\n%s (%s, %s)\n\t%s %s;\n\trtx %s;\n",
8288            TRANSITION_FUNC_NAME, STATE_NAME, INSN_PARAMETER_NAME,
8289            STATE_TYPE_NAME, STATE_NAME, INSN_PARAMETER_NAME);
8290   fprintf (output_file, "{\n  int %s;\n", INTERNAL_INSN_CODE_NAME);
8291   output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
8292                                         INTERNAL_INSN_CODE_NAME, -1);
8293   fprintf (output_file, "  return %s (%s, %s);\n}\n\n",
8294            INTERNAL_TRANSITION_FUNC_NAME, INTERNAL_INSN_CODE_NAME, STATE_NAME);
8295 }
8296
8297 /* The function outputs a code for evaluation of alternative states
8298    number for insns which have reservations in given AUTOMATA_LIST.  */
8299 static void
8300 output_automata_list_state_alts_code (automata_list)
8301      automata_list_el_t automata_list;
8302 {
8303   automata_list_el_t el;
8304   automaton_t automaton;
8305
8306   fprintf (output_file, "      {\n");
8307   for (el = automata_list; el != NULL; el = el->next_automata_list_el)
8308     if (comb_vect_p (el->automaton->state_alts_table))
8309       {
8310         fprintf (output_file, "        int %s;\n", TEMPORARY_VARIABLE_NAME);
8311         break;
8312       }
8313   for (el = automata_list; el != NULL; el = el->next_automata_list_el)
8314     {
8315       automaton = el->automaton;
8316       if (comb_vect_p (automaton->state_alts_table))
8317         {
8318           fprintf (output_file, "\n        %s = ", TEMPORARY_VARIABLE_NAME);
8319           output_state_alts_base_vect_name (output_file, automaton);
8320           fprintf (output_file, " [%s->", CHIP_PARAMETER_NAME);
8321           output_chip_member_name (output_file, automaton);
8322           fprintf (output_file, "] + ");
8323           output_translate_vect_name (output_file, automaton);
8324           fprintf (output_file, " [%s];\n", INTERNAL_INSN_CODE_NAME);
8325           fprintf (output_file, "        if (");
8326           output_state_alts_check_vect_name (output_file, automaton);
8327           fprintf (output_file, " [%s] != %s->",
8328                    TEMPORARY_VARIABLE_NAME, CHIP_PARAMETER_NAME);
8329           output_chip_member_name (output_file, automaton);
8330           fprintf (output_file, ")\n");
8331           fprintf (output_file, "          return 0;\n");
8332           fprintf (output_file, "        else\n");
8333           fprintf (output_file,
8334                    (el == automata_list
8335                     ? "          %s = " : "          %s += "),
8336                    RESULT_VARIABLE_NAME);
8337           output_state_alts_comb_vect_name (output_file, automaton);
8338           fprintf (output_file, " [%s];\n", TEMPORARY_VARIABLE_NAME);
8339         }
8340       else
8341         {
8342           fprintf (output_file,
8343                    (el == automata_list
8344                     ? "\n        %s = " : "        %s += "),
8345                    RESULT_VARIABLE_NAME);
8346           output_state_alts_full_vect_name (output_file, automaton);
8347           fprintf (output_file, " [");
8348           output_translate_vect_name (output_file, automaton);
8349           fprintf (output_file, " [%s] + ", INTERNAL_INSN_CODE_NAME);
8350           fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
8351           output_chip_member_name (output_file, automaton);
8352           fprintf (output_file, " * %d];\n",
8353                    automaton->insn_equiv_classes_num);
8354         }
8355     }
8356   fprintf (output_file, "        break;\n      }\n\n");
8357 }
8358
8359 /* Output function `internal_state_alts'.  */
8360 static void
8361 output_internal_state_alts_func ()
8362 {
8363   fprintf (output_file, "static int %s PARAMS ((int, struct %s *));\n",
8364            INTERNAL_STATE_ALTS_FUNC_NAME, CHIP_NAME);
8365   fprintf (output_file,
8366            "static int\n%s (%s, %s)\n\tint %s;\n\tstruct %s *%s;\n",
8367            INTERNAL_STATE_ALTS_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8368            CHIP_PARAMETER_NAME, INTERNAL_INSN_CODE_NAME, CHIP_NAME,
8369            CHIP_PARAMETER_NAME);
8370   fprintf (output_file, "{\n  int %s;\n", RESULT_VARIABLE_NAME);
8371   fprintf (output_file, "\n  switch (%s)\n    {\n", INTERNAL_INSN_CODE_NAME);
8372   output_insn_code_cases (output_automata_list_state_alts_code);
8373   fprintf (output_file,
8374            "\n    default:\n      %s = 0;\n      break;\n    }\n",
8375            RESULT_VARIABLE_NAME);
8376   fprintf (output_file, "  return %s;\n", RESULT_VARIABLE_NAME);
8377   fprintf (output_file, "}\n\n");
8378 }
8379
8380 /* The function outputs PHR interface function `state_alts'.  */
8381 static void
8382 output_state_alts_func ()
8383 {
8384   fprintf (output_file, "int\n%s (%s, %s)\n\t%s %s;\n\trtx %s;\n",
8385            STATE_ALTS_FUNC_NAME, STATE_NAME, INSN_PARAMETER_NAME,
8386            STATE_TYPE_NAME, STATE_NAME, INSN_PARAMETER_NAME);
8387   fprintf (output_file, "{\n  int %s;\n", INTERNAL_INSN_CODE_NAME);
8388   output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
8389                                         INTERNAL_INSN_CODE_NAME, 0);
8390   fprintf (output_file, "  return %s (%s, %s);\n}\n\n",
8391            INTERNAL_STATE_ALTS_FUNC_NAME, INTERNAL_INSN_CODE_NAME, STATE_NAME);
8392 }
8393
8394 /* Output function `min_issue_delay'.  */
8395 static void
8396 output_min_issue_delay_func ()
8397 {
8398   fprintf (output_file, "int\n%s (%s, %s)\n\t%s %s;\n\trtx %s;\n",
8399            MIN_ISSUE_DELAY_FUNC_NAME, STATE_NAME, INSN_PARAMETER_NAME,
8400            STATE_TYPE_NAME, STATE_NAME, INSN_PARAMETER_NAME);
8401   fprintf (output_file, "{\n  int %s;\n", INTERNAL_INSN_CODE_NAME);
8402   fprintf (output_file, "\n  if (%s != 0)\n    {\n", INSN_PARAMETER_NAME);
8403   fprintf (output_file, "      %s = %s (%s);\n", INTERNAL_INSN_CODE_NAME,
8404            DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME);
8405   fprintf (output_file, "      if (%s > %s)\n        return 0;\n",
8406            INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8407   fprintf (output_file, "    }\n  else\n    %s = %s;\n",
8408            INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8409   fprintf (output_file, "\n  return %s (%s, %s);\n",
8410            INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8411            STATE_NAME);
8412   fprintf (output_file, "}\n\n");
8413 }
8414
8415 /* Output function `internal_dead_lock'.  */
8416 static void
8417 output_internal_dead_lock_func ()
8418 {
8419   automaton_t automaton;
8420
8421   fprintf (output_file, "static int %s PARAMS ((struct %s *));\n",
8422            INTERNAL_DEAD_LOCK_FUNC_NAME, CHIP_NAME);
8423   fprintf (output_file, "static int\n%s (%s)\n\tstruct %s *%s;\n",
8424            INTERNAL_DEAD_LOCK_FUNC_NAME, CHIP_PARAMETER_NAME, CHIP_NAME,
8425            CHIP_PARAMETER_NAME);
8426   fprintf (output_file, "{\n");
8427   for (automaton = description->first_automaton;
8428        automaton != NULL;
8429        automaton = automaton->next_automaton)
8430     {
8431       fprintf (output_file, "  if (");
8432       output_dead_lock_vect_name (output_file, automaton);
8433       fprintf (output_file, " [%s->", CHIP_PARAMETER_NAME);
8434       output_chip_member_name (output_file, automaton);
8435       fprintf (output_file, "])\n    return 1/* TRUE */;\n");
8436     }
8437   fprintf (output_file, "  return 0/* FALSE */;\n}\n\n");
8438 }
8439
8440 /* The function outputs PHR interface function `state_dead_lock_p'.  */
8441 static void
8442 output_dead_lock_func ()
8443 {
8444   fprintf (output_file, "int\n%s (%s)\n\t%s %s;\n",
8445            DEAD_LOCK_FUNC_NAME, STATE_NAME, STATE_TYPE_NAME, STATE_NAME);
8446   fprintf (output_file, "{\n  return %s (%s);\n}\n\n",
8447            INTERNAL_DEAD_LOCK_FUNC_NAME, STATE_NAME);
8448 }
8449
8450 /* Output function `internal_reset'.  */
8451 static void
8452 output_internal_reset_func ()
8453 {
8454   fprintf (output_file, "static void %s PARAMS ((struct %s *));\n",
8455            INTERNAL_RESET_FUNC_NAME, CHIP_NAME);
8456   fprintf (output_file, "static void\n%s (%s)\n\tstruct %s *%s;\n",
8457            INTERNAL_RESET_FUNC_NAME, CHIP_PARAMETER_NAME,
8458            CHIP_NAME, CHIP_PARAMETER_NAME);
8459   fprintf (output_file, "{\n  memset (%s, 0, sizeof (struct %s));\n}\n\n",
8460            CHIP_PARAMETER_NAME, CHIP_NAME);
8461 }
8462
8463 /* The function outputs PHR interface function `state_size'.  */
8464 static void
8465 output_size_func ()
8466 {
8467   fprintf (output_file, "int\n%s ()\n", SIZE_FUNC_NAME);
8468   fprintf (output_file, "{\n  return sizeof (struct %s);\n}\n\n", CHIP_NAME);
8469 }
8470
8471 /* The function outputs PHR interface function `state_reset'.  */
8472 static void
8473 output_reset_func ()
8474 {
8475   fprintf (output_file, "void\n%s (%s)\n\t %s %s;\n",
8476            RESET_FUNC_NAME, STATE_NAME, STATE_TYPE_NAME, STATE_NAME);
8477   fprintf (output_file, "{\n  %s (%s);\n}\n\n", INTERNAL_RESET_FUNC_NAME,
8478            STATE_NAME);
8479 }
8480
8481 /* Output function `min_insn_conflict_delay'.  */
8482 static void
8483 output_min_insn_conflict_delay_func ()
8484 {
8485   fprintf (output_file,
8486            "int\n%s (%s, %s, %s)\n\t%s %s;\n\trtx %s;\n\trtx %s;\n",
8487            MIN_INSN_CONFLICT_DELAY_FUNC_NAME,
8488            STATE_NAME, INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME,
8489            STATE_TYPE_NAME, STATE_NAME,
8490            INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
8491   fprintf (output_file, "{\n  struct %s %s;\n  int %s, %s;\n",
8492            CHIP_NAME, CHIP_NAME, INTERNAL_INSN_CODE_NAME,
8493            INTERNAL_INSN2_CODE_NAME);
8494   output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
8495                                         INTERNAL_INSN_CODE_NAME, 0);
8496   output_internal_insn_code_evaluation (INSN2_PARAMETER_NAME,
8497                                         INTERNAL_INSN2_CODE_NAME, 0);
8498   fprintf (output_file, "  memcpy (&%s, %s, sizeof (%s));\n",
8499            CHIP_NAME, STATE_NAME, CHIP_NAME);
8500   fprintf (output_file, "  %s (&%s);\n", INTERNAL_RESET_FUNC_NAME, CHIP_NAME);
8501   fprintf (output_file, "  if (%s (%s, &%s) > 0)\n    abort ();\n",
8502            INTERNAL_TRANSITION_FUNC_NAME, INTERNAL_INSN_CODE_NAME, CHIP_NAME);
8503   fprintf (output_file, "  return %s (%s, &%s);\n",
8504            INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN2_CODE_NAME,
8505            CHIP_NAME);
8506   fprintf (output_file, "}\n\n");
8507 }
8508
8509 /* Output function `internal_insn_latency'.  */
8510 static void
8511 output_internal_insn_latency_func ()
8512 {
8513   decl_t decl;
8514   struct bypass_decl *bypass;
8515   int i;
8516
8517   fprintf (output_file, "static int %s PARAMS ((int, int, rtx, rtx));\n",
8518            INTERNAL_INSN_LATENCY_FUNC_NAME);
8519   fprintf (output_file, "static int\n%s (%s, %s, %s, %s)",
8520            INTERNAL_INSN_LATENCY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8521            INTERNAL_INSN2_CODE_NAME, INSN_PARAMETER_NAME,
8522            INSN2_PARAMETER_NAME);
8523   fprintf (output_file, "\n\tint %s;\n\tint %s;\n",
8524            INTERNAL_INSN_CODE_NAME, INTERNAL_INSN2_CODE_NAME);
8525   fprintf (output_file,
8526            "\trtx %s ATTRIBUTE_UNUSED;\n\trtx %s ATTRIBUTE_UNUSED;\n",
8527            INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
8528   fprintf (output_file, "{\n  switch (%s)\n    {\n", INTERNAL_INSN_CODE_NAME);
8529   for (i = 0; i < description->decls_num; i++)
8530     {
8531       decl = description->decls [i];
8532       if (decl->mode == dm_insn_reserv)
8533         {
8534           fprintf (output_file, "    case %d:\n",
8535                    DECL_INSN_RESERV (decl)->insn_num);
8536           if (DECL_INSN_RESERV (decl)->bypass_list == NULL)
8537             fprintf (output_file, "      return (%s != %s ? %d : 0);\n",
8538                      INTERNAL_INSN2_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME,
8539                      DECL_INSN_RESERV (decl)->default_latency);
8540           else
8541             {
8542               fprintf (output_file, "      switch (%s)\n        {\n",
8543                        INTERNAL_INSN2_CODE_NAME);
8544               for (bypass = DECL_INSN_RESERV (decl)->bypass_list;
8545                    bypass != NULL;
8546                    bypass = bypass->next)
8547                 {
8548                   fprintf (output_file, "        case %d:\n",
8549                            bypass->in_insn_reserv->insn_num);
8550                   if (bypass->bypass_guard_name == NULL)
8551                     fprintf (output_file, "          return %d;\n",
8552                              bypass->latency);
8553                   else
8554                     fprintf (output_file,
8555                              "          return (%s (%s, %s) ? %d : %d);\n",
8556                              bypass->bypass_guard_name, INSN_PARAMETER_NAME,
8557                              INSN2_PARAMETER_NAME, bypass->latency,
8558                              DECL_INSN_RESERV (decl)->default_latency);
8559                 }
8560               fprintf (output_file, "        default:\n");
8561               fprintf (output_file,
8562                        "          return (%s != %s ? %d : 0);\n        }\n",
8563                        INTERNAL_INSN2_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME,
8564                        DECL_INSN_RESERV (decl)->default_latency);
8565               
8566             }
8567         }
8568     }
8569   fprintf (output_file, "    default:\n      return 0;\n    }\n}\n\n");
8570 }
8571
8572 /* The function outputs PHR interface function `insn_latency'.  */
8573 static void
8574 output_insn_latency_func ()
8575 {
8576   fprintf (output_file, "int\n%s (%s, %s)\n\trtx %s;\n\trtx %s;\n",
8577            INSN_LATENCY_FUNC_NAME, INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME,
8578            INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
8579   fprintf (output_file, "{\n  int %s, %s;\n",
8580            INTERNAL_INSN_CODE_NAME, INTERNAL_INSN2_CODE_NAME);
8581   output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
8582                                         INTERNAL_INSN_CODE_NAME, 0);
8583   output_internal_insn_code_evaluation (INSN2_PARAMETER_NAME,
8584                                         INTERNAL_INSN2_CODE_NAME, 0);
8585   fprintf (output_file, "  return %s (%s, %s, %s, %s);\n}\n\n",
8586            INTERNAL_INSN_LATENCY_FUNC_NAME,
8587            INTERNAL_INSN_CODE_NAME, INTERNAL_INSN2_CODE_NAME,
8588            INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
8589 }
8590
8591 /* The function outputs PHR interface function `print_reservation'.  */
8592 static void
8593 output_print_reservation_func ()
8594 {
8595   decl_t decl;
8596   int i;
8597
8598   fprintf (output_file, "void\n%s (%s, %s)\n\tFILE *%s;\n\trtx %s;\n",
8599            PRINT_RESERVATION_FUNC_NAME, FILE_PARAMETER_NAME,
8600            INSN_PARAMETER_NAME, FILE_PARAMETER_NAME,
8601            INSN_PARAMETER_NAME);
8602   fprintf (output_file, "{\n  int %s;\n", INTERNAL_INSN_CODE_NAME);
8603   fprintf (output_file, "\n  if (%s != 0)\n    {\n", INSN_PARAMETER_NAME);
8604   fprintf (output_file, "      %s = %s (%s);\n",
8605            INTERNAL_INSN_CODE_NAME, DFA_INSN_CODE_FUNC_NAME,
8606            INSN_PARAMETER_NAME);
8607   fprintf (output_file, "      if (%s > %s)\n",
8608            INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8609   fprintf (output_file, "        {\n          fprintf (%s, \"%s\");\n",
8610            FILE_PARAMETER_NAME, NOTHING_NAME);
8611   fprintf (output_file, "          return;\n        }\n");
8612   fprintf (output_file, "    }\n  else\n");
8613   fprintf (output_file,
8614            "    {\n      fprintf (%s, \"%s\");\n      return;\n    }\n",
8615            FILE_PARAMETER_NAME, NOTHING_NAME);
8616   fprintf (output_file, "  switch (%s)\n    {\n", INTERNAL_INSN_CODE_NAME);
8617   for (i = 0; i < description->decls_num; i++)
8618     {
8619       decl = description->decls [i];
8620       if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
8621         {
8622           fprintf (output_file,
8623                    "    case %d:\n", DECL_INSN_RESERV (decl)->insn_num);
8624           fprintf (output_file,
8625                    "      fprintf (%s, \"%s\");\n      break;\n",
8626                    FILE_PARAMETER_NAME,
8627                    regexp_representation (DECL_INSN_RESERV (decl)->regexp));
8628           finish_regexp_representation ();
8629         }
8630     }
8631   fprintf (output_file, "    default:\n      fprintf (%s, \"%s\");\n    }\n",
8632            FILE_PARAMETER_NAME, NOTHING_NAME);
8633   fprintf (output_file, "}\n\n");
8634 }
8635
8636 /* The following function is used to sort unit declaration by their
8637    names.  */
8638 static int
8639 units_cmp (unit1, unit2)
8640      const void *unit1, *unit2;
8641 {
8642   const unit_decl_t u1 = *(unit_decl_t *) unit1;
8643   const unit_decl_t u2 = *(unit_decl_t *) unit2;
8644
8645   return strcmp (u1->name, u2->name);
8646 }
8647
8648 /* The following macro value is name of struct containing unit name
8649    and unit code.  */
8650 #define NAME_CODE_STRUCT_NAME  "name_code"
8651
8652 /* The following macro value is name of table of struct name_code.  */
8653 #define NAME_CODE_TABLE_NAME   "name_code_table"
8654
8655 /* The following macro values are member names for struct name_code.  */
8656 #define NAME_MEMBER_NAME       "name"
8657 #define CODE_MEMBER_NAME       "code"
8658
8659 /* The following macro values are local variable names for function
8660    `get_cpu_unit_code'.  */
8661 #define CMP_VARIABLE_NAME      "cmp"
8662 #define LOW_VARIABLE_NAME      "l"
8663 #define MIDDLE_VARIABLE_NAME   "m"
8664 #define HIGH_VARIABLE_NAME     "h"
8665
8666 /* The following function outputs function to obtain internal cpu unit
8667    code by the cpu unit name.  */
8668 static void
8669 output_get_cpu_unit_code_func ()
8670 {
8671   int i;
8672   unit_decl_t *units;
8673   
8674   fprintf (output_file, "int\n%s (%s)\n\tconst char *%s;\n",
8675            GET_CPU_UNIT_CODE_FUNC_NAME, CPU_UNIT_NAME_PARAMETER_NAME,
8676            CPU_UNIT_NAME_PARAMETER_NAME);
8677   fprintf (output_file, "{\n  struct %s {const char *%s; int %s;};\n",
8678            NAME_CODE_STRUCT_NAME, NAME_MEMBER_NAME, CODE_MEMBER_NAME);
8679   fprintf (output_file, "  int %s, %s, %s, %s;\n", CMP_VARIABLE_NAME,
8680            LOW_VARIABLE_NAME, MIDDLE_VARIABLE_NAME, HIGH_VARIABLE_NAME);
8681   fprintf (output_file, "  static struct %s %s [] =\n    {\n",
8682            NAME_CODE_STRUCT_NAME, NAME_CODE_TABLE_NAME);
8683   units = (unit_decl_t *) xmalloc (sizeof (unit_decl_t)
8684                                    * description->units_num);
8685   memcpy (units, units_array, sizeof (unit_decl_t) * description->units_num);
8686   qsort (units, description->units_num, sizeof (unit_decl_t), units_cmp);
8687   for (i = 0; i < description->units_num; i++)
8688     if (units [i]->query_p)
8689       fprintf (output_file, "      {\"%s\", %d},\n",
8690                units[i]->name, units[i]->query_num);
8691   fprintf (output_file, "    };\n\n");
8692   fprintf (output_file, "  /* The following is binary search: */\n");
8693   fprintf (output_file, "  %s = 0;\n", LOW_VARIABLE_NAME);
8694   fprintf (output_file, "  %s = sizeof (%s) / sizeof (struct %s) - 1;\n",
8695            HIGH_VARIABLE_NAME, NAME_CODE_TABLE_NAME, NAME_CODE_STRUCT_NAME);
8696   fprintf (output_file, "  while (%s <= %s)\n    {\n",
8697            LOW_VARIABLE_NAME, HIGH_VARIABLE_NAME);
8698   fprintf (output_file, "      %s = (%s + %s) / 2;\n",
8699            MIDDLE_VARIABLE_NAME, LOW_VARIABLE_NAME, HIGH_VARIABLE_NAME);
8700   fprintf (output_file, "      %s = strcmp (%s, %s [%s].%s);\n",
8701            CMP_VARIABLE_NAME, CPU_UNIT_NAME_PARAMETER_NAME,
8702            NAME_CODE_TABLE_NAME, MIDDLE_VARIABLE_NAME, NAME_MEMBER_NAME);
8703   fprintf (output_file, "      if (%s < 0)\n", CMP_VARIABLE_NAME);
8704   fprintf (output_file, "        %s = %s - 1;\n",
8705            HIGH_VARIABLE_NAME, MIDDLE_VARIABLE_NAME);
8706   fprintf (output_file, "      else if (%s > 0)\n", CMP_VARIABLE_NAME);
8707   fprintf (output_file, "        %s = %s + 1;\n",
8708            LOW_VARIABLE_NAME, MIDDLE_VARIABLE_NAME);
8709   fprintf (output_file, "      else\n");
8710   fprintf (output_file, "        return %s [%s].%s;\n    }\n",
8711            NAME_CODE_TABLE_NAME, MIDDLE_VARIABLE_NAME, CODE_MEMBER_NAME);
8712   fprintf (output_file, "  return -1;\n}\n\n");
8713   free (units);
8714 }
8715
8716 /* The following function outputs function to check reservation of cpu
8717    unit (its internal code will be passed as the function argument) in
8718    given cpu state.  */
8719 static void
8720 output_cpu_unit_reservation_p ()
8721 {
8722   automaton_t automaton;
8723
8724   fprintf (output_file, "int\n%s (%s, %s)\n\t%s %s;\n\tint %s;\n",
8725            CPU_UNIT_RESERVATION_P_FUNC_NAME, STATE_NAME,
8726            CPU_CODE_PARAMETER_NAME, STATE_TYPE_NAME, STATE_NAME,
8727            CPU_CODE_PARAMETER_NAME);
8728   fprintf (output_file, "{\n  if (%s < 0 || %s >= %d)\n    abort ();\n",
8729            CPU_CODE_PARAMETER_NAME, CPU_CODE_PARAMETER_NAME,
8730            description->query_units_num);
8731   for (automaton = description->first_automaton;
8732        automaton != NULL;
8733        automaton = automaton->next_automaton)
8734     {
8735       fprintf (output_file, "  if ((");
8736       output_reserved_units_table_name (output_file, automaton);
8737       fprintf (output_file, " [((struct %s *) %s)->", CHIP_NAME, STATE_NAME);
8738       output_chip_member_name (output_file, automaton);
8739       fprintf (output_file, " * %d + %s / 8] >> (%s %% 8)) & 1)\n",
8740                (description->query_units_num + 7) / 8,
8741                CPU_CODE_PARAMETER_NAME, CPU_CODE_PARAMETER_NAME);
8742       fprintf (output_file, "    return 1;\n");
8743     }
8744   fprintf (output_file, "  return 0;\n}\n\n");
8745 }
8746
8747 /* The function outputs PHR interface function `dfa_start'.  */
8748 static void
8749 output_dfa_start_func ()
8750 {
8751   fprintf (output_file,
8752            "void\n%s ()\n{\n  int %s;\n\n  %s = get_max_uid ();\n",
8753            DFA_START_FUNC_NAME, I_VARIABLE_NAME,
8754            DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
8755   fprintf (output_file, "  %s = (int *) xmalloc (%s * sizeof (int));\n",
8756            DFA_INSN_CODES_VARIABLE_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
8757   fprintf (output_file,
8758            "  for (%s = 0; %s < %s; %s++)\n    %s [%s] = -1;\n}\n\n",
8759            I_VARIABLE_NAME, I_VARIABLE_NAME,
8760            DFA_INSN_CODES_LENGTH_VARIABLE_NAME, I_VARIABLE_NAME,
8761            DFA_INSN_CODES_VARIABLE_NAME, I_VARIABLE_NAME);
8762 }
8763
8764 /* The function outputs PHR interface function `dfa_finish'.  */
8765 static void
8766 output_dfa_finish_func ()
8767 {
8768   fprintf (output_file, "void\n%s ()\n{\n  free (%s);\n}\n\n",
8769            DFA_FINISH_FUNC_NAME, DFA_INSN_CODES_VARIABLE_NAME);
8770 }
8771
8772 \f
8773
8774 /* The page contains code for output description file (readable
8775    representation of original description and generated DFA(s).  */
8776
8777 /* The function outputs string representation of IR reservation.  */
8778 static void
8779 output_regexp (regexp)
8780      regexp_t regexp;
8781 {
8782   fprintf (output_description_file, "%s", regexp_representation (regexp));
8783   finish_regexp_representation ();
8784 }
8785
8786 /* Output names of units in LIST separated by comma.  */
8787 static void
8788 output_unit_set_el_list (list)
8789      unit_set_el_t list;
8790 {
8791   unit_set_el_t el;
8792
8793   for (el = list; el != NULL; el = el->next_unit_set_el)
8794     {
8795       if (el != list)
8796         fprintf (output_description_file, ",");
8797       fprintf (output_description_file, "%s", el->unit_decl->name);
8798     }
8799 }
8800
8801 /* The function outputs string representation of IR define_reservation
8802    and define_insn_reservation.  */
8803 static void
8804 output_description ()
8805 {
8806   decl_t decl;
8807   int i;
8808
8809   for (i = 0; i < description->decls_num; i++)
8810     {
8811       decl = description->decls [i];
8812       if (decl->mode == dm_unit)
8813         {
8814           if (DECL_UNIT (decl)->excl_list != NULL)
8815             {
8816               fprintf (output_description_file, "unit %s exlusion_set: ",
8817                        DECL_UNIT (decl)->name);
8818               output_unit_set_el_list (DECL_UNIT (decl)->excl_list);
8819               fprintf (output_description_file, "\n");
8820             }
8821           if (DECL_UNIT (decl)->presence_list != NULL)
8822             {
8823               fprintf (output_description_file, "unit %s presence_set: ",
8824                        DECL_UNIT (decl)->name);
8825               output_unit_set_el_list (DECL_UNIT (decl)->presence_list);
8826               fprintf (output_description_file, "\n");
8827             }
8828           if (DECL_UNIT (decl)->absence_list != NULL)
8829             {
8830               fprintf (output_description_file, "unit %s absence_set: ",
8831                        DECL_UNIT (decl)->name);
8832               output_unit_set_el_list (DECL_UNIT (decl)->absence_list);
8833               fprintf (output_description_file, "\n");
8834             }
8835         }
8836     }
8837   fprintf (output_description_file, "\n");
8838   for (i = 0; i < description->decls_num; i++)
8839     {
8840       decl = description->decls [i];
8841       if (decl->mode == dm_reserv)
8842         {
8843           fprintf (output_description_file, "reservation ");
8844           fprintf (output_description_file, DECL_RESERV (decl)->name);
8845           fprintf (output_description_file, ": ");
8846           output_regexp (DECL_RESERV (decl)->regexp);
8847           fprintf (output_description_file, "\n");
8848         }
8849       else if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
8850         {
8851           fprintf (output_description_file, "insn reservation %s ",
8852                    DECL_INSN_RESERV (decl)->name);
8853           print_rtl (output_description_file,
8854                      DECL_INSN_RESERV (decl)->condexp);
8855           fprintf (output_description_file, ": ");
8856           output_regexp (DECL_INSN_RESERV (decl)->regexp);
8857           fprintf (output_description_file, "\n");
8858         }
8859       else if (decl->mode == dm_bypass)
8860         fprintf (output_description_file, "bypass %d %s %s\n",
8861                  DECL_BYPASS (decl)->latency,
8862                  DECL_BYPASS (decl)->out_insn_name,
8863                  DECL_BYPASS (decl)->in_insn_name);
8864     }
8865   fprintf (output_description_file, "\n\f\n");
8866 }
8867
8868 /* The function outputs name of AUTOMATON.  */
8869 static void
8870 output_automaton_name (f, automaton)
8871      FILE *f;
8872      automaton_t automaton;
8873 {
8874   if (automaton->corresponding_automaton_decl == NULL)
8875     fprintf (f, "#%d", automaton->automaton_order_num);
8876   else
8877     fprintf (f, "`%s'", automaton->corresponding_automaton_decl->name);
8878 }
8879
8880 /* Maximal length of line for pretty printing into description
8881    file.  */
8882 #define MAX_LINE_LENGTH 70
8883
8884 /* The function outputs units name belonging to AUTOMATON.  */
8885 static void
8886 output_automaton_units (automaton)
8887      automaton_t automaton;
8888 {
8889   decl_t decl;
8890   char *name;
8891   int curr_line_length;
8892   int there_is_an_automaton_unit;
8893   int i;
8894
8895   fprintf (output_description_file, "\n  Coresponding units:\n");
8896   fprintf (output_description_file, "    ");
8897   curr_line_length = 4;
8898   there_is_an_automaton_unit = 0;
8899   for (i = 0; i < description->decls_num; i++)
8900     {
8901       decl = description->decls [i];
8902       if (decl->mode == dm_unit
8903           && (DECL_UNIT (decl)->corresponding_automaton_num
8904               == automaton->automaton_order_num))
8905         {
8906           there_is_an_automaton_unit = 1;
8907           name = DECL_UNIT (decl)->name;
8908           if (curr_line_length + strlen (name) + 1 > MAX_LINE_LENGTH )
8909             {
8910               curr_line_length = strlen (name) + 4;
8911               fprintf (output_description_file, "\n    ");
8912             }
8913           else
8914             {
8915               curr_line_length += strlen (name) + 1;
8916               fprintf (output_description_file, " ");
8917             }
8918           fprintf (output_description_file, name);
8919         }
8920     }
8921   if (!there_is_an_automaton_unit)
8922     fprintf (output_description_file, "<None>");
8923   fprintf (output_description_file, "\n\n");
8924 }
8925
8926 /* The following variable is used for forming array of all possible cpu unit
8927    reservations described by the current DFA state.  */
8928 static vla_ptr_t state_reservs;
8929
8930 /* The function forms `state_reservs' for STATE.  */
8931 static void
8932 add_state_reservs (state)
8933      state_t state;
8934 {
8935   alt_state_t curr_alt_state;
8936   reserv_sets_t reservs;
8937
8938   if (state->component_states != NULL)
8939     for (curr_alt_state = state->component_states;
8940          curr_alt_state != NULL;
8941          curr_alt_state = curr_alt_state->next_sorted_alt_state)
8942       add_state_reservs (curr_alt_state->state);
8943   else
8944     {
8945       reservs = state->reservs;
8946       VLA_PTR_ADD (state_reservs, reservs);
8947     }
8948 }
8949
8950 /* The function outputs readable represenatation of all out arcs of
8951    STATE.  */
8952 static void
8953 output_state_arcs (state)
8954      state_t state;
8955 {
8956   arc_t arc;
8957   ainsn_t ainsn;
8958   char *insn_name;
8959   int curr_line_length;
8960
8961   for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
8962     {
8963       ainsn = arc->insn;
8964       if (!ainsn->first_insn_with_same_reservs)
8965         abort ();
8966       fprintf (output_description_file, "    ");
8967       curr_line_length = 7;
8968       fprintf (output_description_file, "%2d: ", ainsn->insn_equiv_class_num);
8969       do
8970         {
8971           insn_name = ainsn->insn_reserv_decl->name;
8972           if (curr_line_length + strlen (insn_name) > MAX_LINE_LENGTH)
8973             {
8974               if (ainsn != arc->insn)
8975                 {
8976                   fprintf (output_description_file, ",\n      ");
8977                   curr_line_length = strlen (insn_name) + 6;
8978                 }
8979               else
8980                 curr_line_length += strlen (insn_name);
8981             }
8982           else
8983             {
8984               curr_line_length += strlen (insn_name);
8985               if (ainsn != arc->insn)
8986                 {
8987                   curr_line_length += 2;
8988                   fprintf (output_description_file, ", ");
8989                 }
8990             }
8991           fprintf (output_description_file, insn_name);
8992           ainsn = ainsn->next_same_reservs_insn;
8993         }
8994       while (ainsn != NULL);
8995       fprintf (output_description_file, "    %d (%d)\n",
8996                arc->to_state->order_state_num, arc->state_alts);
8997     }
8998   fprintf (output_description_file, "\n");
8999 }
9000
9001 /* The following function is used for sorting possible cpu unit
9002    reservation of a DFA state.  */
9003 static int
9004 state_reservs_cmp (reservs_ptr_1, reservs_ptr_2)
9005      const void *reservs_ptr_1;
9006      const void *reservs_ptr_2;
9007 {
9008   return reserv_sets_cmp (*(reserv_sets_t *) reservs_ptr_1,
9009                           *(reserv_sets_t *) reservs_ptr_2);
9010 }
9011
9012 /* The following function is used for sorting possible cpu unit
9013    reservation of a DFA state.  */
9014 static void
9015 remove_state_duplicate_reservs ()
9016 {
9017   reserv_sets_t *reservs_ptr;
9018   reserv_sets_t *last_formed_reservs_ptr;
9019
9020   last_formed_reservs_ptr = NULL;
9021   for (reservs_ptr = VLA_PTR_BEGIN (state_reservs);
9022        reservs_ptr <= (reserv_sets_t *) VLA_PTR_LAST (state_reservs);
9023        reservs_ptr++)
9024     if (last_formed_reservs_ptr == NULL)
9025       last_formed_reservs_ptr = reservs_ptr;
9026     else if (reserv_sets_cmp (*last_formed_reservs_ptr, *reservs_ptr) != 0)
9027       {
9028         ++last_formed_reservs_ptr;
9029         *last_formed_reservs_ptr = *reservs_ptr;
9030       }
9031   VLA_PTR_SHORTEN (state_reservs, reservs_ptr - last_formed_reservs_ptr - 1);
9032 }
9033
9034 /* The following function output readable representation of DFA(s)
9035    state used for fast recognition of pipeline hazards.  State is
9036    described by possible (current and scehduled) cpu unit
9037    reservations.  */
9038 static void
9039 output_state (state)
9040      state_t state;
9041 {
9042   reserv_sets_t *reservs_ptr;
9043
9044   VLA_PTR_CREATE (state_reservs, 150, "state reservations");
9045   fprintf (output_description_file, "  State #%d", state->order_state_num);
9046   fprintf (output_description_file,
9047            state->new_cycle_p ? " (new cycle)\n" : "\n");
9048   add_state_reservs (state);
9049   qsort (VLA_PTR_BEGIN (state_reservs), VLA_PTR_LENGTH (state_reservs),
9050          sizeof (reserv_sets_t), state_reservs_cmp);
9051   remove_state_duplicate_reservs ();
9052   for (reservs_ptr = VLA_PTR_BEGIN (state_reservs);
9053        reservs_ptr <= (reserv_sets_t *) VLA_PTR_LAST (state_reservs);
9054        reservs_ptr++)
9055     {
9056       fprintf (output_description_file, "    ");
9057       output_reserv_sets (output_description_file, *reservs_ptr);
9058       fprintf (output_description_file, "\n");
9059     }
9060   fprintf (output_description_file, "\n");
9061   output_state_arcs (state);
9062   VLA_PTR_DELETE (state_reservs);
9063 }
9064
9065 /* The following function output readable representation of
9066    DFAs used for fast recognition of pipeline hazards.  */
9067 static void
9068 output_automaton_descriptions ()
9069 {
9070   automaton_t automaton;
9071
9072   for (automaton = description->first_automaton;
9073        automaton != NULL;
9074        automaton = automaton->next_automaton)
9075     {
9076       fprintf (output_description_file, "\nAutomaton ");
9077       output_automaton_name (output_description_file, automaton);
9078       fprintf (output_description_file, "\n");
9079       output_automaton_units (automaton);
9080       pass_states (automaton, output_state);
9081     }
9082 }
9083
9084 \f
9085
9086 /* The page contains top level function for generation DFA(s) used for
9087    PHR.  */
9088
9089 /* The function outputs statistics about work of different phases of
9090    DFA generator.  */
9091 static void
9092 output_statistics (f)
9093      FILE *f;
9094 {
9095   automaton_t automaton;
9096 #ifndef NDEBUG
9097   int transition_comb_vect_els = 0;
9098   int transition_full_vect_els = 0;
9099   int state_alts_comb_vect_els = 0;
9100   int state_alts_full_vect_els = 0;
9101   int min_issue_delay_vect_els = 0;
9102 #endif
9103
9104   for (automaton = description->first_automaton;
9105        automaton != NULL;
9106        automaton = automaton->next_automaton)
9107     {
9108       fprintf (f, "\nAutomaton ");
9109       output_automaton_name (f, automaton);
9110       fprintf (f, "\n    %5d NDFA states,          %5d NDFA arcs\n",
9111                automaton->NDFA_states_num, automaton->NDFA_arcs_num);
9112       fprintf (f, "    %5d DFA states,           %5d DFA arcs\n",
9113                automaton->DFA_states_num, automaton->DFA_arcs_num);
9114       if (!no_minimization_flag)
9115         fprintf (f, "    %5d minimal DFA states,   %5d minimal DFA arcs\n",
9116                  automaton->minimal_DFA_states_num,
9117                  automaton->minimal_DFA_arcs_num);
9118       fprintf (f, "    %5d all insns      %5d insn equivalence classes\n",
9119                description->insns_num, automaton->insn_equiv_classes_num);
9120 #ifndef NDEBUG
9121       fprintf
9122         (f, "%5ld transition comb vector els, %5ld trans table els: %s\n",
9123          (long) VLA_HWINT_LENGTH (automaton->trans_table->comb_vect),
9124          (long) VLA_HWINT_LENGTH (automaton->trans_table->full_vect),
9125          (comb_vect_p (automaton->trans_table)
9126           ? "use comb vect" : "use simple vect"));
9127       fprintf
9128         (f, "%5ld state alts comb vector els, %5ld state alts table els: %s\n",
9129          (long) VLA_HWINT_LENGTH (automaton->state_alts_table->comb_vect),
9130          (long) VLA_HWINT_LENGTH (automaton->state_alts_table->full_vect),
9131          (comb_vect_p (automaton->state_alts_table)
9132           ? "use comb vect" : "use simple vect"));
9133       fprintf
9134         (f, "%5ld min delay table els, compression factor %d\n",
9135          (long) automaton->DFA_states_num * automaton->insn_equiv_classes_num,
9136          automaton->min_issue_delay_table_compression_factor);
9137       transition_comb_vect_els
9138         += VLA_HWINT_LENGTH (automaton->trans_table->comb_vect);
9139       transition_full_vect_els 
9140         += VLA_HWINT_LENGTH (automaton->trans_table->full_vect);
9141       state_alts_comb_vect_els
9142         += VLA_HWINT_LENGTH (automaton->state_alts_table->comb_vect);
9143       state_alts_full_vect_els
9144         += VLA_HWINT_LENGTH (automaton->state_alts_table->full_vect);
9145       min_issue_delay_vect_els
9146         += automaton->DFA_states_num * automaton->insn_equiv_classes_num;
9147 #endif
9148     }
9149 #ifndef NDEBUG
9150   fprintf (f, "\n%5d all allocated states,     %5d all allocated arcs\n",
9151            allocated_states_num, allocated_arcs_num);
9152   fprintf (f, "%5d all allocated alternative states\n",
9153            allocated_alt_states_num);
9154   fprintf (f, "%5d all transition comb vector els, %5d all trans table els\n",
9155            transition_comb_vect_els, transition_full_vect_els);
9156   fprintf
9157     (f, "%5d all state alts comb vector els, %5d all state alts table els\n",
9158      state_alts_comb_vect_els, state_alts_full_vect_els);
9159   fprintf (f, "%5d all min delay table els\n", min_issue_delay_vect_els);
9160   fprintf (f, "%5d locked states num\n", locked_states_num);
9161 #endif
9162 }
9163
9164 /* The function output times of work of different phases of DFA
9165    generator.  */
9166 static void
9167 output_time_statistics (f)
9168      FILE *f;
9169 {
9170   fprintf (f, "\n  transformation: ");
9171   print_active_time (f, transform_time);
9172   fprintf (f, (!ndfa_flag ? ", building DFA: " : ", building NDFA: "));
9173   print_active_time (f, NDFA_time);
9174   if (ndfa_flag)
9175     {
9176       fprintf (f, ", NDFA -> DFA: ");
9177       print_active_time (f, NDFA_to_DFA_time);
9178     }
9179   fprintf (f, "\n  DFA minimization: ");
9180   print_active_time (f, minimize_time);
9181   fprintf (f, ", making insn equivalence: ");
9182   print_active_time (f, equiv_time);
9183   fprintf (f, "\n all automaton generation: ");
9184   print_active_time (f, automaton_generation_time);
9185   fprintf (f, ", output: ");
9186   print_active_time (f, output_time);
9187   fprintf (f, "\n");
9188 }
9189
9190 /* The function generates DFA (deterministic finate state automaton)
9191    for fast recognition of pipeline hazards.  No errors during
9192    checking must be fixed before this function call.  */
9193 static void
9194 generate ()
9195 {
9196   automata_num = split_argument;
9197   if (description->units_num < automata_num)
9198     automata_num = description->units_num;
9199   initiate_states ();
9200   initiate_arcs ();
9201   initiate_automata_lists ();
9202   initiate_pass_states ();
9203   initiate_excl_sets ();
9204   initiate_presence_absence_sets ();
9205   automaton_generation_time = create_ticker ();
9206   create_automata ();
9207   ticker_off (&automaton_generation_time);
9208 }
9209
9210 \f
9211
9212 /* The following function creates insn attribute whose values are
9213    number alternatives in insn reservations.  */
9214 static void
9215 make_insn_alts_attr ()
9216 {
9217   int i, insn_num;
9218   decl_t decl;
9219   rtx condexp;
9220
9221   condexp = rtx_alloc (COND);
9222   XVEC (condexp, 0) = rtvec_alloc ((description->insns_num - 1) * 2);
9223   XEXP (condexp, 1) = make_numeric_value (0);
9224   for (i = insn_num = 0; i < description->decls_num; i++)
9225     {
9226       decl = description->decls [i];
9227       if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
9228         {
9229           XVECEXP (condexp, 0, 2 * insn_num)
9230             = DECL_INSN_RESERV (decl)->condexp;
9231           XVECEXP (condexp, 0, 2 * insn_num + 1)
9232             = make_numeric_value
9233               (DECL_INSN_RESERV (decl)->transformed_regexp->mode != rm_oneof
9234                ? 1 : REGEXP_ONEOF (DECL_INSN_RESERV (decl)
9235                                    ->transformed_regexp)->regexps_num);
9236           insn_num++;
9237         }
9238     }
9239   if (description->insns_num != insn_num + 1)
9240     abort ();
9241   make_internal_attr (attr_printf (sizeof ("*")
9242                                    + strlen (INSN_ALTS_FUNC_NAME) + 1,
9243                                    "*%s", INSN_ALTS_FUNC_NAME),
9244                       condexp, 0);
9245 }
9246
9247 \f
9248
9249 /* The following function creates attribute which is order number of
9250    insn in pipeline hazard description translator.  */
9251 static void
9252 make_internal_dfa_insn_code_attr ()
9253 {
9254   int i, insn_num;
9255   decl_t decl;
9256   rtx condexp;
9257
9258   condexp = rtx_alloc (COND);
9259   XVEC (condexp, 0) = rtvec_alloc ((description->insns_num - 1) * 2);
9260   XEXP (condexp, 1)
9261     = make_numeric_value (DECL_INSN_RESERV (advance_cycle_insn_decl)
9262                           ->insn_num + 1);
9263   for (i = insn_num = 0; i < description->decls_num; i++)
9264     {
9265       decl = description->decls [i];
9266       if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
9267         {
9268           XVECEXP (condexp, 0, 2 * insn_num)
9269             = DECL_INSN_RESERV (decl)->condexp;
9270           XVECEXP (condexp, 0, 2 * insn_num + 1)
9271             = make_numeric_value (DECL_INSN_RESERV (decl)->insn_num);
9272           insn_num++;
9273         }
9274     }
9275   if (description->insns_num != insn_num + 1)
9276     abort ();
9277   make_internal_attr
9278     (attr_printf (sizeof ("*")
9279                   + strlen (INTERNAL_DFA_INSN_CODE_FUNC_NAME) + 1,
9280                   "*%s", INTERNAL_DFA_INSN_CODE_FUNC_NAME),
9281      condexp, 0);
9282 }
9283
9284 \f
9285
9286 /* The following function creates attribute which order number of insn
9287    in pipeline hazard description translator.  */
9288 static void
9289 make_default_insn_latency_attr ()
9290 {
9291   int i, insn_num;
9292   decl_t decl;
9293   rtx condexp;
9294
9295   condexp = rtx_alloc (COND);
9296   XVEC (condexp, 0) = rtvec_alloc ((description->insns_num - 1) * 2);
9297   XEXP (condexp, 1) = make_numeric_value (0);
9298   for (i = insn_num = 0; i < description->decls_num; i++)
9299     {
9300       decl = description->decls [i];
9301       if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
9302         {
9303           XVECEXP (condexp, 0, 2 * insn_num)
9304             = DECL_INSN_RESERV (decl)->condexp;
9305           XVECEXP (condexp, 0, 2 * insn_num + 1)
9306             = make_numeric_value (DECL_INSN_RESERV (decl)->default_latency);
9307           insn_num++;
9308         }
9309     }
9310   if (description->insns_num != insn_num + 1)
9311     abort ();
9312   make_internal_attr (attr_printf (sizeof ("*")
9313                                    + strlen (INSN_DEFAULT_LATENCY_FUNC_NAME)
9314                                    + 1, "*%s", INSN_DEFAULT_LATENCY_FUNC_NAME),
9315                       condexp, 0);
9316 }
9317
9318 \f
9319
9320 /* The following function creates attribute which returns 1 if given
9321    output insn has bypassing and 0 otherwise.  */
9322 static void
9323 make_bypass_attr ()
9324 {
9325   int i, bypass_insn;
9326   int bypass_insns_num = 0;
9327   decl_t decl;
9328   rtx result_rtx;
9329   
9330   for (i = 0; i < description->decls_num; i++)
9331     {
9332       decl = description->decls [i];
9333       if (decl->mode == dm_insn_reserv
9334           && DECL_INSN_RESERV (decl)->condexp != NULL
9335           && DECL_INSN_RESERV (decl)->bypass_list != NULL)
9336         bypass_insns_num++;
9337     }
9338   if (bypass_insns_num == 0)
9339     result_rtx = make_numeric_value (0);
9340   else
9341     {
9342       result_rtx = rtx_alloc (COND);
9343       XVEC (result_rtx, 0) = rtvec_alloc (bypass_insns_num * 2);
9344       XEXP (result_rtx, 1) = make_numeric_value (0);
9345
9346       for (i = bypass_insn = 0; i < description->decls_num; i++)
9347         {
9348           decl = description->decls [i];
9349           if (decl->mode == dm_insn_reserv
9350               && DECL_INSN_RESERV (decl)->condexp != NULL
9351               && DECL_INSN_RESERV (decl)->bypass_list != NULL)
9352             {
9353               XVECEXP (result_rtx, 0, 2 * bypass_insn)
9354                 = DECL_INSN_RESERV (decl)->condexp;
9355               XVECEXP (result_rtx, 0, 2 * bypass_insn + 1)
9356                 = make_numeric_value (1);
9357               bypass_insn++;
9358             }
9359         }
9360     }
9361   make_internal_attr (attr_printf (sizeof ("*")
9362                                    + strlen (BYPASS_P_FUNC_NAME) + 1,
9363                                    "*%s", BYPASS_P_FUNC_NAME),
9364                       result_rtx, 0);
9365 }
9366
9367 \f
9368
9369 /* This page mainly contains top level functions of pipeline hazards
9370    description translator.  */
9371
9372 /* The following macro value is suffix of name of description file of
9373    pipeline hazards description translator.  */
9374 #define STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX ".dfa"
9375
9376 /* The function returns suffix of given file name.  The returned
9377    string can not be changed.  */
9378 static const char *
9379 file_name_suffix (file_name)
9380      const char *file_name;
9381 {
9382   const char *last_period;
9383
9384   for (last_period = NULL; *file_name != '\0'; file_name++)
9385     if (*file_name == '.')
9386       last_period = file_name;
9387   return (last_period == NULL ? file_name : last_period);
9388 }
9389
9390 /* The function returns base name of given file name, i.e. pointer to
9391    first char after last `/' (or `\' for WIN32) in given file name,
9392    given file name itself if the directory name is absent.  The
9393    returned string can not be changed.  */
9394 static const char *
9395 base_file_name (file_name)
9396      const char *file_name;
9397 {
9398   int directory_name_length;
9399
9400   directory_name_length = strlen (file_name);
9401 #ifdef WIN32
9402   while (directory_name_length >= 0 && file_name[directory_name_length] != '/'
9403          && file_name[directory_name_length] != '\\')
9404 #else
9405   while (directory_name_length >= 0 && file_name[directory_name_length] != '/')
9406 #endif
9407     directory_name_length--;
9408   return file_name + directory_name_length + 1;
9409 }
9410
9411 /* The following is top level function to initialize the work of
9412    pipeline hazards description translator.  */
9413 void
9414 initiate_automaton_gen (argc, argv)
9415      int argc;
9416      char **argv;
9417 {
9418   const char *base_name;
9419   int i;
9420
9421   ndfa_flag = 0;
9422   split_argument = 0;  /* default value */
9423   no_minimization_flag = 0;
9424   time_flag = 0;
9425   v_flag = 0;
9426   w_flag = 0;
9427   for (i = 2; i < argc; i++)
9428     if (strcmp (argv [i], NO_MINIMIZATION_OPTION) == 0)
9429       no_minimization_flag = 1;
9430     else if (strcmp (argv [i], TIME_OPTION) == 0)
9431       time_flag = 1;
9432     else if (strcmp (argv [i], V_OPTION) == 0)
9433       v_flag = 1;
9434     else if (strcmp (argv [i], W_OPTION) == 0)
9435       w_flag = 1;
9436     else if (strcmp (argv [i], NDFA_OPTION) == 0)
9437       ndfa_flag = 1;
9438     else if (strcmp (argv [i], "-split") == 0)
9439       {
9440         if (i + 1 >= argc)
9441           fatal ("-split has no argument.");
9442         fatal ("option `-split' has not been implemented yet\n");
9443         /* split_argument = atoi (argument_vect [i + 1]); */
9444       }
9445   VLA_PTR_CREATE (decls, 150, "decls");
9446   /* Initialize IR storage.  */
9447   obstack_init (&irp);
9448   initiate_automaton_decl_table ();
9449   initiate_insn_decl_table ();
9450   initiate_decl_table ();
9451   output_file = stdout;
9452   output_description_file = NULL;
9453   base_name = base_file_name (argv[1]);
9454   obstack_grow (&irp, base_name,
9455                 strlen (base_name) - strlen (file_name_suffix (base_name)));
9456   obstack_grow (&irp, STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX,
9457                 strlen (STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX) + 1);
9458   obstack_1grow (&irp, '\0');
9459   output_description_file_name = obstack_base (&irp);
9460   obstack_finish (&irp);
9461 }
9462
9463 /* The following function checks existence at least one arc marked by
9464    each insn.  */
9465 static void
9466 check_automata_insn_issues ()
9467 {
9468   automaton_t automaton;
9469   ainsn_t ainsn, reserv_ainsn;
9470
9471   for (automaton = description->first_automaton;
9472        automaton != NULL;
9473        automaton = automaton->next_automaton)
9474     {
9475       for (ainsn = automaton->ainsn_list;
9476            ainsn != NULL;
9477            ainsn = ainsn->next_ainsn)
9478         if (ainsn->first_insn_with_same_reservs && !ainsn->arc_exists_p)
9479           {
9480             for (reserv_ainsn = ainsn;
9481                  reserv_ainsn != NULL;
9482                  reserv_ainsn = reserv_ainsn->next_same_reservs_insn)
9483               if (automaton->corresponding_automaton_decl != NULL)
9484                 {
9485                   if (!w_flag)
9486                     error ("Automaton `%s': Insn `%s' will never be issued",
9487                            automaton->corresponding_automaton_decl->name,
9488                            reserv_ainsn->insn_reserv_decl->name);
9489                   else
9490                     warning
9491                       ("Automaton `%s': Insn `%s' will never be issued",
9492                        automaton->corresponding_automaton_decl->name,
9493                        reserv_ainsn->insn_reserv_decl->name);
9494                 }
9495               else
9496                 {
9497                   if (!w_flag)
9498                     error ("Insn `%s' will never be issued",
9499                            reserv_ainsn->insn_reserv_decl->name);
9500                   else
9501                     warning ("Insn `%s' will never be issued",
9502                              reserv_ainsn->insn_reserv_decl->name);
9503                 }
9504           }
9505     }
9506 }
9507
9508 /* The following vla is used for storing pointers to all achieved
9509    states.  */
9510 static vla_ptr_t automaton_states;
9511
9512 /* This function is called by function pass_states to add an achieved
9513    STATE.  */
9514 static void
9515 add_automaton_state (state)
9516      state_t state;
9517 {
9518   VLA_PTR_ADD (automaton_states, state);
9519 }
9520
9521 /* The following function forms list of important automata (whose
9522    states may be changed after the insn issue) for each insn.  */
9523 static void
9524 form_important_insn_automata_lists ()
9525 {
9526   automaton_t automaton;
9527   state_t *state_ptr;
9528   decl_t decl;
9529   ainsn_t ainsn;
9530   arc_t arc;
9531   int i;
9532
9533   VLA_PTR_CREATE (automaton_states, 1500,
9534                   "automaton states for forming important insn automata sets");
9535   /* Mark important ainsns.  */
9536   for (automaton = description->first_automaton;
9537        automaton != NULL;
9538        automaton = automaton->next_automaton)
9539     {
9540       VLA_PTR_NULLIFY (automaton_states);
9541       pass_states (automaton, add_automaton_state);
9542       for (state_ptr = VLA_PTR_BEGIN (automaton_states);
9543            state_ptr <= (state_t *) VLA_PTR_LAST (automaton_states);
9544            state_ptr++)
9545         {
9546           for (arc = first_out_arc (*state_ptr);
9547                arc != NULL;
9548                arc = next_out_arc (arc))
9549             if (arc->to_state != *state_ptr)
9550               {
9551                 if (!arc->insn->first_insn_with_same_reservs)
9552                   abort ();
9553                 for (ainsn = arc->insn;
9554                      ainsn != NULL;
9555                      ainsn = ainsn->next_same_reservs_insn)
9556                   ainsn->important_p = TRUE;
9557               }
9558         }
9559     }
9560   VLA_PTR_DELETE (automaton_states);
9561   /* Create automata sets for the insns.  */
9562   for (i = 0; i < description->decls_num; i++)
9563     {
9564       decl = description->decls [i];
9565       if (decl->mode == dm_insn_reserv)
9566         {
9567           automata_list_start ();
9568           for (automaton = description->first_automaton;
9569                automaton != NULL;
9570                automaton = automaton->next_automaton)
9571             for (ainsn = automaton->ainsn_list;
9572                  ainsn != NULL;
9573                  ainsn = ainsn->next_ainsn)
9574               if (ainsn->important_p
9575                   && ainsn->insn_reserv_decl == DECL_INSN_RESERV (decl))
9576                 {
9577                   automata_list_add (automaton);
9578                   break;
9579                 }
9580           DECL_INSN_RESERV (decl)->important_automata_list
9581             = automata_list_finish ();
9582         }
9583     }
9584 }
9585
9586
9587 /* The following is top level function to generate automat(a,on) for
9588    fast recognition of pipeline hazards.  */
9589 void
9590 expand_automata ()
9591 {
9592   int i;
9593
9594   description = create_node (sizeof (struct description)
9595                              /* One entry for cycle advancing insn.  */
9596                              + sizeof (decl_t) * VLA_PTR_LENGTH (decls));
9597   description->decls_num = VLA_PTR_LENGTH (decls);
9598   description->query_units_num = 0;
9599   for (i = 0; i < description->decls_num; i++)
9600     {
9601       description->decls [i] = VLA_PTR (decls, i);
9602       if (description->decls [i]->mode == dm_unit
9603           && DECL_UNIT (description->decls [i])->query_p)
9604         DECL_UNIT (description->decls [i])->query_num
9605           = description->query_units_num++;
9606     }
9607   all_time = create_ticker ();
9608   check_time = create_ticker ();
9609   fprintf (stderr, "Check description...");
9610   fflush (stderr);
9611   check_all_description ();
9612   fprintf (stderr, "done\n");
9613   ticker_off (&check_time);
9614   generation_time = create_ticker ();
9615   if (!have_error)
9616     {
9617       transform_insn_regexps ();
9618       check_unit_distributions_to_automata ();
9619     }
9620   if (!have_error)
9621     {
9622       generate ();
9623       check_automata_insn_issues ();
9624     }
9625   if (!have_error)
9626     {
9627       form_important_insn_automata_lists ();
9628       fprintf (stderr, "Generation of attributes...");
9629       fflush (stderr);
9630       make_internal_dfa_insn_code_attr ();
9631       make_insn_alts_attr ();
9632       make_default_insn_latency_attr ();
9633       make_bypass_attr ();
9634       fprintf (stderr, "done\n");
9635     }
9636   ticker_off (&generation_time);
9637   ticker_off (&all_time);
9638   fprintf (stderr, "All other genattrtab stuff...");
9639   fflush (stderr);
9640 }
9641
9642 /* The following is top level function to output PHR and to finish
9643    work with pipeline description translator.  */
9644 void
9645 write_automata ()
9646 {
9647   fprintf (stderr, "done\n");
9648   if (have_error)
9649     fatal ("Errors in DFA description");
9650   ticker_on (&all_time);
9651   output_time = create_ticker ();
9652   fprintf (stderr, "Forming and outputing automata tables...");
9653   fflush (stderr);
9654   output_dfa_max_issue_rate ();
9655   output_tables ();
9656   fprintf (stderr, "done\n");
9657   fprintf (stderr, "Output functions to work with automata...");
9658   fflush (stderr);
9659   output_chip_definitions ();
9660   output_max_insn_queue_index_def ();
9661   output_internal_min_issue_delay_func ();
9662   output_internal_trans_func ();
9663   /* Cache of insn dfa codes: */
9664   fprintf (output_file, "\nstatic int *%s;\n", DFA_INSN_CODES_VARIABLE_NAME);
9665   fprintf (output_file, "\nstatic int %s;\n\n",
9666            DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
9667   output_dfa_insn_code_func ();
9668   output_trans_func ();
9669   fprintf (output_file, "\n#if %s\n\n", AUTOMATON_STATE_ALTS_MACRO_NAME);
9670   output_internal_state_alts_func ();
9671   output_state_alts_func ();
9672   fprintf (output_file, "\n#endif /* #if %s */\n\n",
9673            AUTOMATON_STATE_ALTS_MACRO_NAME);
9674   output_min_issue_delay_func ();
9675   output_internal_dead_lock_func ();
9676   output_dead_lock_func ();
9677   output_size_func ();
9678   output_internal_reset_func ();
9679   output_reset_func ();
9680   output_min_insn_conflict_delay_func ();
9681   output_internal_insn_latency_func ();
9682   output_insn_latency_func ();
9683   output_print_reservation_func ();
9684   if (no_minimization_flag)
9685     {
9686       fprintf (output_file, "\n#if %s\n\n", CPU_UNITS_QUERY_MACRO_NAME);
9687       output_get_cpu_unit_code_func ();
9688       output_cpu_unit_reservation_p ();
9689       fprintf (output_file, "\n#endif /* #if %s */\n\n",
9690                CPU_UNITS_QUERY_MACRO_NAME);
9691     }
9692   output_dfa_start_func ();
9693   output_dfa_finish_func ();
9694   fprintf (stderr, "done\n");
9695   if (v_flag)
9696     {
9697       output_description_file = fopen (output_description_file_name, "w");
9698       if (output_description_file == NULL)
9699         {
9700           perror (output_description_file_name);
9701           exit (FATAL_EXIT_CODE);
9702         }
9703       fprintf (stderr, "Output automata description...");
9704       fflush (stderr);
9705       output_description ();
9706       output_automaton_descriptions ();
9707       fprintf (stderr, "done\n");
9708       output_statistics (output_description_file);
9709     }
9710   output_statistics (stderr);
9711   ticker_off (&output_time);
9712   output_time_statistics (stderr);
9713   finish_states ();
9714   finish_arcs ();
9715   finish_automata_lists ();
9716   if (time_flag)
9717     {
9718       fprintf (stderr, "Summary:\n");
9719       fprintf (stderr, "  check time ");
9720       print_active_time (stderr, check_time);
9721       fprintf (stderr, ", generation time ");
9722       print_active_time (stderr, generation_time);
9723       fprintf (stderr, ", all time ");
9724       print_active_time (stderr, all_time);
9725       fprintf (stderr, "\n");
9726     }
9727   /* Finish all work.  */
9728   if (output_description_file != NULL)
9729     {
9730       fflush (output_description_file);
9731       if (ferror (stdout) != 0)
9732         fatal ("Error in writing DFA description file %s",
9733                output_description_file_name);
9734       fclose (output_description_file);
9735     }
9736   finish_automaton_decl_table ();
9737   finish_insn_decl_table ();
9738   finish_decl_table ();
9739   obstack_free (&irp, NULL);
9740   if (have_error && output_description_file != NULL)
9741     remove (output_description_file_name);
9742 }