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