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