decl2.c (check_classfn): Fix uninitialized warning.
[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 {
5279 if (REGEXP_ALLOF (regexp)->regexps [i]->mode == rm_sequence)
5280 {
5281 seq = REGEXP_ALLOF (regexp)->regexps [i];
5282 if (max_seq_length < REGEXP_SEQUENCE (seq)->regexps_num)
5283 max_seq_length = REGEXP_SEQUENCE (seq)->regexps_num;
5284 }
5285 else if (REGEXP_ALLOF (regexp)->regexps [i]->mode != rm_unit
5286 && REGEXP_ALLOF (regexp)->regexps [i]->mode != rm_nothing)
5287 {
5288 max_seq_length = 0;
5289 break;
5290 }
5291 }
5292 if (max_seq_length != 0)
5293 {
5294 if (max_seq_length == 1 || REGEXP_ALLOF (regexp)->regexps_num <= 1)
5295 abort ();
5296 result = create_node (sizeof (struct regexp)
5297 + sizeof (regexp_t) * (max_seq_length - 1));
5298 result->mode = rm_sequence;
5299 result->pos = regexp->pos;
5300 REGEXP_SEQUENCE (result)->regexps_num = max_seq_length;
5301 for (i = 0; i < max_seq_length; i++)
5302 {
5303 allof_length = 0;
5304 for (j = 0; j < REGEXP_ALLOF (regexp)->regexps_num; j++)
5305 if (REGEXP_ALLOF (regexp)->regexps [j]->mode == rm_sequence
5306 && (i < (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp)
5307 ->regexps [j])->regexps_num)))
5308 {
5309 allof_op
5310 = (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp)->regexps [j])
5311 ->regexps [i]);
5312 allof_length++;
5313 }
5314 else if (i == 0
5315 && (REGEXP_ALLOF (regexp)->regexps [j]->mode
5316 == rm_unit
5317 || (REGEXP_ALLOF (regexp)->regexps [j]->mode
5318 == rm_nothing)))
5319 {
5320 allof_op = REGEXP_ALLOF (regexp)->regexps [j];
5321 allof_length++;
5322 }
5323 if (allof_length == 1)
5324 REGEXP_SEQUENCE (result)->regexps [i] = allof_op;
5325 else
5326 {
5327 allof = create_node (sizeof (struct regexp)
5328 + sizeof (regexp_t)
5329 * (allof_length - 1));
5330 allof->mode = rm_allof;
5331 allof->pos = regexp->pos;
5332 REGEXP_ALLOF (allof)->regexps_num = allof_length;
5333 REGEXP_SEQUENCE (result)->regexps [i] = allof;
5334 allof_length = 0;
5335 for (j = 0; j < REGEXP_ALLOF (regexp)->regexps_num; j++)
5336 if (REGEXP_ALLOF (regexp)->regexps [j]->mode == rm_sequence
5337 && (i <
5338 (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp)
5339 ->regexps [j])->regexps_num)))
5340 {
5341 allof_op = (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp)
5342 ->regexps [j])
5343 ->regexps [i]);
5344 REGEXP_ALLOF (allof)->regexps [allof_length]
5345 = allof_op;
5346 allof_length++;
5347 }
5348 else if (i == 0
5349 && (REGEXP_ALLOF (regexp)->regexps [j]->mode
5350 == rm_unit
5351 || (REGEXP_ALLOF (regexp)->regexps [j]->mode
5352 == rm_nothing)))
5353 {
5354 allof_op = REGEXP_ALLOF (regexp)->regexps [j];
5355 REGEXP_ALLOF (allof)->regexps [allof_length]
5356 = allof_op;
5357 allof_length++;
5358 }
5359 }
5360 }
5361 regexp_transformed_p = 1;
5362 regexp = result;
5363 }
5364 }
5365 return regexp;
5366 }
5367
5368 /* The function traverses IR of reservation and applies transformations
5369 implemented by FUNC. */
5370 static regexp_t
5371 regexp_transform_func (regexp, func)
5372 regexp_t regexp;
5373 regexp_t (*func) PARAMS ((regexp_t regexp));
5374 {
5375 int i;
5376
5377 if (regexp->mode == rm_sequence)
5378 for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
5379 REGEXP_SEQUENCE (regexp)->regexps [i]
5380 = regexp_transform_func (REGEXP_SEQUENCE (regexp)->regexps [i], func);
5381 else if (regexp->mode == rm_allof)
5382 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
5383 REGEXP_ALLOF (regexp)->regexps [i]
5384 = regexp_transform_func (REGEXP_ALLOF (regexp)->regexps [i], func);
5385 else if (regexp->mode == rm_oneof)
5386 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
5387 REGEXP_ONEOF (regexp)->regexps [i]
5388 = regexp_transform_func (REGEXP_ONEOF (regexp)->regexps [i], func);
5389 else if (regexp->mode == rm_repeat)
5390 REGEXP_REPEAT (regexp)->regexp
5391 = regexp_transform_func (REGEXP_REPEAT (regexp)->regexp, func);
5392 else if (regexp->mode != rm_nothing && regexp->mode != rm_unit)
5393 abort ();
5394 return (*func) (regexp);
5395 }
5396
5397 /* The function applies all transformations for IR representation of
5398 reservation REGEXP. */
5399 static regexp_t
5400 transform_regexp (regexp)
5401 regexp_t regexp;
5402 {
5403 regexp = regexp_transform_func (regexp, transform_1);
5404 do
5405 {
5406 regexp_transformed_p = 0;
5407 regexp = regexp_transform_func (regexp, transform_2);
5408 regexp = regexp_transform_func (regexp, transform_3);
5409 }
5410 while (regexp_transformed_p);
5411 return regexp;
5412 }
5413
5414 /* The function applys all transformations for reservations of all
5415 insn declarations. */
5416 static void
5417 transform_insn_regexps ()
5418 {
5419 decl_t decl;
5420 int i;
5421
5422 transform_time = create_ticker ();
5423 add_advance_cycle_insn_decl ();
5424 fprintf (stderr, "Reservation transformation...");
5425 fflush (stderr);
5426 for (i = 0; i < description->decls_num; i++)
5427 {
5428 decl = description->decls [i];
5429 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
5430 DECL_INSN_RESERV (decl)->transformed_regexp
5431 = transform_regexp (copy_insn_regexp
5432 (DECL_INSN_RESERV (decl)->regexp));
5433 }
5434 fprintf (stderr, "done\n");
5435 ticker_off (&transform_time);
5436 fflush (stderr);
5437 }
5438
5439 \f
5440
5441 /* The following variable value is TRUE if the first annotated message
5442 about units to automata distribution has been output. */
5443 static int annotation_message_reported_p;
5444
5445 /* The function processes all alternative reservations on CYCLE in
5446 given REGEXP of insn reservation with INSN_RESERV_NAME to check the
5447 UNIT (or another unit from the same automaton) is not reserved on
5448 the all alternatives. If it is true, the function outputs message
5449 about the rule violation. */
5450 static void
5451 check_unit_distribution_in_reserv (insn_reserv_name, unit, regexp, cycle)
5452 const char *insn_reserv_name;
5453 regexp_t unit;
5454 regexp_t regexp;
5455 int cycle;
5456 {
5457 int i, k;
5458 regexp_t seq, allof;
5459 unit_decl_t unit_decl;
5460
5461 if (regexp == NULL || regexp->mode != rm_oneof)
5462 abort ();
5463 unit_decl = REGEXP_UNIT (unit)->unit_decl;
5464 for (i = REGEXP_ONEOF (regexp)->regexps_num - 1; i >= 0; i--)
5465 {
5466 seq = REGEXP_ONEOF (regexp)->regexps [i];
5467 if (seq->mode == rm_sequence)
5468 {
5469 if (cycle >= REGEXP_SEQUENCE (seq)->regexps_num)
5470 continue;
5471 allof = REGEXP_SEQUENCE (seq)->regexps [cycle];
5472 if (allof->mode == rm_allof)
5473 {
5474 for (k = 0; k < REGEXP_ALLOF (allof)->regexps_num; k++)
5475 if (REGEXP_ALLOF (allof)->regexps [k]->mode == rm_unit
5476 && (REGEXP_UNIT (REGEXP_ALLOF (allof)->regexps [k])
5477 ->unit_decl->automaton_decl
5478 == unit_decl->automaton_decl))
5479 break;
5480 if (k >= REGEXP_ALLOF (allof)->regexps_num)
5481 break;
5482 }
5483 else if (allof->mode == rm_unit
5484 && (REGEXP_UNIT (allof)->unit_decl->automaton_decl
5485 != unit_decl->automaton_decl))
5486 break;
5487 }
5488 else if (cycle != 0)
5489 continue;
5490 else if (seq->mode == rm_allof)
5491 {
5492 for (k = 0; k < REGEXP_ALLOF (seq)->regexps_num; k++)
5493 if (REGEXP_ALLOF (seq)->regexps [k]->mode == rm_unit
5494 && (REGEXP_UNIT (REGEXP_ALLOF (seq)->regexps [k])
5495 ->unit_decl->automaton_decl == unit_decl->automaton_decl))
5496 break;
5497 if (k >= REGEXP_ALLOF (seq)->regexps_num)
5498 break;
5499 }
5500 else if (seq->mode == rm_unit
5501 && (REGEXP_UNIT (seq)->unit_decl->automaton_decl
5502 != unit_decl->automaton_decl))
5503 break;
5504 }
5505 if (i >= 0)
5506 {
5507 if (!annotation_message_reported_p)
5508 {
5509 fprintf (stderr, "\n");
5510 error ("The following units do not satisfy units-automata distribution rule");
5511 error (" (A unit of given unit automaton should be on each reserv. altern.)");
5512 annotation_message_reported_p = TRUE;
5513 }
5514 error ("Unit %s, reserv. %s, cycle %d",
5515 unit_decl->name, insn_reserv_name, cycle);
5516 }
5517 }
5518
5519 /* The function processes given REGEXP to find units with the wrong
5520 distribution. */
5521 static void
5522 check_regexp_units_distribution (insn_reserv_name, regexp)
5523 const char *insn_reserv_name;
5524 regexp_t regexp;
5525 {
5526 int i, j, k;
5527 regexp_t seq, allof, unit;
5528
5529 if (regexp == NULL || regexp->mode != rm_oneof)
5530 return;
5531 for (i = REGEXP_ONEOF (regexp)->regexps_num - 1; i >= 0; i--)
5532 {
5533 seq = REGEXP_ONEOF (regexp)->regexps [i];
5534 if (seq->mode == rm_sequence)
5535 for (j = 0; j < REGEXP_SEQUENCE (seq)->regexps_num; j++)
5536 {
5537 allof = REGEXP_SEQUENCE (seq)->regexps [j];
5538 if (allof->mode == rm_allof)
5539 for (k = 0; k < REGEXP_ALLOF (allof)->regexps_num; k++)
5540 {
5541 unit = REGEXP_ALLOF (allof)->regexps [k];
5542 if (unit->mode == rm_unit)
5543 check_unit_distribution_in_reserv (insn_reserv_name, unit,
5544 regexp, j);
5545 else if (unit->mode != rm_nothing)
5546 abort ();
5547 }
5548 else if (allof->mode == rm_unit)
5549 check_unit_distribution_in_reserv (insn_reserv_name, allof,
5550 regexp, j);
5551 else if (allof->mode != rm_nothing)
5552 abort ();
5553 }
5554 else if (seq->mode == rm_allof)
5555 for (k = 0; k < REGEXP_ALLOF (seq)->regexps_num; k++)
5556 {
5557 unit = REGEXP_ALLOF (seq)->regexps [k];
5558 if (unit->mode == rm_unit)
5559 check_unit_distribution_in_reserv (insn_reserv_name, unit,
5560 regexp, 0);
5561 else if (unit->mode != rm_nothing)
5562 abort ();
5563 }
5564 else if (seq->mode == rm_unit)
5565 check_unit_distribution_in_reserv (insn_reserv_name, seq, regexp, 0);
5566 else if (seq->mode != rm_nothing)
5567 abort ();
5568 }
5569 }
5570
5571 /* The function finds units which violates units to automata
5572 distribution rule. If the units exist, report about them. */
5573 static void
5574 check_unit_distributions_to_automata ()
5575 {
5576 decl_t decl;
5577 int i;
5578
5579 fprintf (stderr, "Check unit distributions to automata...");
5580 annotation_message_reported_p = FALSE;
5581 for (i = 0; i < description->decls_num; i++)
5582 {
5583 decl = description->decls [i];
5584 if (decl->mode == dm_insn_reserv)
5585 check_regexp_units_distribution
5586 (DECL_INSN_RESERV (decl)->name,
5587 DECL_INSN_RESERV (decl)->transformed_regexp);
5588 }
5589 fprintf (stderr, "done\n");
5590 }
5591
5592 \f
5593
5594 /* The page contains code for building alt_states (see comments for
5595 IR) describing all possible insns reservations of an automaton. */
5596
5597 /* Current state being formed for which the current alt_state
5598 refers. */
5599 static state_t state_being_formed;
5600
5601 /* Current alt_state being formed. */
5602 static alt_state_t alt_state_being_formed;
5603
5604 /* This recursive function processes `,' and units in reservation
5605 REGEXP for forming alt_states of AUTOMATON. It is believed that
5606 CURR_CYCLE is start cycle of all reservation REGEXP. */
5607 static int
5608 process_seq_for_forming_states (regexp, automaton, curr_cycle)
5609 regexp_t regexp;
5610 automaton_t automaton;
5611 int curr_cycle;
5612 {
5613 int i;
5614
5615 if (regexp == NULL)
5616 return curr_cycle;
5617 else if (regexp->mode == rm_unit)
5618 {
5619 if (REGEXP_UNIT (regexp)->unit_decl->corresponding_automaton_num
5620 == automaton->automaton_order_num)
5621 set_state_reserv (state_being_formed, curr_cycle,
5622 REGEXP_UNIT (regexp)->unit_decl->unit_num);
5623 return curr_cycle;
5624 }
5625 else if (regexp->mode == rm_sequence)
5626 {
5627 for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
5628 curr_cycle
5629 = process_seq_for_forming_states
5630 (REGEXP_SEQUENCE (regexp)->regexps [i], automaton, curr_cycle) + 1;
5631 return curr_cycle;
5632 }
5633 else if (regexp->mode == rm_allof)
5634 {
5635 int finish_cycle = 0;
5636 int cycle;
5637
5638 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
5639 {
5640 cycle = process_seq_for_forming_states (REGEXP_ALLOF (regexp)
5641 ->regexps [i],
5642 automaton, curr_cycle);
5643 if (finish_cycle < cycle)
5644 finish_cycle = cycle;
5645 }
5646 return finish_cycle;
5647 }
5648 else
5649 {
5650 if (regexp->mode != rm_nothing)
5651 abort ();
5652 return curr_cycle;
5653 }
5654 }
5655
5656 /* This recursive function finishes forming ALT_STATE of AUTOMATON and
5657 inserts alt_state into the table. */
5658 static void
5659 finish_forming_alt_state (alt_state, automaton)
5660 alt_state_t alt_state;
5661 automaton_t automaton ATTRIBUTE_UNUSED;
5662 {
5663 state_t state_in_table;
5664 state_t corresponding_state;
5665
5666 corresponding_state = alt_state->state;
5667 state_in_table = insert_state (corresponding_state);
5668 if (state_in_table != corresponding_state)
5669 {
5670 free_state (corresponding_state);
5671 alt_state->state = state_in_table;
5672 }
5673 }
5674
5675 /* The following variable value is current automaton insn for whose
5676 reservation the alt states are created. */
5677 static ainsn_t curr_ainsn;
5678
5679 /* This recursive function processes `|' in reservation REGEXP for
5680 forming alt_states of AUTOMATON. List of the alt states should
5681 have the same order as in the description. */
5682 static void
5683 process_alts_for_forming_states (regexp, automaton, inside_oneof_p)
5684 regexp_t regexp;
5685 automaton_t automaton;
5686 int inside_oneof_p;
5687 {
5688 int i;
5689
5690 if (regexp->mode != rm_oneof)
5691 {
5692 alt_state_being_formed = get_free_alt_state ();
5693 state_being_formed = get_free_state (1, automaton);
5694 alt_state_being_formed->state = state_being_formed;
5695 /* We inserts in reverse order but we process alternatives also
5696 in reverse order. So we have the same order of alternative
5697 as in the description. */
5698 alt_state_being_formed->next_alt_state = curr_ainsn->alt_states;
5699 curr_ainsn->alt_states = alt_state_being_formed;
5700 (void) process_seq_for_forming_states (regexp, automaton, 0);
5701 finish_forming_alt_state (alt_state_being_formed, automaton);
5702 }
5703 else
5704 {
5705 if (inside_oneof_p)
5706 abort ();
5707 /* We processes it in reverse order to get list with the same
5708 order as in the description. See also the previous
5709 commentary. */
5710 for (i = REGEXP_ONEOF (regexp)->regexps_num - 1; i >= 0; i--)
5711 process_alts_for_forming_states (REGEXP_ONEOF (regexp)->regexps [i],
5712 automaton, 1);
5713 }
5714 }
5715
5716 /* Create nodes alt_state for all AUTOMATON insns. */
5717 static void
5718 create_alt_states (automaton)
5719 automaton_t automaton;
5720 {
5721 struct insn_reserv_decl *reserv_decl;
5722
5723 for (curr_ainsn = automaton->ainsn_list;
5724 curr_ainsn != NULL;
5725 curr_ainsn = curr_ainsn->next_ainsn)
5726 {
5727 reserv_decl = curr_ainsn->insn_reserv_decl;
5728 if (reserv_decl != DECL_INSN_RESERV (advance_cycle_insn_decl))
5729 {
5730 curr_ainsn->alt_states = NULL;
5731 process_alts_for_forming_states (reserv_decl->transformed_regexp,
5732 automaton, 0);
5733 curr_ainsn->sorted_alt_states
5734 = uniq_sort_alt_states (curr_ainsn->alt_states);
5735 }
5736 }
5737 }
5738
5739 \f
5740
5741 /* The page contains major code for building DFA(s) for fast pipeline
5742 hazards recognition. */
5743
5744 /* The function forms list of ainsns of AUTOMATON with the same
5745 reservation. */
5746 static void
5747 form_ainsn_with_same_reservs (automaton)
5748 automaton_t automaton;
5749 {
5750 ainsn_t curr_ainsn;
5751 size_t i;
5752 vla_ptr_t first_insns;
5753 vla_ptr_t last_insns;
5754
5755 VLA_PTR_CREATE (first_insns, 150, "first insns with the same reservs");
5756 VLA_PTR_CREATE (last_insns, 150, "last insns with the same reservs");
5757 for (curr_ainsn = automaton->ainsn_list;
5758 curr_ainsn != NULL;
5759 curr_ainsn = curr_ainsn->next_ainsn)
5760 if (curr_ainsn->insn_reserv_decl
5761 == DECL_INSN_RESERV (advance_cycle_insn_decl))
5762 {
5763 curr_ainsn->next_same_reservs_insn = NULL;
5764 curr_ainsn->first_insn_with_same_reservs = 1;
5765 }
5766 else
5767 {
5768 for (i = 0; i < VLA_PTR_LENGTH (first_insns); i++)
5769 if (alt_states_eq
5770 (curr_ainsn->sorted_alt_states,
5771 ((ainsn_t) VLA_PTR (first_insns, i))->sorted_alt_states))
5772 break;
5773 curr_ainsn->next_same_reservs_insn = NULL;
5774 if (i < VLA_PTR_LENGTH (first_insns))
5775 {
5776 curr_ainsn->first_insn_with_same_reservs = 0;
5777 ((ainsn_t) VLA_PTR (last_insns, i))->next_same_reservs_insn
5778 = curr_ainsn;
5779 VLA_PTR (last_insns, i) = curr_ainsn;
5780 }
5781 else
5782 {
5783 VLA_PTR_ADD (first_insns, curr_ainsn);
5784 VLA_PTR_ADD (last_insns, curr_ainsn);
5785 curr_ainsn->first_insn_with_same_reservs = 1;
5786 }
5787 }
5788 VLA_PTR_DELETE (first_insns);
5789 VLA_PTR_DELETE (last_insns);
5790 }
5791
5792 /* Forming unit reservations which can affect creating the automaton
5793 states achieved from a given state. It permits to build smaller
5794 automata in many cases. We would have the same automata after
5795 the minimization without such optimization, but the automaton
5796 right after the building could be huge. So in other words, usage
5797 of reservs_matter means some minimization during building the
5798 automaton. */
5799 static reserv_sets_t
5800 form_reservs_matter (automaton)
5801 automaton_t automaton;
5802 {
5803 int cycle, unit;
5804 reserv_sets_t reservs_matter = alloc_empty_reserv_sets();
5805
5806 for (cycle = 0; cycle < max_cycles_num; cycle++)
5807 for (unit = 0; unit < description->units_num; unit++)
5808 if (units_array [unit]->automaton_decl
5809 == automaton->corresponding_automaton_decl
5810 && (cycle >= units_array [unit]->min_occ_cycle_num
5811 /* We can not remove queried unit from reservations. */
5812 || units_array [unit]->query_p
5813 /* We can not remove units which are used
5814 `exclusion_set', `presence_set',
5815 `final_presence_set', `absence_set', and
5816 `final_absence_set'. */
5817 || units_array [unit]->in_set_p))
5818 set_unit_reserv (reservs_matter, cycle, unit);
5819 return reservs_matter;
5820 }
5821
5822 /* The following function creates all states of nondeterministic (if
5823 NDFA_FLAG has nonzero value) or deterministic AUTOMATON. */
5824 static void
5825 make_automaton (automaton)
5826 automaton_t automaton;
5827 {
5828 ainsn_t ainsn;
5829 struct insn_reserv_decl *insn_reserv_decl;
5830 alt_state_t alt_state;
5831 state_t state;
5832 state_t start_state;
5833 state_t state2;
5834 ainsn_t advance_cycle_ainsn;
5835 arc_t added_arc;
5836 vla_ptr_t state_stack;
5837 int states_n;
5838 reserv_sets_t reservs_matter = form_reservs_matter (automaton);
5839
5840 VLA_PTR_CREATE (state_stack, 150, "state stack");
5841 /* Create the start state (empty state). */
5842 start_state = insert_state (get_free_state (1, automaton));
5843 automaton->start_state = start_state;
5844 start_state->it_was_placed_in_stack_for_NDFA_forming = 1;
5845 VLA_PTR_ADD (state_stack, start_state);
5846 states_n = 1;
5847 while (VLA_PTR_LENGTH (state_stack) != 0)
5848 {
5849 state = VLA_PTR (state_stack, VLA_PTR_LENGTH (state_stack) - 1);
5850 VLA_PTR_SHORTEN (state_stack, 1);
5851 advance_cycle_ainsn = NULL;
5852 for (ainsn = automaton->ainsn_list;
5853 ainsn != NULL;
5854 ainsn = ainsn->next_ainsn)
5855 if (ainsn->first_insn_with_same_reservs)
5856 {
5857 insn_reserv_decl = ainsn->insn_reserv_decl;
5858 if (insn_reserv_decl != DECL_INSN_RESERV (advance_cycle_insn_decl))
5859 {
5860 /* We process alt_states in the same order as they are
5861 present in the description. */
5862 added_arc = NULL;
5863 for (alt_state = ainsn->alt_states;
5864 alt_state != NULL;
5865 alt_state = alt_state->next_alt_state)
5866 {
5867 state2 = alt_state->state;
5868 if (!intersected_state_reservs_p (state, state2))
5869 {
5870 state2 = states_union (state, state2, reservs_matter);
5871 if (!state2->it_was_placed_in_stack_for_NDFA_forming)
5872 {
5873 state2->it_was_placed_in_stack_for_NDFA_forming
5874 = 1;
5875 VLA_PTR_ADD (state_stack, state2);
5876 states_n++;
5877 if (states_n % 100 == 0)
5878 fprintf (stderr, "*");
5879 }
5880 added_arc = add_arc (state, state2, ainsn, 1);
5881 if (!ndfa_flag)
5882 break;
5883 }
5884 }
5885 if (!ndfa_flag && added_arc != NULL)
5886 {
5887 added_arc->state_alts = 0;
5888 for (alt_state = ainsn->alt_states;
5889 alt_state != NULL;
5890 alt_state = alt_state->next_alt_state)
5891 {
5892 state2 = alt_state->state;
5893 if (!intersected_state_reservs_p (state, state2))
5894 added_arc->state_alts++;
5895 }
5896 }
5897 }
5898 else
5899 advance_cycle_ainsn = ainsn;
5900 }
5901 /* Add transition to advance cycle. */
5902 state2 = state_shift (state, reservs_matter);
5903 if (!state2->it_was_placed_in_stack_for_NDFA_forming)
5904 {
5905 state2->it_was_placed_in_stack_for_NDFA_forming = 1;
5906 VLA_PTR_ADD (state_stack, state2);
5907 states_n++;
5908 if (states_n % 100 == 0)
5909 fprintf (stderr, "*");
5910 }
5911 if (advance_cycle_ainsn == NULL)
5912 abort ();
5913 add_arc (state, state2, advance_cycle_ainsn, 1);
5914 }
5915 VLA_PTR_DELETE (state_stack);
5916 }
5917
5918 /* Foms lists of all arcs of STATE marked by the same ainsn. */
5919 static void
5920 form_arcs_marked_by_insn (state)
5921 state_t state;
5922 {
5923 decl_t decl;
5924 arc_t arc;
5925 int i;
5926
5927 for (i = 0; i < description->decls_num; i++)
5928 {
5929 decl = description->decls [i];
5930 if (decl->mode == dm_insn_reserv)
5931 DECL_INSN_RESERV (decl)->arcs_marked_by_insn = NULL;
5932 }
5933 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
5934 {
5935 if (arc->insn == NULL)
5936 abort ();
5937 arc->next_arc_marked_by_insn
5938 = arc->insn->insn_reserv_decl->arcs_marked_by_insn;
5939 arc->insn->insn_reserv_decl->arcs_marked_by_insn = arc;
5940 }
5941 }
5942
5943 /* The function creates composed state (see comments for IR) from
5944 ORIGINAL_STATE and list of arcs ARCS_MARKED_BY_INSN marked by the
5945 same insn. If the composed state is not in STATE_STACK yet, it is
5946 pushed into STATE_STACK. */
5947 static int
5948 create_composed_state (original_state, arcs_marked_by_insn, state_stack)
5949 state_t original_state;
5950 arc_t arcs_marked_by_insn;
5951 vla_ptr_t *state_stack;
5952 {
5953 state_t state;
5954 alt_state_t alt_state, curr_alt_state;
5955 alt_state_t new_alt_state;
5956 arc_t curr_arc;
5957 arc_t next_arc;
5958 state_t state_in_table;
5959 state_t temp_state;
5960 alt_state_t canonical_alt_states_list;
5961 int alts_number;
5962 int new_state_p = 0;
5963
5964 if (arcs_marked_by_insn == NULL)
5965 return new_state_p;
5966 if (arcs_marked_by_insn->next_arc_marked_by_insn == NULL)
5967 state = arcs_marked_by_insn->to_state;
5968 else
5969 {
5970 if (!ndfa_flag)
5971 abort ();
5972 /* Create composed state. */
5973 state = get_free_state (0, arcs_marked_by_insn->to_state->automaton);
5974 curr_alt_state = NULL;
5975 for (curr_arc = arcs_marked_by_insn;
5976 curr_arc != NULL;
5977 curr_arc = curr_arc->next_arc_marked_by_insn)
5978 if (curr_arc->to_state->component_states == NULL)
5979 {
5980 new_alt_state = get_free_alt_state ();
5981 new_alt_state->next_alt_state = curr_alt_state;
5982 new_alt_state->state = curr_arc->to_state;
5983 curr_alt_state = new_alt_state;
5984 }
5985 else
5986 for (alt_state = curr_arc->to_state->component_states;
5987 alt_state != NULL;
5988 alt_state = alt_state->next_sorted_alt_state)
5989 {
5990 new_alt_state = get_free_alt_state ();
5991 new_alt_state->next_alt_state = curr_alt_state;
5992 new_alt_state->state = alt_state->state;
5993 if (alt_state->state->component_states != NULL)
5994 abort ();
5995 curr_alt_state = new_alt_state;
5996 }
5997 /* There are not identical sets in the alt state list. */
5998 canonical_alt_states_list = uniq_sort_alt_states (curr_alt_state);
5999 if (canonical_alt_states_list->next_sorted_alt_state == NULL)
6000 {
6001 temp_state = state;
6002 state = canonical_alt_states_list->state;
6003 free_state (temp_state);
6004 }
6005 else
6006 {
6007 state->component_states = canonical_alt_states_list;
6008 state_in_table = insert_state (state);
6009 if (state_in_table != state)
6010 {
6011 if (!state_in_table->it_was_placed_in_stack_for_DFA_forming)
6012 abort ();
6013 free_state (state);
6014 state = state_in_table;
6015 }
6016 else
6017 {
6018 if (state->it_was_placed_in_stack_for_DFA_forming)
6019 abort ();
6020 new_state_p = 1;
6021 for (curr_alt_state = state->component_states;
6022 curr_alt_state != NULL;
6023 curr_alt_state = curr_alt_state->next_sorted_alt_state)
6024 for (curr_arc = first_out_arc (curr_alt_state->state);
6025 curr_arc != NULL;
6026 curr_arc = next_out_arc (curr_arc))
6027 add_arc (state, curr_arc->to_state, curr_arc->insn, 1);
6028 }
6029 arcs_marked_by_insn->to_state = state;
6030 for (alts_number = 0,
6031 curr_arc = arcs_marked_by_insn->next_arc_marked_by_insn;
6032 curr_arc != NULL;
6033 curr_arc = next_arc)
6034 {
6035 next_arc = curr_arc->next_arc_marked_by_insn;
6036 remove_arc (original_state, curr_arc);
6037 alts_number++;
6038 }
6039 arcs_marked_by_insn->state_alts = alts_number;
6040 }
6041 }
6042 if (!state->it_was_placed_in_stack_for_DFA_forming)
6043 {
6044 state->it_was_placed_in_stack_for_DFA_forming = 1;
6045 VLA_PTR_ADD (*state_stack, state);
6046 }
6047 return new_state_p;
6048 }
6049
6050 /* The function transforms nondeterministic AUTOMATON into
6051 deterministic. */
6052 static void
6053 NDFA_to_DFA (automaton)
6054 automaton_t automaton;
6055 {
6056 state_t start_state;
6057 state_t state;
6058 decl_t decl;
6059 vla_ptr_t state_stack;
6060 int i;
6061 int states_n;
6062
6063 VLA_PTR_CREATE (state_stack, 150, "state stack");
6064 /* Create the start state (empty state). */
6065 start_state = automaton->start_state;
6066 start_state->it_was_placed_in_stack_for_DFA_forming = 1;
6067 VLA_PTR_ADD (state_stack, start_state);
6068 states_n = 1;
6069 while (VLA_PTR_LENGTH (state_stack) != 0)
6070 {
6071 state = VLA_PTR (state_stack, VLA_PTR_LENGTH (state_stack) - 1);
6072 VLA_PTR_SHORTEN (state_stack, 1);
6073 form_arcs_marked_by_insn (state);
6074 for (i = 0; i < description->decls_num; i++)
6075 {
6076 decl = description->decls [i];
6077 if (decl->mode == dm_insn_reserv
6078 && create_composed_state
6079 (state, DECL_INSN_RESERV (decl)->arcs_marked_by_insn,
6080 &state_stack))
6081 {
6082 states_n++;
6083 if (states_n % 100 == 0)
6084 fprintf (stderr, "*");
6085 }
6086 }
6087 }
6088 VLA_PTR_DELETE (state_stack);
6089 }
6090
6091 /* The following variable value is current number (1, 2, ...) of passing
6092 graph of states. */
6093 static int curr_state_graph_pass_num;
6094
6095 /* This recursive function passes all states achieved from START_STATE
6096 and applies APPLIED_FUNC to them. */
6097 static void
6098 pass_state_graph (start_state, applied_func)
6099 state_t start_state;
6100 void (*applied_func) PARAMS ((state_t state));
6101 {
6102 arc_t arc;
6103
6104 if (start_state->pass_num == curr_state_graph_pass_num)
6105 return;
6106 start_state->pass_num = curr_state_graph_pass_num;
6107 (*applied_func) (start_state);
6108 for (arc = first_out_arc (start_state);
6109 arc != NULL;
6110 arc = next_out_arc (arc))
6111 pass_state_graph (arc->to_state, applied_func);
6112 }
6113
6114 /* This recursive function passes all states of AUTOMATON and applies
6115 APPLIED_FUNC to them. */
6116 static void
6117 pass_states (automaton, applied_func)
6118 automaton_t automaton;
6119 void (*applied_func) PARAMS ((state_t state));
6120 {
6121 curr_state_graph_pass_num++;
6122 pass_state_graph (automaton->start_state, applied_func);
6123 }
6124
6125 /* The function initializes code for passing of all states. */
6126 static void
6127 initiate_pass_states ()
6128 {
6129 curr_state_graph_pass_num = 0;
6130 }
6131
6132 /* The following vla is used for storing pointers to all achieved
6133 states. */
6134 static vla_ptr_t all_achieved_states;
6135
6136 /* This function is called by function pass_states to add an achieved
6137 STATE. */
6138 static void
6139 add_achieved_state (state)
6140 state_t state;
6141 {
6142 VLA_PTR_ADD (all_achieved_states, state);
6143 }
6144
6145 /* The function sets up equivalence numbers of insns which mark all
6146 out arcs of STATE by equiv_class_num_1 (if ODD_ITERATION_FLAG has
6147 nonzero value) or by equiv_class_num_2 of the destination state.
6148 The function returns number of out arcs of STATE. */
6149 static int
6150 set_out_arc_insns_equiv_num (state, odd_iteration_flag)
6151 state_t state;
6152 int odd_iteration_flag;
6153 {
6154 int state_out_arcs_num;
6155 arc_t arc;
6156
6157 state_out_arcs_num = 0;
6158 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6159 {
6160 if (arc->insn->insn_reserv_decl->equiv_class_num != 0
6161 || arc->insn->insn_reserv_decl->state_alts != 0)
6162 abort ();
6163 state_out_arcs_num++;
6164 arc->insn->insn_reserv_decl->equiv_class_num
6165 = (odd_iteration_flag
6166 ? arc->to_state->equiv_class_num_1
6167 : arc->to_state->equiv_class_num_2);
6168 arc->insn->insn_reserv_decl->state_alts = arc->state_alts;
6169 if (arc->insn->insn_reserv_decl->equiv_class_num == 0
6170 || arc->insn->insn_reserv_decl->state_alts <= 0)
6171 abort ();
6172 }
6173 return state_out_arcs_num;
6174 }
6175
6176 /* The function clears equivalence numbers and alt_states in all insns
6177 which mark all out arcs of STATE. */
6178 static void
6179 clear_arc_insns_equiv_num (state)
6180 state_t state;
6181 {
6182 arc_t arc;
6183
6184 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6185 {
6186 arc->insn->insn_reserv_decl->equiv_class_num = 0;
6187 arc->insn->insn_reserv_decl->state_alts = 0;
6188 }
6189 }
6190
6191 /* The function copies pointers to equivalent states from vla FROM
6192 into vla TO. */
6193 static void
6194 copy_equiv_class (to, from)
6195 vla_ptr_t *to;
6196 const vla_ptr_t *from;
6197 {
6198 state_t *class_ptr;
6199
6200 VLA_PTR_NULLIFY (*to);
6201 for (class_ptr = VLA_PTR_BEGIN (*from);
6202 class_ptr <= (state_t *) VLA_PTR_LAST (*from);
6203 class_ptr++)
6204 VLA_PTR_ADD (*to, *class_ptr);
6205 }
6206
6207 /* The following function returns TRUE if STATE reserves the unit with
6208 UNIT_NUM on the first cycle. */
6209 static int
6210 first_cycle_unit_presence (state, unit_num)
6211 state_t state;
6212 int unit_num;
6213 {
6214 int presence_p;
6215
6216 if (state->component_states == NULL)
6217 presence_p = test_unit_reserv (state->reservs, 0, unit_num);
6218 else
6219 presence_p
6220 = test_unit_reserv (state->component_states->state->reservs,
6221 0, unit_num);
6222 return presence_p;
6223 }
6224
6225 /* The function returns nonzero value if STATE is not equivalent to
6226 ANOTHER_STATE from the same current partition on equivalence
6227 classes. Another state has ANOTHER_STATE_OUT_ARCS_NUM number of
6228 output arcs. Iteration of making equivalence partition is defined
6229 by ODD_ITERATION_FLAG. */
6230 static int
6231 state_is_differed (state, another_state, another_state_out_arcs_num,
6232 odd_iteration_flag)
6233 state_t state, another_state;
6234 int another_state_out_arcs_num;
6235 int odd_iteration_flag;
6236 {
6237 arc_t arc;
6238 int state_out_arcs_num;
6239 int i, presence1_p, presence2_p;
6240
6241 state_out_arcs_num = 0;
6242 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6243 {
6244 state_out_arcs_num++;
6245 if ((odd_iteration_flag
6246 ? arc->to_state->equiv_class_num_1
6247 : arc->to_state->equiv_class_num_2)
6248 != arc->insn->insn_reserv_decl->equiv_class_num
6249 || (arc->insn->insn_reserv_decl->state_alts != arc->state_alts))
6250 return 1;
6251 }
6252 if (state_out_arcs_num != another_state_out_arcs_num)
6253 return 1;
6254 /* Now we are looking at the states with the point of view of query
6255 units. */
6256 for (i = 0; i < description->units_num; i++)
6257 if (units_array [i]->query_p)
6258 {
6259 presence1_p = first_cycle_unit_presence (state, i);
6260 presence2_p = first_cycle_unit_presence (another_state, i);
6261 if ((presence1_p && !presence2_p) || (!presence1_p && presence2_p))
6262 return 1;
6263 }
6264 return 0;
6265 }
6266
6267 /* The function makes initial partition of STATES on equivalent
6268 classes. */
6269 static state_t
6270 init_equiv_class (states, states_num)
6271 state_t *states;
6272 int states_num;
6273 {
6274 state_t *state_ptr;
6275 state_t result_equiv_class;
6276
6277 result_equiv_class = NULL;
6278 for (state_ptr = states; state_ptr < states + states_num; state_ptr++)
6279 {
6280 (*state_ptr)->equiv_class_num_1 = 1;
6281 (*state_ptr)->next_equiv_class_state = result_equiv_class;
6282 result_equiv_class = *state_ptr;
6283 }
6284 return result_equiv_class;
6285 }
6286
6287 /* The function processes equivalence class given by its pointer
6288 EQUIV_CLASS_PTR on odd iteration if ODD_ITERATION_FLAG. If there
6289 are not equivalent states, the function partitions the class
6290 removing nonequivalent states and placing them in
6291 *NEXT_ITERATION_CLASSES, increments *NEW_EQUIV_CLASS_NUM_PTR ans
6292 assigns it to the state equivalence number. If the class has been
6293 partitioned, the function returns nonzero value. */
6294 static int
6295 partition_equiv_class (equiv_class_ptr, odd_iteration_flag,
6296 next_iteration_classes, new_equiv_class_num_ptr)
6297 state_t *equiv_class_ptr;
6298 int odd_iteration_flag;
6299 vla_ptr_t *next_iteration_classes;
6300 int *new_equiv_class_num_ptr;
6301 {
6302 state_t new_equiv_class;
6303 int partition_p;
6304 state_t first_state;
6305 state_t curr_state;
6306 state_t prev_state;
6307 state_t next_state;
6308 int out_arcs_num;
6309
6310 partition_p = 0;
6311 if (*equiv_class_ptr == NULL)
6312 abort ();
6313 for (first_state = *equiv_class_ptr;
6314 first_state != NULL;
6315 first_state = new_equiv_class)
6316 {
6317 new_equiv_class = NULL;
6318 if (first_state->next_equiv_class_state != NULL)
6319 {
6320 /* There are more one states in the class equivalence. */
6321 out_arcs_num = set_out_arc_insns_equiv_num (first_state,
6322 odd_iteration_flag);
6323 for (prev_state = first_state,
6324 curr_state = first_state->next_equiv_class_state;
6325 curr_state != NULL;
6326 curr_state = next_state)
6327 {
6328 next_state = curr_state->next_equiv_class_state;
6329 if (state_is_differed (curr_state, first_state, out_arcs_num,
6330 odd_iteration_flag))
6331 {
6332 /* Remove curr state from the class equivalence. */
6333 prev_state->next_equiv_class_state = next_state;
6334 /* Add curr state to the new class equivalence. */
6335 curr_state->next_equiv_class_state = new_equiv_class;
6336 if (new_equiv_class == NULL)
6337 (*new_equiv_class_num_ptr)++;
6338 if (odd_iteration_flag)
6339 curr_state->equiv_class_num_2 = *new_equiv_class_num_ptr;
6340 else
6341 curr_state->equiv_class_num_1 = *new_equiv_class_num_ptr;
6342 new_equiv_class = curr_state;
6343 partition_p = 1;
6344 }
6345 else
6346 prev_state = curr_state;
6347 }
6348 clear_arc_insns_equiv_num (first_state);
6349 }
6350 if (new_equiv_class != NULL)
6351 VLA_PTR_ADD (*next_iteration_classes, new_equiv_class);
6352 }
6353 return partition_p;
6354 }
6355
6356 /* The function finds equivalent states of AUTOMATON. */
6357 static void
6358 evaluate_equiv_classes (automaton, equiv_classes)
6359 automaton_t automaton;
6360 vla_ptr_t *equiv_classes;
6361 {
6362 state_t new_equiv_class;
6363 int new_equiv_class_num;
6364 int odd_iteration_flag;
6365 int finish_flag;
6366 vla_ptr_t next_iteration_classes;
6367 state_t *equiv_class_ptr;
6368 state_t *state_ptr;
6369
6370 VLA_PTR_CREATE (all_achieved_states, 1500, "all achieved states");
6371 pass_states (automaton, add_achieved_state);
6372 new_equiv_class = init_equiv_class (VLA_PTR_BEGIN (all_achieved_states),
6373 VLA_PTR_LENGTH (all_achieved_states));
6374 odd_iteration_flag = 0;
6375 new_equiv_class_num = 1;
6376 VLA_PTR_CREATE (next_iteration_classes, 150, "next iteration classes");
6377 VLA_PTR_ADD (next_iteration_classes, new_equiv_class);
6378 do
6379 {
6380 odd_iteration_flag = !odd_iteration_flag;
6381 finish_flag = 1;
6382 copy_equiv_class (equiv_classes, &next_iteration_classes);
6383 /* Transfer equiv numbers for the next iteration. */
6384 for (state_ptr = VLA_PTR_BEGIN (all_achieved_states);
6385 state_ptr <= (state_t *) VLA_PTR_LAST (all_achieved_states);
6386 state_ptr++)
6387 if (odd_iteration_flag)
6388 (*state_ptr)->equiv_class_num_2 = (*state_ptr)->equiv_class_num_1;
6389 else
6390 (*state_ptr)->equiv_class_num_1 = (*state_ptr)->equiv_class_num_2;
6391 for (equiv_class_ptr = VLA_PTR_BEGIN (*equiv_classes);
6392 equiv_class_ptr <= (state_t *) VLA_PTR_LAST (*equiv_classes);
6393 equiv_class_ptr++)
6394 if (partition_equiv_class (equiv_class_ptr, odd_iteration_flag,
6395 &next_iteration_classes,
6396 &new_equiv_class_num))
6397 finish_flag = 0;
6398 }
6399 while (!finish_flag);
6400 VLA_PTR_DELETE (next_iteration_classes);
6401 VLA_PTR_DELETE (all_achieved_states);
6402 }
6403
6404 /* The function merges equivalent states of AUTOMATON. */
6405 static void
6406 merge_states (automaton, equiv_classes)
6407 automaton_t automaton;
6408 vla_ptr_t *equiv_classes;
6409 {
6410 state_t *equiv_class_ptr;
6411 state_t curr_state;
6412 state_t new_state;
6413 state_t first_class_state;
6414 alt_state_t alt_states;
6415 alt_state_t alt_state, new_alt_state;
6416 arc_t curr_arc;
6417 arc_t next_arc;
6418
6419 /* Create states corresponding to equivalence classes containing two
6420 or more states. */
6421 for (equiv_class_ptr = VLA_PTR_BEGIN (*equiv_classes);
6422 equiv_class_ptr <= (state_t *) VLA_PTR_LAST (*equiv_classes);
6423 equiv_class_ptr++)
6424 if ((*equiv_class_ptr)->next_equiv_class_state != NULL)
6425 {
6426 /* There are more one states in the class equivalence. */
6427 /* Create new compound state. */
6428 new_state = get_free_state (0, automaton);
6429 alt_states = NULL;
6430 first_class_state = *equiv_class_ptr;
6431 for (curr_state = first_class_state;
6432 curr_state != NULL;
6433 curr_state = curr_state->next_equiv_class_state)
6434 {
6435 curr_state->equiv_class_state = new_state;
6436 if (curr_state->component_states == NULL)
6437 {
6438 new_alt_state = get_free_alt_state ();
6439 new_alt_state->state = curr_state;
6440 new_alt_state->next_alt_state = alt_states;
6441 alt_states = new_alt_state;
6442 }
6443 else
6444 for (alt_state = curr_state->component_states;
6445 alt_state != NULL;
6446 alt_state = alt_state->next_sorted_alt_state)
6447 {
6448 new_alt_state = get_free_alt_state ();
6449 new_alt_state->state = alt_state->state;
6450 new_alt_state->next_alt_state = alt_states;
6451 alt_states = new_alt_state;
6452 }
6453 }
6454 /* Its is important that alt states were sorted before and
6455 after merging to have the same quering results. */
6456 new_state->component_states = uniq_sort_alt_states (alt_states);
6457 }
6458 else
6459 (*equiv_class_ptr)->equiv_class_state = *equiv_class_ptr;
6460 for (equiv_class_ptr = VLA_PTR_BEGIN (*equiv_classes);
6461 equiv_class_ptr <= (state_t *) VLA_PTR_LAST (*equiv_classes);
6462 equiv_class_ptr++)
6463 if ((*equiv_class_ptr)->next_equiv_class_state != NULL)
6464 {
6465 first_class_state = *equiv_class_ptr;
6466 /* Create new arcs output from the state corresponding to
6467 equiv class. */
6468 for (curr_arc = first_out_arc (first_class_state);
6469 curr_arc != NULL;
6470 curr_arc = next_out_arc (curr_arc))
6471 add_arc (first_class_state->equiv_class_state,
6472 curr_arc->to_state->equiv_class_state,
6473 curr_arc->insn, curr_arc->state_alts);
6474 /* Delete output arcs from states of given class equivalence. */
6475 for (curr_state = first_class_state;
6476 curr_state != NULL;
6477 curr_state = curr_state->next_equiv_class_state)
6478 {
6479 if (automaton->start_state == curr_state)
6480 automaton->start_state = curr_state->equiv_class_state;
6481 /* Delete the state and its output arcs. */
6482 for (curr_arc = first_out_arc (curr_state);
6483 curr_arc != NULL;
6484 curr_arc = next_arc)
6485 {
6486 next_arc = next_out_arc (curr_arc);
6487 free_arc (curr_arc);
6488 }
6489 }
6490 }
6491 else
6492 {
6493 /* Change `to_state' of arcs output from the state of given
6494 equivalence class. */
6495 for (curr_arc = first_out_arc (*equiv_class_ptr);
6496 curr_arc != NULL;
6497 curr_arc = next_out_arc (curr_arc))
6498 curr_arc->to_state = curr_arc->to_state->equiv_class_state;
6499 }
6500 }
6501
6502 /* The function sets up new_cycle_p for states if there is arc to the
6503 state marked by advance_cycle_insn_decl. */
6504 static void
6505 set_new_cycle_flags (state)
6506 state_t state;
6507 {
6508 arc_t arc;
6509
6510 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6511 if (arc->insn->insn_reserv_decl
6512 == DECL_INSN_RESERV (advance_cycle_insn_decl))
6513 arc->to_state->new_cycle_p = 1;
6514 }
6515
6516 /* The top level function for minimization of deterministic
6517 AUTOMATON. */
6518 static void
6519 minimize_DFA (automaton)
6520 automaton_t automaton;
6521 {
6522 vla_ptr_t equiv_classes;
6523
6524 VLA_PTR_CREATE (equiv_classes, 1500, "equivalence classes");
6525 evaluate_equiv_classes (automaton, &equiv_classes);
6526 merge_states (automaton, &equiv_classes);
6527 pass_states (automaton, set_new_cycle_flags);
6528 VLA_PTR_DELETE (equiv_classes);
6529 }
6530
6531 /* Values of two variables are counted number of states and arcs in an
6532 automaton. */
6533 static int curr_counted_states_num;
6534 static int curr_counted_arcs_num;
6535
6536 /* The function is called by function `pass_states' to count states
6537 and arcs of an automaton. */
6538 static void
6539 incr_states_and_arcs_nums (state)
6540 state_t state;
6541 {
6542 arc_t arc;
6543
6544 curr_counted_states_num++;
6545 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6546 curr_counted_arcs_num++;
6547 }
6548
6549 /* The function counts states and arcs of AUTOMATON. */
6550 static void
6551 count_states_and_arcs (automaton, states_num, arcs_num)
6552 automaton_t automaton;
6553 int *states_num;
6554 int *arcs_num;
6555 {
6556 curr_counted_states_num = 0;
6557 curr_counted_arcs_num = 0;
6558 pass_states (automaton, incr_states_and_arcs_nums);
6559 *states_num = curr_counted_states_num;
6560 *arcs_num = curr_counted_arcs_num;
6561 }
6562
6563 /* The function builds one DFA AUTOMATON for fast pipeline hazards
6564 recognition after checking and simplifying IR of the
6565 description. */
6566 static void
6567 build_automaton (automaton)
6568 automaton_t automaton;
6569 {
6570 int states_num;
6571 int arcs_num;
6572
6573 ticker_on (&NDFA_time);
6574 if (automaton->corresponding_automaton_decl == NULL)
6575 fprintf (stderr, "Create anonymous automaton (1 star is 100 new states):");
6576 else
6577 fprintf (stderr, "Create automaton `%s' (1 star is 100 new states):",
6578 automaton->corresponding_automaton_decl->name);
6579 make_automaton (automaton);
6580 fprintf (stderr, " done\n");
6581 ticker_off (&NDFA_time);
6582 count_states_and_arcs (automaton, &states_num, &arcs_num);
6583 automaton->NDFA_states_num = states_num;
6584 automaton->NDFA_arcs_num = arcs_num;
6585 ticker_on (&NDFA_to_DFA_time);
6586 if (automaton->corresponding_automaton_decl == NULL)
6587 fprintf (stderr, "Make anonymous DFA (1 star is 100 new states):");
6588 else
6589 fprintf (stderr, "Make DFA `%s' (1 star is 100 new states):",
6590 automaton->corresponding_automaton_decl->name);
6591 NDFA_to_DFA (automaton);
6592 fprintf (stderr, " done\n");
6593 ticker_off (&NDFA_to_DFA_time);
6594 count_states_and_arcs (automaton, &states_num, &arcs_num);
6595 automaton->DFA_states_num = states_num;
6596 automaton->DFA_arcs_num = arcs_num;
6597 if (!no_minimization_flag)
6598 {
6599 ticker_on (&minimize_time);
6600 if (automaton->corresponding_automaton_decl == NULL)
6601 fprintf (stderr, "Minimize anonymous DFA...");
6602 else
6603 fprintf (stderr, "Minimize DFA `%s'...",
6604 automaton->corresponding_automaton_decl->name);
6605 minimize_DFA (automaton);
6606 fprintf (stderr, "done\n");
6607 ticker_off (&minimize_time);
6608 count_states_and_arcs (automaton, &states_num, &arcs_num);
6609 automaton->minimal_DFA_states_num = states_num;
6610 automaton->minimal_DFA_arcs_num = arcs_num;
6611 }
6612 }
6613
6614 \f
6615
6616 /* The page contains code for enumeration of all states of an automaton. */
6617
6618 /* Variable used for enumeration of all states of an automaton. Its
6619 value is current number of automaton states. */
6620 static int curr_state_order_num;
6621
6622 /* The function is called by function `pass_states' for enumerating
6623 states. */
6624 static void
6625 set_order_state_num (state)
6626 state_t state;
6627 {
6628 state->order_state_num = curr_state_order_num;
6629 curr_state_order_num++;
6630 }
6631
6632 /* The function enumerates all states of AUTOMATON. */
6633 static void
6634 enumerate_states (automaton)
6635 automaton_t automaton;
6636 {
6637 curr_state_order_num = 0;
6638 pass_states (automaton, set_order_state_num);
6639 automaton->achieved_states_num = curr_state_order_num;
6640 }
6641
6642 \f
6643
6644 /* The page contains code for finding equivalent automaton insns
6645 (ainsns). */
6646
6647 /* The function inserts AINSN into cyclic list
6648 CYCLIC_EQUIV_CLASS_INSN_LIST of ainsns. */
6649 static ainsn_t
6650 insert_ainsn_into_equiv_class (ainsn, cyclic_equiv_class_insn_list)
6651 ainsn_t ainsn;
6652 ainsn_t cyclic_equiv_class_insn_list;
6653 {
6654 if (cyclic_equiv_class_insn_list == NULL)
6655 ainsn->next_equiv_class_insn = ainsn;
6656 else
6657 {
6658 ainsn->next_equiv_class_insn
6659 = cyclic_equiv_class_insn_list->next_equiv_class_insn;
6660 cyclic_equiv_class_insn_list->next_equiv_class_insn = ainsn;
6661 }
6662 return ainsn;
6663 }
6664
6665 /* The function deletes equiv_class_insn into cyclic list of
6666 equivalent ainsns. */
6667 static void
6668 delete_ainsn_from_equiv_class (equiv_class_insn)
6669 ainsn_t equiv_class_insn;
6670 {
6671 ainsn_t curr_equiv_class_insn;
6672 ainsn_t prev_equiv_class_insn;
6673
6674 prev_equiv_class_insn = equiv_class_insn;
6675 for (curr_equiv_class_insn = equiv_class_insn->next_equiv_class_insn;
6676 curr_equiv_class_insn != equiv_class_insn;
6677 curr_equiv_class_insn = curr_equiv_class_insn->next_equiv_class_insn)
6678 prev_equiv_class_insn = curr_equiv_class_insn;
6679 if (prev_equiv_class_insn != equiv_class_insn)
6680 prev_equiv_class_insn->next_equiv_class_insn
6681 = equiv_class_insn->next_equiv_class_insn;
6682 }
6683
6684 /* The function processes AINSN of a state in order to find equivalent
6685 ainsns. INSN_ARCS_ARRAY is table: code of insn -> out arc of the
6686 state. */
6687 static void
6688 process_insn_equiv_class (ainsn, insn_arcs_array)
6689 ainsn_t ainsn;
6690 arc_t *insn_arcs_array;
6691 {
6692 ainsn_t next_insn;
6693 ainsn_t curr_insn;
6694 ainsn_t cyclic_insn_list;
6695 arc_t arc;
6696
6697 if (insn_arcs_array [ainsn->insn_reserv_decl->insn_num] == NULL)
6698 abort ();
6699 curr_insn = ainsn;
6700 /* New class of ainsns which are not equivalent to given ainsn. */
6701 cyclic_insn_list = NULL;
6702 do
6703 {
6704 next_insn = curr_insn->next_equiv_class_insn;
6705 arc = insn_arcs_array [curr_insn->insn_reserv_decl->insn_num];
6706 if (arc == NULL
6707 || (insn_arcs_array [ainsn->insn_reserv_decl->insn_num]->to_state
6708 != arc->to_state))
6709 {
6710 delete_ainsn_from_equiv_class (curr_insn);
6711 cyclic_insn_list = insert_ainsn_into_equiv_class (curr_insn,
6712 cyclic_insn_list);
6713 }
6714 curr_insn = next_insn;
6715 }
6716 while (curr_insn != ainsn);
6717 }
6718
6719 /* The function processes STATE in order to find equivalent ainsns. */
6720 static void
6721 process_state_for_insn_equiv_partition (state)
6722 state_t state;
6723 {
6724 arc_t arc;
6725 arc_t *insn_arcs_array;
6726 int i;
6727 vla_ptr_t insn_arcs_vect;
6728
6729 VLA_PTR_CREATE (insn_arcs_vect, 500, "insn arcs vector");
6730 VLA_PTR_EXPAND (insn_arcs_vect, description->insns_num);
6731 insn_arcs_array = VLA_PTR_BEGIN (insn_arcs_vect);
6732 /* Process insns of the arcs. */
6733 for (i = 0; i < description->insns_num; i++)
6734 insn_arcs_array [i] = NULL;
6735 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6736 insn_arcs_array [arc->insn->insn_reserv_decl->insn_num] = arc;
6737 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
6738 process_insn_equiv_class (arc->insn, insn_arcs_array);
6739 VLA_PTR_DELETE (insn_arcs_vect);
6740 }
6741
6742 /* The function searches for equivalent ainsns of AUTOMATON. */
6743 static void
6744 set_insn_equiv_classes (automaton)
6745 automaton_t automaton;
6746 {
6747 ainsn_t ainsn;
6748 ainsn_t first_insn;
6749 ainsn_t curr_insn;
6750 ainsn_t cyclic_insn_list;
6751 ainsn_t insn_with_same_reservs;
6752 int equiv_classes_num;
6753
6754 /* All insns are included in one equivalence class. */
6755 cyclic_insn_list = NULL;
6756 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
6757 if (ainsn->first_insn_with_same_reservs)
6758 cyclic_insn_list = insert_ainsn_into_equiv_class (ainsn,
6759 cyclic_insn_list);
6760 /* Process insns in order to make equivalence partition. */
6761 pass_states (automaton, process_state_for_insn_equiv_partition);
6762 /* Enumerate equiv classes. */
6763 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
6764 /* Set undefined value. */
6765 ainsn->insn_equiv_class_num = -1;
6766 equiv_classes_num = 0;
6767 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
6768 if (ainsn->insn_equiv_class_num < 0)
6769 {
6770 first_insn = ainsn;
6771 if (!first_insn->first_insn_with_same_reservs)
6772 abort ();
6773 first_insn->first_ainsn_with_given_equialence_num = 1;
6774 curr_insn = first_insn;
6775 do
6776 {
6777 for (insn_with_same_reservs = curr_insn;
6778 insn_with_same_reservs != NULL;
6779 insn_with_same_reservs
6780 = insn_with_same_reservs->next_same_reservs_insn)
6781 insn_with_same_reservs->insn_equiv_class_num = equiv_classes_num;
6782 curr_insn = curr_insn->next_equiv_class_insn;
6783 }
6784 while (curr_insn != first_insn);
6785 equiv_classes_num++;
6786 }
6787 automaton->insn_equiv_classes_num = equiv_classes_num;
6788 }
6789
6790 \f
6791
6792 /* This page contains code for creating DFA(s) and calls functions
6793 building them. */
6794
6795
6796 /* The following value is used to prevent floating point overflow for
6797 estimating an automaton bound. The value should be less DBL_MAX on
6798 the host machine. We use here approximate minimum of maximal
6799 double floating point value required by ANSI C standard. It
6800 will work for non ANSI sun compiler too. */
6801
6802 #define MAX_FLOATING_POINT_VALUE_FOR_AUTOMATON_BOUND 1.0E37
6803
6804 /* The function estimate size of the single DFA used by PHR (pipeline
6805 hazards recognizer). */
6806 static double
6807 estimate_one_automaton_bound ()
6808 {
6809 decl_t decl;
6810 double one_automaton_estimation_bound;
6811 double root_value;
6812 int i;
6813
6814 one_automaton_estimation_bound = 1.0;
6815 for (i = 0; i < description->decls_num; i++)
6816 {
6817 decl = description->decls [i];
6818 if (decl->mode == dm_unit)
6819 {
6820 root_value = exp (log (DECL_UNIT (decl)->max_occ_cycle_num
6821 - DECL_UNIT (decl)->min_occ_cycle_num + 1.0)
6822 / automata_num);
6823 if (MAX_FLOATING_POINT_VALUE_FOR_AUTOMATON_BOUND / root_value
6824 > one_automaton_estimation_bound)
6825 one_automaton_estimation_bound *= root_value;
6826 }
6827 }
6828 return one_automaton_estimation_bound;
6829 }
6830
6831 /* The function compares unit declarations according to their maximal
6832 cycle in reservations. */
6833 static int
6834 compare_max_occ_cycle_nums (unit_decl_1, unit_decl_2)
6835 const void *unit_decl_1;
6836 const void *unit_decl_2;
6837 {
6838 if ((DECL_UNIT (*(decl_t *) unit_decl_1)->max_occ_cycle_num)
6839 < (DECL_UNIT (*(decl_t *) unit_decl_2)->max_occ_cycle_num))
6840 return 1;
6841 else if ((DECL_UNIT (*(decl_t *) unit_decl_1)->max_occ_cycle_num)
6842 == (DECL_UNIT (*(decl_t *) unit_decl_2)->max_occ_cycle_num))
6843 return 0;
6844 else
6845 return -1;
6846 }
6847
6848 /* The function makes heuristic assigning automata to units. Actually
6849 efficacy of the algorithm has been checked yet??? */
6850 static void
6851 units_to_automata_heuristic_distr ()
6852 {
6853 double estimation_bound;
6854 decl_t decl;
6855 decl_t *unit_decl_ptr;
6856 int automaton_num;
6857 int rest_units_num;
6858 double bound_value;
6859 vla_ptr_t unit_decls;
6860 int i;
6861
6862 if (description->units_num == 0)
6863 return;
6864 estimation_bound = estimate_one_automaton_bound ();
6865 VLA_PTR_CREATE (unit_decls, 150, "unit decls");
6866 for (i = 0; i < description->decls_num; i++)
6867 {
6868 decl = description->decls [i];
6869 if (decl->mode == dm_unit)
6870 VLA_PTR_ADD (unit_decls, decl);
6871 }
6872 qsort (VLA_PTR_BEGIN (unit_decls), VLA_PTR_LENGTH (unit_decls),
6873 sizeof (decl_t), compare_max_occ_cycle_nums);
6874 automaton_num = 0;
6875 unit_decl_ptr = VLA_PTR_BEGIN (unit_decls);
6876 bound_value = DECL_UNIT (*unit_decl_ptr)->max_occ_cycle_num;
6877 DECL_UNIT (*unit_decl_ptr)->corresponding_automaton_num = automaton_num;
6878 for (unit_decl_ptr++;
6879 unit_decl_ptr <= (decl_t *) VLA_PTR_LAST (unit_decls);
6880 unit_decl_ptr++)
6881 {
6882 rest_units_num
6883 = ((decl_t *) VLA_PTR_LAST (unit_decls) - unit_decl_ptr + 1);
6884 if (automata_num - automaton_num - 1 > rest_units_num)
6885 abort ();
6886 if (automaton_num < automata_num - 1
6887 && ((automata_num - automaton_num - 1 == rest_units_num)
6888 || (bound_value
6889 > (estimation_bound
6890 / (DECL_UNIT (*unit_decl_ptr)->max_occ_cycle_num)))))
6891 {
6892 bound_value = DECL_UNIT (*unit_decl_ptr)->max_occ_cycle_num;
6893 automaton_num++;
6894 }
6895 else
6896 bound_value *= DECL_UNIT (*unit_decl_ptr)->max_occ_cycle_num;
6897 DECL_UNIT (*unit_decl_ptr)->corresponding_automaton_num = automaton_num;
6898 }
6899 if (automaton_num != automata_num - 1)
6900 abort ();
6901 VLA_PTR_DELETE (unit_decls);
6902 }
6903
6904 /* The functions creates automaton insns for each automata. Automaton
6905 insn is simply insn for given automaton which makes reservation
6906 only of units of the automaton. */
6907 static ainsn_t
6908 create_ainsns ()
6909 {
6910 decl_t decl;
6911 ainsn_t first_ainsn;
6912 ainsn_t curr_ainsn;
6913 ainsn_t prev_ainsn;
6914 int i;
6915
6916 first_ainsn = NULL;
6917 prev_ainsn = NULL;
6918 for (i = 0; i < description->decls_num; i++)
6919 {
6920 decl = description->decls [i];
6921 if (decl->mode == dm_insn_reserv)
6922 {
6923 curr_ainsn = create_node (sizeof (struct ainsn));
6924 curr_ainsn->insn_reserv_decl = DECL_INSN_RESERV (decl);
6925 curr_ainsn->important_p = FALSE;
6926 curr_ainsn->next_ainsn = NULL;
6927 if (prev_ainsn == NULL)
6928 first_ainsn = curr_ainsn;
6929 else
6930 prev_ainsn->next_ainsn = curr_ainsn;
6931 prev_ainsn = curr_ainsn;
6932 }
6933 }
6934 return first_ainsn;
6935 }
6936
6937 /* The function assigns automata to units according to constructions
6938 `define_automaton' in the description. */
6939 static void
6940 units_to_automata_distr ()
6941 {
6942 decl_t decl;
6943 int i;
6944
6945 for (i = 0; i < description->decls_num; i++)
6946 {
6947 decl = description->decls [i];
6948 if (decl->mode == dm_unit)
6949 {
6950 if (DECL_UNIT (decl)->automaton_decl == NULL
6951 || (DECL_UNIT (decl)->automaton_decl->corresponding_automaton
6952 == NULL))
6953 /* Distribute to the first automaton. */
6954 DECL_UNIT (decl)->corresponding_automaton_num = 0;
6955 else
6956 DECL_UNIT (decl)->corresponding_automaton_num
6957 = (DECL_UNIT (decl)->automaton_decl
6958 ->corresponding_automaton->automaton_order_num);
6959 }
6960 }
6961 }
6962
6963 /* The function creates DFA(s) for fast pipeline hazards recognition
6964 after checking and simplifying IR of the description. */
6965 static void
6966 create_automata ()
6967 {
6968 automaton_t curr_automaton;
6969 automaton_t prev_automaton;
6970 decl_t decl;
6971 int curr_automaton_num;
6972 int i;
6973
6974 if (automata_num != 0)
6975 {
6976 units_to_automata_heuristic_distr ();
6977 for (prev_automaton = NULL, curr_automaton_num = 0;
6978 curr_automaton_num < automata_num;
6979 curr_automaton_num++, prev_automaton = curr_automaton)
6980 {
6981 curr_automaton = create_node (sizeof (struct automaton));
6982 curr_automaton->ainsn_list = create_ainsns ();
6983 curr_automaton->corresponding_automaton_decl = NULL;
6984 curr_automaton->next_automaton = NULL;
6985 curr_automaton->automaton_order_num = curr_automaton_num;
6986 if (prev_automaton == NULL)
6987 description->first_automaton = curr_automaton;
6988 else
6989 prev_automaton->next_automaton = curr_automaton;
6990 }
6991 }
6992 else
6993 {
6994 curr_automaton_num = 0;
6995 prev_automaton = NULL;
6996 for (i = 0; i < description->decls_num; i++)
6997 {
6998 decl = description->decls [i];
6999 if (decl->mode == dm_automaton
7000 && DECL_AUTOMATON (decl)->automaton_is_used)
7001 {
7002 curr_automaton = create_node (sizeof (struct automaton));
7003 curr_automaton->ainsn_list = create_ainsns ();
7004 curr_automaton->corresponding_automaton_decl
7005 = DECL_AUTOMATON (decl);
7006 curr_automaton->next_automaton = NULL;
7007 DECL_AUTOMATON (decl)->corresponding_automaton = curr_automaton;
7008 curr_automaton->automaton_order_num = curr_automaton_num;
7009 if (prev_automaton == NULL)
7010 description->first_automaton = curr_automaton;
7011 else
7012 prev_automaton->next_automaton = curr_automaton;
7013 curr_automaton_num++;
7014 prev_automaton = curr_automaton;
7015 }
7016 }
7017 if (curr_automaton_num == 0)
7018 {
7019 curr_automaton = create_node (sizeof (struct automaton));
7020 curr_automaton->ainsn_list = create_ainsns ();
7021 curr_automaton->corresponding_automaton_decl = NULL;
7022 curr_automaton->next_automaton = NULL;
7023 description->first_automaton = curr_automaton;
7024 }
7025 units_to_automata_distr ();
7026 }
7027 NDFA_time = create_ticker ();
7028 ticker_off (&NDFA_time);
7029 NDFA_to_DFA_time = create_ticker ();
7030 ticker_off (&NDFA_to_DFA_time);
7031 minimize_time = create_ticker ();
7032 ticker_off (&minimize_time);
7033 equiv_time = create_ticker ();
7034 ticker_off (&equiv_time);
7035 for (curr_automaton = description->first_automaton;
7036 curr_automaton != NULL;
7037 curr_automaton = curr_automaton->next_automaton)
7038 {
7039 if (curr_automaton->corresponding_automaton_decl == NULL)
7040 fprintf (stderr, "Prepare anonymous automaton creation ... ");
7041 else
7042 fprintf (stderr, "Prepare automaton `%s' creation...",
7043 curr_automaton->corresponding_automaton_decl->name);
7044 create_alt_states (curr_automaton);
7045 form_ainsn_with_same_reservs (curr_automaton);
7046 fprintf (stderr, "done\n");
7047 build_automaton (curr_automaton);
7048 enumerate_states (curr_automaton);
7049 ticker_on (&equiv_time);
7050 set_insn_equiv_classes (curr_automaton);
7051 ticker_off (&equiv_time);
7052 }
7053 }
7054
7055 \f
7056
7057 /* This page contains code for forming string representation of
7058 regexp. The representation is formed on IR obstack. So you should
7059 not work with IR obstack between regexp_representation and
7060 finish_regexp_representation calls. */
7061
7062 /* This recursive function forms string representation of regexp
7063 (without tailing '\0'). */
7064 static void
7065 form_regexp (regexp)
7066 regexp_t regexp;
7067 {
7068 int i;
7069
7070 if (regexp->mode == rm_unit || regexp->mode == rm_reserv)
7071 {
7072 const char *name = (regexp->mode == rm_unit
7073 ? REGEXP_UNIT (regexp)->name
7074 : REGEXP_RESERV (regexp)->name);
7075
7076 obstack_grow (&irp, name, strlen (name));
7077 }
7078 else if (regexp->mode == rm_sequence)
7079 for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++)
7080 {
7081 if (i != 0)
7082 obstack_1grow (&irp, ',');
7083 form_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]);
7084 }
7085 else if (regexp->mode == rm_allof)
7086 {
7087 obstack_1grow (&irp, '(');
7088 for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
7089 {
7090 if (i != 0)
7091 obstack_1grow (&irp, '+');
7092 if (REGEXP_ALLOF (regexp)->regexps[i]->mode == rm_sequence
7093 || REGEXP_ALLOF (regexp)->regexps[i]->mode == rm_oneof)
7094 obstack_1grow (&irp, '(');
7095 form_regexp (REGEXP_ALLOF (regexp)->regexps [i]);
7096 if (REGEXP_ALLOF (regexp)->regexps[i]->mode == rm_sequence
7097 || REGEXP_ALLOF (regexp)->regexps[i]->mode == rm_oneof)
7098 obstack_1grow (&irp, ')');
7099 }
7100 obstack_1grow (&irp, ')');
7101 }
7102 else if (regexp->mode == rm_oneof)
7103 for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
7104 {
7105 if (i != 0)
7106 obstack_1grow (&irp, '|');
7107 if (REGEXP_ONEOF (regexp)->regexps[i]->mode == rm_sequence)
7108 obstack_1grow (&irp, '(');
7109 form_regexp (REGEXP_ONEOF (regexp)->regexps [i]);
7110 if (REGEXP_ONEOF (regexp)->regexps[i]->mode == rm_sequence)
7111 obstack_1grow (&irp, ')');
7112 }
7113 else if (regexp->mode == rm_repeat)
7114 {
7115 char digits [30];
7116
7117 if (REGEXP_REPEAT (regexp)->regexp->mode == rm_sequence
7118 || REGEXP_REPEAT (regexp)->regexp->mode == rm_allof
7119 || REGEXP_REPEAT (regexp)->regexp->mode == rm_oneof)
7120 obstack_1grow (&irp, '(');
7121 form_regexp (REGEXP_REPEAT (regexp)->regexp);
7122 if (REGEXP_REPEAT (regexp)->regexp->mode == rm_sequence
7123 || REGEXP_REPEAT (regexp)->regexp->mode == rm_allof
7124 || REGEXP_REPEAT (regexp)->regexp->mode == rm_oneof)
7125 obstack_1grow (&irp, ')');
7126 sprintf (digits, "*%d", REGEXP_REPEAT (regexp)->repeat_num);
7127 obstack_grow (&irp, digits, strlen (digits));
7128 }
7129 else if (regexp->mode == rm_nothing)
7130 obstack_grow (&irp, NOTHING_NAME, strlen (NOTHING_NAME));
7131 else
7132 abort ();
7133 }
7134
7135 /* The function returns string representation of REGEXP on IR
7136 obstack. */
7137 static const char *
7138 regexp_representation (regexp)
7139 regexp_t regexp;
7140 {
7141 form_regexp (regexp);
7142 obstack_1grow (&irp, '\0');
7143 return obstack_base (&irp);
7144 }
7145
7146 /* The function frees memory allocated for last formed string
7147 representation of regexp. */
7148 static void
7149 finish_regexp_representation ()
7150 {
7151 int length = obstack_object_size (&irp);
7152
7153 obstack_blank_fast (&irp, -length);
7154 }
7155
7156 \f
7157
7158 /* This page contains code for output PHR (pipeline hazards recognizer). */
7159
7160 /* The function outputs minimal C type which is sufficient for
7161 representation numbers in range min_range_value and
7162 max_range_value. Because host machine and build machine may be
7163 different, we use here minimal values required by ANSI C standard
7164 instead of UCHAR_MAX, SHRT_MAX, SHRT_MIN, etc. This is a good
7165 approximation. */
7166
7167 static void
7168 output_range_type (f, min_range_value, max_range_value)
7169 FILE *f;
7170 long int min_range_value;
7171 long int max_range_value;
7172 {
7173 if (min_range_value >= 0 && max_range_value <= 255)
7174 fprintf (f, "unsigned char");
7175 else if (min_range_value >= -127 && max_range_value <= 127)
7176 fprintf (f, "signed char");
7177 else if (min_range_value >= 0 && max_range_value <= 65535)
7178 fprintf (f, "unsigned short");
7179 else if (min_range_value >= -32767 && max_range_value <= 32767)
7180 fprintf (f, "short");
7181 else
7182 fprintf (f, "int");
7183 }
7184
7185 /* The following macro value is used as value of member
7186 `longest_path_length' of state when we are processing path and the
7187 state on the path. */
7188
7189 #define ON_THE_PATH -2
7190
7191 /* The following recursive function searches for the length of the
7192 longest path starting from STATE which does not contain cycles and
7193 `cycle advance' arcs. */
7194
7195 static int
7196 longest_path_length (state)
7197 state_t state;
7198 {
7199 arc_t arc;
7200 int length, result;
7201
7202 if (state->longest_path_length == ON_THE_PATH)
7203 /* We don't expect the path cycle here. Our graph may contain
7204 only cycles with one state on the path not containing `cycle
7205 advance' arcs -- see comment below. */
7206 abort ();
7207 else if (state->longest_path_length != UNDEFINED_LONGEST_PATH_LENGTH)
7208 /* We alreday visited the state. */
7209 return state->longest_path_length;
7210
7211 result = 0;
7212 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
7213 /* Ignore cycles containing one state and `cycle advance' arcs. */
7214 if (arc->to_state != state
7215 && (arc->insn->insn_reserv_decl
7216 != DECL_INSN_RESERV (advance_cycle_insn_decl)))
7217 {
7218 length = longest_path_length (arc->to_state);
7219 if (length > result)
7220 result = length;
7221 }
7222 state->longest_path_length = result + 1;
7223 return result;
7224 }
7225
7226 /* The following variable value is value of the corresponding global
7227 variable in the automaton based pipeline interface. */
7228
7229 static int max_dfa_issue_rate;
7230
7231 /* The following function processes the longest path length staring
7232 from STATE to find MAX_DFA_ISSUE_RATE. */
7233
7234 static void
7235 process_state_longest_path_length (state)
7236 state_t state;
7237 {
7238 int value;
7239
7240 value = longest_path_length (state);
7241 if (value > max_dfa_issue_rate)
7242 max_dfa_issue_rate = value;
7243 }
7244
7245 /* The following macro value is name of the corresponding global
7246 variable in the automaton based pipeline interface. */
7247
7248 #define MAX_DFA_ISSUE_RATE_VAR_NAME "max_dfa_issue_rate"
7249
7250 /* The following function calculates value of the corresponding
7251 global variable and outputs its declaration. */
7252
7253 static void
7254 output_dfa_max_issue_rate ()
7255 {
7256 automaton_t automaton;
7257
7258 if (UNDEFINED_LONGEST_PATH_LENGTH == ON_THE_PATH || ON_THE_PATH >= 0)
7259 abort ();
7260 max_dfa_issue_rate = 0;
7261 for (automaton = description->first_automaton;
7262 automaton != NULL;
7263 automaton = automaton->next_automaton)
7264 pass_states (automaton, process_state_longest_path_length);
7265 fprintf (output_file, "\nint %s = %d;\n",
7266 MAX_DFA_ISSUE_RATE_VAR_NAME, max_dfa_issue_rate);
7267 }
7268
7269 /* The function outputs all initialization values of VECT with length
7270 vect_length. */
7271 static void
7272 output_vect (vect, vect_length)
7273 vect_el_t *vect;
7274 int vect_length;
7275 {
7276 int els_on_line;
7277
7278 els_on_line = 1;
7279 if (vect_length == 0)
7280 fprintf (output_file,
7281 "0 /* This is dummy el because the vect is empty */");
7282 else
7283 {
7284 do
7285 {
7286 fprintf (output_file, "%5ld", (long) *vect);
7287 vect_length--;
7288 if (els_on_line == 10)
7289 {
7290 els_on_line = 0;
7291 fprintf (output_file, ",\n");
7292 }
7293 else if (vect_length != 0)
7294 fprintf (output_file, ", ");
7295 els_on_line++;
7296 vect++;
7297 }
7298 while (vect_length != 0);
7299 }
7300 }
7301
7302 /* The following is name of the structure which represents DFA(s) for
7303 PHR. */
7304 #define CHIP_NAME "DFA_chip"
7305
7306 /* The following is name of member which represents state of a DFA for
7307 PHR. */
7308 static void
7309 output_chip_member_name (f, automaton)
7310 FILE *f;
7311 automaton_t automaton;
7312 {
7313 if (automaton->corresponding_automaton_decl == NULL)
7314 fprintf (f, "automaton_state_%d", automaton->automaton_order_num);
7315 else
7316 fprintf (f, "%s_automaton_state",
7317 automaton->corresponding_automaton_decl->name);
7318 }
7319
7320 /* The following is name of temporary variable which stores state of a
7321 DFA for PHR. */
7322 static void
7323 output_temp_chip_member_name (f, automaton)
7324 FILE *f;
7325 automaton_t automaton;
7326 {
7327 fprintf (f, "_");
7328 output_chip_member_name (f, automaton);
7329 }
7330
7331 /* This is name of macro value which is code of pseudo_insn
7332 representing advancing cpu cycle. Its value is used as internal
7333 code unknown insn. */
7334 #define ADVANCE_CYCLE_VALUE_NAME "DFA__ADVANCE_CYCLE"
7335
7336 /* Output name of translate vector for given automaton. */
7337 static void
7338 output_translate_vect_name (f, automaton)
7339 FILE *f;
7340 automaton_t automaton;
7341 {
7342 if (automaton->corresponding_automaton_decl == NULL)
7343 fprintf (f, "translate_%d", automaton->automaton_order_num);
7344 else
7345 fprintf (f, "%s_translate", automaton->corresponding_automaton_decl->name);
7346 }
7347
7348 /* Output name for simple transition table representation. */
7349 static void
7350 output_trans_full_vect_name (f, automaton)
7351 FILE *f;
7352 automaton_t automaton;
7353 {
7354 if (automaton->corresponding_automaton_decl == NULL)
7355 fprintf (f, "transitions_%d", automaton->automaton_order_num);
7356 else
7357 fprintf (f, "%s_transitions",
7358 automaton->corresponding_automaton_decl->name);
7359 }
7360
7361 /* Output name of comb vector of the transition table for given
7362 automaton. */
7363 static void
7364 output_trans_comb_vect_name (f, automaton)
7365 FILE *f;
7366 automaton_t automaton;
7367 {
7368 if (automaton->corresponding_automaton_decl == NULL)
7369 fprintf (f, "transitions_%d", automaton->automaton_order_num);
7370 else
7371 fprintf (f, "%s_transitions",
7372 automaton->corresponding_automaton_decl->name);
7373 }
7374
7375 /* Output name of check vector of the transition table for given
7376 automaton. */
7377 static void
7378 output_trans_check_vect_name (f, automaton)
7379 FILE *f;
7380 automaton_t automaton;
7381 {
7382 if (automaton->corresponding_automaton_decl == NULL)
7383 fprintf (f, "check_%d", automaton->automaton_order_num);
7384 else
7385 fprintf (f, "%s_check", automaton->corresponding_automaton_decl->name);
7386 }
7387
7388 /* Output name of base vector of the transition table for given
7389 automaton. */
7390 static void
7391 output_trans_base_vect_name (f, automaton)
7392 FILE *f;
7393 automaton_t automaton;
7394 {
7395 if (automaton->corresponding_automaton_decl == NULL)
7396 fprintf (f, "base_%d", automaton->automaton_order_num);
7397 else
7398 fprintf (f, "%s_base", automaton->corresponding_automaton_decl->name);
7399 }
7400
7401 /* Output name for simple alternatives number representation. */
7402 static void
7403 output_state_alts_full_vect_name (f, automaton)
7404 FILE *f;
7405 automaton_t automaton;
7406 {
7407 if (automaton->corresponding_automaton_decl == NULL)
7408 fprintf (f, "state_alts_%d", automaton->automaton_order_num);
7409 else
7410 fprintf (f, "%s_state_alts",
7411 automaton->corresponding_automaton_decl->name);
7412 }
7413
7414 /* Output name of comb vector of the alternatives number table for given
7415 automaton. */
7416 static void
7417 output_state_alts_comb_vect_name (f, automaton)
7418 FILE *f;
7419 automaton_t automaton;
7420 {
7421 if (automaton->corresponding_automaton_decl == NULL)
7422 fprintf (f, "state_alts_%d", automaton->automaton_order_num);
7423 else
7424 fprintf (f, "%s_state_alts",
7425 automaton->corresponding_automaton_decl->name);
7426 }
7427
7428 /* Output name of check vector of the alternatives number table for given
7429 automaton. */
7430 static void
7431 output_state_alts_check_vect_name (f, automaton)
7432 FILE *f;
7433 automaton_t automaton;
7434 {
7435 if (automaton->corresponding_automaton_decl == NULL)
7436 fprintf (f, "check_state_alts_%d", automaton->automaton_order_num);
7437 else
7438 fprintf (f, "%s_check_state_alts",
7439 automaton->corresponding_automaton_decl->name);
7440 }
7441
7442 /* Output name of base vector of the alternatives number table for given
7443 automaton. */
7444 static void
7445 output_state_alts_base_vect_name (f, automaton)
7446 FILE *f;
7447 automaton_t automaton;
7448 {
7449 if (automaton->corresponding_automaton_decl == NULL)
7450 fprintf (f, "base_state_alts_%d", automaton->automaton_order_num);
7451 else
7452 fprintf (f, "%s_base_state_alts",
7453 automaton->corresponding_automaton_decl->name);
7454 }
7455
7456 /* Output name of simple min issue delay table representation. */
7457 static void
7458 output_min_issue_delay_vect_name (f, automaton)
7459 FILE *f;
7460 automaton_t automaton;
7461 {
7462 if (automaton->corresponding_automaton_decl == NULL)
7463 fprintf (f, "min_issue_delay_%d", automaton->automaton_order_num);
7464 else
7465 fprintf (f, "%s_min_issue_delay",
7466 automaton->corresponding_automaton_decl->name);
7467 }
7468
7469 /* Output name of deadlock vector for given automaton. */
7470 static void
7471 output_dead_lock_vect_name (f, automaton)
7472 FILE *f;
7473 automaton_t automaton;
7474 {
7475 if (automaton->corresponding_automaton_decl == NULL)
7476 fprintf (f, "dead_lock_%d", automaton->automaton_order_num);
7477 else
7478 fprintf (f, "%s_dead_lock", automaton->corresponding_automaton_decl->name);
7479 }
7480
7481 /* Output name of reserved units table for AUTOMATON into file F. */
7482 static void
7483 output_reserved_units_table_name (f, automaton)
7484 FILE *f;
7485 automaton_t automaton;
7486 {
7487 if (automaton->corresponding_automaton_decl == NULL)
7488 fprintf (f, "reserved_units_%d", automaton->automaton_order_num);
7489 else
7490 fprintf (f, "%s_reserved_units",
7491 automaton->corresponding_automaton_decl->name);
7492 }
7493
7494 /* Name of the PHR interface macro. */
7495 #define AUTOMATON_STATE_ALTS_MACRO_NAME "AUTOMATON_STATE_ALTS"
7496
7497 /* Name of the PHR interface macro. */
7498 #define CPU_UNITS_QUERY_MACRO_NAME "CPU_UNITS_QUERY"
7499
7500 /* Names of an internal functions: */
7501 #define INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME "internal_min_issue_delay"
7502
7503 /* This is external type of DFA(s) state. */
7504 #define STATE_TYPE_NAME "state_t"
7505
7506 #define INTERNAL_TRANSITION_FUNC_NAME "internal_state_transition"
7507
7508 #define INTERNAL_STATE_ALTS_FUNC_NAME "internal_state_alts"
7509
7510 #define INTERNAL_RESET_FUNC_NAME "internal_reset"
7511
7512 #define INTERNAL_DEAD_LOCK_FUNC_NAME "internal_state_dead_lock_p"
7513
7514 #define INTERNAL_INSN_LATENCY_FUNC_NAME "internal_insn_latency"
7515
7516 /* Name of cache of insn dfa codes. */
7517 #define DFA_INSN_CODES_VARIABLE_NAME "dfa_insn_codes"
7518
7519 /* Name of length of cache of insn dfa codes. */
7520 #define DFA_INSN_CODES_LENGTH_VARIABLE_NAME "dfa_insn_codes_length"
7521
7522 /* Names of the PHR interface functions: */
7523 #define SIZE_FUNC_NAME "state_size"
7524
7525 #define TRANSITION_FUNC_NAME "state_transition"
7526
7527 #define STATE_ALTS_FUNC_NAME "state_alts"
7528
7529 #define MIN_ISSUE_DELAY_FUNC_NAME "min_issue_delay"
7530
7531 #define MIN_INSN_CONFLICT_DELAY_FUNC_NAME "min_insn_conflict_delay"
7532
7533 #define DEAD_LOCK_FUNC_NAME "state_dead_lock_p"
7534
7535 #define RESET_FUNC_NAME "state_reset"
7536
7537 #define INSN_LATENCY_FUNC_NAME "insn_latency"
7538
7539 #define PRINT_RESERVATION_FUNC_NAME "print_reservation"
7540
7541 #define GET_CPU_UNIT_CODE_FUNC_NAME "get_cpu_unit_code"
7542
7543 #define CPU_UNIT_RESERVATION_P_FUNC_NAME "cpu_unit_reservation_p"
7544
7545 #define DFA_CLEAN_INSN_CACHE_FUNC_NAME "dfa_clean_insn_cache"
7546
7547 #define DFA_START_FUNC_NAME "dfa_start"
7548
7549 #define DFA_FINISH_FUNC_NAME "dfa_finish"
7550
7551 /* Names of parameters of the PHR interface functions. */
7552 #define STATE_NAME "state"
7553
7554 #define INSN_PARAMETER_NAME "insn"
7555
7556 #define INSN2_PARAMETER_NAME "insn2"
7557
7558 #define CHIP_PARAMETER_NAME "chip"
7559
7560 #define FILE_PARAMETER_NAME "f"
7561
7562 #define CPU_UNIT_NAME_PARAMETER_NAME "cpu_unit_name"
7563
7564 #define CPU_CODE_PARAMETER_NAME "cpu_unit_code"
7565
7566 /* Names of the variables whose values are internal insn code of rtx
7567 insn. */
7568 #define INTERNAL_INSN_CODE_NAME "insn_code"
7569
7570 #define INTERNAL_INSN2_CODE_NAME "insn2_code"
7571
7572 /* Names of temporary variables in some functions. */
7573 #define TEMPORARY_VARIABLE_NAME "temp"
7574
7575 #define I_VARIABLE_NAME "i"
7576
7577 /* Name of result variable in some functions. */
7578 #define RESULT_VARIABLE_NAME "res"
7579
7580 /* Name of function (attribute) to translate insn into number of insn
7581 alternatives reservation. */
7582 #define INSN_ALTS_FUNC_NAME "insn_alts"
7583
7584 /* Name of function (attribute) to translate insn into internal insn
7585 code. */
7586 #define INTERNAL_DFA_INSN_CODE_FUNC_NAME "internal_dfa_insn_code"
7587
7588 /* Name of function (attribute) to translate insn into internal insn
7589 code with caching. */
7590 #define DFA_INSN_CODE_FUNC_NAME "dfa_insn_code"
7591
7592 /* Name of function (attribute) to translate insn into internal insn
7593 code. */
7594 #define INSN_DEFAULT_LATENCY_FUNC_NAME "insn_default_latency"
7595
7596 /* Name of function (attribute) to translate insn into internal insn
7597 code. */
7598 #define BYPASS_P_FUNC_NAME "bypass_p"
7599
7600 /* Output C type which is used for representation of codes of states
7601 of AUTOMATON. */
7602 static void
7603 output_state_member_type (f, automaton)
7604 FILE *f;
7605 automaton_t automaton;
7606 {
7607 output_range_type (f, 0, automaton->achieved_states_num);
7608 }
7609
7610 /* Output definition of the structure representing current DFA(s)
7611 state(s). */
7612 static void
7613 output_chip_definitions ()
7614 {
7615 automaton_t automaton;
7616
7617 fprintf (output_file, "struct %s\n{\n", CHIP_NAME);
7618 for (automaton = description->first_automaton;
7619 automaton != NULL;
7620 automaton = automaton->next_automaton)
7621 {
7622 fprintf (output_file, " ");
7623 output_state_member_type (output_file, automaton);
7624 fprintf (output_file, " ");
7625 output_chip_member_name (output_file, automaton);
7626 fprintf (output_file, ";\n");
7627 }
7628 fprintf (output_file, "};\n\n");
7629 #if 0
7630 fprintf (output_file, "static struct %s %s;\n\n", CHIP_NAME, CHIP_NAME);
7631 #endif
7632 }
7633
7634
7635 /* The function outputs translate vector of internal insn code into
7636 insn equivalence class number. The equivalence class number is
7637 used to access to table and vectors representing DFA(s). */
7638 static void
7639 output_translate_vect (automaton)
7640 automaton_t automaton;
7641 {
7642 ainsn_t ainsn;
7643 int insn_value;
7644 vla_hwint_t translate_vect;
7645
7646 VLA_HWINT_CREATE (translate_vect, 250, "translate vector");
7647 VLA_HWINT_EXPAND (translate_vect, description->insns_num);
7648 for (insn_value = 0; insn_value <= description->insns_num; insn_value++)
7649 /* Undefined value */
7650 VLA_HWINT (translate_vect, insn_value) = automaton->insn_equiv_classes_num;
7651 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
7652 VLA_HWINT (translate_vect, ainsn->insn_reserv_decl->insn_num)
7653 = ainsn->insn_equiv_class_num;
7654 fprintf (output_file,
7655 "/* Vector translating external insn codes to internal ones.*/\n");
7656 fprintf (output_file, "static const ");
7657 output_range_type (output_file, 0, automaton->insn_equiv_classes_num);
7658 fprintf (output_file, " ");
7659 output_translate_vect_name (output_file, automaton);
7660 fprintf (output_file, "[] ATTRIBUTE_UNUSED = {\n");
7661 output_vect (VLA_HWINT_BEGIN (translate_vect),
7662 VLA_HWINT_LENGTH (translate_vect));
7663 fprintf (output_file, "};\n\n");
7664 VLA_HWINT_DELETE (translate_vect);
7665 }
7666
7667 /* The value in a table state x ainsn -> something which represents
7668 undefined value. */
7669 static int undefined_vect_el_value;
7670
7671 /* The following function returns nonzero value if the best
7672 representation of the table is comb vector. */
7673 static int
7674 comb_vect_p (tab)
7675 state_ainsn_table_t tab;
7676 {
7677 return (2 * VLA_HWINT_LENGTH (tab->full_vect)
7678 > 5 * VLA_HWINT_LENGTH (tab->comb_vect));
7679 }
7680
7681 /* The following function creates new table for AUTOMATON. */
7682 static state_ainsn_table_t
7683 create_state_ainsn_table (automaton)
7684 automaton_t automaton;
7685 {
7686 state_ainsn_table_t tab;
7687 int full_vect_length;
7688 int i;
7689
7690 tab = create_node (sizeof (struct state_ainsn_table));
7691 tab->automaton = automaton;
7692 VLA_HWINT_CREATE (tab->comb_vect, 10000, "comb vector");
7693 VLA_HWINT_CREATE (tab->check_vect, 10000, "check vector");
7694 VLA_HWINT_CREATE (tab->base_vect, 1000, "base vector");
7695 VLA_HWINT_EXPAND (tab->base_vect, automaton->achieved_states_num);
7696 VLA_HWINT_CREATE (tab->full_vect, 10000, "full vector");
7697 full_vect_length = (automaton->insn_equiv_classes_num
7698 * automaton->achieved_states_num);
7699 VLA_HWINT_EXPAND (tab->full_vect, full_vect_length);
7700 for (i = 0; i < full_vect_length; i++)
7701 VLA_HWINT (tab->full_vect, i) = undefined_vect_el_value;
7702 tab->min_base_vect_el_value = 0;
7703 tab->max_base_vect_el_value = 0;
7704 tab->min_comb_vect_el_value = 0;
7705 tab->max_comb_vect_el_value = 0;
7706 return tab;
7707 }
7708
7709 /* The following function outputs the best C representation of the
7710 table TAB of given TABLE_NAME. */
7711 static void
7712 output_state_ainsn_table (tab, table_name, output_full_vect_name_func,
7713 output_comb_vect_name_func,
7714 output_check_vect_name_func,
7715 output_base_vect_name_func)
7716 state_ainsn_table_t tab;
7717 char *table_name;
7718 void (*output_full_vect_name_func) PARAMS ((FILE *, automaton_t));
7719 void (*output_comb_vect_name_func) PARAMS ((FILE *, automaton_t));
7720 void (*output_check_vect_name_func) PARAMS ((FILE *, automaton_t));
7721 void (*output_base_vect_name_func) PARAMS ((FILE *, automaton_t));
7722 {
7723 if (!comb_vect_p (tab))
7724 {
7725 fprintf (output_file, "/* Vector for %s. */\n", table_name);
7726 fprintf (output_file, "static const ");
7727 output_range_type (output_file, tab->min_comb_vect_el_value,
7728 tab->max_comb_vect_el_value);
7729 fprintf (output_file, " ");
7730 (*output_full_vect_name_func) (output_file, tab->automaton);
7731 fprintf (output_file, "[] ATTRIBUTE_UNUSED = {\n");
7732 output_vect (VLA_HWINT_BEGIN (tab->full_vect),
7733 VLA_HWINT_LENGTH (tab->full_vect));
7734 fprintf (output_file, "};\n\n");
7735 }
7736 else
7737 {
7738 fprintf (output_file, "/* Comb vector for %s. */\n", table_name);
7739 fprintf (output_file, "static const ");
7740 output_range_type (output_file, tab->min_comb_vect_el_value,
7741 tab->max_comb_vect_el_value);
7742 fprintf (output_file, " ");
7743 (*output_comb_vect_name_func) (output_file, tab->automaton);
7744 fprintf (output_file, "[] ATTRIBUTE_UNUSED = {\n");
7745 output_vect (VLA_HWINT_BEGIN (tab->comb_vect),
7746 VLA_HWINT_LENGTH (tab->comb_vect));
7747 fprintf (output_file, "};\n\n");
7748 fprintf (output_file, "/* Check vector for %s. */\n", table_name);
7749 fprintf (output_file, "static const ");
7750 output_range_type (output_file, 0, tab->automaton->achieved_states_num);
7751 fprintf (output_file, " ");
7752 (*output_check_vect_name_func) (output_file, tab->automaton);
7753 fprintf (output_file, "[] = {\n");
7754 output_vect (VLA_HWINT_BEGIN (tab->check_vect),
7755 VLA_HWINT_LENGTH (tab->check_vect));
7756 fprintf (output_file, "};\n\n");
7757 fprintf (output_file, "/* Base vector for %s. */\n", table_name);
7758 fprintf (output_file, "static const ");
7759 output_range_type (output_file, tab->min_base_vect_el_value,
7760 tab->max_base_vect_el_value);
7761 fprintf (output_file, " ");
7762 (*output_base_vect_name_func) (output_file, tab->automaton);
7763 fprintf (output_file, "[] = {\n");
7764 output_vect (VLA_HWINT_BEGIN (tab->base_vect),
7765 VLA_HWINT_LENGTH (tab->base_vect));
7766 fprintf (output_file, "};\n\n");
7767 }
7768 }
7769
7770 /* The following function adds vector with length VECT_LENGTH and
7771 elements pointed by VECT to table TAB as its line with number
7772 VECT_NUM. */
7773 static void
7774 add_vect (tab, vect_num, vect, vect_length)
7775 state_ainsn_table_t tab;
7776 int vect_num;
7777 vect_el_t *vect;
7778 int vect_length;
7779 {
7780 int real_vect_length;
7781 vect_el_t *comb_vect_start;
7782 vect_el_t *check_vect_start;
7783 int comb_vect_index;
7784 int comb_vect_els_num;
7785 int vect_index;
7786 int first_unempty_vect_index;
7787 int additional_els_num;
7788 int no_state_value;
7789 vect_el_t vect_el;
7790 int i;
7791
7792 if (vect_length == 0)
7793 abort ();
7794 real_vect_length = tab->automaton->insn_equiv_classes_num;
7795 if (vect [vect_length - 1] == undefined_vect_el_value)
7796 abort ();
7797 /* Form full vector in the table: */
7798 for (i = 0; i < vect_length; i++)
7799 VLA_HWINT (tab->full_vect,
7800 i + tab->automaton->insn_equiv_classes_num * vect_num)
7801 = vect [i];
7802 /* Form comb vector in the table: */
7803 if (VLA_HWINT_LENGTH (tab->comb_vect) != VLA_HWINT_LENGTH (tab->check_vect))
7804 abort ();
7805 comb_vect_start = VLA_HWINT_BEGIN (tab->comb_vect);
7806 comb_vect_els_num = VLA_HWINT_LENGTH (tab->comb_vect);
7807 for (first_unempty_vect_index = 0;
7808 first_unempty_vect_index < vect_length;
7809 first_unempty_vect_index++)
7810 if (vect [first_unempty_vect_index] != undefined_vect_el_value)
7811 break;
7812 /* Search for the place in comb vect for the inserted vect. */
7813 for (comb_vect_index = 0;
7814 comb_vect_index < comb_vect_els_num;
7815 comb_vect_index++)
7816 {
7817 for (vect_index = first_unempty_vect_index;
7818 vect_index < vect_length
7819 && vect_index + comb_vect_index < comb_vect_els_num;
7820 vect_index++)
7821 if (vect [vect_index] != undefined_vect_el_value
7822 && (comb_vect_start [vect_index + comb_vect_index]
7823 != undefined_vect_el_value))
7824 break;
7825 if (vect_index >= vect_length
7826 || vect_index + comb_vect_index >= comb_vect_els_num)
7827 break;
7828 }
7829 /* Slot was found. */
7830 additional_els_num = comb_vect_index + real_vect_length - comb_vect_els_num;
7831 if (additional_els_num < 0)
7832 additional_els_num = 0;
7833 /* Expand comb and check vectors. */
7834 vect_el = undefined_vect_el_value;
7835 no_state_value = tab->automaton->achieved_states_num;
7836 while (additional_els_num > 0)
7837 {
7838 VLA_HWINT_ADD (tab->comb_vect, vect_el);
7839 VLA_HWINT_ADD (tab->check_vect, no_state_value);
7840 additional_els_num--;
7841 }
7842 comb_vect_start = VLA_HWINT_BEGIN (tab->comb_vect);
7843 check_vect_start = VLA_HWINT_BEGIN (tab->check_vect);
7844 if (VLA_HWINT_LENGTH (tab->comb_vect)
7845 < (size_t) (comb_vect_index + real_vect_length))
7846 abort ();
7847 /* Fill comb and check vectors. */
7848 for (vect_index = 0; vect_index < vect_length; vect_index++)
7849 if (vect [vect_index] != undefined_vect_el_value)
7850 {
7851 if (comb_vect_start [comb_vect_index + vect_index]
7852 != undefined_vect_el_value)
7853 abort ();
7854 comb_vect_start [comb_vect_index + vect_index] = vect [vect_index];
7855 if (vect [vect_index] < 0)
7856 abort ();
7857 if (tab->max_comb_vect_el_value < vect [vect_index])
7858 tab->max_comb_vect_el_value = vect [vect_index];
7859 if (tab->min_comb_vect_el_value > vect [vect_index])
7860 tab->min_comb_vect_el_value = vect [vect_index];
7861 check_vect_start [comb_vect_index + vect_index] = vect_num;
7862 }
7863 if (tab->max_base_vect_el_value < comb_vect_index)
7864 tab->max_base_vect_el_value = comb_vect_index;
7865 if (tab->min_base_vect_el_value > comb_vect_index)
7866 tab->min_base_vect_el_value = comb_vect_index;
7867 VLA_HWINT (tab->base_vect, vect_num) = comb_vect_index;
7868 }
7869
7870 /* Return number of out arcs of STATE. */
7871 static int
7872 out_state_arcs_num (state)
7873 state_t state;
7874 {
7875 int result;
7876 arc_t arc;
7877
7878 result = 0;
7879 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
7880 {
7881 if (arc->insn == NULL)
7882 abort ();
7883 if (arc->insn->first_ainsn_with_given_equialence_num)
7884 result++;
7885 }
7886 return result;
7887 }
7888
7889 /* Compare number of possible transitions from the states. */
7890 static int
7891 compare_transition_els_num (state_ptr_1, state_ptr_2)
7892 const void *state_ptr_1;
7893 const void *state_ptr_2;
7894 {
7895 int transition_els_num_1;
7896 int transition_els_num_2;
7897
7898 transition_els_num_1 = out_state_arcs_num (*(state_t *) state_ptr_1);
7899 transition_els_num_2 = out_state_arcs_num (*(state_t *) state_ptr_2);
7900 if (transition_els_num_1 < transition_els_num_2)
7901 return 1;
7902 else if (transition_els_num_1 == transition_els_num_2)
7903 return 0;
7904 else
7905 return -1;
7906 }
7907
7908 /* The function adds element EL_VALUE to vector VECT for a table state
7909 x AINSN. */
7910 static void
7911 add_vect_el (vect, ainsn, el_value)
7912 vla_hwint_t *vect;
7913 ainsn_t ainsn;
7914 int el_value;
7915 {
7916 int equiv_class_num;
7917 int vect_index;
7918
7919 if (ainsn == NULL)
7920 abort ();
7921 equiv_class_num = ainsn->insn_equiv_class_num;
7922 for (vect_index = VLA_HWINT_LENGTH (*vect);
7923 vect_index <= equiv_class_num;
7924 vect_index++)
7925 VLA_HWINT_ADD (*vect, undefined_vect_el_value);
7926 VLA_HWINT (*vect, equiv_class_num) = el_value;
7927 }
7928
7929 /* This is for forming vector of states of an automaton. */
7930 static vla_ptr_t output_states_vect;
7931
7932 /* The function is called by function pass_states. The function adds
7933 STATE to `output_states_vect'. */
7934 static void
7935 add_states_vect_el (state)
7936 state_t state;
7937 {
7938 VLA_PTR_ADD (output_states_vect, state);
7939 }
7940
7941 /* Form and output vectors (comb, check, base or full vector)
7942 representing transition table of AUTOMATON. */
7943 static void
7944 output_trans_table (automaton)
7945 automaton_t automaton;
7946 {
7947 state_t *state_ptr;
7948 arc_t arc;
7949 vla_hwint_t transition_vect;
7950
7951 undefined_vect_el_value = automaton->achieved_states_num;
7952 automaton->trans_table = create_state_ainsn_table (automaton);
7953 /* Create vect of pointers to states ordered by num of transitions
7954 from the state (state with the maximum num is the first). */
7955 VLA_PTR_CREATE (output_states_vect, 1500, "output states vector");
7956 pass_states (automaton, add_states_vect_el);
7957 qsort (VLA_PTR_BEGIN (output_states_vect),
7958 VLA_PTR_LENGTH (output_states_vect),
7959 sizeof (state_t), compare_transition_els_num);
7960 VLA_HWINT_CREATE (transition_vect, 500, "transition vector");
7961 for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
7962 state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
7963 state_ptr++)
7964 {
7965 VLA_HWINT_NULLIFY (transition_vect);
7966 for (arc = first_out_arc (*state_ptr);
7967 arc != NULL;
7968 arc = next_out_arc (arc))
7969 {
7970 if (arc->insn == NULL)
7971 abort ();
7972 if (arc->insn->first_ainsn_with_given_equialence_num)
7973 add_vect_el (&transition_vect, arc->insn,
7974 arc->to_state->order_state_num);
7975 }
7976 add_vect (automaton->trans_table, (*state_ptr)->order_state_num,
7977 VLA_HWINT_BEGIN (transition_vect),
7978 VLA_HWINT_LENGTH (transition_vect));
7979 }
7980 output_state_ainsn_table
7981 (automaton->trans_table, (char *) "state transitions",
7982 output_trans_full_vect_name, output_trans_comb_vect_name,
7983 output_trans_check_vect_name, output_trans_base_vect_name);
7984 VLA_PTR_DELETE (output_states_vect);
7985 VLA_HWINT_DELETE (transition_vect);
7986 }
7987
7988 /* Form and output vectors (comb, check, base or simple vect)
7989 representing alts number table of AUTOMATON. The table is state x
7990 ainsn -> number of possible alternative reservations by the
7991 ainsn. */
7992 static void
7993 output_state_alts_table (automaton)
7994 automaton_t automaton;
7995 {
7996 state_t *state_ptr;
7997 arc_t arc;
7998 vla_hwint_t state_alts_vect;
7999
8000 undefined_vect_el_value = 0; /* no alts when transition is not possible */
8001 automaton->state_alts_table = create_state_ainsn_table (automaton);
8002 /* Create vect of pointers to states ordered by num of transitions
8003 from the state (state with the maximum num is the first). */
8004 VLA_PTR_CREATE (output_states_vect, 1500, "output states vector");
8005 pass_states (automaton, add_states_vect_el);
8006 qsort (VLA_PTR_BEGIN (output_states_vect),
8007 VLA_PTR_LENGTH (output_states_vect),
8008 sizeof (state_t), compare_transition_els_num);
8009 /* Create base, comb, and check vectors. */
8010 VLA_HWINT_CREATE (state_alts_vect, 500, "state alts vector");
8011 for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
8012 state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
8013 state_ptr++)
8014 {
8015 VLA_HWINT_NULLIFY (state_alts_vect);
8016 for (arc = first_out_arc (*state_ptr);
8017 arc != NULL;
8018 arc = next_out_arc (arc))
8019 {
8020 if (arc->insn == NULL)
8021 abort ();
8022 if (arc->insn->first_ainsn_with_given_equialence_num)
8023 add_vect_el (&state_alts_vect, arc->insn, arc->state_alts);
8024 }
8025 add_vect (automaton->state_alts_table, (*state_ptr)->order_state_num,
8026 VLA_HWINT_BEGIN (state_alts_vect),
8027 VLA_HWINT_LENGTH (state_alts_vect));
8028 }
8029 output_state_ainsn_table
8030 (automaton->state_alts_table, (char *) "state insn alternatives",
8031 output_state_alts_full_vect_name, output_state_alts_comb_vect_name,
8032 output_state_alts_check_vect_name, output_state_alts_base_vect_name);
8033 VLA_PTR_DELETE (output_states_vect);
8034 VLA_HWINT_DELETE (state_alts_vect);
8035 }
8036
8037 /* The current number of passing states to find minimal issue delay
8038 value for an ainsn and state. */
8039 static int curr_state_pass_num;
8040
8041 /* This recursive function passes states to find minimal issue delay
8042 value for AINSN. The state being visited is STATE. The function
8043 returns minimal issue delay value for AINSN in STATE or -1 if we
8044 enter into a loop. */
8045 static int
8046 min_issue_delay_pass_states (state, ainsn)
8047 state_t state;
8048 ainsn_t ainsn;
8049 {
8050 arc_t arc;
8051 int min_insn_issue_delay, insn_issue_delay;
8052
8053 if (state->state_pass_num == curr_state_pass_num
8054 || state->min_insn_issue_delay != -1)
8055 /* We've entered into a loop or already have the correct value for
8056 given state and ainsn. */
8057 return state->min_insn_issue_delay;
8058 state->state_pass_num = curr_state_pass_num;
8059 min_insn_issue_delay = -1;
8060 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
8061 if (arc->insn == ainsn)
8062 {
8063 min_insn_issue_delay = 0;
8064 break;
8065 }
8066 else
8067 {
8068 insn_issue_delay = min_issue_delay_pass_states (arc->to_state, ainsn);
8069 if (insn_issue_delay != -1)
8070 {
8071 if (arc->insn->insn_reserv_decl
8072 == DECL_INSN_RESERV (advance_cycle_insn_decl))
8073 insn_issue_delay++;
8074 if (min_insn_issue_delay == -1
8075 || min_insn_issue_delay > insn_issue_delay)
8076 {
8077 min_insn_issue_delay = insn_issue_delay;
8078 if (insn_issue_delay == 0)
8079 break;
8080 }
8081 }
8082 }
8083 return min_insn_issue_delay;
8084 }
8085
8086 /* The function searches minimal issue delay value for AINSN in STATE.
8087 The function can return negative value if we can not issue AINSN. We
8088 will report about it later. */
8089 static int
8090 min_issue_delay (state, ainsn)
8091 state_t state;
8092 ainsn_t ainsn;
8093 {
8094 curr_state_pass_num++;
8095 state->min_insn_issue_delay = min_issue_delay_pass_states (state, ainsn);
8096 return state->min_insn_issue_delay;
8097 }
8098
8099 /* The function initiates code for finding minimal issue delay values.
8100 It should be called only once. */
8101 static void
8102 initiate_min_issue_delay_pass_states ()
8103 {
8104 curr_state_pass_num = 0;
8105 }
8106
8107 /* Form and output vectors representing minimal issue delay table of
8108 AUTOMATON. The table is state x ainsn -> minimal issue delay of
8109 the ainsn. */
8110 static void
8111 output_min_issue_delay_table (automaton)
8112 automaton_t automaton;
8113 {
8114 vla_hwint_t min_issue_delay_vect;
8115 vla_hwint_t compressed_min_issue_delay_vect;
8116 vect_el_t min_delay;
8117 ainsn_t ainsn;
8118 state_t *state_ptr;
8119 int i;
8120
8121 /* Create vect of pointers to states ordered by num of transitions
8122 from the state (state with the maximum num is the first). */
8123 VLA_PTR_CREATE (output_states_vect, 1500, "output states vector");
8124 pass_states (automaton, add_states_vect_el);
8125 VLA_HWINT_CREATE (min_issue_delay_vect, 1500, "min issue delay vector");
8126 VLA_HWINT_EXPAND (min_issue_delay_vect,
8127 VLA_HWINT_LENGTH (output_states_vect)
8128 * automaton->insn_equiv_classes_num);
8129 for (i = 0;
8130 i < ((int) VLA_HWINT_LENGTH (output_states_vect)
8131 * automaton->insn_equiv_classes_num);
8132 i++)
8133 VLA_HWINT (min_issue_delay_vect, i) = 0;
8134 automaton->max_min_delay = 0;
8135 for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
8136 if (ainsn->first_ainsn_with_given_equialence_num)
8137 {
8138 for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
8139 state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
8140 state_ptr++)
8141 (*state_ptr)->min_insn_issue_delay = -1;
8142 for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
8143 state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
8144 state_ptr++)
8145 {
8146 min_delay = min_issue_delay (*state_ptr, ainsn);
8147 if (automaton->max_min_delay < min_delay)
8148 automaton->max_min_delay = min_delay;
8149 VLA_HWINT (min_issue_delay_vect,
8150 (*state_ptr)->order_state_num
8151 * automaton->insn_equiv_classes_num
8152 + ainsn->insn_equiv_class_num) = min_delay;
8153 }
8154 }
8155 fprintf (output_file, "/* Vector of min issue delay of insns. */\n");
8156 fprintf (output_file, "static const ");
8157 output_range_type (output_file, 0, automaton->max_min_delay);
8158 fprintf (output_file, " ");
8159 output_min_issue_delay_vect_name (output_file, automaton);
8160 fprintf (output_file, "[] ATTRIBUTE_UNUSED = {\n");
8161 /* Compress the vector */
8162 if (automaton->max_min_delay < 2)
8163 automaton->min_issue_delay_table_compression_factor = 8;
8164 else if (automaton->max_min_delay < 4)
8165 automaton->min_issue_delay_table_compression_factor = 4;
8166 else if (automaton->max_min_delay < 16)
8167 automaton->min_issue_delay_table_compression_factor = 2;
8168 else
8169 automaton->min_issue_delay_table_compression_factor = 1;
8170 VLA_HWINT_CREATE (compressed_min_issue_delay_vect, 1500,
8171 "compressed min issue delay vector");
8172 VLA_HWINT_EXPAND (compressed_min_issue_delay_vect,
8173 (VLA_HWINT_LENGTH (min_issue_delay_vect)
8174 + automaton->min_issue_delay_table_compression_factor
8175 - 1)
8176 / automaton->min_issue_delay_table_compression_factor);
8177 for (i = 0;
8178 i < (int) VLA_HWINT_LENGTH (compressed_min_issue_delay_vect);
8179 i++)
8180 VLA_HWINT (compressed_min_issue_delay_vect, i) = 0;
8181 for (i = 0; i < (int) VLA_HWINT_LENGTH (min_issue_delay_vect); i++)
8182 VLA_HWINT (compressed_min_issue_delay_vect,
8183 i / automaton->min_issue_delay_table_compression_factor)
8184 |= (VLA_HWINT (min_issue_delay_vect, i)
8185 << (8 - (i % automaton->min_issue_delay_table_compression_factor
8186 + 1)
8187 * (8 / automaton->min_issue_delay_table_compression_factor)));
8188 output_vect (VLA_HWINT_BEGIN (compressed_min_issue_delay_vect),
8189 VLA_HWINT_LENGTH (compressed_min_issue_delay_vect));
8190 fprintf (output_file, "};\n\n");
8191 VLA_PTR_DELETE (output_states_vect);
8192 VLA_HWINT_DELETE (min_issue_delay_vect);
8193 VLA_HWINT_DELETE (compressed_min_issue_delay_vect);
8194 }
8195
8196 #ifndef NDEBUG
8197 /* Number of states which contains transition only by advancing cpu
8198 cycle. */
8199 static int locked_states_num;
8200 #endif
8201
8202 /* Form and output vector representing the locked states of
8203 AUTOMATON. */
8204 static void
8205 output_dead_lock_vect (automaton)
8206 automaton_t automaton;
8207 {
8208 state_t *state_ptr;
8209 arc_t arc;
8210 vla_hwint_t dead_lock_vect;
8211
8212 /* Create vect of pointers to states ordered by num of
8213 transitions from the state (state with the maximum num is the
8214 first). */
8215 VLA_PTR_CREATE (output_states_vect, 1500, "output states vector");
8216 pass_states (automaton, add_states_vect_el);
8217 VLA_HWINT_CREATE (dead_lock_vect, 1500, "is dead locked vector");
8218 VLA_HWINT_EXPAND (dead_lock_vect, VLA_HWINT_LENGTH (output_states_vect));
8219 for (state_ptr = VLA_PTR_BEGIN (output_states_vect);
8220 state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
8221 state_ptr++)
8222 {
8223 arc = first_out_arc (*state_ptr);
8224 if (arc == NULL)
8225 abort ();
8226 VLA_HWINT (dead_lock_vect, (*state_ptr)->order_state_num)
8227 = (next_out_arc (arc) == NULL
8228 && (arc->insn->insn_reserv_decl
8229 == DECL_INSN_RESERV (advance_cycle_insn_decl)) ? 1 : 0);
8230 #ifndef NDEBUG
8231 if (VLA_HWINT (dead_lock_vect, (*state_ptr)->order_state_num))
8232 locked_states_num++;
8233 #endif
8234 }
8235 fprintf (output_file, "/* Vector for locked state flags. */\n");
8236 fprintf (output_file, "static const ");
8237 output_range_type (output_file, 0, 1);
8238 fprintf (output_file, " ");
8239 output_dead_lock_vect_name (output_file, automaton);
8240 fprintf (output_file, "[] = {\n");
8241 output_vect (VLA_HWINT_BEGIN (dead_lock_vect),
8242 VLA_HWINT_LENGTH (dead_lock_vect));
8243 fprintf (output_file, "};\n\n");
8244 VLA_HWINT_DELETE (dead_lock_vect);
8245 VLA_PTR_DELETE (output_states_vect);
8246 }
8247
8248 /* Form and output vector representing reserved units of the states of
8249 AUTOMATON. */
8250 static void
8251 output_reserved_units_table (automaton)
8252 automaton_t automaton;
8253 {
8254 state_t *curr_state_ptr;
8255 vla_hwint_t reserved_units_table;
8256 size_t state_byte_size;
8257 int i;
8258
8259 /* Create vect of pointers to states. */
8260 VLA_PTR_CREATE (output_states_vect, 1500, "output states vector");
8261 pass_states (automaton, add_states_vect_el);
8262 /* Create vector. */
8263 VLA_HWINT_CREATE (reserved_units_table, 1500, "reserved units vector");
8264 state_byte_size = (description->query_units_num + 7) / 8;
8265 VLA_HWINT_EXPAND (reserved_units_table,
8266 VLA_HWINT_LENGTH (output_states_vect) * state_byte_size);
8267 for (i = 0;
8268 i < (int) (VLA_HWINT_LENGTH (output_states_vect) * state_byte_size);
8269 i++)
8270 VLA_HWINT (reserved_units_table, i) = 0;
8271 for (curr_state_ptr = VLA_PTR_BEGIN (output_states_vect);
8272 curr_state_ptr <= (state_t *) VLA_PTR_LAST (output_states_vect);
8273 curr_state_ptr++)
8274 {
8275 for (i = 0; i < description->units_num; i++)
8276 if (units_array [i]->query_p
8277 && first_cycle_unit_presence (*curr_state_ptr, i))
8278 VLA_HWINT (reserved_units_table,
8279 (*curr_state_ptr)->order_state_num * state_byte_size
8280 + units_array [i]->query_num / 8)
8281 += (1 << (units_array [i]->query_num % 8));
8282 }
8283 fprintf (output_file, "/* Vector for reserved units of states. */\n");
8284 fprintf (output_file, "static const ");
8285 output_range_type (output_file, 0, 255);
8286 fprintf (output_file, " ");
8287 output_reserved_units_table_name (output_file, automaton);
8288 fprintf (output_file, "[] = {\n");
8289 output_vect (VLA_HWINT_BEGIN (reserved_units_table),
8290 VLA_HWINT_LENGTH (reserved_units_table));
8291 fprintf (output_file, "};\n\n");
8292 VLA_HWINT_DELETE (reserved_units_table);
8293 VLA_PTR_DELETE (output_states_vect);
8294 }
8295
8296 /* The function outputs all tables representing DFA(s) used for fast
8297 pipeline hazards recognition. */
8298 static void
8299 output_tables ()
8300 {
8301 automaton_t automaton;
8302
8303 #ifndef NDEBUG
8304 locked_states_num = 0;
8305 #endif
8306 initiate_min_issue_delay_pass_states ();
8307 for (automaton = description->first_automaton;
8308 automaton != NULL;
8309 automaton = automaton->next_automaton)
8310 {
8311 output_translate_vect (automaton);
8312 output_trans_table (automaton);
8313 fprintf (output_file, "\n#if %s\n", AUTOMATON_STATE_ALTS_MACRO_NAME);
8314 output_state_alts_table (automaton);
8315 fprintf (output_file, "\n#endif /* #if %s */\n\n",
8316 AUTOMATON_STATE_ALTS_MACRO_NAME);
8317 output_min_issue_delay_table (automaton);
8318 output_dead_lock_vect (automaton);
8319 fprintf (output_file, "\n#if %s\n\n", CPU_UNITS_QUERY_MACRO_NAME);
8320 output_reserved_units_table (automaton);
8321 fprintf (output_file, "\n#endif /* #if %s */\n\n",
8322 CPU_UNITS_QUERY_MACRO_NAME);
8323 }
8324 fprintf (output_file, "\n#define %s %d\n\n", ADVANCE_CYCLE_VALUE_NAME,
8325 DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num);
8326 }
8327
8328 /* The function outputs definition and value of PHR interface variable
8329 `max_insn_queue_index'. Its value is not less than maximal queue
8330 length needed for the insn scheduler. */
8331 static void
8332 output_max_insn_queue_index_def ()
8333 {
8334 int i, max, latency;
8335 decl_t decl;
8336
8337 max = description->max_insn_reserv_cycles;
8338 for (i = 0; i < description->decls_num; i++)
8339 {
8340 decl = description->decls [i];
8341 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
8342 {
8343 latency = DECL_INSN_RESERV (decl)->default_latency;
8344 if (latency > max)
8345 max = latency;
8346 }
8347 else if (decl->mode == dm_bypass)
8348 {
8349 latency = DECL_BYPASS (decl)->latency;
8350 if (latency > max)
8351 max = latency;
8352 }
8353 }
8354 for (i = 0; (1 << i) <= max; i++)
8355 ;
8356 if (i < 0)
8357 abort ();
8358 fprintf (output_file, "\nint max_insn_queue_index = %d;\n\n", (1 << i) - 1);
8359 }
8360
8361
8362 /* The function outputs switch cases for insn reseravtions using
8363 function *output_automata_list_code. */
8364 static void
8365 output_insn_code_cases (output_automata_list_code)
8366 void (*output_automata_list_code) PARAMS ((automata_list_el_t));
8367 {
8368 decl_t decl, decl2;
8369 int i, j;
8370
8371 for (i = 0; i < description->decls_num; i++)
8372 {
8373 decl = description->decls [i];
8374 if (decl->mode == dm_insn_reserv)
8375 DECL_INSN_RESERV (decl)->processed_p = FALSE;
8376 }
8377 for (i = 0; i < description->decls_num; i++)
8378 {
8379 decl = description->decls [i];
8380 if (decl->mode == dm_insn_reserv
8381 && !DECL_INSN_RESERV (decl)->processed_p)
8382 {
8383 for (j = i; j < description->decls_num; j++)
8384 {
8385 decl2 = description->decls [j];
8386 if (decl2->mode == dm_insn_reserv
8387 && (DECL_INSN_RESERV (decl2)->important_automata_list
8388 == DECL_INSN_RESERV (decl)->important_automata_list))
8389 {
8390 DECL_INSN_RESERV (decl2)->processed_p = TRUE;
8391 fprintf (output_file, " case %d: /* %s */\n",
8392 DECL_INSN_RESERV (decl2)->insn_num,
8393 DECL_INSN_RESERV (decl2)->name);
8394 }
8395 }
8396 (*output_automata_list_code)
8397 (DECL_INSN_RESERV (decl)->important_automata_list);
8398 }
8399 }
8400 }
8401
8402
8403 /* The function outputs a code for evaluation of a minimal delay of
8404 issue of insns which have reservations in given AUTOMATA_LIST. */
8405 static void
8406 output_automata_list_min_issue_delay_code (automata_list)
8407 automata_list_el_t automata_list;
8408 {
8409 automata_list_el_t el;
8410 automaton_t automaton;
8411
8412 for (el = automata_list; el != NULL; el = el->next_automata_list_el)
8413 {
8414 automaton = el->automaton;
8415 fprintf (output_file, "\n %s = ", TEMPORARY_VARIABLE_NAME);
8416 output_min_issue_delay_vect_name (output_file, automaton);
8417 fprintf (output_file,
8418 (automaton->min_issue_delay_table_compression_factor != 1
8419 ? " [(" : " ["));
8420 output_translate_vect_name (output_file, automaton);
8421 fprintf (output_file, " [%s] + ", INTERNAL_INSN_CODE_NAME);
8422 fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
8423 output_chip_member_name (output_file, automaton);
8424 fprintf (output_file, " * %d", automaton->insn_equiv_classes_num);
8425 if (automaton->min_issue_delay_table_compression_factor == 1)
8426 fprintf (output_file, "];\n");
8427 else
8428 {
8429 fprintf (output_file, ") / %d];\n",
8430 automaton->min_issue_delay_table_compression_factor);
8431 fprintf (output_file, " %s = (%s >> (8 - (",
8432 TEMPORARY_VARIABLE_NAME, TEMPORARY_VARIABLE_NAME);
8433 output_translate_vect_name (output_file, automaton);
8434 fprintf
8435 (output_file, " [%s] %% %d + 1) * %d)) & %d;\n",
8436 INTERNAL_INSN_CODE_NAME,
8437 automaton->min_issue_delay_table_compression_factor,
8438 8 / automaton->min_issue_delay_table_compression_factor,
8439 (1 << (8 / automaton->min_issue_delay_table_compression_factor))
8440 - 1);
8441 }
8442 if (el == automata_list)
8443 fprintf (output_file, " %s = %s;\n",
8444 RESULT_VARIABLE_NAME, TEMPORARY_VARIABLE_NAME);
8445 else
8446 {
8447 fprintf (output_file, " if (%s > %s)\n",
8448 TEMPORARY_VARIABLE_NAME, RESULT_VARIABLE_NAME);
8449 fprintf (output_file, " %s = %s;\n",
8450 RESULT_VARIABLE_NAME, TEMPORARY_VARIABLE_NAME);
8451 }
8452 }
8453 fprintf (output_file, " break;\n\n");
8454 }
8455
8456 /* Output function `internal_min_issue_delay'. */
8457 static void
8458 output_internal_min_issue_delay_func ()
8459 {
8460 fprintf (output_file, "static int %s PARAMS ((int, struct %s *));\n",
8461 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, CHIP_NAME);
8462 fprintf (output_file,
8463 "static int\n%s (%s, %s)\n\tint %s;\n\tstruct %s *%s ATTRIBUTE_UNUSED;\n",
8464 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8465 CHIP_PARAMETER_NAME, INTERNAL_INSN_CODE_NAME, CHIP_NAME,
8466 CHIP_PARAMETER_NAME);
8467 fprintf (output_file, "{\n int %s ATTRIBUTE_UNUSED;\n int %s = -1;\n",
8468 TEMPORARY_VARIABLE_NAME, RESULT_VARIABLE_NAME);
8469 fprintf (output_file, "\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
8470 output_insn_code_cases (output_automata_list_min_issue_delay_code);
8471 fprintf (output_file,
8472 "\n default:\n %s = -1;\n break;\n }\n",
8473 RESULT_VARIABLE_NAME);
8474 fprintf (output_file, " return %s;\n", RESULT_VARIABLE_NAME);
8475 fprintf (output_file, "}\n\n");
8476 }
8477
8478 /* The function outputs a code changing state after issue of insns
8479 which have reservations in given AUTOMATA_LIST. */
8480 static void
8481 output_automata_list_transition_code (automata_list)
8482 automata_list_el_t automata_list;
8483 {
8484 automata_list_el_t el, next_el;
8485
8486 fprintf (output_file, " {\n");
8487 if (automata_list != NULL && automata_list->next_automata_list_el != NULL)
8488 for (el = automata_list;; el = next_el)
8489 {
8490 next_el = el->next_automata_list_el;
8491 if (next_el == NULL)
8492 break;
8493 fprintf (output_file, " ");
8494 output_state_member_type (output_file, el->automaton);
8495 fprintf (output_file, " ");
8496 output_temp_chip_member_name (output_file, el->automaton);
8497 fprintf (output_file, ";\n");
8498 }
8499 for (el = automata_list; el != NULL; el = el->next_automata_list_el)
8500 if (comb_vect_p (el->automaton->trans_table))
8501 {
8502 fprintf (output_file, "\n %s = ", TEMPORARY_VARIABLE_NAME);
8503 output_trans_base_vect_name (output_file, el->automaton);
8504 fprintf (output_file, " [%s->", CHIP_PARAMETER_NAME);
8505 output_chip_member_name (output_file, el->automaton);
8506 fprintf (output_file, "] + ");
8507 output_translate_vect_name (output_file, el->automaton);
8508 fprintf (output_file, " [%s];\n", INTERNAL_INSN_CODE_NAME);
8509 fprintf (output_file, " if (");
8510 output_trans_check_vect_name (output_file, el->automaton);
8511 fprintf (output_file, " [%s] != %s->",
8512 TEMPORARY_VARIABLE_NAME, CHIP_PARAMETER_NAME);
8513 output_chip_member_name (output_file, el->automaton);
8514 fprintf (output_file, ")\n");
8515 fprintf (output_file, " return %s (%s, %s);\n",
8516 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8517 CHIP_PARAMETER_NAME);
8518 fprintf (output_file, " else\n");
8519 fprintf (output_file, " ");
8520 if (el->next_automata_list_el != NULL)
8521 output_temp_chip_member_name (output_file, el->automaton);
8522 else
8523 {
8524 fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
8525 output_chip_member_name (output_file, el->automaton);
8526 }
8527 fprintf (output_file, " = ");
8528 output_trans_comb_vect_name (output_file, el->automaton);
8529 fprintf (output_file, " [%s];\n", TEMPORARY_VARIABLE_NAME);
8530 }
8531 else
8532 {
8533 fprintf (output_file, "\n %s = ", TEMPORARY_VARIABLE_NAME);
8534 output_trans_full_vect_name (output_file, el->automaton);
8535 fprintf (output_file, " [");
8536 output_translate_vect_name (output_file, el->automaton);
8537 fprintf (output_file, " [%s] + ", INTERNAL_INSN_CODE_NAME);
8538 fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
8539 output_chip_member_name (output_file, el->automaton);
8540 fprintf (output_file, " * %d];\n",
8541 el->automaton->insn_equiv_classes_num);
8542 fprintf (output_file, " if (%s >= %d)\n",
8543 TEMPORARY_VARIABLE_NAME, el->automaton->achieved_states_num);
8544 fprintf (output_file, " return %s (%s, %s);\n",
8545 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8546 CHIP_PARAMETER_NAME);
8547 fprintf (output_file, " else\n ");
8548 if (el->next_automata_list_el != NULL)
8549 output_temp_chip_member_name (output_file, el->automaton);
8550 else
8551 {
8552 fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
8553 output_chip_member_name (output_file, el->automaton);
8554 }
8555 fprintf (output_file, " = %s;\n", TEMPORARY_VARIABLE_NAME);
8556 }
8557 if (automata_list != NULL && automata_list->next_automata_list_el != NULL)
8558 for (el = automata_list;; el = next_el)
8559 {
8560 next_el = el->next_automata_list_el;
8561 if (next_el == NULL)
8562 break;
8563 fprintf (output_file, " %s->", CHIP_PARAMETER_NAME);
8564 output_chip_member_name (output_file, el->automaton);
8565 fprintf (output_file, " = ");
8566 output_temp_chip_member_name (output_file, el->automaton);
8567 fprintf (output_file, ";\n");
8568 }
8569 fprintf (output_file, " return -1;\n");
8570 fprintf (output_file, " }\n");
8571 }
8572
8573 /* Output function `internal_state_transition'. */
8574 static void
8575 output_internal_trans_func ()
8576 {
8577 fprintf (output_file, "static int %s PARAMS ((int, struct %s *));\n",
8578 INTERNAL_TRANSITION_FUNC_NAME, CHIP_NAME);
8579 fprintf (output_file,
8580 "static int\n%s (%s, %s)\n\tint %s;\n\tstruct %s *%s ATTRIBUTE_UNUSED;\n",
8581 INTERNAL_TRANSITION_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8582 CHIP_PARAMETER_NAME, INTERNAL_INSN_CODE_NAME,
8583 CHIP_NAME, CHIP_PARAMETER_NAME);
8584 fprintf (output_file, "{\n int %s ATTRIBUTE_UNUSED;\n", TEMPORARY_VARIABLE_NAME);
8585 fprintf (output_file, "\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
8586 output_insn_code_cases (output_automata_list_transition_code);
8587 fprintf (output_file, "\n default:\n return -1;\n }\n");
8588 fprintf (output_file, "}\n\n");
8589 }
8590
8591 /* Output code
8592
8593 if (insn != 0)
8594 {
8595 insn_code = dfa_insn_code (insn);
8596 if (insn_code > DFA__ADVANCE_CYCLE)
8597 return code;
8598 }
8599 else
8600 insn_code = DFA__ADVANCE_CYCLE;
8601
8602 where insn denotes INSN_NAME, insn_code denotes INSN_CODE_NAME, and
8603 code denotes CODE. */
8604 static void
8605 output_internal_insn_code_evaluation (insn_name, insn_code_name, code)
8606 const char *insn_name;
8607 const char *insn_code_name;
8608 int code;
8609 {
8610 fprintf (output_file, "\n if (%s != 0)\n {\n", insn_name);
8611 fprintf (output_file, " %s = %s (%s);\n", insn_code_name,
8612 DFA_INSN_CODE_FUNC_NAME, insn_name);
8613 fprintf (output_file, " if (%s > %s)\n return %d;\n",
8614 insn_code_name, ADVANCE_CYCLE_VALUE_NAME, code);
8615 fprintf (output_file, " }\n else\n %s = %s;\n\n",
8616 insn_code_name, ADVANCE_CYCLE_VALUE_NAME);
8617 }
8618
8619
8620 /* The function outputs function `dfa_insn_code'. */
8621 static void
8622 output_dfa_insn_code_func ()
8623 {
8624 fprintf (output_file, "#ifdef __GNUC__\n__inline__\n#endif\n");
8625 fprintf (output_file, "static int %s PARAMS ((rtx));\n",
8626 DFA_INSN_CODE_FUNC_NAME);
8627 fprintf (output_file, "static int\n%s (%s)\n\trtx %s;\n",
8628 DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME, INSN_PARAMETER_NAME);
8629 fprintf (output_file, "{\n int %s;\n int %s;\n\n",
8630 INTERNAL_INSN_CODE_NAME, TEMPORARY_VARIABLE_NAME);
8631 fprintf (output_file, " if (INSN_UID (%s) >= %s)\n {\n",
8632 INSN_PARAMETER_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
8633 fprintf (output_file, " %s = %s;\n %s = 2 * INSN_UID (%s);\n",
8634 TEMPORARY_VARIABLE_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
8635 DFA_INSN_CODES_LENGTH_VARIABLE_NAME, INSN_PARAMETER_NAME);
8636 fprintf (output_file, " %s = xrealloc (%s, %s * sizeof (int));\n",
8637 DFA_INSN_CODES_VARIABLE_NAME, DFA_INSN_CODES_VARIABLE_NAME,
8638 DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
8639 fprintf (output_file,
8640 " for (; %s < %s; %s++)\n %s [%s] = -1;\n }\n",
8641 TEMPORARY_VARIABLE_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
8642 TEMPORARY_VARIABLE_NAME, DFA_INSN_CODES_VARIABLE_NAME,
8643 TEMPORARY_VARIABLE_NAME);
8644 fprintf (output_file, " if ((%s = %s [INSN_UID (%s)]) < 0)\n {\n",
8645 INTERNAL_INSN_CODE_NAME, DFA_INSN_CODES_VARIABLE_NAME,
8646 INSN_PARAMETER_NAME);
8647 fprintf (output_file, " %s = %s (%s);\n", INTERNAL_INSN_CODE_NAME,
8648 INTERNAL_DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME);
8649 fprintf (output_file, " %s [INSN_UID (%s)] = %s;\n",
8650 DFA_INSN_CODES_VARIABLE_NAME, INSN_PARAMETER_NAME,
8651 INTERNAL_INSN_CODE_NAME);
8652 fprintf (output_file, " }\n return %s;\n}\n\n",
8653 INTERNAL_INSN_CODE_NAME);
8654 }
8655
8656 /* The function outputs PHR interface function `state_transition'. */
8657 static void
8658 output_trans_func ()
8659 {
8660 fprintf (output_file, "int\n%s (%s, %s)\n\t%s %s;\n\trtx %s;\n",
8661 TRANSITION_FUNC_NAME, STATE_NAME, INSN_PARAMETER_NAME,
8662 STATE_TYPE_NAME, STATE_NAME, INSN_PARAMETER_NAME);
8663 fprintf (output_file, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME);
8664 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
8665 INTERNAL_INSN_CODE_NAME, -1);
8666 fprintf (output_file, " return %s (%s, %s);\n}\n\n",
8667 INTERNAL_TRANSITION_FUNC_NAME, INTERNAL_INSN_CODE_NAME, STATE_NAME);
8668 }
8669
8670 /* The function outputs a code for evaluation of alternative states
8671 number for insns which have reservations in given AUTOMATA_LIST. */
8672 static void
8673 output_automata_list_state_alts_code (automata_list)
8674 automata_list_el_t automata_list;
8675 {
8676 automata_list_el_t el;
8677 automaton_t automaton;
8678
8679 fprintf (output_file, " {\n");
8680 for (el = automata_list; el != NULL; el = el->next_automata_list_el)
8681 if (comb_vect_p (el->automaton->state_alts_table))
8682 {
8683 fprintf (output_file, " int %s;\n", TEMPORARY_VARIABLE_NAME);
8684 break;
8685 }
8686 for (el = automata_list; el != NULL; el = el->next_automata_list_el)
8687 {
8688 automaton = el->automaton;
8689 if (comb_vect_p (automaton->state_alts_table))
8690 {
8691 fprintf (output_file, "\n %s = ", TEMPORARY_VARIABLE_NAME);
8692 output_state_alts_base_vect_name (output_file, automaton);
8693 fprintf (output_file, " [%s->", CHIP_PARAMETER_NAME);
8694 output_chip_member_name (output_file, automaton);
8695 fprintf (output_file, "] + ");
8696 output_translate_vect_name (output_file, automaton);
8697 fprintf (output_file, " [%s];\n", INTERNAL_INSN_CODE_NAME);
8698 fprintf (output_file, " if (");
8699 output_state_alts_check_vect_name (output_file, automaton);
8700 fprintf (output_file, " [%s] != %s->",
8701 TEMPORARY_VARIABLE_NAME, CHIP_PARAMETER_NAME);
8702 output_chip_member_name (output_file, automaton);
8703 fprintf (output_file, ")\n");
8704 fprintf (output_file, " return 0;\n");
8705 fprintf (output_file, " else\n");
8706 fprintf (output_file,
8707 (el == automata_list
8708 ? " %s = " : " %s += "),
8709 RESULT_VARIABLE_NAME);
8710 output_state_alts_comb_vect_name (output_file, automaton);
8711 fprintf (output_file, " [%s];\n", TEMPORARY_VARIABLE_NAME);
8712 }
8713 else
8714 {
8715 fprintf (output_file,
8716 (el == automata_list
8717 ? "\n %s = " : " %s += "),
8718 RESULT_VARIABLE_NAME);
8719 output_state_alts_full_vect_name (output_file, automaton);
8720 fprintf (output_file, " [");
8721 output_translate_vect_name (output_file, automaton);
8722 fprintf (output_file, " [%s] + ", INTERNAL_INSN_CODE_NAME);
8723 fprintf (output_file, "%s->", CHIP_PARAMETER_NAME);
8724 output_chip_member_name (output_file, automaton);
8725 fprintf (output_file, " * %d];\n",
8726 automaton->insn_equiv_classes_num);
8727 }
8728 }
8729 fprintf (output_file, " break;\n }\n\n");
8730 }
8731
8732 /* Output function `internal_state_alts'. */
8733 static void
8734 output_internal_state_alts_func ()
8735 {
8736 fprintf (output_file, "static int %s PARAMS ((int, struct %s *));\n",
8737 INTERNAL_STATE_ALTS_FUNC_NAME, CHIP_NAME);
8738 fprintf (output_file,
8739 "static int\n%s (%s, %s)\n\tint %s;\n\tstruct %s *%s;\n",
8740 INTERNAL_STATE_ALTS_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8741 CHIP_PARAMETER_NAME, INTERNAL_INSN_CODE_NAME, CHIP_NAME,
8742 CHIP_PARAMETER_NAME);
8743 fprintf (output_file, "{\n int %s;\n", RESULT_VARIABLE_NAME);
8744 fprintf (output_file, "\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
8745 output_insn_code_cases (output_automata_list_state_alts_code);
8746 fprintf (output_file,
8747 "\n default:\n %s = 0;\n break;\n }\n",
8748 RESULT_VARIABLE_NAME);
8749 fprintf (output_file, " return %s;\n", RESULT_VARIABLE_NAME);
8750 fprintf (output_file, "}\n\n");
8751 }
8752
8753 /* The function outputs PHR interface function `state_alts'. */
8754 static void
8755 output_state_alts_func ()
8756 {
8757 fprintf (output_file, "int\n%s (%s, %s)\n\t%s %s;\n\trtx %s;\n",
8758 STATE_ALTS_FUNC_NAME, STATE_NAME, INSN_PARAMETER_NAME,
8759 STATE_TYPE_NAME, STATE_NAME, INSN_PARAMETER_NAME);
8760 fprintf (output_file, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME);
8761 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
8762 INTERNAL_INSN_CODE_NAME, 0);
8763 fprintf (output_file, " return %s (%s, %s);\n}\n\n",
8764 INTERNAL_STATE_ALTS_FUNC_NAME, INTERNAL_INSN_CODE_NAME, STATE_NAME);
8765 }
8766
8767 /* Output function `min_issue_delay'. */
8768 static void
8769 output_min_issue_delay_func ()
8770 {
8771 fprintf (output_file, "int\n%s (%s, %s)\n\t%s %s;\n\trtx %s;\n",
8772 MIN_ISSUE_DELAY_FUNC_NAME, STATE_NAME, INSN_PARAMETER_NAME,
8773 STATE_TYPE_NAME, STATE_NAME, INSN_PARAMETER_NAME);
8774 fprintf (output_file, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME);
8775 fprintf (output_file, "\n if (%s != 0)\n {\n", INSN_PARAMETER_NAME);
8776 fprintf (output_file, " %s = %s (%s);\n", INTERNAL_INSN_CODE_NAME,
8777 DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME);
8778 fprintf (output_file, " if (%s > %s)\n return 0;\n",
8779 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8780 fprintf (output_file, " }\n else\n %s = %s;\n",
8781 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8782 fprintf (output_file, "\n return %s (%s, %s);\n",
8783 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8784 STATE_NAME);
8785 fprintf (output_file, "}\n\n");
8786 }
8787
8788 /* Output function `internal_dead_lock'. */
8789 static void
8790 output_internal_dead_lock_func ()
8791 {
8792 automaton_t automaton;
8793
8794 fprintf (output_file, "static int %s PARAMS ((struct %s *));\n",
8795 INTERNAL_DEAD_LOCK_FUNC_NAME, CHIP_NAME);
8796 fprintf (output_file, "static int\n%s (%s)\n\tstruct %s *%s;\n",
8797 INTERNAL_DEAD_LOCK_FUNC_NAME, CHIP_PARAMETER_NAME, CHIP_NAME,
8798 CHIP_PARAMETER_NAME);
8799 fprintf (output_file, "{\n");
8800 for (automaton = description->first_automaton;
8801 automaton != NULL;
8802 automaton = automaton->next_automaton)
8803 {
8804 fprintf (output_file, " if (");
8805 output_dead_lock_vect_name (output_file, automaton);
8806 fprintf (output_file, " [%s->", CHIP_PARAMETER_NAME);
8807 output_chip_member_name (output_file, automaton);
8808 fprintf (output_file, "])\n return 1/* TRUE */;\n");
8809 }
8810 fprintf (output_file, " return 0/* FALSE */;\n}\n\n");
8811 }
8812
8813 /* The function outputs PHR interface function `state_dead_lock_p'. */
8814 static void
8815 output_dead_lock_func ()
8816 {
8817 fprintf (output_file, "int\n%s (%s)\n\t%s %s;\n",
8818 DEAD_LOCK_FUNC_NAME, STATE_NAME, STATE_TYPE_NAME, STATE_NAME);
8819 fprintf (output_file, "{\n return %s (%s);\n}\n\n",
8820 INTERNAL_DEAD_LOCK_FUNC_NAME, STATE_NAME);
8821 }
8822
8823 /* Output function `internal_reset'. */
8824 static void
8825 output_internal_reset_func ()
8826 {
8827 fprintf (output_file, "static void %s PARAMS ((struct %s *));\n",
8828 INTERNAL_RESET_FUNC_NAME, CHIP_NAME);
8829 fprintf (output_file, "static void\n%s (%s)\n\tstruct %s *%s;\n",
8830 INTERNAL_RESET_FUNC_NAME, CHIP_PARAMETER_NAME,
8831 CHIP_NAME, CHIP_PARAMETER_NAME);
8832 fprintf (output_file, "{\n memset (%s, 0, sizeof (struct %s));\n}\n\n",
8833 CHIP_PARAMETER_NAME, CHIP_NAME);
8834 }
8835
8836 /* The function outputs PHR interface function `state_size'. */
8837 static void
8838 output_size_func ()
8839 {
8840 fprintf (output_file, "int\n%s ()\n", SIZE_FUNC_NAME);
8841 fprintf (output_file, "{\n return sizeof (struct %s);\n}\n\n", CHIP_NAME);
8842 }
8843
8844 /* The function outputs PHR interface function `state_reset'. */
8845 static void
8846 output_reset_func ()
8847 {
8848 fprintf (output_file, "void\n%s (%s)\n\t %s %s;\n",
8849 RESET_FUNC_NAME, STATE_NAME, STATE_TYPE_NAME, STATE_NAME);
8850 fprintf (output_file, "{\n %s (%s);\n}\n\n", INTERNAL_RESET_FUNC_NAME,
8851 STATE_NAME);
8852 }
8853
8854 /* Output function `min_insn_conflict_delay'. */
8855 static void
8856 output_min_insn_conflict_delay_func ()
8857 {
8858 fprintf (output_file,
8859 "int\n%s (%s, %s, %s)\n\t%s %s;\n\trtx %s;\n\trtx %s;\n",
8860 MIN_INSN_CONFLICT_DELAY_FUNC_NAME,
8861 STATE_NAME, INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME,
8862 STATE_TYPE_NAME, STATE_NAME,
8863 INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
8864 fprintf (output_file, "{\n struct %s %s;\n int %s, %s;\n",
8865 CHIP_NAME, CHIP_NAME, INTERNAL_INSN_CODE_NAME,
8866 INTERNAL_INSN2_CODE_NAME);
8867 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
8868 INTERNAL_INSN_CODE_NAME, 0);
8869 output_internal_insn_code_evaluation (INSN2_PARAMETER_NAME,
8870 INTERNAL_INSN2_CODE_NAME, 0);
8871 fprintf (output_file, " memcpy (&%s, %s, sizeof (%s));\n",
8872 CHIP_NAME, STATE_NAME, CHIP_NAME);
8873 fprintf (output_file, " %s (&%s);\n", INTERNAL_RESET_FUNC_NAME, CHIP_NAME);
8874 fprintf (output_file, " if (%s (%s, &%s) > 0)\n abort ();\n",
8875 INTERNAL_TRANSITION_FUNC_NAME, INTERNAL_INSN_CODE_NAME, CHIP_NAME);
8876 fprintf (output_file, " return %s (%s, &%s);\n",
8877 INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN2_CODE_NAME,
8878 CHIP_NAME);
8879 fprintf (output_file, "}\n\n");
8880 }
8881
8882 /* Output function `internal_insn_latency'. */
8883 static void
8884 output_internal_insn_latency_func ()
8885 {
8886 decl_t decl;
8887 struct bypass_decl *bypass;
8888 int i;
8889
8890 fprintf (output_file, "static int %s PARAMS ((int, int, rtx, rtx));\n",
8891 INTERNAL_INSN_LATENCY_FUNC_NAME);
8892 fprintf (output_file, "static int\n%s (%s, %s, %s, %s)",
8893 INTERNAL_INSN_LATENCY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
8894 INTERNAL_INSN2_CODE_NAME, INSN_PARAMETER_NAME,
8895 INSN2_PARAMETER_NAME);
8896 fprintf (output_file, "\n\tint %s;\n\tint %s;\n",
8897 INTERNAL_INSN_CODE_NAME, INTERNAL_INSN2_CODE_NAME);
8898 fprintf (output_file,
8899 "\trtx %s ATTRIBUTE_UNUSED;\n\trtx %s ATTRIBUTE_UNUSED;\n",
8900 INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
8901 fprintf (output_file, "{\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
8902 for (i = 0; i < description->decls_num; i++)
8903 {
8904 decl = description->decls [i];
8905 if (decl->mode == dm_insn_reserv)
8906 {
8907 fprintf (output_file, " case %d:\n",
8908 DECL_INSN_RESERV (decl)->insn_num);
8909 if (DECL_INSN_RESERV (decl)->bypass_list == NULL)
8910 fprintf (output_file, " return (%s != %s ? %d : 0);\n",
8911 INTERNAL_INSN2_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME,
8912 DECL_INSN_RESERV (decl)->default_latency);
8913 else
8914 {
8915 fprintf (output_file, " switch (%s)\n {\n",
8916 INTERNAL_INSN2_CODE_NAME);
8917 for (bypass = DECL_INSN_RESERV (decl)->bypass_list;
8918 bypass != NULL;
8919 bypass = bypass->next)
8920 {
8921 fprintf (output_file, " case %d:\n",
8922 bypass->in_insn_reserv->insn_num);
8923 if (bypass->bypass_guard_name == NULL)
8924 fprintf (output_file, " return %d;\n",
8925 bypass->latency);
8926 else
8927 fprintf (output_file,
8928 " return (%s (%s, %s) ? %d : %d);\n",
8929 bypass->bypass_guard_name, INSN_PARAMETER_NAME,
8930 INSN2_PARAMETER_NAME, bypass->latency,
8931 DECL_INSN_RESERV (decl)->default_latency);
8932 }
8933 fprintf (output_file, " default:\n");
8934 fprintf (output_file,
8935 " return (%s != %s ? %d : 0);\n }\n",
8936 INTERNAL_INSN2_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME,
8937 DECL_INSN_RESERV (decl)->default_latency);
8938
8939 }
8940 }
8941 }
8942 fprintf (output_file, " default:\n return 0;\n }\n}\n\n");
8943 }
8944
8945 /* The function outputs PHR interface function `insn_latency'. */
8946 static void
8947 output_insn_latency_func ()
8948 {
8949 fprintf (output_file, "int\n%s (%s, %s)\n\trtx %s;\n\trtx %s;\n",
8950 INSN_LATENCY_FUNC_NAME, INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME,
8951 INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
8952 fprintf (output_file, "{\n int %s, %s;\n",
8953 INTERNAL_INSN_CODE_NAME, INTERNAL_INSN2_CODE_NAME);
8954 output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
8955 INTERNAL_INSN_CODE_NAME, 0);
8956 output_internal_insn_code_evaluation (INSN2_PARAMETER_NAME,
8957 INTERNAL_INSN2_CODE_NAME, 0);
8958 fprintf (output_file, " return %s (%s, %s, %s, %s);\n}\n\n",
8959 INTERNAL_INSN_LATENCY_FUNC_NAME,
8960 INTERNAL_INSN_CODE_NAME, INTERNAL_INSN2_CODE_NAME,
8961 INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
8962 }
8963
8964 /* The function outputs PHR interface function `print_reservation'. */
8965 static void
8966 output_print_reservation_func ()
8967 {
8968 decl_t decl;
8969 int i;
8970
8971 fprintf (output_file, "void\n%s (%s, %s)\n\tFILE *%s;\n\trtx %s;\n",
8972 PRINT_RESERVATION_FUNC_NAME, FILE_PARAMETER_NAME,
8973 INSN_PARAMETER_NAME, FILE_PARAMETER_NAME,
8974 INSN_PARAMETER_NAME);
8975 fprintf (output_file, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME);
8976 fprintf (output_file, "\n if (%s != 0)\n {\n", INSN_PARAMETER_NAME);
8977 fprintf (output_file, " %s = %s (%s);\n",
8978 INTERNAL_INSN_CODE_NAME, DFA_INSN_CODE_FUNC_NAME,
8979 INSN_PARAMETER_NAME);
8980 fprintf (output_file, " if (%s > %s)\n",
8981 INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
8982 fprintf (output_file, " {\n fprintf (%s, \"%s\");\n",
8983 FILE_PARAMETER_NAME, NOTHING_NAME);
8984 fprintf (output_file, " return;\n }\n");
8985 fprintf (output_file, " }\n else\n");
8986 fprintf (output_file,
8987 " {\n fprintf (%s, \"%s\");\n return;\n }\n",
8988 FILE_PARAMETER_NAME, NOTHING_NAME);
8989 fprintf (output_file, " switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
8990 for (i = 0; i < description->decls_num; i++)
8991 {
8992 decl = description->decls [i];
8993 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
8994 {
8995 fprintf (output_file,
8996 " case %d:\n", DECL_INSN_RESERV (decl)->insn_num);
8997 fprintf (output_file,
8998 " fprintf (%s, \"%s\");\n break;\n",
8999 FILE_PARAMETER_NAME,
9000 regexp_representation (DECL_INSN_RESERV (decl)->regexp));
9001 finish_regexp_representation ();
9002 }
9003 }
9004 fprintf (output_file, " default:\n fprintf (%s, \"%s\");\n }\n",
9005 FILE_PARAMETER_NAME, NOTHING_NAME);
9006 fprintf (output_file, "}\n\n");
9007 }
9008
9009 /* The following function is used to sort unit declaration by their
9010 names. */
9011 static int
9012 units_cmp (unit1, unit2)
9013 const void *unit1, *unit2;
9014 {
9015 const unit_decl_t u1 = *(unit_decl_t *) unit1;
9016 const unit_decl_t u2 = *(unit_decl_t *) unit2;
9017
9018 return strcmp (u1->name, u2->name);
9019 }
9020
9021 /* The following macro value is name of struct containing unit name
9022 and unit code. */
9023 #define NAME_CODE_STRUCT_NAME "name_code"
9024
9025 /* The following macro value is name of table of struct name_code. */
9026 #define NAME_CODE_TABLE_NAME "name_code_table"
9027
9028 /* The following macro values are member names for struct name_code. */
9029 #define NAME_MEMBER_NAME "name"
9030 #define CODE_MEMBER_NAME "code"
9031
9032 /* The following macro values are local variable names for function
9033 `get_cpu_unit_code'. */
9034 #define CMP_VARIABLE_NAME "cmp"
9035 #define LOW_VARIABLE_NAME "l"
9036 #define MIDDLE_VARIABLE_NAME "m"
9037 #define HIGH_VARIABLE_NAME "h"
9038
9039 /* The following function outputs function to obtain internal cpu unit
9040 code by the cpu unit name. */
9041 static void
9042 output_get_cpu_unit_code_func ()
9043 {
9044 int i;
9045 unit_decl_t *units;
9046
9047 fprintf (output_file, "int\n%s (%s)\n\tconst char *%s;\n",
9048 GET_CPU_UNIT_CODE_FUNC_NAME, CPU_UNIT_NAME_PARAMETER_NAME,
9049 CPU_UNIT_NAME_PARAMETER_NAME);
9050 fprintf (output_file, "{\n struct %s {const char *%s; int %s;};\n",
9051 NAME_CODE_STRUCT_NAME, NAME_MEMBER_NAME, CODE_MEMBER_NAME);
9052 fprintf (output_file, " int %s, %s, %s, %s;\n", CMP_VARIABLE_NAME,
9053 LOW_VARIABLE_NAME, MIDDLE_VARIABLE_NAME, HIGH_VARIABLE_NAME);
9054 fprintf (output_file, " static struct %s %s [] =\n {\n",
9055 NAME_CODE_STRUCT_NAME, NAME_CODE_TABLE_NAME);
9056 units = (unit_decl_t *) xmalloc (sizeof (unit_decl_t)
9057 * description->units_num);
9058 memcpy (units, units_array, sizeof (unit_decl_t) * description->units_num);
9059 qsort (units, description->units_num, sizeof (unit_decl_t), units_cmp);
9060 for (i = 0; i < description->units_num; i++)
9061 if (units [i]->query_p)
9062 fprintf (output_file, " {\"%s\", %d},\n",
9063 units[i]->name, units[i]->query_num);
9064 fprintf (output_file, " };\n\n");
9065 fprintf (output_file, " /* The following is binary search: */\n");
9066 fprintf (output_file, " %s = 0;\n", LOW_VARIABLE_NAME);
9067 fprintf (output_file, " %s = sizeof (%s) / sizeof (struct %s) - 1;\n",
9068 HIGH_VARIABLE_NAME, NAME_CODE_TABLE_NAME, NAME_CODE_STRUCT_NAME);
9069 fprintf (output_file, " while (%s <= %s)\n {\n",
9070 LOW_VARIABLE_NAME, HIGH_VARIABLE_NAME);
9071 fprintf (output_file, " %s = (%s + %s) / 2;\n",
9072 MIDDLE_VARIABLE_NAME, LOW_VARIABLE_NAME, HIGH_VARIABLE_NAME);
9073 fprintf (output_file, " %s = strcmp (%s, %s [%s].%s);\n",
9074 CMP_VARIABLE_NAME, CPU_UNIT_NAME_PARAMETER_NAME,
9075 NAME_CODE_TABLE_NAME, MIDDLE_VARIABLE_NAME, NAME_MEMBER_NAME);
9076 fprintf (output_file, " if (%s < 0)\n", CMP_VARIABLE_NAME);
9077 fprintf (output_file, " %s = %s - 1;\n",
9078 HIGH_VARIABLE_NAME, MIDDLE_VARIABLE_NAME);
9079 fprintf (output_file, " else if (%s > 0)\n", CMP_VARIABLE_NAME);
9080 fprintf (output_file, " %s = %s + 1;\n",
9081 LOW_VARIABLE_NAME, MIDDLE_VARIABLE_NAME);
9082 fprintf (output_file, " else\n");
9083 fprintf (output_file, " return %s [%s].%s;\n }\n",
9084 NAME_CODE_TABLE_NAME, MIDDLE_VARIABLE_NAME, CODE_MEMBER_NAME);
9085 fprintf (output_file, " return -1;\n}\n\n");
9086 free (units);
9087 }
9088
9089 /* The following function outputs function to check reservation of cpu
9090 unit (its internal code will be passed as the function argument) in
9091 given cpu state. */
9092 static void
9093 output_cpu_unit_reservation_p ()
9094 {
9095 automaton_t automaton;
9096
9097 fprintf (output_file, "int\n%s (%s, %s)\n\t%s %s;\n\tint %s;\n",
9098 CPU_UNIT_RESERVATION_P_FUNC_NAME, STATE_NAME,
9099 CPU_CODE_PARAMETER_NAME, STATE_TYPE_NAME, STATE_NAME,
9100 CPU_CODE_PARAMETER_NAME);
9101 fprintf (output_file, "{\n if (%s < 0 || %s >= %d)\n abort ();\n",
9102 CPU_CODE_PARAMETER_NAME, CPU_CODE_PARAMETER_NAME,
9103 description->query_units_num);
9104 for (automaton = description->first_automaton;
9105 automaton != NULL;
9106 automaton = automaton->next_automaton)
9107 {
9108 fprintf (output_file, " if ((");
9109 output_reserved_units_table_name (output_file, automaton);
9110 fprintf (output_file, " [((struct %s *) %s)->", CHIP_NAME, STATE_NAME);
9111 output_chip_member_name (output_file, automaton);
9112 fprintf (output_file, " * %d + %s / 8] >> (%s %% 8)) & 1)\n",
9113 (description->query_units_num + 7) / 8,
9114 CPU_CODE_PARAMETER_NAME, CPU_CODE_PARAMETER_NAME);
9115 fprintf (output_file, " return 1;\n");
9116 }
9117 fprintf (output_file, " return 0;\n}\n\n");
9118 }
9119
9120 /* The function outputs PHR interface function `dfa_clean_insn_cache'. */
9121 static void
9122 output_dfa_clean_insn_cache_func ()
9123 {
9124 fprintf (output_file,
9125 "void\n%s ()\n{\n int %s;\n\n",
9126 DFA_CLEAN_INSN_CACHE_FUNC_NAME, I_VARIABLE_NAME);
9127 fprintf (output_file,
9128 " for (%s = 0; %s < %s; %s++)\n %s [%s] = -1;\n}\n\n",
9129 I_VARIABLE_NAME, I_VARIABLE_NAME,
9130 DFA_INSN_CODES_LENGTH_VARIABLE_NAME, I_VARIABLE_NAME,
9131 DFA_INSN_CODES_VARIABLE_NAME, I_VARIABLE_NAME);
9132 }
9133
9134 /* The function outputs PHR interface function `dfa_start'. */
9135 static void
9136 output_dfa_start_func ()
9137 {
9138 fprintf (output_file,
9139 "void\n%s ()\n{\n %s = get_max_uid ();\n",
9140 DFA_START_FUNC_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
9141 fprintf (output_file, " %s = (int *) xmalloc (%s * sizeof (int));\n",
9142 DFA_INSN_CODES_VARIABLE_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
9143 fprintf (output_file, " %s ();\n}\n\n", DFA_CLEAN_INSN_CACHE_FUNC_NAME);
9144 }
9145
9146 /* The function outputs PHR interface function `dfa_finish'. */
9147 static void
9148 output_dfa_finish_func ()
9149 {
9150 fprintf (output_file, "void\n%s ()\n{\n free (%s);\n}\n\n",
9151 DFA_FINISH_FUNC_NAME, DFA_INSN_CODES_VARIABLE_NAME);
9152 }
9153
9154 \f
9155
9156 /* The page contains code for output description file (readable
9157 representation of original description and generated DFA(s). */
9158
9159 /* The function outputs string representation of IR reservation. */
9160 static void
9161 output_regexp (regexp)
9162 regexp_t regexp;
9163 {
9164 fprintf (output_description_file, "%s", regexp_representation (regexp));
9165 finish_regexp_representation ();
9166 }
9167
9168 /* Output names of units in LIST separated by comma. */
9169 static void
9170 output_unit_set_el_list (list)
9171 unit_set_el_t list;
9172 {
9173 unit_set_el_t el;
9174
9175 for (el = list; el != NULL; el = el->next_unit_set_el)
9176 {
9177 if (el != list)
9178 fprintf (output_description_file, ", ");
9179 fprintf (output_description_file, "%s", el->unit_decl->name);
9180 }
9181 }
9182
9183 /* Output patterns in LIST separated by comma. */
9184 static void
9185 output_pattern_set_el_list (list)
9186 pattern_set_el_t list;
9187 {
9188 pattern_set_el_t el;
9189 int i;
9190
9191 for (el = list; el != NULL; el = el->next_pattern_set_el)
9192 {
9193 if (el != list)
9194 fprintf (output_description_file, ", ");
9195 for (i = 0; i < el->units_num; i++)
9196 fprintf (output_description_file, (i == 0 ? "%s" : " %s"),
9197 el->unit_decls [i]->name);
9198 }
9199 }
9200
9201 /* The function outputs string representation of IR define_reservation
9202 and define_insn_reservation. */
9203 static void
9204 output_description ()
9205 {
9206 decl_t decl;
9207 int i;
9208
9209 for (i = 0; i < description->decls_num; i++)
9210 {
9211 decl = description->decls [i];
9212 if (decl->mode == dm_unit)
9213 {
9214 if (DECL_UNIT (decl)->excl_list != NULL)
9215 {
9216 fprintf (output_description_file, "unit %s exlusion_set: ",
9217 DECL_UNIT (decl)->name);
9218 output_unit_set_el_list (DECL_UNIT (decl)->excl_list);
9219 fprintf (output_description_file, "\n");
9220 }
9221 if (DECL_UNIT (decl)->presence_list != NULL)
9222 {
9223 fprintf (output_description_file, "unit %s presence_set: ",
9224 DECL_UNIT (decl)->name);
9225 output_pattern_set_el_list (DECL_UNIT (decl)->presence_list);
9226 fprintf (output_description_file, "\n");
9227 }
9228 if (DECL_UNIT (decl)->final_presence_list != NULL)
9229 {
9230 fprintf (output_description_file, "unit %s final_presence_set: ",
9231 DECL_UNIT (decl)->name);
9232 output_pattern_set_el_list
9233 (DECL_UNIT (decl)->final_presence_list);
9234 fprintf (output_description_file, "\n");
9235 }
9236 if (DECL_UNIT (decl)->absence_list != NULL)
9237 {
9238 fprintf (output_description_file, "unit %s absence_set: ",
9239 DECL_UNIT (decl)->name);
9240 output_pattern_set_el_list (DECL_UNIT (decl)->absence_list);
9241 fprintf (output_description_file, "\n");
9242 }
9243 if (DECL_UNIT (decl)->final_absence_list != NULL)
9244 {
9245 fprintf (output_description_file, "unit %s final_absence_set: ",
9246 DECL_UNIT (decl)->name);
9247 output_pattern_set_el_list
9248 (DECL_UNIT (decl)->final_absence_list);
9249 fprintf (output_description_file, "\n");
9250 }
9251 }
9252 }
9253 fprintf (output_description_file, "\n");
9254 for (i = 0; i < description->decls_num; i++)
9255 {
9256 decl = description->decls [i];
9257 if (decl->mode == dm_reserv)
9258 {
9259 fprintf (output_description_file, "reservation ");
9260 fprintf (output_description_file, DECL_RESERV (decl)->name);
9261 fprintf (output_description_file, ": ");
9262 output_regexp (DECL_RESERV (decl)->regexp);
9263 fprintf (output_description_file, "\n");
9264 }
9265 else if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
9266 {
9267 fprintf (output_description_file, "insn reservation %s ",
9268 DECL_INSN_RESERV (decl)->name);
9269 print_rtl (output_description_file,
9270 DECL_INSN_RESERV (decl)->condexp);
9271 fprintf (output_description_file, ": ");
9272 output_regexp (DECL_INSN_RESERV (decl)->regexp);
9273 fprintf (output_description_file, "\n");
9274 }
9275 else if (decl->mode == dm_bypass)
9276 fprintf (output_description_file, "bypass %d %s %s\n",
9277 DECL_BYPASS (decl)->latency,
9278 DECL_BYPASS (decl)->out_insn_name,
9279 DECL_BYPASS (decl)->in_insn_name);
9280 }
9281 fprintf (output_description_file, "\n\f\n");
9282 }
9283
9284 /* The function outputs name of AUTOMATON. */
9285 static void
9286 output_automaton_name (f, automaton)
9287 FILE *f;
9288 automaton_t automaton;
9289 {
9290 if (automaton->corresponding_automaton_decl == NULL)
9291 fprintf (f, "#%d", automaton->automaton_order_num);
9292 else
9293 fprintf (f, "`%s'", automaton->corresponding_automaton_decl->name);
9294 }
9295
9296 /* Maximal length of line for pretty printing into description
9297 file. */
9298 #define MAX_LINE_LENGTH 70
9299
9300 /* The function outputs units name belonging to AUTOMATON. */
9301 static void
9302 output_automaton_units (automaton)
9303 automaton_t automaton;
9304 {
9305 decl_t decl;
9306 char *name;
9307 int curr_line_length;
9308 int there_is_an_automaton_unit;
9309 int i;
9310
9311 fprintf (output_description_file, "\n Coresponding units:\n");
9312 fprintf (output_description_file, " ");
9313 curr_line_length = 4;
9314 there_is_an_automaton_unit = 0;
9315 for (i = 0; i < description->decls_num; i++)
9316 {
9317 decl = description->decls [i];
9318 if (decl->mode == dm_unit
9319 && (DECL_UNIT (decl)->corresponding_automaton_num
9320 == automaton->automaton_order_num))
9321 {
9322 there_is_an_automaton_unit = 1;
9323 name = DECL_UNIT (decl)->name;
9324 if (curr_line_length + strlen (name) + 1 > MAX_LINE_LENGTH )
9325 {
9326 curr_line_length = strlen (name) + 4;
9327 fprintf (output_description_file, "\n ");
9328 }
9329 else
9330 {
9331 curr_line_length += strlen (name) + 1;
9332 fprintf (output_description_file, " ");
9333 }
9334 fprintf (output_description_file, name);
9335 }
9336 }
9337 if (!there_is_an_automaton_unit)
9338 fprintf (output_description_file, "<None>");
9339 fprintf (output_description_file, "\n\n");
9340 }
9341
9342 /* The following variable is used for forming array of all possible cpu unit
9343 reservations described by the current DFA state. */
9344 static vla_ptr_t state_reservs;
9345
9346 /* The function forms `state_reservs' for STATE. */
9347 static void
9348 add_state_reservs (state)
9349 state_t state;
9350 {
9351 alt_state_t curr_alt_state;
9352 reserv_sets_t reservs;
9353
9354 if (state->component_states != NULL)
9355 for (curr_alt_state = state->component_states;
9356 curr_alt_state != NULL;
9357 curr_alt_state = curr_alt_state->next_sorted_alt_state)
9358 add_state_reservs (curr_alt_state->state);
9359 else
9360 {
9361 reservs = state->reservs;
9362 VLA_PTR_ADD (state_reservs, reservs);
9363 }
9364 }
9365
9366 /* The function outputs readable representation of all out arcs of
9367 STATE. */
9368 static void
9369 output_state_arcs (state)
9370 state_t state;
9371 {
9372 arc_t arc;
9373 ainsn_t ainsn;
9374 char *insn_name;
9375 int curr_line_length;
9376
9377 for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
9378 {
9379 ainsn = arc->insn;
9380 if (!ainsn->first_insn_with_same_reservs)
9381 abort ();
9382 fprintf (output_description_file, " ");
9383 curr_line_length = 7;
9384 fprintf (output_description_file, "%2d: ", ainsn->insn_equiv_class_num);
9385 do
9386 {
9387 insn_name = ainsn->insn_reserv_decl->name;
9388 if (curr_line_length + strlen (insn_name) > MAX_LINE_LENGTH)
9389 {
9390 if (ainsn != arc->insn)
9391 {
9392 fprintf (output_description_file, ",\n ");
9393 curr_line_length = strlen (insn_name) + 6;
9394 }
9395 else
9396 curr_line_length += strlen (insn_name);
9397 }
9398 else
9399 {
9400 curr_line_length += strlen (insn_name);
9401 if (ainsn != arc->insn)
9402 {
9403 curr_line_length += 2;
9404 fprintf (output_description_file, ", ");
9405 }
9406 }
9407 fprintf (output_description_file, insn_name);
9408 ainsn = ainsn->next_same_reservs_insn;
9409 }
9410 while (ainsn != NULL);
9411 fprintf (output_description_file, " %d (%d)\n",
9412 arc->to_state->order_state_num, arc->state_alts);
9413 }
9414 fprintf (output_description_file, "\n");
9415 }
9416
9417 /* The following function is used for sorting possible cpu unit
9418 reservation of a DFA state. */
9419 static int
9420 state_reservs_cmp (reservs_ptr_1, reservs_ptr_2)
9421 const void *reservs_ptr_1;
9422 const void *reservs_ptr_2;
9423 {
9424 return reserv_sets_cmp (*(reserv_sets_t *) reservs_ptr_1,
9425 *(reserv_sets_t *) reservs_ptr_2);
9426 }
9427
9428 /* The following function is used for sorting possible cpu unit
9429 reservation of a DFA state. */
9430 static void
9431 remove_state_duplicate_reservs ()
9432 {
9433 reserv_sets_t *reservs_ptr;
9434 reserv_sets_t *last_formed_reservs_ptr;
9435
9436 last_formed_reservs_ptr = NULL;
9437 for (reservs_ptr = VLA_PTR_BEGIN (state_reservs);
9438 reservs_ptr <= (reserv_sets_t *) VLA_PTR_LAST (state_reservs);
9439 reservs_ptr++)
9440 if (last_formed_reservs_ptr == NULL)
9441 last_formed_reservs_ptr = reservs_ptr;
9442 else if (reserv_sets_cmp (*last_formed_reservs_ptr, *reservs_ptr) != 0)
9443 {
9444 ++last_formed_reservs_ptr;
9445 *last_formed_reservs_ptr = *reservs_ptr;
9446 }
9447 VLA_PTR_SHORTEN (state_reservs, reservs_ptr - last_formed_reservs_ptr - 1);
9448 }
9449
9450 /* The following function output readable representation of DFA(s)
9451 state used for fast recognition of pipeline hazards. State is
9452 described by possible (current and scheduled) cpu unit
9453 reservations. */
9454 static void
9455 output_state (state)
9456 state_t state;
9457 {
9458 reserv_sets_t *reservs_ptr;
9459
9460 VLA_PTR_CREATE (state_reservs, 150, "state reservations");
9461 fprintf (output_description_file, " State #%d", state->order_state_num);
9462 fprintf (output_description_file,
9463 state->new_cycle_p ? " (new cycle)\n" : "\n");
9464 add_state_reservs (state);
9465 qsort (VLA_PTR_BEGIN (state_reservs), VLA_PTR_LENGTH (state_reservs),
9466 sizeof (reserv_sets_t), state_reservs_cmp);
9467 remove_state_duplicate_reservs ();
9468 for (reservs_ptr = VLA_PTR_BEGIN (state_reservs);
9469 reservs_ptr <= (reserv_sets_t *) VLA_PTR_LAST (state_reservs);
9470 reservs_ptr++)
9471 {
9472 fprintf (output_description_file, " ");
9473 output_reserv_sets (output_description_file, *reservs_ptr);
9474 fprintf (output_description_file, "\n");
9475 }
9476 fprintf (output_description_file, "\n");
9477 output_state_arcs (state);
9478 VLA_PTR_DELETE (state_reservs);
9479 }
9480
9481 /* The following function output readable representation of
9482 DFAs used for fast recognition of pipeline hazards. */
9483 static void
9484 output_automaton_descriptions ()
9485 {
9486 automaton_t automaton;
9487
9488 for (automaton = description->first_automaton;
9489 automaton != NULL;
9490 automaton = automaton->next_automaton)
9491 {
9492 fprintf (output_description_file, "\nAutomaton ");
9493 output_automaton_name (output_description_file, automaton);
9494 fprintf (output_description_file, "\n");
9495 output_automaton_units (automaton);
9496 pass_states (automaton, output_state);
9497 }
9498 }
9499
9500 \f
9501
9502 /* The page contains top level function for generation DFA(s) used for
9503 PHR. */
9504
9505 /* The function outputs statistics about work of different phases of
9506 DFA generator. */
9507 static void
9508 output_statistics (f)
9509 FILE *f;
9510 {
9511 automaton_t automaton;
9512 int states_num;
9513 #ifndef NDEBUG
9514 int transition_comb_vect_els = 0;
9515 int transition_full_vect_els = 0;
9516 int state_alts_comb_vect_els = 0;
9517 int state_alts_full_vect_els = 0;
9518 int min_issue_delay_vect_els = 0;
9519 #endif
9520
9521 for (automaton = description->first_automaton;
9522 automaton != NULL;
9523 automaton = automaton->next_automaton)
9524 {
9525 fprintf (f, "\nAutomaton ");
9526 output_automaton_name (f, automaton);
9527 fprintf (f, "\n %5d NDFA states, %5d NDFA arcs\n",
9528 automaton->NDFA_states_num, automaton->NDFA_arcs_num);
9529 fprintf (f, " %5d DFA states, %5d DFA arcs\n",
9530 automaton->DFA_states_num, automaton->DFA_arcs_num);
9531 states_num = automaton->DFA_states_num;
9532 if (!no_minimization_flag)
9533 {
9534 fprintf (f, " %5d minimal DFA states, %5d minimal DFA arcs\n",
9535 automaton->minimal_DFA_states_num,
9536 automaton->minimal_DFA_arcs_num);
9537 states_num = automaton->minimal_DFA_states_num;
9538 }
9539 fprintf (f, " %5d all insns %5d insn equivalence classes\n",
9540 description->insns_num, automaton->insn_equiv_classes_num);
9541 #ifndef NDEBUG
9542 fprintf
9543 (f, "%5ld transition comb vector els, %5ld trans table els: %s\n",
9544 (long) VLA_HWINT_LENGTH (automaton->trans_table->comb_vect),
9545 (long) VLA_HWINT_LENGTH (automaton->trans_table->full_vect),
9546 (comb_vect_p (automaton->trans_table)
9547 ? "use comb vect" : "use simple vect"));
9548 fprintf
9549 (f, "%5ld state alts comb vector els, %5ld state alts table els: %s\n",
9550 (long) VLA_HWINT_LENGTH (automaton->state_alts_table->comb_vect),
9551 (long) VLA_HWINT_LENGTH (automaton->state_alts_table->full_vect),
9552 (comb_vect_p (automaton->state_alts_table)
9553 ? "use comb vect" : "use simple vect"));
9554 fprintf
9555 (f, "%5ld min delay table els, compression factor %d\n",
9556 (long) states_num * automaton->insn_equiv_classes_num,
9557 automaton->min_issue_delay_table_compression_factor);
9558 transition_comb_vect_els
9559 += VLA_HWINT_LENGTH (automaton->trans_table->comb_vect);
9560 transition_full_vect_els
9561 += VLA_HWINT_LENGTH (automaton->trans_table->full_vect);
9562 state_alts_comb_vect_els
9563 += VLA_HWINT_LENGTH (automaton->state_alts_table->comb_vect);
9564 state_alts_full_vect_els
9565 += VLA_HWINT_LENGTH (automaton->state_alts_table->full_vect);
9566 min_issue_delay_vect_els
9567 += states_num * automaton->insn_equiv_classes_num;
9568 #endif
9569 }
9570 #ifndef NDEBUG
9571 fprintf (f, "\n%5d all allocated states, %5d all allocated arcs\n",
9572 allocated_states_num, allocated_arcs_num);
9573 fprintf (f, "%5d all allocated alternative states\n",
9574 allocated_alt_states_num);
9575 fprintf (f, "%5d all transition comb vector els, %5d all trans table els\n",
9576 transition_comb_vect_els, transition_full_vect_els);
9577 fprintf
9578 (f, "%5d all state alts comb vector els, %5d all state alts table els\n",
9579 state_alts_comb_vect_els, state_alts_full_vect_els);
9580 fprintf (f, "%5d all min delay table els\n", min_issue_delay_vect_els);
9581 fprintf (f, "%5d locked states num\n", locked_states_num);
9582 #endif
9583 }
9584
9585 /* The function output times of work of different phases of DFA
9586 generator. */
9587 static void
9588 output_time_statistics (f)
9589 FILE *f;
9590 {
9591 fprintf (f, "\n transformation: ");
9592 print_active_time (f, transform_time);
9593 fprintf (f, (!ndfa_flag ? ", building DFA: " : ", building NDFA: "));
9594 print_active_time (f, NDFA_time);
9595 if (ndfa_flag)
9596 {
9597 fprintf (f, ", NDFA -> DFA: ");
9598 print_active_time (f, NDFA_to_DFA_time);
9599 }
9600 fprintf (f, "\n DFA minimization: ");
9601 print_active_time (f, minimize_time);
9602 fprintf (f, ", making insn equivalence: ");
9603 print_active_time (f, equiv_time);
9604 fprintf (f, "\n all automaton generation: ");
9605 print_active_time (f, automaton_generation_time);
9606 fprintf (f, ", output: ");
9607 print_active_time (f, output_time);
9608 fprintf (f, "\n");
9609 }
9610
9611 /* The function generates DFA (deterministic finite state automaton)
9612 for fast recognition of pipeline hazards. No errors during
9613 checking must be fixed before this function call. */
9614 static void
9615 generate ()
9616 {
9617 automata_num = split_argument;
9618 if (description->units_num < automata_num)
9619 automata_num = description->units_num;
9620 initiate_states ();
9621 initiate_arcs ();
9622 initiate_automata_lists ();
9623 initiate_pass_states ();
9624 initiate_excl_sets ();
9625 initiate_presence_absence_pattern_sets ();
9626 automaton_generation_time = create_ticker ();
9627 create_automata ();
9628 ticker_off (&automaton_generation_time);
9629 }
9630
9631 \f
9632
9633 /* The following function creates insn attribute whose values are
9634 number alternatives in insn reservations. */
9635 static void
9636 make_insn_alts_attr ()
9637 {
9638 int i, insn_num;
9639 decl_t decl;
9640 rtx condexp;
9641
9642 condexp = rtx_alloc (COND);
9643 XVEC (condexp, 0) = rtvec_alloc ((description->insns_num - 1) * 2);
9644 XEXP (condexp, 1) = make_numeric_value (0);
9645 for (i = insn_num = 0; i < description->decls_num; i++)
9646 {
9647 decl = description->decls [i];
9648 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
9649 {
9650 XVECEXP (condexp, 0, 2 * insn_num)
9651 = DECL_INSN_RESERV (decl)->condexp;
9652 XVECEXP (condexp, 0, 2 * insn_num + 1)
9653 = make_numeric_value
9654 (DECL_INSN_RESERV (decl)->transformed_regexp->mode != rm_oneof
9655 ? 1 : REGEXP_ONEOF (DECL_INSN_RESERV (decl)
9656 ->transformed_regexp)->regexps_num);
9657 insn_num++;
9658 }
9659 }
9660 if (description->insns_num != insn_num + 1)
9661 abort ();
9662 make_internal_attr (attr_printf (sizeof ("*")
9663 + strlen (INSN_ALTS_FUNC_NAME) + 1,
9664 "*%s", INSN_ALTS_FUNC_NAME),
9665 condexp, 0);
9666 }
9667
9668 \f
9669
9670 /* The following function creates attribute which is order number of
9671 insn in pipeline hazard description translator. */
9672 static void
9673 make_internal_dfa_insn_code_attr ()
9674 {
9675 int i, insn_num;
9676 decl_t decl;
9677 rtx condexp;
9678
9679 condexp = rtx_alloc (COND);
9680 XVEC (condexp, 0) = rtvec_alloc ((description->insns_num - 1) * 2);
9681 XEXP (condexp, 1)
9682 = make_numeric_value (DECL_INSN_RESERV (advance_cycle_insn_decl)
9683 ->insn_num + 1);
9684 for (i = insn_num = 0; i < description->decls_num; i++)
9685 {
9686 decl = description->decls [i];
9687 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
9688 {
9689 XVECEXP (condexp, 0, 2 * insn_num)
9690 = DECL_INSN_RESERV (decl)->condexp;
9691 XVECEXP (condexp, 0, 2 * insn_num + 1)
9692 = make_numeric_value (DECL_INSN_RESERV (decl)->insn_num);
9693 insn_num++;
9694 }
9695 }
9696 if (description->insns_num != insn_num + 1)
9697 abort ();
9698 make_internal_attr
9699 (attr_printf (sizeof ("*")
9700 + strlen (INTERNAL_DFA_INSN_CODE_FUNC_NAME) + 1,
9701 "*%s", INTERNAL_DFA_INSN_CODE_FUNC_NAME),
9702 condexp, 0);
9703 }
9704
9705 \f
9706
9707 /* The following function creates attribute which order number of insn
9708 in pipeline hazard description translator. */
9709 static void
9710 make_default_insn_latency_attr ()
9711 {
9712 int i, insn_num;
9713 decl_t decl;
9714 rtx condexp;
9715
9716 condexp = rtx_alloc (COND);
9717 XVEC (condexp, 0) = rtvec_alloc ((description->insns_num - 1) * 2);
9718 XEXP (condexp, 1) = make_numeric_value (0);
9719 for (i = insn_num = 0; i < description->decls_num; i++)
9720 {
9721 decl = description->decls [i];
9722 if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
9723 {
9724 XVECEXP (condexp, 0, 2 * insn_num)
9725 = DECL_INSN_RESERV (decl)->condexp;
9726 XVECEXP (condexp, 0, 2 * insn_num + 1)
9727 = make_numeric_value (DECL_INSN_RESERV (decl)->default_latency);
9728 insn_num++;
9729 }
9730 }
9731 if (description->insns_num != insn_num + 1)
9732 abort ();
9733 make_internal_attr (attr_printf (sizeof ("*")
9734 + strlen (INSN_DEFAULT_LATENCY_FUNC_NAME)
9735 + 1, "*%s", INSN_DEFAULT_LATENCY_FUNC_NAME),
9736 condexp, 0);
9737 }
9738
9739 \f
9740
9741 /* The following function creates attribute which returns 1 if given
9742 output insn has bypassing and 0 otherwise. */
9743 static void
9744 make_bypass_attr ()
9745 {
9746 int i, bypass_insn;
9747 int bypass_insns_num = 0;
9748 decl_t decl;
9749 rtx result_rtx;
9750
9751 for (i = 0; i < description->decls_num; i++)
9752 {
9753 decl = description->decls [i];
9754 if (decl->mode == dm_insn_reserv
9755 && DECL_INSN_RESERV (decl)->condexp != NULL
9756 && DECL_INSN_RESERV (decl)->bypass_list != NULL)
9757 bypass_insns_num++;
9758 }
9759 if (bypass_insns_num == 0)
9760 result_rtx = make_numeric_value (0);
9761 else
9762 {
9763 result_rtx = rtx_alloc (COND);
9764 XVEC (result_rtx, 0) = rtvec_alloc (bypass_insns_num * 2);
9765 XEXP (result_rtx, 1) = make_numeric_value (0);
9766
9767 for (i = bypass_insn = 0; i < description->decls_num; i++)
9768 {
9769 decl = description->decls [i];
9770 if (decl->mode == dm_insn_reserv
9771 && DECL_INSN_RESERV (decl)->condexp != NULL
9772 && DECL_INSN_RESERV (decl)->bypass_list != NULL)
9773 {
9774 XVECEXP (result_rtx, 0, 2 * bypass_insn)
9775 = DECL_INSN_RESERV (decl)->condexp;
9776 XVECEXP (result_rtx, 0, 2 * bypass_insn + 1)
9777 = make_numeric_value (1);
9778 bypass_insn++;
9779 }
9780 }
9781 }
9782 make_internal_attr (attr_printf (sizeof ("*")
9783 + strlen (BYPASS_P_FUNC_NAME) + 1,
9784 "*%s", BYPASS_P_FUNC_NAME),
9785 result_rtx, 0);
9786 }
9787
9788 \f
9789
9790 /* This page mainly contains top level functions of pipeline hazards
9791 description translator. */
9792
9793 /* The following macro value is suffix of name of description file of
9794 pipeline hazards description translator. */
9795 #define STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX ".dfa"
9796
9797 /* The function returns suffix of given file name. The returned
9798 string can not be changed. */
9799 static const char *
9800 file_name_suffix (file_name)
9801 const char *file_name;
9802 {
9803 const char *last_period;
9804
9805 for (last_period = NULL; *file_name != '\0'; file_name++)
9806 if (*file_name == '.')
9807 last_period = file_name;
9808 return (last_period == NULL ? file_name : last_period);
9809 }
9810
9811 /* The function returns base name of given file name, i.e. pointer to
9812 first char after last `/' (or `\' for WIN32) in given file name,
9813 given file name itself if the directory name is absent. The
9814 returned string can not be changed. */
9815 static const char *
9816 base_file_name (file_name)
9817 const char *file_name;
9818 {
9819 int directory_name_length;
9820
9821 directory_name_length = strlen (file_name);
9822 #ifdef WIN32
9823 while (directory_name_length >= 0 && file_name[directory_name_length] != '/'
9824 && file_name[directory_name_length] != '\\')
9825 #else
9826 while (directory_name_length >= 0 && file_name[directory_name_length] != '/')
9827 #endif
9828 directory_name_length--;
9829 return file_name + directory_name_length + 1;
9830 }
9831
9832 /* The following is top level function to initialize the work of
9833 pipeline hazards description translator. */
9834 void
9835 initiate_automaton_gen (argc, argv)
9836 int argc;
9837 char **argv;
9838 {
9839 const char *base_name;
9840 int i;
9841
9842 ndfa_flag = 0;
9843 split_argument = 0; /* default value */
9844 no_minimization_flag = 0;
9845 time_flag = 0;
9846 v_flag = 0;
9847 w_flag = 0;
9848 for (i = 2; i < argc; i++)
9849 if (strcmp (argv [i], NO_MINIMIZATION_OPTION) == 0)
9850 no_minimization_flag = 1;
9851 else if (strcmp (argv [i], TIME_OPTION) == 0)
9852 time_flag = 1;
9853 else if (strcmp (argv [i], V_OPTION) == 0)
9854 v_flag = 1;
9855 else if (strcmp (argv [i], W_OPTION) == 0)
9856 w_flag = 1;
9857 else if (strcmp (argv [i], NDFA_OPTION) == 0)
9858 ndfa_flag = 1;
9859 else if (strcmp (argv [i], "-split") == 0)
9860 {
9861 if (i + 1 >= argc)
9862 fatal ("-split has no argument.");
9863 fatal ("option `-split' has not been implemented yet\n");
9864 /* split_argument = atoi (argument_vect [i + 1]); */
9865 }
9866 VLA_PTR_CREATE (decls, 150, "decls");
9867 /* Initialize IR storage. */
9868 obstack_init (&irp);
9869 initiate_automaton_decl_table ();
9870 initiate_insn_decl_table ();
9871 initiate_decl_table ();
9872 output_file = stdout;
9873 output_description_file = NULL;
9874 base_name = base_file_name (argv[1]);
9875 obstack_grow (&irp, base_name,
9876 strlen (base_name) - strlen (file_name_suffix (base_name)));
9877 obstack_grow (&irp, STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX,
9878 strlen (STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX) + 1);
9879 obstack_1grow (&irp, '\0');
9880 output_description_file_name = obstack_base (&irp);
9881 obstack_finish (&irp);
9882 }
9883
9884 /* The following function checks existence at least one arc marked by
9885 each insn. */
9886 static void
9887 check_automata_insn_issues ()
9888 {
9889 automaton_t automaton;
9890 ainsn_t ainsn, reserv_ainsn;
9891
9892 for (automaton = description->first_automaton;
9893 automaton != NULL;
9894 automaton = automaton->next_automaton)
9895 {
9896 for (ainsn = automaton->ainsn_list;
9897 ainsn != NULL;
9898 ainsn = ainsn->next_ainsn)
9899 if (ainsn->first_insn_with_same_reservs && !ainsn->arc_exists_p)
9900 {
9901 for (reserv_ainsn = ainsn;
9902 reserv_ainsn != NULL;
9903 reserv_ainsn = reserv_ainsn->next_same_reservs_insn)
9904 if (automaton->corresponding_automaton_decl != NULL)
9905 {
9906 if (!w_flag)
9907 error ("Automaton `%s': Insn `%s' will never be issued",
9908 automaton->corresponding_automaton_decl->name,
9909 reserv_ainsn->insn_reserv_decl->name);
9910 else
9911 warning
9912 ("Automaton `%s': Insn `%s' will never be issued",
9913 automaton->corresponding_automaton_decl->name,
9914 reserv_ainsn->insn_reserv_decl->name);
9915 }
9916 else
9917 {
9918 if (!w_flag)
9919 error ("Insn `%s' will never be issued",
9920 reserv_ainsn->insn_reserv_decl->name);
9921 else
9922 warning ("Insn `%s' will never be issued",
9923 reserv_ainsn->insn_reserv_decl->name);
9924 }
9925 }
9926 }
9927 }
9928
9929 /* The following vla is used for storing pointers to all achieved
9930 states. */
9931 static vla_ptr_t automaton_states;
9932
9933 /* This function is called by function pass_states to add an achieved
9934 STATE. */
9935 static void
9936 add_automaton_state (state)
9937 state_t state;
9938 {
9939 VLA_PTR_ADD (automaton_states, state);
9940 }
9941
9942 /* The following function forms list of important automata (whose
9943 states may be changed after the insn issue) for each insn. */
9944 static void
9945 form_important_insn_automata_lists ()
9946 {
9947 automaton_t automaton;
9948 state_t *state_ptr;
9949 decl_t decl;
9950 ainsn_t ainsn;
9951 arc_t arc;
9952 int i;
9953
9954 VLA_PTR_CREATE (automaton_states, 1500,
9955 "automaton states for forming important insn automata sets");
9956 /* Mark important ainsns. */
9957 for (automaton = description->first_automaton;
9958 automaton != NULL;
9959 automaton = automaton->next_automaton)
9960 {
9961 VLA_PTR_NULLIFY (automaton_states);
9962 pass_states (automaton, add_automaton_state);
9963 for (state_ptr = VLA_PTR_BEGIN (automaton_states);
9964 state_ptr <= (state_t *) VLA_PTR_LAST (automaton_states);
9965 state_ptr++)
9966 {
9967 for (arc = first_out_arc (*state_ptr);
9968 arc != NULL;
9969 arc = next_out_arc (arc))
9970 if (arc->to_state != *state_ptr)
9971 {
9972 if (!arc->insn->first_insn_with_same_reservs)
9973 abort ();
9974 for (ainsn = arc->insn;
9975 ainsn != NULL;
9976 ainsn = ainsn->next_same_reservs_insn)
9977 ainsn->important_p = TRUE;
9978 }
9979 }
9980 }
9981 VLA_PTR_DELETE (automaton_states);
9982 /* Create automata sets for the insns. */
9983 for (i = 0; i < description->decls_num; i++)
9984 {
9985 decl = description->decls [i];
9986 if (decl->mode == dm_insn_reserv)
9987 {
9988 automata_list_start ();
9989 for (automaton = description->first_automaton;
9990 automaton != NULL;
9991 automaton = automaton->next_automaton)
9992 for (ainsn = automaton->ainsn_list;
9993 ainsn != NULL;
9994 ainsn = ainsn->next_ainsn)
9995 if (ainsn->important_p
9996 && ainsn->insn_reserv_decl == DECL_INSN_RESERV (decl))
9997 {
9998 automata_list_add (automaton);
9999 break;
10000 }
10001 DECL_INSN_RESERV (decl)->important_automata_list
10002 = automata_list_finish ();
10003 }
10004 }
10005 }
10006
10007
10008 /* The following is top level function to generate automat(a,on) for
10009 fast recognition of pipeline hazards. */
10010 void
10011 expand_automata ()
10012 {
10013 int i;
10014
10015 description = create_node (sizeof (struct description)
10016 /* One entry for cycle advancing insn. */
10017 + sizeof (decl_t) * VLA_PTR_LENGTH (decls));
10018 description->decls_num = VLA_PTR_LENGTH (decls);
10019 description->query_units_num = 0;
10020 for (i = 0; i < description->decls_num; i++)
10021 {
10022 description->decls [i] = VLA_PTR (decls, i);
10023 if (description->decls [i]->mode == dm_unit
10024 && DECL_UNIT (description->decls [i])->query_p)
10025 DECL_UNIT (description->decls [i])->query_num
10026 = description->query_units_num++;
10027 }
10028 all_time = create_ticker ();
10029 check_time = create_ticker ();
10030 fprintf (stderr, "Check description...");
10031 fflush (stderr);
10032 check_all_description ();
10033 fprintf (stderr, "done\n");
10034 ticker_off (&check_time);
10035 generation_time = create_ticker ();
10036 if (!have_error)
10037 {
10038 transform_insn_regexps ();
10039 check_unit_distributions_to_automata ();
10040 }
10041 if (!have_error)
10042 {
10043 generate ();
10044 check_automata_insn_issues ();
10045 }
10046 if (!have_error)
10047 {
10048 form_important_insn_automata_lists ();
10049 fprintf (stderr, "Generation of attributes...");
10050 fflush (stderr);
10051 make_internal_dfa_insn_code_attr ();
10052 make_insn_alts_attr ();
10053 make_default_insn_latency_attr ();
10054 make_bypass_attr ();
10055 fprintf (stderr, "done\n");
10056 }
10057 ticker_off (&generation_time);
10058 ticker_off (&all_time);
10059 fprintf (stderr, "All other genattrtab stuff...");
10060 fflush (stderr);
10061 }
10062
10063 /* The following is top level function to output PHR and to finish
10064 work with pipeline description translator. */
10065 void
10066 write_automata ()
10067 {
10068 fprintf (stderr, "done\n");
10069 if (have_error)
10070 fatal ("Errors in DFA description");
10071 ticker_on (&all_time);
10072 output_time = create_ticker ();
10073 fprintf (stderr, "Forming and outputing automata tables...");
10074 fflush (stderr);
10075 output_dfa_max_issue_rate ();
10076 output_tables ();
10077 fprintf (stderr, "done\n");
10078 fprintf (stderr, "Output functions to work with automata...");
10079 fflush (stderr);
10080 output_chip_definitions ();
10081 output_max_insn_queue_index_def ();
10082 output_internal_min_issue_delay_func ();
10083 output_internal_trans_func ();
10084 /* Cache of insn dfa codes: */
10085 fprintf (output_file, "\nstatic int *%s;\n", DFA_INSN_CODES_VARIABLE_NAME);
10086 fprintf (output_file, "\nstatic int %s;\n\n",
10087 DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
10088 output_dfa_insn_code_func ();
10089 output_trans_func ();
10090 fprintf (output_file, "\n#if %s\n\n", AUTOMATON_STATE_ALTS_MACRO_NAME);
10091 output_internal_state_alts_func ();
10092 output_state_alts_func ();
10093 fprintf (output_file, "\n#endif /* #if %s */\n\n",
10094 AUTOMATON_STATE_ALTS_MACRO_NAME);
10095 output_min_issue_delay_func ();
10096 output_internal_dead_lock_func ();
10097 output_dead_lock_func ();
10098 output_size_func ();
10099 output_internal_reset_func ();
10100 output_reset_func ();
10101 output_min_insn_conflict_delay_func ();
10102 output_internal_insn_latency_func ();
10103 output_insn_latency_func ();
10104 output_print_reservation_func ();
10105 /* Output function get_cpu_unit_code. */
10106 fprintf (output_file, "\n#if %s\n\n", CPU_UNITS_QUERY_MACRO_NAME);
10107 output_get_cpu_unit_code_func ();
10108 output_cpu_unit_reservation_p ();
10109 fprintf (output_file, "\n#endif /* #if %s */\n\n",
10110 CPU_UNITS_QUERY_MACRO_NAME);
10111 output_dfa_clean_insn_cache_func ();
10112 output_dfa_start_func ();
10113 output_dfa_finish_func ();
10114 fprintf (stderr, "done\n");
10115 if (v_flag)
10116 {
10117 output_description_file = fopen (output_description_file_name, "w");
10118 if (output_description_file == NULL)
10119 {
10120 perror (output_description_file_name);
10121 exit (FATAL_EXIT_CODE);
10122 }
10123 fprintf (stderr, "Output automata description...");
10124 fflush (stderr);
10125 output_description ();
10126 output_automaton_descriptions ();
10127 fprintf (stderr, "done\n");
10128 output_statistics (output_description_file);
10129 }
10130 output_statistics (stderr);
10131 ticker_off (&output_time);
10132 output_time_statistics (stderr);
10133 finish_states ();
10134 finish_arcs ();
10135 finish_automata_lists ();
10136 if (time_flag)
10137 {
10138 fprintf (stderr, "Summary:\n");
10139 fprintf (stderr, " check time ");
10140 print_active_time (stderr, check_time);
10141 fprintf (stderr, ", generation time ");
10142 print_active_time (stderr, generation_time);
10143 fprintf (stderr, ", all time ");
10144 print_active_time (stderr, all_time);
10145 fprintf (stderr, "\n");
10146 }
10147 /* Finish all work. */
10148 if (output_description_file != NULL)
10149 {
10150 fflush (output_description_file);
10151 if (ferror (stdout) != 0)
10152 fatal ("Error in writing DFA description file %s",
10153 output_description_file_name);
10154 fclose (output_description_file);
10155 }
10156 finish_automaton_decl_table ();
10157 finish_insn_decl_table ();
10158 finish_decl_table ();
10159 obstack_free (&irp, NULL);
10160 if (have_error && output_description_file != NULL)
10161 remove (output_description_file_name);
10162 }