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