OSDN Git Service

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