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