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