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